From: Richard Levitte Date: Wed, 8 Jan 2020 13:58:34 +0000 (+0100) Subject: PROV: Fix mixup between general and specialized GCM implementations X-Git-Tag: openssl-3.0.0-alpha1~684 X-Git-Url: https://git.librecmc.org/?a=commitdiff_plain;h=7c66ad65f959fa05ad7b95b0c84384d6e63e56f1;p=oweals%2Fopenssl.git PROV: Fix mixup between general and specialized GCM implementations providers/implementations/ciphers/ciphercommon_gcm_hw.c had an AES specific GCM update function, while providers/implementations/ciphers/cipher_aria_gcm_hw.c had the more general implementation. This moves them around to have the more general implementation in the common source, and place the AES specialiation where it belongs. Reviewed-by: Tomas Mraz Reviewed-by: Shane Lontis (Merged from https://github.com/openssl/openssl/pull/10783) --- diff --git a/providers/implementations/ciphers/cipher_aes_gcm_hw.c b/providers/implementations/ciphers/cipher_aes_gcm_hw.c index 0eb799451d..76c9b00c53 100644 --- a/providers/implementations/ciphers/cipher_aes_gcm_hw.c +++ b/providers/implementations/ciphers/cipher_aes_gcm_hw.c @@ -17,7 +17,7 @@ #include "cipher_aes_gcm.h" -static int generic_aes_gcm_initkey(PROV_GCM_CTX *ctx, const unsigned char *key, +static int aes_gcm_initkey(PROV_GCM_CTX *ctx, const unsigned char *key, size_t keylen) { PROV_AES_GCM_CTX *actx = (PROV_AES_GCM_CTX *)ctx; @@ -59,11 +59,76 @@ static int generic_aes_gcm_initkey(PROV_GCM_CTX *ctx, const unsigned char *key, return 1; } +static int generic_aes_gcm_cipher_update(PROV_GCM_CTX *ctx, const unsigned char *in, + size_t len, unsigned char *out) +{ + if (ctx->enc) { + if (ctx->ctr != NULL) { +#if defined(AES_GCM_ASM) + size_t bulk = 0; + + if (len >= AES_GCM_ENC_BYTES && AES_GCM_ASM(ctx)) { + size_t res = (16 - ctx->gcm.mres) % 16; + + if (CRYPTO_gcm128_encrypt(&ctx->gcm, in, out, res)) + return 0; + + bulk = AES_gcm_encrypt(in + res, out + res, len - res, + ctx->gcm.key, + ctx->gcm.Yi.c, ctx->gcm.Xi.u); + + ctx->gcm.len.u[1] += bulk; + bulk += res; + } + if (CRYPTO_gcm128_encrypt_ctr32(&ctx->gcm, in + bulk, out + bulk, + len - bulk, ctx->ctr)) + return 0; +#else + if (CRYPTO_gcm128_encrypt_ctr32(&ctx->gcm, in, out, len, ctx->ctr)) + return 0; +#endif /* AES_GCM_ASM */ + } else { + if (CRYPTO_gcm128_encrypt(&ctx->gcm, in, out, len)) + return 0; + } + } else { + if (ctx->ctr != NULL) { +#if defined(AES_GCM_ASM) + size_t bulk = 0; + + if (len >= AES_GCM_DEC_BYTES && AES_GCM_ASM(ctx)) { + size_t res = (16 - ctx->gcm.mres) % 16; + + if (CRYPTO_gcm128_decrypt(&ctx->gcm, in, out, res)) + return -1; + + bulk = AES_gcm_decrypt(in + res, out + res, len - res, + ctx->gcm.key, + ctx->gcm.Yi.c, ctx->gcm.Xi.u); + + ctx->gcm.len.u[1] += bulk; + bulk += res; + } + if (CRYPTO_gcm128_decrypt_ctr32(&ctx->gcm, in + bulk, out + bulk, + len - bulk, ctx->ctr)) + return 0; +#else + if (CRYPTO_gcm128_decrypt_ctr32(&ctx->gcm, in, out, len, ctx->ctr)) + return 0; +#endif /* AES_GCM_ASM */ + } else { + if (CRYPTO_gcm128_decrypt(&ctx->gcm, in, out, len)) + return 0; + } + } + return 1; +} + static const PROV_GCM_HW aes_gcm = { - generic_aes_gcm_initkey, + aes_gcm_initkey, gcm_setiv, gcm_aad_update, - gcm_cipher_update, + generic_aes_gcm_cipher_update, gcm_cipher_final, gcm_one_shot }; diff --git a/providers/implementations/ciphers/cipher_aes_gcm_hw_aesni.inc b/providers/implementations/ciphers/cipher_aes_gcm_hw_aesni.inc index 2fc86982c0..ce558dc26e 100644 --- a/providers/implementations/ciphers/cipher_aes_gcm_hw_aesni.inc +++ b/providers/implementations/ciphers/cipher_aes_gcm_hw_aesni.inc @@ -26,7 +26,7 @@ static const PROV_GCM_HW aesni_gcm = { aesni_gcm_initkey, gcm_setiv, gcm_aad_update, - gcm_cipher_update, + generic_aes_gcm_cipher_update, gcm_cipher_final, gcm_one_shot }; diff --git a/providers/implementations/ciphers/cipher_aes_gcm_hw_armv8.inc b/providers/implementations/ciphers/cipher_aes_gcm_hw_armv8.inc index 4e8cc9c54e..6f3c545369 100644 --- a/providers/implementations/ciphers/cipher_aes_gcm_hw_armv8.inc +++ b/providers/implementations/ciphers/cipher_aes_gcm_hw_armv8.inc @@ -72,7 +72,7 @@ static const PROV_GCM_HW armv8_aes_gcm = { armv8_aes_gcm_initkey, gcm_setiv, gcm_aad_update, - gcm_cipher_update, + generic_aes_gcm_cipher_update, gcm_cipher_final, gcm_one_shot }; diff --git a/providers/implementations/ciphers/cipher_aes_gcm_hw_t4.inc b/providers/implementations/ciphers/cipher_aes_gcm_hw_t4.inc index cc7d4ba528..c45a449302 100644 --- a/providers/implementations/ciphers/cipher_aes_gcm_hw_t4.inc +++ b/providers/implementations/ciphers/cipher_aes_gcm_hw_t4.inc @@ -42,7 +42,7 @@ static const PROV_GCM_HW t4_aes_gcm = { t4_aes_gcm_initkey, gcm_setiv, gcm_aad_update, - gcm_cipher_update, + generic_aes_gcm_cipher_update, gcm_cipher_final, gcm_one_shot }; diff --git a/providers/implementations/ciphers/cipher_aria_gcm_hw.c b/providers/implementations/ciphers/cipher_aria_gcm_hw.c index ed1e1851dc..04db40b53b 100644 --- a/providers/implementations/ciphers/cipher_aria_gcm_hw.c +++ b/providers/implementations/ciphers/cipher_aria_gcm_hw.c @@ -23,24 +23,11 @@ static int aria_gcm_initkey(PROV_GCM_CTX *ctx, const unsigned char *key, return 1; } -static int aria_cipher_update(PROV_GCM_CTX *ctx, const unsigned char *in, - size_t len, unsigned char *out) -{ - if (ctx->enc) { - if (CRYPTO_gcm128_encrypt(&ctx->gcm, in, out, len)) - return 0; - } else { - if (CRYPTO_gcm128_decrypt(&ctx->gcm, in, out, len)) - return 0; - } - return 1; -} - static const PROV_GCM_HW aria_gcm = { aria_gcm_initkey, gcm_setiv, gcm_aad_update, - aria_cipher_update, + gcm_cipher_update, gcm_cipher_final, gcm_one_shot }; diff --git a/providers/implementations/ciphers/ciphercommon_gcm_hw.c b/providers/implementations/ciphers/ciphercommon_gcm_hw.c index 1114c36b3f..e5998c4aa4 100644 --- a/providers/implementations/ciphers/ciphercommon_gcm_hw.c +++ b/providers/implementations/ciphers/ciphercommon_gcm_hw.c @@ -26,63 +26,11 @@ int gcm_cipher_update(PROV_GCM_CTX *ctx, const unsigned char *in, size_t len, unsigned char *out) { if (ctx->enc) { - if (ctx->ctr != NULL) { -#if defined(AES_GCM_ASM) - size_t bulk = 0; - - if (len >= AES_GCM_ENC_BYTES && AES_GCM_ASM(ctx)) { - size_t res = (16 - ctx->gcm.mres) % 16; - - if (CRYPTO_gcm128_encrypt(&ctx->gcm, in, out, res)) - return 0; - - bulk = AES_gcm_encrypt(in + res, out + res, len - res, - ctx->gcm.key, - ctx->gcm.Yi.c, ctx->gcm.Xi.u); - - ctx->gcm.len.u[1] += bulk; - bulk += res; - } - if (CRYPTO_gcm128_encrypt_ctr32(&ctx->gcm, in + bulk, out + bulk, - len - bulk, ctx->ctr)) - return 0; -#else - if (CRYPTO_gcm128_encrypt_ctr32(&ctx->gcm, in, out, len, ctx->ctr)) - return 0; -#endif /* AES_GCM_ASM */ - } else { - if (CRYPTO_gcm128_encrypt(&ctx->gcm, in, out, len)) - return 0; - } + if (CRYPTO_gcm128_encrypt(&ctx->gcm, in, out, len)) + return 0; } else { - if (ctx->ctr != NULL) { -#if defined(AES_GCM_ASM) - size_t bulk = 0; - - if (len >= AES_GCM_DEC_BYTES && AES_GCM_ASM(ctx)) { - size_t res = (16 - ctx->gcm.mres) % 16; - - if (CRYPTO_gcm128_decrypt(&ctx->gcm, in, out, res)) - return -1; - - bulk = AES_gcm_decrypt(in + res, out + res, len - res, - ctx->gcm.key, - ctx->gcm.Yi.c, ctx->gcm.Xi.u); - - ctx->gcm.len.u[1] += bulk; - bulk += res; - } - if (CRYPTO_gcm128_decrypt_ctr32(&ctx->gcm, in + bulk, out + bulk, - len - bulk, ctx->ctr)) - return 0; -#else - if (CRYPTO_gcm128_decrypt_ctr32(&ctx->gcm, in, out, len, ctx->ctr)) - return 0; -#endif /* AES_GCM_ASM */ - } else { - if (CRYPTO_gcm128_decrypt(&ctx->gcm, in, out, len)) - return 0; - } + if (CRYPTO_gcm128_decrypt(&ctx->gcm, in, out, len)) + return 0; } return 1; }