[openssl-dev] [openssl.org #4692] 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 use the FIPS module to do the actual block-at-a-time
encryption/decryption.
Kent
--
Ticket here: http://rt.openssl.org/Ticket/Display.html?id=4692
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