diff options
author | Andy Polyakov <appro@openssl.org> | 2018-02-04 15:20:29 +0100 |
---|---|---|
committer | Andy Polyakov <appro@openssl.org> | 2018-07-14 13:36:35 +0200 |
commit | 89d8aade5f4011ddeea7827f08ec544c914f275a (patch) | |
tree | b63cbf85eb6b25d85a9bae2120bba51725cd2285 /crypto/bn | |
parent | 1e839545803107b230a8177875de5994f85984de (diff) |
bn/bn_lib.c: make BN_bn2binpad computationally constant-time.
"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/5254)
Diffstat (limited to 'crypto/bn')
-rw-r--r-- | crypto/bn/bn_lib.c | 23 |
1 files changed, 15 insertions, 8 deletions
diff --git a/crypto/bn/bn_lib.c b/crypto/bn/bn_lib.c index b42df82f8e..a582ce5cf3 100644 --- a/crypto/bn/bn_lib.c +++ b/crypto/bn/bn_lib.c @@ -12,6 +12,7 @@ #include "internal/cryptlib.h" #include "bn_lcl.h" #include <openssl/opensslconf.h> +#include "internal/constant_time_locl.h" /* This stuff appears to be completely unused, so is deprecated */ #if OPENSSL_API_COMPAT < 0x00908000L @@ -416,24 +417,30 @@ 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; + int i, j, top; BN_ULONG l; - bn_check_top(a); i = BN_num_bytes(a); if (tolen == -1) tolen = i; else if (tolen < i) return -1; - /* Add leading zeroes if necessary */ - if (tolen > i) { - memset(to, 0, tolen - i); - to += tolen - i; + + if (i == 0) { + OPENSSL_cleanse(to, tolen); + return tolen; } - while (i--) { + + 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++) = (unsigned char)(l >> (8 * (i % BN_BYTES))) & 0xff; + to[--j] = (unsigned char)(l >> (8 * (i % BN_BYTES)) & mask); } + return tolen; } |