From: Matt Caswell Date: Thu, 5 Dec 2019 18:01:44 +0000 (+0000) Subject: Don't use the low level AES key wrap APIs in CMS X-Git-Tag: openssl-3.0.0-alpha1~738 X-Git-Url: https://git.openssl.org/gitweb/?p=openssl.git;a=commitdiff_plain;h=2852c672a8ecb02a74d0adeeb93c661b7d2d7511 Don't use the low level AES key wrap APIs in CMS We should not be using the low level AES APIs in CMS. Instead we should be using EVP. There was a small amount of use of the low level key wrap APIs - so we convert that to EVP. Reviewed-by: Tomas Mraz (Merged from https://github.com/openssl/openssl/pull/10580) --- diff --git a/crypto/cms/cms_env.c b/crypto/cms/cms_env.c index ecece987ae..ac34f3efd6 100644 --- a/crypto/cms/cms_env.c +++ b/crypto/cms/cms_env.c @@ -13,7 +13,7 @@ #include #include #include -#include +#include #include "cms_local.h" #include "crypto/asn1.h" #include "crypto/evp.h" @@ -625,6 +625,23 @@ int CMS_RecipientInfo_set0_key(CMS_RecipientInfo *ri, return 1; } +static const EVP_CIPHER *cms_get_key_wrap_cipher(size_t keylen) +{ + switch(keylen) { + case 16: + return EVP_aes_128_wrap(); + + case 24: + return EVP_aes_192_wrap(); + + case 32: + return EVP_aes_256_wrap(); + } + + return NULL; +} + + /* Encrypt content key in KEK recipient info */ static int cms_RecipientInfo_kekri_encrypt(const CMS_ContentInfo *cms, @@ -632,36 +649,50 @@ static int cms_RecipientInfo_kekri_encrypt(const CMS_ContentInfo *cms, { CMS_EncryptedContentInfo *ec; CMS_KEKRecipientInfo *kekri; - AES_KEY actx; unsigned char *wkey = NULL; int wkeylen; int r = 0; + const EVP_CIPHER *cipher = NULL; + int outlen = 0; + EVP_CIPHER_CTX *ctx = NULL; ec = cms->d.envelopedData->encryptedContentInfo; kekri = ri->d.kekri; - if (!kekri->key) { + if (kekri->key == NULL) { CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_ENCRYPT, CMS_R_NO_KEY); return 0; } - if (AES_set_encrypt_key(kekri->key, kekri->keylen << 3, &actx)) { - CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_ENCRYPT, - CMS_R_ERROR_SETTING_KEY); + cipher = cms_get_key_wrap_cipher(kekri->keylen); + if (cipher == NULL) { + CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_ENCRYPT, CMS_R_INVALID_KEY_LENGTH); goto err; } + /* 8 byte prefix for AES wrap ciphers */ wkey = OPENSSL_malloc(ec->keylen + 8); - if (wkey == NULL) { CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_ENCRYPT, ERR_R_MALLOC_FAILURE); goto err; } - wkeylen = AES_wrap_key(&actx, NULL, wkey, ec->key, ec->keylen); + ctx = EVP_CIPHER_CTX_new(); + if (ctx == NULL) { + CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_ENCRYPT, ERR_R_MALLOC_FAILURE); + goto err; + } - if (wkeylen <= 0) { + EVP_CIPHER_CTX_set_flags(ctx, EVP_CIPHER_CTX_FLAG_WRAP_ALLOW); + if (!EVP_EncryptInit_ex(ctx, cipher, NULL, kekri->key, NULL) + || !EVP_EncryptUpdate(ctx, wkey, &wkeylen, ec->key, ec->keylen) + || !EVP_EncryptFinal_ex(ctx, wkey + wkeylen, &outlen)) { + CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_ENCRYPT, CMS_R_WRAP_ERROR); + goto err; + } + wkeylen += outlen; + if (!ossl_assert((size_t)wkeylen == ec->keylen + 8)) { CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_ENCRYPT, CMS_R_WRAP_ERROR); goto err; } @@ -671,10 +702,9 @@ static int cms_RecipientInfo_kekri_encrypt(const CMS_ContentInfo *cms, r = 1; err: - if (!r) OPENSSL_free(wkey); - OPENSSL_cleanse(&actx, sizeof(actx)); + EVP_CIPHER_CTX_free(ctx); return r; @@ -687,10 +717,12 @@ static int cms_RecipientInfo_kekri_decrypt(CMS_ContentInfo *cms, { CMS_EncryptedContentInfo *ec; CMS_KEKRecipientInfo *kekri; - AES_KEY actx; unsigned char *ukey = NULL; int ukeylen; int r = 0, wrap_nid; + const EVP_CIPHER *cipher = NULL; + int outlen = 0; + EVP_CIPHER_CTX *ctx = NULL; ec = cms->d.envelopedData->encryptedContentInfo; @@ -716,27 +748,33 @@ static int cms_RecipientInfo_kekri_decrypt(CMS_ContentInfo *cms, goto err; } - if (AES_set_decrypt_key(kekri->key, kekri->keylen << 3, &actx)) { - CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT, - CMS_R_ERROR_SETTING_KEY); + cipher = cms_get_key_wrap_cipher(kekri->keylen); + if (cipher == NULL) { + CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT, CMS_R_INVALID_KEY_LENGTH); goto err; } ukey = OPENSSL_malloc(kekri->encryptedKey->length - 8); - if (ukey == NULL) { CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT, ERR_R_MALLOC_FAILURE); goto err; } - ukeylen = AES_unwrap_key(&actx, NULL, ukey, - kekri->encryptedKey->data, - kekri->encryptedKey->length); + ctx = EVP_CIPHER_CTX_new(); + if (ctx == NULL) { + CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT, ERR_R_MALLOC_FAILURE); + goto err; + } - if (ukeylen <= 0) { + if (!EVP_DecryptInit_ex(ctx, cipher, NULL, kekri->key, NULL) + || !EVP_DecryptUpdate(ctx, ukey, &ukeylen, + kekri->encryptedKey->data, + kekri->encryptedKey->length) + || !EVP_DecryptFinal_ex(ctx, ukey + ukeylen, &outlen)) { CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT, CMS_R_UNWRAP_ERROR); goto err; } + ukeylen += outlen; ec->key = ukey; ec->keylen = ukeylen; @@ -744,10 +782,9 @@ static int cms_RecipientInfo_kekri_decrypt(CMS_ContentInfo *cms, r = 1; err: - if (!r) OPENSSL_free(ukey); - OPENSSL_cleanse(&actx, sizeof(actx)); + EVP_CIPHER_CTX_free(ctx); return r;