summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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);