X-Git-Url: https://git.openssl.org/?a=blobdiff_plain;f=crypto%2Fevp%2Fe_aes.c;h=4f98cdc34db633c34da81efcc0a612eee60aee3d;hb=3538b0f7ad7c4b67788f444827718a89ffb5b08d;hp=b628c05f91e72825f58183b8d226a82ef40555e8;hpb=0be2cc5eb3faa2c79a705fee5977fa49841c1799;p=openssl.git diff --git a/crypto/evp/e_aes.c b/crypto/evp/e_aes.c index b628c05f91..4f98cdc34d 100644 --- a/crypto/evp/e_aes.c +++ b/crypto/evp/e_aes.c @@ -390,22 +390,33 @@ static int aesni_xts_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, return 1; if (key) { + /* The key is two half length keys in reality */ + const int bytes = EVP_CIPHER_CTX_key_length(ctx) / 2; + const int bits = bytes * 8; + + /* + * Verify that the two keys are different. + * + * This addresses Rogaway's vulnerability. + * See comment in aes_xts_init_key() below. + */ + if (memcmp(key, key + bytes, bytes) == 0) { + EVPerr(EVP_F_AESNI_XTS_INIT_KEY, EVP_R_XTS_DUPLICATED_KEYS); + return 0; + } + /* key_len is two AES keys */ if (enc) { - aesni_set_encrypt_key(key, EVP_CIPHER_CTX_key_length(ctx) * 4, - &xctx->ks1.ks); + aesni_set_encrypt_key(key, bits, &xctx->ks1.ks); xctx->xts.block1 = (block128_f) aesni_encrypt; xctx->stream = aesni_xts_encrypt; } else { - aesni_set_decrypt_key(key, EVP_CIPHER_CTX_key_length(ctx) * 4, - &xctx->ks1.ks); + aesni_set_decrypt_key(key, bits, &xctx->ks1.ks); xctx->xts.block1 = (block128_f) aesni_decrypt; xctx->stream = aesni_xts_decrypt; } - aesni_set_encrypt_key(key + EVP_CIPHER_CTX_key_length(ctx) / 2, - EVP_CIPHER_CTX_key_length(ctx) * 4, - &xctx->ks2.ks); + aesni_set_encrypt_key(key + bytes, bits, &xctx->ks2.ks); xctx->xts.block2 = (block128_f) aesni_encrypt; xctx->xts.key1 = &xctx->ks1; @@ -796,7 +807,21 @@ static int aes_t4_xts_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, return 1; if (key) { - int bits = EVP_CIPHER_CTX_key_length(ctx) * 4; + /* The key is two half length keys in reality */ + const int bytes = EVP_CIPHER_CTX_key_length(ctx) / 2; + const int bits = bytes * 8; + + /* + * Verify that the two keys are different. + * + * This addresses Rogaway's vulnerability. + * See comment in aes_xts_init_key() below. + */ + if (memcmp(key, key + bytes, bytes) == 0) { + EVPerr(EVP_F_AES_T4_XTS_INIT_KEY, EVP_R_XTS_DUPLICATED_KEYS); + return 0; + } + xctx->stream = NULL; /* key_len is two AES keys */ if (enc) { @@ -813,8 +838,7 @@ static int aes_t4_xts_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, return 0; } } else { - aes_t4_set_decrypt_key(key, EVP_CIPHER_CTX_key_length(ctx) * 4, - &xctx->ks1.ks); + aes_t4_set_decrypt_key(key, bits, &xctx->ks1.ks); xctx->xts.block1 = (block128_f) aes_t4_decrypt; switch (bits) { case 128: @@ -828,9 +852,7 @@ static int aes_t4_xts_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, } } - aes_t4_set_encrypt_key(key + EVP_CIPHER_CTX_key_length(ctx) / 2, - EVP_CIPHER_CTX_key_length(ctx) * 4, - &xctx->ks2.ks); + aes_t4_set_encrypt_key(key + bytes, bits, &xctx->ks2.ks); xctx->xts.block2 = (block128_f) aes_t4_encrypt; xctx->xts.key1 = &xctx->ks1; @@ -3414,8 +3436,33 @@ static int aes_xts_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, if (!iv && !key) return 1; - if (key) + if (key) { do { + /* The key is two half length keys in reality */ + const int bytes = EVP_CIPHER_CTX_key_length(ctx) / 2; + const int bits = bytes * 8; + + /* + * Verify that the two keys are different. + * + * This addresses the vulnerability described in Rogaway's + * September 2004 paper: + * + * "Efficient Instantiations of Tweakable Blockciphers and + * Refinements to Modes OCB and PMAC". + * (http://web.cs.ucdavis.edu/~rogaway/papers/offsets.pdf) + * + * FIPS 140-2 IG A.9 XTS-AES Key Generation Requirements states + * that: + * "The check for Key_1 != Key_2 shall be done at any place + * BEFORE using the keys in the XTS-AES algorithm to process + * data with them." + */ + if (memcmp(key, key + bytes, bytes) == 0) { + EVPerr(EVP_F_AES_XTS_INIT_KEY, EVP_R_XTS_DUPLICATED_KEYS); + return 0; + } + #ifdef AES_XTS_ASM xctx->stream = enc ? AES_xts_encrypt : AES_xts_decrypt; #else @@ -3425,26 +3472,20 @@ static int aes_xts_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, #ifdef HWAES_CAPABLE if (HWAES_CAPABLE) { if (enc) { - HWAES_set_encrypt_key(key, - EVP_CIPHER_CTX_key_length(ctx) * 4, - &xctx->ks1.ks); + HWAES_set_encrypt_key(key, bits, &xctx->ks1.ks); xctx->xts.block1 = (block128_f) HWAES_encrypt; # ifdef HWAES_xts_encrypt xctx->stream = HWAES_xts_encrypt; # endif } else { - HWAES_set_decrypt_key(key, - EVP_CIPHER_CTX_key_length(ctx) * 4, - &xctx->ks1.ks); + HWAES_set_decrypt_key(key, bits, &xctx->ks1.ks); xctx->xts.block1 = (block128_f) HWAES_decrypt; # ifdef HWAES_xts_decrypt xctx->stream = HWAES_xts_decrypt; #endif } - HWAES_set_encrypt_key(key + EVP_CIPHER_CTX_key_length(ctx) / 2, - EVP_CIPHER_CTX_key_length(ctx) * 4, - &xctx->ks2.ks); + HWAES_set_encrypt_key(key + bytes, bits, &xctx->ks2.ks); xctx->xts.block2 = (block128_f) HWAES_encrypt; xctx->xts.key1 = &xctx->ks1; @@ -3459,20 +3500,14 @@ static int aes_xts_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, #ifdef VPAES_CAPABLE if (VPAES_CAPABLE) { if (enc) { - vpaes_set_encrypt_key(key, - EVP_CIPHER_CTX_key_length(ctx) * 4, - &xctx->ks1.ks); + vpaes_set_encrypt_key(key, bits, &xctx->ks1.ks); xctx->xts.block1 = (block128_f) vpaes_encrypt; } else { - vpaes_set_decrypt_key(key, - EVP_CIPHER_CTX_key_length(ctx) * 4, - &xctx->ks1.ks); + vpaes_set_decrypt_key(key, bits, &xctx->ks1.ks); xctx->xts.block1 = (block128_f) vpaes_decrypt; } - vpaes_set_encrypt_key(key + EVP_CIPHER_CTX_key_length(ctx) / 2, - EVP_CIPHER_CTX_key_length(ctx) * 4, - &xctx->ks2.ks); + vpaes_set_encrypt_key(key + bytes, bits, &xctx->ks2.ks); xctx->xts.block2 = (block128_f) vpaes_encrypt; xctx->xts.key1 = &xctx->ks1; @@ -3482,22 +3517,19 @@ static int aes_xts_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, (void)0; /* terminate potentially open 'else' */ if (enc) { - AES_set_encrypt_key(key, EVP_CIPHER_CTX_key_length(ctx) * 4, - &xctx->ks1.ks); + AES_set_encrypt_key(key, bits, &xctx->ks1.ks); xctx->xts.block1 = (block128_f) AES_encrypt; } else { - AES_set_decrypt_key(key, EVP_CIPHER_CTX_key_length(ctx) * 4, - &xctx->ks1.ks); + AES_set_decrypt_key(key, bits, &xctx->ks1.ks); xctx->xts.block1 = (block128_f) AES_decrypt; } - AES_set_encrypt_key(key + EVP_CIPHER_CTX_key_length(ctx) / 2, - EVP_CIPHER_CTX_key_length(ctx) * 4, - &xctx->ks2.ks); + AES_set_encrypt_key(key + bytes, bits, &xctx->ks2.ks); xctx->xts.block2 = (block128_f) AES_encrypt; xctx->xts.key1 = &xctx->ks1; } while (0); + } if (iv) { xctx->xts.key2 = &xctx->ks2; @@ -3530,22 +3562,6 @@ static int aes_xts_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, return 0; } - /* - * Verify that the two keys are different. - * - * This addresses the vulnerability described in Rogaway's September 2004 - * paper (http://web.cs.ucdavis.edu/~rogaway/papers/offsets.pdf): - * "Efficient Instantiations of Tweakable Blockciphers and Refinements - * to Modes OCB and PMAC". - * - * FIPS 140-2 IG A.9 XTS-AES Key Generation Requirements states that: - * "The check for Key_1 != Key_2 shall be done at any place BEFORE - * using the keys in the XTS-AES algorithm to process data with them." - */ - if (CRYPTO_memcmp(xctx->xts.key1, xctx->xts.key2, - EVP_CIPHER_CTX_key_length(ctx) / 2) == 0) - return 0; - if (xctx->stream) (*xctx->stream) (in, out, len, xctx->xts.key1, xctx->xts.key2,