diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/regress/lib/libcrypto/ec/ec_point_conversion.c | 78 |
1 files changed, 76 insertions, 2 deletions
diff --git a/src/regress/lib/libcrypto/ec/ec_point_conversion.c b/src/regress/lib/libcrypto/ec/ec_point_conversion.c index 0c1b09d221..e4d390ec0b 100644 --- a/src/regress/lib/libcrypto/ec/ec_point_conversion.c +++ b/src/regress/lib/libcrypto/ec/ec_point_conversion.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: ec_point_conversion.c,v 1.15 2024/01/18 16:49:40 tb Exp $ */ | 1 | /* $OpenBSD: ec_point_conversion.c,v 1.16 2024/10/23 14:10:03 tb Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2021 Theo Buehler <tb@openbsd.org> | 3 | * Copyright (c) 2021 Theo Buehler <tb@openbsd.org> |
4 | * Copyright (c) 2021 Joel Sing <jsing@openbsd.org> | 4 | * Copyright (c) 2021 Joel Sing <jsing@openbsd.org> |
@@ -19,6 +19,7 @@ | |||
19 | #include <err.h> | 19 | #include <err.h> |
20 | #include <stdio.h> | 20 | #include <stdio.h> |
21 | #include <stdlib.h> | 21 | #include <stdlib.h> |
22 | #include <string.h> | ||
22 | 23 | ||
23 | #include <openssl/bn.h> | 24 | #include <openssl/bn.h> |
24 | #include <openssl/ec.h> | 25 | #include <openssl/ec.h> |
@@ -204,8 +205,9 @@ static const struct point_conversion { | |||
204 | const char *description; | 205 | const char *description; |
205 | int nid; | 206 | int nid; |
206 | uint8_t octets[256]; | 207 | uint8_t octets[256]; |
207 | uint8_t octets_len; | 208 | size_t octets_len; |
208 | int valid; | 209 | int valid; |
210 | int point_at_infinity; | ||
209 | } point_conversions[] = { | 211 | } point_conversions[] = { |
210 | /* XXX - now that sect571 is no longer tested, add another test? */ | 212 | /* XXX - now that sect571 is no longer tested, add another test? */ |
211 | { | 213 | { |
@@ -214,6 +216,7 @@ static const struct point_conversion { | |||
214 | .octets = { 0x00 }, | 216 | .octets = { 0x00 }, |
215 | .octets_len = 1, | 217 | .octets_len = 1, |
216 | .valid = 1, | 218 | .valid = 1, |
219 | .point_at_infinity = 1, | ||
217 | }, | 220 | }, |
218 | { | 221 | { |
219 | .description = "point at infinity on secp256r1 (flipped y_bit)", | 222 | .description = "point at infinity on secp256r1 (flipped y_bit)", |
@@ -221,6 +224,7 @@ static const struct point_conversion { | |||
221 | .octets = { 0x01 }, | 224 | .octets = { 0x01 }, |
222 | .octets_len = 1, | 225 | .octets_len = 1, |
223 | .valid = 0, | 226 | .valid = 0, |
227 | .point_at_infinity = 1, | ||
224 | }, | 228 | }, |
225 | { | 229 | { |
226 | .description = "zero x compressed point on secp256r1", | 230 | .description = "zero x compressed point on secp256r1", |
@@ -492,6 +496,49 @@ static const size_t N_POINT_CONVERSIONS = | |||
492 | sizeof(point_conversions) / sizeof(point_conversions[0]); | 496 | sizeof(point_conversions) / sizeof(point_conversions[0]); |
493 | 497 | ||
494 | static int | 498 | static int |
499 | check_point_at_infinity(const EC_GROUP *group, const EC_POINT *point, | ||
500 | const struct point_conversion *test) | ||
501 | { | ||
502 | const uint8_t conversion_forms[4] = { 0x00, 0x02, 0x04, 0x06, }; | ||
503 | uint8_t buf[1]; | ||
504 | uint8_t form; | ||
505 | size_t i, ret; | ||
506 | int failed = 0; | ||
507 | |||
508 | /* The form for the point at infinity is expected to fail. */ | ||
509 | form = conversion_forms[0]; | ||
510 | |||
511 | ret = EC_POINT_point2oct(group, point, form, buf, sizeof(buf), NULL); | ||
512 | if (ret != 0) { | ||
513 | fprintf(stderr, "FAIL: %s: expected encoding with form 0x%02x" | ||
514 | "to fail, got %zu\n", test->description, form, ret); | ||
515 | failed |= 1; | ||
516 | } | ||
517 | |||
518 | /* For all other forms we expect the zero octet. */ | ||
519 | for (i = 1; i < sizeof(conversion_forms); i++) { | ||
520 | form = conversion_forms[i]; | ||
521 | |||
522 | ret = EC_POINT_point2oct(group, point, form, buf, sizeof(buf), NULL); | ||
523 | if (ret != 1) { | ||
524 | fprintf(stderr, "FAIL: %s: expected success, got %zu\n", | ||
525 | test->description, ret); | ||
526 | failed |= 1; | ||
527 | continue; | ||
528 | } | ||
529 | |||
530 | if (memcmp(buf, test->octets, test->octets_len) != 0) { | ||
531 | fprintf(stderr, "FAIL: %s: want 0x%02x, got 0x%02x\n", | ||
532 | test->description, test->octets[0], buf[0]); | ||
533 | failed |= 1; | ||
534 | continue; | ||
535 | } | ||
536 | } | ||
537 | |||
538 | return failed; | ||
539 | } | ||
540 | |||
541 | static int | ||
495 | point_conversion_form_y_bit(const struct point_conversion *test) | 542 | point_conversion_form_y_bit(const struct point_conversion *test) |
496 | { | 543 | { |
497 | EC_GROUP *group = NULL; | 544 | EC_GROUP *group = NULL; |
@@ -512,6 +559,33 @@ point_conversion_form_y_bit(const struct point_conversion *test) | |||
512 | failed |= 1; | 559 | failed |= 1; |
513 | } | 560 | } |
514 | 561 | ||
562 | if (test->valid && test->point_at_infinity) | ||
563 | failed |= check_point_at_infinity(group, point, test); | ||
564 | else if (test->valid) { | ||
565 | uint8_t buf[256]; | ||
566 | uint8_t form = test->octets[0] & 0x06; | ||
567 | size_t len; | ||
568 | |||
569 | len = EC_POINT_point2oct(group, point, form, buf, sizeof(buf), NULL); | ||
570 | |||
571 | if (len != test->octets_len) { | ||
572 | fprintf(stderr, "%s: EC_POINT_point2oct: want %zu, got %zu\n", | ||
573 | test->description, test->octets_len, len); | ||
574 | failed |= 1; | ||
575 | goto failed; | ||
576 | } | ||
577 | if (memcmp(test->octets, buf, len) != 0) { | ||
578 | fprintf(stderr, "%s: unexpected encoding\nwant:\n", | ||
579 | test->description); | ||
580 | hexdump(test->octets, test->octets_len); | ||
581 | fprintf(stderr, "\ngot:\n"); | ||
582 | hexdump(buf, len); | ||
583 | failed |= 1; | ||
584 | goto failed; | ||
585 | } | ||
586 | } | ||
587 | |||
588 | failed: | ||
515 | EC_GROUP_free(group); | 589 | EC_GROUP_free(group); |
516 | EC_POINT_free(point); | 590 | EC_POINT_free(point); |
517 | 591 | ||