summaryrefslogtreecommitdiffstats
path: root/src/tests
diff options
context:
space:
mode:
authorSimon Rettberg2024-04-12 14:00:15 +0200
committerSimon Rettberg2024-04-12 14:00:15 +0200
commit98dc341428e247141f120d05fac48c4e144a4c0f (patch)
tree3ebacb37927e338383ac64c2e20eb0b2f820cb85 /src/tests
parentMerge branch 'master' into openslx (diff)
parentMerge branch 'ipxe:master' into aqc1xx (diff)
downloadipxe-98dc341428e247141f120d05fac48c4e144a4c0f.tar.gz
ipxe-98dc341428e247141f120d05fac48c4e144a4c0f.tar.xz
ipxe-98dc341428e247141f120d05fac48c4e144a4c0f.zip
Merge branch 'aqc1xx' into openslx
Diffstat (limited to 'src/tests')
-rw-r--r--src/tests/aes_test.c11
-rw-r--r--src/tests/bigint_test.c112
-rw-r--r--src/tests/des_test.c898
-rw-r--r--src/tests/list_test.c48
-rw-r--r--src/tests/mschapv2_test.c144
-rw-r--r--src/tests/settings_test.c14
-rw-r--r--src/tests/tests.c4
-rw-r--r--src/tests/uuid_test.c156
-rw-r--r--src/tests/x25519_test.c600
-rw-r--r--src/tests/x509_test.c17
10 files changed, 1978 insertions, 26 deletions
diff --git a/src/tests/aes_test.c b/src/tests/aes_test.c
index be119c8d..46a052a2 100644
--- a/src/tests/aes_test.c
+++ b/src/tests/aes_test.c
@@ -63,11 +63,6 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
0x2c, 0x07, 0x3b, 0x61, 0x08, 0xd7, 0x2d, 0x98, 0x10, \
0xa3, 0x09, 0x14, 0xdf, 0xf4 )
-/** Dummy initialisation vector used for NIST ECB-mode test vectors */
-#define AES_IV_NIST_DUMMY \
- IV ( 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 )
-
/** Initialisation vector used for NIST CBC-mode test vectors */
#define AES_IV_NIST_CBC \
IV ( 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, \
@@ -86,7 +81,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
/** AES-128-ECB (same test as AES-128-Core) */
CIPHER_TEST ( aes_128_ecb, &aes_ecb_algorithm,
- AES_KEY_NIST_128, AES_IV_NIST_DUMMY, ADDITIONAL(), AES_PLAINTEXT_NIST,
+ AES_KEY_NIST_128, IV(), ADDITIONAL(), AES_PLAINTEXT_NIST,
CIPHERTEXT ( 0x3a, 0xd7, 0x7b, 0xb4, 0x0d, 0x7a, 0x36, 0x60,
0xa8, 0x9e, 0xca, 0xf3, 0x24, 0x66, 0xef, 0x97,
0xf5, 0xd3, 0xd5, 0x85, 0x03, 0xb9, 0x69, 0x9d,
@@ -110,7 +105,7 @@ CIPHER_TEST ( aes_128_cbc, &aes_cbc_algorithm,
/** AES-192-ECB (same test as AES-192-Core) */
CIPHER_TEST ( aes_192_ecb, &aes_ecb_algorithm,
- AES_KEY_NIST_192, AES_IV_NIST_DUMMY, ADDITIONAL(), AES_PLAINTEXT_NIST,
+ AES_KEY_NIST_192, IV(), ADDITIONAL(), AES_PLAINTEXT_NIST,
CIPHERTEXT ( 0xbd, 0x33, 0x4f, 0x1d, 0x6e, 0x45, 0xf2, 0x5f,
0xf7, 0x12, 0xa2, 0x14, 0x57, 0x1f, 0xa5, 0xcc,
0x97, 0x41, 0x04, 0x84, 0x6d, 0x0a, 0xd3, 0xad,
@@ -134,7 +129,7 @@ CIPHER_TEST ( aes_192_cbc, &aes_cbc_algorithm,
/** AES-256-ECB (same test as AES-256-Core) */
CIPHER_TEST ( aes_256_ecb, &aes_ecb_algorithm,
- AES_KEY_NIST_256, AES_IV_NIST_DUMMY, ADDITIONAL(), AES_PLAINTEXT_NIST,
+ AES_KEY_NIST_256, IV(), ADDITIONAL(), AES_PLAINTEXT_NIST,
CIPHERTEXT ( 0xf3, 0xee, 0xd1, 0xbd, 0xb5, 0xd2, 0xa0, 0x3c,
0x06, 0x4b, 0x5a, 0x7e, 0x3d, 0xb1, 0x81, 0xf8,
0x59, 0x1c, 0xcb, 0x10, 0xd4, 0x10, 0xed, 0x26,
diff --git a/src/tests/bigint_test.c b/src/tests/bigint_test.c
index 8d40c318..76aca105 100644
--- a/src/tests/bigint_test.c
+++ b/src/tests/bigint_test.c
@@ -149,16 +149,38 @@ void bigint_shrink_sample ( const bigint_element_t *source0,
bigint_shrink ( source, dest );
}
+void bigint_copy_sample ( const bigint_element_t *source0,
+ bigint_element_t *dest0, unsigned int size ) {
+ const bigint_t ( size ) *source __attribute__ (( may_alias ))
+ = ( ( const void * ) source0 );
+ bigint_t ( size ) *dest __attribute__ (( may_alias ))
+ = ( ( void * ) dest0 );
+
+ bigint_copy ( source, dest );
+}
+
+void bigint_swap_sample ( bigint_element_t *first0, bigint_element_t *second0,
+ unsigned int size, int swap ) {
+ bigint_t ( size ) *first __attribute__ (( may_alias ))
+ = ( ( void * ) first0 );
+ bigint_t ( size ) *second __attribute__ (( may_alias ))
+ = ( ( void * ) second0 );
+
+ bigint_swap ( first, second, swap );
+}
+
void bigint_multiply_sample ( const bigint_element_t *multiplicand0,
+ unsigned int multiplicand_size,
const bigint_element_t *multiplier0,
- bigint_element_t *result0,
- unsigned int size ) {
- const bigint_t ( size ) *multiplicand __attribute__ (( may_alias ))
- = ( ( const void * ) multiplicand0 );
- const bigint_t ( size ) *multiplier __attribute__ (( may_alias ))
- = ( ( const void * ) multiplier0 );
- bigint_t ( size * 2 ) *result __attribute__ (( may_alias ))
- = ( ( void * ) result0 );
+ unsigned int multiplier_size,
+ bigint_element_t *result0 ) {
+ unsigned int result_size = ( multiplicand_size + multiplier_size );
+ const bigint_t ( multiplicand_size ) __attribute__ (( may_alias ))
+ *multiplicand = ( ( const void * ) multiplicand0 );
+ const bigint_t ( multiplier_size ) __attribute__ (( may_alias ))
+ *multiplier = ( ( const void * ) multiplier0 );
+ bigint_t ( result_size ) __attribute__ (( may_alias ))
+ *result = ( ( void * ) result0 );
bigint_multiply ( multiplicand, multiplier, result );
}
@@ -419,6 +441,42 @@ void bigint_mod_exp_sample ( const bigint_element_t *base0,
} while ( 0 )
/**
+ * Report result of big integer swap test
+ *
+ * @v first Big integer to be conditionally swapped
+ * @v second Big integer to be conditionally swapped
+ */
+#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 ); \
+ } while ( 0 )
+
+/**
* Report result of big integer multiplication test
*
* @v multiplicand Big integer to be multiplied
@@ -430,17 +488,18 @@ void bigint_mod_exp_sample ( const bigint_element_t *base0,
static const uint8_t multiplier_raw[] = multiplier; \
static const uint8_t expected_raw[] = expected; \
uint8_t result_raw[ sizeof ( expected_raw ) ]; \
- unsigned int size = \
+ unsigned int multiplicand_size = \
bigint_required_size ( sizeof ( multiplicand_raw ) ); \
- bigint_t ( size ) multiplicand_temp; \
- bigint_t ( size ) multiplier_temp; \
- bigint_t ( size * 2 ) result_temp; \
+ 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 ( &multiplier_temp ) == \
- bigint_size ( &multiplicand_temp ) ); \
assert ( bigint_size ( &result_temp ) == \
- ( 2 * bigint_size ( &multiplicand_temp ) ) ); \
+ ( bigint_size ( &multiplicand_temp ) + \
+ bigint_size ( &multiplier_temp ) ) ); \
bigint_init ( &multiplicand_temp, multiplicand_raw, \
sizeof ( multiplicand_raw ) ); \
bigint_init ( &multiplier_temp, multiplier_raw, \
@@ -655,6 +714,15 @@ static void bigint_test_exec ( void ) {
bigint_subtract_ok ( BIGINT ( 0xbb, 0x77, 0x32, 0x5a ),
BIGINT ( 0x5a, 0xd5, 0xfe, 0x28 ),
BIGINT ( 0x9f, 0x5e, 0xcb, 0xce ) );
+ bigint_subtract_ok ( BIGINT ( 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff ),
+ BIGINT ( 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 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 ) );
bigint_subtract_ok ( BIGINT ( 0x7b, 0xaa, 0x16, 0xcf, 0x15, 0x87,
0xe0, 0x4f, 0x2c, 0xa3, 0xec, 0x2f,
0x46, 0xfb, 0x83, 0xc6, 0xe0, 0xee,
@@ -1360,6 +1428,14 @@ static void bigint_test_exec ( void ) {
0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff ),
1024 );
+ bigint_swap_ok ( BIGINT ( 0x68, 0x65, 0x6c, 0x6c, 0x6f ),
+ BIGINT ( 0x77, 0x6f, 0x72, 0x6c, 0x64 ) );
+ bigint_swap_ok ( BIGINT ( 0xc8, 0x1c, 0x31, 0xd7, 0x13, 0x69, 0x47,
+ 0x32, 0xb0, 0x0a, 0xf7, 0x2d, 0xb9, 0xc3,
+ 0x35, 0x96 ),
+ BIGINT ( 0x8b, 0x1d, 0x8f, 0x21, 0x76, 0x16, 0x4c,
+ 0xf8, 0xb2, 0x63, 0xed, 0x89, 0x5e, 0x6b,
+ 0x35, 0x7c ) );
bigint_multiply_ok ( BIGINT ( 0xf0 ),
BIGINT ( 0xeb ),
BIGINT ( 0xdc, 0x50 ) );
@@ -1373,6 +1449,12 @@ static void bigint_test_exec ( void ) {
BIGINT ( 0x67, 0x3c, 0x5a, 0x16 ),
BIGINT ( 0x3c, 0xdb, 0x7f, 0xae, 0x12, 0x7e,
0xef, 0x16 ) );
+ bigint_multiply_ok ( BIGINT ( 0x39, 0x1f, 0xc8, 0x6a ),
+ BIGINT ( 0xba, 0x39, 0x4a, 0xb8, 0xac, 0xb3,
+ 0x4f, 0x64, 0x28, 0x46, 0xa6, 0x99 ),
+ BIGINT ( 0x29, 0x8d, 0xe0, 0x5d, 0x08, 0xea,
+ 0x0d, 0xc7, 0x82, 0x5d, 0xba, 0x96,
+ 0x1c, 0xef, 0x83, 0x5a ) );
bigint_multiply_ok ( BIGINT ( 0xe8, 0x08, 0x0b, 0xe9, 0x29, 0x36,
0xea, 0x51, 0x1d, 0x75, 0x1a, 0xd5,
0xba, 0xc6, 0xa0, 0xf3, 0x48, 0x5c,
diff --git a/src/tests/des_test.c b/src/tests/des_test.c
new file mode 100644
index 00000000..ffafbd81
--- /dev/null
+++ b/src/tests/des_test.c
@@ -0,0 +1,898 @@
+/*
+ * 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
+ *
+ * DES tests
+ *
+ * These test vectors are originally provided by NBS (the precursor of
+ * NIST) in SP 500-20, downloadable as a scan of the typewritten
+ * original from:
+ *
+ * https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nbsspecialpublication500-20e1980.pdf
+ */
+
+/* Forcibly enable assertions */
+#undef NDEBUG
+
+#include <assert.h>
+#include <ipxe/des.h>
+#include <ipxe/test.h>
+#include "cipher_test.h"
+
+/** Define a DES 64-bit test value */
+#define DES_VALUE(value) { \
+ ( ( ( ( uint64_t ) (value) ) >> 56 ) & 0xff ), \
+ ( ( ( ( uint64_t ) (value) ) >> 48 ) & 0xff ), \
+ ( ( ( ( uint64_t ) (value) ) >> 40 ) & 0xff ), \
+ ( ( ( ( uint64_t ) (value) ) >> 32 ) & 0xff ), \
+ ( ( ( ( uint64_t ) (value) ) >> 24 ) & 0xff ), \
+ ( ( ( ( uint64_t ) (value) ) >> 16 ) & 0xff ), \
+ ( ( ( ( uint64_t ) (value) ) >> 8 ) & 0xff ), \
+ ( ( ( ( uint64_t ) (value) ) >> 0 ) & 0xff ) \
+ }
+
+/** Define a DES test */
+#define DES_TEST( name, key, plaintext, ciphertext ) \
+ CIPHER_TEST ( name, &des_ecb_algorithm, DES_VALUE ( key ), \
+ IV(), ADDITIONAL(), DES_VALUE ( plaintext ), \
+ DES_VALUE ( ciphertext ), AUTH() )
+
+/* Sample round outputs (page 9) */
+DES_TEST ( des_round_sample,
+ 0x10316e028c8f3b4a, 0x0000000000000000, 0x82dcbafbdeab6602 );
+
+/* Test 1: Initial permutation and expansion tests
+ *
+ * "Set Key=0 and encrypt the 64-bit data vectors e[i]: i=1,...,64"
+ *
+ * Appendix B, page 28 ("IP and E test")
+ */
+DES_TEST ( des_test1_1,
+ 0x0101010101010101, 0x8000000000000000, 0x95f8a5e5dd31d900 );
+DES_TEST ( des_test1_2,
+ 0x0101010101010101, 0x4000000000000000, 0xdd7f121ca5015619 );
+DES_TEST ( des_test1_3,
+ 0x0101010101010101, 0x2000000000000000, 0x2e8653104f3834ea );
+DES_TEST ( des_test1_4,
+ 0x0101010101010101, 0x1000000000000000, 0x4bd388ff6cd81d4f );
+DES_TEST ( des_test1_5,
+ 0x0101010101010101, 0x0800000000000000, 0x20b9e767b2fb1456 );
+DES_TEST ( des_test1_6,
+ 0x0101010101010101, 0x0400000000000000, 0x55579380d77138ef );
+DES_TEST ( des_test1_7,
+ 0x0101010101010101, 0x0200000000000000, 0x6cc5defaaf04512f );
+DES_TEST ( des_test1_8,
+ 0x0101010101010101, 0x0100000000000000, 0x0d9f279ba5d87260 );
+DES_TEST ( des_test1_9,
+ 0x0101010101010101, 0x0080000000000000, 0xd9031b0271bd5a0a );
+DES_TEST ( des_test1_10,
+ 0x0101010101010101, 0x0040000000000000, 0x424250b37c3dd951 );
+DES_TEST ( des_test1_11,
+ 0x0101010101010101, 0x0020000000000000, 0xb8061b7ecd9a21e5 );
+DES_TEST ( des_test1_12,
+ 0x0101010101010101, 0x0010000000000000, 0xf15d0f286b65bd28 );
+DES_TEST ( des_test1_13,
+ 0x0101010101010101, 0x0008000000000000, 0xadd0cc8d6e5deba1 );
+DES_TEST ( des_test1_14,
+ 0x0101010101010101, 0x0004000000000000, 0xe6d5f82752ad63d1 );
+DES_TEST ( des_test1_15,
+ 0x0101010101010101, 0x0002000000000000, 0xecbfe3bd3f591a5e );
+DES_TEST ( des_test1_16,
+ 0x0101010101010101, 0x0001000000000000, 0xf356834379d165cd );
+DES_TEST ( des_test1_17,
+ 0x0101010101010101, 0x0000800000000000, 0x2b9f982f20037fa9 );
+DES_TEST ( des_test1_18,
+ 0x0101010101010101, 0x0000400000000000, 0x889de068a16f0be6 );
+DES_TEST ( des_test1_19,
+ 0x0101010101010101, 0x0000200000000000, 0xe19e275d846a1298 );
+DES_TEST ( des_test1_20,
+ 0x0101010101010101, 0x0000100000000000, 0x329a8ed523d71aec );
+DES_TEST ( des_test1_21,
+ 0x0101010101010101, 0x0000080000000000, 0xe7fce22557d23c97 );
+DES_TEST ( des_test1_22,
+ 0x0101010101010101, 0x0000040000000000, 0x12a9f5817ff2d65d );
+DES_TEST ( des_test1_23,
+ 0x0101010101010101, 0x0000020000000000, 0xa484c3ad38dc9c19 );
+DES_TEST ( des_test1_24,
+ 0x0101010101010101, 0x0000010000000000, 0xfbe00a8a1ef8ad72 );
+DES_TEST ( des_test1_25,
+ 0x0101010101010101, 0x0000008000000000, 0x750d079407521363 );
+DES_TEST ( des_test1_26,
+ 0x0101010101010101, 0x0000004000000000, 0x64feed9c724c2faf );
+DES_TEST ( des_test1_27,
+ 0x0101010101010101, 0x0000002000000000, 0xf02b263b328e2b60 );
+DES_TEST ( des_test1_28,
+ 0x0101010101010101, 0x0000001000000000, 0x9d64555a9a10b852 );
+DES_TEST ( des_test1_29,
+ 0x0101010101010101, 0x0000000800000000, 0xd106ff0bed5255d7 );
+DES_TEST ( des_test1_30,
+ 0x0101010101010101, 0x0000000400000000, 0xe1652c6b138c64a5 );
+DES_TEST ( des_test1_31,
+ 0x0101010101010101, 0x0000000200000000, 0xe428581186ec8f46 );
+DES_TEST ( des_test1_32,
+ 0x0101010101010101, 0x0000000100000000, 0xaeb5f5ede22d1a36 );
+DES_TEST ( des_test1_33,
+ 0x0101010101010101, 0x0000000080000000, 0xe943d7568aec0c5c );
+DES_TEST ( des_test1_34,
+ 0x0101010101010101, 0x0000000040000000, 0xdf98c8276f54b04b );
+DES_TEST ( des_test1_35,
+ 0x0101010101010101, 0x0000000020000000, 0xb160e4680f6c696f );
+DES_TEST ( des_test1_36,
+ 0x0101010101010101, 0x0000000010000000, 0xfa0752b07d9c4ab8 );
+DES_TEST ( des_test1_37,
+ 0x0101010101010101, 0x0000000008000000, 0xca3a2b036dbc8502 );
+DES_TEST ( des_test1_38,
+ 0x0101010101010101, 0x0000000004000000, 0x5e0905517bb59bcf );
+DES_TEST ( des_test1_39,
+ 0x0101010101010101, 0x0000000002000000, 0x814eeb3b91d90726 );
+DES_TEST ( des_test1_40,
+ 0x0101010101010101, 0x0000000001000000, 0x4d49db1532919c9f );
+DES_TEST ( des_test1_41,
+ 0x0101010101010101, 0x0000000000800000, 0x25eb5fc3f8cf0621 );
+DES_TEST ( des_test1_42,
+ 0x0101010101010101, 0x0000000000400000, 0xab6a20c0620d1c6f );
+DES_TEST ( des_test1_43,
+ 0x0101010101010101, 0x0000000000200000, 0x79e90dbc98f92cca );
+DES_TEST ( des_test1_44,
+ 0x0101010101010101, 0x0000000000100000, 0x866ecedd8072bb0e );
+DES_TEST ( des_test1_45,
+ 0x0101010101010101, 0x0000000000080000, 0x8b54536f2f3e64a8 );
+DES_TEST ( des_test1_46,
+ 0x0101010101010101, 0x0000000000040000, 0xea51d3975595b86b );
+DES_TEST ( des_test1_47,
+ 0x0101010101010101, 0x0000000000020000, 0xcaffc6ac4542de31 );
+DES_TEST ( des_test1_48,
+ 0x0101010101010101, 0x0000000000010000, 0x8dd45a2ddf90796c );
+DES_TEST ( des_test1_49,
+ 0x0101010101010101, 0x0000000000008000, 0x1029d55e880ec2d0 );
+DES_TEST ( des_test1_50,
+ 0x0101010101010101, 0x0000000000004000, 0x5d86cb23639dbea9 );
+DES_TEST ( des_test1_51,
+ 0x0101010101010101, 0x0000000000002000, 0x1d1ca853ae7c0c5f );
+DES_TEST ( des_test1_52,
+ 0x0101010101010101, 0x0000000000001000, 0xce332329248f3228 );
+DES_TEST ( des_test1_53,
+ 0x0101010101010101, 0x0000000000000800, 0x8405d1abe24fb942 );
+DES_TEST ( des_test1_54,
+ 0x0101010101010101, 0x0000000000000400, 0xe643d78090ca4207 );
+DES_TEST ( des_test1_55,
+ 0x0101010101010101, 0x0000000000000200, 0x48221b9937748a23 );
+DES_TEST ( des_test1_56,
+ 0x0101010101010101, 0x0000000000000100, 0xdd7c0bbd61fafd54 );
+DES_TEST ( des_test1_57,
+ 0x0101010101010101, 0x0000000000000080, 0x2fbc291a570db5c4 );
+DES_TEST ( des_test1_58,
+ 0x0101010101010101, 0x0000000000000040, 0xe07c30d7e4e26e12 );
+DES_TEST ( des_test1_59,
+ 0x0101010101010101, 0x0000000000000020, 0x0953e2258e8e90a1 );
+DES_TEST ( des_test1_60,
+ 0x0101010101010101, 0x0000000000000010, 0x5b711bc4ceebf2ee );
+DES_TEST ( des_test1_61,
+ 0x0101010101010101, 0x0000000000000008, 0xcc083f1e6d9e85f6 );
+DES_TEST ( des_test1_62,
+ 0x0101010101010101, 0x0000000000000004, 0xd2fd8867d50d2dfe );
+DES_TEST ( des_test1_63,
+ 0x0101010101010101, 0x0000000000000002, 0x06e7ea22ce92708f );
+DES_TEST ( des_test1_64,
+ 0x0101010101010101, 0x0000000000000001, 0x166b40b44aba4bd6 );
+
+/* Test 2: Inverse permutation and expansion tests
+ *
+ * "Set Key=0 and encrypt the results c[i] obtained in Test 1"
+ *
+ * Appendix B, page 28 ("IP and E test")
+ */
+DES_TEST ( des_test2_1,
+ 0x0101010101010101, 0x95f8a5e5dd31d900, 0x8000000000000000 );
+DES_TEST ( des_test2_2,
+ 0x0101010101010101, 0xdd7f121ca5015619, 0x4000000000000000 );
+DES_TEST ( des_test2_3,
+ 0x0101010101010101, 0x2e8653104f3834ea, 0x2000000000000000 );
+DES_TEST ( des_test2_4,
+ 0x0101010101010101, 0x4bd388ff6cd81d4f, 0x1000000000000000 );
+DES_TEST ( des_test2_5,
+ 0x0101010101010101, 0x20b9e767b2fb1456, 0x0800000000000000 );
+DES_TEST ( des_test2_6,
+ 0x0101010101010101, 0x55579380d77138ef, 0x0400000000000000 );
+DES_TEST ( des_test2_7,
+ 0x0101010101010101, 0x6cc5defaaf04512f, 0x0200000000000000 );
+DES_TEST ( des_test2_8,
+ 0x0101010101010101, 0x0d9f279ba5d87260, 0x0100000000000000 );
+DES_TEST ( des_test2_9,
+ 0x0101010101010101, 0xd9031b0271bd5a0a, 0x0080000000000000 );
+DES_TEST ( des_test2_10,
+ 0x0101010101010101, 0x424250b37c3dd951, 0x0040000000000000 );
+DES_TEST ( des_test2_11,
+ 0x0101010101010101, 0xb8061b7ecd9a21e5, 0x0020000000000000 );
+DES_TEST ( des_test2_12,
+ 0x0101010101010101, 0xf15d0f286b65bd28, 0x0010000000000000 );
+DES_TEST ( des_test2_13,
+ 0x0101010101010101, 0xadd0cc8d6e5deba1, 0x0008000000000000 );
+DES_TEST ( des_test2_14,
+ 0x0101010101010101, 0xe6d5f82752ad63d1, 0x0004000000000000 );
+DES_TEST ( des_test2_15,
+ 0x0101010101010101, 0xecbfe3bd3f591a5e, 0x0002000000000000 );
+DES_TEST ( des_test2_16,
+ 0x0101010101010101, 0xf356834379d165cd, 0x0001000000000000 );
+DES_TEST ( des_test2_17,
+ 0x0101010101010101, 0x2b9f982f20037fa9, 0x0000800000000000 );
+DES_TEST ( des_test2_18,
+ 0x0101010101010101, 0x889de068a16f0be6, 0x0000400000000000 );
+DES_TEST ( des_test2_19,
+ 0x0101010101010101, 0xe19e275d846a1298, 0x0000200000000000 );
+DES_TEST ( des_test2_20,
+ 0x0101010101010101, 0x329a8ed523d71aec, 0x0000100000000000 );
+DES_TEST ( des_test2_21,
+ 0x0101010101010101, 0xe7fce22557d23c97, 0x0000080000000000 );
+DES_TEST ( des_test2_22,
+ 0x0101010101010101, 0x12a9f5817ff2d65d, 0x0000040000000000 );
+DES_TEST ( des_test2_23,
+ 0x0101010101010101, 0xa484c3ad38dc9c19, 0x0000020000000000 );
+DES_TEST ( des_test2_24,
+ 0x0101010101010101, 0xfbe00a8a1ef8ad72, 0x0000010000000000 );
+DES_TEST ( des_test2_25,
+ 0x0101010101010101, 0x750d079407521363, 0x0000008000000000 );
+DES_TEST ( des_test2_26,
+ 0x0101010101010101, 0x64feed9c724c2faf, 0x0000004000000000 );
+DES_TEST ( des_test2_27,
+ 0x0101010101010101, 0xf02b263b328e2b60, 0x0000002000000000 );
+DES_TEST ( des_test2_28,
+ 0x0101010101010101, 0x9d64555a9a10b852, 0x0000001000000000 );
+DES_TEST ( des_test2_29,
+ 0x0101010101010101, 0xd106ff0bed5255d7, 0x0000000800000000 );
+DES_TEST ( des_test2_30,
+ 0x0101010101010101, 0xe1652c6b138c64a5, 0x0000000400000000 );
+DES_TEST ( des_test2_31,
+ 0x0101010101010101, 0xe428581186ec8f46, 0x0000000200000000 );
+DES_TEST ( des_test2_32,
+ 0x0101010101010101, 0xaeb5f5ede22d1a36, 0x0000000100000000 );
+DES_TEST ( des_test2_33,
+ 0x0101010101010101, 0xe943d7568aec0c5c, 0x0000000080000000 );
+DES_TEST ( des_test2_34,
+ 0x0101010101010101, 0xdf98c8276f54b04b, 0x0000000040000000 );
+DES_TEST ( des_test2_35,
+ 0x0101010101010101, 0xb160e4680f6c696f, 0x0000000020000000 );
+DES_TEST ( des_test2_36,
+ 0x0101010101010101, 0xfa0752b07d9c4ab8, 0x0000000010000000 );
+DES_TEST ( des_test2_37,
+ 0x0101010101010101, 0xca3a2b036dbc8502, 0x0000000008000000 );
+DES_TEST ( des_test2_38,
+ 0x0101010101010101, 0x5e0905517bb59bcf, 0x0000000004000000 );
+DES_TEST ( des_test2_39,
+ 0x0101010101010101, 0x814eeb3b91d90726, 0x0000000002000000 );
+DES_TEST ( des_test2_40,
+ 0x0101010101010101, 0x4d49db1532919c9f, 0x0000000001000000 );
+DES_TEST ( des_test2_41,
+ 0x0101010101010101, 0x25eb5fc3f8cf0621, 0x0000000000800000 );
+DES_TEST ( des_test2_42,
+ 0x0101010101010101, 0xab6a20c0620d1c6f, 0x0000000000400000 );
+DES_TEST ( des_test2_43,
+ 0x0101010101010101, 0x79e90dbc98f92cca, 0x0000000000200000 );
+DES_TEST ( des_test2_44,
+ 0x0101010101010101, 0x866ecedd8072bb0e, 0x0000000000100000 );
+DES_TEST ( des_test2_45,
+ 0x0101010101010101, 0x8b54536f2f3e64a8, 0x0000000000080000 );
+DES_TEST ( des_test2_46,
+ 0x0101010101010101, 0xea51d3975595b86b, 0x0000000000040000 );
+DES_TEST ( des_test2_47,
+ 0x0101010101010101, 0xcaffc6ac4542de31, 0x0000000000020000 );
+DES_TEST ( des_test2_48,
+ 0x0101010101010101, 0x8dd45a2ddf90796c, 0x0000000000010000 );
+DES_TEST ( des_test2_49,
+ 0x0101010101010101, 0x1029d55e880ec2d0, 0x0000000000008000 );
+DES_TEST ( des_test2_50,
+ 0x0101010101010101, 0x5d86cb23639dbea9, 0x0000000000004000 );
+DES_TEST ( des_test2_51,
+ 0x0101010101010101, 0x1d1ca853ae7c0c5f, 0x0000000000002000 );
+DES_TEST ( des_test2_52,
+ 0x0101010101010101, 0xce332329248f3228, 0x0000000000001000 );
+DES_TEST ( des_test2_53,
+ 0x0101010101010101, 0x8405d1abe24fb942, 0x0000000000000800 );
+DES_TEST ( des_test2_54,
+ 0x0101010101010101, 0xe643d78090ca4207, 0x0000000000000400 );
+DES_TEST ( des_test2_55,
+ 0x0101010101010101, 0x48221b9937748a23, 0x0000000000000200 );
+DES_TEST ( des_test2_56,
+ 0x0101010101010101, 0xdd7c0bbd61fafd54, 0x0000000000000100 );
+DES_TEST ( des_test2_57,
+ 0x0101010101010101, 0x2fbc291a570db5c4, 0x0000000000000080 );
+DES_TEST ( des_test2_58,
+ 0x0101010101010101, 0xe07c30d7e4e26e12, 0x0000000000000040 );
+DES_TEST ( des_test2_59,
+ 0x0101010101010101, 0x0953e2258e8e90a1, 0x0000000000000020 );
+DES_TEST ( des_test2_60,
+ 0x0101010101010101, 0x5b711bc4ceebf2ee, 0x0000000000000010 );
+DES_TEST ( des_test2_61,
+ 0x0101010101010101, 0xcc083f1e6d9e85f6, 0x0000000000000008 );
+DES_TEST ( des_test2_62,
+ 0x0101010101010101, 0xd2fd8867d50d2dfe, 0x0000000000000004 );
+DES_TEST ( des_test2_63,
+ 0x0101010101010101, 0x06e7ea22ce92708f, 0x0000000000000002 );
+DES_TEST ( des_test2_64,
+ 0x0101010101010101, 0x166b40b44aba4bd6, 0x0000000000000001 );
+
+/* Test 3: Data permutation tests
+ *
+ * "Set the plaintext to zero and process the 32 keys in PTEST"
+ *
+ * Appendix B, page 32 ("PTEST")
+ */
+DES_TEST ( des_test3_1,
+ 0x1046913489980131, 0x0000000000000000, 0x88d55e54f54c97b4 );
+DES_TEST ( des_test3_2,
+ 0x1007103489988020, 0x0000000000000000, 0x0c0cc00c83ea48fd );
+DES_TEST ( des_test3_3,
+ 0x10071034c8980120, 0x0000000000000000, 0x83bc8ef3a6570183 );
+DES_TEST ( des_test3_4,
+ 0x1046103489988020, 0x0000000000000000, 0xdf725dcad94ea2e9 );
+DES_TEST ( des_test3_5,
+ 0x1086911519190101, 0x0000000000000000, 0xe652b53b550be8b0 );
+DES_TEST ( des_test3_6,
+ 0x1086911519580101, 0x0000000000000000, 0xaf527120c485cbb0 );
+DES_TEST ( des_test3_7,
+ 0x5107b01519580101, 0x0000000000000000, 0x0f04ce393db926d5 );
+DES_TEST ( des_test3_8,
+ 0x1007b01519190101, 0x0000000000000000, 0xc9f00ffc74079067 );
+DES_TEST ( des_test3_9,
+ 0x3107915498080101, 0x0000000000000000, 0x7cfd82a593252b4e );
+DES_TEST ( des_test3_10,
+ 0x3107919498080101, 0x0000000000000000, 0xcb49a2f9e91363e3 );
+DES_TEST ( des_test3_11,
+ 0x10079115b9080140, 0x0000000000000000, 0x00b588be70d23f56 );
+DES_TEST ( des_test3_12,
+ 0x3107911598080140, 0x0000000000000000, 0x406a9a6ab43399ae );
+DES_TEST ( des_test3_13,
+ 0x1007d01589980101, 0x0000000000000000, 0x6cb773611dca9ada );
+DES_TEST ( des_test3_14,
+ 0x9107911589980101, 0x0000000000000000, 0x67fd21c17dbb5d70 );
+DES_TEST ( des_test3_15,
+ 0x9107d01589190101, 0x0000000000000000, 0x9592cb4110430787 );
+DES_TEST ( des_test3_16,
+ 0x1007d01598980120, 0x0000000000000000, 0xa6b7ff68a318ddd3 );
+DES_TEST ( des_test3_17,
+ 0x1007940498190101, 0x0000000000000000, 0x4d102196c914ca16 );
+DES_TEST ( des_test3_18,
+ 0x0107910491190401, 0x0000000000000000, 0x2dfa9f4573594965 );
+DES_TEST ( des_test3_19,
+ 0x0107910491190101, 0x0000000000000000, 0xb46604816c0e0774 );
+DES_TEST ( des_test3_20,
+ 0x0107940491190401, 0x0000000000000000, 0x6e7e6221a4f34e87 );
+DES_TEST ( des_test3_21,
+ 0x19079210981a0101, 0x0000000000000000, 0xaa85e74643233199 );
+DES_TEST ( des_test3_22,
+ 0x1007911998190801, 0x0000000000000000, 0x2e5a19db4d1962d6 );
+DES_TEST ( des_test3_23,
+ 0x10079119981a0801, 0x0000000000000000, 0x23a866a809d30894 );
+DES_TEST ( des_test3_24,
+ 0x1007921098190101, 0x0000000000000000, 0xd812d961f017d320 );
+DES_TEST ( des_test3_25,
+ 0x100791159819010b, 0x0000000000000000, 0x055605816e58608f );
+DES_TEST ( des_test3_26,
+ 0x1004801598190101, 0x0000000000000000, 0xabd88e8b1b7716f1 );
+DES_TEST ( des_test3_27,
+ 0x1004801598190102, 0x0000000000000000, 0x537ac95be69da1e1 );
+DES_TEST ( des_test3_28,
+ 0x1004801598190108, 0x0000000000000000, 0xaed0f6ae3c25cdd8 );
+DES_TEST ( des_test3_29,
+ 0x1002911498100104, 0x0000000000000000, 0xb3e35a5ee53e7b8d );
+DES_TEST ( des_test3_30,
+ 0x1002911598190104, 0x0000000000000000, 0x61c79c71921a2ef8 );
+DES_TEST ( des_test3_31,
+ 0x1002911598100201, 0x0000000000000000, 0xe2f5728f0995013c );
+DES_TEST ( des_test3_32,
+ 0x1002911698100101, 0x0000000000000000, 0x1aeac39a61f0a464 );
+
+/* Test 4: Key permutation tests
+ *
+ * "Set Data=0 and use the keys e[i]: i=1,...,64 ignoring i=8,16,...,64"
+ *
+ * Test 4 part 1 is the forward direction as described above. Test 4
+ * part 2 ("set data=c[i] from part 1 ... then decipher") is carried
+ * out for us automatically, since CIPHER_TEST() performs both
+ * encryption and decryption tests.
+ *
+ * Appendix B, page 30 ("PC1 and PC2 test")
+ */
+DES_TEST ( des_test4_1,
+ 0x8001010101010101, 0x0000000000000000, 0x95a8d72813daa94d );
+DES_TEST ( des_test4_2,
+ 0x4001010101010101, 0x0000000000000000, 0x0eec1487dd8c26d5 );
+DES_TEST ( des_test4_3,
+ 0x2001010101010101, 0x0000000000000000, 0x7ad16ffb79c45926 );
+DES_TEST ( des_test4_4,
+ 0x1001010101010101, 0x0000000000000000, 0xd3746294ca6a6cf3 );
+DES_TEST ( des_test4_5,
+ 0x0801010101010101, 0x0000000000000000, 0x809f5f873c1fd761 );
+DES_TEST ( des_test4_6,
+ 0x0401010101010101, 0x0000000000000000, 0xc02faffec989d1fc );
+DES_TEST ( des_test4_7,
+ 0x0201010101010101, 0x0000000000000000, 0x4615aa1d33e72f10 );
+DES_TEST ( des_test4_8,
+ 0x0180010101010101, 0x0000000000000000, 0x2055123350c00858 );
+DES_TEST ( des_test4_9,
+ 0x0140010101010101, 0x0000000000000000, 0xdf3b99d6577397c8 );
+DES_TEST ( des_test4_10,
+ 0x0120010101010101, 0x0000000000000000, 0x31fe17369b5288c9 );
+DES_TEST ( des_test4_11,
+ 0x0110010101010101, 0x0000000000000000, 0xdfdd3cc64dae1642 );
+DES_TEST ( des_test4_12,
+ 0x0108010101010101, 0x0000000000000000, 0x178c83ce2b399d94 );
+DES_TEST ( des_test4_13,
+ 0x0104010101010101, 0x0000000000000000, 0x50f636324a9b7f80 );
+DES_TEST ( des_test4_14,
+ 0x0102010101010101, 0x0000000000000000, 0xa8468ee3bc18f06d );
+DES_TEST ( des_test4_15,
+ 0x0101800101010101, 0x0000000000000000, 0xa2dc9e92fd3cde92 );
+DES_TEST ( des_test4_16,
+ 0x0101400101010101, 0x0000000000000000, 0xcac09f797d031287 );
+DES_TEST ( des_test4_17,
+ 0x0101200101010101, 0x0000000000000000, 0x90ba680b22aeb525 );
+DES_TEST ( des_test4_18,
+ 0x0101100101010101, 0x0000000000000000, 0xce7a24f350e280b6 );
+DES_TEST ( des_test4_19,
+ 0x0101080101010101, 0x0000000000000000, 0x882bff0aa01a0b87 );
+DES_TEST ( des_test4_20,
+ 0x0101040101010101, 0x0000000000000000, 0x25610288924511c2 );
+DES_TEST ( des_test4_21,
+ 0x0101020101010101, 0x0000000000000000, 0xc71516c29c75d170 );
+DES_TEST ( des_test4_22,
+ 0x0101018001010101, 0x0000000000000000, 0x5199c29a52c9f059 );
+DES_TEST ( des_test4_23,
+ 0x0101014001010101, 0x0000000000000000, 0xc22f0a294a71f29f );
+DES_TEST ( des_test4_24,
+ 0x0101012001010101, 0x0000000000000000, 0xee371483714c02ea );
+DES_TEST ( des_test4_25,
+ 0x0101011001010101, 0x0000000000000000, 0xa81fbd448f9e522f );
+DES_TEST ( des_test4_26,
+ 0x0101010801010101, 0x0000000000000000, 0x4f644c92e192dfed );
+DES_TEST ( des_test4_27,
+ 0x0101010401010101, 0x0000000000000000, 0x1afa9a66a6df92ae );
+DES_TEST ( des_test4_28,
+ 0x0101010201010101, 0x0000000000000000, 0xb3c1cc715cb879d8 );
+DES_TEST ( des_test4_29,
+ 0x0101010180010101, 0x0000000000000000, 0x19d032e64ab0bd8b );
+DES_TEST ( des_test4_30,
+ 0x0101010140010101, 0x0000000000000000, 0x3cfaa7a7dc8720dc );
+DES_TEST ( des_test4_31,
+ 0x0101010120010101, 0x0000000000000000, 0xb7265f7f447ac6f3 );
+DES_TEST ( des_test4_32,
+ 0x0101010110010101, 0x0000000000000000, 0x9db73b3c0d163f54 );
+DES_TEST ( des_test4_33,
+ 0x0101010108010101, 0x0000000000000000, 0x8181b65babf4a975 );
+DES_TEST ( des_test4_34,
+ 0x0101010104010101, 0x0000000000000000, 0x93c9b64042eaa240 );
+DES_TEST ( des_test4_35,
+ 0x0101010102010101, 0x0000000000000000, 0x5570530829705592 );
+DES_TEST ( des_test4_36,
+ 0x0101010101800101, 0x0000000000000000, 0x8638809e878787a0 );
+DES_TEST ( des_test4_37,
+ 0x0101010101400101, 0x0000000000000000, 0x41b9a79af79ac208 );
+DES_TEST ( des_test4_38,
+ 0x0101010101200101, 0x0000000000000000, 0x7a9be42f2009a892 );
+DES_TEST ( des_test4_39,
+ 0x0101010101100101, 0x0000000000000000, 0x29038d56ba6d2745 );
+DES_TEST ( des_test4_40,
+ 0x0101010101080101, 0x0000000000000000, 0x5495c6abf1e5df51 );
+DES_TEST ( des_test4_41,
+ 0x0101010101040101, 0x0000000000000000, 0xae13dbd561488933 );
+DES_TEST ( des_test4_42,
+ 0x0101010101020101, 0x0000000000000000, 0x024d1ffa8904e389 );
+DES_TEST ( des_test4_43,
+ 0x0101010101018001, 0x0000000000000000, 0xd1399712f99bf02e );
+DES_TEST ( des_test4_44,
+ 0x0101010101014001, 0x0000000000000000, 0x14c1d7c1cffec79e );
+DES_TEST ( des_test4_45,
+ 0x0101010101012001, 0x0000000000000000, 0x1de5279dae3bed6f );
+DES_TEST ( des_test4_46,
+ 0x0101010101011001, 0x0000000000000000, 0xe941a33f85501303 );
+DES_TEST ( des_test4_47,
+ 0x0101010101010801, 0x0000000000000000, 0xda99dbbc9a03f379 );
+DES_TEST ( des_test4_48,
+ 0x0101010101010401, 0x0000000000000000, 0xb7fc92f91d8e92e9 );
+DES_TEST ( des_test4_49,
+ 0x0101010101010201, 0x0000000000000000, 0xae8e5caa3ca04e85 );
+DES_TEST ( des_test4_50,
+ 0x0101010101010180, 0x0000000000000000, 0x9cc62df43b6eed74 );
+DES_TEST ( des_test4_51,
+ 0x0101010101010140, 0x0000000000000000, 0xd863dbb5c59a91a0 );
+DES_TEST ( des_test4_52,
+ 0x0101010101010120, 0x0000000000000000, 0xa1ab2190545b91d7 );
+DES_TEST ( des_test4_53,
+ 0x0101010101010110, 0x0000000000000000, 0x0875041e64c570f7 );
+DES_TEST ( des_test4_54,
+ 0x0101010101010108, 0x0000000000000000, 0x5a594528bebef1cc );
+DES_TEST ( des_test4_55,
+ 0x0101010101010104, 0x0000000000000000, 0xfcdb3291de21f0c0 );
+DES_TEST ( des_test4_56,
+ 0x0101010101010102, 0x0000000000000000, 0x869efd7f9f265a09 );
+
+/* Test 5: S-box tests
+ *
+ * "Set Data and Key equal to the inputs defined in the Substitution
+ * Table test"
+ *
+ * Appendix B, page 33 ("19 key data pairs which exercise every S-box entry")
+ */
+DES_TEST ( des_test5_1,
+ 0x7ca110454a1a6e57, 0x01a1d6d039776742, 0x690f5b0d9a26939b );
+DES_TEST ( des_test5_2,
+ 0x0131d9619dc1376e, 0x5cd54ca83def57da, 0x7a389d10354bd271 );
+DES_TEST ( des_test5_3,
+ 0x07a1133e4a0b2686, 0x0248d43806f67172, 0x868ebb51cab4599a );
+DES_TEST ( des_test5_4,
+ 0x3849674c2602319e, 0x51454b582ddf440a, 0x7178876e01f19b2a );
+DES_TEST ( des_test5_5,
+ 0x04b915ba43feb5b6, 0x42fd443059577fa2, 0xaf37fb421f8c4095 );
+DES_TEST ( des_test5_6,
+ 0x0113b970fd34f2ce, 0x059b5e0851cf143a, 0x86a560f10ec6d85b );
+DES_TEST ( des_test5_7,
+ 0x0170f175468fb5e6, 0x0756d8e0774761d2, 0x0cd3da020021dc09 );
+DES_TEST ( des_test5_8,
+ 0x43297fad38e373fe, 0x762514b829bf486a, 0xea676b2cb7db2b7a );
+DES_TEST ( des_test5_9,
+ 0x07a7137045da2a16, 0x3bdd119049372802, 0xdfd64a815caf1a0f );
+DES_TEST ( des_test5_10,
+ 0x04689104c2fd3b2f, 0x26955f6835af609a, 0x5c513c9c4886c088 );
+DES_TEST ( des_test5_11,
+ 0x37d06bb516cb7546, 0x164d5e404f275232, 0x0a2aeeae3ff4ab77 );
+DES_TEST ( des_test5_12,
+ 0x1f08260d1ac2465e, 0x6b056e18759f5cca, 0xef1bf03e5dfa575a );
+DES_TEST ( des_test5_13,
+ 0x584023641aba6176, 0x004bd6ef09176062, 0x88bf0db6d70dee56 );
+DES_TEST ( des_test5_14,
+ 0x025816164629b007, 0x480d39006ee762f2, 0xa1f9915541020b56 );
+DES_TEST ( des_test5_15,
+ 0x49793ebc79b3258f, 0x437540c8698f3cfa, 0x6fbf1cafcffd0556 );
+DES_TEST ( des_test5_16,
+ 0x4fb05e1515ab73a7, 0x072d43a077075292, 0x2f22e49bab7ca1ac );
+DES_TEST ( des_test5_17,
+ 0x49e95d6d4ca229bf, 0x02fe55778117f12a, 0x5a6b612cc26cce4a );
+DES_TEST ( des_test5_18,
+ 0x018310dc409b26d6, 0x1d9d5c5018f728c2, 0x5f4c038ed12b2e41 );
+DES_TEST ( des_test5_19,
+ 0x1c587f1c13924fef, 0x305532286d6f295a, 0x63fac0d034d9f793 );
+
+/* Unofficial tests
+ *
+ * The official tests are all exactly one block in length. Add some
+ * multi-block tests (generated in Python).
+ */
+CIPHER_TEST ( des_unofficial_ecb, &des_ecb_algorithm,
+ KEY ( 0x6e, 0x6f, 0x70, 0x61, 0x72, 0x69, 0x74, 0x79 ),
+ IV(), ADDITIONAL(),
+ PLAINTEXT ( 0x53, 0x6f, 0x20, 0x63, 0x75, 0x74, 0x65, 0x20,
+ 0x74, 0x6f, 0x20, 0x73, 0x65, 0x65, 0x20, 0x61,
+ 0x20, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69,
+ 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x77,
+ 0x72, 0x69, 0x74, 0x74, 0x65, 0x6e, 0x20, 0x6f,
+ 0x6e, 0x20, 0x61, 0x6e, 0x20, 0x61, 0x63, 0x74,
+ 0x75, 0x61, 0x6c, 0x20, 0x74, 0x79, 0x70, 0x65,
+ 0x77, 0x72, 0x69, 0x74, 0x65, 0x72, 0x21, 0x21 ),
+ CIPHERTEXT ( 0x1a, 0x02, 0x17, 0xcb, 0x93, 0xa3, 0xd2, 0xf2,
+ 0xf9, 0x45, 0x71, 0x1c, 0x33, 0xb1, 0x5c, 0xa4,
+ 0x8b, 0x6b, 0x11, 0x7a, 0x7c, 0x86, 0x7c, 0x7f,
+ 0x9f, 0x56, 0x61, 0x46, 0x7f, 0xa6, 0xae, 0xf1,
+ 0x49, 0xf7, 0x53, 0xe0, 0xbc, 0x15, 0x6a, 0x30,
+ 0xe7, 0xf8, 0xf3, 0x29, 0x11, 0xd8, 0x7d, 0x04,
+ 0x62, 0x5a, 0xaa, 0xa1, 0x89, 0x61, 0x4c, 0xf6,
+ 0x5a, 0x47, 0x3b, 0xc6, 0x04, 0x15, 0xce, 0xf6 ),
+ AUTH() );
+CIPHER_TEST ( des_unofficial_cbc, &des_cbc_algorithm,
+ KEY ( 0x6e, 0x6f, 0x70, 0x61, 0x72, 0x69, 0x74, 0x79 ),
+ IV ( 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 ),
+ ADDITIONAL(),
+ PLAINTEXT ( 0x53, 0x6f, 0x20, 0x63, 0x75, 0x74, 0x65, 0x20,
+ 0x74, 0x6f, 0x20, 0x73, 0x65, 0x65, 0x20, 0x61,
+ 0x20, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69,
+ 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x77,
+ 0x72, 0x69, 0x74, 0x74, 0x65, 0x6e, 0x20, 0x6f,
+ 0x6e, 0x20, 0x61, 0x6e, 0x20, 0x61, 0x63, 0x74,
+ 0x75, 0x61, 0x6c, 0x20, 0x74, 0x79, 0x70, 0x65,
+ 0x77, 0x72, 0x69, 0x74, 0x65, 0x72, 0x21, 0x21 ),
+ CIPHERTEXT ( 0x4c, 0x5f, 0x62, 0xfc, 0xf4, 0x93, 0x09, 0xb5,
+ 0x1d, 0x52, 0x25, 0xec, 0xc7, 0x42, 0x3c, 0x29,
+ 0x33, 0x67, 0xf5, 0xe9, 0xd6, 0x3c, 0x27, 0x5b,
+ 0x49, 0x69, 0xc5, 0xa9, 0x08, 0xa3, 0x14, 0x66,
+ 0x3c, 0x95, 0x33, 0x30, 0xcf, 0x3c, 0x7c, 0xaf,
+ 0xa3, 0xe4, 0xf8, 0x2e, 0xc3, 0x55, 0x57, 0x81,
+ 0x33, 0xd9, 0x90, 0xe2, 0x99, 0xdc, 0x32, 0x10,
+ 0x13, 0x21, 0xb6, 0xc1, 0x6b, 0x0f, 0x22, 0xa9 ),
+ AUTH() );
+
+/**
+ * Perform DES self-test
+ *
+ */
+static void des_test_exec ( void ) {
+
+ /* Sample round outputs (page 9) */
+ cipher_ok ( &des_round_sample );
+
+ /* Test 1: Initial permutation and expansion tests */
+ cipher_ok ( &des_test1_1 );
+ cipher_ok ( &des_test1_2 );
+ cipher_ok ( &des_test1_3 );
+ cipher_ok ( &des_test1_4 );
+ cipher_ok ( &des_test1_5 );
+ cipher_ok ( &des_test1_6 );
+ cipher_ok ( &des_test1_7 );
+ cipher_ok ( &des_test1_8 );
+ cipher_ok ( &des_test1_9 );
+ cipher_ok ( &des_test1_10 );
+ cipher_ok ( &des_test1_11 );
+ cipher_ok ( &des_test1_12 );
+ cipher_ok ( &des_test1_13 );
+ cipher_ok ( &des_test1_14 );
+ cipher_ok ( &des_test1_15 );
+ cipher_ok ( &des_test1_16 );
+ cipher_ok ( &des_test1_17 );
+ cipher_ok ( &des_test1_18 );
+ cipher_ok ( &des_test1_19 );
+ cipher_ok ( &des_test1_20 );
+ cipher_ok ( &des_test1_21 );
+ cipher_ok ( &des_test1_22 );
+ cipher_ok ( &des_test1_23 );
+ cipher_ok ( &des_test1_24 );
+ cipher_ok ( &des_test1_25 );
+ cipher_ok ( &des_test1_26 );
+ cipher_ok ( &des_test1_27 );
+ cipher_ok ( &des_test1_28 );
+ cipher_ok ( &des_test1_29 );
+ cipher_ok ( &des_test1_30 );
+ cipher_ok ( &des_test1_31 );
+ cipher_ok ( &des_test1_32 );
+ cipher_ok ( &des_test1_33 );
+ cipher_ok ( &des_test1_34 );
+ cipher_ok ( &des_test1_35 );
+ cipher_ok ( &des_test1_36 );
+ cipher_ok ( &des_test1_37 );
+ cipher_ok ( &des_test1_38 );
+ cipher_ok ( &des_test1_39 );
+ cipher_ok ( &des_test1_40 );
+ cipher_ok ( &des_test1_41 );
+ cipher_ok ( &des_test1_42 );
+ cipher_ok ( &des_test1_43 );
+ cipher_ok ( &des_test1_44 );
+ cipher_ok ( &des_test1_45 );
+ cipher_ok ( &des_test1_46 );
+ cipher_ok ( &des_test1_47 );
+ cipher_ok ( &des_test1_48 );
+ cipher_ok ( &des_test1_49 );
+ cipher_ok ( &des_test1_50 );
+ cipher_ok ( &des_test1_51 );
+ cipher_ok ( &des_test1_52 );
+ cipher_ok ( &des_test1_53 );
+ cipher_ok ( &des_test1_54 );
+ cipher_ok ( &des_test1_55 );
+ cipher_ok ( &des_test1_56 );
+ cipher_ok ( &des_test1_57 );
+ cipher_ok ( &des_test1_58 );
+ cipher_ok ( &des_test1_59 );
+ cipher_ok ( &des_test1_60 );
+ cipher_ok ( &des_test1_61 );
+ cipher_ok ( &des_test1_62 );
+ cipher_ok ( &des_test1_63 );
+ cipher_ok ( &des_test1_64 );
+
+ /* Test 2: Inverse permutation and expansion tests */
+ cipher_ok ( &des_test2_1 );
+ cipher_ok ( &des_test2_2 );
+ cipher_ok ( &des_test2_3 );
+ cipher_ok ( &des_test2_4 );
+ cipher_ok ( &des_test2_5 );
+ cipher_ok ( &des_test2_6 );
+ cipher_ok ( &des_test2_7 );
+ cipher_ok ( &des_test2_8 );
+ cipher_ok ( &des_test2_9 );
+ cipher_ok ( &des_test2_10 );
+ cipher_ok ( &des_test2_11 );
+ cipher_ok ( &des_test2_12 );
+ cipher_ok ( &des_test2_13 );
+ cipher_ok ( &des_test2_14 );
+ cipher_ok ( &des_test2_15 );
+ cipher_ok ( &des_test2_16 );
+ cipher_ok ( &des_test2_17 );
+ cipher_ok ( &des_test2_18 );
+ cipher_ok ( &des_test2_19 );
+ cipher_ok ( &des_test2_20 );
+ cipher_ok ( &des_test2_21 );
+ cipher_ok ( &des_test2_22 );
+ cipher_ok ( &des_test2_23 );
+ cipher_ok ( &des_test2_24 );
+ cipher_ok ( &des_test2_25 );
+ cipher_ok ( &des_test2_26 );
+ cipher_ok ( &des_test2_27 );
+ cipher_ok ( &des_test2_28 );
+ cipher_ok ( &des_test2_29 );
+ cipher_ok ( &des_test2_30 );
+ cipher_ok ( &des_test2_31 );
+ cipher_ok ( &des_test2_32 );
+ cipher_ok ( &des_test2_33 );
+ cipher_ok ( &des_test2_34 );
+ cipher_ok ( &des_test2_35 );
+ cipher_ok ( &des_test2_36 );
+ cipher_ok ( &des_test2_37 );
+ cipher_ok ( &des_test2_38 );
+ cipher_ok ( &des_test2_39 );
+ cipher_ok ( &des_test2_40 );
+ cipher_ok ( &des_test2_41 );
+ cipher_ok ( &des_test2_42 );
+ cipher_ok ( &des_test2_43 );
+ cipher_ok ( &des_test2_44 );
+ cipher_ok ( &des_test2_45 );
+ cipher_ok ( &des_test2_46 );
+ cipher_ok ( &des_test2_47 );
+ cipher_ok ( &des_test2_48 );
+ cipher_ok ( &des_test2_49 );
+ cipher_ok ( &des_test2_50 );
+ cipher_ok ( &des_test2_51 );
+ cipher_ok ( &des_test2_52 );
+ cipher_ok ( &des_test2_53 );
+ cipher_ok ( &des_test2_54 );
+ cipher_ok ( &des_test2_55 );
+ cipher_ok ( &des_test2_56 );
+ cipher_ok ( &des_test2_57 );
+ cipher_ok ( &des_test2_58 );
+ cipher_ok ( &des_test2_59 );
+ cipher_ok ( &des_test2_60 );
+ cipher_ok ( &des_test2_61 );
+ cipher_ok ( &des_test2_62 );
+ cipher_ok ( &des_test2_63 );
+ cipher_ok ( &des_test2_64 );
+
+ /* Test 3: Data permutation tests */
+ cipher_ok ( &des_test3_1 );
+ cipher_ok ( &des_test3_2 );
+ cipher_ok ( &des_test3_3 );
+ cipher_ok ( &des_test3_4 );
+ cipher_ok ( &des_test3_5 );
+ cipher_ok ( &des_test3_6 );
+ cipher_ok ( &des_test3_7 );
+ cipher_ok ( &des_test3_8 );
+ cipher_ok ( &des_test3_9 );
+ cipher_ok ( &des_test3_10 );
+ cipher_ok ( &des_test3_11 );
+ cipher_ok ( &des_test3_12 );
+ cipher_ok ( &des_test3_13 );
+ cipher_ok ( &des_test3_14 );
+ cipher_ok ( &des_test3_15 );
+ cipher_ok ( &des_test3_16 );
+ cipher_ok ( &des_test3_17 );
+ cipher_ok ( &des_test3_18 );
+ cipher_ok ( &des_test3_19 );
+ cipher_ok ( &des_test3_20 );
+ cipher_ok ( &des_test3_21 );
+ cipher_ok ( &des_test3_22 );
+ cipher_ok ( &des_test3_23 );
+ cipher_ok ( &des_test3_24 );
+ cipher_ok ( &des_test3_25 );
+ cipher_ok ( &des_test3_26 );
+ cipher_ok ( &des_test3_27 );
+ cipher_ok ( &des_test3_28 );
+ cipher_ok ( &des_test3_29 );
+ cipher_ok ( &des_test3_30 );
+ cipher_ok ( &des_test3_31 );
+ cipher_ok ( &des_test3_32 );
+
+ /* Test 4: Key permutation tests */
+ cipher_ok ( &des_test4_1 );
+ cipher_ok ( &des_test4_2 );
+ cipher_ok ( &des_test4_3 );
+ cipher_ok ( &des_test4_4 );
+ cipher_ok ( &des_test4_5 );
+ cipher_ok ( &des_test4_6 );
+ cipher_ok ( &des_test4_7 );
+ cipher_ok ( &des_test4_8 );
+ cipher_ok ( &des_test4_9 );
+ cipher_ok ( &des_test4_10 );
+ cipher_ok ( &des_test4_11 );
+ cipher_ok ( &des_test4_12 );
+ cipher_ok ( &des_test4_13 );
+ cipher_ok ( &des_test4_14 );
+ cipher_ok ( &des_test4_15 );
+ cipher_ok ( &des_test4_16 );
+ cipher_ok ( &des_test4_17 );
+ cipher_ok ( &des_test4_18 );
+ cipher_ok ( &des_test4_19 );
+ cipher_ok ( &des_test4_20 );
+ cipher_ok ( &des_test4_21 );
+ cipher_ok ( &des_test4_22 );
+ cipher_ok ( &des_test4_23 );
+ cipher_ok ( &des_test4_24 );
+ cipher_ok ( &des_test4_25 );
+ cipher_ok ( &des_test4_26 );
+ cipher_ok ( &des_test4_27 );
+ cipher_ok ( &des_test4_28 );
+ cipher_ok ( &des_test4_29 );
+ cipher_ok ( &des_test4_30 );
+ cipher_ok ( &des_test4_31 );
+ cipher_ok ( &des_test4_32 );
+ cipher_ok ( &des_test4_33 );
+ cipher_ok ( &des_test4_34 );
+ cipher_ok ( &des_test4_35 );
+ cipher_ok ( &des_test4_36 );
+ cipher_ok ( &des_test4_37 );
+ cipher_ok ( &des_test4_38 );
+ cipher_ok ( &des_test4_39 );
+ cipher_ok ( &des_test4_40 );
+ cipher_ok ( &des_test4_41 );
+ cipher_ok ( &des_test4_42 );
+ cipher_ok ( &des_test4_43 );
+ cipher_ok ( &des_test4_44 );
+ cipher_ok ( &des_test4_45 );
+ cipher_ok ( &des_test4_46 );
+ cipher_ok ( &des_test4_47 );
+ cipher_ok ( &des_test4_48 );
+ cipher_ok ( &des_test4_49 );
+ cipher_ok ( &des_test4_50 );
+ cipher_ok ( &des_test4_51 );
+ cipher_ok ( &des_test4_52 );
+ cipher_ok ( &des_test4_53 );
+ cipher_ok ( &des_test4_54 );
+ cipher_ok ( &des_test4_55 );
+ cipher_ok ( &des_test4_56 );
+
+ /* Test 5: S-box tests */
+ cipher_ok ( &des_test5_1 );
+ cipher_ok ( &des_test5_2 );
+ cipher_ok ( &des_test5_3 );
+ cipher_ok ( &des_test5_4 );
+ cipher_ok ( &des_test5_5 );
+ cipher_ok ( &des_test5_6 );
+ cipher_ok ( &des_test5_7 );
+ cipher_ok ( &des_test5_8 );
+ cipher_ok ( &des_test5_9 );
+ cipher_ok ( &des_test5_10 );
+ cipher_ok ( &des_test5_11 );
+ cipher_ok ( &des_test5_12 );
+ cipher_ok ( &des_test5_13 );
+ cipher_ok ( &des_test5_14 );
+ cipher_ok ( &des_test5_15 );
+ cipher_ok ( &des_test5_16 );
+ cipher_ok ( &des_test5_17 );
+ cipher_ok ( &des_test5_18 );
+ cipher_ok ( &des_test5_19 );
+
+ /* Multi-block tests */
+ cipher_ok ( &des_unofficial_ecb );
+ cipher_ok ( &des_unofficial_cbc );
+
+ /* Speed tests */
+ DBG ( "DES-ECB encryption required %ld cycles per byte\n",
+ cipher_cost_encrypt ( &des_ecb_algorithm, 8 ) );
+ DBG ( "DES-ECB decryption required %ld cycles per byte\n",
+ cipher_cost_decrypt ( &des_ecb_algorithm, 8 ) );
+ DBG ( "DES-CBC encryption required %ld cycles per byte\n",
+ cipher_cost_encrypt ( &des_cbc_algorithm, 8 ) );
+ DBG ( "DES-CBC decryption required %ld cycles per byte\n",
+ cipher_cost_decrypt ( &des_cbc_algorithm, 8 ) );
+}
+
+/** DES self-test */
+struct self_test des_test __self_test = {
+ .name = "des",
+ .exec = des_test_exec,
+};
diff --git a/src/tests/list_test.c b/src/tests/list_test.c
index d5b5c65d..c24e8082 100644
--- a/src/tests/list_test.c
+++ b/src/tests/list_test.c
@@ -440,6 +440,22 @@ static void list_test_exec ( void ) {
ok ( list_is_first_entry ( &list_tests[3], list, list ) );
ok ( list_is_last_entry ( &list_tests[3], list, list ) );
+ /* Test list_is_head_entry() */
+ INIT_LIST_HEAD ( list );
+ list_add_tail ( &list_tests[1].list, list );
+ list_add_tail ( &list_tests[6].list, list );
+ list_add_tail ( &list_tests[8].list, list );
+ ok ( list_is_head_entry ( list_entry ( list, typeof ( *pos ), list ),
+ list, list ) );
+ ok ( ! list_is_head_entry ( &list_tests[1], list, list ) );
+ ok ( ! list_is_head_entry ( &list_tests[6], list, list ) );
+ ok ( ! list_is_head_entry ( &list_tests[8], list, list ) );
+ list_for_each_entry ( pos, list, list ) {
+ ok ( list_contains_entry ( pos, list, list ) );
+ ok ( ! list_is_head_entry ( pos, list, list ) );
+ }
+ ok ( list_is_head_entry ( pos, list, list ) );
+
/* Test list_for_each() */
INIT_LIST_HEAD ( list );
list_add_tail ( &list_tests[6].list, list );
@@ -502,6 +518,38 @@ static void list_test_exec ( void ) {
list_iterate_entry_ok ( list_for_each_entry_continue_reverse, "",
pos, list, list );
+ /* Test list_for_each_entry_safe_continue() */
+ INIT_LIST_HEAD ( list );
+ list_add_tail ( &list_tests[9].list, list );
+ list_add_tail ( &list_tests[4].list, list );
+ list_add_tail ( &list_tests[2].list, list );
+ list_add_tail ( &list_tests[5].list, list );
+ list_add_tail ( &list_tests[7].list, list );
+ {
+ char *expecteds[] = { "94257", "9457", "947", "94" };
+ char **expected = expecteds;
+ pos = &list_tests[4];
+ list_for_each_entry_safe_continue ( pos, tmp, list, list ) {
+ list_contents_ok ( list, *expected );
+ list_del ( &pos->list );
+ expected++;
+ list_contents_ok ( list, *expected );
+ }
+ }
+ list_contents_ok ( list, "94" );
+ {
+ char *expecteds[] = { "94", "4", "" };
+ char **expected = expecteds;
+ ok ( pos == list_entry ( list, struct list_test, list ) );
+ list_for_each_entry_safe_continue ( pos, tmp, list, list ) {
+ list_contents_ok ( list, *expected );
+ list_del ( &pos->list );
+ expected++;
+ list_contents_ok ( list, *expected );
+ }
+ }
+ ok ( list_empty ( list ) );
+
/* Test list_contains() and list_contains_entry() */
INIT_LIST_HEAD ( list );
INIT_LIST_HEAD ( &list_tests[3].list );
diff --git a/src/tests/mschapv2_test.c b/src/tests/mschapv2_test.c
new file mode 100644
index 00000000..3d10ed18
--- /dev/null
+++ b/src/tests/mschapv2_test.c
@@ -0,0 +1,144 @@
+/*
+ * 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
+ *
+ * MS-CHAPv2 authentication self-tests
+ *
+ */
+
+/* Forcibly enable assertions */
+#undef NDEBUG
+
+#include <stdlib.h>
+#include <string.h>
+#include <ipxe/mschapv2.h>
+#include <ipxe/test.h>
+
+/** An MS-CHAPv2 test */
+struct mschapv2_test {
+ /** Username */
+ const char *username;
+ /** Password */
+ const char *password;
+ /** Authenticator challenge */
+ const struct mschapv2_challenge *challenge;
+ /** Peer challenge */
+ const struct mschapv2_challenge *peer;
+ /** Expected challenge response */
+ const struct mschapv2_response *response;
+ /** Expected authenticator response */
+ const struct mschapv2_auth *auth;
+};
+
+/** Define inline data */
+#define DATA(...) { __VA_ARGS__ }
+
+/** Define an MS-CHAPv2 test */
+#define MSCHAPV2_TEST( name, USERNAME, PASSWORD, CHALLENGE, PEER, \
+ RESPONSE, AUTH ) \
+ static const struct mschapv2_challenge name ## _challenge = { \
+ .byte = CHALLENGE, \
+ }; \
+ static const struct mschapv2_challenge name ## _peer = { \
+ .byte = PEER, \
+ }; \
+ static const union { \
+ struct mschapv2_response response; \
+ uint8_t byte[ sizeof ( struct mschapv2_response ) ]; \
+ } name ## _response = { \
+ .byte = RESPONSE, \
+ }; \
+ static const union { \
+ struct mschapv2_auth auth; \
+ uint8_t byte[ sizeof ( struct mschapv2_auth ) ]; \
+ } name ## _auth = { \
+ .byte = AUTH, \
+ }; \
+ static struct mschapv2_test name = { \
+ .username = USERNAME, \
+ .password = PASSWORD, \
+ .challenge = &name ## _challenge, \
+ .peer = &name ## _peer, \
+ .response = &name ## _response.response, \
+ .auth = &name ## _auth.auth, \
+ };
+
+/** RFC 2759 section 9.2 test case */
+MSCHAPV2_TEST ( rfc2759_test,
+ "User", "clientPass",
+ DATA ( 0x5b, 0x5d, 0x7c, 0x7d, 0x7b, 0x3f, 0x2f, 0x3e,
+ 0x3c, 0x2c, 0x60, 0x21, 0x32, 0x26, 0x26, 0x28 ),
+ DATA ( 0x21, 0x40, 0x23, 0x24, 0x25, 0x5e, 0x26, 0x2a,
+ 0x28, 0x29, 0x5f, 0x2b, 0x3a, 0x33, 0x7c, 0x7e ),
+ DATA ( 0x21, 0x40, 0x23, 0x24, 0x25, 0x5e, 0x26, 0x2a,
+ 0x28, 0x29, 0x5f, 0x2b, 0x3a, 0x33, 0x7c, 0x7e,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x82, 0x30, 0x9e, 0xcd, 0x8d, 0x70, 0x8b, 0x5e,
+ 0xa0, 0x8f, 0xaa, 0x39, 0x81, 0xcd, 0x83, 0x54,
+ 0x42, 0x33, 0x11, 0x4a, 0x3d, 0x85, 0xd6, 0xdf,
+ 0x00 ),
+ "S=407A5589115FD0D6209F510FE9C04566932CDA56" );
+
+/**
+ * Report an MS-CHAPv2 test result
+ *
+ * @v test Authentication test
+ * @v file Test code file
+ * @v line Test code line
+ */
+static void mschapv2_okx ( struct mschapv2_test *test,
+ const char *file, unsigned int line ) {
+ struct mschapv2_response response;
+ struct mschapv2_auth auth;
+
+ /* Compute challenge response */
+ mschapv2_response ( test->username, test->password, test->challenge,
+ test->peer, &response );
+ okx ( memcmp ( &response, test->response, sizeof ( response ) ) == 0,
+ file, line );
+
+ /* Compute authenticator response */
+ mschapv2_auth ( test->username, test->password, test->challenge,
+ test->response, &auth );
+ okx ( memcmp ( &auth, test->auth, sizeof ( auth ) ) == 0, file, line );
+}
+#define mschapv2_ok( test ) \
+ mschapv2_okx ( test, __FILE__, __LINE__ )
+
+/**
+ * Perform MS-CHAPv2 self-test
+ *
+ */
+static void mschapv2_test_exec ( void ) {
+
+ mschapv2_ok ( &rfc2759_test );
+}
+
+/** MS-CHAPv2 self-test */
+struct self_test mschapv2_test __self_test = {
+ .name = "mschapv2",
+ .exec = mschapv2_test_exec,
+};
diff --git a/src/tests/settings_test.c b/src/tests/settings_test.c
index 5da7eb00..edd7b9d7 100644
--- a/src/tests/settings_test.c
+++ b/src/tests/settings_test.c
@@ -420,13 +420,21 @@ static void settings_test_exec ( void ) {
RAW ( 0x80, 0x81, 0x82, 0x83, 0x84, 0x00, 0xff ),
"gIGCg4QA/w==" );
- /* "uuid" setting type (no store capability) */
+ /* "uuid" setting type */
+ storef_ok ( &test_settings, &test_uuid_setting,
+ "36d22ed9-b64f-4fdb-941b-a54a0854f991",
+ RAW ( 0x36, 0xd2, 0x2e, 0xd9, 0xb6, 0x4f, 0x4f, 0xdb, 0x94,
+ 0x1b, 0xa5, 0x4a, 0x08, 0x54, 0xf9, 0x91 ) );
+ storef_ok ( &test_settings, &test_guid_setting,
+ "7ad4478f-c270-4601-a245-78598f25a984",
+ RAW ( 0x8f, 0x47, 0xd4, 0x7a, 0x70, 0xc2, 0x01, 0x46, 0xa2,
+ 0x45, 0x78, 0x59, 0x8f, 0x25, 0xa9, 0x84 ) );
fetchf_ok ( &test_settings, &test_uuid_setting,
- RAW ( 0x1a, 0x6a, 0x74, 0x9d, 0x0e, 0xda, 0x46, 0x1a,0xa8,
+ RAW ( 0x1a, 0x6a, 0x74, 0x9d, 0x0e, 0xda, 0x46, 0x1a, 0xa8,
0x7a, 0x7c, 0xfe, 0x4f, 0xca, 0x4a, 0x57 ),
"1a6a749d-0eda-461a-a87a-7cfe4fca4a57" );
fetchf_ok ( &test_settings, &test_guid_setting,
- RAW ( 0x1a, 0x6a, 0x74, 0x9d, 0x0e, 0xda, 0x46, 0x1a,0xa8,
+ RAW ( 0x1a, 0x6a, 0x74, 0x9d, 0x0e, 0xda, 0x46, 0x1a, 0xa8,
0x7a, 0x7c, 0xfe, 0x4f, 0xca, 0x4a, 0x57 ),
"9d746a1a-da0e-1a46-a87a-7cfe4fca4a57" );
diff --git a/src/tests/tests.c b/src/tests/tests.c
index fbdf562c..cb296049 100644
--- a/src/tests/tests.c
+++ b/src/tests/tests.c
@@ -81,3 +81,7 @@ REQUIRE_OBJECT ( hmac_test );
REQUIRE_OBJECT ( dhe_test );
REQUIRE_OBJECT ( gcm_test );
REQUIRE_OBJECT ( nap_test );
+REQUIRE_OBJECT ( x25519_test );
+REQUIRE_OBJECT ( des_test );
+REQUIRE_OBJECT ( mschapv2_test );
+REQUIRE_OBJECT ( uuid_test );
diff --git a/src/tests/uuid_test.c b/src/tests/uuid_test.c
new file mode 100644
index 00000000..42dc5264
--- /dev/null
+++ b/src/tests/uuid_test.c
@@ -0,0 +1,156 @@
+/*
+ * 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
+ *
+ * UUID tests
+ *
+ */
+
+/* Forcibly enable assertions */
+#undef NDEBUG
+
+#include <string.h>
+#include <byteswap.h>
+#include <ipxe/uuid.h>
+#include <ipxe/test.h>
+
+/** Define an inline UUID value */
+#define UUID( A, B, C, D, E0, E1, E2, E3, E4, E5 ) { \
+ .a = htonl ( A ), \
+ .b = htons ( B ), \
+ .c = htons ( C ), \
+ .d = htons ( D ), \
+ .e = { E0, E1, E2, E3, E4, E5 }, \
+ }
+
+/**
+ * Report a uuid_ntoa() test result
+ *
+ * @v uuid UUID
+ * @v text Expected textual representation
+ * @v file Test code file
+ * @v line Test code line
+ */
+static void uuid_ntoa_okx ( const union uuid *uuid, const char *text,
+ const char *file, unsigned int line ) {
+ const char *actual;
+
+ /* Format address */
+ actual = uuid_ntoa ( uuid );
+ DBG ( "uuid_ntoa ( %08x-%04x-%04x-%04x-%02x%02x%02x%02x%02x%02x ) = "
+ "\"%s\"\n", ntohl ( uuid->canonical.a ),
+ ntohs ( uuid->canonical.b ), ntohs ( uuid->canonical.c ),
+ ntohs ( uuid->canonical.d ), uuid->canonical.e[0],
+ uuid->canonical.e[1], uuid->canonical.e[2], uuid->canonical.e[3],
+ uuid->canonical.e[4], uuid->canonical.e[5], actual );
+ okx ( strcmp ( actual, text ) == 0, file, line );
+}
+#define uuid_ntoa_ok( value, text ) do { \
+ static const union uuid uuid = { \
+ .canonical = value, \
+ }; \
+ uuid_ntoa_okx ( &uuid, text, __FILE__, __LINE__ ); \
+ } while ( 0 )
+
+/**
+ * Report a uuid_aton() test result
+ *
+ * @v text Textual representation
+ * @v uuid Expected UUID
+ * @v file Test code file
+ * @v line Test code line
+ */
+static void uuid_aton_okx ( const char *text, const union uuid *uuid,
+ const char *file, unsigned int line ) {
+ union uuid actual;
+
+ /* Parse address */
+ okx ( uuid_aton ( text, &actual ) == 0, file, line );
+ DBG ( "uuid_aton ( \"%s\" ) = %s\n", text, uuid_ntoa ( &actual ) );
+ okx ( memcmp ( &actual, uuid, sizeof ( actual ) ) == 0, file, line );
+};
+#define uuid_aton_ok( text, value ) do { \
+ static const union uuid uuid = { \
+ .canonical = value, \
+ }; \
+ uuid_aton_okx ( text, &uuid, __FILE__, __LINE__ ); \
+ } while ( 0 )
+
+/**
+ * Report a uuid_aton() failure test result
+ *
+ * @v text Textual representation
+ * @v file Test code file
+ * @v line Test code line
+ */
+static void uuid_aton_fail_okx ( const char *text, const char *file,
+ unsigned int line ) {
+ union uuid actual;
+
+ /* Attempt to parse address */
+ okx ( uuid_aton ( text, &actual ) != 0, file, line );
+}
+#define uuid_aton_fail_ok( text ) \
+ uuid_aton_fail_okx ( text, __FILE__, __LINE__ )
+
+/**
+ * Perform UUID self-tests
+ *
+ */
+static void uuid_test_exec ( void ) {
+
+ /* uuid_ntoa() tests */
+ uuid_ntoa_ok ( UUID ( 0x18725ca6, 0xd699, 0x4e4d, 0xb501,
+ 0xc3, 0x80, 0x91, 0xd2, 0xa4, 0x33 ),
+ "18725ca6-d699-4e4d-b501-c38091d2a433" );
+ uuid_ntoa_ok ( UUID ( 0x1a969b23, 0xc7d5, 0x40fe, 0xb79a,
+ 0xc9, 0x2e, 0xa3, 0x4a ,0xb4, 0x5b ),
+ "1a969b23-c7d5-40fe-b79a-c92ea34ab45b" );
+
+ /* uuid_aton() tests */
+ uuid_aton_ok ( "62b907a8-e1a7-460e-82f7-667d84270c84",
+ UUID ( 0x62b907a8, 0xe1a7, 0x460e, 0x82f7,
+ 0x66, 0x7d, 0x84, 0x27, 0x0c, 0x84 ) );
+ uuid_aton_ok ( "F5D0349C-EF7C-4AD4-B40B-FC2E522A7327",
+ UUID ( 0xf5d0349c, 0xef7c, 0x4ad4, 0xb40b,
+ 0xfc, 0x2e, 0x52, 0x2a, 0x73, 0x27 ) );
+ uuid_aton_ok ( "4edd80ff7b43465589a02b1e7cffa196",
+ UUID ( 0x4edd80ff, 0x7b43, 0x4655, 0x89a0,
+ 0x2b, 0x1e, 0x7c, 0xff, 0xa1, 0x96 ) );
+
+ /* uuid_aton() failure tests */
+ uuid_aton_fail_ok ( "628d677b-cf38-471e-9ad9-c8a5d9220055b6" );
+ uuid_aton_fail_ok ( "5071ca26-fc5f-4580-887a-46d9a103e4" );
+ uuid_aton_fail_ok ( "453aee96:0fb5-4aeb-aecd-d060b2121218" );
+ uuid_aton_fail_ok ( "1ccb524a-b8b9-4b17-x5e2-7996867edc7d" );
+ uuid_aton_fail_ok ( "" );
+}
+
+/** UUID self-test */
+struct self_test uuid_test __self_test = {
+ .name = "uuid",
+ .exec = uuid_test_exec,
+};
diff --git a/src/tests/x25519_test.c b/src/tests/x25519_test.c
new file mode 100644
index 00000000..3dfbd339
--- /dev/null
+++ b/src/tests/x25519_test.c
@@ -0,0 +1,600 @@
+/*
+ * 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
+ *
+ * X25519 key exchange test
+ *
+ * Full key exchange test vectors are taken from RFC7748.
+ *
+ */
+
+/* Forcibly enable assertions */
+#undef NDEBUG
+
+#include <stdint.h>
+#include <string.h>
+#include <ipxe/x25519.h>
+#include <ipxe/test.h>
+
+/** Define inline multiplicand */
+#define MULTIPLICAND(...) { __VA_ARGS__ }
+
+/** Define inline multiplier */
+#define MULTIPLIER(...) { __VA_ARGS__ }
+
+/** Define inline invertend */
+#define INVERTEND(...) { __VA_ARGS__ }
+
+/** Define inline base point */
+#define BASE(...) { __VA_ARGS__ }
+
+/** Define inline scalar multiple */
+#define SCALAR(...) { __VA_ARGS__ }
+
+/** Define inline expected result */
+#define EXPECTED(...) { __VA_ARGS__ }
+
+/** An X25519 multiplication self-test */
+struct x25519_multiply_test {
+ /** Multiplicand */
+ const void *multiplicand;
+ /** Length of multiplicand */
+ size_t multiplicand_len;
+ /** Multiplier */
+ const void *multiplier;
+ /** Length of multiplier */
+ size_t multiplier_len;
+ /** Expected result */
+ const void *expected;
+ /** Length of expected result */
+ size_t expected_len;
+};
+
+/**
+ * Define an X25519 multiplication test
+ *
+ * @v name Test name
+ * @v MULTIPLICAND 258-bit multiplicand
+ * @v MULTIPLIER 258-bit multiplier
+ * @v EXPECTED 255-bit expected result
+ * @ret test X25519 multiplication test
+ */
+#define X25519_MULTIPLY_TEST( name, MULTIPLICAND, MULTIPLIER, \
+ EXPECTED ) \
+ static const uint8_t name ## _multiplicand[] = MULTIPLICAND; \
+ static const uint8_t name ## _multiplier[] = MULTIPLIER; \
+ static const uint8_t name ## _expected[] = EXPECTED; \
+ static struct x25519_multiply_test name = { \
+ .multiplicand = name ## _multiplicand, \
+ .multiplicand_len = sizeof ( name ## _multiplicand ), \
+ .multiplier = name ## _multiplier, \
+ .multiplier_len = sizeof ( name ## _multiplier ), \
+ .expected = name ## _expected, \
+ .expected_len = sizeof ( name ## _expected ), \
+ }
+
+/** An X25519 multiplicative inversion self-test */
+struct x25519_invert_test {
+ /** Invertend */
+ const void *invertend;
+ /** Length of invertend */
+ size_t invertend_len;
+ /** Expected result */
+ const void *expected;
+ /** Length of expected result */
+ size_t expected_len;
+};
+
+/**
+ * Define an X25519 multiplicative inversion test
+ *
+ * @v name Test name
+ * @v INVERTEND 258-bit invertend
+ * @v EXPECTED 255-bit expected result
+ * @ret test X25519 multiplicative inversion test
+ */
+#define X25519_INVERT_TEST( name, INVERTEND, EXPECTED ) \
+ static const uint8_t name ## _invertend[] = INVERTEND; \
+ static const uint8_t name ## _expected[] = EXPECTED; \
+ static struct x25519_invert_test name = { \
+ .invertend = name ## _invertend, \
+ .invertend_len = sizeof ( name ## _invertend ), \
+ .expected = name ## _expected, \
+ .expected_len = sizeof ( name ## _expected ), \
+ }
+
+/** An X25519 key exchange self-test */
+struct x25519_key_test {
+ /** Base */
+ struct x25519_value base;
+ /** Scalar */
+ struct x25519_value scalar;
+ /** Expected result */
+ struct x25519_value expected;
+ /** Number of iterations */
+ unsigned int count;
+ /** Key exchange is expected to fail (i.e. produce all-zeroes) */
+ int fail;
+};
+
+/**
+ * Define an X25519 key exchange test
+ *
+ * @v name Test name
+ * @v COUNT Number of iterations
+ * @v FAIL Expected failure status
+ * @v BASE Base point
+ * @v SCALAR Scalar multiple
+ * @v EXPECTED Expected result
+ * @ret test X25519 key exchange test
+ */
+#define X25519_KEY_TEST( name, COUNT, FAIL, BASE, SCALAR, EXPECTED ) \
+ static struct x25519_key_test name = { \
+ .count = COUNT, \
+ .fail = FAIL, \
+ .base = { .raw = BASE }, \
+ .scalar = { .raw = SCALAR }, \
+ .expected = { .raw = EXPECTED }, \
+ }
+
+/**
+ * Report an X25519 multiplication test result
+ *
+ * @v test X25519 multiplication test
+ * @v file Test code file
+ * @v line Test code line
+ */
+static void x25519_multiply_okx ( struct x25519_multiply_test *test,
+ const char *file, unsigned int line ) {
+ union x25519_oct258 multiplicand;
+ union x25519_oct258 multiplier;
+ union x25519_quad257 expected;
+ union x25519_quad257 actual;
+
+ /* Construct big integers */
+ bigint_init ( &multiplicand.value, test->multiplicand,
+ test->multiplicand_len );
+ DBGC ( test, "X25519 multiplicand:\n" );
+ DBGC_HDA ( test, 0, &multiplicand, sizeof ( multiplicand ) );
+ bigint_init ( &multiplier.value, test->multiplier,
+ test->multiplier_len );
+ DBGC ( test, "X25519 multiplier:\n" );
+ DBGC_HDA ( test, 0, &multiplier, sizeof ( multiplier ) );
+ bigint_init ( &expected.value, test->expected, test->expected_len );
+ DBGC ( test, "X25519 expected product:\n" );
+ DBGC_HDA ( test, 0, &expected, sizeof ( expected ) );
+
+ /* Perform multiplication */
+ x25519_multiply ( &multiplicand, &multiplier, &actual );
+
+ /* Reduce result to allow for comparison */
+ x25519_reduce ( &actual );
+ DBGC ( test, "X25519 actual product:\n" );
+ DBGC_HDA ( test, 0, &actual, sizeof ( actual ) );
+
+ /* Compare against expected result */
+ okx ( memcmp ( &actual, &expected, sizeof ( expected ) ) == 0,
+ file, line );
+}
+#define x25519_multiply_ok( test ) \
+ x25519_multiply_okx ( test, __FILE__, __LINE__ )
+
+/**
+ * Report an X25519 multiplicative inversion test result
+ *
+ * @v test X25519 multiplicative inversion test
+ * @v file Test code file
+ * @v line Test code line
+ */
+static void x25519_invert_okx ( struct x25519_invert_test *test,
+ const char *file, unsigned int line ) {
+ static const uint8_t one[] = { 1 };
+ union x25519_oct258 invertend;
+ union x25519_quad257 expected;
+ union x25519_quad257 actual;
+ union x25519_quad257 product;
+ union x25519_quad257 identity;
+
+ /* Construct big integers */
+ bigint_init ( &invertend.value, test->invertend, test->invertend_len );
+ DBGC ( test, "X25519 invertend:\n" );
+ DBGC_HDA ( test, 0, &invertend, sizeof ( invertend ) );
+ bigint_init ( &expected.value, test->expected, test->expected_len );
+ DBGC ( test, "X25519 expected inverse:\n" );
+ DBGC_HDA ( test, 0, &expected, sizeof ( expected ) );
+ bigint_init ( &identity.value, one, sizeof ( one ) );
+
+ /* Perform inversion */
+ x25519_invert ( &invertend, &actual );
+
+ /* Multiply invertend by inverse */
+ x25519_multiply ( &invertend, &actual.oct258, &product );
+
+ /* Reduce results to allow for comparison */
+ x25519_reduce ( &actual );
+ DBGC ( test, "X25519 actual inverse:\n" );
+ DBGC_HDA ( test, 0, &actual, sizeof ( actual ) );
+ x25519_reduce ( &product );
+ DBGC ( test, "X25519 actual product:\n" );
+ DBGC_HDA ( test, 0, &product, sizeof ( product ) );
+
+ /* Compare against expected results */
+ okx ( memcmp ( &actual, &expected, sizeof ( expected ) ) == 0,
+ file, line );
+ okx ( memcmp ( &product, &identity, sizeof ( identity ) ) == 0,
+ file, line );
+}
+#define x25519_invert_ok( test ) \
+ x25519_invert_okx ( test, __FILE__, __LINE__ )
+
+/**
+ * Report an X25519 key exchange test result
+ *
+ * @v test X25519 key exchange test
+ * @v file Test code file
+ * @v line Test code line
+ */
+static void x25519_key_okx ( struct x25519_key_test *test,
+ const char *file, unsigned int line ) {
+ struct x25519_value base;
+ struct x25519_value scalar;
+ struct x25519_value actual;
+ unsigned int i;
+ int rc;
+
+ /* Construct input values */
+ memcpy ( &base, &test->base, sizeof ( test->base ) );
+ memcpy ( &scalar, &test->scalar, sizeof ( test->scalar ) );
+ DBGC ( test, "X25519 base:\n" );
+ DBGC_HDA ( test, 0, &base, sizeof ( base ) );
+ DBGC ( test, "X25519 scalar:\n" );
+ DBGC_HDA ( test, 0, &scalar, sizeof ( scalar ) );
+ DBGC ( test, "X25519 expected result (x%d):\n", test->count );
+ DBGC_HDA ( test, 0, &test->expected, sizeof ( test->expected ) );
+
+ /* Calculate key */
+ for ( i = 0 ; i < test->count ; i++ ) {
+ rc = x25519_key ( &base, &scalar, &actual );
+ if ( test->fail ) {
+ okx ( rc != 0, file, line );
+ } else {
+ okx ( rc == 0, file, line );
+ }
+ memcpy ( &base, &scalar, sizeof ( base ) );
+ memcpy ( &scalar, &actual, sizeof ( scalar ) );
+ }
+ DBGC ( test, "X25519 actual result (x%d):\n", test->count );
+ DBGC_HDA ( test, 0, &actual, sizeof ( actual ) );
+
+ /* Compare against expected result */
+ okx ( memcmp ( &actual, &test->expected,
+ sizeof ( test->expected ) ) == 0, file, line );
+}
+#define x25519_key_ok( test ) \
+ x25519_key_okx ( test, __FILE__, __LINE__ )
+
+/* Test multiplying small numbers */
+X25519_MULTIPLY_TEST ( multiply_small, MULTIPLICAND ( 6 ),
+ MULTIPLIER ( 9 ), EXPECTED ( 6 * 9 ) );
+
+/* Test exact multiple of field prime */
+X25519_MULTIPLY_TEST ( multiply_k_p,
+ MULTIPLICAND ( 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xed ),
+ MULTIPLIER ( 0x00, 0xe8, 0x0d, 0x83, 0xd4, 0xe9, 0x1e, 0xdd, 0x7a,
+ 0x45, 0x14, 0x87, 0xb7, 0xfc, 0x62, 0x54, 0x1f, 0xb2,
+ 0x97, 0x24, 0xde, 0xfa, 0xd3, 0xe7, 0x3e, 0x83, 0x93,
+ 0x60, 0xbc, 0x20, 0x97, 0x9b, 0x22 ),
+ EXPECTED ( 0x00 ) );
+
+/* 0x0223b8c1e9392456de3eb13b9046685257bdd640fb06671ad11c80317fa3b1799d *
+ * 0x006c031199972a846916419f828b9d2434e465e150bd9c66b3ad3c2d6d1a3d1fa7 =
+ * 0x1ba87e982f7c477616b4d5136ba54733e40081c1c2e27d864aa178ce893d1297 (mod p)
+ */
+X25519_MULTIPLY_TEST ( multiply_1,
+ MULTIPLICAND ( 0x02, 0x23, 0xb8, 0xc1, 0xe9, 0x39, 0x24, 0x56, 0xde,
+ 0x3e, 0xb1, 0x3b, 0x90, 0x46, 0x68, 0x52, 0x57, 0xbd,
+ 0xd6, 0x40, 0xfb, 0x06, 0x67, 0x1a, 0xd1, 0x1c, 0x80,
+ 0x31, 0x7f, 0xa3, 0xb1, 0x79, 0x9d ),
+ MULTIPLIER ( 0x00, 0x6c, 0x03, 0x11, 0x99, 0x97, 0x2a, 0x84, 0x69,
+ 0x16, 0x41, 0x9f, 0x82, 0x8b, 0x9d, 0x24, 0x34, 0xe4,
+ 0x65, 0xe1, 0x50, 0xbd, 0x9c, 0x66, 0xb3, 0xad, 0x3c,
+ 0x2d, 0x6d, 0x1a, 0x3d, 0x1f, 0xa7 ),
+ EXPECTED ( 0x1b, 0xa8, 0x7e, 0x98, 0x2f, 0x7c, 0x47, 0x76, 0x16, 0xb4,
+ 0xd5, 0x13, 0x6b, 0xa5, 0x47, 0x33, 0xe4, 0x00, 0x81, 0xc1,
+ 0xc2, 0xe2, 0x7d, 0x86, 0x4a, 0xa1, 0x78, 0xce, 0x89, 0x3d,
+ 0x12, 0x97 ) );
+
+/* 0x008fadc1a606cb0fb39a1de644815ef6d13b8faa1837f8a88b17fc695a07a0ca6e *
+ * 0x0196da1dac72ff5d2a386ecbe06b65a6a48b8148f6b38a088ca65ed389b74d0fb1 =
+ * 0x351f7bf75ef580249ed6f9ff3996463b0730a1d49b5d36b863e192591157e950 (mod p)
+ */
+X25519_MULTIPLY_TEST ( multiply_2,
+ MULTIPLICAND ( 0x00, 0x8f, 0xad, 0xc1, 0xa6, 0x06, 0xcb, 0x0f, 0xb3,
+ 0x9a, 0x1d, 0xe6, 0x44, 0x81, 0x5e, 0xf6, 0xd1, 0x3b,
+ 0x8f, 0xaa, 0x18, 0x37, 0xf8, 0xa8, 0x8b, 0x17, 0xfc,
+ 0x69, 0x5a, 0x07, 0xa0, 0xca, 0x6e ),
+ MULTIPLIER ( 0x01, 0x96, 0xda, 0x1d, 0xac, 0x72, 0xff, 0x5d, 0x2a,
+ 0x38, 0x6e, 0xcb, 0xe0, 0x6b, 0x65, 0xa6, 0xa4, 0x8b,
+ 0x81, 0x48, 0xf6, 0xb3, 0x8a, 0x08, 0x8c, 0xa6, 0x5e,
+ 0xd3, 0x89, 0xb7, 0x4d, 0x0f, 0xb1 ),
+ EXPECTED ( 0x35, 0x1f, 0x7b, 0xf7, 0x5e, 0xf5, 0x80, 0x24, 0x9e, 0xd6,
+ 0xf9, 0xff, 0x39, 0x96, 0x46, 0x3b, 0x07, 0x30, 0xa1, 0xd4,
+ 0x9b, 0x5d, 0x36, 0xb8, 0x63, 0xe1, 0x92, 0x59, 0x11, 0x57,
+ 0xe9, 0x50 ) );
+
+/* 0x016c307511b2b9437a28df6ec4ce4a2bbdc241330b01a9e71fde8a774bcf36d58b *
+ * 0x0117be31111a2a73ed562b0f79c37459eef50bea63371ecd7b27cd813047229389 =
+ * 0x6b43b5185965f8f0920f31ae1b2cefadd7b078fecf68dbeaa17b9c385b558329 (mod p)
+ */
+X25519_MULTIPLY_TEST ( multiply_3,
+ MULTIPLICAND ( 0x01, 0x6c, 0x30, 0x75, 0x11, 0xb2, 0xb9, 0x43, 0x7a,
+ 0x28, 0xdf, 0x6e, 0xc4, 0xce, 0x4a, 0x2b, 0xbd, 0xc2,
+ 0x41, 0x33, 0x0b, 0x01, 0xa9, 0xe7, 0x1f, 0xde, 0x8a,
+ 0x77, 0x4b, 0xcf, 0x36, 0xd5, 0x8b ),
+ MULTIPLIER ( 0x01, 0x17, 0xbe, 0x31, 0x11, 0x1a, 0x2a, 0x73, 0xed,
+ 0x56, 0x2b, 0x0f, 0x79, 0xc3, 0x74, 0x59, 0xee, 0xf5,
+ 0x0b, 0xea, 0x63, 0x37, 0x1e, 0xcd, 0x7b, 0x27, 0xcd,
+ 0x81, 0x30, 0x47, 0x22, 0x93, 0x89 ),
+ EXPECTED ( 0x6b, 0x43, 0xb5, 0x18, 0x59, 0x65, 0xf8, 0xf0, 0x92, 0x0f,
+ 0x31, 0xae, 0x1b, 0x2c, 0xef, 0xad, 0xd7, 0xb0, 0x78, 0xfe,
+ 0xcf, 0x68, 0xdb, 0xea, 0xa1, 0x7b, 0x9c, 0x38, 0x5b, 0x55,
+ 0x83, 0x29 ) );
+
+/* 0x020b1f9163ce9ff57f43b7a3a69a8dca03580d7b71d8f564135be6128e18c26797 *
+ * 0x018d5288f1142c3fe860e7a113ec1b8ca1f91e1d4c1ff49b7889463e85759cde66 =
+ * 0x28a77d3c8a14323d63b288dbd40315b3f192b8485d86a02cb87d3dfb7a0b5447 (mod p)
+ */
+X25519_MULTIPLY_TEST ( multiply_4,
+ MULTIPLICAND ( 0x02, 0x0b, 0x1f, 0x91, 0x63, 0xce, 0x9f, 0xf5, 0x7f,
+ 0x43, 0xb7, 0xa3, 0xa6, 0x9a, 0x8d, 0xca, 0x03, 0x58,
+ 0x0d, 0x7b, 0x71, 0xd8, 0xf5, 0x64, 0x13, 0x5b, 0xe6,
+ 0x12, 0x8e, 0x18, 0xc2, 0x67, 0x97 ),
+ MULTIPLIER ( 0x01, 0x8d, 0x52, 0x88, 0xf1, 0x14, 0x2c, 0x3f, 0xe8,
+ 0x60, 0xe7, 0xa1, 0x13, 0xec, 0x1b, 0x8c, 0xa1, 0xf9,
+ 0x1e, 0x1d, 0x4c, 0x1f, 0xf4, 0x9b, 0x78, 0x89, 0x46,
+ 0x3e, 0x85, 0x75, 0x9c, 0xde, 0x66 ),
+ EXPECTED ( 0x28, 0xa7, 0x7d, 0x3c, 0x8a, 0x14, 0x32, 0x3d, 0x63, 0xb2,
+ 0x88, 0xdb, 0xd4, 0x03, 0x15, 0xb3, 0xf1, 0x92, 0xb8, 0x48,
+ 0x5d, 0x86, 0xa0, 0x2c, 0xb8, 0x7d, 0x3d, 0xfb, 0x7a, 0x0b,
+ 0x54, 0x47 ) );
+
+/* 0x023139d32c93cd59bf5c941cf0dc98d2c1e2acf72f9e574f7aa0ee89aed453dd32 *
+ * 0x03146d3f31fc377a4c4a15544dc5e7ce8a3a578a8ea9488d990bbb259911ce5dd2 =
+ * 0x4bdb7a35c0a5182000aa67554741e88cfdf460a78c6fae07adf83d2f005d2767 (mod p)
+ */
+X25519_MULTIPLY_TEST ( multiply_5,
+ MULTIPLICAND ( 0x02, 0x31, 0x39, 0xd3, 0x2c, 0x93, 0xcd, 0x59, 0xbf,
+ 0x5c, 0x94, 0x1c, 0xf0, 0xdc, 0x98, 0xd2, 0xc1, 0xe2,
+ 0xac, 0xf7, 0x2f, 0x9e, 0x57, 0x4f, 0x7a, 0xa0, 0xee,
+ 0x89, 0xae, 0xd4, 0x53, 0xdd, 0x32 ),
+ MULTIPLIER ( 0x03, 0x14, 0x6d, 0x3f, 0x31, 0xfc, 0x37, 0x7a, 0x4c,
+ 0x4a, 0x15, 0x54, 0x4d, 0xc5, 0xe7, 0xce, 0x8a, 0x3a,
+ 0x57, 0x8a, 0x8e, 0xa9, 0x48, 0x8d, 0x99, 0x0b, 0xbb,
+ 0x25, 0x99, 0x11, 0xce, 0x5d, 0xd2 ),
+ EXPECTED ( 0x4b, 0xdb, 0x7a, 0x35, 0xc0, 0xa5, 0x18, 0x20, 0x00, 0xaa,
+ 0x67, 0x55, 0x47, 0x41, 0xe8, 0x8c, 0xfd, 0xf4, 0x60, 0xa7,
+ 0x8c, 0x6f, 0xae, 0x07, 0xad, 0xf8, 0x3d, 0x2f, 0x00, 0x5d,
+ 0x27, 0x67 ) );
+
+/* 0x01d58842dea2bc372f7412b29347294739614ff3d719db3ad0ddd1dfb23b982ef8 ^ -1 =
+ * 0x093ff51750809d181a9a5481c564e37cff618def8ec45f464b1a6e24f8b826bd (mod p)
+ */
+X25519_INVERT_TEST ( invert_1,
+ INVERTEND ( 0x01, 0xd5, 0x88, 0x42, 0xde, 0xa2, 0xbc, 0x37, 0x2f,
+ 0x74, 0x12, 0xb2, 0x93, 0x47, 0x29, 0x47, 0x39, 0x61,
+ 0x4f, 0xf3, 0xd7, 0x19, 0xdb, 0x3a, 0xd0, 0xdd, 0xd1,
+ 0xdf, 0xb2, 0x3b, 0x98, 0x2e, 0xf8 ),
+ EXPECTED ( 0x09, 0x3f, 0xf5, 0x17, 0x50, 0x80, 0x9d, 0x18, 0x1a, 0x9a,
+ 0x54, 0x81, 0xc5, 0x64, 0xe3, 0x7c, 0xff, 0x61, 0x8d, 0xef,
+ 0x8e, 0xc4, 0x5f, 0x46, 0x4b, 0x1a, 0x6e, 0x24, 0xf8, 0xb8,
+ 0x26, 0xbd ) );
+
+/* 0x02efc89849b3aa7efe4458a885ab9099a435a240ae5af305535ec42e0829a3b2e9 ^ -1 =
+ * 0x591607b163e89d0ac33a62c881e984a25d3826e3db5ce229af240dc58e5b579a (mod p)
+ */
+X25519_INVERT_TEST ( invert_2,
+ INVERTEND ( 0x02, 0xef, 0xc8, 0x98, 0x49, 0xb3, 0xaa, 0x7e, 0xfe,
+ 0x44, 0x58, 0xa8, 0x85, 0xab, 0x90, 0x99, 0xa4, 0x35,
+ 0xa2, 0x40, 0xae, 0x5a, 0xf3, 0x05, 0x53, 0x5e, 0xc4,
+ 0x2e, 0x08, 0x29, 0xa3, 0xb2, 0xe9 ),
+ EXPECTED ( 0x59, 0x16, 0x07, 0xb1, 0x63, 0xe8, 0x9d, 0x0a, 0xc3, 0x3a,
+ 0x62, 0xc8, 0x81, 0xe9, 0x84, 0xa2, 0x5d, 0x38, 0x26, 0xe3,
+ 0xdb, 0x5c, 0xe2, 0x29, 0xaf, 0x24, 0x0d, 0xc5, 0x8e, 0x5b,
+ 0x57, 0x9a ) );
+
+/* 0x003eabedcbbaa80dd488bd64072bcfbe01a28defe39bf0027312476f57a5e5a5ab ^ -1 =
+ * 0x7d87c2e565b27c5038181a0a7cae9ebe826c8afc1f77128a4d62cce96d2759a2 (mod p)
+ */
+X25519_INVERT_TEST ( invert_3,
+ INVERTEND ( 0x00, 0x3e, 0xab, 0xed, 0xcb, 0xba, 0xa8, 0x0d, 0xd4,
+ 0x88, 0xbd, 0x64, 0x07, 0x2b, 0xcf, 0xbe, 0x01, 0xa2,
+ 0x8d, 0xef, 0xe3, 0x9b, 0xf0, 0x02, 0x73, 0x12, 0x47,
+ 0x6f, 0x57, 0xa5, 0xe5, 0xa5, 0xab ),
+ EXPECTED ( 0x7d, 0x87, 0xc2, 0xe5, 0x65, 0xb2, 0x7c, 0x50, 0x38, 0x18,
+ 0x1a, 0x0a, 0x7c, 0xae, 0x9e, 0xbe, 0x82, 0x6c, 0x8a, 0xfc,
+ 0x1f, 0x77, 0x12, 0x8a, 0x4d, 0x62, 0xcc, 0xe9, 0x6d, 0x27,
+ 0x59, 0xa2 ) );
+
+/* 0x008e944239b02b61c4a3d70628ece66fa2fd5166e6451b4cf36123fdf77656af72 ^ -1 =
+ * 0x08e96161a0eee1b29af396f154950d5c715dc61aff66ee97377ab22adf3321d7 (mod p)
+ */
+X25519_INVERT_TEST ( invert_4,
+ INVERTEND ( 0x00, 0x8e, 0x94, 0x42, 0x39, 0xb0, 0x2b, 0x61, 0xc4,
+ 0xa3, 0xd7, 0x06, 0x28, 0xec, 0xe6, 0x6f, 0xa2, 0xfd,
+ 0x51, 0x66, 0xe6, 0x45, 0x1b, 0x4c, 0xf3, 0x61, 0x23,
+ 0xfd, 0xf7, 0x76, 0x56, 0xaf, 0x72 ),
+ EXPECTED ( 0x08, 0xe9, 0x61, 0x61, 0xa0, 0xee, 0xe1, 0xb2, 0x9a, 0xf3,
+ 0x96, 0xf1, 0x54, 0x95, 0x0d, 0x5c, 0x71, 0x5d, 0xc6, 0x1a,
+ 0xff, 0x66, 0xee, 0x97, 0x37, 0x7a, 0xb2, 0x2a, 0xdf, 0x33,
+ 0x21, 0xd7 ) );
+
+/* 0x00d261a7ab3aa2e4f90e51f30dc6a7ee39c4b032ccd7c524a55304317faf42e12f ^ -1 =
+ * 0x0738781c0aeabfbe6e840c85bd30996ef71bc54988ce16cedd5ab4f30c281597 (mod p)
+ */
+X25519_INVERT_TEST ( invert_5,
+ INVERTEND ( 0x00, 0xd2, 0x61, 0xa7, 0xab, 0x3a, 0xa2, 0xe4, 0xf9,
+ 0x0e, 0x51, 0xf3, 0x0d, 0xc6, 0xa7, 0xee, 0x39, 0xc4,
+ 0xb0, 0x32, 0xcc, 0xd7, 0xc5, 0x24, 0xa5, 0x53, 0x04,
+ 0x31, 0x7f, 0xaf, 0x42, 0xe1, 0x2f ),
+ EXPECTED ( 0x07, 0x38, 0x78, 0x1c, 0x0a, 0xea, 0xbf, 0xbe, 0x6e, 0x84,
+ 0x0c, 0x85, 0xbd, 0x30, 0x99, 0x6e, 0xf7, 0x1b, 0xc5, 0x49,
+ 0x88, 0xce, 0x16, 0xce, 0xdd, 0x5a, 0xb4, 0xf3, 0x0c, 0x28,
+ 0x15, 0x97 ) );
+
+/* Base: 0xe6db6867583030db3594c1a424b15f7c726624ec26b3353b10a903a6d0ab1c4c
+ * Scalar: 0xa546e36bf0527c9d3b16154b82465edd62144c0ac1fc5a18506a2244ba449ac4
+ * Result: 0xc3da55379de9c6908e94ea4df28d084f32eccf03491c71f754b4075577a28552
+ */
+X25519_KEY_TEST ( rfc7748_1, 1, 0,
+ BASE ( 0xe6, 0xdb, 0x68, 0x67, 0x58, 0x30, 0x30, 0xdb, 0x35, 0x94,
+ 0xc1, 0xa4, 0x24, 0xb1, 0x5f, 0x7c, 0x72, 0x66, 0x24, 0xec,
+ 0x26, 0xb3, 0x35, 0x3b, 0x10, 0xa9, 0x03, 0xa6, 0xd0, 0xab,
+ 0x1c, 0x4c ),
+ SCALAR ( 0xa5, 0x46, 0xe3, 0x6b, 0xf0, 0x52, 0x7c, 0x9d, 0x3b, 0x16,
+ 0x15, 0x4b, 0x82, 0x46, 0x5e, 0xdd, 0x62, 0x14, 0x4c, 0x0a,
+ 0xc1, 0xfc, 0x5a, 0x18, 0x50, 0x6a, 0x22, 0x44, 0xba, 0x44,
+ 0x9a, 0xc4 ),
+ EXPECTED ( 0xc3, 0xda, 0x55, 0x37, 0x9d, 0xe9, 0xc6, 0x90, 0x8e, 0x94,
+ 0xea, 0x4d, 0xf2, 0x8d, 0x08, 0x4f, 0x32, 0xec, 0xcf, 0x03,
+ 0x49, 0x1c, 0x71, 0xf7, 0x54, 0xb4, 0x07, 0x55, 0x77, 0xa2,
+ 0x85, 0x52 ) );
+
+/* Base: 0xe5210f12786811d3f4b7959d0538ae2c31dbe7106fc03c3efc4cd549c715a493
+ * Scalar: 0x4b66e9d4d1b4673c5ad22691957d6af5c11b6421e0ea01d42ca4169e7918ba0d
+ * Result: 0x95cbde9476e8907d7aade45cb4b873f88b595a68799fa152e6f8f7647aac7957
+ */
+X25519_KEY_TEST ( rfc7748_2, 1, 0,
+ BASE ( 0xe5, 0x21, 0x0f, 0x12, 0x78, 0x68, 0x11, 0xd3, 0xf4, 0xb7,
+ 0x95, 0x9d, 0x05, 0x38, 0xae, 0x2c, 0x31, 0xdb, 0xe7, 0x10,
+ 0x6f, 0xc0, 0x3c, 0x3e, 0xfc, 0x4c, 0xd5, 0x49, 0xc7, 0x15,
+ 0xa4, 0x93 ),
+ SCALAR ( 0x4b, 0x66, 0xe9, 0xd4, 0xd1, 0xb4, 0x67, 0x3c, 0x5a, 0xd2,
+ 0x26, 0x91, 0x95, 0x7d, 0x6a, 0xf5, 0xc1, 0x1b, 0x64, 0x21,
+ 0xe0, 0xea, 0x01, 0xd4, 0x2c, 0xa4, 0x16, 0x9e, 0x79, 0x18,
+ 0xba, 0x0d ),
+ EXPECTED ( 0x95, 0xcb, 0xde, 0x94, 0x76, 0xe8, 0x90, 0x7d, 0x7a, 0xad,
+ 0xe4, 0x5c, 0xb4, 0xb8, 0x73, 0xf8, 0x8b, 0x59, 0x5a, 0x68,
+ 0x79, 0x9f, 0xa1, 0x52, 0xe6, 0xf8, 0xf7, 0x64, 0x7a, 0xac,
+ 0x79, 0x57 ) );
+
+/* Base: 0x0900000000000000000000000000000000000000000000000000000000000000
+ * Scalar: 0x0900000000000000000000000000000000000000000000000000000000000000
+ * Result: 0x422c8e7a6227d7bca1350b3e2bb7279f7897b87bb6854b783c60e80311ae3079
+ */
+X25519_KEY_TEST ( rfc7748_3, 1, 0,
+ BASE ( 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 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 ( 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00 ),
+ EXPECTED ( 0x42, 0x2c, 0x8e, 0x7a, 0x62, 0x27, 0xd7, 0xbc, 0xa1, 0x35,
+ 0x0b, 0x3e, 0x2b, 0xb7, 0x27, 0x9f, 0x78, 0x97, 0xb8, 0x7b,
+ 0xb6, 0x85, 0x4b, 0x78, 0x3c, 0x60, 0xe8, 0x03, 0x11, 0xae,
+ 0x30, 0x79 ) );
+
+/* Base: 0x0900000000000000000000000000000000000000000000000000000000000000
+ * Scalar: 0x0900000000000000000000000000000000000000000000000000000000000000
+ * Result: 0xb1a5a73158904c020866c13939dd7e1aa26852ee1d2609c92e5a8f1debe2150a
+ * (after 100 iterations)
+ *
+ * RFC7748 gives test vectors for 1000 and 1000000 iterations with
+ * these starting values. This test case stops after 100 iterations
+ * to avoid a pointlessly slow test cycle in the common case of
+ * running tests under Valgrind.
+ */
+X25519_KEY_TEST ( rfc7748_4_100, 100, 0,
+ BASE ( 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 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 ( 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00 ),
+ EXPECTED ( 0xb1, 0xa5, 0xa7, 0x31, 0x58, 0x90, 0x4c, 0x02, 0x08, 0x66,
+ 0xc1, 0x39, 0x39, 0xdd, 0x7e, 0x1a, 0xa2, 0x68, 0x52, 0xee,
+ 0x1d, 0x26, 0x09, 0xc9, 0x2e, 0x5a, 0x8f, 0x1d, 0xeb, 0xe2,
+ 0x15, 0x0a ) );
+
+/* Base: 2^255 - 19 + 1 (deliberately malicious public key)
+ * Scalar: 0x000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0f
+ * Result: Failure (all zeros)
+ */
+X25519_KEY_TEST ( malicious, 1, 1,
+ BASE ( 0xee, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0x7f ),
+ SCALAR ( 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09,
+ 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x00, 0x01, 0x02, 0x03,
+ 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d,
+ 0x0e, 0x0f ),
+ 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 ) );
+
+/**
+ * Perform X25519 self-tests
+ *
+ */
+static void x25519_test_exec ( void ) {
+
+ /* Perform multiplication tests */
+ x25519_multiply_ok ( &multiply_small );
+ x25519_multiply_ok ( &multiply_k_p );
+ x25519_multiply_ok ( &multiply_1 );
+ x25519_multiply_ok ( &multiply_2 );
+ x25519_multiply_ok ( &multiply_3 );
+ x25519_multiply_ok ( &multiply_4 );
+ x25519_multiply_ok ( &multiply_5 );
+
+ /* Perform multiplicative inversion tests */
+ x25519_invert_ok ( &invert_1 );
+ x25519_invert_ok ( &invert_2 );
+ x25519_invert_ok ( &invert_3 );
+ x25519_invert_ok ( &invert_4 );
+ x25519_invert_ok ( &invert_5 );
+
+ /* Perform key exchange tests */
+ x25519_key_ok ( &rfc7748_1 );
+ x25519_key_ok ( &rfc7748_2 );
+ x25519_key_ok ( &rfc7748_3 );
+ x25519_key_ok ( &rfc7748_4_100 );
+ x25519_key_ok ( &malicious );
+}
+
+/** X25519 self-test */
+struct self_test x25519_test __self_test = {
+ .name = "x25519",
+ .exec = x25519_test_exec,
+};
diff --git a/src/tests/x509_test.c b/src/tests/x509_test.c
index b6cba575..50eb4d78 100644
--- a/src/tests/x509_test.c
+++ b/src/tests/x509_test.c
@@ -984,6 +984,7 @@ static void x509_validate_chain_fail_okx ( struct x509_test_chain *chn,
*
*/
static void x509_test_exec ( void ) {
+ struct x509_link *link;
/* Parse all certificates */
x509_certificate_ok ( &root_crt );
@@ -1089,6 +1090,22 @@ static void x509_test_exec ( void ) {
x509_validate_chain_fail_ok ( &useless_chain, test_ca_expired,
&empty_store, &test_root );
+ /* Check chain truncation */
+ link = list_last_entry ( &server_chain.chain->links,
+ struct x509_link, list );
+ ok ( link->cert == root_crt.cert );
+ link = list_prev_entry ( link, &server_chain.chain->links, list );
+ ok ( link->cert == intermediate_crt.cert );
+ x509_validate_chain_ok ( &server_chain, test_time,
+ &empty_store, &test_root );
+ x509_truncate ( server_chain.chain, link );
+ x509_validate_chain_fail_ok ( &server_chain, test_time,
+ &empty_store, &test_root );
+
+ /* Check self-signedess */
+ ok ( x509_is_self_signed ( root_crt.cert ) );
+ ok ( ! x509_is_self_signed ( intermediate_crt.cert ) );
+
/* Sanity check */
assert ( list_empty ( &empty_store.links ) );