X-Git-Url: https://www.bearssl.org/gitweb//home/git/?p=BearSSL;a=blobdiff_plain;f=src%2Frsa%2Frsa_i31_pub.c;h=d5f3fe2cb51c0c6038f96bb17d2e6ef8d50e431a;hp=18e069f8231ebdea910e80edb9c76d808b5fadc8;hb=e4edfb84eda32c3b3aa548f975c4a13d406db989;hpb=3210f38e0491b39aec1ef419cb4114e9483089fb diff --git a/src/rsa/rsa_i31_pub.c b/src/rsa/rsa_i31_pub.c index 18e069f..d5f3fe2 100644 --- a/src/rsa/rsa_i31_pub.c +++ b/src/rsa/rsa_i31_pub.c @@ -24,6 +24,12 @@ #include "inner.h" +/* + * As a strict minimum, we need four buffers that can hold a + * modular integer. + */ +#define TLEN (4 * (2 + ((BR_MAX_RSA_SIZE + 30) / 31))) + /* see bearssl_rsa.h */ uint32_t br_rsa_i31_public(unsigned char *x, size_t xlen, @@ -31,10 +37,10 @@ br_rsa_i31_public(unsigned char *x, size_t xlen, { const unsigned char *n; size_t nlen; - uint32_t m[1 + ((BR_MAX_RSA_SIZE + 30) / 31)]; - uint32_t a[1 + ((BR_MAX_RSA_SIZE + 30) / 31)]; - uint32_t t1[1 + ((BR_MAX_RSA_SIZE + 30) / 31)]; - uint32_t t2[1 + ((BR_MAX_RSA_SIZE + 30) / 31)]; + uint32_t tmp[1 + TLEN]; + uint32_t *m, *a, *t; + size_t fwlen; + long z; uint32_t m0i, r; /* @@ -50,6 +56,29 @@ br_rsa_i31_public(unsigned char *x, size_t xlen, if (nlen == 0 || nlen > (BR_MAX_RSA_SIZE >> 3) || xlen != nlen) { return 0; } + z = (long)nlen << 3; + fwlen = 1; + while (z > 0) { + z -= 31; + fwlen ++; + } + /* + * Round up length to an even number. + */ + fwlen += (fwlen & 1); + + /* + * The modulus gets decoded into m[]. + * The value to exponentiate goes into a[]. + * The temporaries for modular exponentiation are in t[]. + */ + m = tmp; + a = m + fwlen; + t = m + 2 * fwlen; + + /* + * Decode the modulus. + */ br_i31_decode(m, n, nlen); m0i = br_i31_ninv31(m[1]); @@ -67,7 +96,7 @@ br_rsa_i31_public(unsigned char *x, size_t xlen, /* * Compute the modular exponentiation. */ - br_i31_modpow(a, pk->e, pk->elen, m, m0i, t1, t2); + br_i31_modpow_opt(a, pk->e, pk->elen, m, m0i, t, TLEN - 2 * fwlen); /* * Encode the result.