summaryrefslogtreecommitdiffstats
path: root/src/tests
diff options
context:
space:
mode:
Diffstat (limited to 'src/tests')
-rw-r--r--src/tests/acpi_test.c12
-rw-r--r--src/tests/asn1_test.c4
-rw-r--r--src/tests/asn1_test.h3
-rw-r--r--src/tests/bigint_test.c1155
-rw-r--r--src/tests/bofm_test.c117
-rw-r--r--src/tests/cms_test.c509
-rw-r--r--src/tests/cpio_test.c280
-rw-r--r--src/tests/deflate_test.c30
-rw-r--r--src/tests/ecdsa_test.c274
-rw-r--r--src/tests/editstring_test.c198
-rw-r--r--src/tests/efi_siglist_test.c167
-rw-r--r--src/tests/elliptic_test.c154
-rw-r--r--src/tests/elliptic_test.h146
-rw-r--r--src/tests/fdt_test.c320
-rw-r--r--src/tests/gzip_test.c9
-rw-r--r--src/tests/iobuf_test.c8
-rw-r--r--src/tests/ipv4_test.c211
-rw-r--r--src/tests/math_test.c117
-rw-r--r--src/tests/netdev_test.c218
-rw-r--r--src/tests/netdev_test.h111
-rw-r--r--src/tests/p256_test.c291
-rw-r--r--src/tests/p384_test.c383
-rw-r--r--src/tests/pccrc_test.c6
-rw-r--r--src/tests/pixbuf_test.c9
-rw-r--r--src/tests/pixbuf_test.h3
-rw-r--r--src/tests/pubkey_test.c155
-rw-r--r--src/tests/pubkey_test.h278
-rw-r--r--src/tests/rsa_test.c195
-rw-r--r--src/tests/string_test.c36
-rw-r--r--src/tests/test.c3
-rw-r--r--src/tests/tests.c7
-rw-r--r--src/tests/umalloc_test.c26
-rw-r--r--src/tests/x25519_test.c7
-rw-r--r--src/tests/x509_test.c276
-rw-r--r--src/tests/zlib_test.c8
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 ( &not_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 ( &not_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 ( &not_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 ( &not_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 ( &not_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,