From: Michael Brown Date: Fri, 5 Dec 2025 14:47:55 +0000 (+0000) Subject: [crypto] Expose the (prime) group order as an elliptic curve property X-Git-Tag: rolling/bin~71 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d3adea83809537d7476430233994723c690ebfce;p=thirdparty%2Fipxe.git [crypto] Expose the (prime) group order as an elliptic curve property ECDSA requires knowledge of the group order of the base point, and is defined only for curves with a prime group order (e.g. the NIST curves). Add the group order as an explicit property of an elliptic curve, and add tests to verify that the order is correct. Signed-off-by: Michael Brown --- diff --git a/src/crypto/p256.c b/src/crypto/p256.c index 9b0b542a1..2ba66e72c 100644 --- a/src/crypto/p256.c +++ b/src/crypto/p256.c @@ -62,6 +62,13 @@ static const uint8_t p256_base[ P256_LEN * 2 ] = { 0xce, 0xcb, 0xb6, 0x40, 0x68, 0x37, 0xbf, 0x51, 0xf5 }; +/** P-256 group order */ +static const uint8_t p256_order[P256_LEN] = { + 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xbc, 0xe6, 0xfa, 0xad, 0xa7, 0x17, + 0x9e, 0x84, 0xf3, 0xb9, 0xca, 0xc2, 0xfc, 0x63, 0x25, 0x51 +}; + /** P-256 elliptic curve */ WEIERSTRASS_CURVE ( p256, p256_curve, P256_LEN, - p256_prime, p256_a, p256_b, p256_base ); + p256_prime, p256_a, p256_b, p256_base, p256_order ); diff --git a/src/crypto/p384.c b/src/crypto/p384.c index 887bf161d..a53a9ce9d 100644 --- a/src/crypto/p384.c +++ b/src/crypto/p384.c @@ -71,6 +71,15 @@ static const uint8_t p384_base[ P384_LEN * 2 ] = { 0x7a, 0x43, 0x1d, 0x7c, 0x90, 0xea, 0x0e, 0x5f }; +/** P-384 group order */ +static const uint8_t p384_order[P384_LEN] = { + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xc7, 0x63, 0x4d, 0x81, 0xf4, 0x37, 0x2d, 0xdf, 0x58, + 0x1a, 0x0d, 0xb2, 0x48, 0xb0, 0xa7, 0x7a, 0xec, 0xec, 0x19, 0x6a, + 0xcc, 0xc5, 0x29, 0x73 +}; + /** P-384 elliptic curve */ WEIERSTRASS_CURVE ( p384, p384_curve, P384_LEN, - p384_prime, p384_a, p384_b, p384_base ); + p384_prime, p384_a, p384_b, p384_base, p384_order ); diff --git a/src/include/ipxe/crypto.h b/src/include/ipxe/crypto.h index d2adea5d6..8941ffa01 100644 --- a/src/include/ipxe/crypto.h +++ b/src/include/ipxe/crypto.h @@ -183,6 +183,8 @@ struct elliptic_curve { size_t keysize; /** Generator base point */ const void *base; + /** Order of the generator (if prime) */ + const void *order; /** Multiply scalar by curve point * * @v base Base point diff --git a/src/include/ipxe/weierstrass.h b/src/include/ipxe/weierstrass.h index e5e411499..b718886f6 100644 --- a/src/include/ipxe/weierstrass.h +++ b/src/include/ipxe/weierstrass.h @@ -128,7 +128,8 @@ extern int weierstrass_multiply ( struct weierstrass_curve *curve, void *result ); /** Define a Weierstrass curve */ -#define WEIERSTRASS_CURVE( _name, _curve, _len, _prime, _a, _b, _base ) \ +#define WEIERSTRASS_CURVE( _name, _curve, _len, _prime, _a, _b, _base, \ + _order ) \ static bigint_t ( weierstrass_size(_len) ) \ _name ## _cache[WEIERSTRASS_NUM_CACHED]; \ static struct weierstrass_curve _name ## _weierstrass = { \ @@ -161,6 +162,7 @@ extern int weierstrass_multiply ( struct weierstrass_curve *curve, .pointsize = ( WEIERSTRASS_AXES * (_len) ), \ .keysize = (_len), \ .base = (_base), \ + .order = (_order), \ .multiply = _name ## _multiply, \ } diff --git a/src/tests/elliptic_test.c b/src/tests/elliptic_test.c index f856dcc7e..a2266626d 100644 --- a/src/tests/elliptic_test.c +++ b/src/tests/elliptic_test.c @@ -35,10 +35,53 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); #include #include #include +#include #include #include #include "elliptic_test.h" +/** + * Report elliptic curve sanity test result + * + * @v curve Elliptic curve + * @v file Test code file + * @v line Test code line + */ +void elliptic_curve_okx ( struct elliptic_curve *curve, const char *file, + unsigned int line ) { + static const uint8_t one[] = { 1 }; + size_t pointsize = curve->pointsize; + size_t keysize = curve->keysize; + uint8_t point[pointsize]; + uint8_t scalar[keysize]; + struct { + bigint_t ( bigint_required_size ( keysize ) ) scalar; + bigint_t ( bigint_required_size ( keysize ) ) one; + } temp; + + /* Check that curve has the required properties */ + okx ( curve->base != NULL, file, line ); + okx ( curve->order != NULL, file, line ); + + /* Test multiplying base point by group order. Result should + * be the point at infinity, which should not be representable + * as a point in affine coordinates (and so should fail). + */ + okx ( elliptic_multiply ( curve, curve->base, curve->order, + point ) != 0, file, line ); + + /* Test multiplying base point by group order plus one, to get + * back to the base point. + */ + bigint_init ( &temp.scalar, curve->order, keysize ); + bigint_init ( &temp.one, one, sizeof ( one ) ); + bigint_add ( &temp.one, &temp.scalar ); + bigint_done ( &temp.scalar, scalar, sizeof ( scalar ) ); + okx ( elliptic_multiply ( curve, curve->base, scalar, point ) == 0, + file, line ); + okx ( memcmp ( point, curve->base, pointsize ) == 0, file, line ); +} + /** * Report elliptic curve point multiplication test result * diff --git a/src/tests/elliptic_test.h b/src/tests/elliptic_test.h index ea2fb97d9..1fcc4b108 100644 --- a/src/tests/elliptic_test.h +++ b/src/tests/elliptic_test.h @@ -64,9 +64,19 @@ struct elliptic_multiply_test { .expected_len = sizeof ( name ## _expected ), \ }; +extern void elliptic_curve_okx ( struct elliptic_curve *curve, + const char *file, unsigned int line ); extern void elliptic_multiply_okx ( struct elliptic_multiply_test *test, const char *file, unsigned int line ); +/** + * Report an elliptic curve sanity test result + * + * @v curve Elliptic curve + */ +#define elliptic_curve_ok( curve ) \ + elliptic_curve_okx ( curve, __FILE__, __LINE__ ) + /** * Report an elliptic curve point multiplication test result * diff --git a/src/tests/p256_test.c b/src/tests/p256_test.c index e6db61a53..8b425f215 100644 --- a/src/tests/p256_test.c +++ b/src/tests/p256_test.c @@ -157,6 +157,9 @@ ELLIPTIC_MULTIPLY_TEST ( invalid_one, &p256_curve, */ static void p256_test_exec ( void ) { + /* Curve sanity test */ + elliptic_curve_ok ( &p256_curve ); + /* Tests from http://point-at-infinity.org/ecc/nisttv */ elliptic_multiply_ok ( &poi_1 ); elliptic_multiply_ok ( &poi_2 ); diff --git a/src/tests/p384_test.c b/src/tests/p384_test.c index 35c5679f8..0b172c648 100644 --- a/src/tests/p384_test.c +++ b/src/tests/p384_test.c @@ -203,6 +203,9 @@ ELLIPTIC_MULTIPLY_TEST ( invalid_one, &p384_curve, */ static void p384_test_exec ( void ) { + /* Curve sanity test */ + elliptic_curve_ok ( &p384_curve ); + /* Tests from http://point-at-infinity.org/ecc/nisttv */ elliptic_multiply_ok ( &poi_1 ); elliptic_multiply_ok ( &poi_2 );