/src/nss/lib/freebl/ecl/ecp_secp256r1.c
Line | Count | Source |
1 | | /* P-256 from HACL* */ |
2 | | |
3 | | #ifdef FREEBL_NO_DEPEND |
4 | | #include "../stubs.h" |
5 | | #endif |
6 | | |
7 | | #include "ecl-priv.h" |
8 | | #include "secitem.h" |
9 | | #include "secerr.h" |
10 | | #include "secmpi.h" |
11 | | #include "../verified/Hacl_P256.h" |
12 | | |
13 | | /* |
14 | | * Point Validation for P-256. |
15 | | */ |
16 | | |
17 | | SECStatus |
18 | | ec_secp256r1_pt_validate(const SECItem *pt) |
19 | 252k | { |
20 | 252k | SECStatus res = SECSuccess; |
21 | 252k | if (!pt || !pt->data) { |
22 | 0 | PORT_SetError(SEC_ERROR_INVALID_ARGS); |
23 | 0 | res = SECFailure; |
24 | 0 | return res; |
25 | 0 | } |
26 | | |
27 | 252k | if (pt->len != 65) { |
28 | 818 | PORT_SetError(SEC_ERROR_BAD_KEY); |
29 | 818 | res = SECFailure; |
30 | 818 | return res; |
31 | 818 | } |
32 | | |
33 | 251k | if (pt->data[0] != EC_POINT_FORM_UNCOMPRESSED) { |
34 | 180 | PORT_SetError(SEC_ERROR_UNSUPPORTED_EC_POINT_FORM); |
35 | 180 | res = SECFailure; |
36 | 180 | return res; |
37 | 180 | } |
38 | | |
39 | | #ifndef UNSAFE_FUZZER_MODE |
40 | 125k | bool b = Hacl_P256_validate_public_key(pt->data + 1); |
41 | | #else |
42 | 125k | bool b = PR_TRUE; |
43 | | #endif |
44 | | |
45 | 251k | if (!b) { |
46 | 498 | PORT_SetError(SEC_ERROR_BAD_KEY); |
47 | 498 | res = SECFailure; |
48 | 498 | } |
49 | 125k | return res; |
50 | 251k | } Line | Count | Source | 19 | 126k | { | 20 | 126k | SECStatus res = SECSuccess; | 21 | 126k | if (!pt || !pt->data) { | 22 | 0 | PORT_SetError(SEC_ERROR_INVALID_ARGS); | 23 | 0 | res = SECFailure; | 24 | 0 | return res; | 25 | 0 | } | 26 | | | 27 | 126k | if (pt->len != 65) { | 28 | 409 | PORT_SetError(SEC_ERROR_BAD_KEY); | 29 | 409 | res = SECFailure; | 30 | 409 | return res; | 31 | 409 | } | 32 | | | 33 | 125k | if (pt->data[0] != EC_POINT_FORM_UNCOMPRESSED) { | 34 | 90 | PORT_SetError(SEC_ERROR_UNSUPPORTED_EC_POINT_FORM); | 35 | 90 | res = SECFailure; | 36 | 90 | return res; | 37 | 90 | } | 38 | | | 39 | 125k | #ifndef UNSAFE_FUZZER_MODE | 40 | 125k | bool b = Hacl_P256_validate_public_key(pt->data + 1); | 41 | | #else | 42 | | bool b = PR_TRUE; | 43 | | #endif | 44 | | | 45 | 125k | if (!b) { | 46 | 249 | PORT_SetError(SEC_ERROR_BAD_KEY); | 47 | 249 | res = SECFailure; | 48 | 249 | } | 49 | 125k | return res; | 50 | 125k | } |
Line | Count | Source | 19 | 126k | { | 20 | 126k | SECStatus res = SECSuccess; | 21 | 126k | if (!pt || !pt->data) { | 22 | 0 | PORT_SetError(SEC_ERROR_INVALID_ARGS); | 23 | 0 | res = SECFailure; | 24 | 0 | return res; | 25 | 0 | } | 26 | | | 27 | 126k | if (pt->len != 65) { | 28 | 409 | PORT_SetError(SEC_ERROR_BAD_KEY); | 29 | 409 | res = SECFailure; | 30 | 409 | return res; | 31 | 409 | } | 32 | | | 33 | 125k | if (pt->data[0] != EC_POINT_FORM_UNCOMPRESSED) { | 34 | 90 | PORT_SetError(SEC_ERROR_UNSUPPORTED_EC_POINT_FORM); | 35 | 90 | res = SECFailure; | 36 | 90 | return res; | 37 | 90 | } | 38 | | | 39 | | #ifndef UNSAFE_FUZZER_MODE | 40 | | bool b = Hacl_P256_validate_public_key(pt->data + 1); | 41 | | #else | 42 | 125k | bool b = PR_TRUE; | 43 | 125k | #endif | 44 | | | 45 | 125k | if (!b) { | 46 | 249 | PORT_SetError(SEC_ERROR_BAD_KEY); | 47 | 249 | res = SECFailure; | 48 | 249 | } | 49 | 125k | return res; | 50 | 125k | } |
|
51 | | |
52 | | /* |
53 | | * Scalar Validation for P-256. |
54 | | */ |
55 | | |
56 | | SECStatus |
57 | | ec_secp256r1_scalar_validate(const SECItem *scalar) |
58 | 141k | { |
59 | 141k | SECStatus res = SECSuccess; |
60 | 141k | if (!scalar || !scalar->data) { |
61 | 0 | PORT_SetError(SEC_ERROR_INVALID_ARGS); |
62 | 0 | res = SECFailure; |
63 | 0 | return res; |
64 | 0 | } |
65 | | |
66 | 141k | if (scalar->len != 32) { |
67 | 0 | PORT_SetError(SEC_ERROR_BAD_KEY); |
68 | 0 | res = SECFailure; |
69 | 0 | return res; |
70 | 0 | } |
71 | | |
72 | | #ifndef UNSAFE_FUZZER_MODE |
73 | 70.8k | bool b = Hacl_P256_validate_private_key(scalar->data); |
74 | | #else |
75 | 70.8k | bool b = PR_TRUE; |
76 | | #endif |
77 | | |
78 | 141k | if (!b) { |
79 | 0 | PORT_SetError(SEC_ERROR_BAD_KEY); |
80 | 0 | res = SECFailure; |
81 | 0 | } |
82 | 70.8k | return res; |
83 | 141k | } ec_secp256r1_scalar_validate Line | Count | Source | 58 | 70.8k | { | 59 | 70.8k | SECStatus res = SECSuccess; | 60 | 70.8k | if (!scalar || !scalar->data) { | 61 | 0 | PORT_SetError(SEC_ERROR_INVALID_ARGS); | 62 | 0 | res = SECFailure; | 63 | 0 | return res; | 64 | 0 | } | 65 | | | 66 | 70.8k | if (scalar->len != 32) { | 67 | 0 | PORT_SetError(SEC_ERROR_BAD_KEY); | 68 | 0 | res = SECFailure; | 69 | 0 | return res; | 70 | 0 | } | 71 | | | 72 | 70.8k | #ifndef UNSAFE_FUZZER_MODE | 73 | 70.8k | bool b = Hacl_P256_validate_private_key(scalar->data); | 74 | | #else | 75 | | bool b = PR_TRUE; | 76 | | #endif | 77 | | | 78 | 70.8k | if (!b) { | 79 | 0 | PORT_SetError(SEC_ERROR_BAD_KEY); | 80 | 0 | res = SECFailure; | 81 | 0 | } | 82 | 70.8k | return res; | 83 | 70.8k | } |
ec_secp256r1_scalar_validate Line | Count | Source | 58 | 70.8k | { | 59 | 70.8k | SECStatus res = SECSuccess; | 60 | 70.8k | if (!scalar || !scalar->data) { | 61 | 0 | PORT_SetError(SEC_ERROR_INVALID_ARGS); | 62 | 0 | res = SECFailure; | 63 | 0 | return res; | 64 | 0 | } | 65 | | | 66 | 70.8k | if (scalar->len != 32) { | 67 | 0 | PORT_SetError(SEC_ERROR_BAD_KEY); | 68 | 0 | res = SECFailure; | 69 | 0 | return res; | 70 | 0 | } | 71 | | | 72 | | #ifndef UNSAFE_FUZZER_MODE | 73 | | bool b = Hacl_P256_validate_private_key(scalar->data); | 74 | | #else | 75 | 70.8k | bool b = PR_TRUE; | 76 | 70.8k | #endif | 77 | | | 78 | 70.8k | if (!b) { | 79 | 0 | PORT_SetError(SEC_ERROR_BAD_KEY); | 80 | 0 | res = SECFailure; | 81 | 0 | } | 82 | 70.8k | return res; | 83 | 70.8k | } |
|
84 | | |
85 | | /* |
86 | | * Scalar multiplication for P-256. |
87 | | * If P == NULL, the base point is used. |
88 | | * Returns X = k*P |
89 | | */ |
90 | | |
91 | | SECStatus |
92 | | ec_secp256r1_pt_mul(SECItem *X, SECItem *k, SECItem *P) |
93 | 261k | { |
94 | 261k | SECStatus res = SECSuccess; |
95 | 261k | if (!P) { |
96 | 133k | uint8_t derived[64] = { 0 }; |
97 | | |
98 | 133k | if (!X || !k || !X->data || !k->data || |
99 | 133k | X->len < 65 || k->len != 32) { |
100 | 8 | PORT_SetError(SEC_ERROR_INVALID_ARGS); |
101 | 8 | res = SECFailure; |
102 | 8 | return res; |
103 | 8 | } |
104 | | |
105 | | #ifndef UNSAFE_FUZZER_MODE |
106 | 66.9k | bool b = Hacl_P256_dh_initiator(derived, k->data); |
107 | | #else |
108 | 66.9k | bool b = PR_TRUE; |
109 | | #endif |
110 | | |
111 | 133k | if (!b) { |
112 | 32 | PORT_SetError(SEC_ERROR_BAD_KEY); |
113 | 32 | res = SECFailure; |
114 | 32 | return res; |
115 | 32 | } |
116 | | |
117 | 133k | X->len = 65; |
118 | 133k | X->data[0] = EC_POINT_FORM_UNCOMPRESSED; |
119 | 133k | memcpy(X->data + 1, derived, 64); |
120 | | |
121 | 133k | } else { |
122 | 127k | uint8_t full_key[32] = { 0 }; |
123 | 127k | uint8_t *key; |
124 | 127k | uint8_t derived[64] = { 0 }; |
125 | | |
126 | 127k | if (!X || !k || !P || !X->data || !k->data || !P->data || |
127 | 127k | X->len < 32 || P->len != 65 || |
128 | 127k | P->data[0] != EC_POINT_FORM_UNCOMPRESSED) { |
129 | 0 | PORT_SetError(SEC_ERROR_INVALID_ARGS); |
130 | 0 | res = SECFailure; |
131 | 0 | return res; |
132 | 0 | } |
133 | | |
134 | | /* We consider keys of up to size 32, or of size 33 with a single leading 0 */ |
135 | 127k | if (k->len < 32) { |
136 | 0 | memcpy(full_key + 32 - k->len, k->data, k->len); |
137 | 0 | key = full_key; |
138 | 127k | } else if (k->len == 32) { |
139 | 127k | key = k->data; |
140 | 127k | } else if (k->len == 33 && k->data[0] == 0) { |
141 | 0 | key = k->data + 1; |
142 | 0 | } else { |
143 | 0 | PORT_SetError(SEC_ERROR_INVALID_ARGS); |
144 | 0 | res = SECFailure; |
145 | 0 | return res; |
146 | 0 | } |
147 | | |
148 | 127k | bool b = Hacl_P256_dh_responder(derived, P->data + 1, key); |
149 | | |
150 | 127k | if (!b) { |
151 | 22.6k | PORT_SetError(SEC_ERROR_BAD_KEY); |
152 | 22.6k | res = SECFailure; |
153 | 22.6k | return res; |
154 | 22.6k | } |
155 | | |
156 | 104k | X->len = 32; |
157 | 104k | memcpy(X->data, derived, 32); |
158 | 104k | } |
159 | | |
160 | 238k | return res; |
161 | 261k | } Line | Count | Source | 93 | 130k | { | 94 | 130k | SECStatus res = SECSuccess; | 95 | 130k | if (!P) { | 96 | 66.9k | uint8_t derived[64] = { 0 }; | 97 | | | 98 | 66.9k | if (!X || !k || !X->data || !k->data || | 99 | 66.9k | X->len < 65 || k->len != 32) { | 100 | 4 | PORT_SetError(SEC_ERROR_INVALID_ARGS); | 101 | 4 | res = SECFailure; | 102 | 4 | return res; | 103 | 4 | } | 104 | | | 105 | 66.9k | #ifndef UNSAFE_FUZZER_MODE | 106 | 66.9k | bool b = Hacl_P256_dh_initiator(derived, k->data); | 107 | | #else | 108 | | bool b = PR_TRUE; | 109 | | #endif | 110 | | | 111 | 66.9k | if (!b) { | 112 | 16 | PORT_SetError(SEC_ERROR_BAD_KEY); | 113 | 16 | res = SECFailure; | 114 | 16 | return res; | 115 | 16 | } | 116 | | | 117 | 66.9k | X->len = 65; | 118 | 66.9k | X->data[0] = EC_POINT_FORM_UNCOMPRESSED; | 119 | 66.9k | memcpy(X->data + 1, derived, 64); | 120 | | | 121 | 66.9k | } else { | 122 | 63.6k | uint8_t full_key[32] = { 0 }; | 123 | 63.6k | uint8_t *key; | 124 | 63.6k | uint8_t derived[64] = { 0 }; | 125 | | | 126 | 63.6k | if (!X || !k || !P || !X->data || !k->data || !P->data || | 127 | 63.6k | X->len < 32 || P->len != 65 || | 128 | 63.6k | P->data[0] != EC_POINT_FORM_UNCOMPRESSED) { | 129 | 0 | PORT_SetError(SEC_ERROR_INVALID_ARGS); | 130 | 0 | res = SECFailure; | 131 | 0 | return res; | 132 | 0 | } | 133 | | | 134 | | /* We consider keys of up to size 32, or of size 33 with a single leading 0 */ | 135 | 63.6k | if (k->len < 32) { | 136 | 0 | memcpy(full_key + 32 - k->len, k->data, k->len); | 137 | 0 | key = full_key; | 138 | 63.6k | } else if (k->len == 32) { | 139 | 63.6k | key = k->data; | 140 | 63.6k | } else if (k->len == 33 && k->data[0] == 0) { | 141 | 0 | key = k->data + 1; | 142 | 0 | } else { | 143 | 0 | PORT_SetError(SEC_ERROR_INVALID_ARGS); | 144 | 0 | res = SECFailure; | 145 | 0 | return res; | 146 | 0 | } | 147 | | | 148 | 63.6k | bool b = Hacl_P256_dh_responder(derived, P->data + 1, key); | 149 | | | 150 | 63.6k | if (!b) { | 151 | 11.3k | PORT_SetError(SEC_ERROR_BAD_KEY); | 152 | 11.3k | res = SECFailure; | 153 | 11.3k | return res; | 154 | 11.3k | } | 155 | | | 156 | 52.3k | X->len = 32; | 157 | 52.3k | memcpy(X->data, derived, 32); | 158 | 52.3k | } | 159 | | | 160 | 119k | return res; | 161 | 130k | } |
Line | Count | Source | 93 | 130k | { | 94 | 130k | SECStatus res = SECSuccess; | 95 | 130k | if (!P) { | 96 | 66.9k | uint8_t derived[64] = { 0 }; | 97 | | | 98 | 66.9k | if (!X || !k || !X->data || !k->data || | 99 | 66.9k | X->len < 65 || k->len != 32) { | 100 | 4 | PORT_SetError(SEC_ERROR_INVALID_ARGS); | 101 | 4 | res = SECFailure; | 102 | 4 | return res; | 103 | 4 | } | 104 | | | 105 | | #ifndef UNSAFE_FUZZER_MODE | 106 | | bool b = Hacl_P256_dh_initiator(derived, k->data); | 107 | | #else | 108 | 66.9k | bool b = PR_TRUE; | 109 | 66.9k | #endif | 110 | | | 111 | 66.9k | if (!b) { | 112 | 16 | PORT_SetError(SEC_ERROR_BAD_KEY); | 113 | 16 | res = SECFailure; | 114 | 16 | return res; | 115 | 16 | } | 116 | | | 117 | 66.9k | X->len = 65; | 118 | 66.9k | X->data[0] = EC_POINT_FORM_UNCOMPRESSED; | 119 | 66.9k | memcpy(X->data + 1, derived, 64); | 120 | | | 121 | 66.9k | } else { | 122 | 63.6k | uint8_t full_key[32] = { 0 }; | 123 | 63.6k | uint8_t *key; | 124 | 63.6k | uint8_t derived[64] = { 0 }; | 125 | | | 126 | 63.6k | if (!X || !k || !P || !X->data || !k->data || !P->data || | 127 | 63.6k | X->len < 32 || P->len != 65 || | 128 | 63.6k | P->data[0] != EC_POINT_FORM_UNCOMPRESSED) { | 129 | 0 | PORT_SetError(SEC_ERROR_INVALID_ARGS); | 130 | 0 | res = SECFailure; | 131 | 0 | return res; | 132 | 0 | } | 133 | | | 134 | | /* We consider keys of up to size 32, or of size 33 with a single leading 0 */ | 135 | 63.6k | if (k->len < 32) { | 136 | 0 | memcpy(full_key + 32 - k->len, k->data, k->len); | 137 | 0 | key = full_key; | 138 | 63.6k | } else if (k->len == 32) { | 139 | 63.6k | key = k->data; | 140 | 63.6k | } else if (k->len == 33 && k->data[0] == 0) { | 141 | 0 | key = k->data + 1; | 142 | 0 | } else { | 143 | 0 | PORT_SetError(SEC_ERROR_INVALID_ARGS); | 144 | 0 | res = SECFailure; | 145 | 0 | return res; | 146 | 0 | } | 147 | | | 148 | 63.6k | bool b = Hacl_P256_dh_responder(derived, P->data + 1, key); | 149 | | | 150 | 63.6k | if (!b) { | 151 | 11.3k | PORT_SetError(SEC_ERROR_BAD_KEY); | 152 | 11.3k | res = SECFailure; | 153 | 11.3k | return res; | 154 | 11.3k | } | 155 | | | 156 | 52.3k | X->len = 32; | 157 | 52.3k | memcpy(X->data, derived, 32); | 158 | 52.3k | } | 159 | | | 160 | 119k | return res; | 161 | 130k | } |
|
162 | | |
163 | | /* |
164 | | * ECDSA Signature for P-256 |
165 | | */ |
166 | | |
167 | | SECStatus |
168 | | ec_secp256r1_sign_digest(ECPrivateKey *ecPrivKey, SECItem *signature, |
169 | | const SECItem *digest, const unsigned char *kb, |
170 | | const unsigned int kblen) |
171 | 984 | { |
172 | 984 | SECStatus res = SECSuccess; |
173 | | |
174 | 984 | if (!ecPrivKey || !signature || !digest || !kb || |
175 | 984 | !ecPrivKey->privateValue.data || |
176 | 984 | !signature->data || !digest->data || |
177 | 984 | ecPrivKey->ecParams.name != ECCurve_NIST_P256) { |
178 | 0 | PORT_SetError(SEC_ERROR_INVALID_ARGS); |
179 | 0 | res = SECFailure; |
180 | 0 | return res; |
181 | 0 | } |
182 | | |
183 | 984 | if (kblen == 0 || digest->len == 0 || signature->len < 64) { |
184 | 0 | PORT_SetError(SEC_ERROR_INPUT_LEN); |
185 | 0 | res = SECFailure; |
186 | 0 | return res; |
187 | 0 | } |
188 | | |
189 | | // Private keys should be 32 bytes, but some software trims leading zeros, |
190 | | // and some software produces 33 byte keys with a leading zero. We'll |
191 | | // accept these variants. |
192 | 984 | uint8_t padded_key_data[32] = { 0 }; |
193 | 984 | uint8_t *key; |
194 | 984 | SECItem *privKey = &ecPrivKey->privateValue; |
195 | 984 | if (privKey->len == 32) { |
196 | 984 | key = privKey->data; |
197 | 984 | } else if (privKey->len == 33 && privKey->data[0] == 0) { |
198 | 0 | key = privKey->data + 1; |
199 | 0 | } else if (privKey->len < 32) { |
200 | 0 | memcpy(padded_key_data + 32 - privKey->len, privKey->data, privKey->len); |
201 | 0 | key = padded_key_data; |
202 | 0 | } else { |
203 | 0 | PORT_SetError(SEC_ERROR_INPUT_LEN); |
204 | 0 | return SECFailure; |
205 | 0 | } |
206 | | |
207 | 984 | uint8_t hash[32] = { 0 }; |
208 | 984 | if (digest->len < 32) { |
209 | 555 | memcpy(hash + 32 - digest->len, digest->data, digest->len); |
210 | 555 | } else { |
211 | 429 | memcpy(hash, digest->data, 32); |
212 | 429 | } |
213 | | |
214 | 984 | uint8_t nonce[32] = { 0 }; |
215 | 984 | if (kblen < 32) { |
216 | 24 | memcpy(nonce + 32 - kblen, kb, kblen); |
217 | 960 | } else { |
218 | 960 | memcpy(nonce, kb, 32); |
219 | 960 | } |
220 | | |
221 | 984 | #ifndef UNSAFE_FUZZER_MODE |
222 | 984 | bool b = Hacl_P256_ecdsa_sign_p256_without_hash( |
223 | 984 | signature->data, 32, hash, key, nonce); |
224 | | #else |
225 | | bool b = key != NULL; /* Avoiding unused variable warnings */ |
226 | | #endif |
227 | | |
228 | 984 | if (!b) { |
229 | 6 | PORT_SetError(SEC_ERROR_BAD_KEY); |
230 | 6 | res = SECFailure; |
231 | 6 | return res; |
232 | 6 | } |
233 | | |
234 | 978 | signature->len = 64; |
235 | 978 | return res; |
236 | 984 | } |
237 | | |
238 | | /* |
239 | | * ECDSA Signature Verification for P-256 |
240 | | */ |
241 | | |
242 | | SECStatus |
243 | | ec_secp256r1_verify_digest(ECPublicKey *key, const SECItem *signature, |
244 | | const SECItem *digest) |
245 | 394 | { |
246 | 394 | SECStatus res = SECSuccess; |
247 | | |
248 | 394 | unsigned char _padded_sig_data[64] = { 0 }; |
249 | 394 | unsigned char *sig_r, *sig_s; |
250 | | |
251 | 394 | if (!key || !signature || !digest || |
252 | 394 | !key->publicValue.data || |
253 | 394 | !signature->data || !digest->data || |
254 | 394 | key->ecParams.name != ECCurve_NIST_P256) { |
255 | 0 | PORT_SetError(SEC_ERROR_INVALID_ARGS); |
256 | 0 | res = SECFailure; |
257 | 0 | return res; |
258 | 0 | } |
259 | | |
260 | 394 | unsigned int olen = key->ecParams.order.len; |
261 | 394 | if (signature->len == 0 || signature->len % 2 != 0 || |
262 | 394 | signature->len > 2 * olen || |
263 | 394 | digest->len == 0 || key->publicValue.len != 65) { |
264 | 0 | PORT_SetError(SEC_ERROR_INPUT_LEN); |
265 | 0 | res = SECFailure; |
266 | 0 | return res; |
267 | 0 | } |
268 | | |
269 | 394 | if (key->publicValue.data[0] != EC_POINT_FORM_UNCOMPRESSED) { |
270 | 0 | PORT_SetError(SEC_ERROR_UNSUPPORTED_EC_POINT_FORM); |
271 | 0 | res = SECFailure; |
272 | 0 | return res; |
273 | 0 | } |
274 | | |
275 | | /* P-256 signature has to be 64 bytes long, pad it with 0s if it isn't */ |
276 | 394 | if (signature->len != 64) { |
277 | 0 | unsigned split = signature->len / 2; |
278 | 0 | unsigned pad = 32 - split; |
279 | |
|
280 | 0 | unsigned char *o_sig = signature->data; |
281 | 0 | unsigned char *p_sig = _padded_sig_data; |
282 | |
|
283 | 0 | memcpy(p_sig + pad, o_sig, split); |
284 | 0 | memcpy(p_sig + 32 + pad, o_sig + split, split); |
285 | |
|
286 | 0 | sig_r = p_sig; |
287 | 0 | sig_s = p_sig + 32; |
288 | 394 | } else { |
289 | 394 | sig_r = signature->data; |
290 | 394 | sig_s = signature->data + 32; |
291 | 394 | } |
292 | | |
293 | 394 | uint8_t hash[32] = { 0 }; |
294 | 394 | if (digest->len < 32) { |
295 | 108 | memcpy(hash + 32 - digest->len, digest->data, digest->len); |
296 | 286 | } else { |
297 | 286 | memcpy(hash, digest->data, 32); |
298 | 286 | } |
299 | | |
300 | 394 | #ifndef UNSAFE_FUZZER_MODE |
301 | 394 | bool b = Hacl_P256_ecdsa_verif_without_hash( |
302 | 394 | 32, hash, |
303 | 394 | key->publicValue.data + 1, |
304 | 394 | sig_r, sig_s); |
305 | | #else |
306 | | bool b = (sig_r != NULL) && (sig_s != NULL); /* Avoiding unused variable warnings */ |
307 | | #endif |
308 | | |
309 | 394 | if (!b) { |
310 | 301 | PORT_SetError(SEC_ERROR_BAD_SIGNATURE); |
311 | 301 | res = SECFailure; |
312 | 301 | return res; |
313 | 301 | } |
314 | | |
315 | 93 | return res; |
316 | 394 | } |
317 | | |
318 | | /* |
319 | | Point decompression for P-256. |
320 | | |
321 | | publicCompressed must be 33 bytes (1 byte for a sign and 32 bytes for the x coordinate. |
322 | | publicUncompressed must be 64 bytes (32 * 2). |
323 | | The function returns SECSuccess if the decompression was success and the decompresse |
324 | | point is a valid P-256 curve point. |
325 | | */ |
326 | | |
327 | | SECStatus |
328 | | ec_secp256r1_decompress(const SECItem *publicCompressed, SECItem *publicUncompressed) |
329 | 106 | { |
330 | 106 | if (!publicCompressed || !publicCompressed->data) { |
331 | 0 | PORT_SetError(SEC_ERROR_INVALID_ARGS); |
332 | 0 | return SECFailure; |
333 | 0 | } |
334 | | |
335 | 106 | if (publicCompressed->len != 33) { |
336 | 106 | PORT_SetError(SEC_ERROR_BAD_KEY); |
337 | 106 | return SECFailure; |
338 | 106 | } |
339 | | |
340 | 0 | if (!publicUncompressed || !publicUncompressed->data) { |
341 | 0 | PORT_SetError(SEC_ERROR_INVALID_ARGS); |
342 | 0 | return SECFailure; |
343 | 0 | } |
344 | | |
345 | 0 | if (publicUncompressed->len != 65) { |
346 | 0 | PORT_SetError(SEC_ERROR_INVALID_ARGS); |
347 | 0 | return SECFailure; |
348 | 0 | } |
349 | | |
350 | 0 | if (publicCompressed->data[0] != EC_POINT_FORM_COMPRESSED_Y0 && |
351 | 0 | publicCompressed->data[0] != EC_POINT_FORM_COMPRESSED_Y1) { |
352 | 0 | PORT_SetError(SEC_ERROR_UNSUPPORTED_EC_POINT_FORM); |
353 | 0 | return SECFailure; |
354 | 0 | } |
355 | | |
356 | 0 | bool b = Hacl_P256_compressed_to_raw(publicCompressed->data, publicUncompressed->data + 1); |
357 | |
|
358 | 0 | if (!b) { |
359 | 0 | PORT_SetError(SEC_ERROR_BAD_KEY); |
360 | 0 | return SECFailure; |
361 | 0 | } |
362 | | |
363 | 0 | publicUncompressed->data[0] = EC_POINT_FORM_UNCOMPRESSED; |
364 | 0 | return SECSuccess; |
365 | 0 | } |