[openssl-dev] [openssl.org #4693] Change EVP_aes_xxx_wrap to use FIPS crypto module in FIPS mode

Kent Peacock via RT rt at openssl.org
Sat Oct 1 11:02:54 UTC 2016


The FIPS certified 2.0.x crypto module does not incorporate the key wrap 
modes within the module boundary, and calls the local 
AES_{encrypt,decrypt} functions (which is, strictly speaking, a no-no). 
So, it's not using FIPS validated crypto. This patch provides a 
modification to use the appropriate underlying FIPS EVP_aes_..._ecb APIs 
which FIPS module to do the actual block-at-a-time encryption/decryption.

Kent

-- 
Ticket here: http://rt.openssl.org/Ticket/Display.html?id=4693
Please log in as guest with password guest if prompted

-------------- next part --------------
--- crypto/evp/e_aes.c.orig	2016-09-30 16:35:00.973857408 -0700
+++ crypto/evp/e_aes.c	2016-09-30 16:34:20.579119933 -0700
@@ -1920,10 +1920,7 @@
                     EVP_CIPH_FLAG_FIPS | CUSTOM_FLAGS)
 #endif
 typedef struct {
-    union {
-        double align;
-        AES_KEY ks;
-    } ks;
+    EVP_CIPHER_CTX aes_ctx;
     /* Indicates if IV has been set */
     unsigned char *iv;
 } EVP_AES_WRAP_CTX;
@@ -1935,10 +1932,22 @@
     if (!iv && !key)
         return 1;
     if (key) {
-        if (ctx->encrypt)
-            AES_set_encrypt_key(key, ctx->key_len * 8, &wctx->ks.ks);
-        else
-            AES_set_decrypt_key(key, ctx->key_len * 8, &wctx->ks.ks);
+        const EVP_CIPHER *cipher;
+        switch (ctx->key_len * 8) {
+        case 128:
+            cipher = EVP_aes_128_ecb();
+            break;
+        case 192:
+            cipher = EVP_aes_192_ecb();
+            break;
+        case 256:
+            cipher = EVP_aes_256_ecb();
+            break;
+        default:
+            return 0;
+        }
+        EVP_CipherInit(&wctx->aes_ctx, cipher, key, NULL, ctx->encrypt);
+        EVP_CIPHER_CTX_set_padding(&wctx->aes_ctx, 0);
         if (!iv)
             wctx->iv = NULL;
     }
@@ -1949,6 +1958,20 @@
     return 1;
 }
 
+static block128_f
+aes_wrap_encrypt(const unsigned char *in, unsigned char *out, const void *key)
+{
+    int outlen;
+    return EVP_EncryptUpdate(key, out, &outlen, in, 16);
+}
+
+static block128_f
+aes_wrap_decrypt(const unsigned char *in, unsigned char *out, const void *key)
+{
+    int outlen;
+    return EVP_DecryptUpdate(key, out, &outlen, in, 16);
+}
+
 static int aes_wrap_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
                            const unsigned char *in, size_t inlen)
 {
@@ -1969,14 +1992,27 @@
             return inlen - 8;
     }
     if (ctx->encrypt)
-        rv = CRYPTO_128_wrap(&wctx->ks.ks, wctx->iv, out, in, inlen,
-                             (block128_f) AES_encrypt);
+        rv = CRYPTO_128_wrap(&wctx->aes_ctx, wctx->iv, out, in, inlen,
+                             (block128_f) aes_wrap_encrypt);
     else
-        rv = CRYPTO_128_unwrap(&wctx->ks.ks, wctx->iv, out, in, inlen,
-                               (block128_f) AES_decrypt);
+        rv = CRYPTO_128_unwrap(&wctx->aes_ctx, wctx->iv, out, in, inlen,
+                               (block128_f) aes_wrap_decrypt);
     return rv ? (int)rv : -1;
 }
 
+static int aes_wrap_cleanup(EVP_CIPHER_CTX *c)
+{
+    EVP_AES_WRAP_CTX *wctx = c->cipher_data;
+
+    if (wctx) {
+        EVP_CIPHER_CTX_cleanup(&wctx->aes_ctx);
+        OPENSSL_cleanse(c->cipher_data, c->cipher->ctx_size);
+        OPENSSL_free(c->cipher_data);
+    }
+    memset(c, 0, sizeof(EVP_CIPHER_CTX));
+    return 1;
+}
+
 #define WRAP_FLAGS      (EVP_CIPH_WRAP_MODE \
                 | EVP_CIPH_CUSTOM_IV | EVP_CIPH_FLAG_CUSTOM_CIPHER \
                 | EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_FLAG_DEFAULT_ASN1)
@@ -1985,7 +2021,7 @@
     NID_id_aes128_wrap,
     8, 16, 8, WRAP_FLAGS,
     aes_wrap_init_key, aes_wrap_cipher,
-    NULL,
+    aes_wrap_cleanup,
     sizeof(EVP_AES_WRAP_CTX),
     NULL, NULL, NULL, NULL
 };
@@ -1999,7 +2035,7 @@
     NID_id_aes192_wrap,
     8, 24, 8, WRAP_FLAGS,
     aes_wrap_init_key, aes_wrap_cipher,
-    NULL,
+    aes_wrap_cleanup,
     sizeof(EVP_AES_WRAP_CTX),
     NULL, NULL, NULL, NULL
 };
@@ -2013,7 +2049,7 @@
     NID_id_aes256_wrap,
     8, 32, 8, WRAP_FLAGS,
     aes_wrap_init_key, aes_wrap_cipher,
-    NULL,
+    aes_wrap_cleanup,
     sizeof(EVP_AES_WRAP_CTX),
     NULL, NULL, NULL, NULL
 };


More information about the openssl-dev mailing list