From 17135c83fb056f93fe70bdb09dd05ecc08963eed Mon Sep 17 00:00:00 2001 From: Michael Brown Date: Tue, 30 Jan 2024 13:26:36 +0000 Subject: [crypto] Add an abstraction of an elliptic curve Define an abstraction of an elliptic curve with a fixed generator and one supported operation (scalar multiplication of a curve point). Signed-off-by: Michael Brown --- src/crypto/x25519.c | 31 +++++++++++++++++++++++++++++++ src/include/ipxe/crypto.h | 23 +++++++++++++++++++++++ src/include/ipxe/x25519.h | 3 +++ 3 files changed, 57 insertions(+) diff --git a/src/crypto/x25519.c b/src/crypto/x25519.c index d3a19bc..d58f716 100644 --- a/src/crypto/x25519.c +++ b/src/crypto/x25519.c @@ -61,6 +61,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); #include #include #include +#include #include /** X25519 reduction constant @@ -300,6 +301,11 @@ static const uint8_t x25519_121665_raw[] = { 0x01, 0xdb, 0x41 }; /** Constant 121665 (used in the Montgomery ladder) */ static union x25519_oct258 x25519_121665; +/** Constant g=9 (the group generator) */ +static struct x25519_value x25519_generator = { + .raw = { 9, } +}; + /** * Initialise constants * @@ -811,3 +817,28 @@ int x25519_key ( const struct x25519_value *base, /* Fail if result was all zeros (as required by RFC8422) */ return ( bigint_is_zero ( &point.value ) ? -EPERM : 0 ); } + +/** + * Multiply scalar by curve point + * + * @v base Base point (or NULL to use generator) + * @v scalar Scalar multiple + * @v result Result point to fill in + * @ret rc Return status code + */ +static int x25519_curve_multiply ( const void *base, const void *scalar, + void *result ) { + + /* Use base point if applicable */ + if ( ! base ) + base = &x25519_generator; + + return x25519_key ( base, scalar, result ); +} + +/** X25519 elliptic curve */ +struct elliptic_curve x25519_curve = { + .name = "x25519", + .keysize = sizeof ( struct x25519_value ), + .multiply = x25519_curve_multiply, +}; diff --git a/src/include/ipxe/crypto.h b/src/include/ipxe/crypto.h index a15d5eb..9ee1c40 100644 --- a/src/include/ipxe/crypto.h +++ b/src/include/ipxe/crypto.h @@ -195,6 +195,23 @@ struct pubkey_algorithm { const void *public_key, size_t public_key_len ); }; +/** An elliptic curve */ +struct elliptic_curve { + /** Curve name */ + const char *name; + /** Key size */ + size_t keysize; + /** Multiply scalar by curve point + * + * @v base Base point (or NULL to use generator) + * @v scalar Scalar multiple + * @v result Result point to fill in + * @ret rc Return status code + */ + int ( * multiply ) ( const void *base, const void *scalar, + void *result ); +}; + static inline void digest_init ( struct digest_algorithm *digest, void *ctx ) { digest->init ( ctx ); @@ -302,6 +319,12 @@ static inline int pubkey_match ( struct pubkey_algorithm *pubkey, public_key_len ); } +static inline int elliptic_multiply ( struct elliptic_curve *curve, + const void *base, const void *scalar, + void *result ) { + return curve->multiply ( base, scalar, result ); +} + extern void digest_null_init ( void *ctx ); extern void digest_null_update ( void *ctx, const void *src, size_t len ); extern void digest_null_final ( void *ctx, void *out ); diff --git a/src/include/ipxe/x25519.h b/src/include/ipxe/x25519.h index 6524abb..fd7caee 100644 --- a/src/include/ipxe/x25519.h +++ b/src/include/ipxe/x25519.h @@ -11,6 +11,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); #include #include +#include /** X25519 unsigned big integer size * @@ -88,4 +89,6 @@ extern int x25519_key ( const struct x25519_value *base, const struct x25519_value *scalar, struct x25519_value *result ); +extern struct elliptic_curve x25519_curve; + #endif /* _IPXE_X25519_H */ -- cgit v1.1