static int wrap_nettle_cipher_exists(gnutls_cipher_algorithm_t algo) { switch (algo) { case GNUTLS_CIPHER_AES_128_GCM: case GNUTLS_CIPHER_AES_256_GCM: case GNUTLS_CIPHER_AES_128_CBC: case GNUTLS_CIPHER_AES_192_CBC: case GNUTLS_CIPHER_AES_256_CBC: case GNUTLS_CIPHER_3DES_CBC: return 1; case GNUTLS_CIPHER_CAMELLIA_128_GCM: case GNUTLS_CIPHER_CAMELLIA_256_GCM: case GNUTLS_CIPHER_CAMELLIA_128_CBC: case GNUTLS_CIPHER_CAMELLIA_192_CBC: case GNUTLS_CIPHER_CAMELLIA_256_CBC: case GNUTLS_CIPHER_DES_CBC: case GNUTLS_CIPHER_ARCFOUR_128: case GNUTLS_CIPHER_SALSA20_256: case GNUTLS_CIPHER_ESTREAM_SALSA20_256: case GNUTLS_CIPHER_ARCFOUR_40: case GNUTLS_CIPHER_RC2_40_CBC: if (_gnutls_fips_mode_enabled() != 0) return 0; else return 1; default: return 0; } }
int _gnutls_rnd_preinit(void) { int ret; #if defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) # warning Insecure PRNG is enabled ret = gnutls_crypto_rnd_register(100, &_gnutls_fuzz_rnd_ops); if (ret < 0) return ret; #elif defined(ENABLE_FIPS140) /* The FIPS140 random generator is only enabled when we are compiled * with FIPS support, _and_ the system requires FIPS140. */ if (_gnutls_fips_mode_enabled() == 1) { ret = gnutls_crypto_rnd_register(100, &_gnutls_fips_rnd_ops); if (ret < 0) return ret; } #endif ret = _rnd_system_entropy_init(); if (ret < 0) { gnutls_assert(); return GNUTLS_E_RANDOM_FAILED; } return 0; }
/** * gnutls_fips140_mode_enabled: * * Checks whether this library is in FIPS140 mode. * * Returns: return non-zero if true or zero if false. * * Since: 3.3.0 **/ int gnutls_fips140_mode_enabled(void) { #ifdef ENABLE_FIPS140 int ret = _gnutls_fips_mode_enabled(); if (ret == 1) return ret; #endif return 0; }
/* This generates p,q params using the B.3.2.2 algorithm in FIPS 186-4. * * The hash function used is SHA384. * The exponent e used is the value in pub->e. */ int rsa_generate_fips186_4_keypair(struct rsa_public_key *pub, struct rsa_private_key *key, void *random_ctx, nettle_random_func * random, void *progress_ctx, nettle_progress_func * progress, unsigned *rseed_size, void *rseed, /* Desired size of modulo, in bits */ unsigned n_size) { uint8_t seed[128]; unsigned seed_length; int ret; if (_gnutls_fips_mode_enabled() != 0) { if (n_size != 2048 && n_size != 3072) { _gnutls_debug_log("The size of a prime can only be 2048 or 3072\n"); return 0; } } seed_length = SEED_LENGTH(n_size); if (seed_length > sizeof(seed)) return 0; random(random_ctx, seed_length, seed); if (rseed && rseed_size) { if (*rseed_size < seed_length) { return 0; } memcpy(rseed, seed, seed_length); *rseed_size = seed_length; } ret = _rsa_generate_fips186_4_keypair(pub, key, seed_length, seed, progress_ctx, progress, n_size); gnutls_memset(seed, 0, seed_length); return ret; }
/* Returns true(non-zero) or false(0) if the * provided cipher exists */ int _gnutls_cipher_exists(gnutls_cipher_algorithm_t cipher) { const gnutls_crypto_cipher_st *cc; int ret; /* All the other ciphers are disabled on the back-end library. * The NULL needs to be detected here as it is not a cipher * that is provided by the back-end. */ if (cipher == GNUTLS_CIPHER_NULL) { if (_gnutls_fips_mode_enabled() == 0) return 1; else return 0; } cc = _gnutls_get_crypto_cipher(cipher); if (cc != NULL) return 1; ret = _gnutls_cipher_ops.exists(cipher); return ret; }
/** * gnutls_session_ticket_key_generate: * @key: is a pointer to a #gnutls_datum_t which will contain a newly * created key. * * Generate a random key to encrypt security parameters within * SessionTicket. * * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, or an * error code. * * Since: 2.10.0 **/ int gnutls_session_ticket_key_generate(gnutls_datum_t * key) { if (_gnutls_fips_mode_enabled()) { int ret; /* in FIPS140-2 mode gnutls_key_generate imposes * some limits on allowed key size, thus it is not * used. These limits do not affect this function as * it does not generate a "key" but rather key material * that includes nonces and other stuff. */ key->data = gnutls_malloc(TICKET_MASTER_KEY_SIZE); if (key->data == NULL) return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR); key->size = TICKET_MASTER_KEY_SIZE; ret = gnutls_rnd(GNUTLS_RND_RANDOM, key->data, key->size); if (ret < 0) { gnutls_free(key->data); return ret; } return 0; } else { return gnutls_key_generate(key, TICKET_MASTER_KEY_SIZE); } }
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; }
/* This generates p,q params using the B.3.2.2 algorithm in FIPS 186-4. * * The hash function used is SHA384. * The exponent e used is the value in pub->e. */ int _rsa_generate_fips186_4_keypair(struct rsa_public_key *pub, struct rsa_private_key *key, unsigned seed_length, uint8_t * seed, void *progress_ctx, nettle_progress_func * progress, /* Desired size of modulo, in bits */ unsigned n_size) { mpz_t t, r, p1, q1, lcm; int ret; struct dss_params_validation_seeds cert; unsigned l = n_size / 2; if (_gnutls_fips_mode_enabled() != 0) { if (n_size == 2048) { if (seed_length != 14 * 2) { _gnutls_debug_log("Seed length must be 28 bytes (it is %d)\n", seed_length); return 0; } } else if (n_size == 3072) { if (seed_length != 16 * 2) { _gnutls_debug_log("Seed length must be 32 bytes (it is %d)\n", seed_length); return 0; } } else { _gnutls_debug_log("Unsupported size for modulus\n"); return 0; } } if (!mpz_tstbit(pub->e, 0)) { _gnutls_debug_log("Unacceptable e (it is even)\n"); return 0; } if (mpz_cmp_ui(pub->e, 65536) <= 0) { _gnutls_debug_log("Unacceptable e\n"); return 0; } mpz_init(p1); mpz_init(q1); mpz_init(lcm); mpz_init(t); mpz_init(r); mpz_set_ui(t, 1); mpz_mul_2exp(t, t, 256); if (mpz_cmp(pub->e, t) >= 0) { ret = 0; goto cleanup; } cert.pseed_length = sizeof(cert.pseed); ret = rsa_provable_prime(key->p, &cert.pseed_length, cert.pseed, l, seed_length, seed, pub->e, progress_ctx, progress); if (ret == 0) { goto cleanup; } mpz_set_ui(r, 1); mpz_mul_2exp(r, r, (l) - 100); do { cert.qseed_length = sizeof(cert.qseed); ret = rsa_provable_prime(key->q, &cert.qseed_length, cert.qseed, l, cert.pseed_length, cert.pseed, pub->e, progress_ctx, progress); if (ret == 0) { goto cleanup; } cert.pseed_length = cert.qseed_length; memcpy(cert.pseed, cert.qseed, cert.qseed_length); if (mpz_cmp(key->p, key->q) > 0) mpz_sub(t, key->p, key->q); else mpz_sub(t, key->q, key->p); } while (mpz_cmp(t, r) <= 0); memset(&cert, 0, sizeof(cert)); mpz_mul(pub->n, key->p, key->q); assert(mpz_sizeinbase(pub->n, 2) == n_size); /* c = q^{-1} (mod p) */ assert(mpz_invert(key->c, key->q, key->p) != 0); mpz_sub_ui(p1, key->p, 1); mpz_sub_ui(q1, key->q, 1); mpz_lcm(lcm, p1, q1); if (mpz_invert(key->d, pub->e, lcm) == 0) { ret = 0; goto cleanup; } /* Done! Almost, we must compute the auxillary private values. */ /* a = d % (p-1) */ mpz_fdiv_r(key->a, key->d, p1); /* b = d % (q-1) */ mpz_fdiv_r(key->b, key->d, q1); /* c was computed earlier */ pub->size = key->size = (n_size + 7) / 8; assert(pub->size >= RSA_MINIMUM_N_OCTETS); ret = 1; cleanup: mpz_clear(p1); mpz_clear(q1); mpz_clear(lcm); mpz_clear(t); mpz_clear(r); 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; }
static int wrap_nettle_cipher_setkey(void *_ctx, const void *key, size_t keysize) { struct nettle_cipher_ctx *ctx = _ctx; uint8_t des_key[DES3_KEY_SIZE]; switch (ctx->algo) { case GNUTLS_CIPHER_AES_128_GCM: case GNUTLS_CIPHER_AES_256_GCM: gcm_aes_set_key(&ctx->ctx.aes_gcm, keysize, key); break; case GNUTLS_CIPHER_AES_128_CBC: case GNUTLS_CIPHER_AES_192_CBC: case GNUTLS_CIPHER_AES_256_CBC: if (ctx->enc) aes_set_encrypt_key(ctx->ctx_ptr, keysize, key); else aes_set_decrypt_key(ctx->ctx_ptr, keysize, key); break; case GNUTLS_CIPHER_CAMELLIA_128_CBC: case GNUTLS_CIPHER_CAMELLIA_192_CBC: case GNUTLS_CIPHER_CAMELLIA_256_CBC: if (ctx->enc) camellia_set_encrypt_key(ctx->ctx_ptr, keysize, key); else camellia_set_decrypt_key(ctx->ctx_ptr, keysize, key); break; case GNUTLS_CIPHER_3DES_CBC: if (keysize != DES3_KEY_SIZE) { gnutls_assert(); return GNUTLS_E_INTERNAL_ERROR; } des_fix_parity(keysize, des_key, key); if (des3_set_key(ctx->ctx_ptr, des_key) != 1) { gnutls_assert(); } zeroize_temp_key(des_key, sizeof(des_key)); break; case GNUTLS_CIPHER_CAMELLIA_128_GCM: case GNUTLS_CIPHER_CAMELLIA_256_GCM: if (_gnutls_fips_mode_enabled() != 0) return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST); _gcm_camellia_set_key(&ctx->ctx.camellia_gcm, keysize, key); break; case GNUTLS_CIPHER_DES_CBC: if (_gnutls_fips_mode_enabled() != 0) return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST); if (keysize != DES_KEY_SIZE) { gnutls_assert(); return GNUTLS_E_INTERNAL_ERROR; } des_fix_parity(keysize, des_key, key); if (des_set_key(ctx->ctx_ptr, des_key) != 1) { gnutls_assert(); return GNUTLS_E_INTERNAL_ERROR; } zeroize_temp_key(des_key, sizeof(des_key)); break; case GNUTLS_CIPHER_ARCFOUR_128: case GNUTLS_CIPHER_ARCFOUR_40: if (_gnutls_fips_mode_enabled() != 0) return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST); arcfour_set_key(ctx->ctx_ptr, keysize, key); break; case GNUTLS_CIPHER_SALSA20_256: case GNUTLS_CIPHER_ESTREAM_SALSA20_256: if (_gnutls_fips_mode_enabled() != 0) return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST); salsa20_set_key(ctx->ctx_ptr, keysize, key); break; case GNUTLS_CIPHER_RC2_40_CBC: if (_gnutls_fips_mode_enabled() != 0) return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST); arctwo_set_key(ctx->ctx_ptr, keysize, key); break; default: gnutls_assert(); return GNUTLS_E_INVALID_REQUEST; } return 0; }
static int wrap_nettle_cipher_init(gnutls_cipher_algorithm_t algo, void **_ctx, int enc) { struct nettle_cipher_ctx *ctx; ctx = gnutls_calloc(1, sizeof(*ctx)); if (ctx == NULL) { gnutls_assert(); return GNUTLS_E_MEMORY_ERROR; } ctx->algo = algo; ctx->enc = enc; switch (algo) { case GNUTLS_CIPHER_AES_128_GCM: case GNUTLS_CIPHER_AES_256_GCM: ctx->encrypt = _aes_gcm_encrypt; ctx->decrypt = _aes_gcm_decrypt; ctx->i_encrypt = (nettle_crypt_func *) aes_encrypt; ctx->auth = (auth_func) gcm_aes_update; ctx->tag = (tag_func) gcm_aes_digest; ctx->ctx_ptr = &ctx->ctx.aes_gcm; ctx->block_size = AES_BLOCK_SIZE; break; case GNUTLS_CIPHER_AES_128_CBC: case GNUTLS_CIPHER_AES_192_CBC: case GNUTLS_CIPHER_AES_256_CBC: ctx->encrypt = cbc_encrypt; ctx->decrypt = cbc_decrypt; ctx->i_encrypt = (nettle_crypt_func *) aes_encrypt; ctx->i_decrypt = (nettle_crypt_func *) aes_decrypt; ctx->ctx_ptr = &ctx->ctx.aes; ctx->block_size = AES_BLOCK_SIZE; break; case GNUTLS_CIPHER_3DES_CBC: ctx->encrypt = cbc_encrypt; ctx->decrypt = cbc_decrypt; ctx->i_encrypt = (nettle_crypt_func *) des3_encrypt; ctx->i_decrypt = (nettle_crypt_func *) des3_decrypt; ctx->ctx_ptr = &ctx->ctx.des3; ctx->block_size = DES3_BLOCK_SIZE; break; case GNUTLS_CIPHER_CAMELLIA_128_GCM: case GNUTLS_CIPHER_CAMELLIA_256_GCM: if (_gnutls_fips_mode_enabled() != 0) return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST); ctx->encrypt = _camellia_gcm_encrypt; ctx->decrypt = _camellia_gcm_decrypt; ctx->i_encrypt = (nettle_crypt_func *) camellia_crypt; ctx->auth = (auth_func) _gcm_camellia_update; ctx->tag = (tag_func) _gcm_camellia_digest; ctx->ctx_ptr = &ctx->ctx.camellia_gcm; ctx->block_size = CAMELLIA_BLOCK_SIZE; break; case GNUTLS_CIPHER_CAMELLIA_128_CBC: case GNUTLS_CIPHER_CAMELLIA_192_CBC: case GNUTLS_CIPHER_CAMELLIA_256_CBC: if (_gnutls_fips_mode_enabled() != 0) return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST); ctx->encrypt = cbc_encrypt; ctx->decrypt = cbc_decrypt; ctx->i_encrypt = (nettle_crypt_func *) camellia_crypt; ctx->i_decrypt = (nettle_crypt_func *) camellia_crypt; ctx->ctx_ptr = &ctx->ctx.camellia; ctx->block_size = CAMELLIA_BLOCK_SIZE; break; case GNUTLS_CIPHER_DES_CBC: if (_gnutls_fips_mode_enabled() != 0) return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST); ctx->encrypt = cbc_encrypt; ctx->decrypt = cbc_decrypt; ctx->i_encrypt = (nettle_crypt_func *) des_encrypt; ctx->i_decrypt = (nettle_crypt_func *) des_decrypt; ctx->ctx_ptr = &ctx->ctx.des; ctx->block_size = DES_BLOCK_SIZE; break; case GNUTLS_CIPHER_ARCFOUR_128: case GNUTLS_CIPHER_ARCFOUR_40: if (_gnutls_fips_mode_enabled() != 0) return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST); ctx->encrypt = stream_encrypt; ctx->decrypt = stream_encrypt; ctx->i_encrypt = (nettle_crypt_func *) arcfour_crypt; ctx->i_decrypt = (nettle_crypt_func *) arcfour_crypt; ctx->ctx_ptr = &ctx->ctx.arcfour; ctx->block_size = 1; break; case GNUTLS_CIPHER_SALSA20_256: if (_gnutls_fips_mode_enabled() != 0) return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST); ctx->encrypt = stream_encrypt; ctx->decrypt = stream_encrypt; ctx->i_encrypt = (nettle_crypt_func *) salsa20_crypt; ctx->i_decrypt = (nettle_crypt_func *) salsa20_crypt; ctx->ctx_ptr = &ctx->ctx.salsa20; ctx->block_size = 1; break; case GNUTLS_CIPHER_ESTREAM_SALSA20_256: if (_gnutls_fips_mode_enabled() != 0) return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST); ctx->encrypt = stream_encrypt; ctx->decrypt = stream_encrypt; ctx->i_encrypt = (nettle_crypt_func *) salsa20r12_crypt; ctx->i_decrypt = (nettle_crypt_func *) salsa20r12_crypt; ctx->ctx_ptr = &ctx->ctx.salsa20; ctx->block_size = 1; break; case GNUTLS_CIPHER_RC2_40_CBC: if (_gnutls_fips_mode_enabled() != 0) return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST); ctx->encrypt = cbc_encrypt; ctx->decrypt = cbc_decrypt; ctx->i_encrypt = (nettle_crypt_func *) arctwo_encrypt; ctx->i_decrypt = (nettle_crypt_func *) arctwo_decrypt; ctx->ctx_ptr = &ctx->ctx.arctwo; ctx->block_size = ARCTWO_BLOCK_SIZE; break; default: gnutls_assert(); gnutls_free(ctx); return GNUTLS_E_INVALID_REQUEST; } *_ctx = ctx; return 0; }