diff --git a/mongoose.c b/mongoose.c index 81146146..b3f8da14 100644 --- a/mongoose.c +++ b/mongoose.c @@ -7161,7 +7161,9 @@ void mg_mdash_init(struct mg_mgr *mgr) { void mg_mdash_poll(struct mg_mgr *mgr) { static uint64_t timer = 0; - if (mg_mdash_conn == NULL && mg_timer_expired(&timer, 1000, mg_millis())) { + // No RPC handlers means mdash was never set up, or mg_mdash_free() ran + if (mg_mdash_conn == NULL && mgr->rpcs != NULL && + mg_timer_expired(&timer, 1000, mg_millis())) { MG_INFO(("Connecting to %s", MG_MDASH_URL)); mg_mdash_conn = mg_ws_connect(mgr, MG_MDASH_URL, mg_mdash_fn, NULL, "Origin: %s\r\n" @@ -8332,10 +8334,10 @@ void mg_mgr_free(struct mg_mgr *mgr) { while (t != NULL) tmp = t->next, mg_free(t), t = tmp; mgr->timers = NULL; // Important. Next call to poll won't touch timers for (c = mgr->conns; c != NULL; c = c->next) c->is_closing = 1; - mg_mgr_poll(mgr, 0); #if MG_ENABLE_MDASH - mg_mdash_free(mgr); + mg_mdash_free(mgr); // Before the final poll, so mdash does not reconnect #endif + mg_mgr_poll(mgr, 0); #if MG_ENABLE_FREERTOS_TCP FreeRTOS_DeleteSocketSet(mgr->ss); #endif @@ -21936,7 +21938,9 @@ void mg_tls_ctx_free(struct mg_mgr *mgr) { #define MUL31_lo(x, y) (((uint32_t) (x) * (uint32_t) (y)) & 0x7fffffffU) #define CCOPY br_ccopy -static uint32_t NOT(uint32_t ctl) { return ctl ^ 1; } +static uint32_t NOT(uint32_t ctl) { + return ctl ^ 1; +} static uint32_t MUX(uint32_t ctl, uint32_t x, uint32_t y) { return y ^ (-ctl & (x ^ y)); } @@ -21957,10 +21961,18 @@ static uint32_t GT(uint32_t x, uint32_t y) { static uint32_t BIT_LENGTH(uint32_t x) { uint32_t k, c; k = NEQ(x, 0); - c = GT(x, 0xffff); x = MUX(c, x >> 16, x); k += c << 4; - c = GT(x, 0x00ff); x = MUX(c, x >> 8, x); k += c << 3; - c = GT(x, 0x000f); x = MUX(c, x >> 4, x); k += c << 2; - c = GT(x, 0x0003); x = MUX(c, x >> 2, x); k += c << 1; + c = GT(x, 0xffff); + x = MUX(c, x >> 16, x); + k += c << 4; + c = GT(x, 0x00ff); + x = MUX(c, x >> 8, x); + k += c << 3; + c = GT(x, 0x000f); + x = MUX(c, x >> 4, x); + k += c << 2; + c = GT(x, 0x0003); + x = MUX(c, x >> 2, x); + k += c << 1; k += GT(x, 0x0001); return k; } @@ -21990,11 +22002,14 @@ static uint32_t br_divrem(uint32_t, uint32_t, uint32_t, uint32_t *); static void br_i31_muladd_small(uint32_t *, uint32_t, const uint32_t *); static void br_i31_reduce(uint32_t *, const uint32_t *, const uint32_t *); static void br_i31_rshift(uint32_t *, int); -static void br_i31_decode_reduce(uint32_t *, const void *, size_t, const uint32_t *); +static void br_i31_decode_reduce(uint32_t *, const void *, size_t, + const uint32_t *); static void br_i31_mulacc(uint32_t *, const uint32_t *, const uint32_t *); -static void br_i31_montymul(uint32_t *, const uint32_t *, const uint32_t *, const uint32_t *, uint32_t); +static void br_i31_montymul(uint32_t *, const uint32_t *, const uint32_t *, + const uint32_t *, uint32_t); static void br_i31_to_monty(uint32_t *, const uint32_t *); -static void br_i31_modpow(uint32_t *, const unsigned char *, size_t, const uint32_t *, uint32_t, uint32_t *, uint32_t *); +static void br_i31_modpow(uint32_t *, const unsigned char *, size_t, + const uint32_t *, uint32_t, uint32_t *, uint32_t *); static void br_i31_zero(uint32_t *x, uint32_t bit_len) { *x++ = bit_len; memset(x, 0, ((bit_len + 31) >> 5) * sizeof *x); @@ -22008,642 +22023,604 @@ static uint32_t br_div(uint32_t hi, uint32_t lo, uint32_t d) { uint32_t r; return br_divrem(hi, lo, d, &r); } -static uint32_t -br_i31_add(uint32_t *a, const uint32_t *b, uint32_t ctl) -{ - uint32_t cc; - size_t u, m; +static uint32_t br_i31_add(uint32_t *a, const uint32_t *b, uint32_t ctl) { + uint32_t cc; + size_t u, m; - cc = 0; - m = (a[0] + 63) >> 5; - for (u = 1; u < m; u ++) { - uint32_t aw, bw, naw; + cc = 0; + m = (a[0] + 63) >> 5; + for (u = 1; u < m; u++) { + uint32_t aw, bw, naw; - aw = a[u]; - bw = b[u]; - naw = aw + bw + cc; - cc = naw >> 31; - a[u] = MUX(ctl, naw & (uint32_t)0x7FFFFFFF, aw); - } - return cc; + aw = a[u]; + bw = b[u]; + naw = aw + bw + cc; + cc = naw >> 31; + a[u] = MUX(ctl, naw & (uint32_t) 0x7FFFFFFF, aw); + } + return cc; } -static uint32_t -br_i31_sub(uint32_t *a, const uint32_t *b, uint32_t ctl) -{ - uint32_t cc; - size_t u, m; +static uint32_t br_i31_sub(uint32_t *a, const uint32_t *b, uint32_t ctl) { + uint32_t cc; + size_t u, m; - cc = 0; - m = (a[0] + 63) >> 5; - for (u = 1; u < m; u ++) { - uint32_t aw, bw, naw; + cc = 0; + m = (a[0] + 63) >> 5; + for (u = 1; u < m; u++) { + uint32_t aw, bw, naw; - aw = a[u]; - bw = b[u]; - naw = aw - bw - cc; - cc = naw >> 31; - a[u] = MUX(ctl, naw & 0x7FFFFFFF, aw); - } - return cc; + aw = a[u]; + bw = b[u]; + naw = aw - bw - cc; + cc = naw >> 31; + a[u] = MUX(ctl, naw & 0x7FFFFFFF, aw); + } + return cc; } -static uint32_t -br_i31_bit_length(uint32_t *x, size_t xlen) -{ - uint32_t tw, twk; +static uint32_t br_i31_bit_length(uint32_t *x, size_t xlen) { + uint32_t tw, twk; - tw = 0; - twk = 0; - while (xlen -- > 0) { - uint32_t w, c; + tw = 0; + twk = 0; + while (xlen-- > 0) { + uint32_t w, c; - c = EQ(tw, 0); - w = x[xlen]; - tw = MUX(c, w, tw); - twk = MUX(c, (uint32_t)xlen, twk); - } - return (twk << 5) + BIT_LENGTH(tw); + c = EQ(tw, 0); + w = x[xlen]; + tw = MUX(c, w, tw); + twk = MUX(c, (uint32_t) xlen, twk); + } + return (twk << 5) + BIT_LENGTH(tw); } -static void -br_i31_decode(uint32_t *x, const void *src, size_t len) -{ - const unsigned char *buf; - size_t u, v; - uint32_t acc; - int acc_len; +static void br_i31_decode(uint32_t *x, const void *src, size_t len) { + const unsigned char *buf; + size_t u, v; + uint32_t acc; + int acc_len; - buf = (const unsigned char *) src; - u = len; - v = 1; - acc = 0; - acc_len = 0; - while (u -- > 0) { - uint32_t b; + buf = (const unsigned char *) src; + u = len; + v = 1; + acc = 0; + acc_len = 0; + while (u-- > 0) { + uint32_t b; - b = buf[u]; - acc |= (b << acc_len); - acc_len += 8; - if (acc_len >= 31) { - x[v ++] = acc & (uint32_t)0x7FFFFFFF; - acc_len -= 31; - acc = b >> (8 - acc_len); - } - } - if (acc_len != 0) { - x[v ++] = acc; - } - x[0] = br_i31_bit_length(x + 1, v - 1); + b = buf[u]; + acc |= (b << acc_len); + acc_len += 8; + if (acc_len >= 31) { + x[v++] = acc & (uint32_t) 0x7FFFFFFF; + acc_len -= 31; + acc = b >> (8 - acc_len); + } + } + if (acc_len != 0) { + x[v++] = acc; + } + x[0] = br_i31_bit_length(x + 1, v - 1); } -static void -br_i31_encode(void *dst, size_t len, const uint32_t *x) -{ - unsigned char *buf; - size_t k, xlen; - uint32_t acc; - int acc_len; +static void br_i31_encode(void *dst, size_t len, const uint32_t *x) { + unsigned char *buf; + size_t k, xlen; + uint32_t acc; + int acc_len; - xlen = (x[0] + 31) >> 5; - if (xlen == 0) { - memset(dst, 0, len); - return; - } - buf = (unsigned char *)dst + len; - k = 1; - acc = 0; - acc_len = 0; - while (len != 0) { - uint32_t w; + xlen = (x[0] + 31) >> 5; + if (xlen == 0) { + memset(dst, 0, len); + return; + } + buf = (unsigned char *) dst + len; + k = 1; + acc = 0; + acc_len = 0; + while (len != 0) { + uint32_t w; - w = (k <= xlen) ? x[k] : 0; - k ++; - if (acc_len == 0) { - acc = w; - acc_len = 31; - } else { - uint32_t z; + w = (k <= xlen) ? x[k] : 0; + k++; + if (acc_len == 0) { + acc = w; + acc_len = 31; + } else { + uint32_t z; - z = acc | (w << acc_len); - acc_len --; - acc = w >> (31 - acc_len); - if (len >= 4) { - buf -= 4; - len -= 4; - br_enc32be(buf, z); - } else { - switch (len) { - case 3: - buf[-3] = (unsigned char)(z >> 16); - /* fall through */ - case 2: - buf[-2] = (unsigned char)(z >> 8); - /* fall through */ - case 1: - buf[-1] = (unsigned char)z; - break; - } - return; - } - } - } + z = acc | (w << acc_len); + acc_len--; + acc = w >> (31 - acc_len); + if (len >= 4) { + buf -= 4; + len -= 4; + br_enc32be(buf, z); + } else { + switch (len) { + case 3: + buf[-3] = (unsigned char) (z >> 16); + /* fall through */ + case 2: + buf[-2] = (unsigned char) (z >> 8); + /* fall through */ + case 1: + buf[-1] = (unsigned char) z; + break; + } + return; + } + } + } } -static uint32_t -br_i31_ninv31(uint32_t x) -{ - uint32_t y; +static uint32_t br_i31_ninv31(uint32_t x) { + uint32_t y; - y = 2 - x; - y *= 2 - y * x; - y *= 2 - y * x; - y *= 2 - y * x; - y *= 2 - y * x; - return MUX(x & 1, -y, 0) & 0x7FFFFFFF; + y = 2 - x; + y *= 2 - y * x; + y *= 2 - y * x; + y *= 2 - y * x; + y *= 2 - y * x; + return MUX(x & 1, -y, 0) & 0x7FFFFFFF; } -static uint32_t -br_divrem(uint32_t hi, uint32_t lo, uint32_t d, uint32_t *r) -{ - /* TODO: optimize this */ - uint32_t q; - uint32_t ch, cf; - int k; +static uint32_t br_divrem(uint32_t hi, uint32_t lo, uint32_t d, uint32_t *r) { + /* TODO: optimize this */ + uint32_t q; + uint32_t ch, cf; + int k; - q = 0; - ch = EQ(hi, d); - hi = MUX(ch, 0, hi); - for (k = 31; k > 0; k --) { - int j; - uint32_t w, ctl, hi2, lo2; + q = 0; + ch = EQ(hi, d); + hi = MUX(ch, 0, hi); + for (k = 31; k > 0; k--) { + int j; + uint32_t w, ctl, hi2, lo2; - j = 32 - k; - w = (hi << j) | (lo >> k); - ctl = GE(w, d) | (hi >> k); - hi2 = (w - d) >> j; - lo2 = lo - (d << k); - hi = MUX(ctl, hi2, hi); - lo = MUX(ctl, lo2, lo); - q |= ctl << k; - } - cf = GE(lo, d) | hi; - q |= cf; - *r = MUX(cf, lo - d, lo); - return q; + j = 32 - k; + w = (hi << j) | (lo >> k); + ctl = GE(w, d) | (hi >> k); + hi2 = (w - d) >> j; + lo2 = lo - (d << k); + hi = MUX(ctl, hi2, hi); + lo = MUX(ctl, lo2, lo); + q |= ctl << k; + } + cf = GE(lo, d) | hi; + q |= cf; + *r = MUX(cf, lo - d, lo); + return q; } -static void -br_i31_muladd_small(uint32_t *x, uint32_t z, const uint32_t *m) -{ - uint32_t m_bitlen; - unsigned mblr; - size_t u, mlen; - uint32_t a0, a1, b0, hi, g, q, tb; - uint32_t under, over; - uint32_t cc; +static void br_i31_muladd_small(uint32_t *x, uint32_t z, const uint32_t *m) { + uint32_t m_bitlen; + unsigned mblr; + size_t u, mlen; + uint32_t a0, a1, b0, hi, g, q, tb; + uint32_t under, over; + uint32_t cc; - /* - * We can test on the modulus bit length since we accept to - * leak that length. - */ - m_bitlen = m[0]; - if (m_bitlen == 0) { - return; - } - if (m_bitlen <= 31) { - uint32_t lo; + /* + * We can test on the modulus bit length since we accept to + * leak that length. + */ + m_bitlen = m[0]; + if (m_bitlen == 0) { + return; + } + if (m_bitlen <= 31) { + uint32_t lo; - hi = x[1] >> 1; - lo = (x[1] << 31) | z; - x[1] = br_rem(hi, lo, m[1]); - return; - } - mlen = (m_bitlen + 31) >> 5; - mblr = (unsigned)m_bitlen & 31; + hi = x[1] >> 1; + lo = (x[1] << 31) | z; + x[1] = br_rem(hi, lo, m[1]); + return; + } + mlen = (m_bitlen + 31) >> 5; + mblr = (unsigned) m_bitlen & 31; - /* - * Principle: we estimate the quotient (x*2^31+z)/m by - * doing a 64/32 division with the high words. - * - * Let: - * w = 2^31 - * a = (w*a0 + a1) * w^N + a2 - * b = b0 * w^N + b2 - * such that: - * 0 <= a0 < w - * 0 <= a1 < w - * 0 <= a2 < w^N - * w/2 <= b0 < w - * 0 <= b2 < w^N - * a < w*b - * I.e. the two top words of a are a0:a1, the top word of b is - * b0, we ensured that b0 is "full" (high bit set), and a is - * such that the quotient q = a/b fits on one word (0 <= q < w). - * - * If a = b*q + r (with 0 <= r < q), we can estimate q by - * doing an Euclidean division on the top words: - * a0*w+a1 = b0*u + v (with 0 <= v < b0) - * Then the following holds: - * 0 <= u <= w - * u-2 <= q <= u - */ - hi = x[mlen]; - if (mblr == 0) { - a0 = x[mlen]; - memmove(x + 2, x + 1, (mlen - 1) * sizeof *x); - x[1] = z; - a1 = x[mlen]; - b0 = m[mlen]; - } else { - a0 = ((x[mlen] << (31 - mblr)) | (x[mlen - 1] >> mblr)) - & 0x7FFFFFFF; - memmove(x + 2, x + 1, (mlen - 1) * sizeof *x); - x[1] = z; - a1 = ((x[mlen] << (31 - mblr)) | (x[mlen - 1] >> mblr)) - & 0x7FFFFFFF; - b0 = ((m[mlen] << (31 - mblr)) | (m[mlen - 1] >> mblr)) - & 0x7FFFFFFF; - } + /* + * Principle: we estimate the quotient (x*2^31+z)/m by + * doing a 64/32 division with the high words. + * + * Let: + * w = 2^31 + * a = (w*a0 + a1) * w^N + a2 + * b = b0 * w^N + b2 + * such that: + * 0 <= a0 < w + * 0 <= a1 < w + * 0 <= a2 < w^N + * w/2 <= b0 < w + * 0 <= b2 < w^N + * a < w*b + * I.e. the two top words of a are a0:a1, the top word of b is + * b0, we ensured that b0 is "full" (high bit set), and a is + * such that the quotient q = a/b fits on one word (0 <= q < w). + * + * If a = b*q + r (with 0 <= r < q), we can estimate q by + * doing an Euclidean division on the top words: + * a0*w+a1 = b0*u + v (with 0 <= v < b0) + * Then the following holds: + * 0 <= u <= w + * u-2 <= q <= u + */ + hi = x[mlen]; + if (mblr == 0) { + a0 = x[mlen]; + memmove(x + 2, x + 1, (mlen - 1) * sizeof *x); + x[1] = z; + a1 = x[mlen]; + b0 = m[mlen]; + } else { + a0 = ((x[mlen] << (31 - mblr)) | (x[mlen - 1] >> mblr)) & 0x7FFFFFFF; + memmove(x + 2, x + 1, (mlen - 1) * sizeof *x); + x[1] = z; + a1 = ((x[mlen] << (31 - mblr)) | (x[mlen - 1] >> mblr)) & 0x7FFFFFFF; + b0 = ((m[mlen] << (31 - mblr)) | (m[mlen - 1] >> mblr)) & 0x7FFFFFFF; + } - /* - * We estimate a divisor q. If the quotient returned by br_div() - * is g: - * -- If a0 == b0 then g == 0; we want q = 0x7FFFFFFF. - * -- Otherwise: - * -- if g == 0 then we set q = 0; - * -- otherwise, we set q = g - 1. - * The properties described above then ensure that the true - * quotient is q-1, q or q+1. - * - * Take care that a0, a1 and b0 are 31-bit words, not 32-bit. We - * must adjust the parameters to br_div() accordingly. - */ - g = br_div(a0 >> 1, a1 | (a0 << 31), b0); - q = MUX(EQ(a0, b0), 0x7FFFFFFF, MUX(EQ(g, 0), 0, g - 1)); + /* + * We estimate a divisor q. If the quotient returned by br_div() + * is g: + * -- If a0 == b0 then g == 0; we want q = 0x7FFFFFFF. + * -- Otherwise: + * -- if g == 0 then we set q = 0; + * -- otherwise, we set q = g - 1. + * The properties described above then ensure that the true + * quotient is q-1, q or q+1. + * + * Take care that a0, a1 and b0 are 31-bit words, not 32-bit. We + * must adjust the parameters to br_div() accordingly. + */ + g = br_div(a0 >> 1, a1 | (a0 << 31), b0); + q = MUX(EQ(a0, b0), 0x7FFFFFFF, MUX(EQ(g, 0), 0, g - 1)); - /* - * We subtract q*m from x (with the extra high word of value 'hi'). - * Since q may be off by 1 (in either direction), we may have to - * add or subtract m afterwards. - * - * The 'tb' flag will be true (1) at the end of the loop if the - * result is greater than or equal to the modulus (not counting - * 'hi' or the carry). - */ - cc = 0; - tb = 1; - for (u = 1; u <= mlen; u ++) { - uint32_t mw, zw, xw, nxw; - uint64_t zl; + /* + * We subtract q*m from x (with the extra high word of value 'hi'). + * Since q may be off by 1 (in either direction), we may have to + * add or subtract m afterwards. + * + * The 'tb' flag will be true (1) at the end of the loop if the + * result is greater than or equal to the modulus (not counting + * 'hi' or the carry). + */ + cc = 0; + tb = 1; + for (u = 1; u <= mlen; u++) { + uint32_t mw, zw, xw, nxw; + uint64_t zl; - mw = m[u]; - zl = MUL31(mw, q) + cc; - cc = (uint32_t)(zl >> 31); - zw = (uint32_t)zl & (uint32_t)0x7FFFFFFF; - xw = x[u]; - nxw = xw - zw; - cc += nxw >> 31; - nxw &= 0x7FFFFFFF; - x[u] = nxw; - tb = MUX(EQ(nxw, mw), tb, GT(nxw, mw)); - } + mw = m[u]; + zl = MUL31(mw, q) + cc; + cc = (uint32_t) (zl >> 31); + zw = (uint32_t) zl & (uint32_t) 0x7FFFFFFF; + xw = x[u]; + nxw = xw - zw; + cc += nxw >> 31; + nxw &= 0x7FFFFFFF; + x[u] = nxw; + tb = MUX(EQ(nxw, mw), tb, GT(nxw, mw)); + } - /* - * If we underestimated q, then either cc < hi (one extra bit - * beyond the top array word), or cc == hi and tb is true (no - * extra bit, but the result is not lower than the modulus). In - * these cases we must subtract m once. - * - * Otherwise, we may have overestimated, which will show as - * cc > hi (thus a negative result). Correction is adding m once. - */ - over = GT(cc, hi); - under = ~over & (tb | LT(cc, hi)); - br_i31_add(x, m, over); - br_i31_sub(x, m, under); + /* + * If we underestimated q, then either cc < hi (one extra bit + * beyond the top array word), or cc == hi and tb is true (no + * extra bit, but the result is not lower than the modulus). In + * these cases we must subtract m once. + * + * Otherwise, we may have overestimated, which will show as + * cc > hi (thus a negative result). Correction is adding m once. + */ + over = GT(cc, hi); + under = ~over & (tb | LT(cc, hi)); + br_i31_add(x, m, over); + br_i31_sub(x, m, under); } -static void -br_i31_reduce(uint32_t *x, const uint32_t *a, const uint32_t *m) -{ - uint32_t m_bitlen, a_bitlen; - size_t mlen, alen, u; +static void br_i31_reduce(uint32_t *x, const uint32_t *a, const uint32_t *m) { + uint32_t m_bitlen, a_bitlen; + size_t mlen, alen, u; - m_bitlen = m[0]; - mlen = (m_bitlen + 31) >> 5; + m_bitlen = m[0]; + mlen = (m_bitlen + 31) >> 5; - x[0] = m_bitlen; - if (m_bitlen == 0) { - return; - } + x[0] = m_bitlen; + if (m_bitlen == 0) { + return; + } - /* - * If the source is shorter, then simply copy all words from a[] - * and zero out the upper words. - */ - a_bitlen = a[0]; - alen = (a_bitlen + 31) >> 5; - if (a_bitlen < m_bitlen) { - memcpy(x + 1, a + 1, alen * sizeof *a); - for (u = alen; u < mlen; u ++) { - x[u + 1] = 0; - } - return; - } + /* + * If the source is shorter, then simply copy all words from a[] + * and zero out the upper words. + */ + a_bitlen = a[0]; + alen = (a_bitlen + 31) >> 5; + if (a_bitlen < m_bitlen) { + memcpy(x + 1, a + 1, alen * sizeof *a); + for (u = alen; u < mlen; u++) { + x[u + 1] = 0; + } + return; + } - /* - * The source length is at least equal to that of the modulus. - * We must thus copy N-1 words, and input the remaining words - * one by one. - */ - memcpy(x + 1, a + 2 + (alen - mlen), (mlen - 1) * sizeof *a); - x[mlen] = 0; - for (u = 1 + alen - mlen; u > 0; u --) { - br_i31_muladd_small(x, a[u], m); - } + /* + * The source length is at least equal to that of the modulus. + * We must thus copy N-1 words, and input the remaining words + * one by one. + */ + memcpy(x + 1, a + 2 + (alen - mlen), (mlen - 1) * sizeof *a); + x[mlen] = 0; + for (u = 1 + alen - mlen; u > 0; u--) { + br_i31_muladd_small(x, a[u], m); + } } -static void -br_i31_rshift(uint32_t *x, int count) -{ - size_t u, len; - uint32_t r; +static void br_i31_rshift(uint32_t *x, int count) { + size_t u, len; + uint32_t r; - len = (x[0] + 31) >> 5; - if (len == 0) { - return; - } - r = x[1] >> count; - for (u = 2; u <= len; u ++) { - uint32_t w; + len = (x[0] + 31) >> 5; + if (len == 0) { + return; + } + r = x[1] >> count; + for (u = 2; u <= len; u++) { + uint32_t w; - w = x[u]; - x[u - 1] = ((w << (31 - count)) | r) & 0x7FFFFFFF; - r = w >> count; - } - x[len] = r; + w = x[u]; + x[u - 1] = ((w << (31 - count)) | r) & 0x7FFFFFFF; + r = w >> count; + } + x[len] = r; } -static void -br_i31_decode_reduce(uint32_t *x, - const void *src, size_t len, const uint32_t *m) -{ - uint32_t m_ebitlen, m_rbitlen; - size_t mblen, k; - const unsigned char *buf; - uint32_t acc; - int acc_len; +static void br_i31_decode_reduce(uint32_t *x, const void *src, size_t len, + const uint32_t *m) { + uint32_t m_ebitlen, m_rbitlen; + size_t mblen, k; + const unsigned char *buf; + uint32_t acc; + int acc_len; - /* - * Get the encoded bit length. - */ - m_ebitlen = m[0]; + /* + * Get the encoded bit length. + */ + m_ebitlen = m[0]; - /* - * Special case for an invalid (null) modulus. - */ - if (m_ebitlen == 0) { - x[0] = 0; - return; - } + /* + * Special case for an invalid (null) modulus. + */ + if (m_ebitlen == 0) { + x[0] = 0; + return; + } - /* - * Clear the destination. - */ - br_i31_zero(x, m_ebitlen); + /* + * Clear the destination. + */ + br_i31_zero(x, m_ebitlen); - /* - * First decode directly as many bytes as possible. This requires - * computing the actual bit length. - */ - m_rbitlen = m_ebitlen >> 5; - m_rbitlen = (m_ebitlen & 31) + (m_rbitlen << 5) - m_rbitlen; - mblen = (m_rbitlen + 7) >> 3; - k = mblen - 1; - if (k >= len) { - br_i31_decode(x, src, len); - x[0] = m_ebitlen; - return; - } - buf = (const unsigned char *) src; - br_i31_decode(x, buf, k); - x[0] = m_ebitlen; + /* + * First decode directly as many bytes as possible. This requires + * computing the actual bit length. + */ + m_rbitlen = m_ebitlen >> 5; + m_rbitlen = (m_ebitlen & 31) + (m_rbitlen << 5) - m_rbitlen; + mblen = (m_rbitlen + 7) >> 3; + k = mblen - 1; + if (k >= len) { + br_i31_decode(x, src, len); + x[0] = m_ebitlen; + return; + } + buf = (const unsigned char *) src; + br_i31_decode(x, buf, k); + x[0] = m_ebitlen; - /* - * Input remaining bytes, using 31-bit words. - */ - acc = 0; - acc_len = 0; - while (k < len) { - uint32_t v; + /* + * Input remaining bytes, using 31-bit words. + */ + acc = 0; + acc_len = 0; + while (k < len) { + uint32_t v; - v = buf[k ++]; - if (acc_len >= 23) { - acc_len -= 23; - acc <<= (8 - acc_len); - acc |= v >> acc_len; - br_i31_muladd_small(x, acc, m); - acc = v & (0xFF >> (8 - acc_len)); - } else { - acc = (acc << 8) | v; - acc_len += 8; - } - } + v = buf[k++]; + if (acc_len >= 23) { + acc_len -= 23; + acc <<= (8 - acc_len); + acc |= v >> acc_len; + br_i31_muladd_small(x, acc, m); + acc = v & (0xFF >> (8 - acc_len)); + } else { + acc = (acc << 8) | v; + acc_len += 8; + } + } - /* - * We may have some bits accumulated. We then perform a shift to - * be able to inject these bits as a full 31-bit word. - */ - if (acc_len != 0) { - acc = (acc | (x[1] << acc_len)) & 0x7FFFFFFF; - br_i31_rshift(x, 31 - acc_len); - br_i31_muladd_small(x, acc, m); - } + /* + * We may have some bits accumulated. We then perform a shift to + * be able to inject these bits as a full 31-bit word. + */ + if (acc_len != 0) { + acc = (acc | (x[1] << acc_len)) & 0x7FFFFFFF; + br_i31_rshift(x, 31 - acc_len); + br_i31_muladd_small(x, acc, m); + } } -static void -br_i31_mulacc(uint32_t *d, const uint32_t *a, const uint32_t *b) -{ - size_t alen, blen, u; - uint32_t dl, dh; +static void br_i31_mulacc(uint32_t *d, const uint32_t *a, const uint32_t *b) { + size_t alen, blen, u; + uint32_t dl, dh; - alen = (a[0] + 31) >> 5; - blen = (b[0] + 31) >> 5; + alen = (a[0] + 31) >> 5; + blen = (b[0] + 31) >> 5; - /* - * We want to add the two bit lengths, but these are encoded, - * which requires some extra care. - */ - dl = (a[0] & 31) + (b[0] & 31); - dh = (a[0] >> 5) + (b[0] >> 5); - d[0] = (dh << 5) + dl + (~(uint32_t)(dl - 31) >> 31); + /* + * We want to add the two bit lengths, but these are encoded, + * which requires some extra care. + */ + dl = (a[0] & 31) + (b[0] & 31); + dh = (a[0] >> 5) + (b[0] >> 5); + d[0] = (dh << 5) + dl + (~(uint32_t) (dl - 31) >> 31); - for (u = 0; u < blen; u ++) { - uint32_t f; - size_t v; + for (u = 0; u < blen; u++) { + uint32_t f; + size_t v; - /* - * Carry always fits on 31 bits; we want to keep it in a - * 32-bit register on 32-bit architectures (on a 64-bit - * architecture, cast down from 64 to 32 bits means - * clearing the high bits, which is not free; on a 32-bit - * architecture, the same operation really means ignoring - * the top register, which has negative or zero cost). - */ + /* + * Carry always fits on 31 bits; we want to keep it in a + * 32-bit register on 32-bit architectures (on a 64-bit + * architecture, cast down from 64 to 32 bits means + * clearing the high bits, which is not free; on a 32-bit + * architecture, the same operation really means ignoring + * the top register, which has negative or zero cost). + */ #if BR_64 - uint64_t cc; + uint64_t cc; #else - uint32_t cc; + uint32_t cc; #endif - f = b[1 + u]; - cc = 0; - for (v = 0; v < alen; v ++) { - uint64_t z; + f = b[1 + u]; + cc = 0; + for (v = 0; v < alen; v++) { + uint64_t z; - z = (uint64_t)d[1 + u + v] + MUL31(f, a[1 + v]) + cc; - cc = z >> 31; - d[1 + u + v] = (uint32_t)z & 0x7FFFFFFF; - } - d[1 + u + alen] = (uint32_t)cc; - } + z = (uint64_t) d[1 + u + v] + MUL31(f, a[1 + v]) + cc; + cc = z >> 31; + d[1 + u + v] = (uint32_t) z & 0x7FFFFFFF; + } + d[1 + u + alen] = (uint32_t) cc; + } } -static void -br_i31_montymul(uint32_t *d, const uint32_t *x, const uint32_t *y, - const uint32_t *m, uint32_t m0i) -{ - /* - * Each outer loop iteration computes: - * d <- (d + xu*y + f*m) / 2^31 - * We have xu <= 2^31-1 and f <= 2^31-1. - * Thus, if d <= 2*m-1 on input, then: - * 2*m-1 + 2*(2^31-1)*m <= (2^32)*m-1 - * and the new d value is less than 2*m. - * - * We represent d over 31-bit words, with an extra word 'dh' - * which can thus be only 0 or 1. - */ - size_t len, len4, u, v; - uint32_t dh; +static void br_i31_montymul(uint32_t *d, const uint32_t *x, const uint32_t *y, + const uint32_t *m, uint32_t m0i) { + /* + * Each outer loop iteration computes: + * d <- (d + xu*y + f*m) / 2^31 + * We have xu <= 2^31-1 and f <= 2^31-1. + * Thus, if d <= 2*m-1 on input, then: + * 2*m-1 + 2*(2^31-1)*m <= (2^32)*m-1 + * and the new d value is less than 2*m. + * + * We represent d over 31-bit words, with an extra word 'dh' + * which can thus be only 0 or 1. + */ + size_t len, len4, u, v; + uint32_t dh; - len = (m[0] + 31) >> 5; - len4 = len & ~(size_t)3; - br_i31_zero(d, m[0]); - dh = 0; - for (u = 0; u < len; u ++) { - /* - * The carry for each operation fits on 32 bits: - * d[v+1] <= 2^31-1 - * xu*y[v+1] <= (2^31-1)*(2^31-1) - * f*m[v+1] <= (2^31-1)*(2^31-1) - * r <= 2^32-1 - * (2^31-1) + 2*(2^31-1)*(2^31-1) + (2^32-1) = 2^63 - 2^31 - * After division by 2^31, the new r is then at most 2^32-1 - * - * Using a 32-bit carry has performance benefits on 32-bit - * systems; however, on 64-bit architectures, we prefer to - * keep the carry (r) in a 64-bit register, thus avoiding some - * "clear high bits" operations. - */ - uint32_t f, xu; + len = (m[0] + 31) >> 5; + len4 = len & ~(size_t) 3; + br_i31_zero(d, m[0]); + dh = 0; + for (u = 0; u < len; u++) { + /* + * The carry for each operation fits on 32 bits: + * d[v+1] <= 2^31-1 + * xu*y[v+1] <= (2^31-1)*(2^31-1) + * f*m[v+1] <= (2^31-1)*(2^31-1) + * r <= 2^32-1 + * (2^31-1) + 2*(2^31-1)*(2^31-1) + (2^32-1) = 2^63 - 2^31 + * After division by 2^31, the new r is then at most 2^32-1 + * + * Using a 32-bit carry has performance benefits on 32-bit + * systems; however, on 64-bit architectures, we prefer to + * keep the carry (r) in a 64-bit register, thus avoiding some + * "clear high bits" operations. + */ + uint32_t f, xu; #if BR_64 - uint64_t r; + uint64_t r; #else - uint32_t r; + uint32_t r; #endif - xu = x[u + 1]; - f = MUL31_lo((d[1] + MUL31_lo(x[u + 1], y[1])), m0i); + xu = x[u + 1]; + f = MUL31_lo((d[1] + MUL31_lo(x[u + 1], y[1])), m0i); - r = 0; - for (v = 0; v < len4; v += 4) { - uint64_t z; + r = 0; + for (v = 0; v < len4; v += 4) { + uint64_t z; - z = (uint64_t)d[v + 1] + MUL31(xu, y[v + 1]) - + MUL31(f, m[v + 1]) + r; - r = z >> 31; - d[v + 0] = (uint32_t)z & 0x7FFFFFFF; - z = (uint64_t)d[v + 2] + MUL31(xu, y[v + 2]) - + MUL31(f, m[v + 2]) + r; - r = z >> 31; - d[v + 1] = (uint32_t)z & 0x7FFFFFFF; - z = (uint64_t)d[v + 3] + MUL31(xu, y[v + 3]) - + MUL31(f, m[v + 3]) + r; - r = z >> 31; - d[v + 2] = (uint32_t)z & 0x7FFFFFFF; - z = (uint64_t)d[v + 4] + MUL31(xu, y[v + 4]) - + MUL31(f, m[v + 4]) + r; - r = z >> 31; - d[v + 3] = (uint32_t)z & 0x7FFFFFFF; - } - for (; v < len; v ++) { - uint64_t z; + z = (uint64_t) d[v + 1] + MUL31(xu, y[v + 1]) + MUL31(f, m[v + 1]) + r; + r = z >> 31; + d[v + 0] = (uint32_t) z & 0x7FFFFFFF; + z = (uint64_t) d[v + 2] + MUL31(xu, y[v + 2]) + MUL31(f, m[v + 2]) + r; + r = z >> 31; + d[v + 1] = (uint32_t) z & 0x7FFFFFFF; + z = (uint64_t) d[v + 3] + MUL31(xu, y[v + 3]) + MUL31(f, m[v + 3]) + r; + r = z >> 31; + d[v + 2] = (uint32_t) z & 0x7FFFFFFF; + z = (uint64_t) d[v + 4] + MUL31(xu, y[v + 4]) + MUL31(f, m[v + 4]) + r; + r = z >> 31; + d[v + 3] = (uint32_t) z & 0x7FFFFFFF; + } + for (; v < len; v++) { + uint64_t z; - z = (uint64_t)d[v + 1] + MUL31(xu, y[v + 1]) - + MUL31(f, m[v + 1]) + r; - r = z >> 31; - d[v] = (uint32_t)z & 0x7FFFFFFF; - } + z = (uint64_t) d[v + 1] + MUL31(xu, y[v + 1]) + MUL31(f, m[v + 1]) + r; + r = z >> 31; + d[v] = (uint32_t) z & 0x7FFFFFFF; + } - /* - * Since the new dh can only be 0 or 1, the addition of - * the old dh with the carry MUST fit on 32 bits, and - * thus can be done into dh itself. - */ - dh += (uint32_t) r; - d[len] = dh & 0x7FFFFFFF; - dh >>= 31; - } + /* + * Since the new dh can only be 0 or 1, the addition of + * the old dh with the carry MUST fit on 32 bits, and + * thus can be done into dh itself. + */ + dh += (uint32_t) r; + d[len] = dh & 0x7FFFFFFF; + dh >>= 31; + } - /* - * We must write back the bit length because it was overwritten in - * the loop (not overwriting it would require a test in the loop, - * which would yield bigger and slower code). - */ - d[0] = m[0]; + /* + * We must write back the bit length because it was overwritten in + * the loop (not overwriting it would require a test in the loop, + * which would yield bigger and slower code). + */ + d[0] = m[0]; - /* - * d[] may still be greater than m[] at that point; notably, the - * 'dh' word may be non-zero. - */ - br_i31_sub(d, m, NEQ(dh, 0) | NOT(br_i31_sub(d, m, 0))); + /* + * d[] may still be greater than m[] at that point; notably, the + * 'dh' word may be non-zero. + */ + br_i31_sub(d, m, NEQ(dh, 0) | NOT(br_i31_sub(d, m, 0))); } -static void -br_i31_to_monty(uint32_t *x, const uint32_t *m) -{ - uint32_t k; +static void br_i31_to_monty(uint32_t *x, const uint32_t *m) { + uint32_t k; - for (k = (m[0] + 31) >> 5; k > 0; k --) { - br_i31_muladd_small(x, 0, m); - } + for (k = (m[0] + 31) >> 5; k > 0; k--) { + br_i31_muladd_small(x, 0, m); + } } -static void -br_i31_modpow(uint32_t *x, - const unsigned char *e, size_t elen, - const uint32_t *m, uint32_t m0i, uint32_t *t1, uint32_t *t2) -{ - size_t mlen; - uint32_t k; +static void br_i31_modpow(uint32_t *x, const unsigned char *e, size_t elen, + const uint32_t *m, uint32_t m0i, uint32_t *t1, + uint32_t *t2) { + size_t mlen; + uint32_t k; - /* - * 'mlen' is the length of m[] expressed in bytes (including - * the "bit length" first field). - */ - mlen = ((m[0] + 63) >> 5) * sizeof m[0]; + /* + * 'mlen' is the length of m[] expressed in bytes (including + * the "bit length" first field). + */ + mlen = ((m[0] + 63) >> 5) * sizeof m[0]; - /* - * Throughout the algorithm: - * -- t1[] is in Montgomery representation; it contains x, x^2, - * x^4, x^8... - * -- The result is accumulated, in normal representation, in - * the x[] array. - * -- t2[] is used as destination buffer for each multiplication. - * - * Note that there is no need to call br_i32_from_monty(). - */ - memcpy(t1, x, mlen); - br_i31_to_monty(t1, m); - br_i31_zero(x, m[0]); - x[1] = 1; - for (k = 0; k < ((uint32_t)elen << 3); k ++) { - uint32_t ctl; + /* + * Throughout the algorithm: + * -- t1[] is in Montgomery representation; it contains x, x^2, + * x^4, x^8... + * -- The result is accumulated, in normal representation, in + * the x[] array. + * -- t2[] is used as destination buffer for each multiplication. + * + * Note that there is no need to call br_i32_from_monty(). + */ + memcpy(t1, x, mlen); + br_i31_to_monty(t1, m); + br_i31_zero(x, m[0]); + x[1] = 1; + for (k = 0; k < ((uint32_t) elen << 3); k++) { + uint32_t ctl; - ctl = (e[elen - 1 - (k >> 3)] >> (k & 7)) & 1; - br_i31_montymul(t2, x, t1, m, m0i); - CCOPY(ctl, x, t2, mlen); - br_i31_montymul(t2, t1, t1, m, m0i); - memcpy(t1, t2, mlen); - } + ctl = (e[elen - 1 - (k >> 3)] >> (k & 7)) & 1; + br_i31_montymul(t2, x, t1, m, m0i); + CCOPY(ctl, x, t2, mlen); + br_i31_montymul(t2, t1, t1, m, m0i); + memcpy(t1, t2, mlen); + } } static size_t rsa_trim(const uint8_t **p, size_t n) { @@ -22671,8 +22648,8 @@ static int rsa_i31_eq(const uint32_t *a, const uint32_t *b) { } int mg_rsa_mod_pow(const uint8_t *mod, size_t modsz, const uint8_t *exp, - size_t expsz, const uint8_t *msg, size_t msgsz, - uint8_t *out, size_t outsz) { + size_t expsz, const uint8_t *msg, size_t msgsz, uint8_t *out, + size_t outsz) { uint32_t tmp[4 * BR_RSA_WORDS], *m = tmp, *x, *t1, *t2, m0i; int fwlen; if (out == NULL) return -1; @@ -22698,12 +22675,10 @@ int mg_rsa_mod_pow(const uint8_t *mod, size_t modsz, const uint8_t *exp, return 0; } -int mg_rsa_crt_sign(const uint8_t *em, size_t em_len, - const uint8_t *dP, size_t dP_len, - const uint8_t *dQ, size_t dQ_len, - const uint8_t *p, size_t p_len, - const uint8_t *q, size_t q_len, - const uint8_t *qInv, size_t qInv_len, +int mg_rsa_crt_sign(const uint8_t *em, size_t em_len, const uint8_t *dP, + size_t dP_len, const uint8_t *dQ, size_t dQ_len, + const uint8_t *p, size_t p_len, const uint8_t *q, + size_t q_len, const uint8_t *qInv, size_t qInv_len, uint8_t *signature, size_t sig_len) { uint32_t tmp[8 * BR_RSA_FACTOR_WORDS], *mq = tmp, *s2, *mp, *s1, *t1, *t2; uint32_t *c1, *c2; @@ -22724,9 +22699,8 @@ int mg_rsa_crt_sign(const uint8_t *em, size_t em_len, qInv_len = rsa_trim(&qInv, qInv_len); if (p_len < 128 || q_len < 128 || p_len > (BR_MAX_RSA_FACTOR >> 3) || q_len > (BR_MAX_RSA_FACTOR >> 3) || dP_len == 0 || dQ_len == 0 || - qInv_len == 0 || dP_len > p_len || dQ_len > q_len || - qInv_len > p_len || xlen > sizeof(x) || em_len == 0 || - em_len > xlen) { + qInv_len == 0 || dP_len > p_len || dQ_len > q_len || qInv_len > p_len || + xlen > sizeof(x) || em_len == 0 || em_len > xlen) { return -1; } plen = p_len, qlen = q_len; @@ -22745,7 +22719,8 @@ int mg_rsa_crt_sign(const uint8_t *em, size_t em_len, memset(t2, 0, 2 * (size_t) fwlen * sizeof(*t2)); t2[0] = mq[0]; br_i31_mulacc(t2, mq, mp); - if (xlen != ((t2[0] + 7) >> 3)) goto done; + // Convert i31-encoded bit length to byte length, and check + if (xlen != ((t2[0] - (t2[0] >> 5) + 7) >> 3)) goto done; br_i31_encode(signature, xlen, t2); for (u = xlen, ok = 0; u > 0; u--) { uint32_t wn = signature[u - 1], wx = x[u - 1]; @@ -22766,10 +22741,10 @@ int mg_rsa_crt_sign(const uint8_t *em, size_t em_len, br_i31_montymul(t2, s1, t1, mp, p0i); br_i31_mulacc(s2, mq, t2); br_i31_reduce(t1, s2, mq); - ok = rsa_i31_eq(t1, c2); - br_i31_decode(mp, p, plen); - br_i31_reduce(t1, s2, mp); - ok &= rsa_i31_eq(t1, c1); + ok = rsa_i31_eq(t1, c2); // fault check s mod q == m2 + br_i31_decode(t2, p, plen); // recombined sig in s2 overlaps mp, keep p in t2 + br_i31_reduce(t1, s2, t2); + ok &= rsa_i31_eq(t1, c1); // fault check s mod p == m1 if (!ok) goto done; ok = 0; br_i31_encode(signature, sig_len, s2); @@ -22782,8 +22757,8 @@ done: } // MGF1-SHA256 RFC 8017 B.2.1 -static void mgf1_sha256(const uint8_t *seed, size_t seed_len, - uint8_t *mask, size_t mask_len) { +static void mgf1_sha256(const uint8_t *seed, size_t seed_len, uint8_t *mask, + size_t mask_len) { uint8_t cnt[4]; // I2OSP(counter, 4), big-endian uint8_t tmp[32]; // one SHA-256 output block uint32_t counter = 0; @@ -22807,18 +22782,19 @@ static void mgf1_sha256(const uint8_t *seed, size_t seed_len, // em - output of RSA public-key primitive (nlen bytes) // nlen - modulus byte length (66 to 512) // mhash - SHA-256 of the TLS 1.3 signed content (tls->sighash, 32 bytes) -static bool pss_verify_sha256(const uint8_t *em, size_t nlen, const uint8_t *mhash) { +static bool pss_verify_sha256(const uint8_t *em, size_t nlen, + const uint8_t *mhash) { // TLS 1.3: H_len = salt_len = 32 - uint8_t db[479]; // unmasked DB after MGF1 XOR - uint8_t dbmask[479]; // MGF1-SHA256(H, db_len); nlen - hLen - 1 = 479 - uint8_t Hprime[32]; // SHA-256(0x00*8 || mhash || salt) - uint8_t Mprime[8 + 32 + 32]; // 0*8 || mhash || salt + uint8_t db[479]; // unmasked DB after MGF1 XOR + uint8_t dbmask[479]; // MGF1-SHA256(H, db_len); nlen - hLen - 1 = 479 + uint8_t Hprime[32]; // SHA-256(0x00*8 || mhash || salt) + uint8_t Mprime[8 + 32 + 32]; // 0*8 || mhash || salt const uint8_t *H; const uint8_t *salt; size_t db_len; size_t i; uint8_t bad; - + if (nlen < 32 + 32 + 2 || nlen - 32 - 1 > sizeof(db)) return -1; if (em[nlen - 1] != 0xbc) return false; if (em[0] & 0x80) return false; @@ -22826,7 +22802,7 @@ static bool pss_verify_sha256(const uint8_t *em, size_t nlen, const uint8_t *mha H = em + db_len; mgf1_sha256(H, 32, dbmask, db_len); for (i = 0; i < db_len; i++) db[i] = em[i] ^ dbmask[i]; - db[0] &= 0x7f; // DB = 0x00^(db_len-salt_len-1) || 0x01 || salt(salt_Len) + db[0] &= 0x7f; // DB = 0x00^(db_len-salt_len-1) || 0x01 || salt(salt_Len) bad = 0; for (i = 0; i < db_len - 32 - 1; i++) bad |= db[i]; bad |= db[db_len - 32 - 1] ^ 0x01; @@ -22852,12 +22828,12 @@ bool mg_rsa_verify(const uint8_t *em, size_t nlen, const uint8_t *mhash) { // hashlen - hash length, 32 for SHA-256 or 48 for SHA-384 static bool pkcs1_v15_verify(const uint8_t *em, size_t nlen, const uint8_t *hash, size_t hashlen) { - static const uint8_t sha256_di[] = { - 0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, - 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20}; - static const uint8_t sha384_di[] = { - 0x30, 0x41, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, - 0x65, 0x03, 0x04, 0x02, 0x02, 0x05, 0x00, 0x04, 0x30}; + static const uint8_t sha256_di[] = {0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, + 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, + 0x01, 0x05, 0x00, 0x04, 0x20}; + static const uint8_t sha384_di[] = {0x30, 0x41, 0x30, 0x0d, 0x06, 0x09, 0x60, + 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, + 0x02, 0x05, 0x00, 0x04, 0x30}; const uint8_t *di = hashlen == 32 ? sha256_di : sha384_di; size_t disz = hashlen == 32 ? sizeof(sha256_di) : sizeof(sha384_di); size_t pslen, i; diff --git a/src/mdash.c b/src/mdash.c index b082d616..9e58ddaa 100644 --- a/src/mdash.c +++ b/src/mdash.c @@ -157,7 +157,9 @@ void mg_mdash_init(struct mg_mgr *mgr) { void mg_mdash_poll(struct mg_mgr *mgr) { static uint64_t timer = 0; - if (mg_mdash_conn == NULL && mg_timer_expired(&timer, 1000, mg_millis())) { + // No RPC handlers means mdash was never set up, or mg_mdash_free() ran + if (mg_mdash_conn == NULL && mgr->rpcs != NULL && + mg_timer_expired(&timer, 1000, mg_millis())) { MG_INFO(("Connecting to %s", MG_MDASH_URL)); mg_mdash_conn = mg_ws_connect(mgr, MG_MDASH_URL, mg_mdash_fn, NULL, "Origin: %s\r\n" diff --git a/src/net.c b/src/net.c index 3df3ae9e..bf5dbefc 100644 --- a/src/net.c +++ b/src/net.c @@ -299,10 +299,10 @@ void mg_mgr_free(struct mg_mgr *mgr) { while (t != NULL) tmp = t->next, mg_free(t), t = tmp; mgr->timers = NULL; // Important. Next call to poll won't touch timers for (c = mgr->conns; c != NULL; c = c->next) c->is_closing = 1; - mg_mgr_poll(mgr, 0); #if MG_ENABLE_MDASH - mg_mdash_free(mgr); + mg_mdash_free(mgr); // Before the final poll, so mdash does not reconnect #endif + mg_mgr_poll(mgr, 0); #if MG_ENABLE_FREERTOS_TCP FreeRTOS_DeleteSocketSet(mgr->ss); #endif diff --git a/src/tls_rsa.c b/src/tls_rsa.c index b5edc47b..8d1e3a11 100644 --- a/src/tls_rsa.c +++ b/src/tls_rsa.c @@ -1,6 +1,6 @@ +#include "tls_rsa.h" #include "sha256.h" #include "tls.h" -#include "tls_rsa.h" #include "util.h" #if MG_TLS == MG_TLS_BUILTIN @@ -41,7 +41,9 @@ #define MUL31_lo(x, y) (((uint32_t) (x) * (uint32_t) (y)) & 0x7fffffffU) #define CCOPY br_ccopy -static uint32_t NOT(uint32_t ctl) { return ctl ^ 1; } +static uint32_t NOT(uint32_t ctl) { + return ctl ^ 1; +} static uint32_t MUX(uint32_t ctl, uint32_t x, uint32_t y) { return y ^ (-ctl & (x ^ y)); } @@ -62,10 +64,18 @@ static uint32_t GT(uint32_t x, uint32_t y) { static uint32_t BIT_LENGTH(uint32_t x) { uint32_t k, c; k = NEQ(x, 0); - c = GT(x, 0xffff); x = MUX(c, x >> 16, x); k += c << 4; - c = GT(x, 0x00ff); x = MUX(c, x >> 8, x); k += c << 3; - c = GT(x, 0x000f); x = MUX(c, x >> 4, x); k += c << 2; - c = GT(x, 0x0003); x = MUX(c, x >> 2, x); k += c << 1; + c = GT(x, 0xffff); + x = MUX(c, x >> 16, x); + k += c << 4; + c = GT(x, 0x00ff); + x = MUX(c, x >> 8, x); + k += c << 3; + c = GT(x, 0x000f); + x = MUX(c, x >> 4, x); + k += c << 2; + c = GT(x, 0x0003); + x = MUX(c, x >> 2, x); + k += c << 1; k += GT(x, 0x0001); return k; } @@ -95,11 +105,14 @@ static uint32_t br_divrem(uint32_t, uint32_t, uint32_t, uint32_t *); static void br_i31_muladd_small(uint32_t *, uint32_t, const uint32_t *); static void br_i31_reduce(uint32_t *, const uint32_t *, const uint32_t *); static void br_i31_rshift(uint32_t *, int); -static void br_i31_decode_reduce(uint32_t *, const void *, size_t, const uint32_t *); +static void br_i31_decode_reduce(uint32_t *, const void *, size_t, + const uint32_t *); static void br_i31_mulacc(uint32_t *, const uint32_t *, const uint32_t *); -static void br_i31_montymul(uint32_t *, const uint32_t *, const uint32_t *, const uint32_t *, uint32_t); +static void br_i31_montymul(uint32_t *, const uint32_t *, const uint32_t *, + const uint32_t *, uint32_t); static void br_i31_to_monty(uint32_t *, const uint32_t *); -static void br_i31_modpow(uint32_t *, const unsigned char *, size_t, const uint32_t *, uint32_t, uint32_t *, uint32_t *); +static void br_i31_modpow(uint32_t *, const unsigned char *, size_t, + const uint32_t *, uint32_t, uint32_t *, uint32_t *); static void br_i31_zero(uint32_t *x, uint32_t bit_len) { *x++ = bit_len; memset(x, 0, ((bit_len + 31) >> 5) * sizeof *x); @@ -113,642 +126,604 @@ static uint32_t br_div(uint32_t hi, uint32_t lo, uint32_t d) { uint32_t r; return br_divrem(hi, lo, d, &r); } -static uint32_t -br_i31_add(uint32_t *a, const uint32_t *b, uint32_t ctl) -{ - uint32_t cc; - size_t u, m; +static uint32_t br_i31_add(uint32_t *a, const uint32_t *b, uint32_t ctl) { + uint32_t cc; + size_t u, m; - cc = 0; - m = (a[0] + 63) >> 5; - for (u = 1; u < m; u ++) { - uint32_t aw, bw, naw; + cc = 0; + m = (a[0] + 63) >> 5; + for (u = 1; u < m; u++) { + uint32_t aw, bw, naw; - aw = a[u]; - bw = b[u]; - naw = aw + bw + cc; - cc = naw >> 31; - a[u] = MUX(ctl, naw & (uint32_t)0x7FFFFFFF, aw); - } - return cc; + aw = a[u]; + bw = b[u]; + naw = aw + bw + cc; + cc = naw >> 31; + a[u] = MUX(ctl, naw & (uint32_t) 0x7FFFFFFF, aw); + } + return cc; } -static uint32_t -br_i31_sub(uint32_t *a, const uint32_t *b, uint32_t ctl) -{ - uint32_t cc; - size_t u, m; +static uint32_t br_i31_sub(uint32_t *a, const uint32_t *b, uint32_t ctl) { + uint32_t cc; + size_t u, m; - cc = 0; - m = (a[0] + 63) >> 5; - for (u = 1; u < m; u ++) { - uint32_t aw, bw, naw; + cc = 0; + m = (a[0] + 63) >> 5; + for (u = 1; u < m; u++) { + uint32_t aw, bw, naw; - aw = a[u]; - bw = b[u]; - naw = aw - bw - cc; - cc = naw >> 31; - a[u] = MUX(ctl, naw & 0x7FFFFFFF, aw); - } - return cc; + aw = a[u]; + bw = b[u]; + naw = aw - bw - cc; + cc = naw >> 31; + a[u] = MUX(ctl, naw & 0x7FFFFFFF, aw); + } + return cc; } -static uint32_t -br_i31_bit_length(uint32_t *x, size_t xlen) -{ - uint32_t tw, twk; +static uint32_t br_i31_bit_length(uint32_t *x, size_t xlen) { + uint32_t tw, twk; - tw = 0; - twk = 0; - while (xlen -- > 0) { - uint32_t w, c; + tw = 0; + twk = 0; + while (xlen-- > 0) { + uint32_t w, c; - c = EQ(tw, 0); - w = x[xlen]; - tw = MUX(c, w, tw); - twk = MUX(c, (uint32_t)xlen, twk); - } - return (twk << 5) + BIT_LENGTH(tw); + c = EQ(tw, 0); + w = x[xlen]; + tw = MUX(c, w, tw); + twk = MUX(c, (uint32_t) xlen, twk); + } + return (twk << 5) + BIT_LENGTH(tw); } -static void -br_i31_decode(uint32_t *x, const void *src, size_t len) -{ - const unsigned char *buf; - size_t u, v; - uint32_t acc; - int acc_len; +static void br_i31_decode(uint32_t *x, const void *src, size_t len) { + const unsigned char *buf; + size_t u, v; + uint32_t acc; + int acc_len; - buf = (const unsigned char *) src; - u = len; - v = 1; - acc = 0; - acc_len = 0; - while (u -- > 0) { - uint32_t b; + buf = (const unsigned char *) src; + u = len; + v = 1; + acc = 0; + acc_len = 0; + while (u-- > 0) { + uint32_t b; - b = buf[u]; - acc |= (b << acc_len); - acc_len += 8; - if (acc_len >= 31) { - x[v ++] = acc & (uint32_t)0x7FFFFFFF; - acc_len -= 31; - acc = b >> (8 - acc_len); - } - } - if (acc_len != 0) { - x[v ++] = acc; - } - x[0] = br_i31_bit_length(x + 1, v - 1); + b = buf[u]; + acc |= (b << acc_len); + acc_len += 8; + if (acc_len >= 31) { + x[v++] = acc & (uint32_t) 0x7FFFFFFF; + acc_len -= 31; + acc = b >> (8 - acc_len); + } + } + if (acc_len != 0) { + x[v++] = acc; + } + x[0] = br_i31_bit_length(x + 1, v - 1); } -static void -br_i31_encode(void *dst, size_t len, const uint32_t *x) -{ - unsigned char *buf; - size_t k, xlen; - uint32_t acc; - int acc_len; +static void br_i31_encode(void *dst, size_t len, const uint32_t *x) { + unsigned char *buf; + size_t k, xlen; + uint32_t acc; + int acc_len; - xlen = (x[0] + 31) >> 5; - if (xlen == 0) { - memset(dst, 0, len); - return; - } - buf = (unsigned char *)dst + len; - k = 1; - acc = 0; - acc_len = 0; - while (len != 0) { - uint32_t w; + xlen = (x[0] + 31) >> 5; + if (xlen == 0) { + memset(dst, 0, len); + return; + } + buf = (unsigned char *) dst + len; + k = 1; + acc = 0; + acc_len = 0; + while (len != 0) { + uint32_t w; - w = (k <= xlen) ? x[k] : 0; - k ++; - if (acc_len == 0) { - acc = w; - acc_len = 31; - } else { - uint32_t z; + w = (k <= xlen) ? x[k] : 0; + k++; + if (acc_len == 0) { + acc = w; + acc_len = 31; + } else { + uint32_t z; - z = acc | (w << acc_len); - acc_len --; - acc = w >> (31 - acc_len); - if (len >= 4) { - buf -= 4; - len -= 4; - br_enc32be(buf, z); - } else { - switch (len) { - case 3: - buf[-3] = (unsigned char)(z >> 16); - /* fall through */ - case 2: - buf[-2] = (unsigned char)(z >> 8); - /* fall through */ - case 1: - buf[-1] = (unsigned char)z; - break; - } - return; - } - } - } + z = acc | (w << acc_len); + acc_len--; + acc = w >> (31 - acc_len); + if (len >= 4) { + buf -= 4; + len -= 4; + br_enc32be(buf, z); + } else { + switch (len) { + case 3: + buf[-3] = (unsigned char) (z >> 16); + /* fall through */ + case 2: + buf[-2] = (unsigned char) (z >> 8); + /* fall through */ + case 1: + buf[-1] = (unsigned char) z; + break; + } + return; + } + } + } } -static uint32_t -br_i31_ninv31(uint32_t x) -{ - uint32_t y; +static uint32_t br_i31_ninv31(uint32_t x) { + uint32_t y; - y = 2 - x; - y *= 2 - y * x; - y *= 2 - y * x; - y *= 2 - y * x; - y *= 2 - y * x; - return MUX(x & 1, -y, 0) & 0x7FFFFFFF; + y = 2 - x; + y *= 2 - y * x; + y *= 2 - y * x; + y *= 2 - y * x; + y *= 2 - y * x; + return MUX(x & 1, -y, 0) & 0x7FFFFFFF; } -static uint32_t -br_divrem(uint32_t hi, uint32_t lo, uint32_t d, uint32_t *r) -{ - /* TODO: optimize this */ - uint32_t q; - uint32_t ch, cf; - int k; +static uint32_t br_divrem(uint32_t hi, uint32_t lo, uint32_t d, uint32_t *r) { + /* TODO: optimize this */ + uint32_t q; + uint32_t ch, cf; + int k; - q = 0; - ch = EQ(hi, d); - hi = MUX(ch, 0, hi); - for (k = 31; k > 0; k --) { - int j; - uint32_t w, ctl, hi2, lo2; + q = 0; + ch = EQ(hi, d); + hi = MUX(ch, 0, hi); + for (k = 31; k > 0; k--) { + int j; + uint32_t w, ctl, hi2, lo2; - j = 32 - k; - w = (hi << j) | (lo >> k); - ctl = GE(w, d) | (hi >> k); - hi2 = (w - d) >> j; - lo2 = lo - (d << k); - hi = MUX(ctl, hi2, hi); - lo = MUX(ctl, lo2, lo); - q |= ctl << k; - } - cf = GE(lo, d) | hi; - q |= cf; - *r = MUX(cf, lo - d, lo); - return q; + j = 32 - k; + w = (hi << j) | (lo >> k); + ctl = GE(w, d) | (hi >> k); + hi2 = (w - d) >> j; + lo2 = lo - (d << k); + hi = MUX(ctl, hi2, hi); + lo = MUX(ctl, lo2, lo); + q |= ctl << k; + } + cf = GE(lo, d) | hi; + q |= cf; + *r = MUX(cf, lo - d, lo); + return q; } -static void -br_i31_muladd_small(uint32_t *x, uint32_t z, const uint32_t *m) -{ - uint32_t m_bitlen; - unsigned mblr; - size_t u, mlen; - uint32_t a0, a1, b0, hi, g, q, tb; - uint32_t under, over; - uint32_t cc; +static void br_i31_muladd_small(uint32_t *x, uint32_t z, const uint32_t *m) { + uint32_t m_bitlen; + unsigned mblr; + size_t u, mlen; + uint32_t a0, a1, b0, hi, g, q, tb; + uint32_t under, over; + uint32_t cc; - /* - * We can test on the modulus bit length since we accept to - * leak that length. - */ - m_bitlen = m[0]; - if (m_bitlen == 0) { - return; - } - if (m_bitlen <= 31) { - uint32_t lo; + /* + * We can test on the modulus bit length since we accept to + * leak that length. + */ + m_bitlen = m[0]; + if (m_bitlen == 0) { + return; + } + if (m_bitlen <= 31) { + uint32_t lo; - hi = x[1] >> 1; - lo = (x[1] << 31) | z; - x[1] = br_rem(hi, lo, m[1]); - return; - } - mlen = (m_bitlen + 31) >> 5; - mblr = (unsigned)m_bitlen & 31; + hi = x[1] >> 1; + lo = (x[1] << 31) | z; + x[1] = br_rem(hi, lo, m[1]); + return; + } + mlen = (m_bitlen + 31) >> 5; + mblr = (unsigned) m_bitlen & 31; - /* - * Principle: we estimate the quotient (x*2^31+z)/m by - * doing a 64/32 division with the high words. - * - * Let: - * w = 2^31 - * a = (w*a0 + a1) * w^N + a2 - * b = b0 * w^N + b2 - * such that: - * 0 <= a0 < w - * 0 <= a1 < w - * 0 <= a2 < w^N - * w/2 <= b0 < w - * 0 <= b2 < w^N - * a < w*b - * I.e. the two top words of a are a0:a1, the top word of b is - * b0, we ensured that b0 is "full" (high bit set), and a is - * such that the quotient q = a/b fits on one word (0 <= q < w). - * - * If a = b*q + r (with 0 <= r < q), we can estimate q by - * doing an Euclidean division on the top words: - * a0*w+a1 = b0*u + v (with 0 <= v < b0) - * Then the following holds: - * 0 <= u <= w - * u-2 <= q <= u - */ - hi = x[mlen]; - if (mblr == 0) { - a0 = x[mlen]; - memmove(x + 2, x + 1, (mlen - 1) * sizeof *x); - x[1] = z; - a1 = x[mlen]; - b0 = m[mlen]; - } else { - a0 = ((x[mlen] << (31 - mblr)) | (x[mlen - 1] >> mblr)) - & 0x7FFFFFFF; - memmove(x + 2, x + 1, (mlen - 1) * sizeof *x); - x[1] = z; - a1 = ((x[mlen] << (31 - mblr)) | (x[mlen - 1] >> mblr)) - & 0x7FFFFFFF; - b0 = ((m[mlen] << (31 - mblr)) | (m[mlen - 1] >> mblr)) - & 0x7FFFFFFF; - } + /* + * Principle: we estimate the quotient (x*2^31+z)/m by + * doing a 64/32 division with the high words. + * + * Let: + * w = 2^31 + * a = (w*a0 + a1) * w^N + a2 + * b = b0 * w^N + b2 + * such that: + * 0 <= a0 < w + * 0 <= a1 < w + * 0 <= a2 < w^N + * w/2 <= b0 < w + * 0 <= b2 < w^N + * a < w*b + * I.e. the two top words of a are a0:a1, the top word of b is + * b0, we ensured that b0 is "full" (high bit set), and a is + * such that the quotient q = a/b fits on one word (0 <= q < w). + * + * If a = b*q + r (with 0 <= r < q), we can estimate q by + * doing an Euclidean division on the top words: + * a0*w+a1 = b0*u + v (with 0 <= v < b0) + * Then the following holds: + * 0 <= u <= w + * u-2 <= q <= u + */ + hi = x[mlen]; + if (mblr == 0) { + a0 = x[mlen]; + memmove(x + 2, x + 1, (mlen - 1) * sizeof *x); + x[1] = z; + a1 = x[mlen]; + b0 = m[mlen]; + } else { + a0 = ((x[mlen] << (31 - mblr)) | (x[mlen - 1] >> mblr)) & 0x7FFFFFFF; + memmove(x + 2, x + 1, (mlen - 1) * sizeof *x); + x[1] = z; + a1 = ((x[mlen] << (31 - mblr)) | (x[mlen - 1] >> mblr)) & 0x7FFFFFFF; + b0 = ((m[mlen] << (31 - mblr)) | (m[mlen - 1] >> mblr)) & 0x7FFFFFFF; + } - /* - * We estimate a divisor q. If the quotient returned by br_div() - * is g: - * -- If a0 == b0 then g == 0; we want q = 0x7FFFFFFF. - * -- Otherwise: - * -- if g == 0 then we set q = 0; - * -- otherwise, we set q = g - 1. - * The properties described above then ensure that the true - * quotient is q-1, q or q+1. - * - * Take care that a0, a1 and b0 are 31-bit words, not 32-bit. We - * must adjust the parameters to br_div() accordingly. - */ - g = br_div(a0 >> 1, a1 | (a0 << 31), b0); - q = MUX(EQ(a0, b0), 0x7FFFFFFF, MUX(EQ(g, 0), 0, g - 1)); + /* + * We estimate a divisor q. If the quotient returned by br_div() + * is g: + * -- If a0 == b0 then g == 0; we want q = 0x7FFFFFFF. + * -- Otherwise: + * -- if g == 0 then we set q = 0; + * -- otherwise, we set q = g - 1. + * The properties described above then ensure that the true + * quotient is q-1, q or q+1. + * + * Take care that a0, a1 and b0 are 31-bit words, not 32-bit. We + * must adjust the parameters to br_div() accordingly. + */ + g = br_div(a0 >> 1, a1 | (a0 << 31), b0); + q = MUX(EQ(a0, b0), 0x7FFFFFFF, MUX(EQ(g, 0), 0, g - 1)); - /* - * We subtract q*m from x (with the extra high word of value 'hi'). - * Since q may be off by 1 (in either direction), we may have to - * add or subtract m afterwards. - * - * The 'tb' flag will be true (1) at the end of the loop if the - * result is greater than or equal to the modulus (not counting - * 'hi' or the carry). - */ - cc = 0; - tb = 1; - for (u = 1; u <= mlen; u ++) { - uint32_t mw, zw, xw, nxw; - uint64_t zl; + /* + * We subtract q*m from x (with the extra high word of value 'hi'). + * Since q may be off by 1 (in either direction), we may have to + * add or subtract m afterwards. + * + * The 'tb' flag will be true (1) at the end of the loop if the + * result is greater than or equal to the modulus (not counting + * 'hi' or the carry). + */ + cc = 0; + tb = 1; + for (u = 1; u <= mlen; u++) { + uint32_t mw, zw, xw, nxw; + uint64_t zl; - mw = m[u]; - zl = MUL31(mw, q) + cc; - cc = (uint32_t)(zl >> 31); - zw = (uint32_t)zl & (uint32_t)0x7FFFFFFF; - xw = x[u]; - nxw = xw - zw; - cc += nxw >> 31; - nxw &= 0x7FFFFFFF; - x[u] = nxw; - tb = MUX(EQ(nxw, mw), tb, GT(nxw, mw)); - } + mw = m[u]; + zl = MUL31(mw, q) + cc; + cc = (uint32_t) (zl >> 31); + zw = (uint32_t) zl & (uint32_t) 0x7FFFFFFF; + xw = x[u]; + nxw = xw - zw; + cc += nxw >> 31; + nxw &= 0x7FFFFFFF; + x[u] = nxw; + tb = MUX(EQ(nxw, mw), tb, GT(nxw, mw)); + } - /* - * If we underestimated q, then either cc < hi (one extra bit - * beyond the top array word), or cc == hi and tb is true (no - * extra bit, but the result is not lower than the modulus). In - * these cases we must subtract m once. - * - * Otherwise, we may have overestimated, which will show as - * cc > hi (thus a negative result). Correction is adding m once. - */ - over = GT(cc, hi); - under = ~over & (tb | LT(cc, hi)); - br_i31_add(x, m, over); - br_i31_sub(x, m, under); + /* + * If we underestimated q, then either cc < hi (one extra bit + * beyond the top array word), or cc == hi and tb is true (no + * extra bit, but the result is not lower than the modulus). In + * these cases we must subtract m once. + * + * Otherwise, we may have overestimated, which will show as + * cc > hi (thus a negative result). Correction is adding m once. + */ + over = GT(cc, hi); + under = ~over & (tb | LT(cc, hi)); + br_i31_add(x, m, over); + br_i31_sub(x, m, under); } -static void -br_i31_reduce(uint32_t *x, const uint32_t *a, const uint32_t *m) -{ - uint32_t m_bitlen, a_bitlen; - size_t mlen, alen, u; +static void br_i31_reduce(uint32_t *x, const uint32_t *a, const uint32_t *m) { + uint32_t m_bitlen, a_bitlen; + size_t mlen, alen, u; - m_bitlen = m[0]; - mlen = (m_bitlen + 31) >> 5; + m_bitlen = m[0]; + mlen = (m_bitlen + 31) >> 5; - x[0] = m_bitlen; - if (m_bitlen == 0) { - return; - } + x[0] = m_bitlen; + if (m_bitlen == 0) { + return; + } - /* - * If the source is shorter, then simply copy all words from a[] - * and zero out the upper words. - */ - a_bitlen = a[0]; - alen = (a_bitlen + 31) >> 5; - if (a_bitlen < m_bitlen) { - memcpy(x + 1, a + 1, alen * sizeof *a); - for (u = alen; u < mlen; u ++) { - x[u + 1] = 0; - } - return; - } + /* + * If the source is shorter, then simply copy all words from a[] + * and zero out the upper words. + */ + a_bitlen = a[0]; + alen = (a_bitlen + 31) >> 5; + if (a_bitlen < m_bitlen) { + memcpy(x + 1, a + 1, alen * sizeof *a); + for (u = alen; u < mlen; u++) { + x[u + 1] = 0; + } + return; + } - /* - * The source length is at least equal to that of the modulus. - * We must thus copy N-1 words, and input the remaining words - * one by one. - */ - memcpy(x + 1, a + 2 + (alen - mlen), (mlen - 1) * sizeof *a); - x[mlen] = 0; - for (u = 1 + alen - mlen; u > 0; u --) { - br_i31_muladd_small(x, a[u], m); - } + /* + * The source length is at least equal to that of the modulus. + * We must thus copy N-1 words, and input the remaining words + * one by one. + */ + memcpy(x + 1, a + 2 + (alen - mlen), (mlen - 1) * sizeof *a); + x[mlen] = 0; + for (u = 1 + alen - mlen; u > 0; u--) { + br_i31_muladd_small(x, a[u], m); + } } -static void -br_i31_rshift(uint32_t *x, int count) -{ - size_t u, len; - uint32_t r; +static void br_i31_rshift(uint32_t *x, int count) { + size_t u, len; + uint32_t r; - len = (x[0] + 31) >> 5; - if (len == 0) { - return; - } - r = x[1] >> count; - for (u = 2; u <= len; u ++) { - uint32_t w; + len = (x[0] + 31) >> 5; + if (len == 0) { + return; + } + r = x[1] >> count; + for (u = 2; u <= len; u++) { + uint32_t w; - w = x[u]; - x[u - 1] = ((w << (31 - count)) | r) & 0x7FFFFFFF; - r = w >> count; - } - x[len] = r; + w = x[u]; + x[u - 1] = ((w << (31 - count)) | r) & 0x7FFFFFFF; + r = w >> count; + } + x[len] = r; } -static void -br_i31_decode_reduce(uint32_t *x, - const void *src, size_t len, const uint32_t *m) -{ - uint32_t m_ebitlen, m_rbitlen; - size_t mblen, k; - const unsigned char *buf; - uint32_t acc; - int acc_len; +static void br_i31_decode_reduce(uint32_t *x, const void *src, size_t len, + const uint32_t *m) { + uint32_t m_ebitlen, m_rbitlen; + size_t mblen, k; + const unsigned char *buf; + uint32_t acc; + int acc_len; - /* - * Get the encoded bit length. - */ - m_ebitlen = m[0]; + /* + * Get the encoded bit length. + */ + m_ebitlen = m[0]; - /* - * Special case for an invalid (null) modulus. - */ - if (m_ebitlen == 0) { - x[0] = 0; - return; - } + /* + * Special case for an invalid (null) modulus. + */ + if (m_ebitlen == 0) { + x[0] = 0; + return; + } - /* - * Clear the destination. - */ - br_i31_zero(x, m_ebitlen); + /* + * Clear the destination. + */ + br_i31_zero(x, m_ebitlen); - /* - * First decode directly as many bytes as possible. This requires - * computing the actual bit length. - */ - m_rbitlen = m_ebitlen >> 5; - m_rbitlen = (m_ebitlen & 31) + (m_rbitlen << 5) - m_rbitlen; - mblen = (m_rbitlen + 7) >> 3; - k = mblen - 1; - if (k >= len) { - br_i31_decode(x, src, len); - x[0] = m_ebitlen; - return; - } - buf = (const unsigned char *) src; - br_i31_decode(x, buf, k); - x[0] = m_ebitlen; + /* + * First decode directly as many bytes as possible. This requires + * computing the actual bit length. + */ + m_rbitlen = m_ebitlen >> 5; + m_rbitlen = (m_ebitlen & 31) + (m_rbitlen << 5) - m_rbitlen; + mblen = (m_rbitlen + 7) >> 3; + k = mblen - 1; + if (k >= len) { + br_i31_decode(x, src, len); + x[0] = m_ebitlen; + return; + } + buf = (const unsigned char *) src; + br_i31_decode(x, buf, k); + x[0] = m_ebitlen; - /* - * Input remaining bytes, using 31-bit words. - */ - acc = 0; - acc_len = 0; - while (k < len) { - uint32_t v; + /* + * Input remaining bytes, using 31-bit words. + */ + acc = 0; + acc_len = 0; + while (k < len) { + uint32_t v; - v = buf[k ++]; - if (acc_len >= 23) { - acc_len -= 23; - acc <<= (8 - acc_len); - acc |= v >> acc_len; - br_i31_muladd_small(x, acc, m); - acc = v & (0xFF >> (8 - acc_len)); - } else { - acc = (acc << 8) | v; - acc_len += 8; - } - } + v = buf[k++]; + if (acc_len >= 23) { + acc_len -= 23; + acc <<= (8 - acc_len); + acc |= v >> acc_len; + br_i31_muladd_small(x, acc, m); + acc = v & (0xFF >> (8 - acc_len)); + } else { + acc = (acc << 8) | v; + acc_len += 8; + } + } - /* - * We may have some bits accumulated. We then perform a shift to - * be able to inject these bits as a full 31-bit word. - */ - if (acc_len != 0) { - acc = (acc | (x[1] << acc_len)) & 0x7FFFFFFF; - br_i31_rshift(x, 31 - acc_len); - br_i31_muladd_small(x, acc, m); - } + /* + * We may have some bits accumulated. We then perform a shift to + * be able to inject these bits as a full 31-bit word. + */ + if (acc_len != 0) { + acc = (acc | (x[1] << acc_len)) & 0x7FFFFFFF; + br_i31_rshift(x, 31 - acc_len); + br_i31_muladd_small(x, acc, m); + } } -static void -br_i31_mulacc(uint32_t *d, const uint32_t *a, const uint32_t *b) -{ - size_t alen, blen, u; - uint32_t dl, dh; +static void br_i31_mulacc(uint32_t *d, const uint32_t *a, const uint32_t *b) { + size_t alen, blen, u; + uint32_t dl, dh; - alen = (a[0] + 31) >> 5; - blen = (b[0] + 31) >> 5; + alen = (a[0] + 31) >> 5; + blen = (b[0] + 31) >> 5; - /* - * We want to add the two bit lengths, but these are encoded, - * which requires some extra care. - */ - dl = (a[0] & 31) + (b[0] & 31); - dh = (a[0] >> 5) + (b[0] >> 5); - d[0] = (dh << 5) + dl + (~(uint32_t)(dl - 31) >> 31); + /* + * We want to add the two bit lengths, but these are encoded, + * which requires some extra care. + */ + dl = (a[0] & 31) + (b[0] & 31); + dh = (a[0] >> 5) + (b[0] >> 5); + d[0] = (dh << 5) + dl + (~(uint32_t) (dl - 31) >> 31); - for (u = 0; u < blen; u ++) { - uint32_t f; - size_t v; + for (u = 0; u < blen; u++) { + uint32_t f; + size_t v; - /* - * Carry always fits on 31 bits; we want to keep it in a - * 32-bit register on 32-bit architectures (on a 64-bit - * architecture, cast down from 64 to 32 bits means - * clearing the high bits, which is not free; on a 32-bit - * architecture, the same operation really means ignoring - * the top register, which has negative or zero cost). - */ + /* + * Carry always fits on 31 bits; we want to keep it in a + * 32-bit register on 32-bit architectures (on a 64-bit + * architecture, cast down from 64 to 32 bits means + * clearing the high bits, which is not free; on a 32-bit + * architecture, the same operation really means ignoring + * the top register, which has negative or zero cost). + */ #if BR_64 - uint64_t cc; + uint64_t cc; #else - uint32_t cc; + uint32_t cc; #endif - f = b[1 + u]; - cc = 0; - for (v = 0; v < alen; v ++) { - uint64_t z; + f = b[1 + u]; + cc = 0; + for (v = 0; v < alen; v++) { + uint64_t z; - z = (uint64_t)d[1 + u + v] + MUL31(f, a[1 + v]) + cc; - cc = z >> 31; - d[1 + u + v] = (uint32_t)z & 0x7FFFFFFF; - } - d[1 + u + alen] = (uint32_t)cc; - } + z = (uint64_t) d[1 + u + v] + MUL31(f, a[1 + v]) + cc; + cc = z >> 31; + d[1 + u + v] = (uint32_t) z & 0x7FFFFFFF; + } + d[1 + u + alen] = (uint32_t) cc; + } } -static void -br_i31_montymul(uint32_t *d, const uint32_t *x, const uint32_t *y, - const uint32_t *m, uint32_t m0i) -{ - /* - * Each outer loop iteration computes: - * d <- (d + xu*y + f*m) / 2^31 - * We have xu <= 2^31-1 and f <= 2^31-1. - * Thus, if d <= 2*m-1 on input, then: - * 2*m-1 + 2*(2^31-1)*m <= (2^32)*m-1 - * and the new d value is less than 2*m. - * - * We represent d over 31-bit words, with an extra word 'dh' - * which can thus be only 0 or 1. - */ - size_t len, len4, u, v; - uint32_t dh; +static void br_i31_montymul(uint32_t *d, const uint32_t *x, const uint32_t *y, + const uint32_t *m, uint32_t m0i) { + /* + * Each outer loop iteration computes: + * d <- (d + xu*y + f*m) / 2^31 + * We have xu <= 2^31-1 and f <= 2^31-1. + * Thus, if d <= 2*m-1 on input, then: + * 2*m-1 + 2*(2^31-1)*m <= (2^32)*m-1 + * and the new d value is less than 2*m. + * + * We represent d over 31-bit words, with an extra word 'dh' + * which can thus be only 0 or 1. + */ + size_t len, len4, u, v; + uint32_t dh; - len = (m[0] + 31) >> 5; - len4 = len & ~(size_t)3; - br_i31_zero(d, m[0]); - dh = 0; - for (u = 0; u < len; u ++) { - /* - * The carry for each operation fits on 32 bits: - * d[v+1] <= 2^31-1 - * xu*y[v+1] <= (2^31-1)*(2^31-1) - * f*m[v+1] <= (2^31-1)*(2^31-1) - * r <= 2^32-1 - * (2^31-1) + 2*(2^31-1)*(2^31-1) + (2^32-1) = 2^63 - 2^31 - * After division by 2^31, the new r is then at most 2^32-1 - * - * Using a 32-bit carry has performance benefits on 32-bit - * systems; however, on 64-bit architectures, we prefer to - * keep the carry (r) in a 64-bit register, thus avoiding some - * "clear high bits" operations. - */ - uint32_t f, xu; + len = (m[0] + 31) >> 5; + len4 = len & ~(size_t) 3; + br_i31_zero(d, m[0]); + dh = 0; + for (u = 0; u < len; u++) { + /* + * The carry for each operation fits on 32 bits: + * d[v+1] <= 2^31-1 + * xu*y[v+1] <= (2^31-1)*(2^31-1) + * f*m[v+1] <= (2^31-1)*(2^31-1) + * r <= 2^32-1 + * (2^31-1) + 2*(2^31-1)*(2^31-1) + (2^32-1) = 2^63 - 2^31 + * After division by 2^31, the new r is then at most 2^32-1 + * + * Using a 32-bit carry has performance benefits on 32-bit + * systems; however, on 64-bit architectures, we prefer to + * keep the carry (r) in a 64-bit register, thus avoiding some + * "clear high bits" operations. + */ + uint32_t f, xu; #if BR_64 - uint64_t r; + uint64_t r; #else - uint32_t r; + uint32_t r; #endif - xu = x[u + 1]; - f = MUL31_lo((d[1] + MUL31_lo(x[u + 1], y[1])), m0i); + xu = x[u + 1]; + f = MUL31_lo((d[1] + MUL31_lo(x[u + 1], y[1])), m0i); - r = 0; - for (v = 0; v < len4; v += 4) { - uint64_t z; + r = 0; + for (v = 0; v < len4; v += 4) { + uint64_t z; - z = (uint64_t)d[v + 1] + MUL31(xu, y[v + 1]) - + MUL31(f, m[v + 1]) + r; - r = z >> 31; - d[v + 0] = (uint32_t)z & 0x7FFFFFFF; - z = (uint64_t)d[v + 2] + MUL31(xu, y[v + 2]) - + MUL31(f, m[v + 2]) + r; - r = z >> 31; - d[v + 1] = (uint32_t)z & 0x7FFFFFFF; - z = (uint64_t)d[v + 3] + MUL31(xu, y[v + 3]) - + MUL31(f, m[v + 3]) + r; - r = z >> 31; - d[v + 2] = (uint32_t)z & 0x7FFFFFFF; - z = (uint64_t)d[v + 4] + MUL31(xu, y[v + 4]) - + MUL31(f, m[v + 4]) + r; - r = z >> 31; - d[v + 3] = (uint32_t)z & 0x7FFFFFFF; - } - for (; v < len; v ++) { - uint64_t z; + z = (uint64_t) d[v + 1] + MUL31(xu, y[v + 1]) + MUL31(f, m[v + 1]) + r; + r = z >> 31; + d[v + 0] = (uint32_t) z & 0x7FFFFFFF; + z = (uint64_t) d[v + 2] + MUL31(xu, y[v + 2]) + MUL31(f, m[v + 2]) + r; + r = z >> 31; + d[v + 1] = (uint32_t) z & 0x7FFFFFFF; + z = (uint64_t) d[v + 3] + MUL31(xu, y[v + 3]) + MUL31(f, m[v + 3]) + r; + r = z >> 31; + d[v + 2] = (uint32_t) z & 0x7FFFFFFF; + z = (uint64_t) d[v + 4] + MUL31(xu, y[v + 4]) + MUL31(f, m[v + 4]) + r; + r = z >> 31; + d[v + 3] = (uint32_t) z & 0x7FFFFFFF; + } + for (; v < len; v++) { + uint64_t z; - z = (uint64_t)d[v + 1] + MUL31(xu, y[v + 1]) - + MUL31(f, m[v + 1]) + r; - r = z >> 31; - d[v] = (uint32_t)z & 0x7FFFFFFF; - } + z = (uint64_t) d[v + 1] + MUL31(xu, y[v + 1]) + MUL31(f, m[v + 1]) + r; + r = z >> 31; + d[v] = (uint32_t) z & 0x7FFFFFFF; + } - /* - * Since the new dh can only be 0 or 1, the addition of - * the old dh with the carry MUST fit on 32 bits, and - * thus can be done into dh itself. - */ - dh += (uint32_t) r; - d[len] = dh & 0x7FFFFFFF; - dh >>= 31; - } + /* + * Since the new dh can only be 0 or 1, the addition of + * the old dh with the carry MUST fit on 32 bits, and + * thus can be done into dh itself. + */ + dh += (uint32_t) r; + d[len] = dh & 0x7FFFFFFF; + dh >>= 31; + } - /* - * We must write back the bit length because it was overwritten in - * the loop (not overwriting it would require a test in the loop, - * which would yield bigger and slower code). - */ - d[0] = m[0]; + /* + * We must write back the bit length because it was overwritten in + * the loop (not overwriting it would require a test in the loop, + * which would yield bigger and slower code). + */ + d[0] = m[0]; - /* - * d[] may still be greater than m[] at that point; notably, the - * 'dh' word may be non-zero. - */ - br_i31_sub(d, m, NEQ(dh, 0) | NOT(br_i31_sub(d, m, 0))); + /* + * d[] may still be greater than m[] at that point; notably, the + * 'dh' word may be non-zero. + */ + br_i31_sub(d, m, NEQ(dh, 0) | NOT(br_i31_sub(d, m, 0))); } -static void -br_i31_to_monty(uint32_t *x, const uint32_t *m) -{ - uint32_t k; +static void br_i31_to_monty(uint32_t *x, const uint32_t *m) { + uint32_t k; - for (k = (m[0] + 31) >> 5; k > 0; k --) { - br_i31_muladd_small(x, 0, m); - } + for (k = (m[0] + 31) >> 5; k > 0; k--) { + br_i31_muladd_small(x, 0, m); + } } -static void -br_i31_modpow(uint32_t *x, - const unsigned char *e, size_t elen, - const uint32_t *m, uint32_t m0i, uint32_t *t1, uint32_t *t2) -{ - size_t mlen; - uint32_t k; +static void br_i31_modpow(uint32_t *x, const unsigned char *e, size_t elen, + const uint32_t *m, uint32_t m0i, uint32_t *t1, + uint32_t *t2) { + size_t mlen; + uint32_t k; - /* - * 'mlen' is the length of m[] expressed in bytes (including - * the "bit length" first field). - */ - mlen = ((m[0] + 63) >> 5) * sizeof m[0]; + /* + * 'mlen' is the length of m[] expressed in bytes (including + * the "bit length" first field). + */ + mlen = ((m[0] + 63) >> 5) * sizeof m[0]; - /* - * Throughout the algorithm: - * -- t1[] is in Montgomery representation; it contains x, x^2, - * x^4, x^8... - * -- The result is accumulated, in normal representation, in - * the x[] array. - * -- t2[] is used as destination buffer for each multiplication. - * - * Note that there is no need to call br_i32_from_monty(). - */ - memcpy(t1, x, mlen); - br_i31_to_monty(t1, m); - br_i31_zero(x, m[0]); - x[1] = 1; - for (k = 0; k < ((uint32_t)elen << 3); k ++) { - uint32_t ctl; + /* + * Throughout the algorithm: + * -- t1[] is in Montgomery representation; it contains x, x^2, + * x^4, x^8... + * -- The result is accumulated, in normal representation, in + * the x[] array. + * -- t2[] is used as destination buffer for each multiplication. + * + * Note that there is no need to call br_i32_from_monty(). + */ + memcpy(t1, x, mlen); + br_i31_to_monty(t1, m); + br_i31_zero(x, m[0]); + x[1] = 1; + for (k = 0; k < ((uint32_t) elen << 3); k++) { + uint32_t ctl; - ctl = (e[elen - 1 - (k >> 3)] >> (k & 7)) & 1; - br_i31_montymul(t2, x, t1, m, m0i); - CCOPY(ctl, x, t2, mlen); - br_i31_montymul(t2, t1, t1, m, m0i); - memcpy(t1, t2, mlen); - } + ctl = (e[elen - 1 - (k >> 3)] >> (k & 7)) & 1; + br_i31_montymul(t2, x, t1, m, m0i); + CCOPY(ctl, x, t2, mlen); + br_i31_montymul(t2, t1, t1, m, m0i); + memcpy(t1, t2, mlen); + } } static size_t rsa_trim(const uint8_t **p, size_t n) { @@ -776,8 +751,8 @@ static int rsa_i31_eq(const uint32_t *a, const uint32_t *b) { } int mg_rsa_mod_pow(const uint8_t *mod, size_t modsz, const uint8_t *exp, - size_t expsz, const uint8_t *msg, size_t msgsz, - uint8_t *out, size_t outsz) { + size_t expsz, const uint8_t *msg, size_t msgsz, uint8_t *out, + size_t outsz) { uint32_t tmp[4 * BR_RSA_WORDS], *m = tmp, *x, *t1, *t2, m0i; int fwlen; if (out == NULL) return -1; @@ -803,12 +778,10 @@ int mg_rsa_mod_pow(const uint8_t *mod, size_t modsz, const uint8_t *exp, return 0; } -int mg_rsa_crt_sign(const uint8_t *em, size_t em_len, - const uint8_t *dP, size_t dP_len, - const uint8_t *dQ, size_t dQ_len, - const uint8_t *p, size_t p_len, - const uint8_t *q, size_t q_len, - const uint8_t *qInv, size_t qInv_len, +int mg_rsa_crt_sign(const uint8_t *em, size_t em_len, const uint8_t *dP, + size_t dP_len, const uint8_t *dQ, size_t dQ_len, + const uint8_t *p, size_t p_len, const uint8_t *q, + size_t q_len, const uint8_t *qInv, size_t qInv_len, uint8_t *signature, size_t sig_len) { uint32_t tmp[8 * BR_RSA_FACTOR_WORDS], *mq = tmp, *s2, *mp, *s1, *t1, *t2; uint32_t *c1, *c2; @@ -829,9 +802,8 @@ int mg_rsa_crt_sign(const uint8_t *em, size_t em_len, qInv_len = rsa_trim(&qInv, qInv_len); if (p_len < 128 || q_len < 128 || p_len > (BR_MAX_RSA_FACTOR >> 3) || q_len > (BR_MAX_RSA_FACTOR >> 3) || dP_len == 0 || dQ_len == 0 || - qInv_len == 0 || dP_len > p_len || dQ_len > q_len || - qInv_len > p_len || xlen > sizeof(x) || em_len == 0 || - em_len > xlen) { + qInv_len == 0 || dP_len > p_len || dQ_len > q_len || qInv_len > p_len || + xlen > sizeof(x) || em_len == 0 || em_len > xlen) { return -1; } plen = p_len, qlen = q_len; @@ -850,7 +822,8 @@ int mg_rsa_crt_sign(const uint8_t *em, size_t em_len, memset(t2, 0, 2 * (size_t) fwlen * sizeof(*t2)); t2[0] = mq[0]; br_i31_mulacc(t2, mq, mp); - if (xlen != ((t2[0] + 7) >> 3)) goto done; + // Convert i31-encoded bit length to byte length, and check + if (xlen != ((t2[0] - (t2[0] >> 5) + 7) >> 3)) goto done; br_i31_encode(signature, xlen, t2); for (u = xlen, ok = 0; u > 0; u--) { uint32_t wn = signature[u - 1], wx = x[u - 1]; @@ -871,10 +844,10 @@ int mg_rsa_crt_sign(const uint8_t *em, size_t em_len, br_i31_montymul(t2, s1, t1, mp, p0i); br_i31_mulacc(s2, mq, t2); br_i31_reduce(t1, s2, mq); - ok = rsa_i31_eq(t1, c2); - br_i31_decode(mp, p, plen); - br_i31_reduce(t1, s2, mp); - ok &= rsa_i31_eq(t1, c1); + ok = rsa_i31_eq(t1, c2); // fault check s mod q == m2 + br_i31_decode(t2, p, plen); // recombined sig in s2 overlaps mp, keep p in t2 + br_i31_reduce(t1, s2, t2); + ok &= rsa_i31_eq(t1, c1); // fault check s mod p == m1 if (!ok) goto done; ok = 0; br_i31_encode(signature, sig_len, s2); @@ -887,8 +860,8 @@ done: } // MGF1-SHA256 RFC 8017 B.2.1 -static void mgf1_sha256(const uint8_t *seed, size_t seed_len, - uint8_t *mask, size_t mask_len) { +static void mgf1_sha256(const uint8_t *seed, size_t seed_len, uint8_t *mask, + size_t mask_len) { uint8_t cnt[4]; // I2OSP(counter, 4), big-endian uint8_t tmp[32]; // one SHA-256 output block uint32_t counter = 0; @@ -912,18 +885,19 @@ static void mgf1_sha256(const uint8_t *seed, size_t seed_len, // em - output of RSA public-key primitive (nlen bytes) // nlen - modulus byte length (66 to 512) // mhash - SHA-256 of the TLS 1.3 signed content (tls->sighash, 32 bytes) -static bool pss_verify_sha256(const uint8_t *em, size_t nlen, const uint8_t *mhash) { +static bool pss_verify_sha256(const uint8_t *em, size_t nlen, + const uint8_t *mhash) { // TLS 1.3: H_len = salt_len = 32 - uint8_t db[479]; // unmasked DB after MGF1 XOR - uint8_t dbmask[479]; // MGF1-SHA256(H, db_len); nlen - hLen - 1 = 479 - uint8_t Hprime[32]; // SHA-256(0x00*8 || mhash || salt) - uint8_t Mprime[8 + 32 + 32]; // 0*8 || mhash || salt + uint8_t db[479]; // unmasked DB after MGF1 XOR + uint8_t dbmask[479]; // MGF1-SHA256(H, db_len); nlen - hLen - 1 = 479 + uint8_t Hprime[32]; // SHA-256(0x00*8 || mhash || salt) + uint8_t Mprime[8 + 32 + 32]; // 0*8 || mhash || salt const uint8_t *H; const uint8_t *salt; size_t db_len; size_t i; uint8_t bad; - + if (nlen < 32 + 32 + 2 || nlen - 32 - 1 > sizeof(db)) return -1; if (em[nlen - 1] != 0xbc) return false; if (em[0] & 0x80) return false; @@ -931,7 +905,7 @@ static bool pss_verify_sha256(const uint8_t *em, size_t nlen, const uint8_t *mha H = em + db_len; mgf1_sha256(H, 32, dbmask, db_len); for (i = 0; i < db_len; i++) db[i] = em[i] ^ dbmask[i]; - db[0] &= 0x7f; // DB = 0x00^(db_len-salt_len-1) || 0x01 || salt(salt_Len) + db[0] &= 0x7f; // DB = 0x00^(db_len-salt_len-1) || 0x01 || salt(salt_Len) bad = 0; for (i = 0; i < db_len - 32 - 1; i++) bad |= db[i]; bad |= db[db_len - 32 - 1] ^ 0x01; @@ -957,12 +931,12 @@ bool mg_rsa_verify(const uint8_t *em, size_t nlen, const uint8_t *mhash) { // hashlen - hash length, 32 for SHA-256 or 48 for SHA-384 static bool pkcs1_v15_verify(const uint8_t *em, size_t nlen, const uint8_t *hash, size_t hashlen) { - static const uint8_t sha256_di[] = { - 0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, - 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20}; - static const uint8_t sha384_di[] = { - 0x30, 0x41, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, - 0x65, 0x03, 0x04, 0x02, 0x02, 0x05, 0x00, 0x04, 0x30}; + static const uint8_t sha256_di[] = {0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, + 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, + 0x01, 0x05, 0x00, 0x04, 0x20}; + static const uint8_t sha384_di[] = {0x30, 0x41, 0x30, 0x0d, 0x06, 0x09, 0x60, + 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, + 0x02, 0x05, 0x00, 0x04, 0x30}; const uint8_t *di = hashlen == 32 ? sha256_di : sha384_di; size_t disz = hashlen == 32 ? sizeof(sha256_di) : sizeof(sha384_di); size_t pslen, i;