diff options
Diffstat (limited to 'src/regress/lib')
-rw-r--r-- | src/regress/lib/libcrypto/curve25519/ed25519test.c | 134 |
1 files changed, 132 insertions, 2 deletions
diff --git a/src/regress/lib/libcrypto/curve25519/ed25519test.c b/src/regress/lib/libcrypto/curve25519/ed25519test.c index 1ad070ae3b..9053ef0a83 100644 --- a/src/regress/lib/libcrypto/curve25519/ed25519test.c +++ b/src/regress/lib/libcrypto/curve25519/ed25519test.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* $OpenBSD: ed25519test.c,v 1.3 2022/11/09 17:49:54 jsing Exp $ */ | 1 | /* $OpenBSD: ed25519test.c,v 1.4 2022/11/17 19:06:35 tb Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2019 Theo Buehler <tb@openbsd.org> | 3 | * Copyright (c) 2019, 2022 Theo Buehler <tb@openbsd.org> |
4 | * | 4 | * |
5 | * Permission to use, copy, modify, and distribute this software for any | 5 | * Permission to use, copy, modify, and distribute this software for any |
6 | * purpose with or without fee is hereby granted, provided that the above | 6 | * purpose with or without fee is hereby granted, provided that the above |
@@ -17,6 +17,7 @@ | |||
17 | 17 | ||
18 | #include <err.h> | 18 | #include <err.h> |
19 | #include <stdio.h> | 19 | #include <stdio.h> |
20 | #include <stdlib.h> | ||
20 | #include <string.h> | 21 | #include <string.h> |
21 | 22 | ||
22 | #include <openssl/curve25519.h> | 23 | #include <openssl/curve25519.h> |
@@ -353,6 +354,134 @@ test_ED25519_sign(void) | |||
353 | return failed; | 354 | return failed; |
354 | } | 355 | } |
355 | 356 | ||
357 | static void | ||
358 | hexdump(const unsigned char *buf, size_t len) | ||
359 | { | ||
360 | size_t i; | ||
361 | |||
362 | for (i = 1; i <= len; i++) | ||
363 | fprintf(stderr, " 0x%02hhx,%s", buf[i - 1], i % 8 ? "" : "\n"); | ||
364 | |||
365 | if (len % 8) | ||
366 | fprintf(stderr, "\n"); | ||
367 | } | ||
368 | |||
369 | static void | ||
370 | dump_info(const uint8_t *message, size_t message_len, const uint8_t *public_key, | ||
371 | const uint8_t *private_key, const uint8_t *signature) | ||
372 | { | ||
373 | |||
374 | fprintf(stderr, "message:\n"); | ||
375 | hexdump(message, message_len); | ||
376 | |||
377 | fprintf(stderr, "public key:\n"); | ||
378 | hexdump(public_key, ED25519_PUBLIC_KEY_LENGTH); | ||
379 | fprintf(stderr, "private key:\n"); | ||
380 | hexdump(private_key, ED25519_PRIVATE_KEY_LENGTH); | ||
381 | |||
382 | if (signature != NULL) { | ||
383 | fprintf(stderr, "signature:\n"); | ||
384 | hexdump(signature, ED25519_SIGNATURE_LENGTH); | ||
385 | } | ||
386 | } | ||
387 | |||
388 | static void | ||
389 | dump_once(const char *description, const uint8_t *message, size_t message_len, | ||
390 | const uint8_t *public_key, const uint8_t *private_key, | ||
391 | const uint8_t *signature) | ||
392 | { | ||
393 | static int dumped = 0; | ||
394 | |||
395 | if (dumped) | ||
396 | return; | ||
397 | |||
398 | fprintf(stderr, "%s\n", description); | ||
399 | dump_info(message, message_len, public_key, private_key, signature); | ||
400 | |||
401 | dumped = 1; | ||
402 | } | ||
403 | |||
404 | /* | ||
405 | * Little-endian representation of the order of edwards25519, | ||
406 | * see https://www.rfc-editor.org/rfc/rfc7748#section-4.1 | ||
407 | */ | ||
408 | static const uint8_t order[] = { | ||
409 | 0xed, 0xd3, 0xf5, 0x5c, 0x1a, 0x63, 0x12, 0x58, | ||
410 | 0xd6, 0x9c, 0xf7, 0xa2, 0xde, 0xf9, 0xde, 0x14, | ||
411 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
412 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, | ||
413 | }; | ||
414 | |||
415 | /* | ||
416 | * Modify signature by adding the group order to the upper half of the | ||
417 | * signature. This is caught by the check added in curve25519.c r1.14. | ||
418 | */ | ||
419 | static void | ||
420 | modify_signature(uint8_t *signature) | ||
421 | { | ||
422 | uint8_t *upper_half = &signature[32]; | ||
423 | size_t i; | ||
424 | |||
425 | for (i = 0; i < sizeof(order); i++) { | ||
426 | if (i < sizeof(order) - 1 && 0xff - order[i] < upper_half[i]) | ||
427 | upper_half[i + 1] += 1; | ||
428 | upper_half[i] += order[i]; | ||
429 | } | ||
430 | } | ||
431 | |||
432 | static int | ||
433 | test_signature_malleability(void) | ||
434 | { | ||
435 | uint8_t public_key[ED25519_PUBLIC_KEY_LENGTH]; | ||
436 | uint8_t private_key[ED25519_PRIVATE_KEY_LENGTH]; | ||
437 | uint8_t message[32]; | ||
438 | uint8_t signature[ED25519_SIGNATURE_LENGTH]; | ||
439 | int failed = 1; | ||
440 | |||
441 | ED25519_keypair(public_key, private_key); | ||
442 | arc4random_buf(message, sizeof(message)); | ||
443 | |||
444 | if (!ED25519_sign(signature, message, sizeof(message), | ||
445 | public_key, private_key)) { | ||
446 | fprintf(stderr, "Failed to sign random message\n"); | ||
447 | dump_info(message, sizeof(message), public_key, private_key, | ||
448 | NULL); | ||
449 | goto err; | ||
450 | } | ||
451 | |||
452 | if (!ED25519_verify(message, sizeof(message), signature, public_key)) { | ||
453 | fprintf(stderr, "Failed to verify random message\n"); | ||
454 | dump_info(message, sizeof(message), public_key, private_key, | ||
455 | signature); | ||
456 | goto err; | ||
457 | } | ||
458 | |||
459 | modify_signature(signature); | ||
460 | |||
461 | if (ED25519_verify(message, sizeof(message), signature, public_key)) { | ||
462 | dump_once("Verified with modified signature", message, | ||
463 | sizeof(message), public_key, private_key, signature); | ||
464 | goto err; | ||
465 | } | ||
466 | |||
467 | failed = 0; | ||
468 | |||
469 | err: | ||
470 | return failed; | ||
471 | } | ||
472 | |||
473 | static int | ||
474 | test_ED25519_signature_malleability(void) | ||
475 | { | ||
476 | int i; | ||
477 | int failed = 0; | ||
478 | |||
479 | for (i = 0; i < 128; i++) | ||
480 | failed |= test_signature_malleability(); | ||
481 | |||
482 | return failed; | ||
483 | } | ||
484 | |||
356 | int | 485 | int |
357 | main(int argc, char *argv[]) | 486 | main(int argc, char *argv[]) |
358 | { | 487 | { |
@@ -360,6 +489,7 @@ main(int argc, char *argv[]) | |||
360 | 489 | ||
361 | failed |= test_ED25519_verify(); | 490 | failed |= test_ED25519_verify(); |
362 | failed |= test_ED25519_sign(); | 491 | failed |= test_ED25519_sign(); |
492 | failed |= test_ED25519_signature_malleability(); | ||
363 | 493 | ||
364 | if (failed) | 494 | if (failed) |
365 | fprintf(stderr, "FAILED\n"); | 495 | fprintf(stderr, "FAILED\n"); |