bn/bn_lib.c: add computationally constant-time bn_bn2binpad.
authorAndy Polyakov <appro@openssl.org>
Sun, 4 Feb 2018 14:20:29 +0000 (15:20 +0100)
committerAndy Polyakov <appro@openssl.org>
Fri, 10 Aug 2018 19:07:14 +0000 (21:07 +0200)
"Computationally constant-time" means that it might still leak
information about input's length, but only in cases when input
is missing complete BN_ULONG limbs. But even then leak is possible
only if attacker can observe memory access pattern with limb
granularity.

Reviewed-by: Rich Salz <rsalz@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/6889)

(cherry picked from commit 89d8aade5f4011ddeea7827f08ec544c914f275a)

Resolved conflicts:
crypto/bn/bn_lib.c

crypto/bn/bn_lib.c
crypto/bn_int.h

index c6005bf43fc7ee6e0dbbc9e4aad17b042d41aa3a..4ed037d176332dacad01dea84695caf0dd8a1699 100644 (file)
@@ -614,6 +614,42 @@ BIGNUM *BN_bin2bn(const unsigned char *s, int len, BIGNUM *ret)
 }
 
 /* ignore negative */
+static int bn2binpad(const BIGNUM *a, unsigned char *to, int tolen)
+{
+    int i, j, top;
+    BN_ULONG l;
+
+    i = BN_num_bytes(a);
+    if (tolen == -1)
+        tolen = i;
+    else if (tolen < i)
+        return -1;
+
+    if (i == 0) {
+        OPENSSL_cleanse(to, tolen);
+        return tolen;
+    }
+
+    top = a->top * BN_BYTES;
+    for (i = 0, j = tolen; j > 0; i++) {
+        unsigned int mask;
+
+        mask = constant_time_lt(i, top);
+        i -= 1 & ~mask; /* stay on top limb */
+        l = a->d[i / BN_BYTES];
+        to[--j] = (unsigned char)(l >> (8 * (i % BN_BYTES)) & mask);
+    }
+
+    return tolen;
+}
+
+int bn_bn2binpad(const BIGNUM *a, unsigned char *to, int tolen)
+{
+    if (tolen < 0)
+        return -1;
+    return bn2binpad(a, to, tolen);
+}
+
 int BN_bn2bin(const BIGNUM *a, unsigned char *to)
 {
     int n, i;
index 9683e5f60c7ae02a17a5542d0ce397ea8843dcfe..9c42d6f35dc343d01d6608ea18a6605fe8c16830 100644 (file)
@@ -11,3 +11,5 @@ int bn_to_mont_fixed_top(BIGNUM *r, const BIGNUM *a, BN_MONT_CTX *mont,
                          BN_CTX *ctx);
 int bn_mod_add_fixed_top(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
                          const BIGNUM *m);
+
+int bn_bn2binpad(const BIGNUM *a, unsigned char *to, int tolen);