diff options
Diffstat (limited to 'src/crypto/x25519.c')
| -rw-r--r-- | src/crypto/x25519.c | 68 |
1 files changed, 54 insertions, 14 deletions
diff --git a/src/crypto/x25519.c b/src/crypto/x25519.c index d58f7168c..95c42ea13 100644 --- a/src/crypto/x25519.c +++ b/src/crypto/x25519.c @@ -22,6 +22,7 @@ */ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); +FILE_SECBOOT ( PERMITTED ); /** @file * @@ -334,6 +335,7 @@ static void x25519_init_constants ( void ) { /** Initialisation function */ struct init_fn x25519_init_fn __init_fn ( INIT_NORMAL ) = { + .name = "x25519", .initialise = x25519_init_constants, }; @@ -563,8 +565,8 @@ void x25519_invert ( const union x25519_oct258 *invertend, * @v value Big integer to be subtracted from, if possible */ static void x25519_reduce_by ( const x25519_t *subtrahend, x25519_t *value ) { - unsigned int max_bit = ( ( 8 * sizeof ( *value ) ) - 1 ); x25519_t tmp; + int underflow; /* Conditionally subtract subtrahend * @@ -572,8 +574,8 @@ static void x25519_reduce_by ( const x25519_t *subtrahend, x25519_t *value ) { * time) if the subtraction underflows. */ bigint_copy ( value, &tmp ); - bigint_subtract ( subtrahend, value ); - bigint_swap ( value, &tmp, bigint_bit_is_set ( value, max_bit ) ); + underflow = bigint_subtract ( subtrahend, value ); + bigint_swap ( value, &tmp, underflow ); } /** @@ -783,16 +785,29 @@ static void x25519_reverse ( struct x25519_value *value ) { } /** + * Check if X25519 value is zero + * + * @v value Value to check + * @ret is_zero Value is zero + */ +int x25519_is_zero ( const struct x25519_value *value ) { + x25519_t point; + + /* Check if value is zero */ + bigint_init ( &point, value->raw, sizeof ( value->raw ) ); + return bigint_is_zero ( &point ); +} + +/** * Calculate X25519 key * * @v base Base point * @v scalar Scalar multiple * @v result Point to hold result (may overlap base point) - * @ret rc Return status code */ -int x25519_key ( const struct x25519_value *base, - const struct x25519_value *scalar, - struct x25519_value *result ) { +void x25519_key ( const struct x25519_value *base, + const struct x25519_value *scalar, + struct x25519_value *result ) { struct x25519_value *tmp = result; union x25519_quad257 point; @@ -813,15 +828,24 @@ int x25519_key ( const struct x25519_value *base, /* Reverse result */ bigint_done ( &point.value, result->raw, sizeof ( result->raw ) ); x25519_reverse ( result ); +} + +/** + * Check if this is the point at infinity + * + * @v point Curve point + * @ret is_infinity This is the point at infinity + */ +static int x25519_curve_is_infinity ( const void *point ) { - /* Fail if result was all zeros (as required by RFC8422) */ - return ( bigint_is_zero ( &point.value ) ? -EPERM : 0 ); + /* We use all zeroes for the point at infinity (as per RFC8422) */ + return x25519_is_zero ( point ); } /** * Multiply scalar by curve point * - * @v base Base point (or NULL to use generator) + * @v base Base point * @v scalar Scalar multiple * @v result Result point to fill in * @ret rc Return status code @@ -829,16 +853,32 @@ int x25519_key ( const struct x25519_value *base, static int x25519_curve_multiply ( const void *base, const void *scalar, void *result ) { - /* Use base point if applicable */ - if ( ! base ) - base = &x25519_generator; + x25519_key ( base, scalar, result ); + return 0; +} + +/** + * Add curve points (as a one-off operation) + * + * @v addend Curve point to add + * @v augend Curve point to add + * @v result Curve point to hold result + * @ret rc Return status code + */ +static int x25519_curve_add ( const void *addend __unused, + const void *augend __unused, + void *result __unused ) { - return x25519_key ( base, scalar, result ); + return -ENOTTY; } /** X25519 elliptic curve */ struct elliptic_curve x25519_curve = { .name = "x25519", + .pointsize = sizeof ( struct x25519_value ), .keysize = sizeof ( struct x25519_value ), + .base = x25519_generator.raw, + .is_infinity = x25519_curve_is_infinity, .multiply = x25519_curve_multiply, + .add = x25519_curve_add, }; |
