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
--- 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 };
-- openssl-dev mailing list To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-dev