PROV: Fix mixup between general and specialized GCM implementations
authorRichard Levitte <levitte@openssl.org>
Wed, 8 Jan 2020 13:58:34 +0000 (14:58 +0100)
committerRichard Levitte <levitte@openssl.org>
Tue, 14 Jan 2020 13:57:05 +0000 (14:57 +0100)
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 <tmraz@fedoraproject.org>
Reviewed-by: Shane Lontis <shane.lontis@oracle.com>
(Merged from https://github.com/openssl/openssl/pull/10783)

providers/implementations/ciphers/cipher_aes_gcm_hw.c
providers/implementations/ciphers/cipher_aes_gcm_hw_aesni.inc
providers/implementations/ciphers/cipher_aes_gcm_hw_armv8.inc
providers/implementations/ciphers/cipher_aes_gcm_hw_t4.inc
providers/implementations/ciphers/cipher_aria_gcm_hw.c
providers/implementations/ciphers/ciphercommon_gcm_hw.c

index 0eb799451d918b2fd867ea97e19a9bc974a7b021..76c9b00c53717a1cc272a13c22b2787003bd992b 100644 (file)
@@ -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
 };
index 2fc86982c036ed3dc7b2dfa0152fdad7f479051f..ce558dc26e2f0c368a09f78f10944de1bfb80e72 100644 (file)
@@ -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
 };
index 4e8cc9c54e5ef3708811a999b80f14fc5a179148..6f3c5453691f26a4cac9e12c8f3aeaad9b27bc07 100644 (file)
@@ -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
 };
index cc7d4ba528ef51bbdff8fcc6ac6d054440dfdda7..c45a449302afb83a0ffa201779cf764fed8e5698 100644 (file)
@@ -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
 };
index ed1e1851dc67f95a998f97880f06eb2c7d02dbac..04db40b53b9caa5e455cdfc3dd6a6e14d14460b3 100644 (file)
@@ -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
 };
index 1114c36b3f1445c08017c893f38a7b570be897b2..e5998c4aa4416ba3c15c667b8d16c43263b0d2ca 100644 (file)
@@ -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;
 }