From: Nikos Mavrogiannopoulos Date: Fri, 22 Nov 2013 10:49:43 +0000 (+0100) Subject: In FIPS140-2 mode disable non-conformant ciphers, MAC and hash algorithms. X-Git-Tag: gnutls_3_3_0pre0~520^2~59 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=f2730cc5e8c4e099c1fb701032aff41dacbb7f8a;p=thirdparty%2Fgnutls.git In FIPS140-2 mode disable non-conformant ciphers, MAC and hash algorithms. --- diff --git a/lib/algorithms/ciphers.c b/lib/algorithms/ciphers.c index a0d372818b..a99273fe79 100644 --- a/lib/algorithms/ciphers.c +++ b/lib/algorithms/ciphers.c @@ -93,7 +93,15 @@ static const cipher_entry_st algorithms[] = { CIPHER_BLOCK, 16, 16, 0}, #endif + +#ifndef ENABLE_FIPS140 + /* All the other ciphers are disabled on the back-end library. + * This needs to be disabled here as it is merely a placeholder + * rather than an actual cipher. + */ {"NULL", GNUTLS_CIPHER_NULL, 1, 0, CIPHER_STREAM, 0, 0, 0}, +#endif + {0, 0, 0, 0, 0, 0, 0} }; @@ -226,7 +234,8 @@ gnutls_cipher_algorithm_t gnutls_cipher_get_id(const char *name) GNUTLS_CIPHER_LOOP( if (strcasecmp(p->name, name) == 0) { - ret = p->id; + if (p->id == GNUTLS_CIPHER_NULL || _gnutls_cipher_exists(p->id)) + ret = p->id; break; } ); @@ -257,7 +266,7 @@ const gnutls_cipher_algorithm_t *gnutls_cipher_list(void) int i = 0; GNUTLS_CIPHER_LOOP( - if (_gnutls_cipher_exists(p->id)) + if (p->id == GNUTLS_CIPHER_NULL || _gnutls_cipher_exists(p->id)) supported_ciphers[i++] = p->id; ); supported_ciphers[i++] = 0; diff --git a/lib/algorithms/ciphersuites.c b/lib/algorithms/ciphersuites.c index 478dd61f83..763f7ff69c 100644 --- a/lib/algorithms/ciphersuites.c +++ b/lib/algorithms/ciphersuites.c @@ -298,6 +298,9 @@ typedef struct { #define CIPHER_SUITES_COUNT (sizeof(cs_algorithms)/sizeof(gnutls_cipher_suite_entry)-1) +/* The following is a potential list of ciphersuites. For the options to be + * available, the ciphers and MACs must be available to gnutls as well. + */ static const gnutls_cipher_suite_entry cs_algorithms[] = { /* RSA-NULL */ ENTRY(GNUTLS_RSA_NULL_MD5, diff --git a/lib/algorithms/mac.c b/lib/algorithms/mac.c index 595eab348e..e691a4ef3a 100644 --- a/lib/algorithms/mac.c +++ b/lib/algorithms/mac.c @@ -132,7 +132,8 @@ gnutls_digest_algorithm_t gnutls_digest_get_id(const char *name) GNUTLS_HASH_LOOP( if (p->oid != NULL && strcasecmp(p->name, name) == 0) { - ret = p->id; + if (_gnutls_digest_exists(p->id)) + ret = p->id; break; } ); @@ -156,7 +157,8 @@ gnutls_mac_algorithm_t gnutls_mac_get_id(const char *name) GNUTLS_HASH_LOOP( if (strcasecmp(p->name, name) == 0) { - ret = p->id; + if (p->placeholder != 0 || _gnutls_mac_exists(p->id)) + ret = p->id; break; } ); diff --git a/lib/gnutls_hash_int.c b/lib/gnutls_hash_int.c index ddeff10bdb..4e841ca8f8 100644 --- a/lib/gnutls_hash_int.c +++ b/lib/gnutls_hash_int.c @@ -68,6 +68,20 @@ int _gnutls_hash_init(digest_hd_st * dig, const mac_entry_st * e) return 0; } +/* Returns true(non-zero) or false(0) if the + * provided hash exists + */ +int _gnutls_digest_exists(gnutls_digest_algorithm_t algo) +{ + const gnutls_crypto_digest_st *cc = NULL; + + cc = _gnutls_get_crypto_digest(algo); + if (cc != NULL) + return 1; + + return _gnutls_digest_ops.exists(algo); +} + void _gnutls_hash_deinit(digest_hd_st * handle, void *digest) { if (handle->handle == NULL) { diff --git a/lib/gnutls_hash_int.h b/lib/gnutls_hash_int.h index 0377900a92..75061c848c 100644 --- a/lib/gnutls_hash_int.h +++ b/lib/gnutls_hash_int.h @@ -67,6 +67,8 @@ typedef struct { } mac_hd_st; /* basic functions */ +int _gnutls_digest_exists(gnutls_digest_algorithm_t algo); + int _gnutls_mac_exists(gnutls_mac_algorithm_t algorithm); int _gnutls_mac_init(mac_hd_st *, const mac_entry_st * e, const void *key, int keylen); diff --git a/lib/gnutls_priority.c b/lib/gnutls_priority.c index a02093880b..a4c498bc7c 100644 --- a/lib/gnutls_priority.c +++ b/lib/gnutls_priority.c @@ -336,6 +336,7 @@ static const int kx_priority_secure[] = { 0 }; +#ifndef ENABLE_FIPS140 /* If GCM and AES acceleration is available then prefer * them over anything else. */ @@ -366,6 +367,25 @@ static const int cipher_priority_normal[] = { GNUTLS_CIPHER_ARCFOUR_128, 0 }; +#else +static const int cipher_priority_performance[] = { + GNUTLS_CIPHER_AES_128_GCM, + GNUTLS_CIPHER_AES_256_GCM, + GNUTLS_CIPHER_AES_128_CBC, + GNUTLS_CIPHER_AES_256_CBC, + GNUTLS_CIPHER_3DES_CBC, + 0 +}; + +static const int cipher_priority_normal[] = { + GNUTLS_CIPHER_AES_128_GCM, + GNUTLS_CIPHER_AES_256_GCM, + GNUTLS_CIPHER_AES_128_CBC, + GNUTLS_CIPHER_AES_256_CBC, + GNUTLS_CIPHER_3DES_CBC, + 0 +}; +#endif static const int cipher_priority_suiteb128[] = { GNUTLS_CIPHER_AES_128_GCM, @@ -463,7 +483,9 @@ static const int mac_priority_normal[] = { GNUTLS_MAC_SHA256, GNUTLS_MAC_SHA384, GNUTLS_MAC_AEAD, +#ifndef ENABLE_FIPS140 GNUTLS_MAC_MD5, +#endif 0 }; diff --git a/lib/nettle/cipher.c b/lib/nettle/cipher.c index 4d6692043b..e50f4726e6 100644 --- a/lib/nettle/cipher.c +++ b/lib/nettle/cipher.c @@ -126,21 +126,23 @@ 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: +#ifndef ENABLE_FIPS140 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_AES_128_CBC: - case GNUTLS_CIPHER_AES_192_CBC: - case GNUTLS_CIPHER_AES_256_CBC: - case GNUTLS_CIPHER_3DES_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: +#endif return 1; default: return 0; @@ -173,6 +175,25 @@ wrap_nettle_cipher_init(gnutls_cipher_algorithm_t algo, void **_ctx, 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; +#ifndef ENABLE_FIPS140 case GNUTLS_CIPHER_CAMELLIA_128_GCM: case GNUTLS_CIPHER_CAMELLIA_256_GCM: ctx->encrypt = _camellia_gcm_encrypt; @@ -193,24 +214,6 @@ wrap_nettle_cipher_init(gnutls_cipher_algorithm_t algo, void **_ctx, ctx->ctx_ptr = &ctx->ctx.camellia; ctx->block_size = CAMELLIA_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_DES_CBC: ctx->encrypt = cbc_encrypt; ctx->decrypt = cbc_decrypt; @@ -252,6 +255,7 @@ wrap_nettle_cipher_init(gnutls_cipher_algorithm_t algo, void **_ctx, ctx->ctx_ptr = &ctx->ctx.arctwo; ctx->block_size = ARCTWO_BLOCK_SIZE; break; +#endif default: gnutls_assert(); gnutls_free(ctx); @@ -274,11 +278,6 @@ wrap_nettle_cipher_setkey(void *_ctx, const void *key, size_t keysize) case GNUTLS_CIPHER_AES_256_GCM: gcm_aes_set_key(&ctx->ctx.aes_gcm, keysize, key); break; - case GNUTLS_CIPHER_CAMELLIA_128_GCM: - case GNUTLS_CIPHER_CAMELLIA_256_GCM: - _gcm_camellia_set_key(&ctx->ctx.camellia_gcm, keysize, - key); - break; case GNUTLS_CIPHER_AES_128_CBC: case GNUTLS_CIPHER_AES_192_CBC: case GNUTLS_CIPHER_AES_256_CBC: @@ -313,6 +312,12 @@ wrap_nettle_cipher_setkey(void *_ctx, const void *key, size_t keysize) zeroize_temp_key(des_key, sizeof(des_key)); break; +#ifndef ENABLE_FIPS140 + case GNUTLS_CIPHER_CAMELLIA_128_GCM: + case GNUTLS_CIPHER_CAMELLIA_256_GCM: + _gcm_camellia_set_key(&ctx->ctx.camellia_gcm, keysize, + key); + break; case GNUTLS_CIPHER_DES_CBC: if (keysize != DES_KEY_SIZE) { gnutls_assert(); @@ -338,6 +343,7 @@ wrap_nettle_cipher_setkey(void *_ctx, const void *key, size_t keysize) case GNUTLS_CIPHER_RC2_40_CBC: arctwo_set_key(ctx->ctx_ptr, keysize, key); break; +#endif default: gnutls_assert(); return GNUTLS_E_INVALID_REQUEST; @@ -360,6 +366,7 @@ wrap_nettle_cipher_setiv(void *_ctx, const void *iv, size_t ivsize) gcm_aes_set_iv(&ctx->ctx.aes_gcm, GCM_DEFAULT_NONCE_SIZE, iv); break; +#ifndef ENABLE_FIPS140 case GNUTLS_CIPHER_CAMELLIA_128_GCM: case GNUTLS_CIPHER_CAMELLIA_256_GCM: if (ivsize != GCM_DEFAULT_NONCE_SIZE) @@ -375,6 +382,7 @@ wrap_nettle_cipher_setiv(void *_ctx, const void *iv, size_t ivsize) salsa20_set_iv(&ctx->ctx.salsa20, iv); break; +#endif default: if (ivsize > ctx->block_size) return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST); diff --git a/lib/nettle/mac.c b/lib/nettle/mac.c index 73e8c8f18f..9e87a312e3 100644 --- a/lib/nettle/mac.c +++ b/lib/nettle/mac.c @@ -43,12 +43,14 @@ static int wrap_nettle_hash_init(gnutls_digest_algorithm_t algo, struct nettle_hash_ctx { union { struct md5_ctx md5; - struct md2_ctx md2; struct sha224_ctx sha224; struct sha256_ctx sha256; struct sha384_ctx sha384; struct sha512_ctx sha512; struct sha1_ctx sha1; +#ifndef ENABLE_FIPS140 + struct md2_ctx md2; +#endif } ctx; void *ctx_ptr; gnutls_digest_algorithm_t algo; @@ -65,8 +67,10 @@ struct nettle_mac_ctx { struct hmac_sha384_ctx sha384; struct hmac_sha512_ctx sha512; struct hmac_sha1_ctx sha1; +#ifndef ENABLE_FIPS140 struct umac96_ctx umac96; struct umac128_ctx umac128; +#endif } ctx; void *ctx_ptr; @@ -78,6 +82,7 @@ struct nettle_mac_ctx { set_nonce_func set_nonce; }; +#ifndef ENABLE_FIPS140 static void _wrap_umac96_set_key(void *ctx, unsigned len, const uint8_t * key) { @@ -93,6 +98,7 @@ _wrap_umac128_set_key(void *ctx, unsigned len, const uint8_t * key) abort(); umac128_set_key(ctx, key); } +#endif static int _mac_ctx_init(gnutls_mac_algorithm_t algo, struct nettle_mac_ctx *ctx) @@ -141,6 +147,7 @@ static int _mac_ctx_init(gnutls_mac_algorithm_t algo, ctx->ctx_ptr = &ctx->ctx.sha512; ctx->length = SHA512_DIGEST_SIZE; break; +#ifndef ENABLE_FIPS140 case GNUTLS_MAC_UMAC_96: ctx->update = (update_func) umac96_update; ctx->digest = (digest_func) umac96_digest; @@ -157,6 +164,7 @@ static int _mac_ctx_init(gnutls_mac_algorithm_t algo, ctx->ctx_ptr = &ctx->ctx.umac128; ctx->length = 16; break; +#endif default: gnutls_assert(); return GNUTLS_E_INVALID_REQUEST; @@ -198,8 +206,10 @@ static int wrap_nettle_mac_exists(gnutls_mac_algorithm_t algo) case GNUTLS_MAC_SHA256: case GNUTLS_MAC_SHA384: case GNUTLS_MAC_SHA512: +#ifndef ENABLE_FIPS140 case GNUTLS_MAC_UMAC_96: case GNUTLS_MAC_UMAC_128: +#endif return 1; default: return 0; @@ -308,11 +318,14 @@ static int wrap_nettle_hash_exists(gnutls_digest_algorithm_t algo) switch (algo) { case GNUTLS_DIG_MD5: case GNUTLS_DIG_SHA1: - case GNUTLS_DIG_MD2: + case GNUTLS_DIG_SHA224: case GNUTLS_DIG_SHA256: case GNUTLS_DIG_SHA384: case GNUTLS_DIG_SHA512: +#ifndef ENABLE_FIPS140 + case GNUTLS_DIG_MD2: +#endif return 1; default: return 0; @@ -337,13 +350,6 @@ static int _ctx_init(gnutls_digest_algorithm_t algo, ctx->ctx_ptr = &ctx->ctx.sha1; ctx->length = SHA1_DIGEST_SIZE; break; - case GNUTLS_DIG_MD2: - md2_init(&ctx->ctx.md2); - ctx->update = (update_func) md2_update; - ctx->digest = (digest_func) md2_digest; - ctx->ctx_ptr = &ctx->ctx.md2; - ctx->length = MD2_DIGEST_SIZE; - break; case GNUTLS_DIG_SHA224: sha224_init(&ctx->ctx.sha224); ctx->update = (update_func) sha224_update; @@ -372,6 +378,15 @@ static int _ctx_init(gnutls_digest_algorithm_t algo, ctx->ctx_ptr = &ctx->ctx.sha512; ctx->length = SHA512_DIGEST_SIZE; break; +#ifndef ENABLE_FIPS140 + case GNUTLS_DIG_MD2: + md2_init(&ctx->ctx.md2); + ctx->update = (update_func) md2_update; + ctx->digest = (digest_func) md2_digest; + ctx->ctx_ptr = &ctx->ctx.md2; + ctx->length = MD2_DIGEST_SIZE; + break; +#endif default: gnutls_assert(); return GNUTLS_E_INVALID_REQUEST;