diff --git a/crypto/CMakeLists.txt b/crypto/CMakeLists.txt index 4292781e..5d656ecc 100644 --- a/crypto/CMakeLists.txt +++ b/crypto/CMakeLists.txt @@ -113,6 +113,7 @@ add_library( crypto STATIC + crypto.c crypto_error.c mem.c thread.c diff --git a/crypto/base64/base64_test.c b/crypto/base64/base64_test.c index 0bee55fb..e208e816 100644 --- a/crypto/base64/base64_test.c +++ b/crypto/base64/base64_test.c @@ -16,6 +16,7 @@ #include #include +#include #include @@ -117,6 +118,7 @@ static int test_decode(void) { } int main(void) { + CRYPTO_library_init(); ERR_load_crypto_strings(); if (!test_encode()) { diff --git a/crypto/bio/bio_test.c b/crypto/bio/bio_test.c index 75399df5..beb38491 100644 --- a/crypto/bio/bio_test.c +++ b/crypto/bio/bio_test.c @@ -22,6 +22,7 @@ #include #include +#include #include @@ -145,6 +146,7 @@ static int test_printf(void) { } int main(void) { + CRYPTO_library_init(); ERR_load_crypto_strings(); if (!test_socket_connect()) { diff --git a/crypto/bn/bn_test.c b/crypto/bn/bn_test.c index d50b6b5c..11b3c62e 100644 --- a/crypto/bn/bn_test.c +++ b/crypto/bn/bn_test.c @@ -71,6 +71,7 @@ #include #include +#include #include #include @@ -135,6 +136,8 @@ int main(int argc, char *argv[]) { BIO *out = NULL; char *outfile = NULL; + CRYPTO_library_init(); + results = 0; argc--; diff --git a/crypto/bytestring/bytestring_test.c b/crypto/bytestring/bytestring_test.c index 5ea9d485..e4afccdc 100644 --- a/crypto/bytestring/bytestring_test.c +++ b/crypto/bytestring/bytestring_test.c @@ -15,6 +15,7 @@ #include #include +#include #include #include "internal.h" @@ -434,6 +435,8 @@ static int test_ber_convert(void) { } int main(void) { + CRYPTO_library_init(); + if (!test_skip() || !test_get_u() || !test_get_prefixed() || diff --git a/crypto/cipher/aead_test.c b/crypto/cipher/aead_test.c index f0f3cf4d..ff2244c9 100644 --- a/crypto/cipher/aead_test.c +++ b/crypto/cipher/aead_test.c @@ -18,6 +18,7 @@ #include #include +#include /* This program tests an AEAD against a series of test vectors from a file. The * test vector file consists of key-value lines where the key and value are @@ -155,6 +156,8 @@ int main(int argc, char **argv) { unsigned char bufs[NUM_TYPES][BUF_MAX]; unsigned int lengths[NUM_TYPES]; + CRYPTO_library_init(); + if (argc != 3) { fprintf(stderr, "%s \n", argv[0]); return 1; diff --git a/crypto/cipher/cipher_test.c b/crypto/cipher/cipher_test.c index 3dadb8a4..b91b505a 100644 --- a/crypto/cipher/cipher_test.c +++ b/crypto/cipher/cipher_test.c @@ -56,9 +56,10 @@ #include -#include -#include #include +#include +#include +#include static void hexdump(FILE *f, const char *title, const uint8_t *s, int l) { @@ -331,6 +332,8 @@ int main(int argc, char **argv) { const char *input_file; FILE *f; + CRYPTO_library_init(); + if (argc != 2) { fprintf(stderr, "%s \n", argv[0]); return 1; diff --git a/crypto/cpu-intel.c b/crypto/cpu-intel.c index bc3148f5..e2efb2c4 100644 --- a/crypto/cpu-intel.c +++ b/crypto/cpu-intel.c @@ -78,10 +78,6 @@ uint32_t OPENSSL_ia32cap_P[4] = {0}; /* OPENSSL_ia32_cpuid is defined in cpu-x86_64-asm.pl. */ extern uint64_t OPENSSL_ia32_cpuid(uint32_t*); -#if !defined(OPENSSL_WINDOWS) -void OPENSSL_cpuid_setup(void) __attribute__ ((constructor)); -#endif - /* handle_cpu_env applies the value from |in| to the CPUID values in |out[0]| * and |out[1]|. See the comment in |OPENSSL_cpuid_setup| about this. */ static void handle_cpu_env(uint32_t *out, const char *in) { @@ -101,14 +97,7 @@ static void handle_cpu_env(uint32_t *out, const char *in) { } } -#if defined(OPENSSL_WINDOWS) -#pragma section(".CRT$XCU", read) -void __cdecl OPENSSL_cpuid_setup(void); -__declspec(allocate(".CRT$XCU")) void(*cpuid_constructor)(void) = OPENSSL_cpuid_setup; -void __cdecl OPENSSL_cpuid_setup(void) { -#else void OPENSSL_cpuid_setup(void) { -#endif const char *env1, *env2; #if defined(OPENSSL_X86_64) diff --git a/crypto/crypto.c b/crypto/crypto.c new file mode 100644 index 00000000..78241daa --- /dev/null +++ b/crypto/crypto.c @@ -0,0 +1,60 @@ +/* Copyright (c) 2014, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include + +#include "internal.h" + + +/* Currently, the only configurations which require a static initializer are x86 + * and x86_64. Don't bother emitting one in other cases. */ +#if !defined(OPENSSL_X86) && !defined(OPENSSL_X86_64) && \ + !defined(BORINGSSL_NO_STATIC_INITIALIZER) +#define BORINGSSL_NO_STATIC_INITIALIZER +#endif + +#if defined(OPENSSL_WINDOWS) +#define OPENSSL_CDECL __cdecl +#else +#define OPENSSL_CDECL +#endif + +#if !defined(BORINGSSL_NO_STATIC_INITIALIZER) +#if !defined(OPENSSL_WINDOWS) +static void do_library_init(void) __attribute__ ((constructor)); +#else +#pragma section(".CRT$XCU", read) +static void __cdecl do_library_init(void); +__declspec(allocate(".CRT$XCU")) void(*library_init_constructor)(void) = + do_library_init; +#endif +#endif /* !BORINGSSL_NO_STATIC_INITIALIZER */ + +/* do_library_init is the actual initialization function. If + * BORINGSSL_NO_STATIC_INITIALIZER isn't defined, this is set as a static + * initializer. Otherwise, it is called by CRYPTO_library_init. */ +static void OPENSSL_CDECL do_library_init(void) { +#if defined(OPENSSL_X86) || defined(OPENSSL_X86_64) + OPENSSL_cpuid_setup(); +#endif +} + +void CRYPTO_library_init(void) { + /* TODO(davidben): It would be tidier if this build knob could be replaced + * with an internal lazy-init mechanism that would handle things correctly + * in-library. */ +#if defined(BORINGSSL_NO_STATIC_INITIALIZER) + do_library_init(); +#endif +} diff --git a/crypto/dh/dh_test.c b/crypto/dh/dh_test.c index 73dbba92..31b3dd90 100644 --- a/crypto/dh/dh_test.c +++ b/crypto/dh/dh_test.c @@ -60,6 +60,7 @@ #include #include +#include #include #include "internal.h" @@ -93,6 +94,8 @@ int main(int argc, char *argv[]) { int i, alen, blen, aout, bout, ret = 1; BIO *out; + CRYPTO_library_init(); + out = BIO_new(BIO_s_file()); if (out == NULL) { return 1; diff --git a/crypto/dsa/dsa_test.c b/crypto/dsa/dsa_test.c index 8841c129..1edb7e7a 100644 --- a/crypto/dsa/dsa_test.c +++ b/crypto/dsa/dsa_test.c @@ -61,6 +61,7 @@ #include #include +#include #include "internal.h" @@ -107,6 +108,8 @@ int main(int argc, char **argv) { unsigned char sig[256]; unsigned int siglen; + CRYPTO_library_init(); + bio_err = BIO_new_fp(stderr, BIO_NOCLOSE); bio_out = BIO_new_fp(stdout, BIO_NOCLOSE); diff --git a/crypto/ec/example_mul.c b/crypto/ec/example_mul.c index d65c3a17..ebb724fa 100644 --- a/crypto/ec/example_mul.c +++ b/crypto/ec/example_mul.c @@ -68,6 +68,7 @@ #include #include +#include #include #include @@ -120,6 +121,8 @@ err: } int main(void) { + CRYPTO_library_init(); + if (!example_EC_POINT_mul()) { fprintf(stderr, "failed\n"); return 1; diff --git a/crypto/ecdsa/ecdsa_test.c b/crypto/ecdsa/ecdsa_test.c index 64480e31..e3b11425 100644 --- a/crypto/ecdsa/ecdsa_test.c +++ b/crypto/ecdsa/ecdsa_test.c @@ -54,6 +54,7 @@ #include #include +#include #include #include #include @@ -285,10 +286,11 @@ int main(void) { int ret = 1; BIO *out; - out = BIO_new_fp(stdout, BIO_NOCLOSE); - + CRYPTO_library_init(); ERR_load_crypto_strings(); + out = BIO_new_fp(stdout, BIO_NOCLOSE); + if (!test_builtin(out)) goto err; diff --git a/crypto/err/err_test.c b/crypto/err/err_test.c index 14217f72..230cadae 100644 --- a/crypto/err/err_test.c +++ b/crypto/err/err_test.c @@ -14,6 +14,7 @@ #include +#include #include #include @@ -112,6 +113,8 @@ static int test_release(void) { } int main(void) { + CRYPTO_library_init(); + if (!test_overflow() || !test_put_error() || !test_clear_error() || diff --git a/crypto/evp/example_sign.c b/crypto/evp/example_sign.c index 9d2a2969..c25ef2a2 100644 --- a/crypto/evp/example_sign.c +++ b/crypto/evp/example_sign.c @@ -17,6 +17,7 @@ #include #include +#include #include #include #include @@ -198,6 +199,8 @@ out: } int main(void) { + CRYPTO_library_init(); + if (!example_EVP_DigestSignInit()) { fprintf(stderr, "EVP_DigestSignInit failed\n"); return 1; diff --git a/crypto/hmac/hmac_test.c b/crypto/hmac/hmac_test.c index e2ae4a6f..7b851967 100644 --- a/crypto/hmac/hmac_test.c +++ b/crypto/hmac/hmac_test.c @@ -56,6 +56,7 @@ #include +#include #include #include @@ -124,6 +125,8 @@ int main(int argc, char *argv[]) { uint8_t out[EVP_MAX_MD_SIZE]; unsigned out_len; + CRYPTO_library_init(); + for (i = 0; i < NUM_TESTS; i++) { const struct test_st *test = &kTests[i]; diff --git a/crypto/internal.h b/crypto/internal.h index 65a52ed3..ffac2d5e 100644 --- a/crypto/internal.h +++ b/crypto/internal.h @@ -144,6 +144,10 @@ struct st_CRYPTO_EX_DATA_IMPL { #endif /* OPENSSL_WINDOWS */ +#if defined(OPENSSL_X86) || defined(OPENSSL_X86_64) +/* OPENSSL_cpuid_setup initializes OPENSSL_ia32cap_P. */ +void OPENSSL_cpuid_setup(void); +#endif #if defined(__cplusplus) } /* extern C */ diff --git a/crypto/lhash/lhash_test.c b/crypto/lhash/lhash_test.c index 9a94a883..eb40cab2 100644 --- a/crypto/lhash/lhash_test.c +++ b/crypto/lhash/lhash_test.c @@ -14,6 +14,7 @@ #define _BSD_SOURCE +#include #include #include @@ -113,10 +114,14 @@ static char *rand_string(void) { } int main(int argc, char **argv) { - _LHASH *lh = lh_new(NULL, NULL); + _LHASH *lh; struct dummy_lhash dummy_lh = {NULL}; unsigned i; + CRYPTO_library_init(); + + lh = lh_new(NULL, NULL); + for (i = 0; i < 100000; i++) { unsigned action; char *s, *s1, *s2; diff --git a/crypto/md5/md5_test.c b/crypto/md5/md5_test.c index eb5984c8..fd243414 100644 --- a/crypto/md5/md5_test.c +++ b/crypto/md5/md5_test.c @@ -55,8 +55,9 @@ #include -#include +#include #include +#include static const char *const test[] = { @@ -78,6 +79,8 @@ int main(int argc, char **argv) { char md_hex[sizeof(md) * 2 + 1]; int ok = 1; + CRYPTO_library_init(); + for (i = 0; test[i] != NULL; i++) { EVP_Digest(test[i], strlen(test[i]), md, NULL, EVP_md5(), NULL); for (j = 0; j < sizeof(md); j++) { diff --git a/crypto/modes/gcm_test.c b/crypto/modes/gcm_test.c index a112431a..5308976e 100644 --- a/crypto/modes/gcm_test.c +++ b/crypto/modes/gcm_test.c @@ -49,6 +49,7 @@ #include #include +#include #include #include @@ -417,6 +418,8 @@ int main(void) { int ret = 0; unsigned i; + CRYPTO_library_init(); + for (i = 0; i < sizeof(test_cases) / sizeof(struct test_case); i++) { if (!run_test_case(i, &test_cases[i])) { ret = 1; diff --git a/crypto/pkcs8/pkcs12_test.c b/crypto/pkcs8/pkcs12_test.c index 39ed8400..6aea1ebc 100644 --- a/crypto/pkcs8/pkcs12_test.c +++ b/crypto/pkcs8/pkcs12_test.c @@ -17,6 +17,7 @@ #include #include +#include #include #include #include @@ -705,6 +706,7 @@ static int test(const char *name, const uint8_t *der, size_t der_len) { } int main(int argc, char **argv) { + CRYPTO_library_init(); ERR_load_crypto_strings(); if (!test("OpenSSL", kOpenSSL, sizeof(kOpenSSL)) || diff --git a/crypto/rsa/rsa_test.c b/crypto/rsa/rsa_test.c index 897bb610..a5bc3662 100644 --- a/crypto/rsa/rsa_test.c +++ b/crypto/rsa/rsa_test.c @@ -58,6 +58,7 @@ #include #include +#include #include #include @@ -394,6 +395,8 @@ int main(int argc, char *argv[]) { int num; int n; + CRYPTO_library_init(); + plen = sizeof(ptext_ex) - 1; for (v = 0; v < 3; v++) { diff --git a/crypto/sha/sha1_test.c b/crypto/sha/sha1_test.c index a0df062b..d723e407 100644 --- a/crypto/sha/sha1_test.c +++ b/crypto/sha/sha1_test.c @@ -56,8 +56,9 @@ #include -#include +#include #include +#include static const char *const test[] = { @@ -102,6 +103,8 @@ int main(int argc, char **argv) { char md_hex[sizeof(md) * 2 + 1]; int ok = 1; + CRYPTO_library_init(); + for (i = 0; test[i] != NULL; i++) { EVP_Digest(test[i], strlen(test[i]), md, NULL, EVP_sha1(), NULL); for (j = 0; j < sizeof(md); j++) { diff --git a/crypto/x509/pkcs7_test.c b/crypto/x509/pkcs7_test.c index 9d8adcea..2e20c40b 100644 --- a/crypto/x509/pkcs7_test.c +++ b/crypto/x509/pkcs7_test.c @@ -16,6 +16,7 @@ #include #include +#include #include #include @@ -394,6 +395,8 @@ static int test_reparse(const uint8_t *der_bytes, size_t der_len) { } int main(void) { + CRYPTO_library_init(); + if (!test_reparse(kPKCS7NSS, sizeof(kPKCS7NSS)) || !test_reparse(kPKCS7Windows, sizeof(kPKCS7Windows))) { return 1; diff --git a/crypto/x509v3/tabtest.c b/crypto/x509v3/tabtest.c index 06a692e3..f7839388 100644 --- a/crypto/x509v3/tabtest.c +++ b/crypto/x509v3/tabtest.c @@ -62,6 +62,7 @@ #include +#include #include #include "ext_dat.h" @@ -70,6 +71,7 @@ int main(void) { int i, prev = -1, bad = 0; const X509V3_EXT_METHOD **tmp; + CRYPTO_library_init(); i = sizeof(standard_exts) / sizeof(X509V3_EXT_METHOD *); if(i != STANDARD_EXTENSION_COUNT) fprintf(stderr, "Extension number invalid expecting %d\n", i); diff --git a/crypto/x509v3/v3nametest.c b/crypto/x509v3/v3nametest.c index 326b1f93..6a2ea859 100644 --- a/crypto/x509v3/v3nametest.c +++ b/crypto/x509v3/v3nametest.c @@ -55,6 +55,7 @@ #include #include +#include #include #include @@ -391,6 +392,8 @@ static void run_cert(X509 *crt, const char *nameincert, int main(void) { + CRYPTO_library_init(); + const struct set_name_fn *pfn = name_fns; while (pfn->name) { const char *const *pname = names; diff --git a/include/openssl/crypto.h b/include/openssl/crypto.h index ddb97be9..112431e1 100644 --- a/include/openssl/crypto.h +++ b/include/openssl/crypto.h @@ -12,12 +12,34 @@ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -/* This header is provided in order to make compiling against code that expects - OpenSSL easier. */ +#ifndef OPENSSL_HEADER_CRYPTO_H +#define OPENSSL_HEADER_CRYPTO_H + +#include + +#include + +#if defined(__cplusplus) +extern "C" { +#endif + + +/* crypto.h contains functions for initializing the crypto library. */ + + +/* CRYPTO_library_init initializes the crypto library. It must be called if the + * library is built with BORINGSSL_NO_STATIC_INITIALIZER. Otherwise, it does + * nothing and a static initializer is used instead. */ +OPENSSL_EXPORT void CRYPTO_library_init(void); + + +#if defined(__cplusplus) +} /* extern C */ +#endif #define CRYPTO_F_CRYPTO_set_ex_data 100 #define CRYPTO_F_get_class 101 #define CRYPTO_F_get_new_index 102 #define CRYPTO_F_get_func_pointers 103 -#include "mem.h" +#endif /* OPENSSL_HEADER_CRYPTO_H */ diff --git a/ssl/pqueue/CMakeLists.txt b/ssl/pqueue/CMakeLists.txt index 60493505..b7166b40 100644 --- a/ssl/pqueue/CMakeLists.txt +++ b/ssl/pqueue/CMakeLists.txt @@ -14,4 +14,4 @@ add_executable( pqueue_test.c ) -target_link_libraries(pqueue_test ssl) +target_link_libraries(pqueue_test ssl crypto) diff --git a/ssl/pqueue/pqueue_test.c b/ssl/pqueue/pqueue_test.c index 112afedf..16a9ad87 100644 --- a/ssl/pqueue/pqueue_test.c +++ b/ssl/pqueue/pqueue_test.c @@ -16,6 +16,7 @@ #include #include +#include static int trivial() { @@ -79,6 +80,8 @@ static int fixed_random() { } int main(void) { + SSL_library_init(); + if (!trivial() || !fixed_random()) { return 1; } diff --git a/ssl/ssl_algs.c b/ssl/ssl_algs.c index 8f7ede69..9308d40e 100644 --- a/ssl/ssl_algs.c +++ b/ssl/ssl_algs.c @@ -56,11 +56,13 @@ #include "ssl_locl.h" +#include extern const ERR_STRING_DATA SSL_error_string_data[]; int SSL_library_init(void) { + CRYPTO_library_init(); ERR_load_crypto_strings(); ERR_load_strings(SSL_error_string_data); ssl_load_ciphers();