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