diff options
Diffstat (limited to 'src')
| -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"); |
