static int wrap_nettle_rnd_init(void **ctx) { int ret; struct event_st event; uint8_t nonce_key[NONCE_KEY_SIZE]; memset(&rnd_ctx, 0, sizeof(rnd_ctx)); ret = gnutls_mutex_init(&nonce_ctx.mutex); if (ret < 0) { gnutls_assert(); return ret; } ret = gnutls_mutex_init(&rnd_ctx.mutex); if (ret < 0) { gnutls_assert(); return ret; } /* initialize the main RNG */ yarrow256_init(&rnd_ctx.yctx, SOURCES, rnd_ctx.ysources); _rnd_get_event(&event); rnd_ctx.forkid = _gnutls_get_forkid(); ret = do_device_source(&rnd_ctx, 1, &event); if (ret < 0) { gnutls_assert(); return ret; } ret = do_trivia_source(&rnd_ctx, 1, &event); if (ret < 0) { gnutls_assert(); return ret; } yarrow256_slow_reseed(&rnd_ctx.yctx); /* initialize the nonce RNG */ ret = _rnd_get_system_entropy(nonce_key, sizeof(nonce_key)); if (ret < 0) return gnutls_assert_val(ret); ret = nonce_rng_init(&nonce_ctx, nonce_key, sizeof(nonce_key), 1); if (ret < 0) return gnutls_assert_val(ret); return 0; }
/** * gnutls_pkcs11_privkey_init: * @key: A pointer to the type to be initialized * * This function will initialize an private key structure. This * structure can be used for accessing an underlying PKCS#11 object. * * In versions of GnuTLS later than 3.5.11 the object is protected * using locks and a single %gnutls_pkcs11_privkey_t can be re-used * by many threads. However, for performance it is recommended to utilize * one object per key per thread. * * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a * negative error value. **/ int gnutls_pkcs11_privkey_init(gnutls_pkcs11_privkey_t * key) { int ret; FAIL_IF_LIB_ERROR; *key = gnutls_calloc(1, sizeof(struct gnutls_pkcs11_privkey_st)); if (*key == NULL) { gnutls_assert(); return GNUTLS_E_MEMORY_ERROR; } (*key)->uinfo = p11_kit_uri_new(); if ((*key)->uinfo == NULL) { free(*key); gnutls_assert(); return GNUTLS_E_MEMORY_ERROR; } ret = gnutls_mutex_init(&(*key)->mutex); if (ret < 0) { gnutls_assert(); p11_kit_uri_free((*key)->uinfo); free(*key); return GNUTLS_E_LOCKING_ERROR; } return 0; }
static int wrap_nettle_rnd_init (void **ctx) { int ret; ret = gnutls_mutex_init (&rnd_mutex); if (ret < 0) { gnutls_assert (); return ret; } yarrow256_init (&yctx, SOURCES, ysources); ret = do_device_source (1); if (ret < 0) { gnutls_assert (); return ret; } ret = do_trivia_source (1); if (ret < 0) { gnutls_assert (); return ret; } yarrow256_slow_reseed (&yctx); return 0; }
/* Initialize this random subsystem. */ static int _rngfips_init(void **_ctx) { /* Basic initialization is required to initialize mutexes and do a few checks on the implementation. */ struct fips_ctx *ctx; int ret; ret = _rnd_system_entropy_init(); if (ret < 0) return gnutls_assert_val(ret); ctx = gnutls_calloc(1, sizeof(*ctx)); if (ctx == NULL) return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR); ret = gnutls_mutex_init(&rnd_mutex); if (ret < 0) return gnutls_assert_val(ret); ret = _rngfips_ctx_init(ctx); if (ret < 0) return gnutls_assert_val(ret); *_ctx = ctx; return 0; }
static int _gnutls_global_init(unsigned constructor) { int ret = 0, res; int level; const char* e; if (!constructor) { GNUTLS_STATIC_MUTEX_LOCK(global_init_mutex); } _gnutls_init++; if (_gnutls_init > 1) { if (_gnutls_init == 2 && _gnutls_init_ret == 0) { /* some applications may close the urandom fd * before calling gnutls_global_init(). in that * case reopen it */ ret = _gnutls_rnd_check(); if (ret < 0) { gnutls_assert(); goto out; } } ret = _gnutls_init_ret; goto out; } _gnutls_switch_lib_state(LIB_STATE_INIT); e = secure_getenv("GNUTLS_DEBUG_LEVEL"); if (e != NULL) { level = atoi(e); gnutls_global_set_log_level(level); if (_gnutls_log_func == NULL) gnutls_global_set_log_function(default_log_func); _gnutls_debug_log("Enabled GnuTLS "VERSION" logging...\n"); } #ifdef HAVE_DCGETTEXT bindtextdomain(PACKAGE, LOCALEDIR); #endif res = gnutls_crypto_init(); if (res != 0) { gnutls_assert(); ret = GNUTLS_E_CRYPTO_INIT_FAILED; goto out; } ret = _gnutls_system_key_init(); if (ret != 0) { gnutls_assert(); } /* initialize ASN.1 parser */ if (asn1_check_version(GNUTLS_MIN_LIBTASN1_VERSION) == NULL) { gnutls_assert(); _gnutls_debug_log ("Checking for libtasn1 failed: %s < %s\n", asn1_check_version(NULL), GNUTLS_MIN_LIBTASN1_VERSION); ret = GNUTLS_E_INCOMPATIBLE_LIBTASN1_LIBRARY; goto out; } _gnutls_pkix1_asn = ASN1_TYPE_EMPTY; res = asn1_array2tree(pkix_asn1_tab, &_gnutls_pkix1_asn, NULL); if (res != ASN1_SUCCESS) { gnutls_assert(); ret = _gnutls_asn2err(res); goto out; } res = asn1_array2tree(gnutls_asn1_tab, &_gnutls_gnutls_asn, NULL); if (res != ASN1_SUCCESS) { gnutls_assert(); ret = _gnutls_asn2err(res); goto out; } /* Initialize the random generator */ ret = _gnutls_rnd_preinit(); if (ret < 0) { gnutls_assert(); goto out; } /* Initialize the default TLS extensions */ ret = _gnutls_ext_init(); if (ret < 0) { gnutls_assert(); goto out; } ret = gnutls_mutex_init(&_gnutls_file_mutex); if (ret < 0) { gnutls_assert(); goto out; } ret = gnutls_mutex_init(&_gnutls_pkcs11_mutex); if (ret < 0) { gnutls_assert(); goto out; } ret = gnutls_system_global_init(); if (ret < 0) { gnutls_assert(); goto out; } #ifndef _WIN32 ret = _gnutls_register_fork_handler(); if (ret < 0) { gnutls_assert(); goto out; } #endif #ifdef ENABLE_FIPS140 res = _gnutls_fips_mode_enabled(); /* res == 1 -> fips140-2 mode enabled * res == 2 -> only self checks performed - but no failure * res == not in fips140 mode */ if (res != 0) { _gnutls_debug_log("FIPS140-2 mode: %d\n", res); _gnutls_priority_update_fips(); /* first round of self checks, these are done on the * nettle algorithms which are used internally */ ret = _gnutls_fips_perform_self_checks1(); if (res != 2) { if (ret < 0) { gnutls_assert(); goto out; } } } #endif _gnutls_register_accel_crypto(); _gnutls_cryptodev_init(); _gnutls_load_system_priorities(); #ifdef ENABLE_FIPS140 /* These self tests are performed on the overriden algorithms * (e.g., AESNI overriden AES). They are after _gnutls_register_accel_crypto() * intentionally */ if (res != 0) { ret = _gnutls_fips_perform_self_checks2(); if (res != 2) { if (ret < 0) { gnutls_assert(); goto out; } } _gnutls_fips_mode_reset_zombie(); } #endif _gnutls_switch_lib_state(LIB_STATE_OPERATIONAL); ret = 0; out: _gnutls_init_ret = ret; if (!constructor) { GNUTLS_STATIC_MUTEX_UNLOCK(global_init_mutex); } return ret; }
/** * gnutls_global_init: * * This function performs any required precalculations, detects * the supported CPU capabilities and initializes the underlying * cryptographic backend. In order to free any resources * taken by this call you should gnutls_global_deinit() * when gnutls usage is no longer needed. * * This function increments a global counter, so that * gnutls_global_deinit() only releases resources when it has been * called as many times as gnutls_global_init(). This is useful when * GnuTLS is used by more than one library in an application. This * function can be called many times, but will only do something the * first time. * * Since GnuTLS 3.3.0 this function is only required in systems that * do not support library constructors and static linking. This * function also became thread safe. * * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, * otherwise a negative error code is returned. **/ int gnutls_global_init(void) { int ret = 0, res; int level; const char* e; GNUTLS_STATIC_MUTEX_LOCK(global_init_mutex); _gnutls_init++; if (_gnutls_init > 1) { ret = 0; goto out; } _gnutls_switch_lib_state(LIB_STATE_INIT); e = getenv("GNUTLS_DEBUG_LEVEL"); if (e != NULL) { level = atoi(e); gnutls_global_set_log_level(level); if (_gnutls_log_func == NULL) gnutls_global_set_log_function(default_log_func); _gnutls_debug_log("Enabled GnuTLS logging...\n"); } bindtextdomain(PACKAGE, LOCALEDIR); res = gnutls_crypto_init(); if (res != 0) { gnutls_assert(); ret = GNUTLS_E_CRYPTO_INIT_FAILED; goto out; } /* initialize ASN.1 parser */ if (asn1_check_version(GNUTLS_MIN_LIBTASN1_VERSION) == NULL) { gnutls_assert(); _gnutls_debug_log ("Checking for libtasn1 failed: %s < %s\n", asn1_check_version(NULL), GNUTLS_MIN_LIBTASN1_VERSION); ret = GNUTLS_E_INCOMPATIBLE_LIBTASN1_LIBRARY; goto out; } res = asn1_array2tree(pkix_asn1_tab, &_gnutls_pkix1_asn, NULL); if (res != ASN1_SUCCESS) { ret = _gnutls_asn2err(res); goto out; } res = asn1_array2tree(gnutls_asn1_tab, &_gnutls_gnutls_asn, NULL); if (res != ASN1_SUCCESS) { ret = _gnutls_asn2err(res); goto out; } /* Initialize the random generator */ ret = _gnutls_rnd_init(); if (ret < 0) { gnutls_assert(); goto out; } /* Initialize the default TLS extensions */ ret = _gnutls_ext_init(); if (ret < 0) { gnutls_assert(); goto out; } ret = gnutls_mutex_init(&_gnutls_file_mutex); if (ret < 0) { gnutls_assert(); goto out; } ret = gnutls_mutex_init(&_gnutls_pkcs11_mutex); if (ret < 0) { gnutls_assert(); goto out; } ret = gnutls_system_global_init(); if (ret < 0) { gnutls_assert(); goto out; } _gnutls_register_accel_crypto(); _gnutls_cryptodev_init(); #ifdef ENABLE_FIPS140 /* Perform FIPS140 checks last, so that all modules * have been loaded */ res = _gnutls_fips_mode_enabled(); /* res == 1 -> fips140-2 mode enabled * res == 2 -> only self checks performed - but no failure * res == not in fips140 mode */ if (res != 0) { _gnutls_priority_update_fips(); ret = _gnutls_fips_perform_self_checks(); if (res != 2) { if (ret < 0) { gnutls_assert(); goto out; } } } #endif _gnutls_switch_lib_state(LIB_STATE_OPERATIONAL); ret = 0; out: GNUTLS_STATIC_MUTEX_UNLOCK(global_init_mutex); return ret; }
/** * gnutls_global_init: * * This function performs any required precalculations, detects * the supported CPU capabilities and initializes the underlying * cryptographic backend. In order to free any resources * taken by this call you should gnutls_global_deinit() * when gnutls usage is no longer needed. * * This function increments a global counter, so that * gnutls_global_deinit() only releases resources when it has been * called as many times as gnutls_global_init(). This is useful when * GnuTLS is used by more than one library in an application. This * function can be called many times, but will only do something the * first time. * * Note! This function is not thread safe. If two threads call this * function simultaneously, they can cause a race between checking * the global counter and incrementing it, causing both threads to * execute the library initialization code. That would lead to a * memory leak. To handle this, your application could invoke this * function after aquiring a thread mutex. To ignore the potential * memory leak is also an option. * * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, * otherwise a negative error code is returned. **/ int gnutls_global_init (void) { int result = 0; int res; if (_gnutls_init++) goto out; if (gl_sockets_startup (SOCKETS_1_1)) return gnutls_assert_val(GNUTLS_E_FILE_ERROR); bindtextdomain (PACKAGE, LOCALEDIR); res = gnutls_crypto_init (); if (res != 0) { gnutls_assert (); return GNUTLS_E_CRYPTO_INIT_FAILED; } _gnutls_register_accel_crypto(); /* initialize ASN.1 parser * This should not deal with files in the final * version. */ if (asn1_check_version (GNUTLS_MIN_LIBTASN1_VERSION) == NULL) { gnutls_assert (); _gnutls_debug_log ("Checking for libtasn1 failed: %s < %s\n", asn1_check_version (NULL), GNUTLS_MIN_LIBTASN1_VERSION); return GNUTLS_E_INCOMPATIBLE_LIBTASN1_LIBRARY; } res = asn1_array2tree (pkix_asn1_tab, &_gnutls_pkix1_asn, NULL); if (res != ASN1_SUCCESS) { result = _gnutls_asn2err (res); goto out; } res = asn1_array2tree (gnutls_asn1_tab, &_gnutls_gnutls_asn, NULL); if (res != ASN1_SUCCESS) { result = _gnutls_asn2err (res); goto out; } /* Initialize the random generator */ result = _gnutls_rnd_init (); if (result < 0) { gnutls_assert (); goto out; } /* Initialize the default TLS extensions */ result = _gnutls_ext_init (); if (result < 0) { gnutls_assert (); goto out; } result = gnutls_mutex_init(&_gnutls_file_mutex); if (result < 0) { gnutls_assert(); goto out; } result = gnutls_system_global_init (); if (result < 0) { gnutls_assert (); goto out; } #ifdef ENABLE_PKCS11 gnutls_pkcs11_init (GNUTLS_PKCS11_FLAG_AUTO, NULL); #endif _gnutls_cryptodev_init (); out: return result; }