]> git.ipfire.org Git - thirdparty/gnutls.git/commitdiff
In FIPS140-2 mode disable non-conformant ciphers, MAC and hash algorithms.
authorNikos Mavrogiannopoulos <nmav@redhat.com>
Fri, 22 Nov 2013 10:49:43 +0000 (11:49 +0100)
committerNikos Mavrogiannopoulos <nmav@redhat.com>
Wed, 27 Nov 2013 10:41:44 +0000 (11:41 +0100)
lib/algorithms/ciphers.c
lib/algorithms/ciphersuites.c
lib/algorithms/mac.c
lib/gnutls_hash_int.c
lib/gnutls_hash_int.h
lib/gnutls_priority.c
lib/nettle/cipher.c
lib/nettle/mac.c

index a0d372818b0265621454beae1b479a73dc5a21f9..a99273fe791c69117d8beb53f60390d524d2d69d 100644 (file)
@@ -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;
index 478dd61f831195529b987adff09d860e1a77447b..763f7ff69cd2d1f82f2098dee45270d49d7395cf 100644 (file)
@@ -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,
index 595eab348e23a72f808a0ee05fb08f02895e2773..e691a4ef3a8740e79dc6b37eae4ddbaf117f6e45 100644 (file)
@@ -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;
                }
        );
index ddeff10bdb60fe24b36b5cb1682fc1a56d6cde59..4e841ca8f803ecb1f73d793709de4a11f09ea1df 100644 (file)
@@ -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) {
index 0377900a925369a0c170cae8260e91fc1ac4e7d8..75061c848cf1434a6e72145001c1f6f5e2f3807b 100644 (file)
@@ -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);
index a02093880be0c5f263d370ce1a06b21c3a8f031d..a4c498bc7c4b5c057810a76f6d89ed8479e259de 100644 (file)
@@ -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
 };
 
index 4d6692043bba1e9365403c499097a9fc18735e56..e50f4726e61a6fda8dbb0723f5ad63357808aadd 100644 (file)
@@ -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);
index 73e8c8f18f41649f19c00705d083453de7bf9e07..9e87a312e3510a8891847f6595241368c04279d0 100644 (file)
@@ -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;