]> git.ipfire.org Git - thirdparty/openssl.git/commitdiff
Optimize CMAC_Update for better performance.
authorfisher.yu <fisher.yu@arm.com>
Thu, 11 May 2023 06:43:57 +0000 (06:43 +0000)
committerPauli <pauli@openssl.org>
Thu, 8 Jun 2023 23:08:27 +0000 (09:08 +1000)
    Reduce the number of EVP_Cipher function calls in CMAC_Update,
    to improve performance of CMAC.
    Below are command and result of performance improvement.

    COMMAND: openssl speed -cmac ALGORITHM

    IMPROVEMENT(%):
    A72   stands for Cortex A72
    N1    stands for Neoverse N1
    N2    stands for Neoverse N2
                        A72 N1 N2 x86
    aes-128-cbc@256 65.4 54.6 37.9 86.6
    aes-128-cbc@1024 156.0 105.6 65.8 197.1
    aes-128-cbc@8192 237.7 139.2 80.5 285.8
    aes-128-cbc@16384 249.1 143.5 82.2 294.1
    aes-192-cbc@256 65.6 46.5 30.9 77.8
    aes-192-cbc@1024 154.2 87.5 50.8 167.4
    aes-192-cbc@8192 226.5 117.0 60.5 231.7
    aes-192-cbc@16384 236.3 120.1 61.7 238.4
    aes-256-cbc@256 66.0 40.3 22.2 69.5
    aes-256-cbc@1024 136.8 74.6 35.7 142.2
    aes-256-cbc@8192 189.7 93.5 41.5 191.7
    aes-256-cbc@16384 196.6 95.8 42.2 195.9
    des-ede3-cbc@64 6.9 4.4 2.9 7.2
    des-ede3-cbc@256 9.3 6.1 4.3 13.1
    des-ede3-cbc@1024 10.0 6.4 4.8 14.9
    des-ede3-cbc@8192 10.3 6.5 5.1 15.5
    des-ede3-cbc@16384 10.3 6.4 5.1 15.5
    sm4-cbc@256 9.5 3.0 - 18.0
    sm4-cbc@1024 12.3 3.6 - 24.6
    sm4-cbc@8192 13.2 3.8 - 27.0
    sm4-cbc@16384 13.5 3.8 - 27.2

Reviewed-by: Tomas Mraz <tomas@openssl.org>
Reviewed-by: Paul Dale <pauli@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/21102)

crypto/cmac/cmac.c

index b7cbba90c04f655a59e9d3d9f1d984ab65feec0d..961df0d719170f75215e737d74408fc23ae63392 100644 (file)
@@ -20,6 +20,7 @@
 #include <openssl/cmac.h>
 #include <openssl/err.h>
 
+#define LOCAL_BUF_SIZE 2048
 struct CMAC_CTX_st {
     /* Cipher context to use */
     EVP_CIPHER_CTX *cctx;
@@ -162,6 +163,8 @@ int CMAC_Update(CMAC_CTX *ctx, const void *in, size_t dlen)
 {
     const unsigned char *data = in;
     int bl;
+    size_t max_burst_blocks, cipher_blocks;
+    unsigned char buf[LOCAL_BUF_SIZE];
 
     if (ctx->nlast_block == -1)
         return 0;
@@ -188,11 +191,35 @@ int CMAC_Update(CMAC_CTX *ctx, const void *in, size_t dlen)
             return 0;
     }
     /* Encrypt all but one of the complete blocks left */
-    while (dlen > (size_t)bl) {
-        if (EVP_Cipher(ctx->cctx, ctx->tbl, data, bl) <= 0)
-            return 0;
-        dlen -= bl;
-        data += bl;
+
+    max_burst_blocks = LOCAL_BUF_SIZE / bl;
+    cipher_blocks = (dlen - 1) / bl;
+    if (max_burst_blocks == 0) {
+        /*
+         * In case block length is greater than local buffer size,
+         * use ctx->tbl as cipher output.
+         */
+        while (dlen > (size_t)bl) {
+            if (EVP_Cipher(ctx->cctx, ctx->tbl, data, bl) <= 0)
+                return 0;
+            dlen -= bl;
+            data += bl;
+        }
+    } else {
+        while (cipher_blocks > max_burst_blocks) {
+            if (EVP_Cipher(ctx->cctx, buf, data, max_burst_blocks * bl) <= 0)
+                return 0;
+            dlen -= max_burst_blocks * bl;
+            data += max_burst_blocks * bl;
+            cipher_blocks -= max_burst_blocks;
+        }
+        if (cipher_blocks > 0) {
+            if (EVP_Cipher(ctx->cctx, buf, data, cipher_blocks * bl) <= 0)
+                return 0;
+            dlen -= cipher_blocks * bl;
+            data += cipher_blocks * bl;
+            memcpy(ctx->tbl, &buf[(cipher_blocks - 1) * bl], bl);
+        }
     }
     /* Copy any data left to last block buffer */
     memcpy(ctx->last_block, data, dlen);