summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndy Polyakov <appro@openssl.org>2018-02-04 15:20:29 +0100
committerAndy Polyakov <appro@openssl.org>2018-08-10 21:07:14 +0200
commit6412738be390dd9bf680cef89f22e4c810ab065f (patch)
tree92d2bd37bd9a9c3bc43ea7b94905b5dd8d9a05b8
parentf72a7ce8bc0a5c0866c6a848a7f54854d67aeba2 (diff)
bn/bn_lib.c: add computationally constant-time bn_bn2binpad.
"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
-rw-r--r--crypto/bn/bn_lib.c36
-rw-r--r--crypto/bn_int.h2
2 files changed, 38 insertions, 0 deletions
diff --git a/crypto/bn/bn_lib.c b/crypto/bn/bn_lib.c
index c6005bf43f..4ed037d176 100644
--- a/crypto/bn/bn_lib.c
+++ b/crypto/bn/bn_lib.c
@@ -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;
diff --git a/crypto/bn_int.h b/crypto/bn_int.h
index 9683e5f60c..9c42d6f35d 100644
--- a/crypto/bn_int.h
+++ b/crypto/bn_int.h
@@ -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);