Skip to contentSkip to conversation

lib/crypto: aes-cmac: Hide selection mask value from compilers

PATCH Applied Eric Biggers 2 participants 3 messages Oct 31 – Nov 3

Subsystems (2)
lore
Share & tools
lore

Eric Biggers

author maintainer
#0 lore raw

PATCH 1/1 lib/crypto: aes-cmac: Hide selection mask value from compilers

Hide selection mask values from compilers, so that they cannot see that they are used to select between two values and potentially generate a secret-dependent branch. This is not known to be happening here, but we might as well be extra careful.

Since the selected values are only 0x87 and 0 here, change the type of the mask to 'unsigned long' so that the compiler is not forced to materialize it in a register pair on 32-bit architectures.

---
 lib/crypto/aes.c | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)
lib/crypto/aes.c +5 -3
index e1c191551736..1d26fd8be028 100644
@@ -578,7 +578,7 @@ static void aes_cbcmac_blocks(u8 h[AES_BLOCK_SIZE],
 int aes_cmac_preparekey(struct aes_cmac_key *key, const u8 *in_key,
 			size_t key_len)
 {
-	u64 hi, lo, mask;
+	u64 hi, lo;
 	int err;
 
 	/* Prepare the AES key. */
@@ -596,9 +596,11 @@ int aes_cmac_preparekey(struct aes_cmac_key *key, const u8 *in_key,
 	hi = be64_to_cpu(key->k_final[0].w[0]);
 	lo = be64_to_cpu(key->k_final[0].w[1]);
 	for (int i = 0; i < 2; i++) {
-		mask = ((s64)hi >> 63) & 0x87;
+		unsigned long mask = (s64)hi >> 63;
+
+		OPTIMIZER_HIDE_VAR(mask);
 		hi = (hi << 1) ^ (lo >> 63);
-		lo = (lo << 1) ^ mask;
+		lo = (lo << 1) ^ (mask & 0x87);
 		key->k_final[i].w[0] = cpu_to_be64(hi);
 		key->k_final[i].w[1] = cpu_to_be64(lo);
 	}

base-commit: 2a500a04d6f969318c05f46aedb6e73fc1963a00

Signature · 1 line
2.56.0
maintainer Reviewed-by on v1 1/1
#1 lore raw
Quoted 5 lines · Eric Biggers

Hide selection mask values from compilers, so that they cannot see that they are used to select between two values and potentially generate a secret-dependent branch. This is not known to be happening here, but we might as well be extra careful.

Quoted 9 lines

Since the selected values are only 0x87 and 0 here, change the type of the mask to 'unsigned long' so that the compiler is not forced to materialize it in a register pair on 32-bit architectures.

---
 lib/crypto/aes.c | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)
Quoted 32 lines
lib/crypto/aes.c +5 -3
index e1c191551736..1d26fd8be028 100644
@@ -578,7 +578,7 @@ static void aes_cbcmac_blocks(u8 h[AES_BLOCK_SIZE],
 int aes_cmac_preparekey(struct aes_cmac_key *key, const u8 *in_key,
 			size_t key_len)
 {
-	u64 hi, lo, mask;
+	u64 hi, lo;
 	int err;
 
 	/* Prepare the AES key. */
@@ -596,9 +596,11 @@ int aes_cmac_preparekey(struct aes_cmac_key *key, 
 const u8 *in_key,
 	hi = be64_to_cpu(key->k_final[0].w[0]);
 	lo = be64_to_cpu(key->k_final[0].w[1]);
 	for (int i = 0; i < 2; i++) {
-		mask = ((s64)hi >> 63) & 0x87;
+		unsigned long mask = (s64)hi >> 63;
+
+		OPTIMIZER_HIDE_VAR(mask);
 		hi = (hi << 1) ^ (lo >> 63);
-		lo = (lo << 1) ^ mask;
+		lo = (lo << 1) ^ (mask & 0x87);
 		key->k_final[i].w[0] = cpu_to_be64(hi);
 		key->k_final[i].w[1] = cpu_to_be64(lo);

}

base-commit: 2a500a04d6f969318c05f46aedb6e73fc1963a00

Signature · 1 line
2.56.0
author maintainer Applied
#2 lore raw
In reply to Eric Biggers
Quoted 5 lines · Eric Biggers

Hide selection mask values from compilers, so that they cannot see that they are used to select between two values and potentially generate a secret-dependent branch. This is not known to be happening here, but we might as well be extra careful.

Quoted 8 lines

Since the selected values are only 0x87 and 0 here, change the type of the mask to 'unsigned long' so that the compiler is not forced to materialize it in a register pair on 32-bit architectures.

---
 lib/crypto/aes.c | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

Applied to https://git.kernel.org/pub/scm/linux/kernel/git/ebiggers/linux.git/log/?h=libcrypto-next

- Eric