summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/regress/lib/libcrypto/ecdsa/ecdsatest.c372
1 files changed, 177 insertions, 195 deletions
diff --git a/src/regress/lib/libcrypto/ecdsa/ecdsatest.c b/src/regress/lib/libcrypto/ecdsa/ecdsatest.c
index cb8f38b348..64815812b7 100644
--- a/src/regress/lib/libcrypto/ecdsa/ecdsatest.c
+++ b/src/regress/lib/libcrypto/ecdsa/ecdsatest.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: ecdsatest.c,v 1.13 2022/08/31 09:39:59 tb Exp $ */ 1/* $OpenBSD: ecdsatest.c,v 1.14 2022/09/02 11:47:25 tb Exp $ */
2/* 2/*
3 * Written by Nils Larsch for the OpenSSL project. 3 * Written by Nils Larsch for the OpenSSL project.
4 */ 4 */
@@ -84,118 +84,116 @@
84#include <openssl/err.h> 84#include <openssl/err.h>
85 85
86/* declaration of the test functions */ 86/* declaration of the test functions */
87int x9_62_test_internal(BIO *out, int nid, const char *r, const char *s); 87int x9_62_test_internal(int nid, const char *r, const char *s);
88int test_builtin(BIO *); 88int test_builtin(void);
89 89
90/* some tests from the X9.62 draft */ 90/* some tests from the X9.62 draft */
91int 91int
92x9_62_test_internal(BIO *out, int nid, const char *r_in, const char *s_in) 92x9_62_test_internal(int nid, const char *r_in, const char *s_in)
93{ 93{
94 int ret = 0; 94 EVP_MD_CTX *md_ctx = NULL;
95 const char message[] = "abc"; 95 const char message[] = "abc";
96 unsigned char digest[20]; 96 unsigned char digest[20];
97 unsigned int dgst_len = 0; 97 unsigned int dgst_len = 0;
98 EVP_MD_CTX *md_ctx = NULL; 98 EC_KEY *key = NULL;
99 EC_KEY *key = NULL;
100 ECDSA_SIG *signature = NULL; 99 ECDSA_SIG *signature = NULL;
101 BIGNUM *r = NULL, *s = NULL; 100 BIGNUM *r = NULL, *s = NULL;
101 int failed = 1;
102 102
103 if ((md_ctx = EVP_MD_CTX_new()) == NULL) 103 if ((md_ctx = EVP_MD_CTX_new()) == NULL)
104 goto x962_int_err; 104 goto err;
105 /* get the message digest */ 105
106 if (!EVP_DigestInit(md_ctx, EVP_sha1())) 106 if (!EVP_DigestInit(md_ctx, EVP_sha1()))
107 goto x962_int_err; 107 goto err;
108 if (!EVP_DigestUpdate(md_ctx, (const void*)message, 3)) 108 if (!EVP_DigestUpdate(md_ctx, message, 3))
109 goto x962_int_err; 109 goto err;
110 if (!EVP_DigestFinal(md_ctx, digest, &dgst_len)) 110 if (!EVP_DigestFinal(md_ctx, digest, &dgst_len))
111 goto x962_int_err; 111 goto err;
112
113 printf("testing %s: ", OBJ_nid2sn(nid));
112 114
113 BIO_printf(out, "testing %s: ", OBJ_nid2sn(nid));
114 /* create the key */
115 if ((key = EC_KEY_new_by_curve_name(nid)) == NULL) 115 if ((key = EC_KEY_new_by_curve_name(nid)) == NULL)
116 goto x962_int_err; 116 goto err;
117 if (!EC_KEY_generate_key(key)) 117 if (!EC_KEY_generate_key(key))
118 goto x962_int_err; 118 goto err;
119 BIO_printf(out, "."); 119
120 (void)BIO_flush(out); 120 printf(".");
121 /* create the signature */ 121 fflush(stdout);
122 signature = ECDSA_do_sign(digest, 20, key); 122
123 if (signature == NULL) 123 if ((signature = ECDSA_do_sign(digest, 20, key)) == NULL)
124 goto x962_int_err; 124 goto err;
125 BIO_printf(out, "."); 125
126 (void)BIO_flush(out); 126 printf(".");
127 /* compare the created signature with the expected signature */ 127 fflush(stdout);
128 if ((r = BN_new()) == NULL || (s = BN_new()) == NULL) 128
129 goto x962_int_err; 129 if (!BN_dec2bn(&r, r_in) || !BN_dec2bn(&s, s_in))
130 if (!BN_dec2bn(&r, r_in) || 130 goto err;
131 !BN_dec2bn(&s, s_in))
132 goto x962_int_err;
133 if (BN_cmp(ECDSA_SIG_get0_r(signature), r) || 131 if (BN_cmp(ECDSA_SIG_get0_r(signature), r) ||
134 BN_cmp(ECDSA_SIG_get0_s(signature), s)) 132 BN_cmp(ECDSA_SIG_get0_s(signature), s))
135 goto x962_int_err; 133 goto err;
136 BIO_printf(out, "."); 134
137 (void)BIO_flush(out); 135 printf(".");
138 /* verify the signature */ 136 fflush(stdout);
137
139 if (ECDSA_do_verify(digest, 20, signature, key) != 1) 138 if (ECDSA_do_verify(digest, 20, signature, key) != 1)
140 goto x962_int_err; 139 goto err;
141 BIO_printf(out, "."); 140
142 (void)BIO_flush(out); 141 printf(".");
143 142 fflush(stdout);
144 BIO_printf(out, " ok\n"); 143
145 ret = 1; 144 printf(" ok\n");
146 x962_int_err: 145
147 if (!ret) 146 failed = 0;
148 BIO_printf(out, " failed\n"); 147
149 if (key) 148 err:
150 EC_KEY_free(key); 149 if (failed)
151 if (signature) 150 printf(" failed\n");
152 ECDSA_SIG_free(signature); 151 EC_KEY_free(key);
153 if (r) 152 ECDSA_SIG_free(signature);
154 BN_free(r); 153 BN_free(r);
155 if (s) 154 BN_free(s);
156 BN_free(s);
157 EVP_MD_CTX_free(md_ctx); 155 EVP_MD_CTX_free(md_ctx);
158 return ret; 156 return failed;
159} 157}
160 158
161int 159int
162test_builtin(BIO *out) 160test_builtin(void)
163{ 161{
162 unsigned char digest[20], wrong_digest[20];
164 EC_builtin_curve *curves = NULL; 163 EC_builtin_curve *curves = NULL;
165 size_t num_curves = 0, n = 0; 164 size_t num_curves = 0, n = 0;
166 EC_KEY *eckey = NULL, *wrong_eckey = NULL; 165 EC_KEY *eckey = NULL, *wrong_eckey = NULL;
167 EC_GROUP *group; 166 EC_GROUP *group;
168 ECDSA_SIG *ecdsa_sig = NULL; 167 ECDSA_SIG *ecdsa_sig = NULL;
169 BIGNUM *r = NULL, *s = NULL; 168 BIGNUM *r = NULL, *s = NULL;
170 unsigned char digest[20], wrong_digest[20]; 169 unsigned char *signature = NULL;
171 unsigned char *signature = NULL; 170 const unsigned char *sig_ptr;
172 const unsigned char *sig_ptr; 171 unsigned char *sig_ptr2;
173 unsigned char *sig_ptr2; 172 unsigned char *raw_buf = NULL;
174 unsigned char *raw_buf = NULL; 173 unsigned int sig_len, degree, r_len, s_len, bn_len, buf_len;
175 unsigned int sig_len, degree, r_len, s_len, bn_len, buf_len; 174 int nid;
176 int nid, ret = 0; 175 int failed = 1;
177 176
178 /* fill digest values with some random data */ 177 /* fill digest values with some random data */
179 arc4random_buf(digest, 20); 178 arc4random_buf(digest, 20);
180 arc4random_buf(wrong_digest, 20); 179 arc4random_buf(wrong_digest, 20);
181 180
182 /* create and verify a ecdsa signature with every available curve */ 181 /* create and verify a ecdsa signature with every available curve */
183 BIO_printf(out, "\ntesting ECDSA_sign() and ECDSA_verify() " 182 printf("\ntesting ECDSA_sign() and ECDSA_verify() "
184 "with some internal curves:\n"); 183 "with some internal curves:\n");
185 184
186 /* get a list of all internal curves */ 185 /* get a list of all internal curves */
187 num_curves = EC_get_builtin_curves(NULL, 0); 186 num_curves = EC_get_builtin_curves(NULL, 0);
188 187
189 curves = reallocarray(NULL, sizeof(EC_builtin_curve), num_curves); 188 curves = reallocarray(NULL, sizeof(EC_builtin_curve), num_curves);
190
191 if (curves == NULL) { 189 if (curves == NULL) {
192 BIO_printf(out, "reallocarray error\n"); 190 printf("reallocarray error\n");
193 goto builtin_err; 191 goto err;
194 } 192 }
195 193
196 if (!EC_get_builtin_curves(curves, num_curves)) { 194 if (!EC_get_builtin_curves(curves, num_curves)) {
197 BIO_printf(out, "unable to get internal curves\n"); 195 printf("unable to get internal curves\n");
198 goto builtin_err; 196 goto err;
199 } 197 }
200 198
201 /* now create and verify a signature for every curve */ 199 /* now create and verify a signature for every curve */
@@ -205,94 +203,85 @@ test_builtin(BIO *out)
205 nid = curves[n].nid; 203 nid = curves[n].nid;
206 if (nid == NID_ipsec4) 204 if (nid == NID_ipsec4)
207 continue; 205 continue;
208 /* create new ecdsa key (== EC_KEY) */ 206
209 if ((eckey = EC_KEY_new()) == NULL) 207 if ((eckey = EC_KEY_new()) == NULL)
210 goto builtin_err; 208 goto err;
211 group = EC_GROUP_new_by_curve_name(nid); 209 group = EC_GROUP_new_by_curve_name(nid);
212 if (group == NULL) 210 if (group == NULL)
213 goto builtin_err; 211 goto err;
214 if (EC_KEY_set_group(eckey, group) == 0) 212 if (EC_KEY_set_group(eckey, group) == 0)
215 goto builtin_err; 213 goto err;
214 degree = EC_GROUP_get_degree(group);
216 EC_GROUP_free(group); 215 EC_GROUP_free(group);
217 degree = EC_GROUP_get_degree(EC_KEY_get0_group(eckey));
218 if (degree < 160) { 216 if (degree < 160) {
219 /* drop the curve */ 217 /* drop the curve */
220 EC_KEY_free(eckey); 218 EC_KEY_free(eckey);
221 eckey = NULL; 219 eckey = NULL;
222 continue; 220 continue;
223 } 221 }
224 BIO_printf(out, "%s: ", OBJ_nid2sn(nid)); 222 printf("%s: ", OBJ_nid2sn(nid));
225 /* create key */ 223
226 if (!EC_KEY_generate_key(eckey)) { 224 if (!EC_KEY_generate_key(eckey)) {
227 BIO_printf(out, " failed\n"); 225 goto err;
228 goto builtin_err;
229 } 226 }
230 /* create second key */ 227
231 if ((wrong_eckey = EC_KEY_new()) == NULL) 228 if ((wrong_eckey = EC_KEY_new()) == NULL)
232 goto builtin_err; 229 goto err;
233 group = EC_GROUP_new_by_curve_name(nid); 230 group = EC_GROUP_new_by_curve_name(nid);
234 if (group == NULL) 231 if (group == NULL)
235 goto builtin_err; 232 goto err;
236 if (EC_KEY_set_group(wrong_eckey, group) == 0) 233 if (EC_KEY_set_group(wrong_eckey, group) == 0)
237 goto builtin_err; 234 goto err;
238 EC_GROUP_free(group); 235 EC_GROUP_free(group);
239 if (!EC_KEY_generate_key(wrong_eckey)) { 236 if (!EC_KEY_generate_key(wrong_eckey))
240 BIO_printf(out, " failed\n"); 237 goto err;
241 goto builtin_err; 238
242 } 239 printf(".");
240 fflush(stdout);
241
242 if (!EC_KEY_check_key(eckey))
243 goto err;
244
245 printf(".");
246 fflush(stdout);
243 247
244 BIO_printf(out, ".");
245 (void)BIO_flush(out);
246 /* check key */
247 if (!EC_KEY_check_key(eckey)) {
248 BIO_printf(out, " failed\n");
249 goto builtin_err;
250 }
251 BIO_printf(out, ".");
252 (void)BIO_flush(out);
253 /* create signature */
254 if ((sig_len = ECDSA_size(eckey)) == 0) 248 if ((sig_len = ECDSA_size(eckey)) == 0)
255 goto builtin_err; 249 goto err;
256 if ((signature = malloc(sig_len)) == NULL) 250 if ((signature = malloc(sig_len)) == NULL)
257 goto builtin_err; 251 goto err;
258 if (!ECDSA_sign(0, digest, 20, signature, &sig_len, eckey)) { 252 if (!ECDSA_sign(0, digest, 20, signature, &sig_len, eckey))
259 BIO_printf(out, " failed\n"); 253 goto err;
260 goto builtin_err; 254
261 } 255 printf(".");
262 BIO_printf(out, "."); 256 fflush(stdout);
263 (void)BIO_flush(out); 257
264 /* verify signature */ 258 if (ECDSA_verify(0, digest, 20, signature, sig_len, eckey) != 1)
265 if (ECDSA_verify(0, digest, 20, signature, sig_len, 259 goto err;
266 eckey) != 1) { 260
267 BIO_printf(out, " failed\n"); 261 printf(".");
268 goto builtin_err; 262 fflush(stdout);
269 } 263
270 BIO_printf(out, ".");
271 (void)BIO_flush(out);
272 /* verify signature with the wrong key */ 264 /* verify signature with the wrong key */
273 if (ECDSA_verify(0, digest, 20, signature, sig_len, 265 if (ECDSA_verify(0, digest, 20, signature, sig_len,
274 wrong_eckey) == 1) { 266 wrong_eckey) == 1)
275 BIO_printf(out, " failed\n"); 267 goto err;
276 goto builtin_err; 268
277 } 269 printf(".");
278 BIO_printf(out, "."); 270 fflush(stdout);
279 (void)BIO_flush(out); 271
280 /* wrong digest */
281 if (ECDSA_verify(0, wrong_digest, 20, signature, sig_len, 272 if (ECDSA_verify(0, wrong_digest, 20, signature, sig_len,
282 eckey) == 1) { 273 eckey) == 1)
283 BIO_printf(out, " failed\n"); 274 goto err;
284 goto builtin_err; 275
285 } 276 printf(".");
286 BIO_printf(out, "."); 277 fflush(stdout);
287 (void)BIO_flush(out); 278
288 /* wrong length */
289 if (ECDSA_verify(0, digest, 20, signature, sig_len - 1, 279 if (ECDSA_verify(0, digest, 20, signature, sig_len - 1,
290 eckey) == 1) { 280 eckey) == 1)
291 BIO_printf(out, " failed\n"); 281 goto err;
292 goto builtin_err; 282
293 } 283 printf(".");
294 BIO_printf(out, "."); 284 fflush(stdout);
295 (void)BIO_flush(out);
296 285
297 /* 286 /*
298 * Modify a single byte of the signature: to ensure we don't 287 * Modify a single byte of the signature: to ensure we don't
@@ -301,82 +290,77 @@ test_builtin(BIO *out)
301 */ 290 */
302 sig_ptr = signature; 291 sig_ptr = signature;
303 if ((ecdsa_sig = d2i_ECDSA_SIG(NULL, &sig_ptr, 292 if ((ecdsa_sig = d2i_ECDSA_SIG(NULL, &sig_ptr,
304 sig_len)) == NULL) { 293 sig_len)) == NULL)
305 BIO_printf(out, " failed\n"); 294 goto err;
306 goto builtin_err;
307 }
308 295
309 /* Store the two BIGNUMs in raw_buf. */ 296 /* Store the two BIGNUMs in raw_buf. */
310 r_len = BN_num_bytes(ECDSA_SIG_get0_r(ecdsa_sig)); 297 r_len = BN_num_bytes(ECDSA_SIG_get0_r(ecdsa_sig));
311 s_len = BN_num_bytes(ECDSA_SIG_get0_s(ecdsa_sig)); 298 s_len = BN_num_bytes(ECDSA_SIG_get0_s(ecdsa_sig));
312 bn_len = (degree + 7) / 8; 299 bn_len = (degree + 7) / 8;
313 if ((r_len > bn_len) || (s_len > bn_len)) { 300 if ((r_len > bn_len) || (s_len > bn_len))
314 BIO_printf(out, " failed\n"); 301 goto err;
315 goto builtin_err; 302
316 }
317 buf_len = 2 * bn_len; 303 buf_len = 2 * bn_len;
318 if ((raw_buf = calloc(1, buf_len)) == NULL) 304 if ((raw_buf = calloc(1, buf_len)) == NULL)
319 goto builtin_err; 305 goto err;
320 BN_bn2bin(ECDSA_SIG_get0_r(ecdsa_sig), raw_buf + bn_len - r_len); 306 BN_bn2bin(ECDSA_SIG_get0_r(ecdsa_sig),
321 BN_bn2bin(ECDSA_SIG_get0_s(ecdsa_sig), raw_buf + buf_len - s_len); 307 raw_buf + bn_len - r_len);
308 BN_bn2bin(ECDSA_SIG_get0_s(ecdsa_sig),
309 raw_buf + buf_len - s_len);
322 310
323 /* Modify a single byte in the buffer. */ 311 /* Modify a single byte in the buffer. */
324 offset = raw_buf[10] % buf_len; 312 offset = raw_buf[10] % buf_len;
325 dirt = raw_buf[11] ? raw_buf[11] : 1; 313 dirt = raw_buf[11] ? raw_buf[11] : 1;
326 raw_buf[offset] ^= dirt; 314 raw_buf[offset] ^= dirt;
327 /* Now read the BIGNUMs back in from raw_buf. */ 315 /* Now read the BIGNUMs back in from raw_buf. */
328 if ((r = BN_bin2bn(raw_buf, bn_len, NULL)) == NULL || 316 if ((r = BN_bin2bn(raw_buf, bn_len, NULL)) == NULL ||
329 (s = BN_bin2bn(raw_buf + bn_len, bn_len, NULL)) == NULL) 317 (s = BN_bin2bn(raw_buf + bn_len, bn_len, NULL)) == NULL)
330 goto builtin_err; 318 goto err;
331 if (!ECDSA_SIG_set0(ecdsa_sig, r, s)) 319 if (!ECDSA_SIG_set0(ecdsa_sig, r, s))
332 goto builtin_err; 320 goto err;
333 r = NULL; 321 r = NULL;
334 s = NULL; 322 s = NULL;
335 323
336 if ((sig_len = i2d_ECDSA_SIG(ecdsa_sig, NULL)) <= 0) 324 if ((sig_len = i2d_ECDSA_SIG(ecdsa_sig, NULL)) <= 0)
337 goto builtin_err; 325 goto err;
338 free(signature); 326 free(signature);
339 if ((signature = calloc(1, sig_len)) == NULL) 327 if ((signature = calloc(1, sig_len)) == NULL)
340 goto builtin_err; 328 goto err;
341 329
342 sig_ptr2 = signature; 330 sig_ptr2 = signature;
343 if ((sig_len = i2d_ECDSA_SIG(ecdsa_sig, &sig_ptr2)) <= 0) 331 if ((sig_len = i2d_ECDSA_SIG(ecdsa_sig, &sig_ptr2)) <= 0)
344 goto builtin_err; 332 goto err;
345 if (ECDSA_verify(0, digest, 20, signature, sig_len, 333 if (ECDSA_verify(0, digest, 20, signature, sig_len, eckey) == 1)
346 eckey) == 1) { 334 goto err;
347 BIO_printf(out, " failed\n"); 335
348 goto builtin_err;
349 }
350 /* Sanity check: undo the modification and verify signature. */ 336 /* Sanity check: undo the modification and verify signature. */
351 raw_buf[offset] ^= dirt; 337 raw_buf[offset] ^= dirt;
352 if ((r = BN_bin2bn(raw_buf, bn_len, NULL)) == NULL || 338 if ((r = BN_bin2bn(raw_buf, bn_len, NULL)) == NULL ||
353 (s = BN_bin2bn(raw_buf + bn_len, bn_len, NULL)) == NULL) 339 (s = BN_bin2bn(raw_buf + bn_len, bn_len, NULL)) == NULL)
354 goto builtin_err; 340 goto err;
355 if (!ECDSA_SIG_set0(ecdsa_sig, r, s)) 341 if (!ECDSA_SIG_set0(ecdsa_sig, r, s))
356 goto builtin_err; 342 goto err;
357 r = NULL; 343 r = NULL;
358 s = NULL; 344 s = NULL;
359 345
360 if ((sig_len = i2d_ECDSA_SIG(ecdsa_sig, NULL)) <= 0) 346 if ((sig_len = i2d_ECDSA_SIG(ecdsa_sig, NULL)) <= 0)
361 goto builtin_err; 347 goto err;
362 free(signature); 348 free(signature);
363 if ((signature = calloc(1, sig_len)) == NULL) 349 if ((signature = calloc(1, sig_len)) == NULL)
364 goto builtin_err; 350 goto err;
365 351
366 sig_ptr2 = signature; 352 sig_ptr2 = signature;
367 if ((sig_len = i2d_ECDSA_SIG(ecdsa_sig, &sig_ptr2)) <= 0) 353 if ((sig_len = i2d_ECDSA_SIG(ecdsa_sig, &sig_ptr2)) <= 0)
368 goto builtin_err; 354 goto err;
369 if (ECDSA_verify(0, digest, 20, signature, sig_len, 355 if (ECDSA_verify(0, digest, 20, signature, sig_len,
370 eckey) != 1) { 356 eckey) != 1)
371 BIO_printf(out, " failed\n"); 357 goto err;
372 goto builtin_err; 358
373 } 359 printf(".");
374 BIO_printf(out, "."); 360 fflush(stdout);
375 (void)BIO_flush(out); 361
362 printf(" ok\n");
376 363
377 BIO_printf(out, " ok\n");
378 /* cleanup */
379 /* clean bogus errors */
380 ERR_clear_error(); 364 ERR_clear_error();
381 free(signature); 365 free(signature);
382 signature = NULL; 366 signature = NULL;
@@ -390,8 +374,12 @@ test_builtin(BIO *out)
390 raw_buf = NULL; 374 raw_buf = NULL;
391 } 375 }
392 376
393 ret = 1; 377 failed = 0;
394 builtin_err: 378
379 err:
380 if (failed)
381 printf(" failed\n");
382
395 BN_free(r); 383 BN_free(r);
396 BN_free(s); 384 BN_free(s);
397 EC_KEY_free(eckey); 385 EC_KEY_free(eckey);
@@ -401,36 +389,30 @@ test_builtin(BIO *out)
401 free(raw_buf); 389 free(raw_buf);
402 free(curves); 390 free(curves);
403 391
404 return ret; 392 return failed;
405} 393}
406 394
407int 395int
408main(void) 396main(void)
409{ 397{
410 int ret = 1; 398 int failed = 1;
411 BIO *out;
412
413 out = BIO_new_fp(stdout, BIO_NOCLOSE);
414
415 ERR_load_crypto_strings();
416 399
417 /* the tests */ 400 /* the tests */
418 if (!test_builtin(out)) 401 if (test_builtin())
419 goto err; 402 goto err;
420 403
421 ret = 0; 404 printf("\nECDSA test passed\n");
405 failed = 0;
406
422 err: 407 err:
423 if (ret) 408 if (failed) {
424 BIO_printf(out, "\nECDSA test failed\n"); 409 printf("\nECDSA test failed\n");
425 else 410 ERR_print_errors_fp(stdout);
426 BIO_printf(out, "\nECDSA test passed\n"); 411 }
427 if (ret) 412
428 ERR_print_errors(out);
429 CRYPTO_cleanup_all_ex_data(); 413 CRYPTO_cleanup_all_ex_data();
430 ERR_remove_thread_state(NULL); 414 ERR_remove_thread_state(NULL);
431 ERR_free_strings(); 415 ERR_free_strings();
432 CRYPTO_mem_leaks(out); 416
433 if (out != NULL) 417 return failed;
434 BIO_free(out);
435 return ret;
436} 418}