Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 11 Feb 2021 15:25:55 GMT
From:      Mark Johnston <markj@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org
Subject:   git: 860e0c7fb848 - stable/13 - armv8crypto: Fix some edge cases in the AES-GCM implementation
Message-ID:  <202102111525.11BFPtIN010970@gitrepo.freebsd.org>

next in thread | raw e-mail | index | archive | help
The branch stable/13 has been updated by markj:

URL: https://cgit.FreeBSD.org/src/commit/?id=860e0c7fb84863580521142825330aa941dee313

commit 860e0c7fb84863580521142825330aa941dee313
Author:     Mark Johnston <markj@FreeBSD.org>
AuthorDate: 2021-02-08 14:19:07 +0000
Commit:     Mark Johnston <markj@FreeBSD.org>
CommitDate: 2021-02-11 15:25:39 +0000

    armv8crypto: Fix some edge cases in the AES-GCM implementation
    
    - We were only hashing up to the first 16 bytes of the AAD.
    - When computing the digest during decryption, handle the case where
      len == trailer, i.e., len < AES_BLOCK_LEN, properly.
    
    While here:
    
    - trailer is always smaller than AES_BLOCK_LEN, so remove a pair of
      unnecessary modulus operations.
    - Replace some byte-by-byte loops with memcpy() and memset() calls.
      In particular, zero the full block before copying a partial block into
      it since we do that elsewhere and it means that the memset() length is
      known at compile time.
    
    Reviewed by:    jhb
    Sponsored by:   Ampere Computing
    Submitted by:   Klara, Inc.
    Differential Revision:  https://reviews.freebsd.org/D28501
    
    (cherry picked from commit 0dc7076037a87100060309f7179ef6a01f32f99e)
---
 sys/crypto/armv8/armv8_crypto_wrap.c | 47 ++++++++++++++++++++++--------------
 1 file changed, 29 insertions(+), 18 deletions(-)

diff --git a/sys/crypto/armv8/armv8_crypto_wrap.c b/sys/crypto/armv8/armv8_crypto_wrap.c
index ea93f1b9a176..2f880258bf46 100644
--- a/sys/crypto/armv8/armv8_crypto_wrap.c
+++ b/sys/crypto/armv8/armv8_crypto_wrap.c
@@ -263,9 +263,16 @@ armv8_aes_encrypt_gcm(AES_key_t *aes_key, size_t len,
 	aes_counter[AES_BLOCK_LEN - 1] = 2;
 
 	memset(Xi.c, 0, sizeof(Xi.c));
-	memset(block, 0, sizeof(block));
-	memcpy(block, authdata, min(authdatalen, sizeof(block)));
-	gcm_ghash_v8(Xi.u, Htable, block, AES_BLOCK_LEN);
+	trailer = authdatalen % AES_BLOCK_LEN;
+	if (authdatalen - trailer > 0) {
+		gcm_ghash_v8(Xi.u, Htable, authdata, authdatalen - trailer);
+		authdata += authdatalen - trailer;
+	}
+	if (trailer > 0 || authdatalen == 0) {
+		memset(block, 0, sizeof(block));
+		memcpy(block, authdata, trailer);
+		gcm_ghash_v8(Xi.u, Htable, block, AES_BLOCK_LEN);
+	}
 
 	from64 = (const uint64_t*)from;
 	to64 = (uint64_t*)to;
@@ -288,13 +295,11 @@ armv8_aes_encrypt_gcm(AES_key_t *aes_key, size_t len,
 	if (trailer) {
 		aes_v8_encrypt(aes_counter, EKi.c, aes_key);
 		AES_INC_COUNTER(aes_counter);
+		memset(block, 0, sizeof(block));
 		for (i = 0; i < trailer; i++) {
-			block[i] = to[i] = from[i] ^ EKi.c[i % AES_BLOCK_LEN];
+			block[i] = to[i] = from[i] ^ EKi.c[i];
 		}
 
-		for (; i < AES_BLOCK_LEN; i++)
-			block[i] = 0;
-
 		gcm_ghash_v8(Xi.u, Htable, block, AES_BLOCK_LEN);
 	}
 
@@ -343,17 +348,23 @@ armv8_aes_decrypt_gcm(AES_key_t *aes_key, size_t len,
 	aes_v8_encrypt(aes_counter, EK0.c, aes_key);
 
 	memset(Xi.c, 0, sizeof(Xi.c));
-	memset(block, 0, sizeof(block));
-	memcpy(block, authdata, min(authdatalen, sizeof(block)));
-	gcm_ghash_v8(Xi.u, Htable, block, AES_BLOCK_LEN);
-	trailer = len % AES_BLOCK_LEN;
-	gcm_ghash_v8(Xi.u, Htable, from, len - trailer);
+	trailer = authdatalen % AES_BLOCK_LEN;
+	if (authdatalen - trailer > 0) {
+		gcm_ghash_v8(Xi.u, Htable, authdata, authdatalen - trailer);
+		authdata += authdatalen - trailer;
+	}
+	if (trailer > 0 || authdatalen == 0) {
+		memset(block, 0, sizeof(block));
+		memcpy(block, authdata, trailer);
+		gcm_ghash_v8(Xi.u, Htable, block, AES_BLOCK_LEN);
+	}
 
-	if (trailer) {
-		for (i = 0; i < trailer; i++)
-			block[i] = from[len - trailer + i];
-		for (; i < AES_BLOCK_LEN; i++)
-			block[i] = 0;
+	trailer = len % AES_BLOCK_LEN;
+	if (len - trailer > 0)
+		gcm_ghash_v8(Xi.u, Htable, from, len - trailer);
+	if (trailer > 0) {
+		memset(block, 0, sizeof(block));
+		memcpy(block, from + len - trailer, trailer);
 		gcm_ghash_v8(Xi.u, Htable, block, AES_BLOCK_LEN);
 	}
 
@@ -392,7 +403,7 @@ armv8_aes_decrypt_gcm(AES_key_t *aes_key, size_t len,
 		aes_v8_encrypt(aes_counter, EKi.c, aes_key);
 		AES_INC_COUNTER(aes_counter);
 		for (i = 0; i < trailer; i++)
-			to[i] = from[i] ^ EKi.c[i % AES_BLOCK_LEN];
+			to[i] = from[i] ^ EKi.c[i];
 	}
 
 out:



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202102111525.11BFPtIN010970>