diff options
Diffstat (limited to 'src/tests')
35 files changed, 4809 insertions, 917 deletions
diff --git a/src/tests/acpi_test.c b/src/tests/acpi_test.c index 1ca5befaf..6e8840217 100644 --- a/src/tests/acpi_test.c +++ b/src/tests/acpi_test.c @@ -32,6 +32,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); /* Forcibly enable assertions */ #undef NDEBUG +#include <string.h> #include <ipxe/acpi.h> #include <ipxe/acpimac.h> #include <ipxe/if_ether.h> @@ -185,26 +186,27 @@ static struct acpi_test_tables *acpi_test_tables; * * @v signature Requested table signature * @v index Requested index of table with this signature - * @ret table Table, or UNULL if not found + * @ret table Table, or NULL if not found */ -static userptr_t acpi_test_find ( uint32_t signature, unsigned int index ) { +static const struct acpi_header * acpi_test_find ( uint32_t signature, + unsigned int index ) { struct acpi_test_table *table; unsigned int i; /* Fail if no test tables are installed */ if ( ! acpi_test_tables ) - return UNULL; + return NULL; /* Scan through test tables */ for ( i = 0 ; i < acpi_test_tables->count ; i++ ) { table = acpi_test_tables->table[i]; if ( ( signature == le32_to_cpu ( table->signature.raw ) ) && ( index-- == 0 ) ) { - return virt_to_user ( table->data ); + return table->data; } } - return UNULL; + return NULL; } /** Override ACPI table finder */ diff --git a/src/tests/asn1_test.c b/src/tests/asn1_test.c index df3f01b63..4760b97fb 100644 --- a/src/tests/asn1_test.c +++ b/src/tests/asn1_test.c @@ -33,6 +33,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); #undef NDEBUG #include <stdlib.h> +#include <string.h> #include <assert.h> #include <ipxe/image.h> #include <ipxe/asn1.h> @@ -58,9 +59,6 @@ void asn1_okx ( struct asn1_test *test, const char *file, unsigned int line ) { /* Sanity check */ assert ( sizeof ( out ) == digest->digestsize ); - /* Correct image data pointer */ - test->image->data = virt_to_user ( ( void * ) test->image->data ); - /* Check that image is detected as correct type */ okx ( register_image ( test->image ) == 0, file, line ); okx ( test->image->type == test->type, file, line ); diff --git a/src/tests/asn1_test.h b/src/tests/asn1_test.h index c8167ed36..f8310f5ba 100644 --- a/src/tests/asn1_test.h +++ b/src/tests/asn1_test.h @@ -46,7 +46,8 @@ struct asn1_test { static struct image _name ## __image = { \ .refcnt = REF_INIT ( ref_no_free ), \ .name = #_name, \ - .data = ( userptr_t ) ( _name ## __file ), \ + .flags = ( IMAGE_STATIC | IMAGE_STATIC_NAME ), \ + .data = _name ## __file, \ .len = sizeof ( _name ## __file ), \ }; \ static struct asn1_test_digest _name ## _expected[] = { \ diff --git a/src/tests/bigint_test.c b/src/tests/bigint_test.c index 76aca1059..b3ad02ea2 100644 --- a/src/tests/bigint_test.c +++ b/src/tests/bigint_test.c @@ -40,6 +40,14 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); /** Define inline big integer */ #define BIGINT(...) { __VA_ARGS__ } +/** A big integer test value */ +struct bigint_test { + /** Raw value */ + const uint8_t *raw; + /** Length of raw value */ + size_t len; +}; + /* Provide global functions to allow inspection of generated assembly code */ void bigint_init_sample ( bigint_element_t *value0, unsigned int size, @@ -58,38 +66,38 @@ void bigint_done_sample ( const bigint_element_t *value0, unsigned int size, bigint_done ( value, out, len ); } -void bigint_add_sample ( const bigint_element_t *addend0, - bigint_element_t *value0, unsigned int size ) { +int bigint_add_sample ( const bigint_element_t *addend0, + bigint_element_t *value0, unsigned int size ) { const bigint_t ( size ) *addend __attribute__ (( may_alias )) = ( ( const void * ) addend0 ); bigint_t ( size ) *value __attribute__ (( may_alias )) = ( ( void * ) value0 ); - bigint_add ( addend, value ); + return bigint_add ( addend, value ); } -void bigint_subtract_sample ( const bigint_element_t *subtrahend0, - bigint_element_t *value0, unsigned int size ) { +int bigint_subtract_sample ( const bigint_element_t *subtrahend0, + bigint_element_t *value0, unsigned int size ) { const bigint_t ( size ) *subtrahend __attribute__ (( may_alias )) = ( ( const void * ) subtrahend0 ); bigint_t ( size ) *value __attribute__ (( may_alias )) = ( ( void * ) value0 ); - bigint_subtract ( subtrahend, value ); + return bigint_subtract ( subtrahend, value ); } -void bigint_rol_sample ( bigint_element_t *value0, unsigned int size ) { +int bigint_shl_sample ( bigint_element_t *value0, unsigned int size ) { bigint_t ( size ) *value __attribute__ (( may_alias )) = ( ( void * ) value0 ); - bigint_rol ( value ); + return bigint_shl ( value ); } -void bigint_ror_sample ( bigint_element_t *value0, unsigned int size ) { +int bigint_shr_sample ( bigint_element_t *value0, unsigned int size ) { bigint_t ( size ) *value __attribute__ (( may_alias )) = ( ( void * ) value0 ); - bigint_ror ( value ); + return bigint_shr ( value ); } int bigint_is_zero_sample ( const bigint_element_t *value0, @@ -185,22 +193,39 @@ void bigint_multiply_sample ( const bigint_element_t *multiplicand0, bigint_multiply ( multiplicand, multiplier, result ); } -void bigint_mod_multiply_sample ( const bigint_element_t *multiplicand0, - const bigint_element_t *multiplier0, - const bigint_element_t *modulus0, - bigint_element_t *result0, - unsigned int size, - void *tmp ) { - const bigint_t ( size ) *multiplicand __attribute__ (( may_alias )) - = ( ( const void * ) multiplicand0 ); - const bigint_t ( size ) *multiplier __attribute__ (( may_alias )) - = ( ( const void * ) multiplier0 ); - const bigint_t ( size ) *modulus __attribute__ (( may_alias )) - = ( ( const void * ) modulus0 ); - bigint_t ( size ) *result __attribute__ (( may_alias )) - = ( ( void * ) result0 ); +void bigint_reduce_sample ( const bigint_element_t *modulus0, + bigint_element_t *result0, unsigned int size ) { + const bigint_t ( size ) __attribute__ (( may_alias )) + *modulus = ( ( const void * ) modulus0 ); + bigint_t ( size ) __attribute__ (( may_alias )) + *result = ( ( void * ) result0 ); + + bigint_reduce ( modulus, result ); +} + +void bigint_mod_invert_sample ( const bigint_element_t *invertend0, + bigint_element_t *inverse0, + unsigned int size ) { + const bigint_t ( size ) __attribute__ (( may_alias )) + *invertend = ( ( const void * ) invertend0 ); + bigint_t ( size ) __attribute__ (( may_alias )) + *inverse = ( ( void * ) inverse0 ); + + bigint_mod_invert ( invertend, inverse ); +} + +void bigint_montgomery_sample ( const bigint_element_t *modulus0, + bigint_element_t *value0, + bigint_element_t *result0, + unsigned int size ) { + const bigint_t ( size ) __attribute__ (( may_alias )) + *modulus = ( ( const void * ) modulus0 ); + bigint_t ( 2 * size ) __attribute__ (( may_alias )) + *value = ( ( void * ) value0 ); + bigint_t ( size ) __attribute__ (( may_alias )) + *result = ( ( void * ) result0 ); - bigint_mod_multiply ( multiplicand, multiplier, modulus, result, tmp ); + bigint_montgomery ( modulus, value, result ); } void bigint_mod_exp_sample ( const bigint_element_t *base0, @@ -227,33 +252,50 @@ void bigint_mod_exp_sample ( const bigint_element_t *base0, * @v addend Big integer to add * @v value Big integer to be added to * @v expected Big integer expected result + * @v overflow Expected result overflows range + * @v file Test code file + * @v line Test code line */ -#define bigint_add_ok( addend, value, expected ) do { \ +static void bigint_add_okx ( struct bigint_test *addend, + struct bigint_test *value, + struct bigint_test *expected, int overflow, + const char *file, unsigned int line ) { + uint8_t result_raw[ expected->len ]; + unsigned int size = bigint_required_size ( value->len ); + unsigned int msb = ( 8 * value->len ); + bigint_t ( size ) addend_temp; + bigint_t ( size ) value_temp; + int carry; + + assert ( bigint_size ( &addend_temp ) == bigint_size ( &value_temp ) ); + bigint_init ( &value_temp, value->raw, value->len ); + bigint_init ( &addend_temp, addend->raw, addend->len ); + DBG ( "Add: 0x%s", bigint_ntoa ( &addend_temp ) ); + DBG ( " + 0x%s", bigint_ntoa ( &value_temp ) ); + carry = bigint_add ( &addend_temp, &value_temp ); + DBG ( " = 0x%s%s\n", bigint_ntoa ( &value_temp ), + ( carry ? " (carry)" : "" ) ); + bigint_done ( &value_temp, result_raw, sizeof ( result_raw ) ); + + okx ( memcmp ( result_raw, expected->raw, sizeof ( result_raw ) ) == 0, + file, line ); + if ( sizeof ( result_raw ) < sizeof ( value_temp ) ) + carry += bigint_bit_is_set ( &value_temp, msb ); + okx ( carry == overflow, file, line ); +} +#define bigint_add_ok( addend, value, expected, overflow ) do { \ static const uint8_t addend_raw[] = addend; \ static const uint8_t value_raw[] = value; \ static const uint8_t expected_raw[] = expected; \ - uint8_t result_raw[ sizeof ( expected_raw ) ]; \ - unsigned int size = \ - bigint_required_size ( sizeof ( value_raw ) ); \ - bigint_t ( size ) addend_temp; \ - bigint_t ( size ) value_temp; \ - {} /* Fix emacs alignment */ \ - \ - assert ( bigint_size ( &addend_temp ) == \ - bigint_size ( &value_temp ) ); \ - bigint_init ( &value_temp, value_raw, sizeof ( value_raw ) ); \ - bigint_init ( &addend_temp, addend_raw, \ - sizeof ( addend_raw ) ); \ - DBG ( "Add:\n" ); \ - DBG_HDA ( 0, &addend_temp, sizeof ( addend_temp ) ); \ - DBG_HDA ( 0, &value_temp, sizeof ( value_temp ) ); \ - bigint_add ( &addend_temp, &value_temp ); \ - DBG_HDA ( 0, &value_temp, sizeof ( value_temp ) ); \ - bigint_done ( &value_temp, result_raw, sizeof ( result_raw ) ); \ - \ - ok ( memcmp ( result_raw, expected_raw, \ - sizeof ( result_raw ) ) == 0 ); \ - } while ( 0 ) + static struct bigint_test addend_test = \ + { addend_raw, sizeof ( addend_raw ) }; \ + static struct bigint_test value_test = \ + { value_raw, sizeof ( value_raw ) }; \ + static struct bigint_test expected_test = \ + { expected_raw, sizeof ( expected_raw ) }; \ + bigint_add_okx ( &addend_test, &value_test, &expected_test, \ + overflow, __FILE__, __LINE__ ); \ +} while ( 0 ) /** * Report result of big integer subtraction test @@ -261,84 +303,128 @@ void bigint_mod_exp_sample ( const bigint_element_t *base0, * @v subtrahend Big integer to subtract * @v value Big integer to be subtracted from * @v expected Big integer expected result + * @v underflow Expected result underflows range + * @v file Test code file + * @v line Test code line */ -#define bigint_subtract_ok( subtrahend, value, expected ) do { \ +static void bigint_subtract_okx ( struct bigint_test *subtrahend, + struct bigint_test *value, + struct bigint_test *expected, int underflow, + const char *file, unsigned int line ) { + uint8_t result_raw[ expected->len ]; + unsigned int size = bigint_required_size ( value->len ); + bigint_t ( size ) subtrahend_temp; + bigint_t ( size ) value_temp; + int borrow; + + assert ( bigint_size ( &subtrahend_temp ) == + bigint_size ( &value_temp ) ); + bigint_init ( &value_temp, value->raw, value->len ); + bigint_init ( &subtrahend_temp, subtrahend->raw, subtrahend->len ); + DBG ( "Subtract: 0x%s", bigint_ntoa ( &value_temp ) ); + DBG ( " - 0x%s", bigint_ntoa ( &subtrahend_temp ) ); + borrow = bigint_subtract ( &subtrahend_temp, &value_temp ); + DBG ( " = 0x%s%s\n", bigint_ntoa ( &value_temp ), + ( borrow ? " (borrow)" : "" ) ); + bigint_done ( &value_temp, result_raw, sizeof ( result_raw ) ); + + okx ( memcmp ( result_raw, expected->raw, sizeof ( result_raw ) ) == 0, + file, line ); + okx ( borrow == underflow, file, line ); +} +#define bigint_subtract_ok( subtrahend, value, expected, \ + underflow ) do { \ static const uint8_t subtrahend_raw[] = subtrahend; \ static const uint8_t value_raw[] = value; \ static const uint8_t expected_raw[] = expected; \ - uint8_t result_raw[ sizeof ( expected_raw ) ]; \ - unsigned int size = \ - bigint_required_size ( sizeof ( value_raw ) ); \ - bigint_t ( size ) subtrahend_temp; \ - bigint_t ( size ) value_temp; \ - {} /* Fix emacs alignment */ \ - \ - assert ( bigint_size ( &subtrahend_temp ) == \ - bigint_size ( &value_temp ) ); \ - bigint_init ( &value_temp, value_raw, sizeof ( value_raw ) ); \ - bigint_init ( &subtrahend_temp, subtrahend_raw, \ - sizeof ( subtrahend_raw ) ); \ - DBG ( "Subtract:\n" ); \ - DBG_HDA ( 0, &subtrahend_temp, sizeof ( subtrahend_temp ) ); \ - DBG_HDA ( 0, &value_temp, sizeof ( value_temp ) ); \ - bigint_subtract ( &subtrahend_temp, &value_temp ); \ - DBG_HDA ( 0, &value_temp, sizeof ( value_temp ) ); \ - bigint_done ( &value_temp, result_raw, sizeof ( result_raw ) ); \ - \ - ok ( memcmp ( result_raw, expected_raw, \ - sizeof ( result_raw ) ) == 0 ); \ + static struct bigint_test subtrahend_test = \ + { subtrahend_raw, sizeof ( subtrahend_raw ) }; \ + static struct bigint_test value_test = \ + { value_raw, sizeof ( value_raw ) }; \ + static struct bigint_test expected_test = \ + { expected_raw, sizeof ( expected_raw ) }; \ + bigint_subtract_okx ( &subtrahend_test, &value_test, \ + &expected_test, underflow, \ + __FILE__, __LINE__ ); \ } while ( 0 ) /** - * Report result of big integer left rotation test + * Report result of big integer left shift test * * @v value Big integer * @v expected Big integer expected result + * @v bit Expected bit shifted out + * @v file Test code file + * @v line Test code line */ -#define bigint_rol_ok( value, expected ) do { \ +static void bigint_shl_okx ( struct bigint_test *value, + struct bigint_test *expected, int bit, + const char *file, unsigned int line ) { + uint8_t result_raw[ expected->len ]; + unsigned int size = bigint_required_size ( value->len ); + unsigned int msb = ( 8 * value->len ); + bigint_t ( size ) value_temp; + int out; + + bigint_init ( &value_temp, value->raw, value->len ); + DBG ( "Shift left 0x%s << 1", bigint_ntoa ( &value_temp ) ); + out = bigint_shl ( &value_temp ); + DBG ( " = 0x%s (%d)\n", bigint_ntoa ( &value_temp ), out ); + bigint_done ( &value_temp, result_raw, sizeof ( result_raw ) ); + + okx ( memcmp ( result_raw, expected->raw, sizeof ( result_raw ) ) == 0, + file, line ); + if ( sizeof ( result_raw ) < sizeof ( value_temp ) ) + out += bigint_bit_is_set ( &value_temp, msb ); + okx ( out == bit, file, line ); +} +#define bigint_shl_ok( value, expected, bit ) do { \ static const uint8_t value_raw[] = value; \ static const uint8_t expected_raw[] = expected; \ - uint8_t result_raw[ sizeof ( expected_raw ) ]; \ - unsigned int size = \ - bigint_required_size ( sizeof ( value_raw ) ); \ - bigint_t ( size ) value_temp; \ - {} /* Fix emacs alignment */ \ - \ - bigint_init ( &value_temp, value_raw, sizeof ( value_raw ) ); \ - DBG ( "Rotate left:\n" ); \ - DBG_HDA ( 0, &value_temp, sizeof ( value_temp ) ); \ - bigint_rol ( &value_temp ); \ - DBG_HDA ( 0, &value_temp, sizeof ( value_temp ) ); \ - bigint_done ( &value_temp, result_raw, sizeof ( result_raw ) ); \ - \ - ok ( memcmp ( result_raw, expected_raw, \ - sizeof ( result_raw ) ) == 0 ); \ + static struct bigint_test value_test = \ + { value_raw, sizeof ( value_raw ) }; \ + static struct bigint_test expected_test = \ + { expected_raw, sizeof ( expected_raw ) }; \ + bigint_shl_okx ( &value_test, &expected_test, bit, \ + __FILE__, __LINE__ ); \ } while ( 0 ) /** - * Report result of big integer right rotation test + * Report result of big integer right shift test * * @v value Big integer * @v expected Big integer expected result + * @v bit Expected bit shifted out + * @v file Test code file + * @v line Test code line */ -#define bigint_ror_ok( value, expected ) do { \ +static void bigint_shr_okx ( struct bigint_test *value, + struct bigint_test *expected, int bit, + const char *file, unsigned int line ) { + uint8_t result_raw[ expected->len ]; + unsigned int size = bigint_required_size ( value->len ); + bigint_t ( size ) value_temp; + int out; + + bigint_init ( &value_temp, value->raw, value->len ); + DBG ( "Shift right 0x%s >> 1", bigint_ntoa ( &value_temp ) ); + out = bigint_shr ( &value_temp ); + DBG ( " = 0x%s (%d)\n", bigint_ntoa ( &value_temp ), out ); + bigint_done ( &value_temp, result_raw, sizeof ( result_raw ) ); + + okx ( memcmp ( result_raw, expected->raw, sizeof ( result_raw ) ) == 0, + file, line ); + okx ( out == bit, file, line ); +} +#define bigint_shr_ok( value, expected, bit ) do { \ static const uint8_t value_raw[] = value; \ static const uint8_t expected_raw[] = expected; \ - uint8_t result_raw[ sizeof ( expected_raw ) ]; \ - unsigned int size = \ - bigint_required_size ( sizeof ( value_raw ) ); \ - bigint_t ( size ) value_temp; \ - {} /* Fix emacs alignment */ \ - \ - bigint_init ( &value_temp, value_raw, sizeof ( value_raw ) ); \ - DBG ( "Rotate right:\n" ); \ - DBG_HDA ( 0, &value_temp, sizeof ( value_temp ) ); \ - bigint_ror ( &value_temp ); \ - DBG_HDA ( 0, &value_temp, sizeof ( value_temp ) ); \ - bigint_done ( &value_temp, result_raw, sizeof ( result_raw ) ); \ - \ - ok ( memcmp ( result_raw, expected_raw, \ - sizeof ( result_raw ) ) == 0 ); \ + static struct bigint_test value_test = \ + { value_raw, sizeof ( value_raw ) }; \ + static struct bigint_test expected_test = \ + { expected_raw, sizeof ( expected_raw ) }; \ + bigint_shr_okx ( &value_test, &expected_test, bit, \ + __FILE__, __LINE__ ); \ } while ( 0 ) /** @@ -346,21 +432,27 @@ void bigint_mod_exp_sample ( const bigint_element_t *base0, * * @v value Big integer * @v expected Expected result + * @v file Test code file + * @v line Test code line */ +static void bigint_is_zero_okx ( struct bigint_test *value, int expected, + const char *file, unsigned int line ) { + unsigned int size = bigint_required_size ( value->len ); + bigint_t ( size ) value_temp; + int is_zero; + + bigint_init ( &value_temp, value->raw, value->len ); + DBG ( "Zero comparison: 0x%s", bigint_ntoa ( &value_temp ) ); + is_zero = bigint_is_zero ( &value_temp ); + DBG ( " %s 0\n", ( is_zero ? "==" : "!=" ) ); + okx ( ( !! is_zero ) == ( !! (expected) ), file, line ); +} #define bigint_is_zero_ok( value, expected ) do { \ static const uint8_t value_raw[] = value; \ - unsigned int size = \ - bigint_required_size ( sizeof ( value_raw ) ); \ - bigint_t ( size ) value_temp; \ - int is_zero; \ - {} /* Fix emacs alignment */ \ - \ - bigint_init ( &value_temp, value_raw, sizeof ( value_raw ) ); \ - DBG ( "Zero comparison:\n" ); \ - DBG_HDA ( 0, &value_temp, sizeof ( value_temp ) ); \ - is_zero = bigint_is_zero ( &value_temp ); \ - DBG ( "...is %szero\n", ( is_zero ? "" : "not " ) ); \ - ok ( ( !! is_zero ) == ( !! (expected) ) ); \ + static struct bigint_test value_test = \ + { value_raw, sizeof ( value_raw ) }; \ + bigint_is_zero_okx ( &value_test, expected, \ + __FILE__, __LINE__ ); \ } while ( 0 ) /** @@ -369,29 +461,37 @@ void bigint_mod_exp_sample ( const bigint_element_t *base0, * @v value Big integer * @v reference Reference big integer * @v expected Expected result + * @v file Test code file + * @v line Test code line */ +static void bigint_is_geq_okx ( struct bigint_test *value, + struct bigint_test *reference, int expected, + const char *file, unsigned int line ) { + unsigned int size = bigint_required_size ( value->len ); + bigint_t ( size ) value_temp; + bigint_t ( size ) reference_temp; + int is_geq; + + assert ( bigint_size ( &reference_temp ) == + bigint_size ( &value_temp ) ); + bigint_init ( &value_temp, value->raw, value->len ); + bigint_init ( &reference_temp, reference->raw, reference->len ); + DBG ( "Greater-than-or-equal comparison: 0x%s", + bigint_ntoa ( &value_temp ) ); + is_geq = bigint_is_geq ( &value_temp, &reference_temp ); + DBG ( " %s 0x%s\n", ( is_geq ? ">=" : "<" ), + bigint_ntoa ( &reference_temp ) ); + okx ( ( !! is_geq ) == ( !! (expected) ), file, line ); +} #define bigint_is_geq_ok( value, reference, expected ) do { \ static const uint8_t value_raw[] = value; \ static const uint8_t reference_raw[] = reference; \ - unsigned int size = \ - bigint_required_size ( sizeof ( value_raw ) ); \ - bigint_t ( size ) value_temp; \ - bigint_t ( size ) reference_temp; \ - int is_geq; \ - {} /* Fix emacs alignment */ \ - \ - assert ( bigint_size ( &reference_temp ) == \ - bigint_size ( &value_temp ) ); \ - bigint_init ( &value_temp, value_raw, sizeof ( value_raw ) ); \ - bigint_init ( &reference_temp, reference_raw, \ - sizeof ( reference_raw ) ); \ - DBG ( "Greater-than-or-equal comparison:\n" ); \ - DBG_HDA ( 0, &value_temp, sizeof ( value_temp ) ); \ - DBG_HDA ( 0, &reference_temp, sizeof ( reference_temp ) ); \ - is_geq = bigint_is_geq ( &value_temp, &reference_temp ); \ - DBG ( "...is %sgreater than or equal\n", \ - ( is_geq ? "" : "not " ) ); \ - ok ( ( !! is_geq ) == ( !! (expected) ) ); \ + static struct bigint_test value_test = \ + { value_raw, sizeof ( value_raw ) }; \ + static struct bigint_test reference_test = \ + { reference_raw, sizeof ( reference_raw ) }; \ + bigint_is_geq_okx ( &value_test, &reference_test, expected, \ + __FILE__, __LINE__ ); \ } while ( 0 ) /** @@ -400,22 +500,28 @@ void bigint_mod_exp_sample ( const bigint_element_t *base0, * @v value Big integer * @v bit Bit to test * @v expected Expected result + * @v file Test code file + * @v line Test code line */ +static void bigint_bit_is_set_okx ( struct bigint_test *value, + unsigned int bit, int expected, + const char *file, unsigned int line ) { + unsigned int size = bigint_required_size ( value->len ); + bigint_t ( size ) value_temp; + int bit_is_set; + + bigint_init ( &value_temp, value->raw, value->len ); + DBG ( "Bit set: 0x%s bit %d", bigint_ntoa ( &value_temp ), bit ); + bit_is_set = bigint_bit_is_set ( &value_temp, bit ); + DBG ( " is %sset\n", ( bit_is_set ? "" : "not " ) ); + okx ( ( !! bit_is_set ) == ( !! (expected) ), file, line ); +} #define bigint_bit_is_set_ok( value, bit, expected ) do { \ static const uint8_t value_raw[] = value; \ - unsigned int size = \ - bigint_required_size ( sizeof ( value_raw ) ); \ - bigint_t ( size ) value_temp; \ - int bit_is_set; \ - {} /* Fix emacs alignment */ \ - \ - bigint_init ( &value_temp, value_raw, sizeof ( value_raw ) ); \ - DBG ( "Bit set:\n" ); \ - DBG_HDA ( 0, &value_temp, sizeof ( value_temp ) ); \ - bit_is_set = bigint_bit_is_set ( &value_temp, bit ); \ - DBG ( "...bit %d is %sset\n", bit, \ - ( bit_is_set ? "" : "not " ) ); \ - ok ( ( !! bit_is_set ) == ( !! (expected) ) ); \ + static struct bigint_test value_test = \ + { value_raw, sizeof ( value_raw ) }; \ + bigint_bit_is_set_okx ( &value_test, bit, expected, \ + __FILE__, __LINE__ ); \ } while ( 0 ) /** @@ -423,21 +529,27 @@ void bigint_mod_exp_sample ( const bigint_element_t *base0, * * @v value Big integer * @v expected Expected result + * @v file Test code file + * @v line Test code line */ +static void bigint_max_set_bit_okx ( struct bigint_test *value, int expected, + const char *file, unsigned int line ) { + unsigned int size = bigint_required_size ( value->len ); + bigint_t ( size ) value_temp; + int max_set_bit; + + bigint_init ( &value_temp, value->raw, value->len ); + DBG ( "Maximum set bit: 0x%s", bigint_ntoa ( &value_temp ) ); + max_set_bit = bigint_max_set_bit ( &value_temp ); + DBG ( " MSB is bit %d\n", ( max_set_bit - 1 ) ); + okx ( max_set_bit == expected, file, line ); +} #define bigint_max_set_bit_ok( value, expected ) do { \ static const uint8_t value_raw[] = value; \ - unsigned int size = \ - bigint_required_size ( sizeof ( value_raw ) ); \ - bigint_t ( size ) value_temp; \ - int max_set_bit; \ - {} /* Fix emacs alignment */ \ - \ - bigint_init ( &value_temp, value_raw, sizeof ( value_raw ) ); \ - DBG ( "Maximum set bit:\n" ); \ - DBG_HDA ( 0, &value_temp, sizeof ( value_temp ) ); \ - max_set_bit = bigint_max_set_bit ( &value_temp ); \ - DBG ( "...maximum set bit is bit %d\n", ( max_set_bit - 1 ) ); \ - ok ( max_set_bit == (expected) ); \ + static struct bigint_test value_test = \ + { value_raw, sizeof ( value_raw ) }; \ + bigint_max_set_bit_okx ( &value_test, expected, \ + __FILE__, __LINE__ ); \ } while ( 0 ) /** @@ -445,35 +557,46 @@ void bigint_mod_exp_sample ( const bigint_element_t *base0, * * @v first Big integer to be conditionally swapped * @v second Big integer to be conditionally swapped + * @v file Test code file + * @v line Test code line */ +static void bigint_swap_okx ( struct bigint_test *first, + struct bigint_test *second, + const char *file, unsigned int line ) { + uint8_t temp[ first->len ]; + unsigned int size = bigint_required_size ( sizeof ( temp) ); + bigint_t ( size ) first_temp; + bigint_t ( size ) second_temp; + + assert ( first->len == sizeof ( temp ) ); + assert ( second->len == sizeof ( temp ) ); + bigint_init ( &first_temp, first->raw, first->len ); + bigint_init ( &second_temp, second->raw, second->len ); + bigint_swap ( &first_temp, &second_temp, 0 ); + bigint_done ( &first_temp, temp, sizeof ( temp ) ); + okx ( memcmp ( temp, first->raw, sizeof ( temp ) ) == 0, file, line ); + bigint_done ( &second_temp, temp, sizeof ( temp ) ); + okx ( memcmp ( temp, second->raw, sizeof ( temp ) ) == 0, file, line ); + bigint_swap ( &first_temp, &second_temp, 1 ); + bigint_done ( &first_temp, temp, sizeof ( temp ) ); + okx ( memcmp ( temp, second->raw, sizeof ( temp ) ) == 0, file, line ); + bigint_done ( &second_temp, temp, sizeof ( temp ) ); + okx ( memcmp ( temp, first->raw, sizeof ( temp ) ) == 0, file, line ); + bigint_swap ( &first_temp, &second_temp, 1 ); + bigint_done ( &first_temp, temp, sizeof ( temp ) ); + okx ( memcmp ( temp, first->raw, sizeof ( temp ) ) == 0, file, line ); + bigint_done ( &second_temp, temp, sizeof ( temp ) ); + okx ( memcmp ( temp, second->raw, sizeof ( temp ) ) == 0, file, line ); +} #define bigint_swap_ok( first, second ) do { \ static const uint8_t first_raw[] = first; \ static const uint8_t second_raw[] = second; \ - uint8_t temp[ sizeof ( first_raw ) ]; \ - unsigned int size = bigint_required_size ( sizeof ( temp) ); \ - bigint_t ( size ) first_temp; \ - bigint_t ( size ) second_temp; \ - {} /* Fix emacs alignment */ \ - \ - assert ( sizeof ( first_raw ) == sizeof ( temp ) ); \ - assert ( sizeof ( second_raw ) == sizeof ( temp ) ); \ - bigint_init ( &first_temp, first_raw, sizeof ( first_raw ) ); \ - bigint_init ( &second_temp, second_raw, sizeof ( second_raw ) );\ - bigint_swap ( &first_temp, &second_temp, 0 ); \ - bigint_done ( &first_temp, temp, sizeof ( temp ) ); \ - ok ( memcmp ( temp, first_raw, sizeof ( temp ) ) == 0 ); \ - bigint_done ( &second_temp, temp, sizeof ( temp ) ); \ - ok ( memcmp ( temp, second_raw, sizeof ( temp ) ) == 0 ); \ - bigint_swap ( &first_temp, &second_temp, 1 ); \ - bigint_done ( &first_temp, temp, sizeof ( temp ) ); \ - ok ( memcmp ( temp, second_raw, sizeof ( temp ) ) == 0 ); \ - bigint_done ( &second_temp, temp, sizeof ( temp ) ); \ - ok ( memcmp ( temp, first_raw, sizeof ( temp ) ) == 0 ); \ - bigint_swap ( &first_temp, &second_temp, 1 ); \ - bigint_done ( &first_temp, temp, sizeof ( temp ) ); \ - ok ( memcmp ( temp, first_raw, sizeof ( temp ) ) == 0 ); \ - bigint_done ( &second_temp, temp, sizeof ( temp ) ); \ - ok ( memcmp ( temp, second_raw, sizeof ( temp ) ) == 0 ); \ + static struct bigint_test first_test = \ + { first_raw, sizeof ( first_raw ) }; \ + static struct bigint_test second_test = \ + { second_raw, sizeof ( second_raw ) }; \ + bigint_swap_okx ( &first_test, &second_test, \ + __FILE__, __LINE__ ); \ } while ( 0 ) /** @@ -482,88 +605,175 @@ void bigint_mod_exp_sample ( const bigint_element_t *base0, * @v multiplicand Big integer to be multiplied * @v multiplier Big integer to be multiplied * @v expected Big integer expected result + * @v file Test code file + * @v line Test code line */ +static void bigint_multiply_okx ( struct bigint_test *multiplicand, + struct bigint_test *multiplier, + struct bigint_test *expected, + const char *file, unsigned int line ) { + uint8_t result_raw[ expected->len ]; + unsigned int multiplicand_size = + bigint_required_size ( multiplicand->len ); + unsigned int multiplier_size = + bigint_required_size ( multiplier->len ); + bigint_t ( multiplicand_size ) multiplicand_temp; + bigint_t ( multiplier_size ) multiplier_temp; + bigint_t ( multiplicand_size + multiplier_size ) result_temp; + + assert ( bigint_size ( &result_temp ) == + ( bigint_size ( &multiplicand_temp ) + + bigint_size ( &multiplier_temp ) ) ); + bigint_init ( &multiplicand_temp, multiplicand->raw, + multiplicand->len ); + bigint_init ( &multiplier_temp, multiplier->raw, multiplier->len ); + DBG ( "Multiply 0x%s", bigint_ntoa ( &multiplicand_temp ) ); + DBG ( " * 0x%s", bigint_ntoa ( &multiplier_temp ) ); + bigint_multiply ( &multiplicand_temp, &multiplier_temp, &result_temp ); + DBG ( " = 0x%s\n", bigint_ntoa ( &result_temp ) ); + bigint_done ( &result_temp, result_raw, sizeof ( result_raw ) ); + + okx ( memcmp ( result_raw, expected->raw, sizeof ( result_raw ) ) == 0, + file, line ); +} #define bigint_multiply_ok( multiplicand, multiplier, expected ) do { \ static const uint8_t multiplicand_raw[] = multiplicand; \ static const uint8_t multiplier_raw[] = multiplier; \ static const uint8_t expected_raw[] = expected; \ - uint8_t result_raw[ sizeof ( expected_raw ) ]; \ - unsigned int multiplicand_size = \ - bigint_required_size ( sizeof ( multiplicand_raw ) ); \ - unsigned int multiplier_size = \ - bigint_required_size ( sizeof ( multiplier_raw ) ); \ - bigint_t ( multiplicand_size ) multiplicand_temp; \ - bigint_t ( multiplier_size ) multiplier_temp; \ - bigint_t ( multiplicand_size + multiplier_size ) result_temp; \ - {} /* Fix emacs alignment */ \ - \ - assert ( bigint_size ( &result_temp ) == \ - ( bigint_size ( &multiplicand_temp ) + \ - bigint_size ( &multiplier_temp ) ) ); \ - bigint_init ( &multiplicand_temp, multiplicand_raw, \ - sizeof ( multiplicand_raw ) ); \ - bigint_init ( &multiplier_temp, multiplier_raw, \ - sizeof ( multiplier_raw ) ); \ - DBG ( "Multiply:\n" ); \ - DBG_HDA ( 0, &multiplicand_temp, sizeof ( multiplicand_temp ) );\ - DBG_HDA ( 0, &multiplier_temp, sizeof ( multiplier_temp ) ); \ - bigint_multiply ( &multiplicand_temp, &multiplier_temp, \ - &result_temp ); \ - DBG_HDA ( 0, &result_temp, sizeof ( result_temp ) ); \ - bigint_done ( &result_temp, result_raw, sizeof ( result_raw ) );\ - \ - ok ( memcmp ( result_raw, expected_raw, \ - sizeof ( result_raw ) ) == 0 ); \ + static struct bigint_test multiplicand_test = \ + { multiplicand_raw, sizeof ( multiplicand_raw ) }; \ + static struct bigint_test multiplier_test = \ + { multiplier_raw, sizeof ( multiplier_raw ) }; \ + static struct bigint_test expected_test = \ + { expected_raw, sizeof ( expected_raw ) }; \ + bigint_multiply_okx ( &multiplicand_test, &multiplier_test, \ + &expected_test, __FILE__, __LINE__ ); \ } while ( 0 ) /** - * Report result of big integer modular multiplication test + * Report result of big integer modular direct reduction of R^2 test * - * @v multiplicand Big integer to be multiplied - * @v multiplier Big integer to be multiplied * @v modulus Big integer modulus * @v expected Big integer expected result + * @v file Test code file + * @v line Test code line */ -#define bigint_mod_multiply_ok( multiplicand, multiplier, modulus, \ - expected ) do { \ - static const uint8_t multiplicand_raw[] = multiplicand; \ - static const uint8_t multiplier_raw[] = multiplier; \ +static void bigint_reduce_okx ( struct bigint_test *modulus, + struct bigint_test *expected, + const char *file, unsigned int line ) { + uint8_t result_raw[ expected->len ]; + unsigned int size = bigint_required_size ( modulus->len ); + bigint_t ( size ) modulus_temp; + bigint_t ( size ) result_temp; + + assert ( bigint_size ( &modulus_temp ) == + bigint_size ( &result_temp ) ); + assert ( sizeof ( result_temp ) == sizeof ( result_raw ) ); + bigint_init ( &modulus_temp, modulus->raw, modulus->len ); + DBG ( "Modular reduce (2^%zd)", ( 2 * 8 * sizeof ( modulus_temp ) ) ); + bigint_reduce ( &modulus_temp, &result_temp ); + DBG ( " = 0x%s", bigint_ntoa ( &result_temp ) ); + DBG ( " (mod 0x%s)\n", bigint_ntoa ( &modulus_temp ) ); + + bigint_done ( &result_temp, result_raw, sizeof ( result_raw ) ); + + okx ( memcmp ( result_raw, expected->raw, sizeof ( result_raw ) ) == 0, + file, line ); +} +#define bigint_reduce_ok( modulus, expected ) do { \ static const uint8_t modulus_raw[] = modulus; \ static const uint8_t expected_raw[] = expected; \ - uint8_t result_raw[ sizeof ( expected_raw ) ]; \ - unsigned int size = \ - bigint_required_size ( sizeof ( multiplicand_raw ) ); \ - bigint_t ( size ) multiplicand_temp; \ - bigint_t ( size ) multiplier_temp; \ - bigint_t ( size ) modulus_temp; \ - bigint_t ( size ) result_temp; \ - size_t tmp_len = bigint_mod_multiply_tmp_len ( &modulus_temp ); \ - uint8_t tmp[tmp_len]; \ - {} /* Fix emacs alignment */ \ - \ - assert ( bigint_size ( &multiplier_temp ) == \ - bigint_size ( &multiplicand_temp ) ); \ - assert ( bigint_size ( &multiplier_temp ) == \ - bigint_size ( &modulus_temp ) ); \ - assert ( bigint_size ( &multiplier_temp ) == \ - bigint_size ( &result_temp ) ); \ - bigint_init ( &multiplicand_temp, multiplicand_raw, \ - sizeof ( multiplicand_raw ) ); \ - bigint_init ( &multiplier_temp, multiplier_raw, \ - sizeof ( multiplier_raw ) ); \ - bigint_init ( &modulus_temp, modulus_raw, \ - sizeof ( modulus_raw ) ); \ - DBG ( "Modular multiply:\n" ); \ - DBG_HDA ( 0, &multiplicand_temp, sizeof ( multiplicand_temp ) );\ - DBG_HDA ( 0, &multiplier_temp, sizeof ( multiplier_temp ) ); \ - DBG_HDA ( 0, &modulus_temp, sizeof ( modulus_temp ) ); \ - bigint_mod_multiply ( &multiplicand_temp, &multiplier_temp, \ - &modulus_temp, &result_temp, tmp ); \ - DBG_HDA ( 0, &result_temp, sizeof ( result_temp ) ); \ - bigint_done ( &result_temp, result_raw, sizeof ( result_raw ) );\ - \ - ok ( memcmp ( result_raw, expected_raw, \ - sizeof ( result_raw ) ) == 0 ); \ + static struct bigint_test modulus_test = \ + { modulus_raw, sizeof ( modulus_raw ) }; \ + static struct bigint_test expected_test = \ + { expected_raw, sizeof ( expected_raw ) }; \ + bigint_reduce_okx ( &modulus_test, &expected_test, \ + __FILE__, __LINE__ ); \ + } while ( 0 ) + +/** + * Report result of big integer modular inversion test + * + * @v invertend Big integer to be inverted + * @v expected Big integer expected result + * @v file Test code file + * @v line Test code line + */ +static void bigint_mod_invert_okx ( struct bigint_test *invertend, + struct bigint_test *expected, + const char *file, unsigned int line ) { + uint8_t inverse_raw[ expected->len ]; + unsigned int invertend_size = bigint_required_size ( invertend->len ); + unsigned int inverse_size = + bigint_required_size ( sizeof ( inverse_raw ) ); + bigint_t ( invertend_size ) invertend_temp; + bigint_t ( inverse_size ) inverse_temp; + + bigint_init ( &invertend_temp, invertend->raw, invertend->len ); + DBG ( "Modular invert: 0x%s", bigint_ntoa ( &invertend_temp ) ); + bigint_mod_invert ( &invertend_temp, &inverse_temp ); + DBG ( " * 0x%s = 1 (mod 2^%zd)\n", bigint_ntoa ( &inverse_temp ), + ( 8 * sizeof ( inverse_raw ) ) ); + bigint_done ( &inverse_temp, inverse_raw, sizeof ( inverse_raw ) ); + + okx ( memcmp ( inverse_raw, expected->raw, + sizeof ( inverse_raw ) ) == 0, file, line ); +} +#define bigint_mod_invert_ok( invertend, expected ) do { \ + static const uint8_t invertend_raw[] = invertend; \ + static const uint8_t expected_raw[] = expected; \ + static struct bigint_test invertend_test = \ + { invertend_raw, sizeof ( invertend_raw ) }; \ + static struct bigint_test expected_test = \ + { expected_raw, sizeof ( expected_raw ) }; \ + bigint_mod_invert_okx ( &invertend_test, &expected_test, \ + __FILE__, __LINE__ ); \ + } while ( 0 ) + +/** + * Report result of Montgomery reduction (REDC) test + * + * @v modulus Big integer modulus + * @v mont Big integer Montgomery product + * @v expected Big integer expected result + * @v file Test code file + * @v line Test code line + */ +static void bigint_montgomery_okx ( struct bigint_test *modulus, + struct bigint_test *mont, + struct bigint_test *expected, + const char *file, unsigned int line ) { + uint8_t result_raw[ expected->len ]; + unsigned int size = bigint_required_size ( modulus->len ); + bigint_t ( size ) modulus_temp; + bigint_t ( 2 * size ) mont_temp; + bigint_t ( size ) result_temp; + + assert ( ( modulus->len % sizeof ( bigint_element_t ) ) == 0 ); + bigint_init ( &modulus_temp, modulus->raw, modulus->len ); + bigint_init ( &mont_temp, mont->raw, mont->len ); + DBG ( "Montgomery 0x%s", bigint_ntoa ( &mont_temp ) ); + bigint_montgomery ( &modulus_temp, &mont_temp, &result_temp ); + DBG ( " = 0x%s * (2 ^ %zd)", bigint_ntoa ( &result_temp ), + ( 8 * sizeof ( modulus_temp ) ) ); + DBG ( " (mod 0x%s)\n", bigint_ntoa ( &modulus_temp ) ); + bigint_done ( &result_temp, result_raw, sizeof ( result_raw ) ); + + okx ( memcmp ( result_raw, expected->raw, sizeof ( result_raw ) ) == 0, + file, line ); +} +#define bigint_montgomery_ok( modulus, mont, expected ) do { \ + static const uint8_t modulus_raw[] = modulus; \ + static const uint8_t mont_raw[] = mont; \ + static const uint8_t expected_raw[] = expected; \ + static struct bigint_test modulus_test = \ + { modulus_raw, sizeof ( modulus_raw ) }; \ + static struct bigint_test mont_test = \ + { mont_raw, sizeof ( mont_raw ) }; \ + static struct bigint_test expected_test = \ + { expected_raw, sizeof ( expected_raw ) }; \ + bigint_montgomery_okx ( &modulus_test, &mont_test, \ + &expected_test, __FILE__, __LINE__ ); \ } while ( 0 ) /** @@ -573,46 +783,56 @@ void bigint_mod_exp_sample ( const bigint_element_t *base0, * @v modulus Big integer modulus * @v exponent Big integer exponent * @v expected Big integer expected result + * @v file Test code file + * @v line Test code line */ +static void bigint_mod_exp_okx ( struct bigint_test *base, + struct bigint_test *modulus, + struct bigint_test *exponent, + struct bigint_test *expected, + const char *file, unsigned int line ) { + uint8_t result_raw[ expected->len ]; + unsigned int size = bigint_required_size ( base->len ); + unsigned int exponent_size = bigint_required_size ( exponent->len ); + bigint_t ( size ) base_temp; + bigint_t ( size ) modulus_temp; + bigint_t ( exponent_size ) exponent_temp; + bigint_t ( size ) result_temp; + size_t tmp_len = bigint_mod_exp_tmp_len ( &modulus_temp ); + uint8_t tmp[tmp_len]; + + assert ( bigint_size ( &modulus_temp ) == bigint_size ( &base_temp ) ); + assert ( bigint_size ( &modulus_temp ) == + bigint_size ( &result_temp ) ); + bigint_init ( &base_temp, base->raw, base->len ); + bigint_init ( &modulus_temp, modulus->raw, modulus->len ); + bigint_init ( &exponent_temp, exponent->raw, exponent->len ); + DBG ( "Modular exponentiation: 0x%s", bigint_ntoa ( &base_temp ) ); + DBG ( " ^ 0x%s", bigint_ntoa ( &exponent_temp ) ); + bigint_mod_exp ( &base_temp, &modulus_temp, &exponent_temp, + &result_temp, tmp ); + DBG ( " = 0x%s", bigint_ntoa ( &result_temp ) ); + DBG ( " (mod 0x%s)\n", bigint_ntoa ( &modulus_temp ) ); + bigint_done ( &result_temp, result_raw, sizeof ( result_raw ) ); + + okx ( memcmp ( result_raw, expected->raw, sizeof ( result_raw ) ) == 0, + file, line ); +} #define bigint_mod_exp_ok( base, modulus, exponent, expected ) do { \ static const uint8_t base_raw[] = base; \ static const uint8_t modulus_raw[] = modulus; \ static const uint8_t exponent_raw[] = exponent; \ static const uint8_t expected_raw[] = expected; \ - uint8_t result_raw[ sizeof ( expected_raw ) ]; \ - unsigned int size = \ - bigint_required_size ( sizeof ( base_raw ) ); \ - unsigned int exponent_size = \ - bigint_required_size ( sizeof ( exponent_raw ) ); \ - bigint_t ( size ) base_temp; \ - bigint_t ( size ) modulus_temp; \ - bigint_t ( exponent_size ) exponent_temp; \ - bigint_t ( size ) result_temp; \ - size_t tmp_len = bigint_mod_exp_tmp_len ( &modulus_temp, \ - &exponent_temp ); \ - uint8_t tmp[tmp_len]; \ - {} /* Fix emacs alignment */ \ - \ - assert ( bigint_size ( &modulus_temp ) == \ - bigint_size ( &base_temp ) ); \ - assert ( bigint_size ( &modulus_temp ) == \ - bigint_size ( &result_temp ) ); \ - bigint_init ( &base_temp, base_raw, sizeof ( base_raw ) ); \ - bigint_init ( &modulus_temp, modulus_raw, \ - sizeof ( modulus_raw ) ); \ - bigint_init ( &exponent_temp, exponent_raw, \ - sizeof ( exponent_raw ) ); \ - DBG ( "Modular exponentiation:\n" ); \ - DBG_HDA ( 0, &base_temp, sizeof ( base_temp ) ); \ - DBG_HDA ( 0, &modulus_temp, sizeof ( modulus_temp ) ); \ - DBG_HDA ( 0, &exponent_temp, sizeof ( exponent_temp ) ); \ - bigint_mod_exp ( &base_temp, &modulus_temp, &exponent_temp, \ - &result_temp, tmp ); \ - DBG_HDA ( 0, &result_temp, sizeof ( result_temp ) ); \ - bigint_done ( &result_temp, result_raw, sizeof ( result_raw ) );\ - \ - ok ( memcmp ( result_raw, expected_raw, \ - sizeof ( result_raw ) ) == 0 ); \ + static struct bigint_test base_test = \ + { base_raw, sizeof ( base_raw ) }; \ + static struct bigint_test modulus_test = \ + { modulus_raw, sizeof ( modulus_raw ) }; \ + static struct bigint_test exponent_test = \ + { exponent_raw, sizeof ( exponent_raw ) }; \ + static struct bigint_test expected_test = \ + { expected_raw, sizeof ( expected_raw ) }; \ + bigint_mod_exp_okx ( &base_test, &modulus_test, &exponent_test, \ + &expected_test, __FILE__, __LINE__ ); \ } while ( 0 ) /** @@ -621,18 +841,31 @@ void bigint_mod_exp_sample ( const bigint_element_t *base0, */ static void bigint_test_exec ( void ) { + bigint_add_ok ( BIGINT(), BIGINT(), BIGINT(), 0 ); bigint_add_ok ( BIGINT ( 0x8a ), BIGINT ( 0x43 ), - BIGINT ( 0xcd ) ); + BIGINT ( 0xcd ), 0 ); bigint_add_ok ( BIGINT ( 0xc5, 0x7b ), BIGINT ( 0xd6, 0xb1 ), - BIGINT ( 0x9c, 0x2c ) ); + BIGINT ( 0x9c, 0x2c ), 1 ); bigint_add_ok ( BIGINT ( 0xf9, 0xd9, 0xdc ), BIGINT ( 0x6d, 0x4b, 0xca ), - BIGINT ( 0x67, 0x25, 0xa6 ) ); + BIGINT ( 0x67, 0x25, 0xa6 ), 1 ); bigint_add_ok ( BIGINT ( 0xdd, 0xc2, 0x20, 0x5f ), BIGINT ( 0x80, 0x32, 0xc4, 0xb0 ), - BIGINT ( 0x5d, 0xf4, 0xe5, 0x0f ) ); + BIGINT ( 0x5d, 0xf4, 0xe5, 0x0f ), 1 ); + bigint_add_ok ( BIGINT ( 0x5e, 0x46, 0x4d, 0xc6, 0xa2, 0x7d, 0x45, + 0xc3 ), + BIGINT ( 0xd6, 0xc0, 0xd7, 0xd4, 0xf6, 0x04, 0x47, + 0xed ), + BIGINT ( 0x35, 0x07, 0x25, 0x9b, 0x98, 0x81, 0x8d, + 0xb0 ), 1 ); + bigint_add_ok ( BIGINT ( 0x0e, 0x46, 0x4d, 0xc6, 0xa2, 0x7d, 0x45, + 0xc3 ), + BIGINT ( 0xd6, 0xc0, 0xd7, 0xd4, 0xf6, 0x04, 0x47, + 0xed ), + BIGINT ( 0xe5, 0x07, 0x25, 0x9b, 0x98, 0x81, 0x8d, + 0xb0 ), 0 ); bigint_add_ok ( BIGINT ( 0x01, 0xed, 0x45, 0x4b, 0x41, 0xeb, 0x4c, 0x2e, 0x53, 0x07, 0x15, 0x51, 0x56, 0x47, 0x29, 0xfc, 0x9c, 0xbd, 0xbd, 0xfb, 0x1b, @@ -644,7 +877,7 @@ static void bigint_test_exec ( void ) { BIGINT ( 0x75, 0xdb, 0x41, 0x80, 0x73, 0x0e, 0x23, 0xe0, 0x3d, 0x98, 0x70, 0x36, 0x11, 0x03, 0xcb, 0x35, 0x0f, 0x6c, 0x09, 0x17, 0xdc, - 0xd6, 0xd0 ) ); + 0xd6, 0xd0 ), 0 ); bigint_add_ok ( BIGINT ( 0x06, 0x8e, 0xd6, 0x18, 0xbb, 0x4b, 0x0c, 0xc5, 0x85, 0xde, 0xee, 0x9b, 0x3f, 0x65, 0x63, 0x86, 0xf5, 0x5a, 0x9f, 0xa2, 0xd7, @@ -701,19 +934,20 @@ static void bigint_test_exec ( void ) { 0x68, 0x76, 0xf5, 0x20, 0xa1, 0xa8, 0x1a, 0x9f, 0x60, 0x58, 0xff, 0xb6, 0x76, 0x45, 0xe6, 0xed, 0x61, 0x8d, 0xe6, 0xc0, 0x72, - 0x1c, 0x07 ) ); + 0x1c, 0x07 ), 0 ); + bigint_subtract_ok ( BIGINT(), BIGINT(), BIGINT(), 0 ); bigint_subtract_ok ( BIGINT ( 0x83 ), BIGINT ( 0x50 ), - BIGINT ( 0xcd ) ); + BIGINT ( 0xcd ), 1 ); bigint_subtract_ok ( BIGINT ( 0x2c, 0x7c ), BIGINT ( 0x49, 0x0e ), - BIGINT ( 0x1c, 0x92 ) ); + BIGINT ( 0x1c, 0x92 ), 0 ); bigint_subtract_ok ( BIGINT ( 0x9c, 0x30, 0xbf ), BIGINT ( 0xde, 0x4e, 0x07 ), - BIGINT ( 0x42, 0x1d, 0x48 ) ); + BIGINT ( 0x42, 0x1d, 0x48 ), 0 ); bigint_subtract_ok ( BIGINT ( 0xbb, 0x77, 0x32, 0x5a ), BIGINT ( 0x5a, 0xd5, 0xfe, 0x28 ), - BIGINT ( 0x9f, 0x5e, 0xcb, 0xce ) ); + BIGINT ( 0x9f, 0x5e, 0xcb, 0xce ), 1 ); bigint_subtract_ok ( BIGINT ( 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff ), @@ -722,7 +956,7 @@ static void bigint_test_exec ( void ) { 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a ), BIGINT ( 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x2b ) ); + 0x00, 0x00, 0x00, 0x00, 0x00, 0x2b ), 1 ); bigint_subtract_ok ( BIGINT ( 0x7b, 0xaa, 0x16, 0xcf, 0x15, 0x87, 0xe0, 0x4f, 0x2c, 0xa3, 0xec, 0x2f, 0x46, 0xfb, 0x83, 0xc6, 0xe0, 0xee, @@ -734,7 +968,7 @@ static void bigint_test_exec ( void ) { BIGINT ( 0xca, 0xab, 0x9f, 0x54, 0x4e, 0x48, 0x75, 0x8c, 0x63, 0x28, 0x69, 0x78, 0xe8, 0x8a, 0x3d, 0xd8, 0x4b, 0x24, - 0xb8, 0xa4, 0x71, 0x6d, 0x6b ) ); + 0xb8, 0xa4, 0x71, 0x6d, 0x6b ), 1 ); bigint_subtract_ok ( BIGINT ( 0x5b, 0x06, 0x77, 0x7b, 0xfd, 0x34, 0x5f, 0x0f, 0xd9, 0xbd, 0x8e, 0x5d, 0xc8, 0x4a, 0x70, 0x95, 0x1b, 0xb6, @@ -800,24 +1034,37 @@ static void bigint_test_exec ( void ) { 0x29, 0x8c, 0x43, 0x9f, 0xf0, 0x9d, 0xda, 0xc8, 0x8c, 0x71, 0x86, 0x97, 0x7f, 0xcb, 0x94, 0x31, 0x1d, 0xbc, - 0x44, 0x1a ) ); - bigint_rol_ok ( BIGINT ( 0xe0 ), - BIGINT ( 0xc0 ) ); - bigint_rol_ok ( BIGINT ( 0x43, 0x1d ), - BIGINT ( 0x86, 0x3a ) ); - bigint_rol_ok ( BIGINT ( 0xac, 0xed, 0x9b ), - BIGINT ( 0x59, 0xdb, 0x36 ) ); - bigint_rol_ok ( BIGINT ( 0x2c, 0xe8, 0x3a, 0x22 ), - BIGINT ( 0x59, 0xd0, 0x74, 0x44 ) ); - bigint_rol_ok ( BIGINT ( 0x4e, 0x88, 0x4a, 0x05, 0x5e, 0x10, 0xee, + 0x44, 0x1a ), 0 ); + bigint_shl_ok ( BIGINT(), BIGINT(), 0 ); + bigint_shl_ok ( BIGINT ( 0xe0 ), + BIGINT ( 0xc0 ), 1 ); + bigint_shl_ok ( BIGINT ( 0x43, 0x1d ), + BIGINT ( 0x86, 0x3a ), 0 ); + bigint_shl_ok ( BIGINT ( 0xac, 0xed, 0x9b ), + BIGINT ( 0x59, 0xdb, 0x36 ), 1 ); + bigint_shl_ok ( BIGINT ( 0x2c, 0xe8, 0x3a, 0x22 ), + BIGINT ( 0x59, 0xd0, 0x74, 0x44 ), 0 ); + bigint_shl_ok ( BIGINT ( 0x4e, 0x88, 0x4a, 0x05, 0x5e, 0x10, 0xee, 0x5b, 0xc6, 0x40, 0x0e, 0x03, 0xd7, 0x0d, 0x28, 0xa5, 0x55, 0xb2, 0x50, 0xef, 0x69, 0xd1, 0x1d ), BIGINT ( 0x9d, 0x10, 0x94, 0x0a, 0xbc, 0x21, 0xdc, 0xb7, 0x8c, 0x80, 0x1c, 0x07, 0xae, 0x1a, 0x51, 0x4a, 0xab, 0x64, 0xa1, 0xde, 0xd3, - 0xa2, 0x3a ) ); - bigint_rol_ok ( BIGINT ( 0x07, 0x62, 0x78, 0x70, 0x2e, 0xd4, 0x41, + 0xa2, 0x3a ), 0 ); + bigint_shl_ok ( BIGINT ( 0x84, 0x56, 0xaa, 0xb4, 0x23, 0xd4, 0x4e, + 0xea, 0x92, 0x34, 0x61, 0x11, 0x3e, 0x38, + 0x31, 0x8b ), + BIGINT ( 0x08, 0xad, 0x55, 0x68, 0x47, 0xa8, 0x9d, + 0xd5, 0x24, 0x68, 0xc2, 0x22, 0x7c, 0x70, + 0x63, 0x16 ), 1 ); + bigint_shl_ok ( BIGINT ( 0x4a, 0x2b, 0x6b, 0x7c, 0xbf, 0x8a, 0x43, + 0x71, 0x96, 0xd6, 0x2f, 0x14, 0xa0, 0x2a, + 0xf8, 0x15 ), + BIGINT ( 0x94, 0x56, 0xd6, 0xf9, 0x7f, 0x14, 0x86, + 0xe3, 0x2d, 0xac, 0x5e, 0x29, 0x40, 0x55, + 0xf0, 0x2a ), 0 ); + bigint_shl_ok ( BIGINT ( 0x07, 0x62, 0x78, 0x70, 0x2e, 0xd4, 0x41, 0xaa, 0x9b, 0x50, 0xb1, 0x9a, 0x71, 0xf5, 0x1c, 0x2f, 0xe7, 0x0d, 0xf1, 0x46, 0x57, 0x04, 0x99, 0x78, 0x4e, 0x84, 0x78, 0xba, @@ -854,24 +1101,37 @@ static void bigint_test_exec ( void ) { 0x10, 0xee, 0x09, 0xea, 0x09, 0x9a, 0xd6, 0x49, 0x7c, 0x1e, 0xdb, 0xc7, 0x65, 0xa6, 0x0e, 0xd1, 0xd2, 0x00, 0xb3, 0x41, 0xc9, - 0x3c, 0xbc ) ); - bigint_ror_ok ( BIGINT ( 0x8f ), - BIGINT ( 0x47 ) ); - bigint_ror_ok ( BIGINT ( 0xaa, 0x1d ), - BIGINT ( 0x55, 0x0e ) ); - bigint_ror_ok ( BIGINT ( 0xf0, 0xbd, 0x68 ), - BIGINT ( 0x78, 0x5e, 0xb4 ) ); - bigint_ror_ok ( BIGINT ( 0x33, 0xa0, 0x3d, 0x95 ), - BIGINT ( 0x19, 0xd0, 0x1e, 0xca ) ); - bigint_ror_ok ( BIGINT ( 0xa1, 0xf4, 0xb9, 0x64, 0x91, 0x99, 0xa1, + 0x3c, 0xbc ), 0 ); + bigint_shr_ok ( BIGINT(), BIGINT(), 0 ); + bigint_shr_ok ( BIGINT ( 0x8f ), + BIGINT ( 0x47 ), 1 ); + bigint_shr_ok ( BIGINT ( 0xaa, 0x1d ), + BIGINT ( 0x55, 0x0e ), 1 ); + bigint_shr_ok ( BIGINT ( 0xf0, 0xbd, 0x68 ), + BIGINT ( 0x78, 0x5e, 0xb4 ), 0 ); + bigint_shr_ok ( BIGINT ( 0x33, 0xa0, 0x3d, 0x95 ), + BIGINT ( 0x19, 0xd0, 0x1e, 0xca ), 1 ); + bigint_shr_ok ( BIGINT ( 0xa1, 0xf4, 0xb9, 0x64, 0x91, 0x99, 0xa1, 0xf4, 0xae, 0xeb, 0x71, 0x97, 0x1b, 0x71, 0x09, 0x38, 0x3f, 0x8f, 0xc5, 0x3a, 0xb9, 0x75, 0x94 ), BIGINT ( 0x50, 0xfa, 0x5c, 0xb2, 0x48, 0xcc, 0xd0, 0xfa, 0x57, 0x75, 0xb8, 0xcb, 0x8d, 0xb8, 0x84, 0x9c, 0x1f, 0xc7, 0xe2, 0x9d, 0x5c, - 0xba, 0xca ) ); - bigint_ror_ok ( BIGINT ( 0xc0, 0xb3, 0x78, 0x46, 0x69, 0x6e, 0x35, + 0xba, 0xca ), 0 ); + bigint_shr_ok ( BIGINT ( 0xa4, 0x19, 0xbb, 0x93, 0x0b, 0x3f, 0x47, + 0x5b, 0xb4, 0xb5, 0x7d, 0x75, 0x42, 0x22, + 0xcc, 0xdf ), + BIGINT ( 0x52, 0x0c, 0xdd, 0xc9, 0x85, 0x9f, 0xa3, + 0xad, 0xda, 0x5a, 0xbe, 0xba, 0xa1, 0x11, + 0x66, 0x6f ), 1 ); + bigint_shr_ok ( BIGINT ( 0x27, 0x7e, 0x8f, 0x60, 0x40, 0x93, 0x43, + 0xd6, 0x89, 0x3e, 0x40, 0x61, 0x9a, 0x04, + 0x4c, 0x02 ), + BIGINT ( 0x13, 0xbf, 0x47, 0xb0, 0x20, 0x49, 0xa1, + 0xeb, 0x44, 0x9f, 0x20, 0x30, 0xcd, 0x02, + 0x26, 0x01 ), 0 ); + bigint_shr_ok ( BIGINT ( 0xc0, 0xb3, 0x78, 0x46, 0x69, 0x6e, 0x35, 0x94, 0xed, 0x28, 0xdc, 0xfd, 0xf6, 0xdb, 0x2d, 0x24, 0xcb, 0xa4, 0x6f, 0x0e, 0x58, 0x89, 0x04, 0xec, 0xc8, 0x0c, 0x2d, 0xb3, @@ -908,7 +1168,8 @@ static void bigint_test_exec ( void ) { 0x10, 0x64, 0x55, 0x07, 0xec, 0xa8, 0xc7, 0x46, 0xa8, 0x94, 0xb0, 0xf7, 0xa4, 0x57, 0x1f, 0x72, 0x88, 0x5f, 0xed, 0x4d, 0xc9, - 0x59, 0xbb ) ); + 0x59, 0xbb ), 1 ); + bigint_is_zero_ok ( BIGINT(), 1 ); bigint_is_zero_ok ( BIGINT ( 0x9b ), 0 ); bigint_is_zero_ok ( BIGINT ( 0x5a, 0x9d ), @@ -1017,6 +1278,7 @@ static void bigint_test_exec ( void ) { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff ), 0 ); + bigint_is_geq_ok ( BIGINT(), BIGINT(), 1 ); bigint_is_geq_ok ( BIGINT ( 0xa2 ), BIGINT ( 0x58 ), 1 ); @@ -1284,6 +1546,7 @@ static void bigint_test_exec ( void ) { 0x83, 0xf8, 0xa2, 0x11, 0xf5, 0xd4, 0xcb, 0xe0 ), 1013, 0 ); + bigint_max_set_bit_ok ( BIGINT(), 0 ); bigint_max_set_bit_ok ( BIGINT ( 0x3a ), 6 ); bigint_max_set_bit_ok ( BIGINT ( 0x03 ), @@ -1674,126 +1937,103 @@ static void bigint_test_exec ( void ) { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 ) ); - bigint_mod_multiply_ok ( BIGINT ( 0x37 ), - BIGINT ( 0x67 ), - BIGINT ( 0x3f ), - BIGINT ( 0x3a ) ); - bigint_mod_multiply_ok ( BIGINT ( 0x45, 0x94 ), - BIGINT ( 0xbd, 0xd2 ), - BIGINT ( 0xca, 0xc7 ), - BIGINT ( 0xac, 0xc1 ) ); - bigint_mod_multiply_ok ( BIGINT ( 0x8e, 0xcd, 0x74 ), - BIGINT ( 0xe2, 0xf1, 0xea ), - BIGINT ( 0x59, 0x51, 0x53 ), - BIGINT ( 0x22, 0xdd, 0x1c ) ); - bigint_mod_multiply_ok ( BIGINT ( 0xc2, 0xa8, 0x40, 0x6f ), - BIGINT ( 0x29, 0xd7, 0xf4, 0x77 ), - BIGINT ( 0xbb, 0xbd, 0xdb, 0x3d ), - BIGINT ( 0x8f, 0x39, 0xd0, 0x47 ) ); - bigint_mod_multiply_ok ( BIGINT ( 0x2e, 0xcb, 0x74, 0x7c, 0x64, 0x60, - 0xb3, 0x44, 0xf3, 0x23, 0x49, 0x4a, - 0xc6, 0xb6, 0xbf, 0xea, 0x80, 0xd8, - 0x34, 0xc5, 0x54, 0x22, 0x09 ), - BIGINT ( 0x61, 0x2c, 0x5a, 0xc5, 0xde, 0x07, - 0x65, 0x8e, 0xab, 0x88, 0x1a, 0x2e, - 0x7a, 0x95, 0x17, 0xe3, 0x3b, 0x17, - 0xe4, 0x21, 0xb0, 0xb4, 0x57 ), - BIGINT ( 0x8e, 0x46, 0xa5, 0x87, 0x7b, 0x7f, - 0xc4, 0xd7, 0x31, 0xb1, 0x94, 0xe7, - 0xe7, 0x1c, 0x7e, 0x7a, 0xc2, 0x6c, - 0xce, 0xcb, 0xc8, 0x5d, 0x70 ), - BIGINT ( 0x1e, 0xd1, 0x5b, 0x3d, 0x1d, 0x17, - 0x7c, 0x31, 0x95, 0x13, 0x1b, 0xd8, - 0xee, 0x0a, 0xb0, 0xe1, 0x5b, 0x13, - 0xad, 0x83, 0xe9, 0xf8, 0x7f ) ); - bigint_mod_multiply_ok ( BIGINT ( 0x56, 0x37, 0xab, 0x07, 0x8b, 0x25, - 0xa7, 0xc2, 0x50, 0x30, 0x43, 0xfc, - 0x63, 0x8b, 0xdf, 0x84, 0x68, 0x85, - 0xca, 0xce, 0x44, 0x5c, 0xb1, 0x14, - 0xa4, 0xb5, 0xba, 0x43, 0xe0, 0x31, - 0x45, 0x6b, 0x82, 0xa9, 0x0b, 0x9e, - 0x3a, 0xb0, 0x39, 0x09, 0x2a, 0x68, - 0x2e, 0x0f, 0x09, 0x54, 0x47, 0x04, - 0xdb, 0xcf, 0x4a, 0x3a, 0x2d, 0x7b, - 0x7d, 0x50, 0xa4, 0xc5, 0xeb, 0x13, - 0xdd, 0x49, 0x61, 0x7d, 0x18, 0xa1, - 0x0d, 0x6b, 0x58, 0xba, 0x9f, 0x7c, - 0x81, 0x34, 0x9e, 0xf9, 0x9c, 0x9e, - 0x28, 0xa8, 0x1c, 0x15, 0x16, 0x20, - 0x3c, 0x0a, 0xb1, 0x11, 0x06, 0x93, - 0xbc, 0xd8, 0x4e, 0x49, 0xae, 0x7b, - 0xb4, 0x02, 0x8b, 0x1c, 0x5b, 0x18, - 0xb4, 0xac, 0x7f, 0xdd, 0x70, 0xef, - 0x87, 0xac, 0x1b, 0xac, 0x25, 0xa3, - 0xc9, 0xa7, 0x3a, 0xc5, 0x76, 0x68, - 0x09, 0x1f, 0xa1, 0x48, 0x53, 0xb6, - 0x13, 0xac ), - BIGINT ( 0xef, 0x5c, 0x1f, 0x1a, 0x44, 0x64, - 0x66, 0xcf, 0xdd, 0x3f, 0x0b, 0x27, - 0x81, 0xa7, 0x91, 0x7a, 0x35, 0x7b, - 0x0f, 0x46, 0x5e, 0xca, 0xbf, 0xf8, - 0x50, 0x5e, 0x99, 0x7c, 0xc6, 0x64, - 0x43, 0x00, 0x9f, 0xb2, 0xda, 0xfa, - 0x42, 0x15, 0x9c, 0xa3, 0xd6, 0xc8, - 0x64, 0xa7, 0x65, 0x4a, 0x98, 0xf7, - 0xb3, 0x96, 0x5f, 0x42, 0xf9, 0x73, - 0xe1, 0x75, 0xc3, 0xc4, 0x0b, 0x5d, - 0x5f, 0xf3, 0x04, 0x8a, 0xee, 0x59, - 0xa6, 0x1b, 0x06, 0x38, 0x0b, 0xa2, - 0x9f, 0xb4, 0x4f, 0x6d, 0x50, 0x5e, - 0x37, 0x37, 0x21, 0x83, 0x9d, 0xa3, - 0x12, 0x16, 0x4d, 0xab, 0x36, 0x51, - 0x21, 0xb1, 0x74, 0x66, 0x40, 0x9a, - 0xd3, 0x72, 0xcc, 0x18, 0x40, 0x53, - 0x89, 0xff, 0xd7, 0x00, 0x8d, 0x7e, - 0x93, 0x81, 0xdb, 0x29, 0xb6, 0xd7, - 0x23, 0x2b, 0x67, 0x2f, 0x11, 0x98, - 0x49, 0x87, 0x2f, 0x46, 0xb7, 0x33, - 0x6d, 0x12 ), - BIGINT ( 0x67, 0x7a, 0x17, 0x6a, 0xd2, 0xf8, - 0x49, 0xfb, 0x7c, 0x95, 0x25, 0x54, - 0xf0, 0xab, 0x5b, 0xb3, 0x0e, 0x01, - 0xab, 0xd3, 0x65, 0x6f, 0x7e, 0x18, - 0x05, 0xed, 0x9b, 0xc4, 0x90, 0x6c, - 0xd0, 0x6d, 0x94, 0x79, 0x28, 0xd6, - 0x24, 0x77, 0x9a, 0x08, 0xd2, 0x2f, - 0x7c, 0x2d, 0xa0, 0x0c, 0x14, 0xbe, - 0x7b, 0xee, 0x9e, 0x48, 0x88, 0x3c, - 0x8f, 0x9f, 0xb9, 0x7a, 0xcb, 0x98, - 0x76, 0x61, 0x0d, 0xee, 0xa2, 0x42, - 0x67, 0x1b, 0x2c, 0x42, 0x8f, 0x41, - 0xcc, 0x78, 0xba, 0xba, 0xaa, 0xa2, - 0x92, 0xb0, 0x6e, 0x0c, 0x4e, 0xe1, - 0xa5, 0x13, 0x7d, 0x8a, 0x8f, 0x81, - 0x95, 0x8a, 0xdf, 0x57, 0x93, 0x88, - 0x27, 0x4f, 0x1a, 0x59, 0xa4, 0x74, - 0x22, 0xa9, 0x78, 0xe5, 0xed, 0xb1, - 0x09, 0x26, 0x59, 0xde, 0x88, 0x21, - 0x8d, 0xa2, 0xa8, 0x58, 0x10, 0x7b, - 0x65, 0x96, 0xbf, 0x69, 0x3b, 0xc5, - 0x55, 0xf8 ), - BIGINT ( 0x15, 0xf7, 0x00, 0xeb, 0xc7, 0x5a, - 0x6f, 0xf0, 0x50, 0xf3, 0x21, 0x8a, - 0x8e, 0xa6, 0xf6, 0x67, 0x56, 0x7d, - 0x07, 0x45, 0x89, 0xdb, 0xd7, 0x7e, - 0x9e, 0x28, 0x7f, 0xfb, 0xed, 0xca, - 0x2c, 0xbf, 0x47, 0x77, 0x99, 0x95, - 0xf3, 0xd6, 0x9d, 0xc5, 0x57, 0x81, - 0x7f, 0x97, 0xf2, 0x6b, 0x24, 0xee, - 0xce, 0xc5, 0x9b, 0xe6, 0x42, 0x2d, - 0x37, 0xb7, 0xeb, 0x3d, 0xb5, 0xf7, - 0x1e, 0x86, 0xc2, 0x40, 0x44, 0xc9, - 0x85, 0x5a, 0x1a, 0xc0, 0xac, 0x9e, - 0x78, 0x69, 0x00, 0x7b, 0x93, 0x65, - 0xd7, 0x7f, 0x0c, 0xd6, 0xba, 0x4f, - 0x06, 0x00, 0x61, 0x05, 0xb2, 0x44, - 0xb4, 0xe7, 0xbb, 0x3b, 0x96, 0xb0, - 0x6d, 0xe8, 0x43, 0xd2, 0x03, 0xb7, - 0x0a, 0xc4, 0x6d, 0x30, 0xd8, 0xd5, - 0xe6, 0x54, 0x65, 0xdd, 0xa9, 0x1b, - 0x50, 0xc0, 0xb9, 0x95, 0xb0, 0x7d, - 0x7c, 0xca, 0x63, 0xf8, 0x72, 0xbe, - 0x3b, 0x00 ) ); + bigint_reduce_ok ( BIGINT ( 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00 ), + BIGINT ( 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00 ) ); + bigint_reduce_ok ( BIGINT ( 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01 ), + BIGINT ( 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00 ) ); + bigint_reduce_ok ( BIGINT ( 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, + 0x00 ), + BIGINT ( 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00 ) ); + bigint_reduce_ok ( BIGINT ( 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00 ), + BIGINT ( 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00 ) ); + bigint_reduce_ok ( BIGINT ( 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff ), + BIGINT ( 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01 ) ); + bigint_reduce_ok ( BIGINT ( 0x39, 0x18, 0x47, 0xc9, 0xa2, 0x1d, 0x4b, + 0xa6 ), + BIGINT ( 0x30, 0x9d, 0xcc, 0xac, 0xd6, 0xf9, 0x2f, + 0xa0 ) ); + bigint_reduce_ok ( BIGINT ( 0x81, 0x96, 0xdb, 0x36, 0xa6, 0xb7, 0x41, + 0x45, 0x92, 0x37, 0x7d, 0x48, 0x1b, 0x2f, + 0x3c, 0xa6 ), + BIGINT ( 0x4a, 0x68, 0x25, 0xf7, 0x2b, 0x72, 0x91, + 0x6e, 0x09, 0x83, 0xca, 0xf1, 0x45, 0x79, + 0x84, 0x18 ) ); + bigint_reduce_ok ( BIGINT ( 0x84, 0x2d, 0xe4, 0x1c, 0xc3, 0x11, 0x4f, + 0xa0, 0x90, 0x4b, 0xa9, 0xa1, 0xdf, 0xed, + 0x4b, 0xe0, 0xb7, 0xfc, 0x5e, 0xd1, 0x91, + 0x59, 0x4d, 0xc2, 0xae, 0x2f, 0x46, 0x9e, + 0x32, 0x6e, 0xf4, 0x67 ), + BIGINT ( 0x46, 0xdd, 0x36, 0x6c, 0x0b, 0xac, 0x3a, + 0x8f, 0x9a, 0x25, 0x90, 0xb2, 0x39, 0xe9, + 0xa4, 0x65, 0xc1, 0xd4, 0xc1, 0x99, 0x61, + 0x95, 0x47, 0xab, 0x4f, 0xd7, 0xad, 0xd4, + 0x3e, 0xe9, 0x9c, 0xfc ) ); + bigint_mod_invert_ok ( BIGINT ( 0x01 ), BIGINT ( 0x01 ) ); + bigint_mod_invert_ok ( BIGINT ( 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff ), + BIGINT ( 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff ) ); + bigint_mod_invert_ok ( BIGINT ( 0xa4, 0xcb, 0xbc, 0xc9, 0x9f, 0x7a, + 0x65, 0xbf ), + BIGINT ( 0xb9, 0xd5, 0xf4, 0x88, 0x0b, 0xf8, + 0x8a, 0x3f ) ); + bigint_mod_invert_ok ( BIGINT ( 0x95, 0x6a, 0xc5, 0xe7, 0x2e, 0x5b, + 0x44, 0xed, 0xbf, 0x7e, 0xfe, 0x8d, + 0xf4, 0x5a, 0x48, 0xc1 ), + BIGINT ( 0xad, 0xb8, 0x3d, 0x85, 0x10, 0xdf, + 0xea, 0x70, 0x71, 0x2c, 0x80, 0xf4, + 0x6e, 0x66, 0x47, 0x41 ) ); + bigint_mod_invert_ok ( BIGINT ( 0x35, 0xe4, 0x80, 0x48, 0xdd, 0xa1, + 0x46, 0xc0, 0x84, 0x63, 0xc1, 0xe4, + 0xf7, 0xbf, 0xb3, 0x05 ), + BIGINT ( 0xf2, 0x9c, 0x63, 0x29, 0xfa, 0xe4, + 0xbf, 0x90, 0xa6, 0x9a, 0xec, 0xcf, + 0x5f, 0xe2, 0x21, 0xcd ) ); + bigint_mod_invert_ok ( BIGINT ( 0xb9, 0xbb, 0x7f, 0x9c, 0x7a, 0x32, + 0x43, 0xed, 0x9d, 0xd4, 0x0d, 0x6f, + 0x32, 0xfa, 0x4b, 0x62, 0x38, 0x3a, + 0xbf, 0x4c, 0xbd, 0xa8, 0x47, 0xce, + 0xa2, 0x30, 0x34, 0xe0, 0x2c, 0x09, + 0x14, 0x89 ), + BIGINT ( 0xfc, 0x05, 0xc4, 0x2a, 0x90, 0x99, + 0x82, 0xf8, 0x81, 0x1d, 0x87, 0xb8, + 0xca, 0xe4, 0x95, 0xe2, 0xac, 0x18, + 0xb3, 0xe1, 0x3e, 0xc6, 0x5a, 0x03, + 0x51, 0x6f, 0xb7, 0xe3, 0xa5, 0xd6, + 0xa1, 0xb9 ) ); + bigint_mod_invert_ok ( BIGINT ( 0xfe, 0x43, 0xf6, 0xa0, 0x32, 0x02, + 0x47, 0xaa, 0xaa, 0x0e, 0x33, 0x19, + 0x2e, 0xe6, 0x22, 0x07 ), + BIGINT ( 0x7b, 0xd1, 0x0f, 0x78, 0x0c, 0x65, + 0xab, 0xb7 ) ); + bigint_montgomery_ok ( BIGINT ( 0x74, 0xdf, 0xd1, 0xb8, 0x14, 0xf7, + 0x05, 0x83 ), + BIGINT ( 0x50, 0x6a, 0x38, 0x55, 0x9f, 0xb9, + 0x9d, 0xba, 0xff, 0x23, 0x86, 0x65, + 0xe3, 0x2c, 0x3f, 0x17 ), + BIGINT ( 0x45, 0x1f, 0x51, 0x44, 0x6f, 0x3c, + 0x09, 0x6b ) ); + bigint_montgomery_ok ( BIGINT ( 0x2e, 0x32, 0x90, 0x69, 0x6e, 0xa8, + 0x47, 0x4c, 0xad, 0xe4, 0xe7, 0x4c, + 0x03, 0xcb, 0xe6, 0x55 ), + BIGINT ( 0x1e, 0x43, 0xf9, 0xc2, 0x61, 0xdd, + 0xe8, 0xbf, 0xb8, 0xea, 0xe0, 0xdb, + 0xed, 0x66, 0x80, 0x1e, 0xe8, 0xf8, + 0xd1, 0x1d, 0xca, 0x8d, 0x45, 0xe9, + 0xc5, 0xeb, 0x77, 0x21, 0x34, 0xe0, + 0xf5, 0x5a ), + BIGINT ( 0x03, 0x38, 0xfb, 0xb6, 0xf3, 0x80, + 0x91, 0xb2, 0x68, 0x2f, 0x81, 0x44, + 0xbf, 0x43, 0x0a, 0x4e ) ); bigint_mod_exp_ok ( BIGINT ( 0xcd ), BIGINT ( 0xbb ), BIGINT ( 0x25 ), @@ -1810,6 +2050,14 @@ static void bigint_test_exec ( void ) { BIGINT ( 0xb9 ), BIGINT ( 0x39, 0x68, 0xba, 0x7d ), BIGINT ( 0x17 ) ); + bigint_mod_exp_ok ( BIGINT ( 0x71, 0x4d, 0x02, 0xe9 ), + BIGINT ( 0x00, 0x00, 0x00, 0x00 ), + BIGINT ( 0x91, 0x7f, 0x4e, 0x3a, 0x5d, 0x5c ), + BIGINT ( 0x00, 0x00, 0x00, 0x00 ) ); + bigint_mod_exp_ok ( BIGINT ( 0x2b, 0xf5, 0x07, 0xaf ), + BIGINT ( 0x6e, 0xb5, 0xda, 0x5a ), + BIGINT ( 0x00, 0x00, 0x00, 0x00, 0x00 ), + BIGINT ( 0x00, 0x00, 0x00, 0x01 ) ); bigint_mod_exp_ok ( BIGINT ( 0x2e ), BIGINT ( 0xb7 ), BIGINT ( 0x39, 0x07, 0x1b, 0x49, 0x5b, 0xea, @@ -2514,6 +2762,25 @@ static void bigint_test_exec ( void ) { 0xfa, 0x83, 0xd4, 0x7c, 0xe9, 0x77, 0x46, 0x91, 0x3a, 0x50, 0x0d, 0x6a, 0x25, 0xd0 ) ); + bigint_mod_exp_ok ( BIGINT ( 0x5b, 0x80, 0xc5, 0x03, 0xb3, 0x1e, + 0x46, 0x9b, 0xa3, 0x0a, 0x70, 0x43, + 0x51, 0x2a, 0x4a, 0x44, 0xcb, 0x87, + 0x3e, 0x00, 0x2a, 0x48, 0x46, 0xf5, + 0xb3, 0xb9, 0x73, 0xa7, 0x77, 0xfc, + 0x2a, 0x1d ), + BIGINT ( 0x5e, 0x8c, 0x80, 0x03, 0xe7, 0xb0, + 0x45, 0x23, 0x8f, 0xe0, 0x77, 0x02, + 0xc0, 0x7e, 0xfb, 0xc4, 0xbe, 0x7b, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00 ), + BIGINT ( 0x71, 0xd9, 0x38, 0xb6 ), + BIGINT ( 0x52, 0xfc, 0x73, 0x55, 0x2f, 0x86, + 0x0f, 0xde, 0x04, 0xbc, 0x6d, 0xb8, + 0xfd, 0x48, 0xf8, 0x8c, 0x91, 0x1c, + 0xa0, 0x8a, 0x70, 0xa8, 0xc6, 0x20, + 0x0a, 0x0d, 0x3b, 0x2a, 0x92, 0x65, + 0x9c, 0x59 ) ); } /** Big integer self-test */ diff --git a/src/tests/bofm_test.c b/src/tests/bofm_test.c index 829924887..bc400284f 100644 --- a/src/tests/bofm_test.c +++ b/src/tests/bofm_test.c @@ -26,7 +26,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); #include <stdint.h> #include <stdio.h> #include <string.h> -#include <ipxe/uaccess.h> +#include <byteswap.h> #include <ipxe/init.h> #include <ipxe/pci.h> #include <ipxe/ethernet.h> @@ -111,7 +111,7 @@ void bofm_test ( struct pci_device *pci ) { printf ( "BOFMTEST performing harvest\n" ); bofmtab_harvest.en.busdevfn = pci->busdevfn; DBG_HDA ( 0, &bofmtab_harvest, sizeof ( bofmtab_harvest ) ); - bofmrc = bofm ( virt_to_user ( &bofmtab_harvest ), pci ); + bofmrc = bofm ( &bofmtab_harvest, pci ); printf ( "BOFMTEST harvest result %08x\n", bofmrc ); if ( bofmtab_harvest.en.options & BOFM_EN_HVST ) { printf ( "BOFMTEST harvested MAC address %s\n", @@ -125,7 +125,7 @@ void bofm_test ( struct pci_device *pci ) { printf ( "BOFMTEST performing update\n" ); bofmtab_update.en.busdevfn = pci->busdevfn; DBG_HDA ( 0, &bofmtab_update, sizeof ( bofmtab_update ) ); - bofmrc = bofm ( virt_to_user ( &bofmtab_update ), pci ); + bofmrc = bofm ( &bofmtab_update, pci ); printf ( "BOFMTEST update result %08x\n", bofmrc ); if ( bofmtab_update.en.options & BOFM_EN_CSM_SUCCESS ) { printf ( "BOFMTEST updated MAC address to %s\n", @@ -137,6 +137,109 @@ void bofm_test ( struct pci_device *pci ) { } /** + * Harvest dummy Ethernet MAC + * + * @v bofm BOFM device + * @v mport Multi-port index + * @v mac MAC to fill in + * @ret rc Return status code + */ +static int bofm_dummy_harvest ( struct bofm_device *bofm, unsigned int mport, + uint8_t *mac ) { + struct { + uint16_t vendor; + uint16_t device; + uint16_t mport; + } __attribute__ (( packed )) dummy_mac; + + /* Construct dummy MAC address */ + dummy_mac.vendor = cpu_to_be16 ( bofm->pci->vendor ); + dummy_mac.device = cpu_to_be16 ( bofm->pci->device ); + dummy_mac.mport = cpu_to_be16 ( mport ); + memcpy ( mac, &dummy_mac, sizeof ( dummy_mac ) ); + printf ( "BOFMTEST mport %d constructed dummy MAC %s\n", + mport, eth_ntoa ( mac ) ); + + return 0; +} + +/** + * Update Ethernet MAC for BOFM + * + * @v bofm BOFM device + * @v mport Multi-port index + * @v mac MAC to fill in + * @ret rc Return status code + */ +static int bofm_dummy_update ( struct bofm_device *bofm __unused, + unsigned int mport, const uint8_t *mac ) { + + printf ( "BOFMTEST mport %d asked to update MAC to %s\n", + mport, eth_ntoa ( mac ) ); + return 0; +} + +/** Dummy BOFM operations */ +static struct bofm_operations bofm_dummy_operations = { + .harvest = bofm_dummy_harvest, + .update = bofm_dummy_update, +}; + +/** Dummy BOFM device */ +static struct bofm_device bofm_dummy; + +/** + * Probe dummy BOFM device + * + * @v pci PCI device + * @v id PCI ID + * @ret rc Return status code + */ +static int bofm_dummy_probe ( struct pci_device *pci ) { + int rc; + + /* Ignore probe for any other devices */ + if ( pci->busdevfn != bofm_dummy.pci->busdevfn ) + return 0; + + /* Register BOFM device */ + if ( ( rc = bofm_register ( &bofm_dummy ) ) != 0 ) + return rc; + + printf ( "BOFMTEST using dummy BOFM driver\n" ); + return 0; +} + +/** + * Remove dummy BOFM device + * + * @v pci PCI device + */ +static void bofm_dummy_remove ( struct pci_device *pci ) { + + /* Ignore removal for any other devices */ + if ( pci->busdevfn != bofm_dummy.pci->busdevfn ) + return; + + /* Unregister BOFM device */ + bofm_unregister ( &bofm_dummy ); +} + +/** Dummy BOFM driver PCI IDs */ +static struct pci_device_id bofm_dummy_ids[1] = { + { .name = "dummy" }, +}; + +/** Dummy BOFM driver */ +struct pci_driver bofm_dummy_driver __bofm_test_driver = { + .ids = bofm_dummy_ids, + .id_count = ( sizeof ( bofm_dummy_ids ) / + sizeof ( bofm_dummy_ids[0] ) ), + .probe = bofm_dummy_probe, + .remove = bofm_dummy_remove, +}; + +/** * Perform BOFM test at initialisation time * */ @@ -149,7 +252,7 @@ static void bofm_test_init ( void ) { * bus:dev.fn address in order to perform a BOFM test at * initialisation time. */ - // busdevfn = PCI_BUSDEVFN ( <bus>, <dev>, <fn> ); + // busdevfn = PCI_BUSDEVFN ( <segment>, <bus>, <dev>, <fn> ); /* Skip test if no PCI bus:dev.fn is defined */ if ( busdevfn < 0 ) @@ -164,11 +267,17 @@ static void bofm_test_init ( void ) { return; } + /* Initialise dummy BOFM device */ + bofm_init ( &bofm_dummy, &pci, &bofm_dummy_operations ); + bofm_dummy_ids[0].vendor = pci.vendor; + bofm_dummy_ids[0].device = pci.device; + /* Perform test */ bofm_test ( &pci ); } /** BOFM test initialisation function */ struct init_fn bofm_test_init_fn __init_fn ( INIT_NORMAL ) = { + .name = "bofm", .initialise = bofm_test_init, }; diff --git a/src/tests/cms_test.c b/src/tests/cms_test.c index f35fa206d..b71190cba 100644 --- a/src/tests/cms_test.c +++ b/src/tests/cms_test.c @@ -36,30 +36,39 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); #include <string.h> #include <ipxe/sha256.h> #include <ipxe/x509.h> -#include <ipxe/uaccess.h> +#include <ipxe/image.h> +#include <ipxe/der.h> #include <ipxe/cms.h> +#include <ipxe/privkey.h> #include <ipxe/test.h> /** Fingerprint algorithm used for X.509 test certificates */ #define cms_test_algorithm sha256_algorithm -/** CMS test code blob */ -struct cms_test_code { - /** Data */ - const void *data; - /** Length of data */ - size_t len; +/** Test image */ +struct cms_test_image { + /** Image */ + struct image image; +}; + +/** Test CMS message */ +struct cms_test_message { + /** Message image */ + struct image image; + /** Parsed message */ + struct cms_message *cms; }; -/** CMS test signature */ -struct cms_test_signature { - /** Data */ +/** Test CMS key pair */ +struct cms_test_keypair { + /** Private key */ + struct private_key privkey; + /** Certificate data */ const void *data; - /** Length of data */ + /** Length of certificate data */ size_t len; - - /** Parsed signature */ - struct cms_signature *sig; + /** Parsed certificate */ + struct x509_certificate *cert; }; /** Define inline data */ @@ -68,24 +77,64 @@ struct cms_test_signature { /** Define inline fingerprint data */ #define FINGERPRINT(...) { __VA_ARGS__ } -/** Define a test code blob */ -#define SIGNED_CODE( name, DATA ) \ - static const uint8_t name ## _data[] = DATA; \ - static struct cms_test_code name = { \ - .data = name ## _data, \ - .len = sizeof ( name ## _data ), \ +/** Define a test image */ +#define IMAGE( NAME, DATA ) \ + static const uint8_t NAME ## _data[] = DATA; \ + static struct cms_test_image NAME = { \ + .image = { \ + .refcnt = REF_INIT ( ref_no_free ), \ + .name = #NAME, \ + .flags = ( IMAGE_STATIC | IMAGE_STATIC_NAME ), \ + .data = NAME ## _data, \ + .len = sizeof ( NAME ## _data ), \ + }, \ + } + +/** Define a writable test image */ +#define IMAGE_RW( NAME, DATA ) \ + static uint8_t NAME ## _data[] = DATA; \ + static struct cms_test_image NAME = { \ + .image = { \ + .refcnt = REF_INIT ( ref_no_free ), \ + .name = #NAME, \ + .flags = ( IMAGE_STATIC | IMAGE_STATIC_NAME ), \ + .data = NAME ## _data, \ + .len = sizeof ( NAME ## _data ), \ + }, \ } -/** Define a test signature */ -#define SIGNATURE( name, DATA ) \ - static const uint8_t name ## _data[] = DATA; \ - static struct cms_test_signature name = { \ - .data = name ## _data, \ - .len = sizeof ( name ## _data ), \ +/** Define a test message */ +#define MESSAGE( NAME, DATA ) \ + static const uint8_t NAME ## _data[] = DATA; \ + static struct cms_test_message NAME = { \ + .image = { \ + .refcnt = REF_INIT ( ref_no_free ), \ + .name = #NAME, \ + .flags = ( IMAGE_STATIC | IMAGE_STATIC_NAME ), \ + .type = &der_image_type, \ + .data = NAME ## _data, \ + .len = sizeof ( NAME ## _data ), \ + }, \ + } + +/** Define a test key pair */ +#define KEYPAIR( NAME, PRIVKEY, CERT ) \ + static uint8_t NAME ## _privkey[] = PRIVKEY; \ + static const uint8_t NAME ## _cert[] = CERT; \ + static struct cms_test_keypair NAME = { \ + .privkey = { \ + .refcnt = REF_INIT ( ref_no_free ), \ + .builder = { \ + .data = NAME ## _privkey, \ + .len = sizeof ( NAME ## _privkey ), \ + }, \ + }, \ + .data = NAME ## _cert, \ + .len = sizeof ( NAME ## _cert ), \ } /** Code that has been signed */ -SIGNED_CODE ( test_code, +IMAGE ( test_code, DATA ( 0x23, 0x21, 0x69, 0x70, 0x78, 0x65, 0x0a, 0x0a, 0x65, 0x63, 0x68, 0x6f, 0x20, 0x54, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x61, 0x20, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x20, @@ -97,7 +146,7 @@ SIGNED_CODE ( test_code, 0x65, 0x6c, 0x6c, 0x0a ) ); /** Code that has not been signed */ -SIGNED_CODE ( bad_code, +IMAGE ( bad_code, DATA ( 0x23, 0x21, 0x69, 0x70, 0x78, 0x65, 0x0a, 0x0a, 0x65, 0x63, 0x68, 0x6f, 0x20, 0x54, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x61, 0x20, 0x6d, 0x61, 0x6c, 0x69, 0x63, 0x69, 0x6f, @@ -107,8 +156,125 @@ SIGNED_CODE ( bad_code, 0x6f, 0x75, 0x20, 0x77, 0x61, 0x6e, 0x74, 0x21, 0x0a, 0x73, 0x68, 0x65, 0x6c, 0x6c, 0x0a ) ); +/** Plaintext of encrypted code */ +IMAGE ( hidden_code, + DATA ( 0x23, 0x21, 0x69, 0x70, 0x78, 0x65, 0x0a, 0x0a, 0x65, 0x63, + 0x68, 0x6f, 0x20, 0x54, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, + 0x20, 0x61, 0x20, 0x64, 0x65, 0x63, 0x72, 0x79, 0x70, 0x74, + 0x65, 0x64, 0x20, 0x69, 0x50, 0x58, 0x45, 0x20, 0x73, 0x63, + 0x72, 0x69, 0x70, 0x74, 0x2e, 0x20, 0x20, 0x44, 0x6f, 0x20, + 0x61, 0x6e, 0x79, 0x74, 0x68, 0x69, 0x6e, 0x67, 0x20, 0x79, + 0x6f, 0x75, 0x20, 0x77, 0x61, 0x6e, 0x74, 0x21, 0x0a, 0x73, + 0x68, 0x65, 0x6c, 0x6c, 0x0a ) ); + +/** Code encrypted with AES-256-CBC */ +IMAGE_RW ( hidden_code_cbc_dat, + DATA ( 0xaa, 0x63, 0x9f, 0x12, 0xeb, 0x1e, 0xdd, 0x9b, 0xb6, 0x4d, + 0x81, 0xd5, 0xba, 0x2d, 0x86, 0x7a, 0x1c, 0x39, 0x10, 0x60, + 0x43, 0xac, 0x1b, 0x4e, 0x43, 0xb7, 0x50, 0x5a, 0x6d, 0x7a, + 0x4b, 0xd8, 0x65, 0x3c, 0x3e, 0xbd, 0x40, 0x9e, 0xb2, 0xe1, + 0x7d, 0x80, 0xf8, 0x22, 0x50, 0xf7, 0x32, 0x3a, 0x43, 0xf9, + 0xdf, 0xa6, 0xab, 0xa4, 0xb3, 0xdd, 0x27, 0x88, 0xd9, 0xb0, + 0x99, 0xb5, 0x7a, 0x89, 0x6c, 0xb7, 0x63, 0x45, 0x42, 0x7d, + 0xbe, 0x43, 0xab, 0x7e, 0x6c, 0x0c, 0xd5, 0xba, 0x9e, 0x37 ) ); + +/** Envelope for code encrypted with AES-256-CBC */ +MESSAGE ( hidden_code_cbc_env, + DATA ( 0x30, 0x82, 0x01, 0x70, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, + 0xf7, 0x0d, 0x01, 0x07, 0x03, 0xa0, 0x82, 0x01, 0x61, 0x30, + 0x82, 0x01, 0x5d, 0x02, 0x01, 0x00, 0x31, 0x82, 0x01, 0x2a, + 0x30, 0x82, 0x01, 0x26, 0x02, 0x01, 0x00, 0x30, 0x81, 0x8e, + 0x30, 0x81, 0x88, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, + 0x04, 0x06, 0x13, 0x02, 0x47, 0x42, 0x31, 0x17, 0x30, 0x15, + 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x0e, 0x43, 0x61, 0x6d, + 0x62, 0x72, 0x69, 0x64, 0x67, 0x65, 0x73, 0x68, 0x69, 0x72, + 0x65, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x07, + 0x0c, 0x09, 0x43, 0x61, 0x6d, 0x62, 0x72, 0x69, 0x64, 0x67, + 0x65, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x0a, + 0x0c, 0x0f, 0x46, 0x65, 0x6e, 0x20, 0x53, 0x79, 0x73, 0x74, + 0x65, 0x6d, 0x73, 0x20, 0x4c, 0x74, 0x64, 0x31, 0x11, 0x30, + 0x0f, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x08, 0x69, 0x70, + 0x78, 0x65, 0x2e, 0x6f, 0x72, 0x67, 0x31, 0x1f, 0x30, 0x1d, + 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x16, 0x69, 0x50, 0x58, + 0x45, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2d, 0x74, 0x65, 0x73, + 0x74, 0x20, 0x6c, 0x65, 0x61, 0x66, 0x20, 0x43, 0x41, 0x02, + 0x01, 0x08, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, + 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x04, 0x81, 0x80, + 0x10, 0x26, 0x94, 0x97, 0xe5, 0x84, 0x53, 0xf9, 0x03, 0xc4, + 0xf6, 0xc1, 0x55, 0xf5, 0x00, 0x23, 0xb9, 0x80, 0x20, 0x85, + 0xd2, 0xf2, 0xc4, 0x61, 0xdb, 0x73, 0x8d, 0xe1, 0xa1, 0x73, + 0x7d, 0x31, 0x12, 0xb7, 0xac, 0xa4, 0xe0, 0x40, 0x10, 0xcf, + 0xd5, 0x55, 0x70, 0x75, 0x9f, 0x7b, 0x61, 0xd3, 0x9e, 0xc6, + 0x58, 0x78, 0x05, 0x66, 0xc1, 0x86, 0x2f, 0x00, 0xcd, 0xe9, + 0x32, 0x63, 0x7c, 0x95, 0xd7, 0x75, 0x46, 0xde, 0x76, 0x7d, + 0x49, 0x64, 0x86, 0xd6, 0xeb, 0x0f, 0x1c, 0x01, 0x20, 0xb9, + 0xb9, 0x42, 0xc4, 0x20, 0x1f, 0x3f, 0xae, 0x5f, 0xb9, 0xd0, + 0xb6, 0x49, 0xcc, 0x4c, 0xd9, 0xcb, 0x36, 0xa4, 0x2f, 0xb1, + 0x97, 0x40, 0xf3, 0xe7, 0x19, 0x88, 0x93, 0x58, 0x61, 0x31, + 0xac, 0x9a, 0x93, 0x6e, 0x79, 0x31, 0x3a, 0x79, 0xa4, 0x20, + 0x38, 0x17, 0x92, 0x40, 0x7c, 0x98, 0xea, 0x86, 0x30, 0x2a, + 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, + 0x01, 0x30, 0x1d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, + 0x03, 0x04, 0x01, 0x2a, 0x04, 0x10, 0xd8, 0x80, 0xc5, 0xfa, + 0xc3, 0x25, 0xa0, 0x22, 0xb5, 0x6c, 0x0c, 0x27, 0x2c, 0xe9, + 0xba, 0xcf ) ); + +/** Code encrypted with AES-256-GCM (no block padding) */ +IMAGE_RW ( hidden_code_gcm_dat, + DATA ( 0x0c, 0x96, 0xa6, 0x54, 0x9a, 0xc2, 0x24, 0x89, 0x15, 0x00, + 0x90, 0xe1, 0x35, 0xca, 0x4a, 0x84, 0x8e, 0x0b, 0xc3, 0x5e, + 0xc0, 0x61, 0x61, 0xbd, 0x2e, 0x69, 0x84, 0x7a, 0x2f, 0xf6, + 0xbe, 0x39, 0x04, 0x0a, 0x8d, 0x91, 0x6b, 0xaf, 0x63, 0xd4, + 0x03, 0xf1, 0x72, 0x38, 0xee, 0x27, 0xd6, 0x5a, 0xae, 0x15, + 0xd5, 0xec, 0xb6, 0xb6, 0x4f, 0x6f, 0xf6, 0x76, 0x22, 0x74, + 0xca, 0x72, 0x0b, 0xfa, 0x6a, 0x0e, 0x4a, 0x3e, 0x8c, 0x60, + 0x78, 0x24, 0x48, 0x58, 0xdd ) ); + +/** Envelope for code encrypted with AES-256-GCM (no block padding) */ +MESSAGE ( hidden_code_gcm_env, + DATA ( 0x30, 0x82, 0x01, 0x85, 0x06, 0x0b, 0x2a, 0x86, 0x48, 0x86, + 0xf7, 0x0d, 0x01, 0x09, 0x10, 0x01, 0x17, 0xa0, 0x82, 0x01, + 0x74, 0x30, 0x82, 0x01, 0x70, 0x02, 0x01, 0x00, 0x31, 0x82, + 0x01, 0x2a, 0x30, 0x82, 0x01, 0x26, 0x02, 0x01, 0x00, 0x30, + 0x81, 0x8e, 0x30, 0x81, 0x88, 0x31, 0x0b, 0x30, 0x09, 0x06, + 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x47, 0x42, 0x31, 0x17, + 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x0e, 0x43, + 0x61, 0x6d, 0x62, 0x72, 0x69, 0x64, 0x67, 0x65, 0x73, 0x68, + 0x69, 0x72, 0x65, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, + 0x04, 0x07, 0x0c, 0x09, 0x43, 0x61, 0x6d, 0x62, 0x72, 0x69, + 0x64, 0x67, 0x65, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, + 0x04, 0x0a, 0x0c, 0x0f, 0x46, 0x65, 0x6e, 0x20, 0x53, 0x79, + 0x73, 0x74, 0x65, 0x6d, 0x73, 0x20, 0x4c, 0x74, 0x64, 0x31, + 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x08, + 0x69, 0x70, 0x78, 0x65, 0x2e, 0x6f, 0x72, 0x67, 0x31, 0x1f, + 0x30, 0x1d, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x16, 0x69, + 0x50, 0x58, 0x45, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2d, 0x74, + 0x65, 0x73, 0x74, 0x20, 0x6c, 0x65, 0x61, 0x66, 0x20, 0x43, + 0x41, 0x02, 0x01, 0x08, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, + 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x04, + 0x81, 0x80, 0x7e, 0xbc, 0xba, 0xee, 0xfa, 0x50, 0x46, 0xee, + 0xed, 0xf1, 0x54, 0xe1, 0x46, 0xeb, 0x57, 0x3e, 0x76, 0xd7, + 0x8f, 0xe3, 0x26, 0x42, 0x3d, 0x28, 0xf9, 0xdc, 0x20, 0xe6, + 0x27, 0x3b, 0x89, 0xcb, 0xab, 0xd5, 0xad, 0xc2, 0xf0, 0x4f, + 0xa8, 0xb9, 0x77, 0x5b, 0x6c, 0xe6, 0x34, 0x22, 0x73, 0x5b, + 0xa4, 0x8e, 0x1c, 0xc2, 0xf8, 0x50, 0xef, 0xe5, 0xcf, 0x80, + 0x16, 0x79, 0x6b, 0x0f, 0xa7, 0xfd, 0xdc, 0x60, 0x9c, 0x94, + 0x60, 0xa6, 0x12, 0x5a, 0xfb, 0xc2, 0xc8, 0x4c, 0x64, 0x83, + 0x99, 0x73, 0xfc, 0xa1, 0xf8, 0xa5, 0x82, 0x75, 0xba, 0x53, + 0xeb, 0xc8, 0x94, 0x0e, 0x29, 0x23, 0x9a, 0x2b, 0xa6, 0x63, + 0x2d, 0x5b, 0x9f, 0x38, 0x70, 0x21, 0xe8, 0xe9, 0xa6, 0xcf, + 0xf2, 0xbe, 0x66, 0xf4, 0xcc, 0x91, 0x01, 0x4f, 0x04, 0x00, + 0x4a, 0x55, 0xc9, 0x42, 0x76, 0xd4, 0x3f, 0x65, 0x0c, 0x76, + 0x30, 0x2b, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, + 0x01, 0x07, 0x01, 0x30, 0x1e, 0x06, 0x09, 0x60, 0x86, 0x48, + 0x01, 0x65, 0x03, 0x04, 0x01, 0x2e, 0x30, 0x11, 0x04, 0x0c, + 0x72, 0xb5, 0x14, 0xfb, 0x05, 0x78, 0x70, 0x1c, 0xf4, 0x4b, + 0xba, 0xbf, 0x02, 0x01, 0x10, 0x04, 0x10, 0x1e, 0x44, 0xda, + 0x5c, 0x75, 0x7e, 0x4f, 0xa7, 0xe7, 0xd9, 0x98, 0x80, 0x9c, + 0x25, 0x6a, 0xfb ) ); + /** Valid signature */ -SIGNATURE ( codesigned_sig, +MESSAGE ( codesigned_sig, DATA ( 0x30, 0x82, 0x0c, 0x41, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x02, 0xa0, 0x82, 0x0c, 0x32, 0x30, 0x82, 0x0c, 0x2e, 0x02, 0x01, 0x01, 0x31, 0x09, 0x30, 0x07, @@ -426,7 +592,7 @@ SIGNATURE ( codesigned_sig, 0xbf ) ); /** Signature with a broken certificate chain */ -SIGNATURE ( brokenchain_sig, +MESSAGE ( brokenchain_sig, DATA ( 0x30, 0x82, 0x09, 0x8a, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x02, 0xa0, 0x82, 0x09, 0x7b, 0x30, 0x82, 0x09, 0x77, 0x02, 0x01, 0x01, 0x31, 0x09, 0x30, 0x07, @@ -674,7 +840,7 @@ SIGNATURE ( brokenchain_sig, 0xf9, 0x71, 0x64, 0x03, 0x05, 0xbf ) ); /** Signature generated with a non-code-signing certificate */ -SIGNATURE ( genericsigned_sig, +MESSAGE ( genericsigned_sig, DATA ( 0x30, 0x82, 0x0c, 0x2f, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x02, 0xa0, 0x82, 0x0c, 0x20, 0x30, 0x82, 0x0c, 0x1c, 0x02, 0x01, 0x01, 0x31, 0x09, 0x30, 0x07, @@ -990,7 +1156,7 @@ SIGNATURE ( genericsigned_sig, 0x7e, 0x7c, 0x99 ) ); /** Signature generated with a non-signing certificate */ -SIGNATURE ( nonsigned_sig, +MESSAGE ( nonsigned_sig, DATA ( 0x30, 0x82, 0x0c, 0x12, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x02, 0xa0, 0x82, 0x0c, 0x03, 0x30, 0x82, 0x0b, 0xff, 0x02, 0x01, 0x01, 0x31, 0x09, 0x30, 0x07, @@ -1302,6 +1468,138 @@ SIGNATURE ( nonsigned_sig, 0x5d, 0x70, 0x47, 0x54, 0xbc, 0x15, 0xad, 0x9c, 0xe8, 0x90, 0x52, 0x3e, 0x49, 0x86 ) ); +/** Client certificate and private key */ +KEYPAIR ( client_keypair, + DATA ( 0x30, 0x82, 0x02, 0x77, 0x02, 0x01, 0x00, 0x30, 0x0d, 0x06, + 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, + 0x05, 0x00, 0x04, 0x82, 0x02, 0x61, 0x30, 0x82, 0x02, 0x5d, + 0x02, 0x01, 0x00, 0x02, 0x81, 0x81, 0x00, 0xb7, 0x9f, 0xb5, + 0x90, 0xfa, 0x47, 0x25, 0xee, 0x3b, 0x04, 0x02, 0x4f, 0xd4, + 0x1d, 0x62, 0x46, 0x9d, 0xce, 0x79, 0x3a, 0x80, 0x3a, 0xc4, + 0x06, 0x6a, 0x67, 0xd4, 0x3a, 0x61, 0x71, 0xcd, 0xb3, 0xcc, + 0x1b, 0xfc, 0x2f, 0x17, 0xa8, 0xf2, 0x26, 0x9e, 0x54, 0xd3, + 0x49, 0x81, 0x22, 0xa9, 0x72, 0x4c, 0xe8, 0x92, 0xb7, 0x1e, + 0x44, 0x8f, 0xa9, 0x4d, 0x83, 0x0b, 0x89, 0x2a, 0xc7, 0xb3, + 0xad, 0x54, 0x32, 0x76, 0x62, 0x1e, 0xe5, 0xbe, 0xc1, 0xa8, + 0x7a, 0x2b, 0xf0, 0xa9, 0x9a, 0xfb, 0xb8, 0x18, 0x0c, 0x30, + 0x5a, 0x13, 0x9c, 0x21, 0x26, 0x96, 0x4f, 0x39, 0x98, 0x64, + 0x41, 0x3b, 0x94, 0xc8, 0xe3, 0xb7, 0x8c, 0x33, 0x9e, 0xd0, + 0x71, 0xd0, 0x2f, 0xe3, 0x7d, 0x2c, 0x57, 0x27, 0x42, 0x26, + 0xd9, 0x2c, 0xb4, 0x55, 0xd5, 0x66, 0xb7, 0xbf, 0x00, 0xa1, + 0xcc, 0x61, 0x19, 0x99, 0x61, 0x02, 0x03, 0x01, 0x00, 0x01, + 0x02, 0x81, 0x80, 0x50, 0x63, 0x2f, 0xe6, 0xb7, 0x5a, 0xfc, + 0x85, 0x0d, 0xfb, 0x14, 0x54, 0x04, 0x65, 0x94, 0xc7, 0x9b, + 0x80, 0x6f, 0xdc, 0x27, 0x95, 0x12, 0x8a, 0x48, 0x7d, 0x0a, + 0x11, 0x40, 0xe5, 0xc4, 0x8b, 0x29, 0x19, 0x3b, 0x4f, 0x16, + 0x89, 0x94, 0xf1, 0x49, 0x31, 0x93, 0x8a, 0x43, 0x69, 0x7c, + 0x4b, 0x18, 0xd6, 0x5c, 0x9c, 0xa4, 0x38, 0x99, 0xb8, 0x21, + 0xc1, 0xf4, 0x03, 0xe9, 0xe1, 0xa1, 0x8b, 0xcb, 0x51, 0x4f, + 0x64, 0x68, 0x1c, 0x73, 0xc0, 0x0d, 0xd2, 0xcd, 0x87, 0xcc, + 0x45, 0xe8, 0xbf, 0x88, 0xea, 0x6c, 0x42, 0xfa, 0x03, 0x7a, + 0x29, 0xd2, 0xcf, 0xf1, 0xcb, 0xae, 0xea, 0xfb, 0x50, 0xf2, + 0xbd, 0x02, 0x4f, 0x2f, 0x4f, 0xba, 0x82, 0xa9, 0xde, 0x60, + 0x56, 0xd4, 0x07, 0x73, 0xdf, 0x12, 0x09, 0x73, 0x7b, 0x54, + 0x35, 0xc6, 0x28, 0x10, 0xb0, 0xbd, 0xc8, 0xe1, 0x8f, 0xb2, + 0x41, 0x02, 0x41, 0x00, 0xd8, 0xf9, 0x6c, 0x70, 0x56, 0x3c, + 0x74, 0x44, 0x53, 0x13, 0xed, 0x92, 0xab, 0xbc, 0x0c, 0x5c, + 0x66, 0x2c, 0xd7, 0xed, 0x10, 0x82, 0xe3, 0xe3, 0x2e, 0xda, + 0x4d, 0x3e, 0x1f, 0xc0, 0x50, 0xa8, 0xf2, 0xce, 0x77, 0xa9, + 0xae, 0xa2, 0x2d, 0x49, 0x6a, 0x6f, 0x01, 0xe3, 0xca, 0x57, + 0xf4, 0xcc, 0xb4, 0x3f, 0xd9, 0xc3, 0x58, 0x54, 0xe7, 0x62, + 0xfc, 0x40, 0xc8, 0xba, 0x18, 0x0d, 0xfe, 0x89, 0x02, 0x41, + 0x00, 0xd8, 0xa6, 0xaa, 0x4b, 0xcc, 0xcf, 0xc4, 0x47, 0x84, + 0x13, 0x39, 0x5b, 0x2e, 0xcb, 0xe0, 0x41, 0xd0, 0x2c, 0x96, + 0x58, 0x73, 0xab, 0xf6, 0x41, 0x0c, 0x7b, 0xbe, 0x60, 0xa1, + 0xcb, 0x00, 0x1a, 0xb0, 0x4b, 0xc1, 0xf5, 0x27, 0x43, 0x97, + 0x87, 0x30, 0x3c, 0x27, 0xa3, 0xe3, 0xf1, 0xa7, 0x45, 0x01, + 0xe2, 0x1c, 0x43, 0xe9, 0x48, 0x43, 0x76, 0x24, 0x4b, 0x2b, + 0xc7, 0x67, 0x3e, 0x4e, 0x19, 0x02, 0x40, 0x6a, 0x43, 0x96, + 0x31, 0x5a, 0x7a, 0xd7, 0x32, 0x93, 0x41, 0xa2, 0x4c, 0x00, + 0x21, 0xe4, 0x27, 0xe8, 0xbe, 0xb3, 0xad, 0xde, 0x35, 0x4c, + 0xa8, 0xfa, 0x4c, 0x5e, 0x22, 0x3b, 0xe8, 0xb3, 0x58, 0x5b, + 0x3a, 0x75, 0x6e, 0xbc, 0x21, 0x9f, 0x6e, 0x62, 0x5b, 0x25, + 0xa0, 0xcb, 0x7b, 0xd2, 0x5f, 0xe3, 0x33, 0x96, 0x52, 0x4e, + 0xd3, 0x9e, 0x53, 0x63, 0x59, 0xd3, 0x35, 0x19, 0x0c, 0xd9, + 0x89, 0x02, 0x41, 0x00, 0x8f, 0x8d, 0xb7, 0xaf, 0x6c, 0x31, + 0x8b, 0x0c, 0x1c, 0x1e, 0xa4, 0xd5, 0x9f, 0x67, 0x65, 0xdc, + 0x15, 0xf5, 0x45, 0x55, 0xac, 0xa7, 0x98, 0x0f, 0x38, 0x17, + 0x52, 0x69, 0x33, 0x2b, 0x90, 0x91, 0x1e, 0x99, 0xc4, 0x16, + 0x0e, 0x03, 0x42, 0x87, 0x48, 0x55, 0xc3, 0xaa, 0x5b, 0xe2, + 0x86, 0x84, 0x3a, 0x20, 0x39, 0xbc, 0x61, 0xfa, 0x09, 0x01, + 0x62, 0x41, 0x10, 0xec, 0x1a, 0xa3, 0xf5, 0x19, 0x02, 0x41, + 0x00, 0x98, 0x04, 0xc8, 0x8e, 0xd0, 0xfa, 0xe5, 0xab, 0x8a, + 0x1c, 0x4a, 0xc2, 0xf7, 0xd4, 0xad, 0x52, 0x51, 0x81, 0xa6, + 0x59, 0x62, 0x84, 0x16, 0x82, 0xf2, 0x5d, 0xd0, 0x5d, 0x4a, + 0xcf, 0x94, 0x2f, 0x13, 0x47, 0xd4, 0xc2, 0x7f, 0x89, 0x2e, + 0x40, 0xf5, 0xfc, 0xf8, 0x82, 0xc6, 0x53, 0xd4, 0x75, 0x32, + 0x47, 0x1d, 0xcf, 0xd1, 0xae, 0x35, 0x41, 0x7a, 0xdc, 0x10, + 0x0c, 0xc2, 0xd6, 0xe1, 0xd5 ), + DATA ( 0x30, 0x82, 0x02, 0x7f, 0x30, 0x82, 0x01, 0xe8, 0x02, 0x01, + 0x08, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, + 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x81, 0x88, 0x31, + 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, + 0x47, 0x42, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, + 0x08, 0x0c, 0x0e, 0x43, 0x61, 0x6d, 0x62, 0x72, 0x69, 0x64, + 0x67, 0x65, 0x73, 0x68, 0x69, 0x72, 0x65, 0x31, 0x12, 0x30, + 0x10, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0c, 0x09, 0x43, 0x61, + 0x6d, 0x62, 0x72, 0x69, 0x64, 0x67, 0x65, 0x31, 0x18, 0x30, + 0x16, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x0f, 0x46, 0x65, + 0x6e, 0x20, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x73, 0x20, + 0x4c, 0x74, 0x64, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, + 0x04, 0x0b, 0x0c, 0x08, 0x69, 0x70, 0x78, 0x65, 0x2e, 0x6f, + 0x72, 0x67, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x04, + 0x03, 0x0c, 0x16, 0x69, 0x50, 0x58, 0x45, 0x20, 0x73, 0x65, + 0x6c, 0x66, 0x2d, 0x74, 0x65, 0x73, 0x74, 0x20, 0x6c, 0x65, + 0x61, 0x66, 0x20, 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, 0x32, + 0x34, 0x30, 0x38, 0x32, 0x39, 0x32, 0x32, 0x31, 0x39, 0x35, + 0x38, 0x5a, 0x17, 0x0d, 0x32, 0x35, 0x30, 0x38, 0x32, 0x39, + 0x32, 0x32, 0x31, 0x39, 0x35, 0x38, 0x5a, 0x30, 0x81, 0x86, + 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x47, 0x42, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, + 0x04, 0x08, 0x0c, 0x0e, 0x43, 0x61, 0x6d, 0x62, 0x72, 0x69, + 0x64, 0x67, 0x65, 0x73, 0x68, 0x69, 0x72, 0x65, 0x31, 0x12, + 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0c, 0x09, 0x43, + 0x61, 0x6d, 0x62, 0x72, 0x69, 0x64, 0x67, 0x65, 0x31, 0x18, + 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x0f, 0x46, + 0x65, 0x6e, 0x20, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x73, + 0x20, 0x4c, 0x74, 0x64, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03, + 0x55, 0x04, 0x0b, 0x0c, 0x08, 0x69, 0x70, 0x78, 0x65, 0x2e, + 0x6f, 0x72, 0x67, 0x31, 0x1d, 0x30, 0x1b, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x0c, 0x14, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, + 0x2e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x69, 0x70, 0x78, 0x65, + 0x2e, 0x6f, 0x72, 0x67, 0x30, 0x81, 0x9f, 0x30, 0x0d, 0x06, + 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, + 0x05, 0x00, 0x03, 0x81, 0x8d, 0x00, 0x30, 0x81, 0x89, 0x02, + 0x81, 0x81, 0x00, 0xb7, 0x9f, 0xb5, 0x90, 0xfa, 0x47, 0x25, + 0xee, 0x3b, 0x04, 0x02, 0x4f, 0xd4, 0x1d, 0x62, 0x46, 0x9d, + 0xce, 0x79, 0x3a, 0x80, 0x3a, 0xc4, 0x06, 0x6a, 0x67, 0xd4, + 0x3a, 0x61, 0x71, 0xcd, 0xb3, 0xcc, 0x1b, 0xfc, 0x2f, 0x17, + 0xa8, 0xf2, 0x26, 0x9e, 0x54, 0xd3, 0x49, 0x81, 0x22, 0xa9, + 0x72, 0x4c, 0xe8, 0x92, 0xb7, 0x1e, 0x44, 0x8f, 0xa9, 0x4d, + 0x83, 0x0b, 0x89, 0x2a, 0xc7, 0xb3, 0xad, 0x54, 0x32, 0x76, + 0x62, 0x1e, 0xe5, 0xbe, 0xc1, 0xa8, 0x7a, 0x2b, 0xf0, 0xa9, + 0x9a, 0xfb, 0xb8, 0x18, 0x0c, 0x30, 0x5a, 0x13, 0x9c, 0x21, + 0x26, 0x96, 0x4f, 0x39, 0x98, 0x64, 0x41, 0x3b, 0x94, 0xc8, + 0xe3, 0xb7, 0x8c, 0x33, 0x9e, 0xd0, 0x71, 0xd0, 0x2f, 0xe3, + 0x7d, 0x2c, 0x57, 0x27, 0x42, 0x26, 0xd9, 0x2c, 0xb4, 0x55, + 0xd5, 0x66, 0xb7, 0xbf, 0x00, 0xa1, 0xcc, 0x61, 0x19, 0x99, + 0x61, 0x02, 0x03, 0x01, 0x00, 0x01, 0x30, 0x0d, 0x06, 0x09, + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, + 0x00, 0x03, 0x81, 0x81, 0x00, 0x22, 0x6e, 0x8b, 0x81, 0xc3, + 0x13, 0x89, 0x31, 0xcc, 0x6d, 0x44, 0xa5, 0x77, 0x31, 0x79, + 0xff, 0xea, 0x8a, 0x4e, 0xe6, 0xb6, 0x4a, 0xf0, 0x01, 0xd3, + 0x9f, 0xd7, 0x23, 0x14, 0x4c, 0xdd, 0xa3, 0xdf, 0xd6, 0x2b, + 0x2a, 0xc4, 0xba, 0xf7, 0xef, 0xfd, 0x78, 0xd5, 0xd7, 0xfd, + 0xd7, 0x77, 0x17, 0x20, 0x4f, 0xf3, 0x94, 0xd6, 0x74, 0xd5, + 0x09, 0x54, 0x16, 0x49, 0x6e, 0xd9, 0x41, 0xa7, 0x43, 0x77, + 0x7f, 0xef, 0xd3, 0xd7, 0xbb, 0x8b, 0xf0, 0x7d, 0x1f, 0x00, + 0x4a, 0xac, 0x18, 0xff, 0x20, 0x32, 0xd1, 0x1c, 0x13, 0xf2, + 0xe0, 0xd7, 0x70, 0xec, 0xb6, 0xf7, 0xa3, 0x42, 0xa1, 0x64, + 0x26, 0x30, 0x9f, 0x47, 0xd4, 0xfb, 0xfb, 0x06, 0xdb, 0x0b, + 0xb3, 0x27, 0xe6, 0x04, 0xe2, 0x94, 0x35, 0x8b, 0xa5, 0xfd, + 0x80, 0x1d, 0xa6, 0x72, 0x32, 0x30, 0x99, 0x6c, 0xbf, 0xd3, + 0x26, 0xa3, 0x8a ) ); + /** iPXE self-test root CA certificate */ static uint8_t root_crt_fingerprint[] = FINGERPRINT ( 0x71, 0x5d, 0x51, 0x37, 0x5e, 0x18, 0xb3, 0xbc, @@ -1345,26 +1643,48 @@ static time_t test_time = 1332374737ULL; /* Thu Mar 22 00:05:37 2012 */ static time_t test_expired = 1375573111ULL; /* Sat Aug 3 23:38:31 2013 */ /** - * Report signature parsing test result + * Report message parsing test result * - * @v sgn Test signature + * @v msg Test message * @v file Test code file * @v line Test code line */ -static void cms_signature_okx ( struct cms_test_signature *sgn, - const char *file, unsigned int line ) { +static void cms_message_okx ( struct cms_test_message *msg, + const char *file, unsigned int line ) { - okx ( cms_signature ( sgn->data, sgn->len, &sgn->sig ) == 0, + /* Check ability to parse message */ + okx ( cms_message ( &msg->image, &msg->cms ) == 0, file, line ); +} +#define cms_message_ok( msg ) \ + cms_message_okx ( msg, __FILE__, __LINE__ ) + +/** + * Report key pair parsing test result + * + * @v keypair Test key pair + * @v file Test code file + * @v line Test code line + */ +static void cms_keypair_okx ( struct cms_test_keypair *keypair, + const char *file, unsigned int line ) { + + /* Check ability to parse certificate */ + okx ( x509_certificate ( keypair->data, keypair->len, + &keypair->cert ) == 0, file, line ); + okx ( keypair->cert != NULL, file, line ); + + /* Check certificate can be identified by public key */ + okx ( x509_find_key ( NULL, &keypair->privkey ) == keypair->cert, file, line ); } -#define cms_signature_ok( sgn ) \ - cms_signature_okx ( sgn, __FILE__, __LINE__ ) +#define cms_keypair_ok( keypair ) \ + cms_keypair_okx ( keypair, __FILE__, __LINE__ ) /** * Report signature verification test result * - * @v sgn Test signature - * @v code Test signed code + * @v msg Test signature message + * @v img Test signed image * @v name Test verification name * @v time Test verification time * @v store Test certificate store @@ -1372,25 +1692,29 @@ static void cms_signature_okx ( struct cms_test_signature *sgn, * @v file Test code file * @v line Test code line */ -static void cms_verify_okx ( struct cms_test_signature *sgn, - struct cms_test_code *code, const char *name, +static void cms_verify_okx ( struct cms_test_message *msg, + struct cms_test_image *img, const char *name, time_t time, struct x509_chain *store, struct x509_root *root, const char *file, unsigned int line ) { - x509_invalidate_chain ( sgn->sig->certificates ); - okx ( cms_verify ( sgn->sig, virt_to_user ( code->data ), code->len, - name, time, store, root ) == 0, file, line ); + /* Invalidate any certificates from previous tests */ + x509_invalidate_chain ( msg->cms->certificates ); + + /* Check ability to verify signature */ + okx ( cms_verify ( msg->cms, &img->image, name, time, store, + root ) == 0, file, line ); + okx ( img->image.flags & IMAGE_TRUSTED, file, line ); } -#define cms_verify_ok( sgn, code, name, time, store, root ) \ - cms_verify_okx ( sgn, code, name, time, store, root, \ +#define cms_verify_ok( msg, img, name, time, store, root ) \ + cms_verify_okx ( msg, img, name, time, store, root, \ __FILE__, __LINE__ ) /** * Report signature verification failure test result * - * @v sgn Test signature - * @v code Test signed code + * @v msg Test signature message + * @v img Test signed image * @v name Test verification name * @v time Test verification time * @v store Test certificate store @@ -1398,31 +1722,69 @@ static void cms_verify_okx ( struct cms_test_signature *sgn, * @v file Test code file * @v line Test code line */ -static void cms_verify_fail_okx ( struct cms_test_signature *sgn, - struct cms_test_code *code, const char *name, +static void cms_verify_fail_okx ( struct cms_test_message *msg, + struct cms_test_image *img, const char *name, time_t time, struct x509_chain *store, struct x509_root *root, const char *file, unsigned int line ) { - x509_invalidate_chain ( sgn->sig->certificates ); - okx ( cms_verify ( sgn->sig, virt_to_user ( code->data ), code->len, - name, time, store, root ) != 0, file, line ); + /* Invalidate any certificates from previous tests */ + x509_invalidate_chain ( msg->cms->certificates ); + + /* Check inability to verify signature */ + okx ( cms_verify ( msg->cms, &img->image, name, time, store, + root ) != 0, file, line ); + okx ( ! ( img->image.flags & IMAGE_TRUSTED ), file, line ); } -#define cms_verify_fail_ok( sgn, code, name, time, store, root ) \ - cms_verify_fail_okx ( sgn, code, name, time, store, root, \ +#define cms_verify_fail_ok( msg, img, name, time, store, root ) \ + cms_verify_fail_okx ( msg, img, name, time, store, root, \ __FILE__, __LINE__ ) /** + * Report decryption test result + * + * @v img Encrypted data image + * @v envelope Envelope message + * @v keypair Key pair + * @v expected Expected plaintext image + * @v file Test code file + * @v line Test code line + */ +static void cms_decrypt_okx ( struct cms_test_image *img, + struct cms_test_message *envelope, + struct cms_test_keypair *keypair, + struct cms_test_image *expected, + const char *file, unsigned int line ) { + + /* Check ability to decrypt image */ + okx ( cms_decrypt ( envelope->cms, &img->image, NULL, + &keypair->privkey ) == 0, file, line ); + + /* Check decrypted image matches expected plaintext */ + okx ( img->image.len == expected->image.len, file, line ); + okx ( memcmp ( img->image.data, expected->image.data, + expected->image.len ) == 0, file, line ); +} +#define cms_decrypt_ok( data, envelope, keypair, expected ) \ + cms_decrypt_okx ( data, envelope, keypair, expected, \ + __FILE__, __LINE__ ) + +/** * Perform CMS self-tests * */ static void cms_test_exec ( void ) { - /* Check that all signatures can be parsed */ - cms_signature_ok ( &codesigned_sig ); - cms_signature_ok ( &brokenchain_sig ); - cms_signature_ok ( &genericsigned_sig ); - cms_signature_ok ( &nonsigned_sig ); + /* Check that all key pairs can be parsed */ + cms_keypair_ok ( &client_keypair ); + + /* Check that all messages can be parsed */ + cms_message_ok ( &codesigned_sig ); + cms_message_ok ( &brokenchain_sig ); + cms_message_ok ( &genericsigned_sig ); + cms_message_ok ( &nonsigned_sig ); + cms_message_ok ( &hidden_code_cbc_env ); + cms_message_ok ( &hidden_code_gcm_env ); /* Check good signature */ cms_verify_ok ( &codesigned_sig, &test_code, "codesign.test.ipxe.org", @@ -1459,14 +1821,27 @@ static void cms_test_exec ( void ) { cms_verify_fail_ok ( &codesigned_sig, &test_code, NULL, test_expired, &empty_store, &test_root ); + /* Check CBC decryption (with padding) */ + cms_decrypt_ok ( &hidden_code_cbc_dat, &hidden_code_cbc_env, + &client_keypair, &hidden_code ); + + /* Check GCM decryption (no padding) */ + cms_decrypt_ok ( &hidden_code_gcm_dat, &hidden_code_gcm_env, + &client_keypair, &hidden_code ); + /* Sanity check */ assert ( list_empty ( &empty_store.links ) ); - /* Drop signature references */ - cms_put ( nonsigned_sig.sig ); - cms_put ( genericsigned_sig.sig ); - cms_put ( brokenchain_sig.sig ); - cms_put ( codesigned_sig.sig ); + /* Drop message references */ + cms_put ( hidden_code_gcm_env.cms ); + cms_put ( hidden_code_cbc_env.cms ); + cms_put ( nonsigned_sig.cms ); + cms_put ( genericsigned_sig.cms ); + cms_put ( brokenchain_sig.cms ); + cms_put ( codesigned_sig.cms ); + + /* Drop certificate references */ + x509_put ( client_keypair.cert ); } /** CMS self-test */ diff --git a/src/tests/cpio_test.c b/src/tests/cpio_test.c new file mode 100644 index 000000000..24baf947b --- /dev/null +++ b/src/tests/cpio_test.c @@ -0,0 +1,280 @@ +/* + * Copyright (C) 2025 Michael Brown <mbrown@fensystems.co.uk>. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + * + * You can also choose to distribute this program under the terms of + * the Unmodified Binary Distribution Licence (as given in the file + * COPYING.UBDL), provided that you have satisfied its requirements. + */ + +FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); + +/** @file + * + * CPIO self-tests + * + */ + +/* Forcibly enable assertions */ +#undef NDEBUG + +#include <stdlib.h> +#include <string.h> +#include <ipxe/cpio.h> +#include <ipxe/test.h> + +/** A CPIO test */ +struct cpio_test { + /** Test name */ + const char *name; + /** Image length */ + size_t len; + /** Image command line */ + const char *cmdline; + /** Expected CPIO headers */ + const uint8_t *expected; + /** Length of expected CPIO headers */ + size_t expected_len; + /** Expected number of CPIO headers */ + unsigned int expected_count; +}; + +/** Define an expected CPIO header */ +#define CPIO_HEADER( mode, filesize, namesize, pname ) \ + "070701" "00000000" mode "00000000" "00000000" "00000001" \ + "00000000" filesize "00000000" "00000000" "00000000" "00000000" \ + namesize "00000000" pname + +/** Define a one-byte padding */ +#define PAD1 "\0" + +/** Define a two-byte padding */ +#define PAD2 "\0\0" + +/** Define a three-byte padding */ +#define PAD3 "\0\0\0" + +/** Define four-byte padding */ +#define PAD4 "\0\0\0\0" + +/** Define a CPIO test */ +#define CPIO_TEST( NAME, LEN, CMDLINE, COUNT, EXPECTED ) \ + static const uint8_t NAME ## _expected[] = EXPECTED; \ + static struct cpio_test NAME = { \ + .name = #NAME, \ + .len = LEN, \ + .cmdline = CMDLINE, \ + .expected = NAME ## _expected, \ + .expected_len = ( sizeof ( NAME ## _expected ) \ + - 1 /* NUL */ ), \ + .expected_count = COUNT, \ + }; + +/** + * Report a CPIO test result + * + * @v test CPIO test + * @v file Test code file + * @v line Test code line + */ +static void cpio_okx ( struct cpio_test *test, const char *file, + unsigned int line ) { + struct cpio_header cpio; + struct image *image; + uint8_t *data; + size_t len; + size_t cpio_len; + unsigned int i; + unsigned int j; + + DBGC ( test, "CPIO len %#zx cmdline \"%s\"\n", + test->len, test->cmdline ); + DBGC2_HDA ( test, 0, test->expected, test->expected_len ); + + /* Sanity check */ + okx ( ( test->expected_len % CPIO_ALIGN ) == 0, file, line ); + + /* Construct dummy image */ + image = alloc_image ( NULL ); + okx ( image != NULL, file, line ); + okx ( image_set_name ( image, test->name ) == 0, file, line ); + okx ( image_set_len ( image, test->len ) == 0, file, line ); + okx ( image_set_cmdline ( image, test->cmdline ) == 0, file, line ); + + /* Calculate length of CPIO headers */ + len = 0; + for ( i = 0 ; ( cpio_len = cpio_header ( image, i, &cpio ) ) ; i++ ) { + okx ( cpio_len >= sizeof ( cpio ), file, line ); + len += ( cpio_len + cpio_pad_len ( cpio_len ) ); + okx ( cpio_pad_len ( cpio_len ) > 0, file, line ); + okx ( ( len % CPIO_ALIGN ) == 0, file, line ); + } + okx ( i == test->expected_count, file, line ); + okx ( len == test->expected_len, file, line ); + + /* Allocate space for CPIO headers */ + data = zalloc ( len ); + okx ( data != NULL, file, line ); + + /* Construct CPIO headers */ + len = 0; + for ( i = 0 ; ( cpio_len = cpio_header ( image, i, &cpio ) ) ; i++ ) { + memcpy ( ( data + len ), &cpio, sizeof ( cpio ) ); + memcpy ( ( data + len + sizeof ( cpio ) ), cpio_name ( image ), + ( cpio_len - sizeof ( cpio ) ) ); + DBGC ( test, "CPIO hdr %d: ", i ); + for ( j = 0 ; j < cpio_len ; j++ ) { + if ( ( j <= sizeof ( cpio ) && ! ( ( j + 2 ) % 8 ) ) ) + DBGC ( test, " " ); + DBGC ( test, "%c", data[ len + j ] ); + } + DBGC ( test, "\n" ); + len += ( cpio_len + cpio_pad_len ( cpio_len ) ); + } + okx ( i == test->expected_count, file, line ); + okx ( len == test->expected_len, file, line ); + + /* Verify constructed CPIO headers */ + DBGC2_HDA ( test, 0, data, len ); + okx ( memcmp ( data, test->expected, test->expected_len ) == 0, + file, line ); + + /* Free constructed headers */ + free ( data ); + + /* Drop reference to dummy image */ + image_put ( image ); +} +#define cpio_ok( test ) cpio_okx ( test, __FILE__, __LINE__ ) + +/* Image with no command line */ +CPIO_TEST ( no_cmdline, 42, NULL, 0, "" ); + +/* Image with empty command line */ +CPIO_TEST ( empty_cmdline, 154, "", 0, "" ); + +/* All slashes */ +CPIO_TEST ( all_slashes, 64, "////", 0, "" ); + +/* Simple filename */ +CPIO_TEST ( simple, 0x69, "wimboot", 1, + CPIO_HEADER ( "000081a4", "00000069", "00000008", + "wimboot" PAD3 ) ); + +/* Initial slash */ +CPIO_TEST ( init_slash, 0x273, "/wimboot", 1, + CPIO_HEADER ( "000081a4", "00000273", "00000009", + "/wimboot" PAD2 ) ); + +/* Initial slashes */ +CPIO_TEST ( init_slashes, 0x94, "///initscript", 1, + CPIO_HEADER ( "000081a4", "00000094", "0000000e", + "///initscript" PAD1 ) ); + +/* Full path */ +CPIO_TEST ( path, 0x341, "/usr/share/oem/config.ign", 1, + CPIO_HEADER ( "000081a4", "00000341", "0000001a", + "/usr/share/oem/config.ign" PAD1 ) ); + +/* Full path, mkdir=0 */ +CPIO_TEST ( path_mkdir_0, 0x341, "/usr/share/oem/config.ign mkdir=0", 1, + CPIO_HEADER ( "000081a4", "00000341", "0000001a", + "/usr/share/oem/config.ign" PAD1 ) ); + +/* Full path, mkdir=1 */ +CPIO_TEST ( path_mkdir_1, 0x341, "/usr/share/oem/config.ign mkdir=1", 2, + CPIO_HEADER ( "000041ed", "00000000", "0000000f", + "/usr/share/oem" PAD4 ) + CPIO_HEADER ( "000081a4", "00000341", "0000001a", + "/usr/share/oem/config.ign" PAD1 ) ); + +/* Full path, mkdir=2 */ +CPIO_TEST ( path_mkdir_2, 0x341, "/usr/share/oem/config.ign mkdir=2", 3, + CPIO_HEADER ( "000041ed", "00000000", "0000000b", + "/usr/share" PAD4 ) + CPIO_HEADER ( "000041ed", "00000000", "0000000f", + "/usr/share/oem" PAD4 ) + CPIO_HEADER ( "000081a4", "00000341", "0000001a", + "/usr/share/oem/config.ign" PAD1 ) ); + +/* Full path, mkdir=-1 */ +CPIO_TEST ( path_mkdir_all, 0x341, "/usr/share/oem/config.ign mkdir=-1", 4, + CPIO_HEADER ( "000041ed", "00000000", "00000005", + "/usr" PAD2 ) + CPIO_HEADER ( "000041ed", "00000000", "0000000b", + "/usr/share" PAD4 ) + CPIO_HEADER ( "000041ed", "00000000", "0000000f", + "/usr/share/oem" PAD4 ) + CPIO_HEADER ( "000081a4", "00000341", "0000001a", + "/usr/share/oem/config.ign" PAD1 ) ); + +/* Simple directory */ +CPIO_TEST ( dir, 0, "/opt/", 1, + CPIO_HEADER ( "000041ed", "00000000", "00000005", + "/opt" PAD2 ) ); + +/* Directory tree */ +CPIO_TEST ( tree, 0, "/opt/oem/scripts/ mkdir=-1", 3, + CPIO_HEADER ( "000041ed", "00000000", "00000005", + "/opt" PAD2 ) + CPIO_HEADER ( "000041ed", "00000000", "00000009", + "/opt/oem" PAD2 ) + CPIO_HEADER ( "000041ed", "00000000", "00000011", + "/opt/oem/scripts" PAD2 ) ); + +/* Custom mode */ +CPIO_TEST ( mode, 39, "/sbin/init mode=755", 1, + CPIO_HEADER ( "000081ed", "00000027", "0000000b", + "/sbin/init" PAD4 ) ); + +/* Chaos */ +CPIO_TEST ( chaos, 73, "///etc//init.d///runthings mode=700 mkdir=99", 3, + CPIO_HEADER ( "000041ed", "00000000", "00000007", + "///etc" PAD4 ) + CPIO_HEADER ( "000041ed", "00000000", "0000000f", + "///etc//init.d" PAD4 ) + CPIO_HEADER ( "000081c0", "00000049", "0000001b", + "///etc//init.d///runthings" PAD4 ) ); + +/** + * Perform CPIO self-test + * + */ +static void cpio_test_exec ( void ) { + + cpio_ok ( &no_cmdline ); + cpio_ok ( &empty_cmdline ); + cpio_ok ( &all_slashes ); + cpio_ok ( &simple ); + cpio_ok ( &init_slash ); + cpio_ok ( &init_slashes ); + cpio_ok ( &path ); + cpio_ok ( &path_mkdir_0 ); + cpio_ok ( &path_mkdir_1 ); + cpio_ok ( &path_mkdir_2 ); + cpio_ok ( &path_mkdir_all ); + cpio_ok ( &dir ); + cpio_ok ( &tree ); + cpio_ok ( &mode ); + cpio_ok ( &chaos ); +} + +/** CPIO self-test */ +struct self_test cpio_test __self_test = { + .name = "cpio", + .exec = cpio_test_exec, +}; diff --git a/src/tests/deflate_test.c b/src/tests/deflate_test.c index 20ff5b9a2..f7086b45d 100644 --- a/src/tests/deflate_test.c +++ b/src/tests/deflate_test.c @@ -156,19 +156,18 @@ static void deflate_okx ( struct deflate *deflate, struct deflate_test *test, struct deflate_test_fragments *frags, const char *file, unsigned int line ) { - uint8_t data[ test->expected_len ]; - struct deflate_chunk in; - struct deflate_chunk out; - size_t frag_len = -1UL; - size_t offset = 0; + uint8_t buf[ test->expected_len ]; + const void *data = test->compressed; size_t remaining = test->compressed_len; + size_t frag_len = -1UL; + struct deflate_chunk out; unsigned int i; /* Initialise decompressor */ deflate_init ( deflate, test->format ); /* Initialise output chunk */ - deflate_chunk_init ( &out, virt_to_user ( data ), 0, sizeof ( data ) ); + deflate_chunk_init ( &out, buf, 0, sizeof ( buf ) ); /* Process input (in fragments, if applicable) */ for ( i = 0 ; i < ( sizeof ( frags->len ) / @@ -179,16 +178,15 @@ static void deflate_okx ( struct deflate *deflate, frag_len = frags->len[i]; if ( frag_len > remaining ) frag_len = remaining; - deflate_chunk_init ( &in, virt_to_user ( test->compressed ), - offset, ( offset + frag_len ) ); /* Decompress this fragment */ - okx ( deflate_inflate ( deflate, &in, &out ) == 0, file, line ); - okx ( in.len == ( offset + frag_len ), file, line ); - okx ( in.offset == in.len, file, line ); + okx ( deflate_inflate ( deflate, data, frag_len, + &out ) == 0, file, line ); + okx ( deflate->in == ( data + frag_len ), file, line ); + okx ( deflate->end == ( data + frag_len ), file, line ); /* Move to next fragment */ - offset = in.offset; + data += frag_len; remaining -= frag_len; if ( ! remaining ) break; @@ -199,9 +197,13 @@ static void deflate_okx ( struct deflate *deflate, /* Check decompression has terminated as expected */ okx ( deflate_finished ( deflate ), file, line ); - okx ( offset == test->compressed_len, file, line ); + okx ( deflate->in == ( test->compressed + test->compressed_len ), + file, line ); + okx ( deflate->end == ( test->compressed + test->compressed_len ), + file, line ); okx ( out.offset == test->expected_len, file, line ); - okx ( memcmp ( data, test->expected, test->expected_len ) == 0, + okx ( out.data == buf, file, line ); + okx ( memcmp ( out.data, test->expected, test->expected_len ) == 0, file, line ); } #define deflate_ok( deflate, test, frags ) \ diff --git a/src/tests/ecdsa_test.c b/src/tests/ecdsa_test.c new file mode 100644 index 000000000..0ea039b1f --- /dev/null +++ b/src/tests/ecdsa_test.c @@ -0,0 +1,274 @@ +/* + * Copyright (C) 2025 Michael Brown <mbrown@fensystems.co.uk>. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + * + * You can also choose to distribute this program under the terms of + * the Unmodified Binary Distribution Licence (as given in the file + * COPYING.UBDL), provided that you have satisfied its requirements. + */ + +FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); + +/** @file + * + * ECDSA self-tests + * + * These test vectors are generated using openssl's ecparam, pkey, + * pkcs8, and dgst tools. + */ + +/* Forcibly enable assertions */ +#undef NDEBUG + +#include <string.h> +#include <ipxe/crypto.h> +#include <ipxe/ecdsa.h> +#include <ipxe/sha256.h> +#include <ipxe/sha512.h> +#include <ipxe/test.h> +#include "pubkey_test.h" + +/** "Hello world" P-256 signature test (traditional private key) */ +PUBKEY_SIGN_TEST ( p256_hw_test, &ecdsa_algorithm, + PRIVATE ( 0x30, 0x77, 0x02, 0x01, 0x01, 0x04, 0x20, 0x5d, 0xc9, 0xbc, + 0x58, 0x82, 0x99, 0xaf, 0x56, 0x6a, 0x4a, 0x4d, 0xec, 0xce, + 0x9f, 0x6d, 0xfd, 0xb4, 0xfa, 0x5f, 0x8c, 0xd2, 0xfe, 0x5a, + 0x4b, 0x9b, 0x83, 0x0a, 0xe6, 0x86, 0x90, 0x13, 0x12, 0xa0, + 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, + 0x07, 0xa1, 0x44, 0x03, 0x42, 0x00, 0x04, 0x31, 0x20, 0x90, + 0xeb, 0xd1, 0x74, 0xc0, 0x88, 0x03, 0x97, 0x96, 0x67, 0x11, + 0xda, 0x74, 0xe9, 0x09, 0xd1, 0x64, 0x01, 0x26, 0x9b, 0x30, + 0x8c, 0x6a, 0xbe, 0xcf, 0x6f, 0x01, 0xd5, 0x86, 0xe2, 0xab, + 0x60, 0x8f, 0x5b, 0x60, 0x86, 0xc8, 0x2d, 0xee, 0xa7, 0x42, + 0x59, 0xd5, 0xdc, 0x3d, 0xb8, 0x13, 0x8f, 0x90, 0x26, 0xfc, + 0xf5, 0xce, 0xcb, 0xf9, 0x68, 0x91, 0x59, 0x87, 0xc6, 0x7d, + 0x2a ), + PUBLIC ( 0x30, 0x59, 0x30, 0x13, 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, + 0x3d, 0x02, 0x01, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, + 0x03, 0x01, 0x07, 0x03, 0x42, 0x00, 0x04, 0x31, 0x20, 0x90, + 0xeb, 0xd1, 0x74, 0xc0, 0x88, 0x03, 0x97, 0x96, 0x67, 0x11, + 0xda, 0x74, 0xe9, 0x09, 0xd1, 0x64, 0x01, 0x26, 0x9b, 0x30, + 0x8c, 0x6a, 0xbe, 0xcf, 0x6f, 0x01, 0xd5, 0x86, 0xe2, 0xab, + 0x60, 0x8f, 0x5b, 0x60, 0x86, 0xc8, 0x2d, 0xee, 0xa7, 0x42, + 0x59, 0xd5, 0xdc, 0x3d, 0xb8, 0x13, 0x8f, 0x90, 0x26, 0xfc, + 0xf5, 0xce, 0xcb, 0xf9, 0x68, 0x91, 0x59, 0x87, 0xc6, 0x7d, + 0x2a ), + PLAINTEXT ( 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x20, 0x77, 0x6f, 0x72, 0x6c, + 0x64, 0x0a ), + &sha256_algorithm, + SIGNATURE ( 0x30, 0x45, 0x02, 0x21, 0x00, 0xc4, 0xb5, 0xb9, 0x40, 0xf7, + 0x73, 0x9f, 0x77, 0x90, 0xa1, 0xa0, 0x0d, 0xc4, 0xd3, 0x1e, + 0x18, 0x08, 0xc0, 0xe9, 0xb1, 0xf5, 0x16, 0x71, 0xf0, 0x75, + 0x9f, 0xac, 0x5e, 0xeb, 0xca, 0x0d, 0x02, 0x02, 0x20, 0x32, + 0xb6, 0x77, 0x9e, 0x19, 0x1f, 0xde, 0x03, 0x1d, 0x8a, 0x29, + 0xe4, 0x97, 0xb9, 0x90, 0x1b, 0xff, 0xf3, 0x10, 0x8d, 0xc3, + 0x41, 0x4e, 0xc1, 0xef, 0x59, 0x37, 0xc3, 0xf7, 0xd5, 0xbe, + 0xb0 ) ); + +/** "Hello world" P-256 signature test (traditional private key, SHA-512) */ +PUBKEY_SIGN_TEST ( p256_hw_sha512_test, &ecdsa_algorithm, + PRIVATE ( 0x30, 0x77, 0x02, 0x01, 0x01, 0x04, 0x20, 0x5d, 0xc9, 0xbc, + 0x58, 0x82, 0x99, 0xaf, 0x56, 0x6a, 0x4a, 0x4d, 0xec, 0xce, + 0x9f, 0x6d, 0xfd, 0xb4, 0xfa, 0x5f, 0x8c, 0xd2, 0xfe, 0x5a, + 0x4b, 0x9b, 0x83, 0x0a, 0xe6, 0x86, 0x90, 0x13, 0x12, 0xa0, + 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, + 0x07, 0xa1, 0x44, 0x03, 0x42, 0x00, 0x04, 0x31, 0x20, 0x90, + 0xeb, 0xd1, 0x74, 0xc0, 0x88, 0x03, 0x97, 0x96, 0x67, 0x11, + 0xda, 0x74, 0xe9, 0x09, 0xd1, 0x64, 0x01, 0x26, 0x9b, 0x30, + 0x8c, 0x6a, 0xbe, 0xcf, 0x6f, 0x01, 0xd5, 0x86, 0xe2, 0xab, + 0x60, 0x8f, 0x5b, 0x60, 0x86, 0xc8, 0x2d, 0xee, 0xa7, 0x42, + 0x59, 0xd5, 0xdc, 0x3d, 0xb8, 0x13, 0x8f, 0x90, 0x26, 0xfc, + 0xf5, 0xce, 0xcb, 0xf9, 0x68, 0x91, 0x59, 0x87, 0xc6, 0x7d, + 0x2a ), + PUBLIC ( 0x30, 0x59, 0x30, 0x13, 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, + 0x3d, 0x02, 0x01, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, + 0x03, 0x01, 0x07, 0x03, 0x42, 0x00, 0x04, 0x31, 0x20, 0x90, + 0xeb, 0xd1, 0x74, 0xc0, 0x88, 0x03, 0x97, 0x96, 0x67, 0x11, + 0xda, 0x74, 0xe9, 0x09, 0xd1, 0x64, 0x01, 0x26, 0x9b, 0x30, + 0x8c, 0x6a, 0xbe, 0xcf, 0x6f, 0x01, 0xd5, 0x86, 0xe2, 0xab, + 0x60, 0x8f, 0x5b, 0x60, 0x86, 0xc8, 0x2d, 0xee, 0xa7, 0x42, + 0x59, 0xd5, 0xdc, 0x3d, 0xb8, 0x13, 0x8f, 0x90, 0x26, 0xfc, + 0xf5, 0xce, 0xcb, 0xf9, 0x68, 0x91, 0x59, 0x87, 0xc6, 0x7d, + 0x2a ), + PLAINTEXT ( 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x20, 0x77, 0x6f, 0x72, 0x6c, + 0x64, 0x0a ), + &sha512_algorithm, + SIGNATURE ( 0x30, 0x45, 0x02, 0x21, 0x00, 0x8b, 0x62, 0xf5, 0xda, 0x49, + 0x41, 0x85, 0xfe, 0xac, 0x1c, 0x6f, 0xf3, 0x43, 0xd9, 0xa6, + 0x03, 0x89, 0x5f, 0x1c, 0x5a, 0xd4, 0x8e, 0xdd, 0x4a, 0x58, + 0x48, 0x8f, 0x07, 0xb3, 0x85, 0xdb, 0x07, 0x02, 0x20, 0x7c, + 0x82, 0x77, 0x9c, 0x03, 0xd1, 0xd9, 0x2f, 0xf9, 0x1e, 0xcb, + 0x06, 0x29, 0x37, 0x0c, 0x96, 0x17, 0xc7, 0xc4, 0x3c, 0x0d, + 0x4a, 0x2e, 0x85, 0xe1, 0x13, 0x29, 0xc2, 0x46, 0x2d, 0x2f, + 0x85 ) ); + +/** Random message P-256 signature test (PKCS#8 private key) */ +PUBKEY_SIGN_TEST ( p256_random_test, &ecdsa_algorithm, + PRIVATE ( 0x30, 0x81, 0x87, 0x02, 0x01, 0x00, 0x30, 0x13, 0x06, 0x07, + 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01, 0x06, 0x08, 0x2a, + 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07, 0x04, 0x6d, 0x30, + 0x6b, 0x02, 0x01, 0x01, 0x04, 0x20, 0x5d, 0xc9, 0xbc, 0x58, + 0x82, 0x99, 0xaf, 0x56, 0x6a, 0x4a, 0x4d, 0xec, 0xce, 0x9f, + 0x6d, 0xfd, 0xb4, 0xfa, 0x5f, 0x8c, 0xd2, 0xfe, 0x5a, 0x4b, + 0x9b, 0x83, 0x0a, 0xe6, 0x86, 0x90, 0x13, 0x12, 0xa1, 0x44, + 0x03, 0x42, 0x00, 0x04, 0x31, 0x20, 0x90, 0xeb, 0xd1, 0x74, + 0xc0, 0x88, 0x03, 0x97, 0x96, 0x67, 0x11, 0xda, 0x74, 0xe9, + 0x09, 0xd1, 0x64, 0x01, 0x26, 0x9b, 0x30, 0x8c, 0x6a, 0xbe, + 0xcf, 0x6f, 0x01, 0xd5, 0x86, 0xe2, 0xab, 0x60, 0x8f, 0x5b, + 0x60, 0x86, 0xc8, 0x2d, 0xee, 0xa7, 0x42, 0x59, 0xd5, 0xdc, + 0x3d, 0xb8, 0x13, 0x8f, 0x90, 0x26, 0xfc, 0xf5, 0xce, 0xcb, + 0xf9, 0x68, 0x91, 0x59, 0x87, 0xc6, 0x7d, 0x2a ), + PUBLIC ( 0x30, 0x59, 0x30, 0x13, 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, + 0x3d, 0x02, 0x01, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, + 0x03, 0x01, 0x07, 0x03, 0x42, 0x00, 0x04, 0x31, 0x20, 0x90, + 0xeb, 0xd1, 0x74, 0xc0, 0x88, 0x03, 0x97, 0x96, 0x67, 0x11, + 0xda, 0x74, 0xe9, 0x09, 0xd1, 0x64, 0x01, 0x26, 0x9b, 0x30, + 0x8c, 0x6a, 0xbe, 0xcf, 0x6f, 0x01, 0xd5, 0x86, 0xe2, 0xab, + 0x60, 0x8f, 0x5b, 0x60, 0x86, 0xc8, 0x2d, 0xee, 0xa7, 0x42, + 0x59, 0xd5, 0xdc, 0x3d, 0xb8, 0x13, 0x8f, 0x90, 0x26, 0xfc, + 0xf5, 0xce, 0xcb, 0xf9, 0x68, 0x91, 0x59, 0x87, 0xc6, 0x7d, + 0x2a ), + PLAINTEXT ( 0xe0, 0xf0, 0x1b, 0xd1, 0x95, 0xe0, 0x4b, 0xd1, 0xf7, 0x4a, + 0x18, 0xca, 0x60, 0x02, 0x29, 0xc1, 0x58, 0x03, 0xf8, 0xc2, + 0x3c, 0x0f, 0x86, 0x55, 0xc5, 0x22, 0x88, 0x7e, 0x1f, 0x6c, + 0x4e, 0x14, 0xb5, 0x7e, 0x52, 0x02, 0x40, 0xb2, 0x70, 0xa6, + 0x60, 0xef, 0xcb, 0xab, 0xbd, 0x9d, 0xbe, 0x88, 0x41, 0x3f, + 0x0f, 0x44, 0x24, 0xdf, 0x86, 0x1c, 0x41, 0x39, 0x38, 0xf9, + 0x7e, 0x26, 0xcb, 0x1e, 0x31, 0xa6, 0x4c, 0x38, 0x3f, 0x55, + 0xb6, 0xbe, 0x8a, 0xc8, 0xbd, 0xa8, 0x96, 0xef, 0x68, 0xf8, + 0x4e, 0x28, 0xd2, 0x4d, 0x31, 0x02, 0xb8, 0x4c, 0xb6, 0xd2, + 0x34, 0x1d, 0x95, 0xfa, 0x37, 0xfe, 0x29, 0x1f, 0xe3, 0x06, + 0x19, 0xe7, 0x21, 0x16, 0x3d, 0xa0, 0xdb, 0xb6, 0x9b, 0x5b, + 0x61, 0x28, 0x6f, 0x32, 0xe1, 0x5e, 0x6e, 0xe1, 0x11, 0xb3, + 0x28, 0x82, 0xf1, 0xf4, 0x75, 0x1f, 0x0d, 0x7c, 0x0d, 0x8f, + 0x43, 0x55, 0xc9, 0xad, 0x9d, 0x8a, 0xd4, 0xf9, 0xb4, 0xd5, + 0x9a, 0xda, 0xd7, 0xe3, 0x15, 0xcb, 0x09, 0x2c, 0x2d, 0xc4, + 0x9d, 0x9c, 0x34, 0xe1, 0x84, 0x1c, 0xbd, 0x38, 0x3b, 0x0e, + 0xa3, 0xfd, 0x78, 0x29, 0x79, 0xa9, 0x73, 0x36, 0x8f, 0xab, + 0xef, 0xb3, 0x4e, 0x93, 0xc8, 0x18, 0xba, 0x3a, 0x3d, 0x78, + 0x0f, 0x47, 0xa4, 0x0b, 0x87, 0xfd, 0x00, 0x11, 0x34, 0x41, + 0x6c, 0x01, 0x4e, 0xdd, 0x77, 0x81, 0x21, 0x54, 0x64, 0x60, + 0xa1, 0xe0, 0xc9, 0x4b, 0xc6, 0xc6, 0x07, 0x52, 0xa2, 0xba, + 0x51, 0xc9, 0xa0, 0xa8, 0xf6, 0xa4, 0xdf, 0x37, 0x80, 0xc5, + 0x03, 0x1d, 0x9c, 0x85, 0xf9, 0x93, 0x4d, 0x1b, 0xec, 0x1c, + 0x1f, 0xab, 0xb2, 0xfa, 0x0c, 0xc5, 0x59, 0x2e, 0xf7, 0x01, + 0xc6, 0x3b, 0x39, 0x0e, 0x90, 0x92, 0x42, 0x76, 0x80, 0xfe, + 0x67, 0x05, 0xdd, 0x80, 0xf4, 0x06 ), + &sha256_algorithm, + SIGNATURE ( 0x30, 0x44, 0x02, 0x20, 0x12, 0x9c, 0x69, 0xb2, 0x61, 0x49, + 0x95, 0x0e, 0xab, 0x3b, 0x8f, 0x15, 0x31, 0x97, 0x30, 0x73, + 0x68, 0xe1, 0xcb, 0x32, 0x45, 0xe7, 0x9c, 0x8f, 0x50, 0xa0, + 0x84, 0x89, 0x16, 0xf8, 0x59, 0xe9, 0x02, 0x20, 0x7f, 0x46, + 0x97, 0xf1, 0x99, 0x45, 0x09, 0x0f, 0x80, 0xe1, 0xf3, 0xfc, + 0x62, 0x6b, 0x35, 0xb1, 0x4c, 0xdb, 0x48, 0x0b, 0xff, 0x48, + 0xae, 0x3a, 0x5b, 0x20, 0x48, 0x31, 0x91, 0x88, 0xba, + 0xde ) ); + +/** Random message P-384 signature test (PKCS#8 private key) */ +PUBKEY_SIGN_TEST ( p384_random_test, &ecdsa_algorithm, + PRIVATE ( 0x30, 0x81, 0xb6, 0x02, 0x01, 0x00, 0x30, 0x10, 0x06, 0x07, + 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01, 0x06, 0x05, 0x2b, + 0x81, 0x04, 0x00, 0x22, 0x04, 0x81, 0x9e, 0x30, 0x81, 0x9b, + 0x02, 0x01, 0x01, 0x04, 0x30, 0x5f, 0xc5, 0x6a, 0x6e, 0xf2, + 0x91, 0xf2, 0x1e, 0xa9, 0x80, 0xd3, 0xfd, 0xd3, 0x3a, 0x0b, + 0x6b, 0xd0, 0x8c, 0xdb, 0x4a, 0xd9, 0x72, 0x6d, 0x56, 0x11, + 0x43, 0x10, 0x64, 0x45, 0x20, 0x6e, 0x3a, 0x77, 0x99, 0x55, + 0x72, 0x86, 0x30, 0xd4, 0x69, 0xd6, 0x10, 0x2d, 0x2d, 0x46, + 0x72, 0x1f, 0x3e, 0xa1, 0x64, 0x03, 0x62, 0x00, 0x04, 0x6a, + 0xb2, 0x1a, 0x29, 0x54, 0x71, 0x27, 0x3c, 0x02, 0x3e, 0x3b, + 0x4c, 0x0e, 0x69, 0x4f, 0xe3, 0xdf, 0x8d, 0x02, 0x76, 0x7c, + 0x12, 0x2e, 0x31, 0xe7, 0x8b, 0xc8, 0x09, 0x1e, 0x0a, 0x5d, + 0x98, 0x0a, 0x3c, 0x43, 0xc6, 0xd4, 0x95, 0x53, 0xc0, 0x53, + 0x91, 0xdd, 0x70, 0x03, 0x77, 0xe7, 0xe8, 0xe9, 0x04, 0x46, + 0x7e, 0x9a, 0x8f, 0x0b, 0x21, 0x30, 0x06, 0x80, 0xa1, 0xc1, + 0xff, 0x20, 0x91, 0x68, 0x1f, 0x84, 0x01, 0x52, 0x28, 0xb8, + 0x18, 0xb0, 0xcc, 0x33, 0x9c, 0x44, 0x98, 0xa3, 0x59, 0x92, + 0x36, 0xe3, 0x46, 0x72, 0xa8, 0x86, 0xec, 0x69, 0x24, 0x29, + 0x29, 0xc0, 0xca, 0x2b, 0x40 ), + PUBLIC ( 0x30, 0x76, 0x30, 0x10, 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, + 0x3d, 0x02, 0x01, 0x06, 0x05, 0x2b, 0x81, 0x04, 0x00, 0x22, + 0x03, 0x62, 0x00, 0x04, 0x6a, 0xb2, 0x1a, 0x29, 0x54, 0x71, + 0x27, 0x3c, 0x02, 0x3e, 0x3b, 0x4c, 0x0e, 0x69, 0x4f, 0xe3, + 0xdf, 0x8d, 0x02, 0x76, 0x7c, 0x12, 0x2e, 0x31, 0xe7, 0x8b, + 0xc8, 0x09, 0x1e, 0x0a, 0x5d, 0x98, 0x0a, 0x3c, 0x43, 0xc6, + 0xd4, 0x95, 0x53, 0xc0, 0x53, 0x91, 0xdd, 0x70, 0x03, 0x77, + 0xe7, 0xe8, 0xe9, 0x04, 0x46, 0x7e, 0x9a, 0x8f, 0x0b, 0x21, + 0x30, 0x06, 0x80, 0xa1, 0xc1, 0xff, 0x20, 0x91, 0x68, 0x1f, + 0x84, 0x01, 0x52, 0x28, 0xb8, 0x18, 0xb0, 0xcc, 0x33, 0x9c, + 0x44, 0x98, 0xa3, 0x59, 0x92, 0x36, 0xe3, 0x46, 0x72, 0xa8, + 0x86, 0xec, 0x69, 0x24, 0x29, 0x29, 0xc0, 0xca, 0x2b, 0x40 ), + PLAINTEXT ( 0xe0, 0xf0, 0x1b, 0xd1, 0x95, 0xe0, 0x4b, 0xd1, 0xf7, 0x4a, + 0x18, 0xca, 0x60, 0x02, 0x29, 0xc1, 0x58, 0x03, 0xf8, 0xc2, + 0x3c, 0x0f, 0x86, 0x55, 0xc5, 0x22, 0x88, 0x7e, 0x1f, 0x6c, + 0x4e, 0x14, 0xb5, 0x7e, 0x52, 0x02, 0x40, 0xb2, 0x70, 0xa6, + 0x60, 0xef, 0xcb, 0xab, 0xbd, 0x9d, 0xbe, 0x88, 0x41, 0x3f, + 0x0f, 0x44, 0x24, 0xdf, 0x86, 0x1c, 0x41, 0x39, 0x38, 0xf9, + 0x7e, 0x26, 0xcb, 0x1e, 0x31, 0xa6, 0x4c, 0x38, 0x3f, 0x55, + 0xb6, 0xbe, 0x8a, 0xc8, 0xbd, 0xa8, 0x96, 0xef, 0x68, 0xf8, + 0x4e, 0x28, 0xd2, 0x4d, 0x31, 0x02, 0xb8, 0x4c, 0xb6, 0xd2, + 0x34, 0x1d, 0x95, 0xfa, 0x37, 0xfe, 0x29, 0x1f, 0xe3, 0x06, + 0x19, 0xe7, 0x21, 0x16, 0x3d, 0xa0, 0xdb, 0xb6, 0x9b, 0x5b, + 0x61, 0x28, 0x6f, 0x32, 0xe1, 0x5e, 0x6e, 0xe1, 0x11, 0xb3, + 0x28, 0x82, 0xf1, 0xf4, 0x75, 0x1f, 0x0d, 0x7c, 0x0d, 0x8f, + 0x43, 0x55, 0xc9, 0xad, 0x9d, 0x8a, 0xd4, 0xf9, 0xb4, 0xd5, + 0x9a, 0xda, 0xd7, 0xe3, 0x15, 0xcb, 0x09, 0x2c, 0x2d, 0xc4, + 0x9d, 0x9c, 0x34, 0xe1, 0x84, 0x1c, 0xbd, 0x38, 0x3b, 0x0e, + 0xa3, 0xfd, 0x78, 0x29, 0x79, 0xa9, 0x73, 0x36, 0x8f, 0xab, + 0xef, 0xb3, 0x4e, 0x93, 0xc8, 0x18, 0xba, 0x3a, 0x3d, 0x78, + 0x0f, 0x47, 0xa4, 0x0b, 0x87, 0xfd, 0x00, 0x11, 0x34, 0x41, + 0x6c, 0x01, 0x4e, 0xdd, 0x77, 0x81, 0x21, 0x54, 0x64, 0x60, + 0xa1, 0xe0, 0xc9, 0x4b, 0xc6, 0xc6, 0x07, 0x52, 0xa2, 0xba, + 0x51, 0xc9, 0xa0, 0xa8, 0xf6, 0xa4, 0xdf, 0x37, 0x80, 0xc5, + 0x03, 0x1d, 0x9c, 0x85, 0xf9, 0x93, 0x4d, 0x1b, 0xec, 0x1c, + 0x1f, 0xab, 0xb2, 0xfa, 0x0c, 0xc5, 0x59, 0x2e, 0xf7, 0x01, + 0xc6, 0x3b, 0x39, 0x0e, 0x90, 0x92, 0x42, 0x76, 0x80, 0xfe, + 0x67, 0x05, 0xdd, 0x80, 0xf4, 0x06 ), + &sha512_algorithm, + SIGNATURE ( 0x30, 0x64, 0x02, 0x30, 0x17, 0xa4, 0x1f, 0x5d, 0xb7, 0x6d, + 0x85, 0xd0, 0x1f, 0xf1, 0x28, 0x5c, 0x45, 0x27, 0x15, 0x30, + 0x9c, 0xb5, 0xe3, 0x36, 0x70, 0xf3, 0x82, 0xa6, 0x1c, 0x4a, + 0xb7, 0x87, 0xc7, 0x86, 0xae, 0x5d, 0x99, 0xba, 0xa9, 0x9a, + 0x2b, 0x25, 0x0a, 0xd2, 0x25, 0x1d, 0xe9, 0x78, 0xff, 0x2d, + 0x8d, 0xd6, 0x02, 0x30, 0x55, 0x95, 0x5d, 0x4d, 0x74, 0x3d, + 0xd1, 0xae, 0xf0, 0x6d, 0x6a, 0x77, 0x40, 0xa6, 0x57, 0xb2, + 0xb1, 0xee, 0xef, 0xd5, 0xcf, 0xeb, 0xa8, 0x82, 0x22, 0x1a, + 0xaf, 0x1e, 0xbc, 0x51, 0x59, 0xb7, 0x66, 0xbb, 0x83, 0x38, + 0x8b, 0x28, 0xa7, 0x84, 0x4e, 0x5c, 0x0a, 0x07, 0x56, 0x75, + 0x01, 0x8a ) ); + +/** + * Perform ECDSA self-tests + * + */ +static void ecdsa_test_exec ( void ) { + + pubkey_sign_ok ( &p256_hw_test ); + pubkey_sign_ok ( &p256_hw_sha512_test ); + pubkey_sign_ok ( &p256_random_test ); + pubkey_sign_ok ( &p384_random_test ); +} + +/** ECDSA self-test */ +struct self_test ecdsa_test __self_test = { + .name = "ecdsa", + .exec = ecdsa_test_exec, +}; + +/* Drag in required ASN.1 OID-identified algorithms */ +REQUIRING_SYMBOL ( ecdsa_test ); +REQUIRE_OBJECT ( oid_p256 ); +REQUIRE_OBJECT ( oid_p384 ); diff --git a/src/tests/editstring_test.c b/src/tests/editstring_test.c new file mode 100644 index 000000000..72da33a77 --- /dev/null +++ b/src/tests/editstring_test.c @@ -0,0 +1,198 @@ +/* + * Copyright (C) 2024 Michael Brown <mbrown@fensystems.co.uk>. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + * + * You can also choose to distribute this program under the terms of + * the Unmodified Binary Distribution Licence (as given in the file + * COPYING.UBDL), provided that you have satisfied its requirements. + */ + +FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); + +/** @file + * + * Editable string tests + * + */ + +/* Forcibly enable assertions */ +#undef NDEBUG + +#include <stdlib.h> +#include <string.h> +#include <ctype.h> +#include <ipxe/keys.h> +#include <ipxe/editstring.h> +#include <ipxe/test.h> + +/** An editable string test */ +struct editstring_test { + /** Initial string, or NULL */ + const char *start; + /** Key sequence */ + const int *keys; + /** Length of key sequence */ + unsigned int count; + /** Expected result */ + const char *expected; +}; + +/** Define an inline key sequence */ +#define KEYS(...) { __VA_ARGS__ } + +/** Define an editable string test */ +#define EDITSTRING_TEST( name, START, EXPECTED, KEYS ) \ + static const int name ## _keys[] = KEYS; \ + static struct editstring_test name = { \ + .start = START, \ + .keys = name ## _keys, \ + .count = ( sizeof ( name ## _keys ) / \ + sizeof ( name ## _keys[0] ) ), \ + .expected = EXPECTED, \ + }; + +/* Simple typing */ +EDITSTRING_TEST ( simple, "", "hello world!", + KEYS ( 'h', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', + 'd', '!' ) ); + +/* Simple typing from a NULL starting value */ +EDITSTRING_TEST ( simple_null, NULL, "hi there", + KEYS ( 'h', 'i', ' ', 't', 'h', 'e', 'r', 'e' ) ); + +/* Insertion */ +EDITSTRING_TEST ( insert, "in middle", "in the middle", + KEYS ( KEY_LEFT, KEY_LEFT, KEY_LEFT, KEY_LEFT, KEY_LEFT, + KEY_LEFT, 't', 'h', 'e', ' ' ) ); + +/* Backspace at end */ +EDITSTRING_TEST ( backspace_end, "byebye", "bye", + KEYS ( KEY_BACKSPACE, KEY_BACKSPACE, KEY_BACKSPACE ) ); + +/* Backspace of whole string */ +EDITSTRING_TEST ( backspace_all, "abc", "", + KEYS ( KEY_BACKSPACE, KEY_BACKSPACE, KEY_BACKSPACE ) ); + +/* Backspace of empty string */ +EDITSTRING_TEST ( backspace_empty, NULL, "", KEYS ( KEY_BACKSPACE ) ); + +/* Backspace beyond start of string */ +EDITSTRING_TEST ( backspace_beyond, "too far", "", + KEYS ( KEY_BACKSPACE, KEY_BACKSPACE, KEY_BACKSPACE, + KEY_BACKSPACE, KEY_BACKSPACE, KEY_BACKSPACE, + KEY_BACKSPACE, KEY_BACKSPACE, KEY_BACKSPACE ) ); + +/* Deletion of character at cursor via DEL */ +EDITSTRING_TEST ( delete_dc, "go away", "goaway", + KEYS ( KEY_HOME, KEY_RIGHT, KEY_RIGHT, KEY_DC ) ); + +/* Deletion of character at cursor via Ctrl-D */ +EDITSTRING_TEST ( delete_ctrl_d, "not here", "nohere", + KEYS ( KEY_LEFT, KEY_LEFT, KEY_LEFT, KEY_LEFT, KEY_LEFT, + KEY_LEFT, CTRL_D, CTRL_D ) ); + +/* Deletion of word at end of string */ +EDITSTRING_TEST ( word_end, "remove these two words", "remove these ", + KEYS ( CTRL_W, CTRL_W ) ); + +/* Deletion of word at start of string */ +EDITSTRING_TEST ( word_start, "no word", "word", + KEYS ( CTRL_A, KEY_RIGHT, KEY_RIGHT, KEY_RIGHT, CTRL_W ) ); + +/* Deletion of word mid-string */ +EDITSTRING_TEST ( word_mid, "delete this word", "delete word", + KEYS ( KEY_LEFT, KEY_LEFT, KEY_LEFT, KEY_LEFT, CTRL_W ) ); + +/* Deletion to start of line */ +EDITSTRING_TEST ( sol, "everything must go", "go", + KEYS ( KEY_LEFT, KEY_LEFT, CTRL_U ) ); + +/* Delete to end of line */ +EDITSTRING_TEST ( eol, "all is lost", "all", + KEYS ( KEY_HOME, KEY_RIGHT, KEY_RIGHT, KEY_RIGHT, CTRL_K ) ); + +/** + * Report an editable string test result + * + * @v test Editable string test + * @v file Test code file + * @v line Test code line + */ +static void editstring_okx ( struct editstring_test *test, const char *file, + unsigned int line ) { + struct edit_string string; + unsigned int i; + char *actual; + int key; + + /* Initialise editable string */ + memset ( &string, 0, sizeof ( string ) ); + actual = NULL; + init_editstring ( &string, &actual ); + + /* Set initial string content */ + okx ( replace_string ( &string, test->start ) == 0, file, line ); + okx ( actual != NULL, file, line ); + okx ( string.cursor == ( test->start ? strlen ( test->start ) : 0 ), + file, line ); + DBGC ( test, "Initial string: \"%s\"\n", actual ); + + /* Inject keypresses */ + for ( i = 0 ; i < test->count ; i++ ) { + key = test->keys[i]; + okx ( edit_string ( &string, key ) == 0, file, line ); + okx ( actual != NULL, file, line ); + okx ( string.cursor <= strlen ( actual ), file, line ); + DBGC ( test, "After key %#02x (%c): \"%s\"\n", + key, ( isprint ( key ) ? key : '.' ), actual ); + } + + /* Verify result string */ + okx ( strcmp ( actual, test->expected ) == 0, file, line ); + + /* Free result string */ + free ( actual ); +} +#define editstring_ok( test ) editstring_okx ( test, __FILE__, __LINE__ ) + +/** + * Perform editable string self-tests + * + */ +static void editstring_test_exec ( void ) { + + editstring_ok ( &simple ); + editstring_ok ( &simple_null ); + editstring_ok ( &insert ); + editstring_ok ( &backspace_end ); + editstring_ok ( &backspace_all ); + editstring_ok ( &backspace_empty ); + editstring_ok ( &backspace_beyond ); + editstring_ok ( &delete_dc ); + editstring_ok ( &delete_ctrl_d ); + editstring_ok ( &word_end ); + editstring_ok ( &word_start ); + editstring_ok ( &word_mid ); + editstring_ok ( &sol ); + editstring_ok ( &eol ); +} + +/** Editable string self-test */ +struct self_test editstring_test __self_test = { + .name = "editstring", + .exec = editstring_test_exec, +}; diff --git a/src/tests/efi_siglist_test.c b/src/tests/efi_siglist_test.c new file mode 100644 index 000000000..12d1ec6ac --- /dev/null +++ b/src/tests/efi_siglist_test.c @@ -0,0 +1,167 @@ +/* + * Copyright (C) 2025 Michael Brown <mbrown@fensystems.co.uk>. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + * + * You can also choose to distribute this program under the terms of + * the Unmodified Binary Distribution Licence (as given in the file + * COPYING.UBDL), provided that you have satisfied its requirements. + */ + +FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); + +/** @file + * + * EFI signature list self-tests + * + */ + +/* Forcibly enable assertions */ +#undef NDEBUG + +#include <string.h> +#include <assert.h> +#include <ipxe/test.h> +#include <ipxe/efi/efi_siglist.h> +#include "asn1_test.h" + +/** Define inline data */ +#define DATA(...) { __VA_ARGS__ } + +/** Define inline expected digest */ +#define DIGEST(...) { { __VA_ARGS__ } } + +/** Two certificates, one PEM, one DER, created by efisecdb */ +ASN1 ( efisecdb, &efisig_image_type, + DATA ( 0xa1, 0x59, 0xc0, 0xa5, 0xe4, 0x94, 0xa7, 0x4a, 0x87, 0xb5, + 0xab, 0x15, 0x5c, 0x2b, 0xf0, 0x72, 0x94, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x78, 0x01, 0x00, 0x00, 0xaf, 0x1e, + 0xbb, 0xc0, 0x33, 0x74, 0xa2, 0x4c, 0x93, 0xf2, 0xe9, 0x74, + 0x1b, 0x90, 0x98, 0x6c, 0x30, 0x82, 0x01, 0x64, 0x30, 0x82, + 0x01, 0x0e, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x01, 0x01, + 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, + 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x10, 0x31, 0x0e, 0x30, + 0x0c, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x05, 0x74, 0x65, + 0x73, 0x74, 0x32, 0x30, 0x1e, 0x17, 0x0d, 0x32, 0x35, 0x30, + 0x33, 0x31, 0x31, 0x31, 0x31, 0x31, 0x37, 0x32, 0x36, 0x5a, + 0x17, 0x0d, 0x32, 0x35, 0x30, 0x34, 0x31, 0x30, 0x31, 0x31, + 0x31, 0x37, 0x32, 0x36, 0x5a, 0x30, 0x10, 0x31, 0x0e, 0x30, + 0x0c, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x05, 0x74, 0x65, + 0x73, 0x74, 0x32, 0x30, 0x5c, 0x30, 0x0d, 0x06, 0x09, 0x2a, + 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, + 0x03, 0x4b, 0x00, 0x30, 0x48, 0x02, 0x41, 0x00, 0xc6, 0x75, + 0x2e, 0xc8, 0x09, 0x37, 0x14, 0xd3, 0xc0, 0xa5, 0x88, 0x3e, + 0x0d, 0xf9, 0x6f, 0x9f, 0xf2, 0xab, 0x3a, 0xe4, 0x6c, 0x0e, + 0x2b, 0x78, 0x3c, 0xe9, 0x1a, 0x52, 0x66, 0xbc, 0x7b, 0x7f, + 0xbe, 0xaa, 0xcd, 0x23, 0x68, 0x76, 0x26, 0x95, 0x45, 0x42, + 0xb5, 0xc6, 0x16, 0x2e, 0x3b, 0x33, 0x9d, 0x82, 0x6e, 0x6a, + 0xcf, 0xa5, 0x72, 0x71, 0x40, 0xff, 0xdc, 0x1d, 0x77, 0xe6, + 0x6f, 0x87, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x53, 0x30, + 0x51, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, + 0x04, 0x14, 0x1c, 0x11, 0x40, 0xcc, 0x63, 0xab, 0xad, 0x6a, + 0xa8, 0x83, 0x17, 0xbb, 0xc5, 0xc6, 0x94, 0x29, 0xe1, 0xad, + 0x4e, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, + 0x18, 0x30, 0x16, 0x80, 0x14, 0x1c, 0x11, 0x40, 0xcc, 0x63, + 0xab, 0xad, 0x6a, 0xa8, 0x83, 0x17, 0xbb, 0xc5, 0xc6, 0x94, + 0x29, 0xe1, 0xad, 0x4e, 0x21, 0x30, 0x0f, 0x06, 0x03, 0x55, + 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x05, 0x30, 0x03, 0x01, + 0x01, 0xff, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, + 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x41, 0x00, + 0x57, 0xa3, 0x3a, 0x9c, 0x83, 0xae, 0x94, 0x4c, 0xcd, 0x06, + 0x86, 0x9b, 0x25, 0x70, 0x87, 0x61, 0xfe, 0xbf, 0xb4, 0xa6, + 0x52, 0x0b, 0x37, 0x37, 0x85, 0xbb, 0xea, 0x79, 0x2b, 0x0b, + 0xc4, 0x29, 0x03, 0x8d, 0xa0, 0x26, 0xc2, 0xb4, 0x25, 0x1c, + 0x87, 0x08, 0xcb, 0x94, 0xee, 0x61, 0x48, 0xa4, 0xe1, 0x77, + 0xa6, 0x24, 0x2d, 0x15, 0x1b, 0x15, 0x62, 0x6a, 0x0f, 0x28, + 0x7c, 0xcc, 0xa6, 0xaf, 0xa1, 0x59, 0xc0, 0xa5, 0xe4, 0x94, + 0xa7, 0x4a, 0x87, 0xb5, 0xab, 0x15, 0x5c, 0x2b, 0xf0, 0x72, + 0x4a, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2e, 0x02, + 0x00, 0x00, 0xaf, 0x1e, 0xbb, 0xc0, 0x33, 0x74, 0xa2, 0x4c, + 0x93, 0xf2, 0xe9, 0x74, 0x1b, 0x90, 0x98, 0x6c, 0x2d, 0x2d, + 0x2d, 0x2d, 0x2d, 0x42, 0x45, 0x47, 0x49, 0x4e, 0x20, 0x43, + 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, + 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x4d, 0x49, 0x49, 0x42, + 0x5a, 0x44, 0x43, 0x43, 0x41, 0x51, 0x36, 0x67, 0x41, 0x77, + 0x49, 0x42, 0x41, 0x67, 0x49, 0x42, 0x41, 0x54, 0x41, 0x4e, + 0x42, 0x67, 0x6b, 0x71, 0x68, 0x6b, 0x69, 0x47, 0x39, 0x77, + 0x30, 0x42, 0x41, 0x51, 0x73, 0x46, 0x41, 0x44, 0x41, 0x51, + 0x4d, 0x51, 0x34, 0x77, 0x44, 0x41, 0x59, 0x44, 0x56, 0x51, + 0x51, 0x44, 0x44, 0x41, 0x56, 0x30, 0x5a, 0x58, 0x4e, 0x30, + 0x0a, 0x4d, 0x54, 0x41, 0x65, 0x46, 0x77, 0x30, 0x79, 0x4e, + 0x54, 0x41, 0x7a, 0x4d, 0x54, 0x45, 0x78, 0x4d, 0x54, 0x45, + 0x33, 0x4d, 0x44, 0x42, 0x61, 0x46, 0x77, 0x30, 0x79, 0x4e, + 0x54, 0x41, 0x30, 0x4d, 0x54, 0x41, 0x78, 0x4d, 0x54, 0x45, + 0x33, 0x4d, 0x44, 0x42, 0x61, 0x4d, 0x42, 0x41, 0x78, 0x44, + 0x6a, 0x41, 0x4d, 0x42, 0x67, 0x4e, 0x56, 0x42, 0x41, 0x4d, + 0x4d, 0x42, 0x58, 0x52, 0x6c, 0x0a, 0x63, 0x33, 0x51, 0x78, + 0x4d, 0x46, 0x77, 0x77, 0x44, 0x51, 0x59, 0x4a, 0x4b, 0x6f, + 0x5a, 0x49, 0x68, 0x76, 0x63, 0x4e, 0x41, 0x51, 0x45, 0x42, + 0x42, 0x51, 0x41, 0x44, 0x53, 0x77, 0x41, 0x77, 0x53, 0x41, + 0x4a, 0x42, 0x41, 0x4e, 0x4d, 0x56, 0x4c, 0x35, 0x67, 0x78, + 0x76, 0x6c, 0x35, 0x31, 0x30, 0x32, 0x42, 0x4c, 0x6c, 0x31, + 0x78, 0x79, 0x7a, 0x56, 0x44, 0x6c, 0x4c, 0x77, 0x63, 0x62, + 0x0a, 0x59, 0x72, 0x6e, 0x52, 0x4e, 0x76, 0x53, 0x72, 0x68, + 0x6f, 0x2f, 0x59, 0x61, 0x31, 0x6f, 0x63, 0x31, 0x71, 0x76, + 0x73, 0x75, 0x34, 0x72, 0x71, 0x43, 0x64, 0x2f, 0x30, 0x68, + 0x65, 0x6a, 0x55, 0x6a, 0x4e, 0x66, 0x71, 0x4b, 0x47, 0x64, + 0x79, 0x57, 0x61, 0x49, 0x67, 0x43, 0x45, 0x38, 0x71, 0x78, + 0x4e, 0x50, 0x34, 0x68, 0x32, 0x64, 0x37, 0x4e, 0x72, 0x45, + 0x43, 0x41, 0x77, 0x45, 0x41, 0x0a, 0x41, 0x61, 0x4e, 0x54, + 0x4d, 0x46, 0x45, 0x77, 0x48, 0x51, 0x59, 0x44, 0x56, 0x52, + 0x30, 0x4f, 0x42, 0x42, 0x59, 0x45, 0x46, 0x47, 0x38, 0x46, + 0x4d, 0x78, 0x52, 0x6e, 0x53, 0x6b, 0x36, 0x34, 0x65, 0x79, + 0x42, 0x69, 0x56, 0x43, 0x35, 0x75, 0x67, 0x73, 0x35, 0x63, + 0x4f, 0x77, 0x38, 0x6a, 0x4d, 0x42, 0x38, 0x47, 0x41, 0x31, + 0x55, 0x64, 0x49, 0x77, 0x51, 0x59, 0x4d, 0x42, 0x61, 0x41, + 0x0a, 0x46, 0x47, 0x38, 0x46, 0x4d, 0x78, 0x52, 0x6e, 0x53, + 0x6b, 0x36, 0x34, 0x65, 0x79, 0x42, 0x69, 0x56, 0x43, 0x35, + 0x75, 0x67, 0x73, 0x35, 0x63, 0x4f, 0x77, 0x38, 0x6a, 0x4d, + 0x41, 0x38, 0x47, 0x41, 0x31, 0x55, 0x64, 0x45, 0x77, 0x45, + 0x42, 0x2f, 0x77, 0x51, 0x46, 0x4d, 0x41, 0x4d, 0x42, 0x41, + 0x66, 0x38, 0x77, 0x44, 0x51, 0x59, 0x4a, 0x4b, 0x6f, 0x5a, + 0x49, 0x68, 0x76, 0x63, 0x4e, 0x0a, 0x41, 0x51, 0x45, 0x4c, + 0x42, 0x51, 0x41, 0x44, 0x51, 0x51, 0x41, 0x4a, 0x4d, 0x54, + 0x78, 0x6c, 0x62, 0x4e, 0x43, 0x58, 0x62, 0x6b, 0x2f, 0x73, + 0x6a, 0x79, 0x67, 0x4b, 0x30, 0x39, 0x58, 0x68, 0x50, 0x38, + 0x48, 0x74, 0x4c, 0x6b, 0x45, 0x2b, 0x34, 0x33, 0x6e, 0x61, + 0x67, 0x44, 0x39, 0x4b, 0x52, 0x48, 0x35, 0x53, 0x52, 0x47, + 0x6b, 0x68, 0x45, 0x43, 0x34, 0x50, 0x7a, 0x68, 0x53, 0x31, + 0x0a, 0x52, 0x76, 0x65, 0x34, 0x79, 0x4a, 0x35, 0x50, 0x2b, + 0x4b, 0x4a, 0x74, 0x36, 0x4d, 0x65, 0x78, 0x38, 0x4c, 0x48, + 0x37, 0x79, 0x2b, 0x74, 0x38, 0x61, 0x42, 0x62, 0x79, 0x68, + 0x56, 0x30, 0x47, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x45, + 0x4e, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, + 0x43, 0x41, 0x54, 0x45, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a ), + DIGEST ( 0x87, 0x95, 0x3b, 0x90, 0xb5, 0x5c, 0xb6, 0x7b, 0xc3, 0xfb, + 0xcb, 0x2c, 0x72, 0xbd, 0x4c, 0x2d, 0xb9, 0x9f, 0x10, 0xda ), + DIGEST ( 0x9b, 0x08, 0xa2, 0x7d, 0x53, 0x35, 0x0a, 0xeb, 0x53, 0xca, + 0x50, 0x66, 0xc0, 0xfd, 0xbd, 0x70, 0x78, 0xf2, 0xa0, 0xc9 ) ); + +/** + * Perform EFI signature list self-test + * + */ +static void efisig_test_exec ( void ) { + + /* Perform tests */ + asn1_ok ( &efisecdb ); +} + +/** EFI signature list self-test */ +struct self_test efisig_test __self_test = { + .name = "efisig", + .exec = efisig_test_exec, +}; diff --git a/src/tests/elliptic_test.c b/src/tests/elliptic_test.c new file mode 100644 index 000000000..614257d92 --- /dev/null +++ b/src/tests/elliptic_test.c @@ -0,0 +1,154 @@ +/* + * Copyright (C) 2025 Michael Brown <mbrown@fensystems.co.uk>. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + * + * You can also choose to distribute this program under the terms of + * the Unmodified Binary Distribution Licence (as given in the file + * COPYING.UBDL), provided that you have satisfied its requirements. + */ + +FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); + +/** @file + * + * Elliptic curve self-tests + * + */ + +/* Forcibly enable assertions */ +#undef NDEBUG + +#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 ); + okx ( ( ! elliptic_is_infinity ( curve, curve->base ) ), file, line ); + + /* Test multiplying base point by group order. Result should + * be the point at infinity. + */ + okx ( elliptic_multiply ( curve, curve->base, curve->order, + point ) == 0, file, line ); + okx ( elliptic_is_infinity ( curve, point ), 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 + * + * @v test Elliptic curve point multiplication test + * @v file Test code file + * @v line Test code line + */ +void elliptic_multiply_okx ( struct elliptic_multiply_test *test, + const char *file, unsigned int line ) { + struct elliptic_curve *curve = test->curve; + size_t pointsize = curve->pointsize; + size_t keysize = curve->keysize; + uint8_t actual[pointsize]; + const void *base; + int rc; + + /* Sanity checks */ + okx ( ( test->base_len == pointsize ) || ( ! test->base_len ), + file, line ); + okx ( test->scalar_len == keysize, file, line ); + okx ( ( test->expected_len == pointsize ) || ( ! test->expected_len ), + file, line ); + + /* Perform point multiplication */ + base = ( test->base_len ? test->base : curve->base ); + rc = elliptic_multiply ( curve, base, test->scalar, actual ); + if ( test->expected_len ) { + okx ( rc == 0, file, line ); + } else { + okx ( rc != 0, file, line ); + } + + /* Check expected result */ + okx ( memcmp ( actual, test->expected, test->expected_len ) == 0, + file, line ); +} + +/** + * Report elliptic curve point addition test result + * + * @v test Elliptic curve point addition test + * @v file Test code file + * @v line Test code line + */ +void elliptic_add_okx ( struct elliptic_add_test *test, + const char *file, unsigned int line ) { + struct elliptic_curve *curve = test->curve; + size_t pointsize = curve->pointsize; + uint8_t actual[pointsize]; + int rc; + + /* Sanity checks */ + okx ( test->addend_len == pointsize, file, line ); + okx ( test->augend_len == pointsize, file, line ); + okx ( ( test->expected_len == pointsize ) || ( ! test->expected_len ), + file, line ); + + /* Perform point addition */ + rc = elliptic_add ( curve, test->addend, test->augend, actual ); + if ( test->expected_len ) { + okx ( rc == 0, file, line ); + } else { + okx ( rc != 0, file, line ); + } + + /* Check expected result */ + okx ( memcmp ( actual, test->expected, test->expected_len ) == 0, + file, line ); +} diff --git a/src/tests/elliptic_test.h b/src/tests/elliptic_test.h new file mode 100644 index 000000000..eab242f17 --- /dev/null +++ b/src/tests/elliptic_test.h @@ -0,0 +1,146 @@ +#ifndef _ELLIPTIC_TEST_H +#define _ELLIPTIC_TEST_H + +FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); + +#include <stdint.h> +#include <ipxe/crypto.h> +#include <ipxe/test.h> + +/** An elliptic curve point multiplication test */ +struct elliptic_multiply_test { + /** Elliptic curve */ + struct elliptic_curve *curve; + /** Base point */ + const void *base; + /** Length of base point (or 0 to use generator) */ + size_t base_len; + /** Scalar multiple */ + const void *scalar; + /** Length of scalar multiple */ + size_t scalar_len; + /** Expected result point */ + const void *expected; + /** Length of expected result point (or 0 to expect failure) */ + size_t expected_len; +}; + +/** An elliptic curve point addition test */ +struct elliptic_add_test { + /** Elliptic curve */ + struct elliptic_curve *curve; + /** Addend point */ + const void *addend; + /** Length of addend point */ + size_t addend_len; + /** Augend point */ + const void *augend; + /** Length of augend point */ + size_t augend_len; + /** Expected result point */ + const void *expected; + /** Length of expected result point (or 0 to expect failure) */ + size_t expected_len; +}; + +/** Define inline base point */ +#define BASE(...) { __VA_ARGS__ } + +/** Define base point to be curve's generator */ +#define BASE_GENERATOR BASE() + +/** Define inline scalar multiple */ +#define SCALAR(...) { __VA_ARGS__ } + +/** Define inline addend point */ +#define ADDEND(...) { __VA_ARGS__ } + +/** Define inline augend point */ +#define AUGEND(...) { __VA_ARGS__ } + +/** Define inline expected result point */ +#define EXPECTED(...) { __VA_ARGS__ } + +/** Define result as an expected failure */ +#define EXPECTED_FAIL EXPECTED() + +/** + * Define an elliptic curve point multiplication test + * + * @v name Test name + * @v CURVE Elliptic curve + * @v BASE Base point + * @v SCALAR Scalar multiple + * @v EXPECTED Expected result point + * @ret test Elliptic curve point multiplication test + */ +#define ELLIPTIC_MULTIPLY_TEST( name, CURVE, BASE, SCALAR, EXPECTED ) \ + static const uint8_t name ## _base[] = BASE; \ + static const uint8_t name ## _scalar[] = SCALAR; \ + static const uint8_t name ## _expected[] = EXPECTED; \ + static struct elliptic_multiply_test name = { \ + .curve = CURVE, \ + .base = name ## _base, \ + .base_len = sizeof ( name ## _base ), \ + .scalar = name ## _scalar, \ + .scalar_len = sizeof ( name ## _scalar ), \ + .expected = name ## _expected, \ + .expected_len = sizeof ( name ## _expected ), \ + }; + +/** + * Define an elliptic curve point addition test + * + * @v name Test name + * @v CURVE Elliptic curve + * @v ADDEND Addend point + * @v AUGEND Augend point + * @v EXPECTED Expected result point + * @ret test Elliptic curve point multiplication test + */ +#define ELLIPTIC_ADD_TEST( name, CURVE, ADDEND, AUGEND, EXPECTED ) \ + static const uint8_t name ## _addend[] = ADDEND; \ + static const uint8_t name ## _augend[] = AUGEND; \ + static const uint8_t name ## _expected[] = EXPECTED; \ + static struct elliptic_add_test name = { \ + .curve = CURVE, \ + .addend = name ## _addend, \ + .addend_len = sizeof ( name ## _addend ), \ + .augend = name ## _augend, \ + .augend_len = sizeof ( name ## _augend ), \ + .expected = name ## _expected, \ + .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 ); +extern void elliptic_add_okx ( struct elliptic_add_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 + * + * @v test Elliptic curve point multiplication test + */ +#define elliptic_multiply_ok( test ) \ + elliptic_multiply_okx ( test, __FILE__, __LINE__ ) + +/** + * Report an elliptic curve point addition test result + * + * @v test Elliptic curve point addition test + */ +#define elliptic_add_ok( test ) \ + elliptic_add_okx ( test, __FILE__, __LINE__ ) + +#endif /* _ELLIPTIC_TEST_H */ diff --git a/src/tests/fdt_test.c b/src/tests/fdt_test.c new file mode 100644 index 000000000..07f7e8911 --- /dev/null +++ b/src/tests/fdt_test.c @@ -0,0 +1,320 @@ +/* + * Copyright (C) 2025 Michael Brown <mbrown@fensystems.co.uk>. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + * + * You can also choose to distribute this program under the terms of + * the Unmodified Binary Distribution Licence (as given in the file + * COPYING.UBDL), provided that you have satisfied its requirements. + */ + +FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); + +/** @file + * + * Flattened device tree self-tests + * + */ + +/* Forcibly enable assertions */ +#undef NDEBUG + +#include <string.h> +#include <ipxe/fdt.h> +#include <ipxe/image.h> +#include <ipxe/test.h> + +/** Simplified QEMU sifive_u device tree blob */ +static const uint8_t sifive_u[] = { + 0xd0, 0x0d, 0xfe, 0xed, 0x00, 0x00, 0x05, 0x8f, 0x00, 0x00, 0x00, 0x38, + 0x00, 0x00, 0x04, 0x9c, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x11, + 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf3, + 0x00, 0x00, 0x04, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, + 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x02, + 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x1b, + 0x73, 0x69, 0x66, 0x69, 0x76, 0x65, 0x2c, 0x68, 0x69, 0x66, 0x69, 0x76, + 0x65, 0x2d, 0x75, 0x6e, 0x6c, 0x65, 0x61, 0x73, 0x68, 0x65, 0x64, 0x2d, + 0x61, 0x30, 0x30, 0x00, 0x73, 0x69, 0x66, 0x69, 0x76, 0x65, 0x2c, 0x68, + 0x69, 0x66, 0x69, 0x76, 0x65, 0x2d, 0x75, 0x6e, 0x6c, 0x65, 0x61, 0x73, + 0x68, 0x65, 0x64, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x1c, + 0x00, 0x00, 0x00, 0x26, 0x53, 0x69, 0x46, 0x69, 0x76, 0x65, 0x20, 0x48, + 0x69, 0x46, 0x69, 0x76, 0x65, 0x20, 0x55, 0x6e, 0x6c, 0x65, 0x61, 0x73, + 0x68, 0x65, 0x64, 0x20, 0x41, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x63, 0x68, 0x6f, 0x73, 0x65, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, + 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x2c, 0x2f, 0x73, 0x6f, 0x63, + 0x2f, 0x73, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x40, 0x31, 0x30, 0x30, 0x31, + 0x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, + 0x00, 0x00, 0x00, 0x01, 0x61, 0x6c, 0x69, 0x61, 0x73, 0x65, 0x73, 0x00, + 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x38, + 0x2f, 0x73, 0x6f, 0x63, 0x2f, 0x73, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x40, + 0x31, 0x30, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x40, + 0x2f, 0x73, 0x6f, 0x63, 0x2f, 0x65, 0x74, 0x68, 0x65, 0x72, 0x6e, 0x65, + 0x74, 0x40, 0x31, 0x30, 0x30, 0x39, 0x30, 0x30, 0x30, 0x30, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x63, 0x70, 0x75, 0x73, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, + 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x4a, + 0x00, 0x0f, 0x42, 0x40, 0x00, 0x00, 0x00, 0x01, 0x63, 0x70, 0x75, 0x40, + 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x5d, 0x63, 0x70, 0x75, 0x00, 0x00, 0x00, 0x00, 0x03, + 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x6d, + 0x6f, 0x6b, 0x61, 0x79, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, + 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x1b, 0x72, 0x69, 0x73, 0x63, + 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x25, + 0x00, 0x00, 0x00, 0x74, 0x72, 0x76, 0x36, 0x34, 0x69, 0x6d, 0x61, 0x63, + 0x5f, 0x7a, 0x69, 0x63, 0x6e, 0x74, 0x72, 0x5f, 0x7a, 0x69, 0x63, 0x73, + 0x72, 0x5f, 0x7a, 0x69, 0x66, 0x65, 0x6e, 0x63, 0x65, 0x69, 0x5f, 0x7a, + 0x69, 0x68, 0x70, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x69, 0x6e, 0x74, 0x65, 0x72, 0x72, 0x75, 0x70, 0x74, 0x2d, 0x63, 0x6f, + 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x7e, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x8f, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x0f, + 0x00, 0x00, 0x00, 0x1b, 0x72, 0x69, 0x73, 0x63, 0x76, 0x2c, 0x63, 0x70, + 0x75, 0x2d, 0x69, 0x6e, 0x74, 0x63, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, + 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00, 0x00, 0x03, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, + 0x00, 0x00, 0x00, 0x01, 0x6d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x40, 0x38, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x03, + 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x5d, 0x6d, 0x65, 0x6d, 0x6f, + 0x72, 0x79, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x10, + 0x00, 0x00, 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, + 0x00, 0x00, 0x00, 0x01, 0x73, 0x6f, 0x63, 0x00, 0x00, 0x00, 0x00, 0x03, + 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, + 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x0f, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x0b, + 0x00, 0x00, 0x00, 0x1b, 0x73, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x2d, 0x62, + 0x75, 0x73, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xb2, 0x00, 0x00, 0x00, 0x01, 0x73, 0x65, 0x72, 0x69, + 0x61, 0x6c, 0x40, 0x31, 0x30, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x00, + 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x69, + 0x00, 0x00, 0x00, 0x00, 0x10, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x0d, + 0x00, 0x00, 0x00, 0x1b, 0x73, 0x69, 0x66, 0x69, 0x76, 0x65, 0x2c, 0x75, + 0x61, 0x72, 0x74, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, + 0x00, 0x00, 0x00, 0x01, 0x65, 0x74, 0x68, 0x65, 0x72, 0x6e, 0x65, 0x74, + 0x40, 0x31, 0x30, 0x30, 0x39, 0x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x0f, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, + 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0xb9, 0x52, 0x54, 0x00, 0x12, + 0x34, 0x56, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0xcb, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x03, + 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0xd6, 0x67, 0x6d, 0x69, 0x69, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x08, + 0x00, 0x00, 0x00, 0xdf, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x00, + 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x69, + 0x00, 0x00, 0x00, 0x00, 0x10, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0a, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x03, + 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x1b, 0x73, 0x69, 0x66, 0x69, + 0x76, 0x65, 0x2c, 0x66, 0x75, 0x35, 0x34, 0x30, 0x2d, 0x63, 0x30, 0x30, + 0x30, 0x2d, 0x67, 0x65, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, + 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0xe9, 0x00, 0x00, 0x00, 0x02, + 0x54, 0x0b, 0xe4, 0x00, 0x00, 0x00, 0x00, 0x01, 0x65, 0x74, 0x68, 0x65, + 0x72, 0x6e, 0x65, 0x74, 0x2d, 0x70, 0x68, 0x79, 0x40, 0x30, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x69, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0xaa, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x02, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, + 0x00, 0x00, 0x00, 0x09, 0x23, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, + 0x2d, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x00, 0x23, 0x73, 0x69, 0x7a, 0x65, + 0x2d, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x00, 0x63, 0x6f, 0x6d, 0x70, 0x61, + 0x74, 0x69, 0x62, 0x6c, 0x65, 0x00, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x00, + 0x73, 0x74, 0x64, 0x6f, 0x75, 0x74, 0x2d, 0x70, 0x61, 0x74, 0x68, 0x00, + 0x73, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x30, 0x00, 0x65, 0x74, 0x68, 0x65, + 0x72, 0x6e, 0x65, 0x74, 0x30, 0x00, 0x74, 0x69, 0x6d, 0x65, 0x62, 0x61, + 0x73, 0x65, 0x2d, 0x66, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, + 0x00, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, + 0x00, 0x72, 0x65, 0x67, 0x00, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x00, + 0x72, 0x69, 0x73, 0x63, 0x76, 0x2c, 0x69, 0x73, 0x61, 0x00, 0x23, 0x69, + 0x6e, 0x74, 0x65, 0x72, 0x72, 0x75, 0x70, 0x74, 0x2d, 0x63, 0x65, 0x6c, + 0x6c, 0x73, 0x00, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x72, 0x75, 0x70, 0x74, + 0x2d, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x00, + 0x6c, 0x69, 0x6e, 0x75, 0x78, 0x2c, 0x70, 0x68, 0x61, 0x6e, 0x64, 0x6c, + 0x65, 0x00, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x00, 0x6c, 0x6f, 0x63, + 0x61, 0x6c, 0x2d, 0x6d, 0x61, 0x63, 0x2d, 0x61, 0x64, 0x64, 0x72, 0x65, + 0x73, 0x73, 0x00, 0x70, 0x68, 0x79, 0x2d, 0x68, 0x61, 0x6e, 0x64, 0x6c, + 0x65, 0x00, 0x70, 0x68, 0x79, 0x2d, 0x6d, 0x6f, 0x64, 0x65, 0x00, 0x72, + 0x65, 0x67, 0x2d, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x00, 0x6d, 0x61, 0x78, + 0x2d, 0x73, 0x70, 0x65, 0x65, 0x64, 0x00 +}; + +/** + * Perform FDT self-test + * + */ +static void fdt_test_exec ( void ) { + struct fdt_descriptor desc; + struct fdt_header *hdr; + struct fdt fdt; + const char *string; + struct image *image; + uint32_t u32; + uint64_t u64; + unsigned int count; + unsigned int offset; + + /* Verify parsing */ + hdr = ( ( struct fdt_header * ) sifive_u ); + ok ( fdt_parse ( &fdt, hdr, 0 ) != 0 ); + ok ( fdt_parse ( &fdt, hdr, 1 ) != 0 ); + ok ( fdt_parse ( &fdt, hdr, ( sizeof ( sifive_u ) - 1 ) ) != 0 ); + ok ( fdt_parse ( &fdt, hdr, -1UL ) == 0 ); + ok ( fdt.len == sizeof ( sifive_u ) ); + ok ( fdt_parse ( &fdt, hdr, sizeof ( sifive_u ) ) == 0 ); + ok ( fdt.len == sizeof ( sifive_u ) ); + + /* Verify string properties */ + ok ( ( string = fdt_string ( &fdt, 0, "model" ) ) != NULL ); + ok ( strcmp ( string, "SiFive HiFive Unleashed A00" ) == 0 ); + ok ( ( string = fdt_string ( &fdt, 0, "nonexistent" ) ) == NULL ); + + /* Verify string list properties */ + ok ( ( string = fdt_strings ( &fdt, 0, "model", &count ) ) != NULL ); + ok ( count == 1 ); + ok ( memcmp ( string, "SiFive HiFive Unleashed A00", 28 ) == 0 ); + ok ( ( string = fdt_strings ( &fdt, 0, "compatible", + &count ) ) != NULL ); + ok ( count == 2 ); + ok ( memcmp ( string, "sifive,hifive-unleashed-a00\0" + "sifive,hifive-unleashed", 52 ) == 0 ); + ok ( ( string = fdt_strings ( &fdt, 0, "nonexistent", + &count ) ) == NULL ); + ok ( count == 0 ); + + /* Verify path lookup */ + ok ( fdt_path ( &fdt, "", &offset ) == 0 ); + ok ( offset == 0 ); + ok ( fdt_path ( &fdt, "/", &offset ) == 0 ); + ok ( offset == 0 ); + ok ( fdt_path ( &fdt, "/cpus/cpu@0/interrupt-controller", + &offset ) == 0 ); + ok ( ( string = fdt_string ( &fdt, offset, "compatible" ) ) != NULL ); + ok ( strcmp ( string, "riscv,cpu-intc" ) == 0 ); + ok ( fdt_path ( &fdt, "//soc/serial@10010000//", &offset ) == 0 ); + ok ( ( string = fdt_string ( &fdt, offset, "compatible" ) ) != NULL ); + ok ( strcmp ( string, "sifive,uart0" ) == 0 ); + ok ( fdt_path ( &fdt, "/nonexistent", &offset ) != 0 ); + ok ( fdt_path ( &fdt, "/cpus/nonexistent", &offset ) != 0 ); + ok ( fdt_path ( &fdt, "/soc/serial@10010000:115200n8", + &offset ) == 0 ); + ok ( ( string = fdt_string ( &fdt, offset, "compatible" ) ) != NULL ); + ok ( strcmp ( string, "sifive,uart0" ) == 0 ); + + /* Verify 64-bit integer properties */ + ok ( fdt_u64 ( &fdt, 0, "#address-cells", &u64 ) == 0 ); + ok ( u64 == 2 ); + ok ( fdt_path ( &fdt, "/soc/ethernet@10090000", &offset ) == 0 ); + ok ( fdt_u64 ( &fdt, offset, "max-speed", &u64 ) == 0 ); + ok ( u64 == 10000000000ULL ); + ok ( fdt_u64 ( &fdt, offset, "#nonexistent", &u64 ) != 0 ); + + /* Verify 32-bit integer properties */ + ok ( fdt_u32 ( &fdt, 0, "#address-cells", &u32 ) == 0 ); + ok ( u32 == 2 ); + ok ( fdt_u32 ( &fdt, 0, "#nonexistent", &u32 ) != 0 ); + ok ( fdt_path ( &fdt, "/soc/ethernet@10090000", &offset ) == 0 ); + ok ( fdt_u32 ( &fdt, offset, "max-speed", &u32 ) != 0 ); + + /* Verify phandle properties */ + ok ( fdt_path ( &fdt, "/cpus/cpu@0/interrupt-controller", + &offset ) == 0 ); + ok ( fdt_phandle ( &fdt, offset ) == 0x03 ); + ok ( fdt_path ( &fdt, "/soc/ethernet@10090000/ethernet-phy@0", + &offset ) == 0 ); + ok ( fdt_phandle ( &fdt, offset ) == 0x08 ); + ok ( fdt_path ( &fdt, "/soc/serial@10010000", &offset ) == 0 ); + ok ( fdt_phandle ( &fdt, offset ) == 0 ); + + /* Verify cell properties */ + ok ( fdt_path ( &fdt, "/soc/ethernet@10090000", &offset ) == 0 ); + ok ( fdt_cells ( &fdt, offset, "reg", 4, 2, &u64 ) == 0 ); + ok ( u64 == 0x100a0000 ); + ok ( fdt_cells ( &fdt, offset, "reg", 6, 2, &u64 ) == 0 ); + ok ( u64 == 0x1000 ); + ok ( fdt_cells ( &fdt, offset, "reg", 0, 2, &u64 ) == 0 ); + ok ( u64 == 0x10090000 ); + ok ( fdt_cells ( &fdt, offset, "reg", 6, 0, &u64 ) == 0 ); + ok ( u64 == 0x1000 ); + ok ( fdt_cells ( &fdt, offset, "reg", 8, 0, &u64 ) == 0 ); + ok ( u64 == 0 ); + ok ( fdt_cells ( &fdt, offset, "reg", 7, 2, &u64 ) != 0 ); + ok ( fdt_cells ( &fdt, offset, "notareg", 0, 1, &u64 ) != 0 ); + + /* Verify alias lookup */ + ok ( fdt_alias ( &fdt, "serial0", &offset ) == 0 ); + ok ( ( string = fdt_string ( &fdt, offset, "compatible" ) ) != NULL ); + ok ( strcmp ( string, "sifive,uart0" ) == 0 ); + ok ( fdt_alias ( &fdt, "nonexistent0", &offset ) != 0 ); + ok ( fdt_alias ( &fdt, "ethernet0:params", &offset ) == 0 ); + ok ( ( string = fdt_string ( &fdt, offset, "phy-mode" ) ) != NULL ); + ok ( strcmp ( string, "gmii" ) == 0 ); + + /* Verify node description */ + ok ( fdt_path ( &fdt, "/memory@80000000", &offset ) == 0 ); + ok ( fdt_describe ( &fdt, offset, &desc ) == 0 ); + ok ( desc.offset == offset ); + ok ( strcmp ( desc.name, "memory@80000000" ) == 0 ); + ok ( desc.data == NULL ); + ok ( desc.len == 0 ); + ok ( desc.depth == +1 ); + ok ( fdt_describe ( &fdt, desc.next, &desc ) == 0 ); + ok ( strcmp ( desc.name, "device_type" ) == 0 ); + ok ( strcmp ( desc.data, "memory" ) == 0 ); + ok ( desc.depth == 0 ); + + /* Verify parent lookup */ + ok ( fdt_path ( &fdt, "/soc/ethernet@10090000/ethernet-phy@0", + &offset ) == 0 ); + ok ( fdt_parent ( &fdt, offset, &offset ) == 0 ); + ok ( fdt_describe ( &fdt, offset, &desc ) == 0 ); + ok ( strcmp ( desc.name, "ethernet@10090000" ) == 0 ); + ok ( fdt_parent ( &fdt, offset, &offset ) == 0 ); + ok ( fdt_describe ( &fdt, offset, &desc ) == 0 ); + ok ( strcmp ( desc.name, "soc" ) == 0 ); + ok ( fdt_parent ( &fdt, offset, &offset ) == 0 ); + ok ( offset == 0 ); + + /* Verify device tree creation */ + image = image_memory ( "test.dtb", sifive_u, sizeof ( sifive_u ) ); + ok ( image != NULL ); + image_tag ( image, &fdt_image ); + ok ( fdt_create ( &hdr, "hello world", 0xabcd0000, 0x00001234 ) == 0 ); + ok ( fdt_parse ( &fdt, hdr, -1UL ) == 0 ); + ok ( fdt_path ( &fdt, "/chosen", &offset ) == 0 ); + ok ( ( string = fdt_string ( &fdt, offset, "bootargs" ) ) != NULL ); + ok ( strcmp ( string, "hello world" ) == 0 ); + ok ( fdt_u64 ( &fdt, offset, "linux,initrd-start", &u64 ) == 0 ); + ok ( u64 == 0xabcd0000 ); + ok ( fdt_u64 ( &fdt, offset, "linux,initrd-end", &u64 ) == 0 ); + ok ( u64 == 0xabcd1234 ); + fdt_remove ( hdr ); + unregister_image ( image ); +} + +/** FDT self-test */ +struct self_test fdt_test __self_test = { + .name = "fdt", + .exec = fdt_test_exec, +}; diff --git a/src/tests/gzip_test.c b/src/tests/gzip_test.c index fa76edc53..6fd0ec854 100644 --- a/src/tests/gzip_test.c +++ b/src/tests/gzip_test.c @@ -33,6 +33,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); #undef NDEBUG #include <stdint.h> +#include <string.h> #include <ipxe/image.h> #include <ipxe/gzip.h> #include <ipxe/test.h> @@ -114,8 +115,7 @@ static void gzip_okx ( struct gzip_test *test, const char *file, struct image *extracted; /* Construct compressed image */ - image = image_memory ( test->compressed_name, - virt_to_user ( test->compressed ), + image = image_memory ( test->compressed_name, test->compressed, test->compressed_len ); okx ( image != NULL, file, line ); okx ( image->len == test->compressed_len, file, line ); @@ -128,9 +128,8 @@ static void gzip_okx ( struct gzip_test *test, const char *file, /* Verify extracted image content */ okx ( extracted->len == test->expected_len, file, line ); - okx ( memcmp_user ( extracted->data, 0, - virt_to_user ( test->expected ), 0, - test->expected_len ) == 0, file, line ); + okx ( memcmp ( extracted->data, test->expected, + test->expected_len ) == 0, file, line ); /* Verify extracted image name */ okx ( strcmp ( extracted->name, test->expected_name ) == 0, diff --git a/src/tests/iobuf_test.c b/src/tests/iobuf_test.c index a417c2e8c..27fbccf0d 100644 --- a/src/tests/iobuf_test.c +++ b/src/tests/iobuf_test.c @@ -62,7 +62,7 @@ static inline void alloc_iob_okx ( size_t len, size_t align, size_t offset, "offset %#zx\n", iobuf, virt_to_phys ( iobuf->data ), iob_tailroom ( iobuf ), len, align, offset ); - /* Validate requested length and alignment */ + /* Validate requested length and data alignment */ okx ( ( ( ( intptr_t ) iobuf ) & ( __alignof__ ( *iobuf ) - 1 ) ) == 0, file, line ); okx ( iob_tailroom ( iobuf ) >= len, file, line ); @@ -70,6 +70,12 @@ static inline void alloc_iob_okx ( size_t len, size_t align, size_t offset, ( ( virt_to_phys ( iobuf->data ) & ( align - 1 ) ) == ( offset & ( align - 1 ) ) ) ), file, line ); + /* Validate overall buffer alignment */ + okx ( ( ( ( intptr_t ) iobuf->head ) & ( IOB_ZLEN - 1 ) ) == 0, + file, line ); + okx ( ( ( ( intptr_t ) iobuf->end ) & ( IOB_ZLEN - 1 ) ) == 0, + file, line ); + /* Overwrite entire content of I/O buffer (for Valgrind) */ memset ( iob_put ( iobuf, len ), 0x55, len ); diff --git a/src/tests/ipv4_test.c b/src/tests/ipv4_test.c index f84a8b81f..be2760027 100644 --- a/src/tests/ipv4_test.c +++ b/src/tests/ipv4_test.c @@ -34,9 +34,12 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); #include <stdint.h> #include <string.h> +#include <assert.h> #include <byteswap.h> #include <ipxe/in.h> +#include <ipxe/ip.h> #include <ipxe/test.h> +#include "netdev_test.h" /** Define inline IPv4 address */ #define IPV4(a,b,c,d) \ @@ -105,6 +108,124 @@ static void inet_aton_fail_okx ( const char *text, const char *file, inet_aton_fail_okx ( text, __FILE__, __LINE__ ) /** + * Report an ipv4_route() test result + * + * @v dest Destination address + * @v scope Destination scope test network device, or NULL + * @v next Expected next hop address (on success) + * @v egress Expected egress device, or NULL to expect failure + * @v src Expected source address (on success) + * @v bcast Expected broadcast packet (on success) + * @v file Test code file + * @v line Test code line + */ +static void ipv4_route_okx ( const char *dest, struct testnet *scope, + const char *next, struct testnet *egress, + const char *src, int bcast, + const char *file, unsigned int line ) { + struct ipv4_miniroute *miniroute; + struct in_addr in_dest; + struct in_addr in_src; + struct in_addr in_next; + struct in_addr actual; + unsigned int scope_id; + + /* Sanity checks */ + assert ( ( scope == NULL ) || ( scope->netdev != NULL ) ); + assert ( ( egress == NULL ) == ( src == NULL ) ); + + /* Parse addresses */ + okx ( inet_aton ( dest, &in_dest ) != 0, file, line ); + if ( src ) + okx ( inet_aton ( src, &in_src ) != 0, file, line ); + if ( next ) { + okx ( inet_aton ( next, &in_next ) != 0, file, line ); + } else { + in_next.s_addr = in_dest.s_addr; + } + + /* Perform routing */ + actual.s_addr = in_dest.s_addr; + scope_id = ( scope ? scope->netdev->scope_id : 0 ); + miniroute = ipv4_route ( scope_id, &actual ); + + /* Validate result */ + if ( src ) { + + /* Check that a route was found */ + okx ( miniroute != NULL, file, line ); + DBG ( "ipv4_route ( %s, %s ) = %s", + ( scope ? scope->dev.name : "<any>" ), dest, + inet_ntoa ( actual ) ); + DBG ( " from %s via %s\n", + inet_ntoa ( miniroute->address ), egress->dev.name ); + + /* Check that expected network device was used */ + okx ( miniroute->netdev == egress->netdev, file, line ); + + /* Check that expected source address was used */ + okx ( miniroute->address.s_addr == in_src.s_addr, file, line ); + + /* Check that expected next hop address was used */ + okx ( actual.s_addr == in_next.s_addr, file, line ); + + /* Check that expected broadcast choice was used */ + okx ( ( ! ( ( ~actual.s_addr ) & miniroute->hostmask.s_addr ) ) + == ( !! bcast ), file, line ); + + } else { + + /* Routing is expected to fail */ + okx ( miniroute == NULL, file, line ); + DBG ( "ipv4_route ( %s, %s ) = <unreachable>\n", + ( scope ? scope->dev.name : "<any>" ), dest ); + } +} +#define ipv4_route_ok( dest, scope, next, egress, src, bcast ) \ + ipv4_route_okx ( dest, scope, next, egress, src, bcast, \ + __FILE__, __LINE__ ) + +/** net0: Single address and gateway (DHCP assignment) */ +TESTNET ( net0, + { "dhcp/ip", "192.168.0.1" }, + { "dhcp/netmask", "255.255.255.0" }, + { "dhcp/gateway", "192.168.0.254" } ); + +/** net1: Single address and gateway (DHCP assignment) */ +TESTNET ( net1, + { "dhcp/ip", "192.168.0.2" }, + { "dhcp/netmask", "255.255.255.0" }, + { "dhcp/gateway", "192.168.0.254" } ); + +/** net2: Small /31 subnet mask */ +TESTNET ( net2, + { "ip", "10.31.31.0" }, + { "netmask", "255.255.255.254" }, + { "gateway", "10.31.31.1" } ); + +/** net3: Small /32 subnet mask */ +TESTNET ( net3, + { "ip", "10.32.32.32" }, + { "netmask", "255.255.255.255" }, + { "gateway", "192.168.32.254" } ); + +/** net4: Local subnet with no gateway */ +TESTNET ( net4, + { "ip", "192.168.86.1" }, + { "netmask", "255.255.240.0" } ); + +/** net5: Static routes */ +TESTNET ( net5, + { "ip", "10.42.0.1" }, + { "netmask", "255.255.0.0" }, + { "gateway", "10.42.0.254" /* should be ignored */ }, + { "static-routes", + "19:0a:2b:2b:80:0a:2a:2b:2b:" /* 10.43.43.128/25 via 10.42.43.43 */ + "10:c0:a8:0a:2a:c0:a8:" /* 192.168.0.0/16 via 10.42.192.168 */ + "18:c0:a8:00:00:00:00:00:" /* 192.168.0.0/24 on-link */ + "00:0a:2a:01:01" /* default via 10.42.1.1 */ } ); + +/** * Perform IPv4 self-tests * */ @@ -145,6 +266,96 @@ static void ipv4_test_exec ( void ) { inet_aton_fail_ok ( "127.0.0" ); /* Too short */ inet_aton_fail_ok ( "1.2.3.a" ); /* Invalid characters */ inet_aton_fail_ok ( "127.0..1" ); /* Missing bytes */ + + /* Single address and gateway */ + testnet_ok ( &net0 ); + ipv4_route_ok ( "192.168.0.10", NULL, + "192.168.0.10", &net0, "192.168.0.1", 0 ); + ipv4_route_ok ( "10.0.0.6", NULL, + "192.168.0.254", &net0, "192.168.0.1", 0 ); + ipv4_route_ok ( "192.168.0.255", NULL, + "192.168.0.255", &net0, "192.168.0.1", 1 ); + testnet_remove_ok ( &net0 ); + + /* Overridden DHCP-assigned address */ + testnet_ok ( &net1 ); + ipv4_route_ok ( "192.168.1.3", NULL, + "192.168.0.254", &net1, "192.168.0.2", 0 ); + testnet_set_ok ( &net1, "ip", "192.168.1.2" ); + ipv4_route_ok ( "192.168.1.3", NULL, + "192.168.1.3", &net1, "192.168.1.2", 0 ); + testnet_remove_ok ( &net1 ); + + /* Small /31 subnet */ + testnet_ok ( &net2 ); + ipv4_route_ok ( "10.31.31.1", NULL, + "10.31.31.1", &net2, "10.31.31.0", 0 ); + ipv4_route_ok ( "212.13.204.60", NULL, + "10.31.31.1", &net2, "10.31.31.0", 0 ); + testnet_remove_ok ( &net2 ); + + /* Small /32 subnet */ + testnet_ok ( &net3 ); + ipv4_route_ok ( "10.32.32.31", NULL, + "192.168.32.254", &net3, "10.32.32.32", 0 ); + ipv4_route_ok ( "8.8.8.8", NULL, + "192.168.32.254", &net3, "10.32.32.32", 0 ); + testnet_remove_ok ( &net3 ); + + /* No gateway */ + testnet_ok ( &net4 ); + ipv4_route_ok ( "192.168.87.1", NULL, + "192.168.87.1", &net4, "192.168.86.1", 0 ); + ipv4_route_ok ( "192.168.96.1", NULL, NULL, NULL, NULL, 0 ); + testnet_remove_ok ( &net4 ); + + /* Multiple interfaces */ + testnet_ok ( &net0 ); + testnet_ok ( &net1 ); + testnet_ok ( &net2 ); + testnet_close_ok ( &net1 ); + ipv4_route_ok ( "192.168.0.9", NULL, + "192.168.0.9", &net0, "192.168.0.1", 0 ); + ipv4_route_ok ( "10.31.31.1", NULL, + "10.31.31.1", &net2, "10.31.31.0", 0 ); + testnet_close_ok ( &net0 ); + testnet_open_ok ( &net1 ); + ipv4_route_ok ( "192.168.0.9", NULL, + "192.168.0.9", &net1, "192.168.0.2", 0 ); + ipv4_route_ok ( "10.31.31.1", NULL, + "10.31.31.1", &net2, "10.31.31.0", 0 ); + testnet_close_ok ( &net2 ); + ipv4_route_ok ( "8.8.8.8", NULL, + "192.168.0.254", &net1, "192.168.0.2", 0 ); + testnet_close_ok ( &net1 ); + testnet_open_ok ( &net0 ); + ipv4_route_ok ( "8.8.8.8", NULL, + "192.168.0.254", &net0, "192.168.0.1", 0 ); + testnet_close_ok ( &net0 ); + testnet_open_ok ( &net2 ); + ipv4_route_ok ( "8.8.8.8", NULL, + "10.31.31.1", &net2, "10.31.31.0", 0 ); + testnet_remove_ok ( &net2 ); + testnet_remove_ok ( &net1 ); + testnet_remove_ok ( &net0 ); + + /* Static routes */ + testnet_ok ( &net5 ); + ipv4_route_ok ( "10.42.99.0", NULL, + "10.42.99.0", &net5, "10.42.0.1", 0 ); + ipv4_route_ok ( "8.8.8.8", NULL, + "10.42.1.1", &net5, "10.42.0.1", 0 ); + ipv4_route_ok ( "10.43.43.1", NULL, + "10.42.1.1", &net5, "10.42.0.1", 0 ); + ipv4_route_ok ( "10.43.43.129", NULL, + "10.42.43.43", &net5, "10.42.0.1", 0 ); + ipv4_route_ok ( "192.168.54.8", NULL, + "10.42.192.168", &net5, "10.42.0.1", 0 ); + ipv4_route_ok ( "192.168.0.8", NULL, + "192.168.0.8", &net5, "10.42.0.1", 0 ); + ipv4_route_ok ( "192.168.0.255", NULL, + "192.168.0.255", &net5, "10.42.0.1", 1 ); + testnet_remove_ok ( &net5 ); } /** IPv4 self-test */ diff --git a/src/tests/math_test.c b/src/tests/math_test.c index 1a244f1eb..68e66c3e3 100644 --- a/src/tests/math_test.c +++ b/src/tests/math_test.c @@ -79,6 +79,42 @@ __attribute__ (( noinline )) int flsll_var ( long long value ) { } /** + * Force a use of runtime 64-bit shift left + * + * @v value Value + * @v shift Shift amount + * @ret value Shifted value + */ +__attribute__ (( noinline )) uint64_t lsl64_var ( uint64_t value, + unsigned int shift ) { + return ( value << shift ); +} + +/** + * Force a use of runtime 64-bit logical shift right + * + * @v value Value + * @v shift Shift amount + * @ret value Shifted value + */ +__attribute__ (( noinline )) uint64_t lsr64_var ( uint64_t value, + unsigned int shift ) { + return ( value >> shift ); +} + +/** + * Force a use of runtime 64-bit arithmetic shift right + * + * @v value Value + * @v shift Shift amount + * @ret value Shifted value + */ +__attribute__ (( noinline )) int64_t asr64_var ( int64_t value, + unsigned int shift ) { + return ( value >> shift ); +} + +/** * Check current stack pointer * * @ret stack A value at a fixed offset from the current stack pointer @@ -273,6 +309,72 @@ flsll_okx ( long long value, int msb, const char *file, unsigned int line ) { #define flsll_ok( value, msb ) flsll_okx ( value, msb, __FILE__, __LINE__ ) /** + * Report a 64-bit shift left test result + * + * @v value Value + * @v shift Shift amount + * @v expected Expected value + * @v file Test code file + * @v line Test code line + */ +static inline __attribute__ (( always_inline )) void +lsl64_okx ( uint64_t value, unsigned int shift, uint64_t expected, + const char *file, unsigned int line ) { + + /* Verify as a compile-time calculation */ + okx ( ( value << shift ) == expected, file, line ); + + /* Verify as a runtime calculation */ + okx ( lsl64_var ( value, shift ) == expected, file, line ); +} +#define lsl64_ok( value, shift, expected ) \ + lsl64_okx ( value, shift, expected, __FILE__, __LINE__ ) + +/** + * Report a 64-bit logical shift right test result + * + * @v value Value + * @v shift Shift amount + * @v expected Expected value + * @v file Test code file + * @v line Test code line + */ +static inline __attribute__ (( always_inline )) void +lsr64_okx ( uint64_t value, unsigned int shift, uint64_t expected, + const char *file, unsigned int line ) { + + /* Verify as a compile-time calculation */ + okx ( ( value >> shift ) == expected, file, line ); + + /* Verify as a runtime calculation */ + okx ( lsr64_var ( value, shift ) == expected, file, line ); +} +#define lsr64_ok( value, shift, expected ) \ + lsr64_okx ( value, shift, expected, __FILE__, __LINE__ ) + +/** + * Report a 64-bit arithmetic shift right test result + * + * @v value Value + * @v shift Shift amount + * @v expected Expected value + * @v file Test code file + * @v line Test code line + */ +static inline __attribute__ (( always_inline )) void +asr64_okx ( int64_t value, unsigned int shift, int64_t expected, + const char *file, unsigned int line ) { + + /* Verify as a compile-time calculation */ + okx ( ( value >> shift ) == expected, file, line ); + + /* Verify as a runtime calculation */ + okx ( asr64_var ( value, shift ) == expected, file, line ); +} +#define asr64_ok( value, shift, expected ) \ + asr64_okx ( value, shift, expected, __FILE__, __LINE__ ) + +/** * Report a 64-bit unsigned integer division test result * * @v dividend Dividend @@ -375,6 +477,21 @@ static void math_test_exec ( void ) { * etc. (including checking that the implicit calling * convention assumed by gcc matches our expectations). */ + lsl64_ok ( 0x06760c14710540c2ULL, 0, 0x06760c14710540c2ULL ); + lsr64_ok ( 0x06760c14710540c2ULL, 0, 0x06760c14710540c2ULL ); + asr64_ok ( 0x06760c14710540c2ULL, 0, 0x06760c14710540c2ULL ); + lsl64_ok ( 0xccafd1a8cb724c13ULL, 20, 0x1a8cb724c1300000ULL ); + lsr64_ok ( 0xccafd1a8cb724c13ULL, 20, 0x00000ccafd1a8cb7ULL ); + asr64_ok ( 0xccafd1a8cb724c13ULL, 20, 0xfffffccafd1a8cb7ULL ); + lsl64_ok ( 0x83567264b1234518ULL, 32, 0xb123451800000000ULL ); + lsr64_ok ( 0x83567264b1234518ULL, 32, 0x0000000083567264ULL ); + asr64_ok ( 0x83567264b1234518ULL, 32, 0xffffffff83567264ULL ); + lsl64_ok ( 0x69ee42fcbf1a4ea4ULL, 47, 0x2752000000000000ULL ); + lsr64_ok ( 0x69ee42fcbf1a4ea4ULL, 47, 0x000000000000d3dcULL ); + asr64_ok ( 0x69ee42fcbf1a4ea4ULL, 47, 0x000000000000d3dcULL ); + lsl64_ok ( 0xaa20b8caddee4269ULL, 63, 0x8000000000000000ULL ); + lsr64_ok ( 0xaa20b8caddee4269ULL, 63, 0x0000000000000001ULL ); + asr64_ok ( 0xaa20b8caddee4269ULL, 63, 0xffffffffffffffffULL ); u64divmod_ok ( 0x2b90ddccf699f765ULL, 0xed9f5e73ULL, 0x2eef6ab4ULL, 0x0e12f089ULL ); s64divmod_ok ( 0x2b90ddccf699f765ULL, 0xed9f5e73ULL, diff --git a/src/tests/netdev_test.c b/src/tests/netdev_test.c new file mode 100644 index 000000000..388a5af88 --- /dev/null +++ b/src/tests/netdev_test.c @@ -0,0 +1,218 @@ +/* + * Copyright (C) 2025 Michael Brown <mbrown@fensystems.co.uk>. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + * + * You can also choose to distribute this program under the terms of + * the Unmodified Binary Distribution Licence (as given in the file + * COPYING.UBDL), provided that you have satisfied its requirements. + */ + +FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); + +/** @file + * + * Network device tests + * + */ + +/* Forcibly enable assertions */ +#undef NDEBUG + +#include <string.h> +#include <stdio.h> +#include <ipxe/netdevice.h> +#include <ipxe/ethernet.h> +#include <ipxe/test.h> +#include "netdev_test.h" + +/** + * Open network device + * + * @v netdev Network device + * @ret rc Return status code + */ +static int testnet_open ( struct net_device *netdev __unused ) { + + /* Do nothing, successfully */ + return 0; +} + +/** + * Close network device + * + * @v netdev Network device + */ +static void testnet_close ( struct net_device *netdev __unused ) { + + /* Do nothing */ +} + +/** + * Transmit packet + * + * @v netdev Network device + * @v iobuf I/O buffer + * @ret rc Return status code + */ +static int testnet_transmit ( struct net_device *netdev, + struct io_buffer *iobuf ) { + + /* Complete immediately */ + netdev_tx_complete ( netdev, iobuf ); + return 0; +} + +/** + * Poll for completed and received packets + * + * @v netdev Network device + */ +static void testnet_poll ( struct net_device *netdev __unused ) { + + /* Do nothing */ +} + +/** Test network device operations */ +static struct net_device_operations testnet_operations = { + .open = testnet_open, + .close = testnet_close, + .transmit = testnet_transmit, + .poll = testnet_poll, +}; + +/** + * Report a network device creation test result + * + * @v testnet Test network device + * @v file Test code file + * @v line Test code line + */ +void testnet_okx ( struct testnet *testnet, const char *file, + unsigned int line ) { + struct testnet_setting *testset; + unsigned int i; + + /* Allocate device */ + testnet->netdev = alloc_etherdev ( 0 ); + okx ( testnet->netdev != NULL, file, line ); + netdev_init ( testnet->netdev, &testnet_operations ); + testnet->netdev->dev = &testnet->dev; + snprintf ( testnet->netdev->name, sizeof ( testnet->netdev->name ), + "%s", testnet->dev.name ); + + /* Register device */ + okx ( register_netdev ( testnet->netdev ) == 0, file, line ); + + /* Open device */ + testnet_open_okx ( testnet, file, line ); + + /* Apply initial settings */ + for ( i = 0 ; i < testnet->count ; i++ ) { + testset = &testnet->testset[i]; + testnet_set_okx ( testnet, testset->name, testset->value, + file, line ); + } +} + +/** + * Report a network device opening test result + * + * @v testnet Test network device + * @v file Test code file + * @v line Test code line + */ +void testnet_open_okx ( struct testnet *testnet, const char *file, + unsigned int line ) { + + /* Sanity check */ + okx ( testnet->netdev != NULL, file, line ); + + /* Open device */ + okx ( netdev_open ( testnet->netdev ) == 0, file, line ); +} + +/** + * Report a network device setting test result + * + * @v testnet Test network device + * @v name Setting name (relative to network device's settings) + * @v value Setting value + * @v file Test code file + * @v line Test code line + */ +void testnet_set_okx ( struct testnet *testnet, const char *name, + const char *value, const char *file, + unsigned int line ) { + char fullname[ strlen ( testnet->dev.name ) + 1 /* "." or "/" */ + + strlen ( name ) + 1 /* NUL */ ]; + struct settings *settings; + struct setting setting; + + /* Sanity check */ + okx ( testnet->netdev != NULL, file, line ); + settings = netdev_settings ( testnet->netdev ); + okx ( settings != NULL, file, line ); + okx ( strcmp ( settings->name, testnet->dev.name ) == 0, file, line ); + + /* Construct setting name */ + snprintf ( fullname, sizeof ( fullname ), "%s%c%s", testnet->dev.name, + ( strchr ( name, '/' ) ? '.' : '/' ), name ); + + /* Parse setting name */ + okx ( parse_setting_name ( fullname, autovivify_child_settings, + &settings, &setting ) == 0, file, line ); + + /* Apply setting */ + okx ( storef_setting ( settings, &setting, value ) == 0, file, line ); +} + +/** + * Report a network device closing test result + * + * @v testnet Test network device + * @v file Test code file + * @v line Test code line + */ +void testnet_close_okx ( struct testnet *testnet, const char *file, + unsigned int line ) { + + /* Sanity check */ + okx ( testnet->netdev != NULL, file, line ); + + /* Close device */ + netdev_close ( testnet->netdev ); +} + +/** + * Report a network device removal test result + * + * @v testnet Test network device + * @v file Test code file + * @v line Test code line + */ +void testnet_remove_okx ( struct testnet *testnet, const char *file, + unsigned int line ) { + + /* Sanity check */ + okx ( testnet->netdev != NULL, file, line ); + + /* Remove device */ + unregister_netdev ( testnet->netdev ); + netdev_nullify ( testnet->netdev ); + netdev_put ( testnet->netdev ); + testnet->netdev = NULL; +} diff --git a/src/tests/netdev_test.h b/src/tests/netdev_test.h new file mode 100644 index 000000000..ddb8c9b11 --- /dev/null +++ b/src/tests/netdev_test.h @@ -0,0 +1,111 @@ +#ifndef _NETDEV_TEST_H +#define _NETDEV_TEST_H + +/** @file + * + * Network device tests + * + */ + +FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); + +#include <ipxe/device.h> +#include <ipxe/netdevice.h> + +/** A test network device setting */ +struct testnet_setting { + /** Setting name (relative to network device's settings) */ + const char *name; + /** Value */ + const char *value; +}; + +/** A test network device */ +struct testnet { + /** Network device */ + struct net_device *netdev; + /** Dummy physical device */ + struct device dev; + /** Initial settings */ + struct testnet_setting *testset; + /** Number of initial settings */ + unsigned int count; +}; + +/** + * Declare a test network device + * + * @v NAME Network device name + * @v ... Initial network device settings + */ +#define TESTNET( NAME, ... ) \ + static struct testnet_setting NAME ## _setting[] = { \ + __VA_ARGS__ \ + }; \ + static struct testnet NAME = { \ + .dev = { \ + .name = #NAME, \ + .driver_name = "testnet", \ + .siblings = \ + LIST_HEAD_INIT ( NAME.dev.siblings ), \ + .children = \ + LIST_HEAD_INIT ( NAME.dev.children ), \ + }, \ + .testset = NAME ## _setting, \ + .count = ( sizeof ( NAME ## _setting ) / \ + sizeof ( NAME ## _setting[0] ) ), \ + }; + +/** + * Report a network device creation test result + * + * @v testnet Test network device + */ +#define testnet_ok( testnet ) testnet_okx ( testnet, __FILE__, __LINE__ ) +extern void testnet_okx ( struct testnet *testnet, const char *file, + unsigned int line ); + +/** + * Report a network device opening test result + * + * @v testnet Test network device + */ +#define testnet_open_ok( testnet ) \ + testnet_open_okx ( testnet, __FILE__, __LINE__ ) +extern void testnet_open_okx ( struct testnet *testnet, const char *file, + unsigned int line ); + +/** + * Report a network device setting test result + * + * @v testnet Test network device + * @v name Setting name (relative to network device's settings) + * @v value Setting value + */ +#define testnet_set_ok( testnet, name, value ) \ + testnet_set_okx ( testnet, name, value, __FILE__, __LINE__ ) +extern void testnet_set_okx ( struct testnet *testnet, const char *name, + const char *value, const char *file, + unsigned int line ); + +/** + * Report a network device closing test result + * + * @v testnet Test network device + */ +#define testnet_close_ok( testnet ) \ + testnet_close_okx ( testnet, __FILE__, __LINE__ ) +extern void testnet_close_okx ( struct testnet *testnet, const char *file, + unsigned int line ); + +/** + * Report a network device removal test result + * + * @v testnet Test network device + */ +#define testnet_remove_ok( testnet ) \ + testnet_remove_okx ( testnet, __FILE__, __LINE__ ) +extern void testnet_remove_okx ( struct testnet *testnet, const char *file, + unsigned int line ); + +#endif /* _NETDEV_TEST_H */ diff --git a/src/tests/p256_test.c b/src/tests/p256_test.c new file mode 100644 index 000000000..2a04b69c8 --- /dev/null +++ b/src/tests/p256_test.c @@ -0,0 +1,291 @@ +/* + * Copyright (C) 2025 Michael Brown <mbrown@fensystems.co.uk>. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + * + * You can also choose to distribute this program under the terms of + * the Unmodified Binary Distribution Licence (as given in the file + * COPYING.UBDL), provided that you have satisfied its requirements. + */ + +FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); + +/** @file + * + * NIST P-256 elliptic curve self-tests + * + */ + +/* Forcibly enable assertions */ +#undef NDEBUG + +#include <ipxe/p256.h> +#include <ipxe/test.h> +#include "elliptic_test.h" + +/* http://point-at-infinity.org/ecc/nisttv k=1 */ +ELLIPTIC_MULTIPLY_TEST ( poi_1, &p256_curve, BASE_GENERATOR, + SCALAR ( 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 ), + EXPECTED ( 0x6b, 0x17, 0xd1, 0xf2, 0xe1, 0x2c, 0x42, 0x47, + 0xf8, 0xbc, 0xe6, 0xe5, 0x63, 0xa4, 0x40, 0xf2, + 0x77, 0x03, 0x7d, 0x81, 0x2d, 0xeb, 0x33, 0xa0, + 0xf4, 0xa1, 0x39, 0x45, 0xd8, 0x98, 0xc2, 0x96, + 0x4f, 0xe3, 0x42, 0xe2, 0xfe, 0x1a, 0x7f, 0x9b, + 0x8e, 0xe7, 0xeb, 0x4a, 0x7c, 0x0f, 0x9e, 0x16, + 0x2b, 0xce, 0x33, 0x57, 0x6b, 0x31, 0x5e, 0xce, + 0xcb, 0xb6, 0x40, 0x68, 0x37, 0xbf, 0x51, 0xf5 ) ); + +/* http://point-at-infinity.org/ecc/nisttv k=2 */ +ELLIPTIC_MULTIPLY_TEST ( poi_2, &p256_curve, BASE_GENERATOR, + SCALAR ( 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02 ), + EXPECTED ( 0x7c, 0xf2, 0x7b, 0x18, 0x8d, 0x03, 0x4f, 0x7e, + 0x8a, 0x52, 0x38, 0x03, 0x04, 0xb5, 0x1a, 0xc3, + 0xc0, 0x89, 0x69, 0xe2, 0x77, 0xf2, 0x1b, 0x35, + 0xa6, 0x0b, 0x48, 0xfc, 0x47, 0x66, 0x99, 0x78, + 0x07, 0x77, 0x55, 0x10, 0xdb, 0x8e, 0xd0, 0x40, + 0x29, 0x3d, 0x9a, 0xc6, 0x9f, 0x74, 0x30, 0xdb, + 0xba, 0x7d, 0xad, 0xe6, 0x3c, 0xe9, 0x82, 0x29, + 0x9e, 0x04, 0xb7, 0x9d, 0x22, 0x78, 0x73, 0xd1 ) ); + +/* http://point-at-infinity.org/ecc/nisttv k=2 (as base) to k=20 */ +ELLIPTIC_MULTIPLY_TEST ( poi_2_20, &p256_curve, + BASE ( 0x7c, 0xf2, 0x7b, 0x18, 0x8d, 0x03, 0x4f, 0x7e, + 0x8a, 0x52, 0x38, 0x03, 0x04, 0xb5, 0x1a, 0xc3, + 0xc0, 0x89, 0x69, 0xe2, 0x77, 0xf2, 0x1b, 0x35, + 0xa6, 0x0b, 0x48, 0xfc, 0x47, 0x66, 0x99, 0x78, + 0x07, 0x77, 0x55, 0x10, 0xdb, 0x8e, 0xd0, 0x40, + 0x29, 0x3d, 0x9a, 0xc6, 0x9f, 0x74, 0x30, 0xdb, + 0xba, 0x7d, 0xad, 0xe6, 0x3c, 0xe9, 0x82, 0x29, + 0x9e, 0x04, 0xb7, 0x9d, 0x22, 0x78, 0x73, 0xd1 ), + SCALAR ( 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a ), + EXPECTED ( 0x83, 0xa0, 0x1a, 0x93, 0x78, 0x39, 0x5b, 0xab, + 0x9b, 0xcd, 0x6a, 0x0a, 0xd0, 0x3c, 0xc5, 0x6d, + 0x56, 0xe6, 0xb1, 0x92, 0x50, 0x46, 0x5a, 0x94, + 0xa2, 0x34, 0xdc, 0x4c, 0x6b, 0x28, 0xda, 0x9a, + 0x76, 0xe4, 0x9b, 0x6d, 0xe2, 0xf7, 0x32, 0x34, + 0xae, 0x6a, 0x5e, 0xb9, 0xd6, 0x12, 0xb7, 0x5c, + 0x9f, 0x22, 0x02, 0xbb, 0x69, 0x23, 0xf5, 0x4f, + 0xf8, 0x24, 0x0a, 0xaa, 0x86, 0xf6, 0x40, 0xb8 ) ); + +/* http://point-at-infinity.org/ecc/nisttv k=112233445566778899 */ +ELLIPTIC_MULTIPLY_TEST ( poi_mid, &p256_curve, BASE_GENERATOR, + SCALAR ( 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x8e, 0xbb, 0xb9, 0x5e, 0xed, 0x0e, 0x13 ), + EXPECTED ( 0x33, 0x91, 0x50, 0x84, 0x4e, 0xc1, 0x52, 0x34, + 0x80, 0x7f, 0xe8, 0x62, 0xa8, 0x6b, 0xe7, 0x79, + 0x77, 0xdb, 0xfb, 0x3a, 0xe3, 0xd9, 0x6f, 0x4c, + 0x22, 0x79, 0x55, 0x13, 0xae, 0xaa, 0xb8, 0x2f, + 0xb1, 0xc1, 0x4d, 0xdf, 0xdc, 0x8e, 0xc1, 0xb2, + 0x58, 0x3f, 0x51, 0xe8, 0x5a, 0x5e, 0xb3, 0xa1, + 0x55, 0x84, 0x0f, 0x20, 0x34, 0x73, 0x0e, 0x9b, + 0x5a, 0xda, 0x38, 0xb6, 0x74, 0x33, 0x6a, 0x21 ) ); + +/* http://point-at-infinity.org/ecc/nisttv k=<largest> */ +ELLIPTIC_MULTIPLY_TEST ( poi_large, &p256_curve, BASE_GENERATOR, + SCALAR ( 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, 0x50 ), + EXPECTED ( 0x6b, 0x17, 0xd1, 0xf2, 0xe1, 0x2c, 0x42, 0x47, + 0xf8, 0xbc, 0xe6, 0xe5, 0x63, 0xa4, 0x40, 0xf2, + 0x77, 0x03, 0x7d, 0x81, 0x2d, 0xeb, 0x33, 0xa0, + 0xf4, 0xa1, 0x39, 0x45, 0xd8, 0x98, 0xc2, 0x96, + 0xb0, 0x1c, 0xbd, 0x1c, 0x01, 0xe5, 0x80, 0x65, + 0x71, 0x18, 0x14, 0xb5, 0x83, 0xf0, 0x61, 0xe9, + 0xd4, 0x31, 0xcc, 0xa9, 0x94, 0xce, 0xa1, 0x31, + 0x34, 0x49, 0xbf, 0x97, 0xc8, 0x40, 0xae, 0x0a ) ); + +/* Point at infinity */ +ELLIPTIC_MULTIPLY_TEST ( infinity, &p256_curve, + BASE ( 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ), + SCALAR ( 0x8d, 0x50, 0x48, 0x0c, 0xbe, 0x22, 0x4d, 0x01, + 0xbc, 0xff, 0x67, 0x8d, 0xad, 0xb1, 0x87, 0x99, + 0x47, 0xb9, 0x79, 0x02, 0xb0, 0x70, 0x47, 0xf0, + 0x9f, 0x17, 0x25, 0x7e, 0xcf, 0x0b, 0x3e, 0x73 ), + EXPECTED ( 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ) ); + +/* Invalid curve point (zero, base_y) */ +ELLIPTIC_MULTIPLY_TEST ( invalid_zero, &p256_curve, + BASE ( 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x4f, 0xe3, 0x42, 0xe2, 0xfe, 0x1a, 0x7f, 0x9b, + 0x8e, 0xe7, 0xeb, 0x4a, 0x7c, 0x0f, 0x9e, 0x16, + 0x2b, 0xce, 0x33, 0x57, 0x6b, 0x31, 0x5e, 0xce, + 0xcb, 0xb6, 0x40, 0x68, 0x37, 0xbf, 0x51, 0xf4 ), + SCALAR ( 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 ), + EXPECTED_FAIL ); + +/* Invalid curve point (base_x, base_y - 1) */ +ELLIPTIC_MULTIPLY_TEST ( invalid_one, &p256_curve, + BASE ( 0x6b, 0x17, 0xd1, 0xf2, 0xe1, 0x2c, 0x42, 0x47, + 0xf8, 0xbc, 0xe6, 0xe5, 0x63, 0xa4, 0x40, 0xf2, + 0x77, 0x03, 0x7d, 0x81, 0x2d, 0xeb, 0x33, 0xa0, + 0xf4, 0xa1, 0x39, 0x45, 0xd8, 0x98, 0xc2, 0x96, + 0x4f, 0xe3, 0x42, 0xe2, 0xfe, 0x1a, 0x7f, 0x9b, + 0x8e, 0xe7, 0xeb, 0x4a, 0x7c, 0x0f, 0x9e, 0x16, + 0x2b, 0xce, 0x33, 0x57, 0x6b, 0x31, 0x5e, 0xce, + 0xcb, 0xb6, 0x40, 0x68, 0x37, 0xbf, 0x51, 0xf4 ), + SCALAR ( 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 ), + EXPECTED_FAIL ); + +/* http://point-at-infinity.org/ecc/nisttv k=2 + k=2 => k=4 */ +ELLIPTIC_ADD_TEST ( poi_2_2_4, &p256_curve, + ADDEND ( 0x7c, 0xf2, 0x7b, 0x18, 0x8d, 0x03, 0x4f, 0x7e, + 0x8a, 0x52, 0x38, 0x03, 0x04, 0xb5, 0x1a, 0xc3, + 0xc0, 0x89, 0x69, 0xe2, 0x77, 0xf2, 0x1b, 0x35, + 0xa6, 0x0b, 0x48, 0xfc, 0x47, 0x66, 0x99, 0x78, + 0x07, 0x77, 0x55, 0x10, 0xdb, 0x8e, 0xd0, 0x40, + 0x29, 0x3d, 0x9a, 0xc6, 0x9f, 0x74, 0x30, 0xdb, + 0xba, 0x7d, 0xad, 0xe6, 0x3c, 0xe9, 0x82, 0x29, + 0x9e, 0x04, 0xb7, 0x9d, 0x22, 0x78, 0x73, 0xd1 ), + AUGEND ( 0x7c, 0xf2, 0x7b, 0x18, 0x8d, 0x03, 0x4f, 0x7e, + 0x8a, 0x52, 0x38, 0x03, 0x04, 0xb5, 0x1a, 0xc3, + 0xc0, 0x89, 0x69, 0xe2, 0x77, 0xf2, 0x1b, 0x35, + 0xa6, 0x0b, 0x48, 0xfc, 0x47, 0x66, 0x99, 0x78, + 0x07, 0x77, 0x55, 0x10, 0xdb, 0x8e, 0xd0, 0x40, + 0x29, 0x3d, 0x9a, 0xc6, 0x9f, 0x74, 0x30, 0xdb, + 0xba, 0x7d, 0xad, 0xe6, 0x3c, 0xe9, 0x82, 0x29, + 0x9e, 0x04, 0xb7, 0x9d, 0x22, 0x78, 0x73, 0xd1 ), + EXPECTED ( 0xe2, 0x53, 0x4a, 0x35, 0x32, 0xd0, 0x8f, 0xbb, + 0xa0, 0x2d, 0xde, 0x65, 0x9e, 0xe6, 0x2b, 0xd0, + 0x03, 0x1f, 0xe2, 0xdb, 0x78, 0x55, 0x96, 0xef, + 0x50, 0x93, 0x02, 0x44, 0x6b, 0x03, 0x08, 0x52, + 0xe0, 0xf1, 0x57, 0x5a, 0x4c, 0x63, 0x3c, 0xc7, + 0x19, 0xdf, 0xee, 0x5f, 0xda, 0x86, 0x2d, 0x76, + 0x4e, 0xfc, 0x96, 0xc3, 0xf3, 0x0e, 0xe0, 0x05, + 0x5c, 0x42, 0xc2, 0x3f, 0x18, 0x4e, 0xd8, 0xc6 ) ); + +/* http://point-at-infinity.org/ecc/nisttv k=3 + k=5 => k=8 */ +ELLIPTIC_ADD_TEST ( poi_3_5_8, &p256_curve, + ADDEND ( 0x5e, 0xcb, 0xe4, 0xd1, 0xa6, 0x33, 0x0a, 0x44, + 0xc8, 0xf7, 0xef, 0x95, 0x1d, 0x4b, 0xf1, 0x65, + 0xe6, 0xc6, 0xb7, 0x21, 0xef, 0xad, 0xa9, 0x85, + 0xfb, 0x41, 0x66, 0x1b, 0xc6, 0xe7, 0xfd, 0x6c, + 0x87, 0x34, 0x64, 0x0c, 0x49, 0x98, 0xff, 0x7e, + 0x37, 0x4b, 0x06, 0xce, 0x1a, 0x64, 0xa2, 0xec, + 0xd8, 0x2a, 0xb0, 0x36, 0x38, 0x4f, 0xb8, 0x3d, + 0x9a, 0x79, 0xb1, 0x27, 0xa2, 0x7d, 0x50, 0x32 ), + AUGEND ( 0x51, 0x59, 0x0b, 0x7a, 0x51, 0x51, 0x40, 0xd2, + 0xd7, 0x84, 0xc8, 0x56, 0x08, 0x66, 0x8f, 0xdf, + 0xef, 0x8c, 0x82, 0xfd, 0x1f, 0x5b, 0xe5, 0x24, + 0x21, 0x55, 0x4a, 0x0d, 0xc3, 0xd0, 0x33, 0xed, + 0xe0, 0xc1, 0x7d, 0xa8, 0x90, 0x4a, 0x72, 0x7d, + 0x8a, 0xe1, 0xbf, 0x36, 0xbf, 0x8a, 0x79, 0x26, + 0x0d, 0x01, 0x2f, 0x00, 0xd4, 0xd8, 0x08, 0x88, + 0xd1, 0xd0, 0xbb, 0x44, 0xfd, 0xa1, 0x6d, 0xa4 ), + EXPECTED ( 0x62, 0xd9, 0x77, 0x9d, 0xbe, 0xe9, 0xb0, 0x53, + 0x40, 0x42, 0x74, 0x2d, 0x3a, 0xb5, 0x4c, 0xad, + 0xc1, 0xd2, 0x38, 0x98, 0x0f, 0xce, 0x97, 0xdb, + 0xb4, 0xdd, 0x9d, 0xc1, 0xdb, 0x6f, 0xb3, 0x93, + 0xad, 0x5a, 0xcc, 0xbd, 0x91, 0xe9, 0xd8, 0x24, + 0x4f, 0xf1, 0x5d, 0x77, 0x11, 0x67, 0xce, 0xe0, + 0xa2, 0xed, 0x51, 0xf6, 0xbb, 0xe7, 0x6a, 0x78, + 0xda, 0x54, 0x0a, 0x6a, 0x0f, 0x09, 0x95, 0x7e ) ); + +/* http://point-at-infinity.org/ecc/nisttv k=1 + k=n-1 => infinity */ +ELLIPTIC_ADD_TEST ( poi_1_n_1, &p256_curve, + ADDEND ( 0x6b, 0x17, 0xd1, 0xf2, 0xe1, 0x2c, 0x42, 0x47, + 0xf8, 0xbc, 0xe6, 0xe5, 0x63, 0xa4, 0x40, 0xf2, + 0x77, 0x03, 0x7d, 0x81, 0x2d, 0xeb, 0x33, 0xa0, + 0xf4, 0xa1, 0x39, 0x45, 0xd8, 0x98, 0xc2, 0x96, + 0x4f, 0xe3, 0x42, 0xe2, 0xfe, 0x1a, 0x7f, 0x9b, + 0x8e, 0xe7, 0xeb, 0x4a, 0x7c, 0x0f, 0x9e, 0x16, + 0x2b, 0xce, 0x33, 0x57, 0x6b, 0x31, 0x5e, 0xce, + 0xcb, 0xb6, 0x40, 0x68, 0x37, 0xbf, 0x51, 0xf5 ), + AUGEND ( 0x6b, 0x17, 0xd1, 0xf2, 0xe1, 0x2c, 0x42, 0x47, + 0xf8, 0xbc, 0xe6, 0xe5, 0x63, 0xa4, 0x40, 0xf2, + 0x77, 0x03, 0x7d, 0x81, 0x2d, 0xeb, 0x33, 0xa0, + 0xf4, 0xa1, 0x39, 0x45, 0xd8, 0x98, 0xc2, 0x96, + 0xb0, 0x1c, 0xbd, 0x1c, 0x01, 0xe5, 0x80, 0x65, + 0x71, 0x18, 0x14, 0xb5, 0x83, 0xf0, 0x61, 0xe9, + 0xd4, 0x31, 0xcc, 0xa9, 0x94, 0xce, 0xa1, 0x31, + 0x34, 0x49, 0xbf, 0x97, 0xc8, 0x40, 0xae, 0x0a ), + EXPECTED ( 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ) ); + +/** + * Perform P-256 self-test + * + */ +static void p256_test_exec ( void ) { + + /* Curve sanity test */ + elliptic_curve_ok ( &p256_curve ); + + /* Multiplication tests from http://point-at-infinity.org/ecc/nisttv */ + elliptic_multiply_ok ( &poi_1 ); + elliptic_multiply_ok ( &poi_2 ); + elliptic_multiply_ok ( &poi_2_20 ); + elliptic_multiply_ok ( &poi_mid ); + elliptic_multiply_ok ( &poi_large ); + + /* Point at infinity */ + elliptic_multiply_ok ( &infinity ); + + /* Invalid point tests */ + elliptic_multiply_ok ( &invalid_zero ); + elliptic_multiply_ok ( &invalid_one ); + + /* Addition tests from http://point-at-infinity.org/ecc/nisttv */ + elliptic_add_ok ( &poi_2_2_4 ); + elliptic_add_ok ( &poi_3_5_8 ); + elliptic_add_ok ( &poi_1_n_1 ); +} + +/** P-256 self-test */ +struct self_test p256_test __self_test = { + .name = "p256", + .exec = p256_test_exec, +}; diff --git a/src/tests/p384_test.c b/src/tests/p384_test.c new file mode 100644 index 000000000..b1b93faa4 --- /dev/null +++ b/src/tests/p384_test.c @@ -0,0 +1,383 @@ +/* + * Copyright (C) 2025 Michael Brown <mbrown@fensystems.co.uk>. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + * + * You can also choose to distribute this program under the terms of + * the Unmodified Binary Distribution Licence (as given in the file + * COPYING.UBDL), provided that you have satisfied its requirements. + */ + +FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); + +/** @file + * + * NIST P-384 elliptic curve self-tests + * + */ + +/* Forcibly enable assertions */ +#undef NDEBUG + +#include <ipxe/p384.h> +#include <ipxe/test.h> +#include "elliptic_test.h" + +/* http://point-at-infinity.org/ecc/nisttv k=1 */ +ELLIPTIC_MULTIPLY_TEST ( poi_1, &p384_curve, BASE_GENERATOR, + SCALAR ( 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 ), + EXPECTED ( 0xaa, 0x87, 0xca, 0x22, 0xbe, 0x8b, 0x05, 0x37, + 0x8e, 0xb1, 0xc7, 0x1e, 0xf3, 0x20, 0xad, 0x74, + 0x6e, 0x1d, 0x3b, 0x62, 0x8b, 0xa7, 0x9b, 0x98, + 0x59, 0xf7, 0x41, 0xe0, 0x82, 0x54, 0x2a, 0x38, + 0x55, 0x02, 0xf2, 0x5d, 0xbf, 0x55, 0x29, 0x6c, + 0x3a, 0x54, 0x5e, 0x38, 0x72, 0x76, 0x0a, 0xb7, + 0x36, 0x17, 0xde, 0x4a, 0x96, 0x26, 0x2c, 0x6f, + 0x5d, 0x9e, 0x98, 0xbf, 0x92, 0x92, 0xdc, 0x29, + 0xf8, 0xf4, 0x1d, 0xbd, 0x28, 0x9a, 0x14, 0x7c, + 0xe9, 0xda, 0x31, 0x13, 0xb5, 0xf0, 0xb8, 0xc0, + 0x0a, 0x60, 0xb1, 0xce, 0x1d, 0x7e, 0x81, 0x9d, + 0x7a, 0x43, 0x1d, 0x7c, 0x90, 0xea, 0x0e, 0x5f ) ); + +/* http://point-at-infinity.org/ecc/nisttv k=2 */ +ELLIPTIC_MULTIPLY_TEST ( poi_2, &p384_curve, BASE_GENERATOR, + SCALAR ( 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02 ), + EXPECTED ( 0x08, 0xd9, 0x99, 0x05, 0x7b, 0xa3, 0xd2, 0xd9, + 0x69, 0x26, 0x00, 0x45, 0xc5, 0x5b, 0x97, 0xf0, + 0x89, 0x02, 0x59, 0x59, 0xa6, 0xf4, 0x34, 0xd6, + 0x51, 0xd2, 0x07, 0xd1, 0x9f, 0xb9, 0x6e, 0x9e, + 0x4f, 0xe0, 0xe8, 0x6e, 0xbe, 0x0e, 0x64, 0xf8, + 0x5b, 0x96, 0xa9, 0xc7, 0x52, 0x95, 0xdf, 0x61, + 0x8e, 0x80, 0xf1, 0xfa, 0x5b, 0x1b, 0x3c, 0xed, + 0xb7, 0xbf, 0xe8, 0xdf, 0xfd, 0x6d, 0xba, 0x74, + 0xb2, 0x75, 0xd8, 0x75, 0xbc, 0x6c, 0xc4, 0x3e, + 0x90, 0x4e, 0x50, 0x5f, 0x25, 0x6a, 0xb4, 0x25, + 0x5f, 0xfd, 0x43, 0xe9, 0x4d, 0x39, 0xe2, 0x2d, + 0x61, 0x50, 0x1e, 0x70, 0x0a, 0x94, 0x0e, 0x80 ) ); + +/* http://point-at-infinity.org/ecc/nisttv k=2 (as base) to k=20 */ +ELLIPTIC_MULTIPLY_TEST ( poi_2_20, &p384_curve, + BASE ( 0x08, 0xd9, 0x99, 0x05, 0x7b, 0xa3, 0xd2, 0xd9, + 0x69, 0x26, 0x00, 0x45, 0xc5, 0x5b, 0x97, 0xf0, + 0x89, 0x02, 0x59, 0x59, 0xa6, 0xf4, 0x34, 0xd6, + 0x51, 0xd2, 0x07, 0xd1, 0x9f, 0xb9, 0x6e, 0x9e, + 0x4f, 0xe0, 0xe8, 0x6e, 0xbe, 0x0e, 0x64, 0xf8, + 0x5b, 0x96, 0xa9, 0xc7, 0x52, 0x95, 0xdf, 0x61, + 0x8e, 0x80, 0xf1, 0xfa, 0x5b, 0x1b, 0x3c, 0xed, + 0xb7, 0xbf, 0xe8, 0xdf, 0xfd, 0x6d, 0xba, 0x74, + 0xb2, 0x75, 0xd8, 0x75, 0xbc, 0x6c, 0xc4, 0x3e, + 0x90, 0x4e, 0x50, 0x5f, 0x25, 0x6a, 0xb4, 0x25, + 0x5f, 0xfd, 0x43, 0xe9, 0x4d, 0x39, 0xe2, 0x2d, + 0x61, 0x50, 0x1e, 0x70, 0x0a, 0x94, 0x0e, 0x80 ), + SCALAR ( 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a ), + EXPECTED ( 0x60, 0x55, 0x08, 0xec, 0x02, 0xc5, 0x34, 0xbc, + 0xee, 0xe9, 0x48, 0x4c, 0x86, 0x08, 0x6d, 0x21, + 0x39, 0x84, 0x9e, 0x2b, 0x11, 0xc1, 0xa9, 0xca, + 0x1e, 0x28, 0x08, 0xde, 0xc2, 0xea, 0xf1, 0x61, + 0xac, 0x8a, 0x10, 0x5d, 0x70, 0xd4, 0xf8, 0x5c, + 0x50, 0x59, 0x9b, 0xe5, 0x80, 0x0a, 0x62, 0x3f, + 0x51, 0x58, 0xee, 0x87, 0x96, 0x2a, 0xc6, 0xb8, + 0x1f, 0x00, 0xa1, 0x03, 0xb8, 0x54, 0x3a, 0x07, + 0x38, 0x1b, 0x76, 0x39, 0xa3, 0xa6, 0x5f, 0x13, + 0x53, 0xae, 0xf1, 0x1b, 0x73, 0x31, 0x06, 0xdd, + 0xe9, 0x2e, 0x99, 0xb7, 0x8d, 0xe3, 0x67, 0xb4, + 0x8e, 0x23, 0x8c, 0x38, 0xda, 0xd8, 0xee, 0xdd ) ); + +/* http://point-at-infinity.org/ecc/nisttv k=112233445566778899 */ +ELLIPTIC_MULTIPLY_TEST ( poi_mid, &p384_curve, BASE_GENERATOR, + SCALAR ( 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x8e, 0xbb, 0xb9, 0x5e, 0xed, 0x0e, 0x13 ), + EXPECTED ( 0xa4, 0x99, 0xef, 0xe4, 0x88, 0x39, 0xbc, 0x3a, + 0xbc, 0xd1, 0xc5, 0xce, 0xdb, 0xdd, 0x51, 0x90, + 0x4f, 0x95, 0x14, 0xdb, 0x44, 0xf4, 0x68, 0x6d, + 0xb9, 0x18, 0x98, 0x3b, 0x0c, 0x9d, 0xc3, 0xae, + 0xe0, 0x5a, 0x88, 0xb7, 0x24, 0x33, 0xe9, 0x51, + 0x5f, 0x91, 0xa3, 0x29, 0xf5, 0xf4, 0xfa, 0x60, + 0x3b, 0x7c, 0xa2, 0x8e, 0xf3, 0x1f, 0x80, 0x9c, + 0x2f, 0x1b, 0xa2, 0x4a, 0xae, 0xd8, 0x47, 0xd0, + 0xf8, 0xb4, 0x06, 0xa4, 0xb8, 0x96, 0x85, 0x42, + 0xde, 0x13, 0x9d, 0xb5, 0x82, 0x8c, 0xa4, 0x10, + 0xe6, 0x15, 0xd1, 0x18, 0x2e, 0x25, 0xb9, 0x1b, + 0x11, 0x31, 0xe2, 0x30, 0xb7, 0x27, 0xd3, 0x6a ) ); + +/* http://point-at-infinity.org/ecc/nisttv k=<largest> */ +ELLIPTIC_MULTIPLY_TEST ( poi_large, &p384_curve, BASE_GENERATOR, + SCALAR ( 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, 0x72 ), + EXPECTED ( 0xaa, 0x87, 0xca, 0x22, 0xbe, 0x8b, 0x05, 0x37, + 0x8e, 0xb1, 0xc7, 0x1e, 0xf3, 0x20, 0xad, 0x74, + 0x6e, 0x1d, 0x3b, 0x62, 0x8b, 0xa7, 0x9b, 0x98, + 0x59, 0xf7, 0x41, 0xe0, 0x82, 0x54, 0x2a, 0x38, + 0x55, 0x02, 0xf2, 0x5d, 0xbf, 0x55, 0x29, 0x6c, + 0x3a, 0x54, 0x5e, 0x38, 0x72, 0x76, 0x0a, 0xb7, + 0xc9, 0xe8, 0x21, 0xb5, 0x69, 0xd9, 0xd3, 0x90, + 0xa2, 0x61, 0x67, 0x40, 0x6d, 0x6d, 0x23, 0xd6, + 0x07, 0x0b, 0xe2, 0x42, 0xd7, 0x65, 0xeb, 0x83, + 0x16, 0x25, 0xce, 0xec, 0x4a, 0x0f, 0x47, 0x3e, + 0xf5, 0x9f, 0x4e, 0x30, 0xe2, 0x81, 0x7e, 0x62, + 0x85, 0xbc, 0xe2, 0x84, 0x6f, 0x15, 0xf1, 0xa0 ) ); + +/* Point at infinity */ +ELLIPTIC_MULTIPLY_TEST ( infinity, &p384_curve, + BASE ( 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ), + SCALAR ( 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 ), + EXPECTED ( 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ) ); + +/* Invalid curve point (zero, base_y) */ +ELLIPTIC_MULTIPLY_TEST ( invalid_zero, &p384_curve, + BASE ( 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x36, 0x17, 0xde, 0x4a, 0x96, 0x26, 0x2c, 0x6f, + 0x5d, 0x9e, 0x98, 0xbf, 0x92, 0x92, 0xdc, 0x29, + 0xf8, 0xf4, 0x1d, 0xbd, 0x28, 0x9a, 0x14, 0x7c, + 0xe9, 0xda, 0x31, 0x13, 0xb5, 0xf0, 0xb8, 0xc0, + 0x0a, 0x60, 0xb1, 0xce, 0x1d, 0x7e, 0x81, 0x9d, + 0x7a, 0x43, 0x1d, 0x7c, 0x90, 0xea, 0x0e, 0x5e ), + SCALAR ( 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 ), + EXPECTED_FAIL ); + +/* Invalid curve point (base_x, base_y - 1) */ +ELLIPTIC_MULTIPLY_TEST ( invalid_one, &p384_curve, + BASE ( 0xaa, 0x87, 0xca, 0x22, 0xbe, 0x8b, 0x05, 0x37, + 0x8e, 0xb1, 0xc7, 0x1e, 0xf3, 0x20, 0xad, 0x74, + 0x6e, 0x1d, 0x3b, 0x62, 0x8b, 0xa7, 0x9b, 0x98, + 0x59, 0xf7, 0x41, 0xe0, 0x82, 0x54, 0x2a, 0x38, + 0x55, 0x02, 0xf2, 0x5d, 0xbf, 0x55, 0x29, 0x6c, + 0x3a, 0x54, 0x5e, 0x38, 0x72, 0x76, 0x0a, 0xb7, + 0x36, 0x17, 0xde, 0x4a, 0x96, 0x26, 0x2c, 0x6f, + 0x5d, 0x9e, 0x98, 0xbf, 0x92, 0x92, 0xdc, 0x29, + 0xf8, 0xf4, 0x1d, 0xbd, 0x28, 0x9a, 0x14, 0x7c, + 0xe9, 0xda, 0x31, 0x13, 0xb5, 0xf0, 0xb8, 0xc0, + 0x0a, 0x60, 0xb1, 0xce, 0x1d, 0x7e, 0x81, 0x9d, + 0x7a, 0x43, 0x1d, 0x7c, 0x90, 0xea, 0x0e, 0x5e ), + SCALAR ( 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 ), + EXPECTED_FAIL ); + +/* http://point-at-infinity.org/ecc/nisttv k=2 + k=2 => k=4 */ +ELLIPTIC_ADD_TEST ( poi_2_2_4, &p384_curve, + ADDEND ( 0x08, 0xd9, 0x99, 0x05, 0x7b, 0xa3, 0xd2, 0xd9, + 0x69, 0x26, 0x00, 0x45, 0xc5, 0x5b, 0x97, 0xf0, + 0x89, 0x02, 0x59, 0x59, 0xa6, 0xf4, 0x34, 0xd6, + 0x51, 0xd2, 0x07, 0xd1, 0x9f, 0xb9, 0x6e, 0x9e, + 0x4f, 0xe0, 0xe8, 0x6e, 0xbe, 0x0e, 0x64, 0xf8, + 0x5b, 0x96, 0xa9, 0xc7, 0x52, 0x95, 0xdf, 0x61, + 0x8e, 0x80, 0xf1, 0xfa, 0x5b, 0x1b, 0x3c, 0xed, + 0xb7, 0xbf, 0xe8, 0xdf, 0xfd, 0x6d, 0xba, 0x74, + 0xb2, 0x75, 0xd8, 0x75, 0xbc, 0x6c, 0xc4, 0x3e, + 0x90, 0x4e, 0x50, 0x5f, 0x25, 0x6a, 0xb4, 0x25, + 0x5f, 0xfd, 0x43, 0xe9, 0x4d, 0x39, 0xe2, 0x2d, + 0x61, 0x50, 0x1e, 0x70, 0x0a, 0x94, 0x0e, 0x80 ), + AUGEND ( 0x08, 0xd9, 0x99, 0x05, 0x7b, 0xa3, 0xd2, 0xd9, + 0x69, 0x26, 0x00, 0x45, 0xc5, 0x5b, 0x97, 0xf0, + 0x89, 0x02, 0x59, 0x59, 0xa6, 0xf4, 0x34, 0xd6, + 0x51, 0xd2, 0x07, 0xd1, 0x9f, 0xb9, 0x6e, 0x9e, + 0x4f, 0xe0, 0xe8, 0x6e, 0xbe, 0x0e, 0x64, 0xf8, + 0x5b, 0x96, 0xa9, 0xc7, 0x52, 0x95, 0xdf, 0x61, + 0x8e, 0x80, 0xf1, 0xfa, 0x5b, 0x1b, 0x3c, 0xed, + 0xb7, 0xbf, 0xe8, 0xdf, 0xfd, 0x6d, 0xba, 0x74, + 0xb2, 0x75, 0xd8, 0x75, 0xbc, 0x6c, 0xc4, 0x3e, + 0x90, 0x4e, 0x50, 0x5f, 0x25, 0x6a, 0xb4, 0x25, + 0x5f, 0xfd, 0x43, 0xe9, 0x4d, 0x39, 0xe2, 0x2d, + 0x61, 0x50, 0x1e, 0x70, 0x0a, 0x94, 0x0e, 0x80 ), + EXPECTED ( 0x13, 0x82, 0x51, 0xcd, 0x52, 0xac, 0x92, 0x98, + 0xc1, 0xc8, 0xaa, 0xd9, 0x77, 0x32, 0x1d, 0xeb, + 0x97, 0xe7, 0x09, 0xbd, 0x0b, 0x4c, 0xa0, 0xac, + 0xa5, 0x5d, 0xc8, 0xad, 0x51, 0xdc, 0xfc, 0x9d, + 0x15, 0x89, 0xa1, 0x59, 0x7e, 0x3a, 0x51, 0x20, + 0xe1, 0xef, 0xd6, 0x31, 0xc6, 0x3e, 0x18, 0x35, + 0xca, 0xca, 0xe2, 0x98, 0x69, 0xa6, 0x2e, 0x16, + 0x31, 0xe8, 0xa2, 0x81, 0x81, 0xab, 0x56, 0x61, + 0x6d, 0xc4, 0x5d, 0x91, 0x8a, 0xbc, 0x09, 0xf3, + 0xab, 0x0e, 0x63, 0xcf, 0x79, 0x2a, 0xa4, 0xdc, + 0xed, 0x73, 0x87, 0xbe, 0x37, 0xbb, 0xa5, 0x69, + 0x54, 0x9f, 0x1c, 0x02, 0xb2, 0x70, 0xed, 0x67 ) ); + +/* http://point-at-infinity.org/ecc/nisttv k=3 + k=5 => k=8 */ +ELLIPTIC_ADD_TEST ( poi_3_5_8, &p384_curve, + ADDEND ( 0x07, 0x7a, 0x41, 0xd4, 0x60, 0x6f, 0xfa, 0x14, + 0x64, 0x79, 0x3c, 0x7e, 0x5f, 0xdc, 0x7d, 0x98, + 0xcb, 0x9d, 0x39, 0x10, 0x20, 0x2d, 0xcd, 0x06, + 0xbe, 0xa4, 0xf2, 0x40, 0xd3, 0x56, 0x6d, 0xa6, + 0xb4, 0x08, 0xbb, 0xae, 0x50, 0x26, 0x58, 0x0d, + 0x02, 0xd7, 0xe5, 0xc7, 0x05, 0x00, 0xc8, 0x31, + 0xc9, 0x95, 0xf7, 0xca, 0x0b, 0x0c, 0x42, 0x83, + 0x7d, 0x0b, 0xbe, 0x96, 0x02, 0xa9, 0xfc, 0x99, + 0x85, 0x20, 0xb4, 0x1c, 0x85, 0x11, 0x5a, 0xa5, + 0xf7, 0x68, 0x4c, 0x0e, 0xdc, 0x11, 0x1e, 0xac, + 0xc2, 0x4a, 0xbd, 0x6b, 0xe4, 0xb5, 0xd2, 0x98, + 0xb6, 0x5f, 0x28, 0x60, 0x0a, 0x2f, 0x1d, 0xf1 ), + AUGEND ( 0x11, 0xde, 0x24, 0xa2, 0xc2, 0x51, 0xc7, 0x77, + 0x57, 0x3c, 0xac, 0x5e, 0xa0, 0x25, 0xe4, 0x67, + 0xf2, 0x08, 0xe5, 0x1d, 0xbf, 0xf9, 0x8f, 0xc5, + 0x4f, 0x66, 0x61, 0xcb, 0xe5, 0x65, 0x83, 0xb0, + 0x37, 0x88, 0x2f, 0x4a, 0x1c, 0xa2, 0x97, 0xe6, + 0x0a, 0xbc, 0xdb, 0xc3, 0x83, 0x6d, 0x84, 0xbc, + 0x8f, 0xa6, 0x96, 0xc7, 0x74, 0x40, 0xf9, 0x2d, + 0x0f, 0x58, 0x37, 0xe9, 0x0a, 0x00, 0xe7, 0xc5, + 0x28, 0x4b, 0x44, 0x77, 0x54, 0xd5, 0xde, 0xe8, + 0x8c, 0x98, 0x65, 0x33, 0xb6, 0x90, 0x1a, 0xeb, + 0x31, 0x77, 0x68, 0x6d, 0x0a, 0xe8, 0xfb, 0x33, + 0x18, 0x44, 0x14, 0xab, 0xe6, 0xc1, 0x71, 0x3a ), + EXPECTED ( 0x16, 0x92, 0x77, 0x8e, 0xa5, 0x96, 0xe0, 0xbe, + 0x75, 0x11, 0x42, 0x97, 0xa6, 0xfa, 0x38, 0x34, + 0x45, 0xbf, 0x22, 0x7f, 0xbe, 0x58, 0x19, 0x0a, + 0x90, 0x0c, 0x3c, 0x73, 0x25, 0x6f, 0x11, 0xfb, + 0x5a, 0x32, 0x58, 0xd6, 0xf4, 0x03, 0xd5, 0xec, + 0xe6, 0xe9, 0xb2, 0x69, 0xd8, 0x22, 0xc8, 0x7d, + 0xdc, 0xd2, 0x36, 0x57, 0x00, 0xd4, 0x10, 0x6a, + 0x83, 0x53, 0x88, 0xba, 0x3d, 0xb8, 0xfd, 0x0e, + 0x22, 0x55, 0x4a, 0xdc, 0x6d, 0x52, 0x1c, 0xd4, + 0xbd, 0x1c, 0x30, 0xc2, 0xec, 0x0e, 0xec, 0x19, + 0x6b, 0xad, 0xe1, 0xe9, 0xcd, 0xd1, 0x70, 0x8d, + 0x6f, 0x6a, 0xbf, 0xa4, 0x02, 0x2b, 0x0a, 0xd2 ) ); + +/* http://point-at-infinity.org/ecc/nisttv k=1 + k=n-1 => infinity */ +ELLIPTIC_ADD_TEST ( poi_1_n_1, &p384_curve, + ADDEND ( 0xaa, 0x87, 0xca, 0x22, 0xbe, 0x8b, 0x05, 0x37, + 0x8e, 0xb1, 0xc7, 0x1e, 0xf3, 0x20, 0xad, 0x74, + 0x6e, 0x1d, 0x3b, 0x62, 0x8b, 0xa7, 0x9b, 0x98, + 0x59, 0xf7, 0x41, 0xe0, 0x82, 0x54, 0x2a, 0x38, + 0x55, 0x02, 0xf2, 0x5d, 0xbf, 0x55, 0x29, 0x6c, + 0x3a, 0x54, 0x5e, 0x38, 0x72, 0x76, 0x0a, 0xb7, + 0x36, 0x17, 0xde, 0x4a, 0x96, 0x26, 0x2c, 0x6f, + 0x5d, 0x9e, 0x98, 0xbf, 0x92, 0x92, 0xdc, 0x29, + 0xf8, 0xf4, 0x1d, 0xbd, 0x28, 0x9a, 0x14, 0x7c, + 0xe9, 0xda, 0x31, 0x13, 0xb5, 0xf0, 0xb8, 0xc0, + 0x0a, 0x60, 0xb1, 0xce, 0x1d, 0x7e, 0x81, 0x9d, + 0x7a, 0x43, 0x1d, 0x7c, 0x90, 0xea, 0x0e, 0x5f ), + AUGEND ( 0xaa, 0x87, 0xca, 0x22, 0xbe, 0x8b, 0x05, 0x37, + 0x8e, 0xb1, 0xc7, 0x1e, 0xf3, 0x20, 0xad, 0x74, + 0x6e, 0x1d, 0x3b, 0x62, 0x8b, 0xa7, 0x9b, 0x98, + 0x59, 0xf7, 0x41, 0xe0, 0x82, 0x54, 0x2a, 0x38, + 0x55, 0x02, 0xf2, 0x5d, 0xbf, 0x55, 0x29, 0x6c, + 0x3a, 0x54, 0x5e, 0x38, 0x72, 0x76, 0x0a, 0xb7, + 0xc9, 0xe8, 0x21, 0xb5, 0x69, 0xd9, 0xd3, 0x90, + 0xa2, 0x61, 0x67, 0x40, 0x6d, 0x6d, 0x23, 0xd6, + 0x07, 0x0b, 0xe2, 0x42, 0xd7, 0x65, 0xeb, 0x83, + 0x16, 0x25, 0xce, 0xec, 0x4a, 0x0f, 0x47, 0x3e, + 0xf5, 0x9f, 0x4e, 0x30, 0xe2, 0x81, 0x7e, 0x62, + 0x85, 0xbc, 0xe2, 0x84, 0x6f, 0x15, 0xf1, 0xa0 ), + EXPECTED ( 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ) ); + +/** + * Perform P-384 self-test + * + */ +static void p384_test_exec ( void ) { + + /* Curve sanity test */ + elliptic_curve_ok ( &p384_curve ); + + /* Multiplication tests from http://point-at-infinity.org/ecc/nisttv */ + elliptic_multiply_ok ( &poi_1 ); + elliptic_multiply_ok ( &poi_2 ); + elliptic_multiply_ok ( &poi_2_20 ); + elliptic_multiply_ok ( &poi_mid ); + elliptic_multiply_ok ( &poi_large ); + + /* Point at infinity */ + elliptic_multiply_ok ( &infinity ); + + /* Invalid point tests */ + elliptic_multiply_ok ( &invalid_zero ); + elliptic_multiply_ok ( &invalid_one ); + + /* Addition tests from http://point-at-infinity.org/ecc/nisttv */ + elliptic_add_ok ( &poi_2_2_4 ); + elliptic_add_ok ( &poi_3_5_8 ); + elliptic_add_ok ( &poi_1_n_1 ); +} + +/** P-384 self-test */ +struct self_test p384_test __self_test = { + .name = "p384", + .exec = p384_test_exec, +}; diff --git a/src/tests/pccrc_test.c b/src/tests/pccrc_test.c index e69493202..f3f38d360 100644 --- a/src/tests/pccrc_test.c +++ b/src/tests/pccrc_test.c @@ -35,7 +35,6 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); #include <stdint.h> #include <string.h> #include <assert.h> -#include <ipxe/uaccess.h> #include <ipxe/pccrc.h> #include <ipxe/sha256.h> #include <ipxe/sha512.h> @@ -362,11 +361,10 @@ static void peerdist_info_okx ( struct peerdist_info_test *test, const char *file, unsigned int line ) { /* Parse content information */ - okx ( peerdist_info ( virt_to_user ( test->data ), test->len, - info ) == 0, file, line ); + okx ( peerdist_info ( test->data, test->len, info ) == 0, file, line ); /* Verify content information */ - okx ( info->raw.data == virt_to_user ( test->data ), file, line ); + okx ( info->raw.data == test->data, file, line ); okx ( info->raw.len == test->len, file, line ); okx ( info->digest == test->expected_digest, file, line ); okx ( info->digestsize == test->expected_digestsize, file, line ); diff --git a/src/tests/pixbuf_test.c b/src/tests/pixbuf_test.c index aaa516bb2..cbc3a7617 100644 --- a/src/tests/pixbuf_test.c +++ b/src/tests/pixbuf_test.c @@ -32,6 +32,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); /* Forcibly enable assertions */ #undef NDEBUG +#include <string.h> #include <assert.h> #include <ipxe/image.h> #include <ipxe/pixbuf.h> @@ -54,9 +55,6 @@ void pixbuf_okx ( struct pixel_buffer_test *test, const char *file, assert ( ( test->width * test->height * sizeof ( test->data[0] ) ) == test->len ); - /* Correct image data pointer */ - test->image->data = virt_to_user ( ( void * ) test->image->data ); - /* Check that image is detected as correct type */ okx ( register_image ( test->image ) == 0, file, line ); okx ( test->image->type == test->type, file, line ); @@ -71,9 +69,8 @@ void pixbuf_okx ( struct pixel_buffer_test *test, const char *file, /* Check pixel buffer data */ okx ( pixbuf->len == test->len, file, line ); - okx ( memcmp_user ( pixbuf->data, 0, - virt_to_user ( test->data ), 0, - test->len ) == 0, file, line ); + okx ( memcmp ( pixbuf->data, test->data, test->len ) == 0, + file, line ); pixbuf_put ( pixbuf ); } diff --git a/src/tests/pixbuf_test.h b/src/tests/pixbuf_test.h index d12829d89..cf3d548f9 100644 --- a/src/tests/pixbuf_test.h +++ b/src/tests/pixbuf_test.h @@ -41,7 +41,8 @@ struct pixel_buffer_test { static struct image _name ## __image = { \ .refcnt = REF_INIT ( ref_no_free ), \ .name = #_name, \ - .data = ( userptr_t ) ( _name ## __file ), \ + .flags = ( IMAGE_STATIC | IMAGE_STATIC_NAME ), \ + .data = _name ## __file, \ .len = sizeof ( _name ## __file ), \ }; \ static struct pixel_buffer_test _name = { \ diff --git a/src/tests/pubkey_test.c b/src/tests/pubkey_test.c new file mode 100644 index 000000000..b94ed90ff --- /dev/null +++ b/src/tests/pubkey_test.c @@ -0,0 +1,155 @@ +/* + * Copyright (C) 2024 Michael Brown <mbrown@fensystems.co.uk>. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + * + * You can also choose to distribute this program under the terms of + * the Unmodified Binary Distribution Licence (as given in the file + * COPYING.UBDL), provided that you have satisfied its requirements. + */ + +FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); + +/** @file + * + * Public key self-tests + * + */ + +/* Forcibly enable assertions */ +#undef NDEBUG + +#include <stdint.h> +#include <stdlib.h> +#include <string.h> +#include <assert.h> +#include <ipxe/crypto.h> +#include <ipxe/test.h> +#include "pubkey_test.h" + +/** + * Report public key encryption and decryption test result + * + * @v test Public key encryption and decryption test + * @v file Test code file + * @v line Test code line + */ +void pubkey_okx ( struct pubkey_test *test, const char *file, + unsigned int line ) { + struct pubkey_algorithm *pubkey = test->pubkey; + struct asn1_builder plaintext; + struct asn1_builder ciphertext; + + /* Test key matching */ + okx ( pubkey_match ( pubkey, &test->private, &test->public ) == 0, + file, line ); + + /* Test decrypting with private key to obtain known plaintext */ + plaintext.data = NULL; + plaintext.len = 0; + okx ( pubkey_decrypt ( pubkey, &test->private, &test->ciphertext, + &plaintext ) == 0, file, line ); + okx ( asn1_compare ( asn1_built ( &plaintext ), + &test->plaintext ) == 0, file, line ); + free ( plaintext.data ); + + /* Test encrypting with private key and decrypting with public key */ + ciphertext.data = NULL; + ciphertext.len = 0; + plaintext.data = NULL; + plaintext.len = 0; + okx ( pubkey_encrypt ( pubkey, &test->private, &test->plaintext, + &ciphertext ) == 0, file, line ); + okx ( pubkey_decrypt ( pubkey, &test->public, + asn1_built ( &ciphertext ), + &plaintext ) == 0, file, line ); + okx ( asn1_compare ( asn1_built ( &plaintext ), + &test->plaintext ) == 0, file, line ); + free ( ciphertext.data ); + free ( plaintext.data ); + + /* Test encrypting with public key and decrypting with private key */ + ciphertext.data = NULL; + ciphertext.len = 0; + plaintext.data = NULL; + plaintext.len = 0; + okx ( pubkey_encrypt ( pubkey, &test->public, &test->plaintext, + &ciphertext ) == 0, file, line ); + okx ( pubkey_decrypt ( pubkey, &test->private, + asn1_built ( &ciphertext ), + &plaintext ) == 0, file, line ); + okx ( asn1_compare ( asn1_built ( &plaintext ), + &test->plaintext ) == 0, file, line ); + free ( ciphertext.data ); + free ( plaintext.data ); +} + +/** + * Report public key signature test result + * + * @v test Public key signature test + * @v file Test code file + * @v line Test code line + */ +void pubkey_sign_okx ( struct pubkey_sign_test *test, const char *file, + unsigned int line ) { + struct pubkey_algorithm *pubkey = test->pubkey; + struct digest_algorithm *digest = test->digest; + uint8_t digestctx[digest->ctxsize]; + uint8_t digestout[digest->digestsize]; + uint8_t signature[test->signature.len]; + struct asn1_cursor cursor = { signature, sizeof ( signature ) }; + struct asn1_builder builder = { NULL, 0 }; + uint8_t *bad; + + /* Test key matching */ + okx ( pubkey_match ( pubkey, &test->private, &test->public ) == 0, + file, line ); + + /* Construct digest over plaintext */ + digest_init ( digest, digestctx ); + digest_update ( digest, digestctx, test->plaintext, + test->plaintext_len ); + digest_final ( digest, digestctx, digestout ); + + /* Test verification using public key */ + okx ( pubkey_verify ( pubkey, &test->public, digest, digestout, + &test->signature ) == 0, file, line ); + + /* Test verification failure of modified signature */ + memcpy ( signature, test->signature.data, sizeof ( signature ) ); + bad = ( signature + ( sizeof ( signature ) / 2 ) ); + *bad ^= 0x40; + okx ( pubkey_verify ( pubkey, &test->public, digest, digestout, + &cursor ) != 0, file, line ); + *bad ^= 0x40; + okx ( pubkey_verify ( pubkey, &test->public, digest, digestout, + &cursor ) == 0, file, line ); + + /* Test signing using private key */ + okx ( pubkey_sign ( pubkey, &test->private, digest, digestout, + &builder ) == 0, file, line ); + okx ( builder.len != 0, file, line ); + okx ( asn1_compare ( asn1_built ( &builder ), &test->signature ) == 0, + file, line ); + + /* Test verification of constructed signature */ + okx ( pubkey_verify ( pubkey, &test->public, digest, digestout, + asn1_built ( &builder ) ) == 0, file, line ); + + /* Free signature */ + free ( builder.data ); +} diff --git a/src/tests/pubkey_test.h b/src/tests/pubkey_test.h index cd65b8703..33b301a6e 100644 --- a/src/tests/pubkey_test.h +++ b/src/tests/pubkey_test.h @@ -7,169 +7,151 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); #include <ipxe/crypto.h> #include <ipxe/test.h> -/** - * Report public key decryption test result - * - * @v pubkey Public key algorithm - * @v key Key - * @v key_len Key length - * @v ciphertext Ciphertext - * @v ciphertext_len Ciphertext length - * @v expected Expected plaintext - * @v expected_len Expected plaintext length - */ -#define pubkey_decrypt_ok( pubkey, key, key_len, ciphertext, \ - ciphertext_len, expected, expected_len ) do {\ - uint8_t ctx[ (pubkey)->ctxsize ]; \ - \ - ok ( pubkey_init ( (pubkey), ctx, (key), (key_len) ) == 0 ); \ - { \ - size_t max_len = pubkey_max_len ( (pubkey), ctx ); \ - uint8_t decrypted[ max_len ]; \ - int decrypted_len; \ - \ - decrypted_len = pubkey_decrypt ( (pubkey), ctx, \ - (ciphertext), \ - (ciphertext_len), \ - decrypted ); \ - ok ( decrypted_len == ( ( int ) (expected_len) ) ); \ - ok ( memcmp ( decrypted, (expected), \ - (expected_len) ) == 0 ); \ - } \ - pubkey_final ( (pubkey), ctx ); \ - } while ( 0 ) +/** A public-key encryption and decryption test */ +struct pubkey_test { + /** Public-key algorithm */ + struct pubkey_algorithm *pubkey; + /** Private key */ + const struct asn1_cursor private; + /** Public key */ + const struct asn1_cursor public; + /** Plaintext */ + const struct asn1_cursor plaintext; + /** Ciphertext + * + * Note that the encryption process may include some random + * padding, so a given plaintext will encrypt to multiple + * different ciphertexts. + */ + const struct asn1_cursor ciphertext; +}; + +/** A public-key signature test */ +struct pubkey_sign_test { + /** Public-key algorithm */ + struct pubkey_algorithm *pubkey; + /** Private key */ + const struct asn1_cursor private; + /** Public key */ + const struct asn1_cursor public; + /** Plaintext */ + const void *plaintext; + /** Plaintext length */ + size_t plaintext_len; + /** Signature algorithm */ + struct digest_algorithm *digest; + /** Signature */ + const struct asn1_cursor signature; +}; + +/** Define inline private key data */ +#define PRIVATE(...) { __VA_ARGS__ } + +/** Define inline public key data */ +#define PUBLIC(...) { __VA_ARGS__ } + +/** Define inline plaintext data */ +#define PLAINTEXT(...) { __VA_ARGS__ } + +/** Define inline ciphertext data */ +#define CIPHERTEXT(...) { __VA_ARGS__ } + +/** Define inline signature data */ +#define SIGNATURE(...) { __VA_ARGS__ } /** - * Report public key encryption and decryption test result + * Define a public-key encryption and decryption test * - * @v pubkey Public key algorithm - * @v encrypt_key Encryption key - * @v encrypt_key_len Encryption key length - * @v decrypt_key Decryption key - * @v decrypt_key_len Decryption key length - * @v plaintext Plaintext - * @v plaintext_len Plaintext length + * @v name Test name + * @v PUBKEY Public-key algorithm + * @v PRIVATE Private key + * @v PUBLIC Public key + * @v PLAINTEXT Plaintext + * @v CIPHERTEXT Ciphertext + * @ret test Encryption and decryption test */ -#define pubkey_encrypt_ok( pubkey, encrypt_key, encrypt_key_len, \ - decrypt_key, decrypt_key_len, plaintext, \ - plaintext_len ) do { \ - uint8_t ctx[ (pubkey)->ctxsize ]; \ - \ - ok ( pubkey_init ( (pubkey), ctx, (encrypt_key), \ - (encrypt_key_len) ) == 0 ); \ - { \ - size_t max_len = pubkey_max_len ( (pubkey), ctx ); \ - uint8_t encrypted[ max_len ]; \ - int encrypted_len; \ - \ - encrypted_len = pubkey_encrypt ( (pubkey), ctx, \ - (plaintext), \ - (plaintext_len), \ - encrypted ); \ - ok ( encrypted_len >= 0 ); \ - pubkey_decrypt_ok ( (pubkey), (decrypt_key), \ - (decrypt_key_len), encrypted, \ - encrypted_len, (plaintext), \ - (plaintext_len) ); \ - } \ - pubkey_final ( (pubkey), ctx ); \ - } while ( 0 ) +#define PUBKEY_TEST( name, PUBKEY, PRIVATE, PUBLIC, PLAINTEXT, \ + CIPHERTEXT ) \ + static const uint8_t name ## _private[] = PRIVATE; \ + static const uint8_t name ## _public[] = PUBLIC; \ + static const uint8_t name ## _plaintext[] = PLAINTEXT; \ + static const uint8_t name ## _ciphertext[] = CIPHERTEXT; \ + static struct pubkey_test name = { \ + .pubkey = PUBKEY, \ + .private = { \ + .data = name ## _private, \ + .len = sizeof ( name ## _private ), \ + }, \ + .public = { \ + .data = name ## _public, \ + .len = sizeof ( name ## _public ), \ + }, \ + .plaintext = { \ + .data = name ## _plaintext, \ + .len = sizeof ( name ## _plaintext ), \ + }, \ + .ciphertext = { \ + .data = name ## _ciphertext, \ + .len = sizeof ( name ## _ciphertext ), \ + }, \ + } /** - * Report public key signature test result + * Define a public-key signature test * - * @v pubkey Public key algorithm - * @v key Key - * @v key_len Key length - * @v digest Digest algorithm - * @v plaintext Plaintext - * @v plaintext_len Plaintext length - * @v expected Expected signature - * @v expected_len Expected signature length + * @v name Test name + * @v PUBKEY Public-key algorithm + * @v PRIVATE Private key + * @v PUBLIC Public key + * @v PLAINTEXT Plaintext + * @v DIGEST Digest algorithm + * @v SIGNATURE Signature + * @ret test Signature test */ -#define pubkey_sign_ok( pubkey, key, key_len, digest, plaintext, \ - plaintext_len, expected, expected_len ) do { \ - uint8_t ctx[ (pubkey)->ctxsize ]; \ - uint8_t digestctx[ (digest)->ctxsize ]; \ - uint8_t digestout[ (digest)->digestsize ]; \ - \ - digest_init ( (digest), digestctx ); \ - digest_update ( (digest), digestctx, (plaintext), \ - (plaintext_len) ); \ - digest_final ( (digest), digestctx, digestout ); \ - \ - ok ( pubkey_init ( (pubkey), ctx, (key), (key_len) ) == 0 ); \ - { \ - size_t max_len = pubkey_max_len ( (pubkey), ctx ); \ - uint8_t signature[ max_len ]; \ - int signature_len; \ - \ - signature_len = pubkey_sign ( (pubkey), ctx, (digest), \ - digestout, signature ); \ - ok ( signature_len == ( ( int ) (expected_len) ) ); \ - ok ( memcmp ( signature, (expected), \ - (expected_len) ) == 0 ); \ - } \ - pubkey_final ( (pubkey), ctx ); \ - } while ( 0 ) +#define PUBKEY_SIGN_TEST( name, PUBKEY, PRIVATE, PUBLIC, PLAINTEXT, \ + DIGEST, SIGNATURE ) \ + static const uint8_t name ## _private[] = PRIVATE; \ + static const uint8_t name ## _public[] = PUBLIC; \ + static const uint8_t name ## _plaintext[] = PLAINTEXT; \ + static const uint8_t name ## _signature[] = SIGNATURE; \ + static struct pubkey_sign_test name = { \ + .pubkey = PUBKEY, \ + .private = { \ + .data = name ## _private, \ + .len = sizeof ( name ## _private ), \ + }, \ + .public = { \ + .data = name ## _public, \ + .len = sizeof ( name ## _public ), \ + }, \ + .plaintext = name ## _plaintext, \ + .plaintext_len = sizeof ( name ## _plaintext ), \ + .digest = DIGEST, \ + .signature = { \ + .data = name ## _signature, \ + .len = sizeof ( name ## _signature ), \ + }, \ + } + +extern void pubkey_okx ( struct pubkey_test *test, + const char *file, unsigned int line ); +extern void pubkey_sign_okx ( struct pubkey_sign_test *test, + const char *file, unsigned int line ); /** - * Report public key verification test result + * Report a public key encryption and decryption test result * - * @v pubkey Public key algorithm - * @v key Key - * @v key_len Key length - * @v digest Digest algorithm - * @v plaintext Plaintext - * @v plaintext_len Plaintext length - * @v signature Signature - * @v signature_len Signature length + * @v test Public key encryption and decryption test */ -#define pubkey_verify_ok( pubkey, key, key_len, digest, plaintext, \ - plaintext_len, signature, signature_len ) do {\ - uint8_t ctx[ (pubkey)->ctxsize ]; \ - uint8_t digestctx[ (digest)->ctxsize ]; \ - uint8_t digestout[ (digest)->digestsize ]; \ - \ - digest_init ( (digest), digestctx ); \ - digest_update ( (digest), digestctx, (plaintext), \ - (plaintext_len) ); \ - digest_final ( (digest), digestctx, digestout ); \ - \ - ok ( pubkey_init ( (pubkey), ctx, (key), (key_len) ) == 0 ); \ - ok ( pubkey_verify ( (pubkey), ctx, (digest), digestout, \ - (signature), (signature_len) ) == 0 ); \ - pubkey_final ( (pubkey), ctx ); \ - } while ( 0 ) +#define pubkey_ok( test ) \ + pubkey_okx ( test, __FILE__, __LINE__ ) /** - * Report public key verification test result + * Report a public key signature test result * - * @v pubkey Public key algorithm - * @v key Key - * @v key_len Key length - * @v digest Digest algorithm - * @v plaintext Plaintext - * @v plaintext_len Plaintext length - * @v signature Signature - * @v signature_len Signature length + * @v test Public key signature test */ -#define pubkey_verify_fail_ok( pubkey, key, key_len, digest, plaintext, \ - plaintext_len, signature, \ - signature_len ) do { \ - uint8_t ctx[ (pubkey)->ctxsize ]; \ - uint8_t digestctx[ (digest)->ctxsize ]; \ - uint8_t digestout[ (digest)->digestsize ]; \ - \ - digest_init ( (digest), digestctx ); \ - digest_update ( (digest), digestctx, (plaintext), \ - (plaintext_len) ); \ - digest_final ( (digest), digestctx, digestout ); \ - \ - ok ( pubkey_init ( (pubkey), ctx, (key), (key_len) ) == 0 ); \ - ok ( pubkey_verify ( (pubkey), ctx, (digest), digestout, \ - (signature), (signature_len) ) != 0 ); \ - pubkey_final ( (pubkey), ctx ); \ - } while ( 0 ) +#define pubkey_sign_ok( test ) \ + pubkey_sign_okx ( test, __FILE__, __LINE__ ) #endif /* _PUBKEY_TEST_H */ diff --git a/src/tests/rsa_test.c b/src/tests/rsa_test.c index 46894f603..13160934a 100644 --- a/src/tests/rsa_test.c +++ b/src/tests/rsa_test.c @@ -43,171 +43,8 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); #include <ipxe/test.h> #include "pubkey_test.h" -/** Define inline private key data */ -#define PRIVATE(...) { __VA_ARGS__ } - -/** Define inline public key data */ -#define PUBLIC(...) { __VA_ARGS__ } - -/** Define inline plaintext data */ -#define PLAINTEXT(...) { __VA_ARGS__ } - -/** Define inline ciphertext data */ -#define CIPHERTEXT(...) { __VA_ARGS__ } - -/** Define inline signature data */ -#define SIGNATURE(...) { __VA_ARGS__ } - -/** An RSA encryption and decryption self-test */ -struct rsa_encrypt_decrypt_test { - /** Private key */ - const void *private; - /** Private key length */ - size_t private_len; - /** Public key */ - const void *public; - /** Public key length */ - size_t public_len; - /** Plaintext */ - const void *plaintext; - /** Plaintext length */ - size_t plaintext_len; - /** Ciphertext - * - * Note that the encryption process includes some random - * padding, so a given plaintext will encrypt to multiple - * different ciphertexts. - */ - const void *ciphertext; - /** Ciphertext length */ - size_t ciphertext_len; -}; - -/** - * Define an RSA encryption and decryption test - * - * @v name Test name - * @v PRIVATE Private key - * @v PUBLIC Public key - * @v PLAINTEXT Plaintext - * @v CIPHERTEXT Ciphertext - * @ret test Encryption and decryption test - */ -#define RSA_ENCRYPT_DECRYPT_TEST( name, PRIVATE, PUBLIC, PLAINTEXT, \ - CIPHERTEXT ) \ - static const uint8_t name ## _private[] = PRIVATE; \ - static const uint8_t name ## _public[] = PUBLIC; \ - static const uint8_t name ## _plaintext[] = PLAINTEXT; \ - static const uint8_t name ## _ciphertext[] = CIPHERTEXT; \ - static struct rsa_encrypt_decrypt_test name = { \ - .private = name ## _private, \ - .private_len = sizeof ( name ## _private ), \ - .public = name ## _public, \ - .public_len = sizeof ( name ## _public ), \ - .plaintext = name ## _plaintext, \ - .plaintext_len = sizeof ( name ## _plaintext ), \ - .ciphertext = name ## _ciphertext, \ - .ciphertext_len = sizeof ( name ## _ciphertext ), \ - } - -/** An RSA signature self-test */ -struct rsa_signature_test { - /** Private key */ - const void *private; - /** Private key length */ - size_t private_len; - /** Public key */ - const void *public; - /** Public key length */ - size_t public_len; - /** Plaintext */ - const void *plaintext; - /** Plaintext length */ - size_t plaintext_len; - /** Signature algorithm */ - struct asn1_algorithm *algorithm; - /** Signature */ - const void *signature; - /** Signature length */ - size_t signature_len; -}; - -/** - * Define an RSA signature test - * - * @v name Test name - * @v PRIVATE Private key - * @v PUBLIC Public key - * @v PLAINTEXT Plaintext - * @v ALGORITHM Signature algorithm - * @v SIGNATURE Signature - * @ret test Signature test - */ -#define RSA_SIGNATURE_TEST( name, PRIVATE, PUBLIC, PLAINTEXT, \ - ALGORITHM, SIGNATURE ) \ - static const uint8_t name ## _private[] = PRIVATE; \ - static const uint8_t name ## _public[] = PUBLIC; \ - static const uint8_t name ## _plaintext[] = PLAINTEXT; \ - static const uint8_t name ## _signature[] = SIGNATURE; \ - static struct rsa_signature_test name = { \ - .private = name ## _private, \ - .private_len = sizeof ( name ## _private ), \ - .public = name ## _public, \ - .public_len = sizeof ( name ## _public ), \ - .plaintext = name ## _plaintext, \ - .plaintext_len = sizeof ( name ## _plaintext ), \ - .algorithm = ALGORITHM, \ - .signature = name ## _signature, \ - .signature_len = sizeof ( name ## _signature ), \ - } - -/** - * Report RSA encryption and decryption test result - * - * @v test RSA encryption and decryption test - */ -#define rsa_encrypt_decrypt_ok( test ) do { \ - pubkey_decrypt_ok ( &rsa_algorithm, (test)->private, \ - (test)->private_len, (test)->ciphertext, \ - (test)->ciphertext_len, (test)->plaintext, \ - (test)->plaintext_len ); \ - pubkey_encrypt_ok ( &rsa_algorithm, (test)->private, \ - (test)->private_len, (test)->public, \ - (test)->public_len, (test)->plaintext, \ - (test)->plaintext_len ); \ - pubkey_encrypt_ok ( &rsa_algorithm, (test)->public, \ - (test)->public_len, (test)->private, \ - (test)->private_len, (test)->plaintext, \ - (test)->plaintext_len ); \ - } while ( 0 ) - - -/** - * Report RSA signature test result - * - * @v test RSA signature test - */ -#define rsa_signature_ok( test ) do { \ - struct digest_algorithm *digest = (test)->algorithm->digest; \ - uint8_t bad_signature[ (test)->signature_len ]; \ - pubkey_sign_ok ( &rsa_algorithm, (test)->private, \ - (test)->private_len, digest, \ - (test)->plaintext, (test)->plaintext_len, \ - (test)->signature, (test)->signature_len ); \ - pubkey_verify_ok ( &rsa_algorithm, (test)->public, \ - (test)->public_len, digest, \ - (test)->plaintext, (test)->plaintext_len, \ - (test)->signature, (test)->signature_len ); \ - memset ( bad_signature, 0, sizeof ( bad_signature ) ); \ - pubkey_verify_fail_ok ( &rsa_algorithm, (test)->public, \ - (test)->public_len, digest, \ - (test)->plaintext, \ - (test)->plaintext_len, bad_signature, \ - sizeof ( bad_signature ) ); \ - } while ( 0 ) - /** "Hello world" encryption and decryption test (traditional PKCS#1 key) */ -RSA_ENCRYPT_DECRYPT_TEST ( hw_test, +PUBKEY_TEST ( hw_test, &rsa_algorithm, PRIVATE ( 0x30, 0x82, 0x01, 0x3b, 0x02, 0x01, 0x00, 0x02, 0x41, 0x00, 0xd2, 0xf1, 0x04, 0x67, 0xf6, 0x2c, 0x96, 0x07, 0xa6, 0xbd, 0x85, 0xac, 0xc1, 0x17, 0x5d, 0xe8, 0xf0, 0x93, 0x94, 0x0c, @@ -261,7 +98,7 @@ RSA_ENCRYPT_DECRYPT_TEST ( hw_test, 0x38, 0x43, 0xf9, 0x41 ) ); /** "Hello world" encryption and decryption test (PKCS#8 key) */ -RSA_ENCRYPT_DECRYPT_TEST ( hw_test_pkcs8, +PUBKEY_TEST ( hw_test_pkcs8, &rsa_algorithm, PRIVATE ( 0x30, 0x82, 0x01, 0x55, 0x02, 0x01, 0x00, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x04, 0x82, 0x01, 0x3f, 0x30, 0x82, 0x01, 0x3b, @@ -318,7 +155,7 @@ RSA_ENCRYPT_DECRYPT_TEST ( hw_test_pkcs8, 0x38, 0x43, 0xf9, 0x41 ) ); /** Random message MD5 signature test */ -RSA_SIGNATURE_TEST ( md5_test, +PUBKEY_SIGN_TEST ( md5_test, &rsa_algorithm, PRIVATE ( 0x30, 0x82, 0x01, 0x3b, 0x02, 0x01, 0x00, 0x02, 0x41, 0x00, 0xf9, 0x3f, 0x78, 0x44, 0xe2, 0x0e, 0x25, 0xf1, 0x0e, 0x94, 0xcd, 0xca, 0x6f, 0x9e, 0xea, 0x6d, 0xdf, 0xcd, 0xa0, 0x7c, @@ -381,7 +218,7 @@ RSA_SIGNATURE_TEST ( md5_test, 0xf2, 0x8d, 0xfc, 0xfc, 0x37, 0xf7, 0xc7, 0x6d, 0x6c, 0xd8, 0x24, 0x0c, 0x6a, 0xec, 0x82, 0x5c, 0x72, 0xf1, 0xfc, 0x05, 0xed, 0x8e, 0xe8, 0xd9, 0x8b, 0x8b, 0x67, 0x02, 0x95 ), - &md5_with_rsa_encryption_algorithm, + &md5_algorithm, SIGNATURE ( 0xdb, 0x56, 0x3d, 0xea, 0xae, 0x81, 0x4b, 0x3b, 0x2e, 0x8e, 0xb8, 0xee, 0x13, 0x61, 0xc6, 0xe7, 0xd7, 0x50, 0xcd, 0x0d, 0x34, 0x3a, 0xfe, 0x9a, 0x8d, 0xf8, 0xfb, 0xd6, 0x7e, 0xbd, @@ -391,7 +228,7 @@ RSA_SIGNATURE_TEST ( md5_test, 0xac, 0x45, 0x00, 0xa8 ) ); /** Random message SHA-1 signature test */ -RSA_SIGNATURE_TEST ( sha1_test, +PUBKEY_SIGN_TEST ( sha1_test, &rsa_algorithm, PRIVATE ( 0x30, 0x82, 0x01, 0x3b, 0x02, 0x01, 0x00, 0x02, 0x41, 0x00, 0xe0, 0x3a, 0x8d, 0x35, 0xe1, 0x92, 0x2f, 0xea, 0x0d, 0x82, 0x60, 0x2e, 0xb6, 0x0b, 0x02, 0xd3, 0xf4, 0x39, 0xfb, 0x06, @@ -454,7 +291,7 @@ RSA_SIGNATURE_TEST ( sha1_test, 0x30, 0x91, 0x1c, 0xaa, 0x6c, 0x24, 0x42, 0x1b, 0x1a, 0xba, 0x30, 0x40, 0x49, 0x83, 0xd9, 0xd7, 0x66, 0x7e, 0x5c, 0x1a, 0x4b, 0x7f, 0xa6, 0x8e, 0x8a, 0xd6, 0x0c, 0x65, 0x75 ), - &sha1_with_rsa_encryption_algorithm, + &sha1_algorithm, SIGNATURE ( 0xa5, 0x5a, 0x8a, 0x67, 0x81, 0x76, 0x7e, 0xad, 0x99, 0x22, 0xf1, 0x47, 0x64, 0xd2, 0xfb, 0x81, 0x45, 0xeb, 0x85, 0x56, 0xf8, 0x7d, 0xb8, 0xec, 0x41, 0x17, 0x84, 0xf7, 0x2b, 0xbb, @@ -464,7 +301,7 @@ RSA_SIGNATURE_TEST ( sha1_test, 0x0e, 0x3d, 0x80, 0x80 ) ); /** Random message SHA-256 signature test */ -RSA_SIGNATURE_TEST ( sha256_test, +PUBKEY_SIGN_TEST ( sha256_test, &rsa_algorithm, PRIVATE ( 0x30, 0x82, 0x01, 0x3a, 0x02, 0x01, 0x00, 0x02, 0x41, 0x00, 0xa5, 0xe9, 0xdb, 0xa9, 0x1a, 0x6e, 0xd6, 0x4c, 0x25, 0x50, 0xfe, 0x61, 0x77, 0x08, 0x7a, 0x80, 0x36, 0xcb, 0x88, 0x49, @@ -527,7 +364,7 @@ RSA_SIGNATURE_TEST ( sha256_test, 0x91, 0x71, 0xd6, 0x2d, 0xa1, 0xae, 0x81, 0x0c, 0xed, 0x54, 0x48, 0x79, 0x8a, 0x78, 0x05, 0x74, 0x4d, 0x4f, 0xf0, 0xe0, 0x3c, 0x41, 0x5c, 0x04, 0x0b, 0x68, 0x57, 0xc5, 0xd6 ), - &sha256_with_rsa_encryption_algorithm, + &sha256_algorithm, SIGNATURE ( 0x02, 0x2e, 0xc5, 0x2a, 0x2b, 0x7f, 0xb4, 0x80, 0xca, 0x9d, 0x96, 0x5b, 0xaf, 0x1f, 0x72, 0x5b, 0x6e, 0xf1, 0x69, 0x7f, 0x4d, 0x41, 0xd5, 0x9f, 0x00, 0xdc, 0x47, 0xf4, 0x68, 0x8f, @@ -542,11 +379,11 @@ RSA_SIGNATURE_TEST ( sha256_test, */ static void rsa_test_exec ( void ) { - rsa_encrypt_decrypt_ok ( &hw_test ); - rsa_encrypt_decrypt_ok ( &hw_test_pkcs8 ); - rsa_signature_ok ( &md5_test ); - rsa_signature_ok ( &sha1_test ); - rsa_signature_ok ( &sha256_test ); + pubkey_ok ( &hw_test ); + pubkey_ok ( &hw_test_pkcs8 ); + pubkey_sign_ok ( &md5_test ); + pubkey_sign_ok ( &sha1_test ); + pubkey_sign_ok ( &sha256_test ); } /** RSA self-test */ @@ -554,3 +391,9 @@ struct self_test rsa_test __self_test = { .name = "rsa", .exec = rsa_test_exec, }; + +/* Drag in required ASN.1 OID-identified algorithms */ +REQUIRING_SYMBOL ( rsa_test ); +REQUIRE_OBJECT ( rsa_md5 ); +REQUIRE_OBJECT ( rsa_sha1 ); +REQUIRE_OBJECT ( rsa_sha256 ); diff --git a/src/tests/string_test.c b/src/tests/string_test.c index 3afb8deb2..6662848d3 100644 --- a/src/tests/string_test.c +++ b/src/tests/string_test.c @@ -38,6 +38,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); #include <stdio.h> #include <string.h> #include <strings.h> +#include <wchar.h> #include <ipxe/string.h> #include <ipxe/test.h> @@ -204,6 +205,24 @@ static void string_test_exec ( void ) { free ( dup ); } + /* Test stpcpy() */ + { + const char longer[12] = "duplicateme"; + const char shorter[6] = "hello"; + char dest[12]; + char *dnul; + + dnul = stpcpy ( dest, longer ); + ok ( *dnul == '\0' ); + ok ( dnul == &dest[11] ); + ok ( memcmp ( dest, longer, 12 ) == 0 ); + dnul = stpcpy ( dest, shorter ); + ok ( *dnul == '\0' ); + ok ( dnul == &dest[5] ); + ok ( memcmp ( dest, shorter, 6 ) == 0 ); + ok ( memcmp ( ( dest + 6 ), ( longer + 6 ), 6 ) == 0 ); + } + /* Test strcpy() */ { const char longer[7] = "copyme"; @@ -304,6 +323,23 @@ static void string_test_exec ( void ) { + 17 ) * 26 + 10 ) ); ok ( endp == &string[6] ); } + + /* Test wcslen() */ + ok ( wcslen ( L"" ) == 0 ); + ok ( wcslen ( L"Helloo" ) == 6 ); + ok ( wcslen ( L"Helloo woorld!" ) == 14 ); + ok ( wcslen ( L"Helloo\0woorld!" ) == 6 ); + + /* Test wcsnlen() */ + ok ( wcsnlen ( L"", 0 ) == 0 ); + ok ( wcsnlen ( L"", 10 ) == 0 ); + ok ( wcsnlen ( L"Helloo", 0 ) == 0 ); + ok ( wcsnlen ( L"Helloo", 3 ) == 3 ); + ok ( wcsnlen ( L"Helloo", 5 ) == 5 ); + ok ( wcsnlen ( L"Helloo", 16 ) == 6 ); + ok ( wcsnlen ( L"Helloo woorld!", 5 ) == 5 ); + ok ( wcsnlen ( L"Helloo woorld!", 11 ) == 11 ); + ok ( wcsnlen ( L"Helloo woorld!", 16 ) == 14 ); } /** String self-test */ diff --git a/src/tests/test.c b/src/tests/test.c index 4c49d4c16..e4f5eb838 100644 --- a/src/tests/test.c +++ b/src/tests/test.c @@ -34,6 +34,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); #include <stddef.h> #include <stdio.h> +#include <string.h> #include <errno.h> #include <assert.h> #include <ipxe/test.h> @@ -161,6 +162,7 @@ static struct image_type test_image_type = { static struct image test_image = { .refcnt = REF_INIT ( ref_no_free ), .name = "<TESTS>", + .flags = ( IMAGE_STATIC | IMAGE_STATIC_NAME ), .type = &test_image_type, }; @@ -178,5 +180,6 @@ static void test_init ( void ) { /** Self-test initialisation function */ struct init_fn test_init_fn __init_fn ( INIT_EARLY ) = { + .name = "test", .initialise = test_init, }; diff --git a/src/tests/tests.c b/src/tests/tests.c index cb296049e..130eba949 100644 --- a/src/tests/tests.c +++ b/src/tests/tests.c @@ -85,3 +85,10 @@ REQUIRE_OBJECT ( x25519_test ); REQUIRE_OBJECT ( des_test ); REQUIRE_OBJECT ( mschapv2_test ); REQUIRE_OBJECT ( uuid_test ); +REQUIRE_OBJECT ( editstring_test ); +REQUIRE_OBJECT ( p256_test ); +REQUIRE_OBJECT ( p384_test ); +REQUIRE_OBJECT ( efi_siglist_test ); +REQUIRE_OBJECT ( cpio_test ); +REQUIRE_OBJECT ( fdt_test ); +REQUIRE_OBJECT ( ecdsa_test ); diff --git a/src/tests/umalloc_test.c b/src/tests/umalloc_test.c deleted file mode 100644 index 53810833c..000000000 --- a/src/tests/umalloc_test.c +++ /dev/null @@ -1,26 +0,0 @@ -#include <stdio.h> -#include <ipxe/uaccess.h> -#include <ipxe/umalloc.h> -#include <ipxe/io.h> - -void umalloc_test ( void ) { - struct memory_map memmap; - userptr_t bob; - userptr_t fred; - - printf ( "Before allocation:\n" ); - get_memmap ( &memmap ); - - bob = umalloc ( 1234 ); - bob = urealloc ( bob, 12345 ); - fred = umalloc ( 999 ); - - printf ( "After allocation:\n" ); - get_memmap ( &memmap ); - - ufree ( bob ); - ufree ( fred ); - - printf ( "After freeing:\n" ); - get_memmap ( &memmap ); -} diff --git a/src/tests/x25519_test.c b/src/tests/x25519_test.c index 3dfbd3393..bd348b832 100644 --- a/src/tests/x25519_test.c +++ b/src/tests/x25519_test.c @@ -263,7 +263,6 @@ static void x25519_key_okx ( struct x25519_key_test *test, struct x25519_value scalar; struct x25519_value actual; unsigned int i; - int rc; /* Construct input values */ memcpy ( &base, &test->base, sizeof ( test->base ) ); @@ -277,11 +276,11 @@ static void x25519_key_okx ( struct x25519_key_test *test, /* Calculate key */ for ( i = 0 ; i < test->count ; i++ ) { - rc = x25519_key ( &base, &scalar, &actual ); + x25519_key ( &base, &scalar, &actual ); if ( test->fail ) { - okx ( rc != 0, file, line ); + okx ( x25519_is_zero ( &actual ), file, line ); } else { - okx ( rc == 0, file, line ); + okx ( ( ! x25519_is_zero ( &actual ) ), file, line ); } memcpy ( &base, &scalar, sizeof ( base ) ); memcpy ( &scalar, &actual, sizeof ( scalar ) ); diff --git a/src/tests/x509_test.c b/src/tests/x509_test.c index 50eb4d787..1a8adc55e 100644 --- a/src/tests/x509_test.c +++ b/src/tests/x509_test.c @@ -646,6 +646,242 @@ CERTIFICATE ( bad_path_len_crt, 0x53, 0x5a, 0xc8, 0x99, 0xe5, 0xdf, 0x79, 0x07, 0x00, 0x2c, 0x9f, 0x49, 0x91, 0x21, 0xeb, 0xfc ) ); +/* + * subject iPXE self-test EC intermediate CA + * issuer iPXE self-test root CA + */ +CERTIFICATE ( ecintermediate_crt, + DATA ( 0x30, 0x82, 0x03, 0x3a, 0x30, 0x82, 0x02, 0xa3, 0xa0, 0x03, + 0x02, 0x01, 0x02, 0x02, 0x01, 0x04, 0x30, 0x0d, 0x06, 0x09, + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, + 0x00, 0x30, 0x81, 0x88, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, + 0x55, 0x04, 0x06, 0x13, 0x02, 0x47, 0x42, 0x31, 0x17, 0x30, + 0x15, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x0e, 0x43, 0x61, + 0x6d, 0x62, 0x72, 0x69, 0x64, 0x67, 0x65, 0x73, 0x68, 0x69, + 0x72, 0x65, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, + 0x07, 0x0c, 0x09, 0x43, 0x61, 0x6d, 0x62, 0x72, 0x69, 0x64, + 0x67, 0x65, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, + 0x0a, 0x0c, 0x0f, 0x46, 0x65, 0x6e, 0x20, 0x53, 0x79, 0x73, + 0x74, 0x65, 0x6d, 0x73, 0x20, 0x4c, 0x74, 0x64, 0x31, 0x11, + 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x08, 0x69, + 0x70, 0x78, 0x65, 0x2e, 0x6f, 0x72, 0x67, 0x31, 0x1f, 0x30, + 0x1d, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x16, 0x69, 0x50, + 0x58, 0x45, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2d, 0x74, 0x65, + 0x73, 0x74, 0x20, 0x72, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x41, + 0x30, 0x1e, 0x17, 0x0d, 0x32, 0x35, 0x31, 0x32, 0x31, 0x39, + 0x31, 0x34, 0x33, 0x32, 0x35, 0x39, 0x5a, 0x17, 0x0d, 0x32, + 0x38, 0x30, 0x39, 0x31, 0x34, 0x31, 0x34, 0x33, 0x32, 0x35, + 0x39, 0x5a, 0x30, 0x81, 0x93, 0x31, 0x0b, 0x30, 0x09, 0x06, + 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x47, 0x42, 0x31, 0x17, + 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x0e, 0x43, + 0x61, 0x6d, 0x62, 0x72, 0x69, 0x64, 0x67, 0x65, 0x73, 0x68, + 0x69, 0x72, 0x65, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, + 0x04, 0x07, 0x0c, 0x09, 0x43, 0x61, 0x6d, 0x62, 0x72, 0x69, + 0x64, 0x67, 0x65, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, + 0x04, 0x0a, 0x0c, 0x0f, 0x46, 0x65, 0x6e, 0x20, 0x53, 0x79, + 0x73, 0x74, 0x65, 0x6d, 0x73, 0x20, 0x4c, 0x74, 0x64, 0x31, + 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x08, + 0x69, 0x70, 0x78, 0x65, 0x2e, 0x6f, 0x72, 0x67, 0x31, 0x2a, + 0x30, 0x28, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x21, 0x69, + 0x50, 0x58, 0x45, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2d, 0x74, + 0x65, 0x73, 0x74, 0x20, 0x45, 0x43, 0x20, 0x69, 0x6e, 0x74, + 0x65, 0x72, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, 0x20, + 0x43, 0x41, 0x30, 0x59, 0x30, 0x13, 0x06, 0x07, 0x2a, 0x86, + 0x48, 0xce, 0x3d, 0x02, 0x01, 0x06, 0x08, 0x2a, 0x86, 0x48, + 0xce, 0x3d, 0x03, 0x01, 0x07, 0x03, 0x42, 0x00, 0x04, 0xf8, + 0xb9, 0xac, 0x83, 0x58, 0xf1, 0xa9, 0x6f, 0x85, 0x22, 0xf7, + 0x04, 0x8d, 0x52, 0xff, 0xef, 0x85, 0xd1, 0x43, 0xfa, 0xdb, + 0x1a, 0xa1, 0x8d, 0x8b, 0x40, 0x6f, 0x85, 0x2f, 0x38, 0x4c, + 0x19, 0x79, 0xe0, 0x6a, 0x52, 0x1f, 0x6c, 0x78, 0x3e, 0x2e, + 0x06, 0x40, 0x35, 0x8b, 0x93, 0xe8, 0xe1, 0xef, 0x37, 0x93, + 0xe6, 0x70, 0x37, 0xf3, 0x12, 0x05, 0x82, 0x46, 0xdd, 0xf2, + 0x8a, 0x26, 0x70, 0xa3, 0x81, 0xed, 0x30, 0x81, 0xea, 0x30, + 0x0f, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, + 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x0e, 0x06, 0x03, + 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, + 0x02, 0x04, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, + 0x16, 0x04, 0x14, 0x15, 0x30, 0x20, 0x14, 0x09, 0xba, 0x24, + 0x27, 0x38, 0x39, 0x28, 0xc9, 0x02, 0x62, 0x4e, 0x76, 0x79, + 0x91, 0x89, 0x9b, 0x30, 0x81, 0xa7, 0x06, 0x03, 0x55, 0x1d, + 0x23, 0x04, 0x81, 0x9f, 0x30, 0x81, 0x9c, 0xa1, 0x81, 0x8e, + 0xa4, 0x81, 0x8b, 0x30, 0x81, 0x88, 0x31, 0x0b, 0x30, 0x09, + 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x47, 0x42, 0x31, + 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x0e, + 0x43, 0x61, 0x6d, 0x62, 0x72, 0x69, 0x64, 0x67, 0x65, 0x73, + 0x68, 0x69, 0x72, 0x65, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, + 0x55, 0x04, 0x07, 0x0c, 0x09, 0x43, 0x61, 0x6d, 0x62, 0x72, + 0x69, 0x64, 0x67, 0x65, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, + 0x55, 0x04, 0x0a, 0x0c, 0x0f, 0x46, 0x65, 0x6e, 0x20, 0x53, + 0x79, 0x73, 0x74, 0x65, 0x6d, 0x73, 0x20, 0x4c, 0x74, 0x64, + 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, + 0x08, 0x69, 0x70, 0x78, 0x65, 0x2e, 0x6f, 0x72, 0x67, 0x31, + 0x1f, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x16, + 0x69, 0x50, 0x58, 0x45, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2d, + 0x74, 0x65, 0x73, 0x74, 0x20, 0x72, 0x6f, 0x6f, 0x74, 0x20, + 0x43, 0x41, 0x82, 0x09, 0x00, 0xc6, 0xb8, 0x9c, 0x58, 0xd2, + 0xdc, 0xc9, 0x5d, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, + 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x81, + 0x81, 0x00, 0x19, 0x30, 0x56, 0x0d, 0x5d, 0x6c, 0x4d, 0x7c, + 0x68, 0x47, 0x59, 0xf1, 0xde, 0xd6, 0x6b, 0xdc, 0xa4, 0x43, + 0x01, 0x1b, 0xff, 0xb3, 0xfc, 0x78, 0xda, 0x31, 0xe0, 0x36, + 0xd8, 0x0c, 0x5d, 0x4e, 0xb7, 0x33, 0xd2, 0xb3, 0x2c, 0x41, + 0xb0, 0xc6, 0x8a, 0xba, 0x64, 0xe8, 0x85, 0x46, 0x81, 0x3a, + 0x8f, 0xef, 0x17, 0x66, 0x68, 0x91, 0xbd, 0x54, 0xea, 0x03, + 0xa4, 0xf9, 0x15, 0x47, 0x2a, 0xde, 0xeb, 0xe0, 0x2c, 0xd8, + 0x49, 0x1a, 0x10, 0xed, 0x72, 0x78, 0x77, 0x94, 0xed, 0xf9, + 0x68, 0xe6, 0x93, 0x93, 0xb5, 0x99, 0x1b, 0xd7, 0x07, 0x1d, + 0xe3, 0x94, 0xa6, 0xd3, 0x48, 0xcc, 0x7a, 0x1f, 0x59, 0xba, + 0x31, 0x23, 0xf9, 0x09, 0xe5, 0x2f, 0xda, 0xea, 0xf3, 0xd8, + 0xc8, 0xa8, 0x71, 0xb9, 0x69, 0xf3, 0x17, 0x4c, 0xc2, 0xf1, + 0x67, 0xbb, 0xf5, 0x8c, 0x4e, 0x46, 0x63, 0x58, 0x54, 0x8e ), + FINGERPRINT ( 0x21, 0x7b, 0x48, 0x59, 0xf1, 0x5e, 0x8a, 0x75, + 0xd1, 0xee, 0x60, 0x4a, 0x7d, 0x8f, 0xa8, 0xe2, + 0x6c, 0x25, 0xc4, 0x05, 0x13, 0x46, 0x65, 0x63, + 0x0b, 0x8d, 0x46, 0x52, 0x6e, 0x3c, 0x4e, 0x10 ) ); + +/* + * subject iPXE self-test EC leaf CA + * issuer iPXE self-test EC intermediate CA + */ +CERTIFICATE ( ecleaf_crt, + DATA ( 0x30, 0x82, 0x02, 0x74, 0x30, 0x82, 0x02, 0x1b, 0xa0, 0x03, + 0x02, 0x01, 0x02, 0x02, 0x01, 0x02, 0x30, 0x0a, 0x06, 0x08, + 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, 0x30, 0x81, + 0x93, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x47, 0x42, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, + 0x55, 0x04, 0x08, 0x0c, 0x0e, 0x43, 0x61, 0x6d, 0x62, 0x72, + 0x69, 0x64, 0x67, 0x65, 0x73, 0x68, 0x69, 0x72, 0x65, 0x31, + 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0c, 0x09, + 0x43, 0x61, 0x6d, 0x62, 0x72, 0x69, 0x64, 0x67, 0x65, 0x31, + 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x0f, + 0x46, 0x65, 0x6e, 0x20, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, + 0x73, 0x20, 0x4c, 0x74, 0x64, 0x31, 0x11, 0x30, 0x0f, 0x06, + 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x08, 0x69, 0x70, 0x78, 0x65, + 0x2e, 0x6f, 0x72, 0x67, 0x31, 0x2a, 0x30, 0x28, 0x06, 0x03, + 0x55, 0x04, 0x03, 0x0c, 0x21, 0x69, 0x50, 0x58, 0x45, 0x20, + 0x73, 0x65, 0x6c, 0x66, 0x2d, 0x74, 0x65, 0x73, 0x74, 0x20, + 0x45, 0x43, 0x20, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6d, 0x65, + 0x64, 0x69, 0x61, 0x74, 0x65, 0x20, 0x43, 0x41, 0x30, 0x1e, + 0x17, 0x0d, 0x32, 0x35, 0x31, 0x32, 0x31, 0x39, 0x31, 0x34, + 0x33, 0x32, 0x35, 0x39, 0x5a, 0x17, 0x0d, 0x32, 0x38, 0x30, + 0x39, 0x31, 0x34, 0x31, 0x34, 0x33, 0x32, 0x35, 0x39, 0x5a, + 0x30, 0x81, 0x8b, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, + 0x04, 0x06, 0x13, 0x02, 0x47, 0x42, 0x31, 0x17, 0x30, 0x15, + 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x0e, 0x43, 0x61, 0x6d, + 0x62, 0x72, 0x69, 0x64, 0x67, 0x65, 0x73, 0x68, 0x69, 0x72, + 0x65, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x07, + 0x0c, 0x09, 0x43, 0x61, 0x6d, 0x62, 0x72, 0x69, 0x64, 0x67, + 0x65, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x0a, + 0x0c, 0x0f, 0x46, 0x65, 0x6e, 0x20, 0x53, 0x79, 0x73, 0x74, + 0x65, 0x6d, 0x73, 0x20, 0x4c, 0x74, 0x64, 0x31, 0x11, 0x30, + 0x0f, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x08, 0x69, 0x70, + 0x78, 0x65, 0x2e, 0x6f, 0x72, 0x67, 0x31, 0x22, 0x30, 0x20, + 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x19, 0x69, 0x50, 0x58, + 0x45, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2d, 0x74, 0x65, 0x73, + 0x74, 0x20, 0x45, 0x43, 0x20, 0x6c, 0x65, 0x61, 0x66, 0x20, + 0x43, 0x41, 0x30, 0x59, 0x30, 0x13, 0x06, 0x07, 0x2a, 0x86, + 0x48, 0xce, 0x3d, 0x02, 0x01, 0x06, 0x08, 0x2a, 0x86, 0x48, + 0xce, 0x3d, 0x03, 0x01, 0x07, 0x03, 0x42, 0x00, 0x04, 0xa4, + 0x10, 0x14, 0x39, 0xde, 0x28, 0x87, 0x52, 0xb0, 0xe3, 0x87, + 0x1b, 0x0f, 0xeb, 0xdf, 0x9b, 0x78, 0x47, 0xeb, 0x76, 0xbb, + 0xf6, 0x6d, 0x26, 0x0e, 0x2b, 0xec, 0xd2, 0x8e, 0x78, 0xac, + 0x35, 0x44, 0xd7, 0x79, 0x3f, 0x97, 0x01, 0x8e, 0x8f, 0x08, + 0xcb, 0x87, 0x1e, 0xd2, 0xba, 0x1b, 0x4b, 0xd2, 0x93, 0x99, + 0x62, 0x05, 0xeb, 0x75, 0x2a, 0x8f, 0xf9, 0xdb, 0x9c, 0xf4, + 0xbb, 0x60, 0x8d, 0xa3, 0x66, 0x30, 0x64, 0x30, 0x12, 0x06, + 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30, + 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x00, 0x30, 0x0e, 0x06, + 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, + 0x02, 0x02, 0x04, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, + 0x04, 0x16, 0x04, 0x14, 0xbc, 0xca, 0xd5, 0xfb, 0x11, 0x6d, + 0xf4, 0xa8, 0x43, 0x12, 0x5f, 0x72, 0xe8, 0x28, 0xe1, 0x9a, + 0xe8, 0xd5, 0xc7, 0x7f, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, + 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x15, 0x30, 0x20, + 0x14, 0x09, 0xba, 0x24, 0x27, 0x38, 0x39, 0x28, 0xc9, 0x02, + 0x62, 0x4e, 0x76, 0x79, 0x91, 0x89, 0x9b, 0x30, 0x0a, 0x06, + 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, 0x03, + 0x47, 0x00, 0x30, 0x44, 0x02, 0x20, 0x22, 0x73, 0x07, 0xe2, + 0x21, 0xaa, 0xc5, 0x0a, 0x88, 0x51, 0xd6, 0x8e, 0x51, 0xf7, + 0x67, 0x88, 0x6e, 0xe4, 0xe4, 0x14, 0xb7, 0x5b, 0x4d, 0xd1, + 0xfc, 0x21, 0xc8, 0xd8, 0x94, 0xf6, 0x7e, 0x54, 0x02, 0x20, + 0x33, 0x2a, 0x0c, 0x58, 0xfd, 0x0f, 0xd5, 0x89, 0x79, 0x60, + 0x81, 0xeb, 0x23, 0x4f, 0x49, 0x92, 0x09, 0xa5, 0x0f, 0xb6, + 0xf3, 0x52, 0xa3, 0x2e, 0xf6, 0x37, 0xbf, 0x9f, 0x9d, 0x7a, + 0xbf, 0x15 ), + FINGERPRINT ( 0xe3, 0x46, 0x2e, 0x10, 0x43, 0x1b, 0xca, 0xb8, + 0x7c, 0x2e, 0xa0, 0xd5, 0x60, 0x09, 0xb6, 0xef, + 0x5d, 0x62, 0x23, 0xe1, 0xcd, 0xbb, 0x71, 0x28, + 0xf0, 0x93, 0xd7, 0xf3, 0x6e, 0x1e, 0x71, 0xe5 ) ); + +/* + * subject boot.test.ipxe.org + * issuer iPXE self-test EC leaf CA + */ +CERTIFICATE ( ecserver_crt, + DATA ( 0x30, 0x82, 0x02, 0x43, 0x30, 0x82, 0x01, 0xe8, 0xa0, 0x03, + 0x02, 0x01, 0x02, 0x02, 0x01, 0x03, 0x30, 0x0a, 0x06, 0x08, + 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, 0x30, 0x81, + 0x8b, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x47, 0x42, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, + 0x55, 0x04, 0x08, 0x0c, 0x0e, 0x43, 0x61, 0x6d, 0x62, 0x72, + 0x69, 0x64, 0x67, 0x65, 0x73, 0x68, 0x69, 0x72, 0x65, 0x31, + 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0c, 0x09, + 0x43, 0x61, 0x6d, 0x62, 0x72, 0x69, 0x64, 0x67, 0x65, 0x31, + 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x0f, + 0x46, 0x65, 0x6e, 0x20, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, + 0x73, 0x20, 0x4c, 0x74, 0x64, 0x31, 0x11, 0x30, 0x0f, 0x06, + 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x08, 0x69, 0x70, 0x78, 0x65, + 0x2e, 0x6f, 0x72, 0x67, 0x31, 0x22, 0x30, 0x20, 0x06, 0x03, + 0x55, 0x04, 0x03, 0x0c, 0x19, 0x69, 0x50, 0x58, 0x45, 0x20, + 0x73, 0x65, 0x6c, 0x66, 0x2d, 0x74, 0x65, 0x73, 0x74, 0x20, + 0x45, 0x43, 0x20, 0x6c, 0x65, 0x61, 0x66, 0x20, 0x43, 0x41, + 0x30, 0x1e, 0x17, 0x0d, 0x32, 0x35, 0x31, 0x32, 0x31, 0x39, + 0x31, 0x34, 0x33, 0x32, 0x35, 0x39, 0x5a, 0x17, 0x0d, 0x32, + 0x36, 0x31, 0x32, 0x31, 0x39, 0x31, 0x34, 0x33, 0x32, 0x35, + 0x39, 0x5a, 0x30, 0x81, 0x84, 0x31, 0x0b, 0x30, 0x09, 0x06, + 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x47, 0x42, 0x31, 0x17, + 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x0e, 0x43, + 0x61, 0x6d, 0x62, 0x72, 0x69, 0x64, 0x67, 0x65, 0x73, 0x68, + 0x69, 0x72, 0x65, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, + 0x04, 0x07, 0x0c, 0x09, 0x43, 0x61, 0x6d, 0x62, 0x72, 0x69, + 0x64, 0x67, 0x65, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, + 0x04, 0x0a, 0x0c, 0x0f, 0x46, 0x65, 0x6e, 0x20, 0x53, 0x79, + 0x73, 0x74, 0x65, 0x6d, 0x73, 0x20, 0x4c, 0x74, 0x64, 0x31, + 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x08, + 0x69, 0x70, 0x78, 0x65, 0x2e, 0x6f, 0x72, 0x67, 0x31, 0x1b, + 0x30, 0x19, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x12, 0x62, + 0x6f, 0x6f, 0x74, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x69, + 0x70, 0x78, 0x65, 0x2e, 0x6f, 0x72, 0x67, 0x30, 0x59, 0x30, + 0x13, 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01, + 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07, + 0x03, 0x42, 0x00, 0x04, 0x81, 0xac, 0xb9, 0xde, 0x2e, 0xf9, + 0xae, 0x5c, 0x33, 0xba, 0x43, 0x54, 0xeb, 0xc6, 0x08, 0xa1, + 0xed, 0xf7, 0x6a, 0x78, 0x77, 0x8b, 0x2c, 0x59, 0x61, 0x6d, + 0x25, 0xaf, 0x2c, 0xe4, 0x3e, 0x22, 0x65, 0x85, 0xa4, 0x9a, + 0x7f, 0xe3, 0xbe, 0x6c, 0x65, 0xa1, 0x4f, 0x74, 0x60, 0x06, + 0x8b, 0xf2, 0x5f, 0xe3, 0xdf, 0x8b, 0xc2, 0xb9, 0x67, 0x0e, + 0xcc, 0x4e, 0x87, 0x53, 0x2e, 0xad, 0x71, 0xbb, 0xa3, 0x42, + 0x30, 0x40, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, + 0x16, 0x04, 0x14, 0x4f, 0xe2, 0x6c, 0x54, 0xd0, 0x6c, 0x66, + 0x39, 0xb8, 0x2a, 0x3f, 0x30, 0x6e, 0x56, 0x84, 0x3b, 0xb2, + 0x6b, 0xef, 0x89, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, + 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0xbc, 0xca, 0xd5, 0xfb, + 0x11, 0x6d, 0xf4, 0xa8, 0x43, 0x12, 0x5f, 0x72, 0xe8, 0x28, + 0xe1, 0x9a, 0xe8, 0xd5, 0xc7, 0x7f, 0x30, 0x0a, 0x06, 0x08, + 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, 0x03, 0x49, + 0x00, 0x30, 0x46, 0x02, 0x21, 0x00, 0x8d, 0x22, 0x2a, 0x92, + 0xcf, 0x39, 0xc6, 0xbe, 0x01, 0x09, 0x82, 0x75, 0x2b, 0xe2, + 0xd7, 0xf0, 0x78, 0x2e, 0xde, 0x95, 0x0a, 0xbf, 0xbe, 0x2e, + 0xb4, 0x17, 0x0f, 0x44, 0x22, 0xa4, 0x27, 0x27, 0x02, 0x21, + 0x00, 0x80, 0xa8, 0x37, 0xab, 0xd6, 0xf4, 0x38, 0x73, 0xe0, + 0x48, 0x69, 0x67, 0xbc, 0xbb, 0xfd, 0x3e, 0x2a, 0xb4, 0xe7, + 0xd0, 0x93, 0xb3, 0xff, 0xc8, 0xd0, 0x9a, 0x8b, 0xc6, 0x06, + 0xfa, 0xe3, 0x8d ), + FINGERPRINT ( 0xcf, 0x32, 0x56, 0xb9, 0x9c, 0x0c, 0x4a, 0xf5, + 0x92, 0x59, 0x90, 0x11, 0x87, 0x17, 0x85, 0xea, + 0xc8, 0x8c, 0x5e, 0x13, 0xe2, 0x09, 0xb6, 0xe9, + 0x15, 0xa8, 0xf5, 0x57, 0x93, 0x47, 0x46, 0xc2 ) ); + /** Valid certificate chain up to boot.test.ipxe.org */ CHAIN ( server_chain, &server_crt, &leaf_crt, &intermediate_crt, &root_crt ); @@ -666,6 +902,13 @@ CHAIN ( useless_chain, &useless_crt, &leaf_crt, &intermediate_crt, &root_crt ); CHAIN ( bad_path_len_chain, &bad_path_len_crt, &useless_crt, &leaf_crt, &intermediate_crt, &root_crt ); +/** Valid certificate chain up to ECDSA boot.test.ipxe.org */ +CHAIN ( ecserver_chain, + &ecserver_crt, &ecleaf_crt, &ecintermediate_crt, &root_crt ); + +/** Broken certificate chain up to ECDSA boot.test.ipxe.org */ +CHAIN ( broken_ecserver_chain, &ecserver_crt, &ecintermediate_crt, &root_crt ); + /** Empty certificate store */ static struct x509_chain empty_store = { .refcnt = REF_INIT ( ref_no_free ), @@ -706,6 +949,9 @@ static struct x509_root dummy_root = { /** Time at which all test certificates are valid */ static time_t test_time = 1332374737ULL; /* Thu Mar 22 00:05:37 2012 */ +/** Time at which all ECDSA test certificates are valid */ +static time_t ectest_time = 1766154603ULL; /* Fri 19 Dec 14:30:03 GMT 2025 */ + /** Time at which end-entity test certificates are invalid */ static time_t test_expired = 1375573111ULL; /* Sat Aug 3 23:38:31 2013 */ @@ -994,6 +1240,9 @@ static void x509_test_exec ( void ) { x509_certificate_ok ( &server_crt ); x509_certificate_ok ( ¬_ca_crt ); x509_certificate_ok ( &bad_path_len_crt ); + x509_certificate_ok ( &ecintermediate_crt ); + x509_certificate_ok ( &ecleaf_crt ); + x509_certificate_ok ( &ecserver_crt ); /* Check cache functionality */ x509_cached_ok ( &root_crt ); @@ -1003,6 +1252,9 @@ static void x509_test_exec ( void ) { x509_cached_ok ( &server_crt ); x509_cached_ok ( ¬_ca_crt ); x509_cached_ok ( &bad_path_len_crt ); + x509_cached_ok ( &ecintermediate_crt ); + x509_cached_ok ( &ecleaf_crt ); + x509_cached_ok ( &ecserver_crt ); /* Check all certificate fingerprints */ x509_fingerprint_ok ( &root_crt ); @@ -1012,6 +1264,9 @@ static void x509_test_exec ( void ) { x509_fingerprint_ok ( &server_crt ); x509_fingerprint_ok ( ¬_ca_crt ); x509_fingerprint_ok ( &bad_path_len_crt ); + x509_fingerprint_ok ( &ecintermediate_crt ); + x509_fingerprint_ok ( &ecleaf_crt ); + x509_fingerprint_ok ( &ecserver_crt ); /* Check pairwise issuing */ x509_check_issuer_ok ( &intermediate_crt, &root_crt ); @@ -1020,6 +1275,9 @@ static void x509_test_exec ( void ) { x509_check_issuer_ok ( &server_crt, &leaf_crt ); x509_check_issuer_fail_ok ( ¬_ca_crt, &server_crt ); x509_check_issuer_ok ( &bad_path_len_crt, &useless_crt ); + x509_check_issuer_ok ( &ecintermediate_crt, &root_crt ); + x509_check_issuer_ok ( &ecleaf_crt, &ecintermediate_crt ); + x509_check_issuer_ok ( &ecserver_crt, &ecleaf_crt ); /* Check root certificate stores */ x509_check_root_ok ( &root_crt, &test_root ); @@ -1061,6 +1319,8 @@ static void x509_test_exec ( void ) { x509_chain_ok ( ¬_ca_chain ); x509_chain_ok ( &useless_chain ); x509_chain_ok ( &bad_path_len_chain ); + x509_chain_ok ( &ecserver_chain ); + x509_chain_ok ( &broken_ecserver_chain ); /* Check certificate chains */ x509_validate_chain_ok ( &server_chain, test_time, @@ -1081,6 +1341,10 @@ static void x509_test_exec ( void ) { &empty_store, &test_root ); x509_validate_chain_fail_ok ( &bad_path_len_chain, test_time, &empty_store, &test_root ); + x509_validate_chain_ok ( &ecserver_chain, ectest_time, &empty_store, + &test_root ); + x509_validate_chain_fail_ok ( &broken_ecserver_chain, ectest_time, + &empty_store, &test_root ); /* Check certificate chain expiry times */ x509_validate_chain_fail_ok ( &server_chain, test_expired, @@ -1110,6 +1374,8 @@ static void x509_test_exec ( void ) { assert ( list_empty ( &empty_store.links ) ); /* Drop chain references */ + x509_chain_put ( broken_ecserver_chain.chain ); + x509_chain_put ( ecserver_chain.chain ); x509_chain_put ( bad_path_len_chain.chain ); x509_chain_put ( useless_chain.chain ); x509_chain_put ( not_ca_chain.chain ); @@ -1118,6 +1384,9 @@ static void x509_test_exec ( void ) { x509_chain_put ( server_chain.chain ); /* Drop certificate references */ + x509_put ( ecserver_crt.cert ); + x509_put ( ecintermediate_crt.cert ); + x509_put ( ecleaf_crt.cert ); x509_put ( bad_path_len_crt.cert ); x509_put ( not_ca_crt.cert ); x509_put ( server_crt.cert ); @@ -1135,8 +1404,9 @@ struct self_test x509_test __self_test = { /* Drag in algorithms required for tests */ REQUIRING_SYMBOL ( x509_test ); -REQUIRE_OBJECT ( rsa ); -REQUIRE_OBJECT ( sha1 ); -REQUIRE_OBJECT ( sha256 ); +REQUIRE_OBJECT ( rsa_sha1 ); +REQUIRE_OBJECT ( rsa_sha256 ); +REQUIRE_OBJECT ( ecdsa_sha256 ); +REQUIRE_OBJECT ( oid_p256 ); REQUIRE_OBJECT ( ipv4 ); REQUIRE_OBJECT ( ipv6 ); diff --git a/src/tests/zlib_test.c b/src/tests/zlib_test.c index df52d09ac..807c5e429 100644 --- a/src/tests/zlib_test.c +++ b/src/tests/zlib_test.c @@ -89,8 +89,7 @@ static void zlib_okx ( struct zlib_test *test, const char *file, struct image *extracted; /* Construct compressed image */ - image = image_memory ( test->compressed_name, - virt_to_user ( test->compressed ), + image = image_memory ( test->compressed_name, test->compressed, test->compressed_len ); okx ( image != NULL, file, line ); okx ( image->len == test->compressed_len, file, line ); @@ -103,9 +102,8 @@ static void zlib_okx ( struct zlib_test *test, const char *file, /* Verify extracted image content */ okx ( extracted->len == test->expected_len, file, line ); - okx ( memcmp_user ( extracted->data, 0, - virt_to_user ( test->expected ), 0, - test->expected_len ) == 0, file, line ); + okx ( memcmp ( extracted->data, test->expected, + test->expected_len ) == 0, file, line ); /* Verify extracted image name */ okx ( strcmp ( extracted->name, test->expected_name ) == 0, |
