]> git.ipfire.org Git - thirdparty/openssl.git/commitdiff
Fix leakage when the cacheline is 32-bytes in CBC_MAC_ROTATE_IN_PLACE
authorbasavesh <basavesh.shivakumar@gmail.com>
Tue, 5 Apr 2022 15:49:09 +0000 (17:49 +0200)
committerTomas Mraz <tomas@openssl.org>
Mon, 9 May 2022 14:41:29 +0000 (16:41 +0200)
rotated_mac is a 64-byte aligned buffer of size 64 and rotate_offset is secret.
Consider a weaker leakage model(CL) where only cacheline base address is leaked,
i.e address/32 for 32-byte cacheline(CL32).

Previous code used to perform two loads
    1. rotated_mac[rotate_offset ^ 32] and
    2. rotated_mac[rotate_offset++]
which would leak 2q + 1, 2q for 0 <= rotate_offset < 32
and 2q, 2q + 1 for 32 <= rotate_offset < 64

The proposed fix performs load operations which will always leak 2q, 2q + 1 and
selects the appropriate value in constant-time.

Reviewed-by: Matt Caswell <matt@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/18050)

ssl/record/ssl3_record.c

index f158544789bb5621257421b83698c04b8a20ba1b..69f1a64cb3bb38c01b40574077f1a63f8289abba 100644 (file)
@@ -1532,6 +1532,7 @@ int ssl3_cbc_copy_mac(unsigned char *out,
 #if defined(CBC_MAC_ROTATE_IN_PLACE)
     unsigned char rotated_mac_buf[64 + EVP_MAX_MD_SIZE];
     unsigned char *rotated_mac;
+    char aux1, aux2, aux3, mask;
 #else
     unsigned char rotated_mac[EVP_MAX_MD_SIZE];
 #endif
@@ -1581,9 +1582,16 @@ int ssl3_cbc_copy_mac(unsigned char *out,
 #if defined(CBC_MAC_ROTATE_IN_PLACE)
     j = 0;
     for (i = 0; i < md_size; i++) {
-        /* in case cache-line is 32 bytes, touch second line */
-        ((volatile unsigned char *)rotated_mac)[rotate_offset ^ 32];
-        out[j++] = rotated_mac[rotate_offset++];
+        /*
+         * in case cache-line is 32 bytes,
+         * load from both lines and select appropriately
+         */
+        aux1 = rotated_mac[rotate_offset & ~32];
+        aux2 = rotated_mac[rotate_offset | 32];
+        mask = constant_time_eq_8(rotate_offset & ~32, rotate_offset);
+        aux3 = constant_time_select_8(mask, aux1, aux2);
+        out[j++] = aux3;
+        rotate_offset++;
         rotate_offset &= constant_time_lt_s(rotate_offset, md_size);
     }
 #else