#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 + 14) / 15)))
+
/* see bearssl_rsa.h */
uint32_t
br_rsa_i15_public(unsigned char *x, size_t xlen,
{
const unsigned char *n;
size_t nlen;
- uint16_t m[1 + ((BR_MAX_RSA_SIZE + 14) / 15)];
- uint16_t a[1 + ((BR_MAX_RSA_SIZE + 14) / 15)];
- uint16_t t1[1 + ((BR_MAX_RSA_SIZE + 14) / 15)];
- uint16_t t2[1 + ((BR_MAX_RSA_SIZE + 14) / 15)];
+ uint16_t tmp[1 + TLEN];
+ uint16_t *m, *a, *t;
+ size_t fwlen;
+ long z;
uint16_t m0i;
uint32_t r;
if (nlen == 0 || nlen > (BR_MAX_RSA_SIZE >> 3) || xlen != nlen) {
return 0;
}
+ z = (long)nlen << 3;
+ fwlen = 1;
+ while (z > 0) {
+ z -= 15;
+ 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 exponentiations are in t[].
+ *
+ * We want the first value word of each integer to be aligned
+ * on a 32-bit boundary.
+ */
+ m = tmp;
+ if (((uintptr_t)m & 2) == 0) {
+ m ++;
+ }
+ a = m + fwlen;
+ t = m + 2 * fwlen;
+
+ /*
+ * Decode the modulus.
+ */
br_i15_decode(m, n, nlen);
m0i = br_i15_ninv15(m[1]);
/*
* Compute the modular exponentiation.
*/
- br_i15_modpow(a, pk->e, pk->elen, m, m0i, t1, t2);
+ br_i15_modpow_opt(a, pk->e, pk->elen, m, m0i, t, TLEN - 2 * fwlen);
/*
* Encode the result.