mirror of
https://github.com/ipxe/ipxe
synced 2025-12-06 17:30:26 +03:00
[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 <mcb30@ipxe.org>
This commit is contained in:
@@ -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 );
|
||||
|
||||
@@ -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 );
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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, \
|
||||
}
|
||||
|
||||
|
||||
@@ -35,10 +35,53 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include <ipxe/bigint.h>
|
||||
#include <ipxe/crypto.h>
|
||||
#include <ipxe/test.h>
|
||||
#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
|
||||
*
|
||||
|
||||
@@ -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
|
||||
*
|
||||
|
||||
@@ -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 );
|
||||
|
||||
@@ -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 );
|
||||
|
||||
Reference in New Issue
Block a user