wolfssl: fixes for CVE-2018-16870 & CVE-2019-13628
[openwrt/openwrt.git] / package / libs / wolfssl / patches / 020-Improve-nonce-use-in-ECC-mulmod.patch
1 From ba4d612892bf6e3aae9cca7edce2a6d6b43e3e22 Mon Sep 17 00:00:00 2001
2 From: Sean Parkinson <sean@wolfssl.com>
3 Date: Wed, 17 Jul 2019 08:26:02 +1000
4 Subject: [PATCH] Improve nonce use in ECC mulmod
5
6 (cherry picked from commit 483f6a5acd9808b405306661c121aa6407464dc2)
7
8 --- a/wolfcrypt/src/ecc.c
9 +++ b/wolfcrypt/src/ecc.c
10 @@ -2039,7 +2039,7 @@ int wc_ecc_mulmod_ex(mp_int* k, ecc_poin
11 #define M_POINTS 8
12 int first = 1, bitbuf = 0, bitcpy = 0, j;
13 #else
14 - #define M_POINTS 3
15 + #define M_POINTS 4
16 #endif
17
18 ecc_point *tG, *M[M_POINTS];
19 @@ -2253,7 +2253,9 @@ int wc_ecc_mulmod_ex(mp_int* k, ecc_poin
20 mode = 0;
21 bitcnt = 1;
22 buf = 0;
23 - digidx = get_digit_count(k) - 1;
24 + digidx = get_digit_count(modulus) - 1;
25 + /* The order MAY be 1 bit longer than the modulus. */
26 + digidx += (modulus->dp[digidx] >> (DIGIT_BIT-1));
27
28 /* perform ops */
29 if (err == MP_OKAY) {
30 @@ -2272,25 +2274,53 @@ int wc_ecc_mulmod_ex(mp_int* k, ecc_poin
31 i = (buf >> (DIGIT_BIT - 1)) & 1;
32 buf <<= 1;
33
34 - if (mode == 0 && i == 0) {
35 + if (mode == 0) {
36 + mode = i;
37 /* timing resistant - dummy operations */
38 if (err == MP_OKAY)
39 - err = ecc_projective_add_point(M[0], M[1], M[2], a, modulus,
40 + err = ecc_projective_add_point(M[1], M[2], M[2], a, modulus,
41 mp);
42 +#ifdef WC_NO_CACHE_RESISTANT
43 if (err == MP_OKAY)
44 - err = ecc_projective_dbl_point(M[1], M[2], a, modulus, mp);
45 - if (err == MP_OKAY)
46 - continue;
47 - }
48 -
49 - if (mode == 0 && i == 1) {
50 - mode = 1;
51 - /* timing resistant - dummy operations */
52 - if (err == MP_OKAY)
53 - err = ecc_projective_add_point(M[0], M[1], M[2], a, modulus,
54 - mp);
55 - if (err == MP_OKAY)
56 - err = ecc_projective_dbl_point(M[1], M[2], a, modulus, mp);
57 + err = ecc_projective_dbl_point(M[2], M[3], a, modulus, mp);
58 +#else
59 + /* instead of using M[i] for double, which leaks key bit to cache
60 + * monitor, use M[2] as temp, make sure address calc is constant,
61 + * keep M[0] and M[1] in cache */
62 + if (err == MP_OKAY)
63 + err = mp_copy((mp_int*)
64 + ( ((wolfssl_word)M[0]->x & wc_off_on_addr[i^1]) +
65 + ((wolfssl_word)M[1]->x & wc_off_on_addr[i])),
66 + M[2]->x);
67 + if (err == MP_OKAY)
68 + err = mp_copy((mp_int*)
69 + ( ((wolfssl_word)M[0]->y & wc_off_on_addr[i^1]) +
70 + ((wolfssl_word)M[1]->y & wc_off_on_addr[i])),
71 + M[2]->y);
72 + if (err == MP_OKAY)
73 + err = mp_copy((mp_int*)
74 + ( ((wolfssl_word)M[0]->z & wc_off_on_addr[i^1]) +
75 + ((wolfssl_word)M[1]->z & wc_off_on_addr[i])),
76 + M[2]->z);
77 + if (err == MP_OKAY)
78 + err = ecc_projective_dbl_point(M[2], M[3], a, modulus, mp);
79 + /* copy M[2] back to M[i] */
80 + if (err == MP_OKAY)
81 + err = mp_copy(M[2]->x,
82 + (mp_int*)
83 + ( ((wolfssl_word)M[0]->x & wc_off_on_addr[i^1]) +
84 + ((wolfssl_word)M[1]->x & wc_off_on_addr[i])) );
85 + if (err == MP_OKAY)
86 + err = mp_copy(M[2]->y,
87 + (mp_int*)
88 + ( ((wolfssl_word)M[0]->y & wc_off_on_addr[i^1]) +
89 + ((wolfssl_word)M[1]->y & wc_off_on_addr[i])) );
90 + if (err == MP_OKAY)
91 + err = mp_copy(M[2]->z,
92 + (mp_int*)
93 + ( ((wolfssl_word)M[0]->z & wc_off_on_addr[i^1]) +
94 + ((wolfssl_word)M[1]->z & wc_off_on_addr[i])) );
95 +#endif
96 if (err == MP_OKAY)
97 continue;
98 }