mirror of
https://github.com/ipxe/ipxe
synced 2026-05-18 10:00:30 +03:00
[test] Use mock random data for public key self-tests
Make the public key self-tests fully deterministic by temporarily overriding the function used to obtain random data for RSA encryption. Signed-off-by: Michael Brown <mcb30@ipxe.org>
This commit is contained in:
+8
-1
@@ -70,6 +70,9 @@ struct rsa_context {
|
||||
void *tmp;
|
||||
};
|
||||
|
||||
/** Generate random data */
|
||||
int ( * rsa_get_random ) ( void *data, size_t len ) = get_random_nz;
|
||||
|
||||
/**
|
||||
* Identify RSA prefix
|
||||
*
|
||||
@@ -331,7 +334,7 @@ static int rsa_encrypt ( const struct asn1_cursor *key,
|
||||
encoded = temp;
|
||||
encoded[0] = 0x00;
|
||||
encoded[1] = 0x02;
|
||||
if ( ( rc = get_random_nz ( &encoded[2], random_nz_len ) ) != 0 ) {
|
||||
if ( ( rc = rsa_get_random ( &encoded[2], random_nz_len ) ) != 0 ) {
|
||||
DBGC ( &context, "RSA %p could not generate random data: %s\n",
|
||||
&context, strerror ( rc ) );
|
||||
goto err_random;
|
||||
@@ -339,6 +342,8 @@ static int rsa_encrypt ( const struct asn1_cursor *key,
|
||||
encoded[ 2 + random_nz_len ] = 0x00;
|
||||
memcpy ( &encoded[ context.max_len - plaintext->len ],
|
||||
plaintext->data, plaintext->len );
|
||||
DBGC ( &context, "RSA %p encoded:\n", &context );
|
||||
DBGC_HDA ( &context, 0, encoded, context.max_len );
|
||||
|
||||
/* Create space for ciphertext */
|
||||
if ( ( rc = asn1_grow ( ciphertext, context.max_len ) ) != 0 )
|
||||
@@ -404,6 +409,8 @@ static int rsa_decrypt ( const struct asn1_cursor *key,
|
||||
temp = context.input0;
|
||||
encoded = temp;
|
||||
rsa_cipher ( &context, ciphertext->data, encoded );
|
||||
DBGC ( &context, "RSA %p encoded:\n", &context );
|
||||
DBGC_HDA ( &context, 0, encoded, context.max_len );
|
||||
|
||||
/* Parse the message */
|
||||
end = ( encoded + context.max_len );
|
||||
|
||||
@@ -58,4 +58,6 @@ struct rsa_digestinfo_prefix {
|
||||
|
||||
extern struct pubkey_algorithm rsa_algorithm;
|
||||
|
||||
extern int ( * rsa_get_random ) ( void *data, size_t len );
|
||||
|
||||
#endif /* _IPXE_RSA_H */
|
||||
|
||||
@@ -67,6 +67,7 @@ PUBKEY_SIGN_TEST ( p256_hw_test, &ecdsa_algorithm,
|
||||
0x59, 0xd5, 0xdc, 0x3d, 0xb8, 0x13, 0x8f, 0x90, 0x26, 0xfc,
|
||||
0xf5, 0xce, 0xcb, 0xf9, 0x68, 0x91, 0x59, 0x87, 0xc6, 0x7d,
|
||||
0x2a ),
|
||||
RANDOM(),
|
||||
PLAINTEXT ( 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x20, 0x77, 0x6f, 0x72, 0x6c,
|
||||
0x64, 0x0a ),
|
||||
&sha256_algorithm,
|
||||
@@ -104,6 +105,7 @@ PUBKEY_SIGN_TEST ( p256_hw_sha512_test, &ecdsa_algorithm,
|
||||
0x59, 0xd5, 0xdc, 0x3d, 0xb8, 0x13, 0x8f, 0x90, 0x26, 0xfc,
|
||||
0xf5, 0xce, 0xcb, 0xf9, 0x68, 0x91, 0x59, 0x87, 0xc6, 0x7d,
|
||||
0x2a ),
|
||||
RANDOM(),
|
||||
PLAINTEXT ( 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x20, 0x77, 0x6f, 0x72, 0x6c,
|
||||
0x64, 0x0a ),
|
||||
&sha512_algorithm,
|
||||
@@ -142,6 +144,7 @@ PUBKEY_SIGN_TEST ( p256_random_test, &ecdsa_algorithm,
|
||||
0x59, 0xd5, 0xdc, 0x3d, 0xb8, 0x13, 0x8f, 0x90, 0x26, 0xfc,
|
||||
0xf5, 0xce, 0xcb, 0xf9, 0x68, 0x91, 0x59, 0x87, 0xc6, 0x7d,
|
||||
0x2a ),
|
||||
RANDOM(),
|
||||
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,
|
||||
@@ -211,6 +214,7 @@ PUBKEY_SIGN_TEST ( p384_random_test, &ecdsa_algorithm,
|
||||
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 ),
|
||||
RANDOM(),
|
||||
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,
|
||||
|
||||
@@ -40,6 +40,34 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
#include <ipxe/test.h>
|
||||
#include "pubkey_test.h"
|
||||
|
||||
/** Random data input */
|
||||
static const uint8_t *pubkey_random;
|
||||
|
||||
/** Length of random data input */
|
||||
static size_t pubkey_random_len;
|
||||
|
||||
/**
|
||||
* Get random data input
|
||||
*
|
||||
* @v data Output buffer
|
||||
* @v len Length of output buffer
|
||||
* @ret rc Return status code
|
||||
*/
|
||||
int pubkey_test_get_random ( void *data, size_t len ) {
|
||||
|
||||
/* Sanity check */
|
||||
assert ( len <= pubkey_random_len );
|
||||
|
||||
/* Return random data */
|
||||
memcpy ( data, pubkey_random, len );
|
||||
|
||||
/* Consume random data */
|
||||
pubkey_random += len;
|
||||
pubkey_random_len -= len;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Report public key encryption and decryption test result
|
||||
*
|
||||
@@ -57,6 +85,18 @@ void pubkey_okx ( struct pubkey_test *test, const char *file,
|
||||
okx ( pubkey_match ( pubkey, &test->private, &test->public ) == 0,
|
||||
file, line );
|
||||
|
||||
/* Test encrypting with public key to obtain known ciphertext */
|
||||
ciphertext.data = NULL;
|
||||
ciphertext.len = 0;
|
||||
pubkey_random = test->random;
|
||||
pubkey_random_len = test->random_len;
|
||||
okx ( pubkey_encrypt ( pubkey, &test->public, &test->plaintext,
|
||||
&ciphertext ) == 0, file, line );
|
||||
okx ( pubkey_random_len == 0, file, line );
|
||||
okx ( asn1_compare ( asn1_built ( &ciphertext ),
|
||||
&test->ciphertext ) == 0, file, line );
|
||||
free ( ciphertext.data );
|
||||
|
||||
/* Test decrypting with private key to obtain known plaintext */
|
||||
plaintext.data = NULL;
|
||||
plaintext.len = 0;
|
||||
@@ -71,8 +111,11 @@ void pubkey_okx ( struct pubkey_test *test, const char *file,
|
||||
ciphertext.len = 0;
|
||||
plaintext.data = NULL;
|
||||
plaintext.len = 0;
|
||||
pubkey_random = test->random;
|
||||
pubkey_random_len = test->random_len;
|
||||
okx ( pubkey_encrypt ( pubkey, &test->private, &test->plaintext,
|
||||
&ciphertext ) == 0, file, line );
|
||||
okx ( pubkey_random_len == 0, file, line );
|
||||
okx ( pubkey_decrypt ( pubkey, &test->public,
|
||||
asn1_built ( &ciphertext ),
|
||||
&plaintext ) == 0, file, line );
|
||||
@@ -86,8 +129,11 @@ void pubkey_okx ( struct pubkey_test *test, const char *file,
|
||||
ciphertext.len = 0;
|
||||
plaintext.data = NULL;
|
||||
plaintext.len = 0;
|
||||
pubkey_random = test->random;
|
||||
pubkey_random_len = test->random_len;
|
||||
okx ( pubkey_encrypt ( pubkey, &test->public, &test->plaintext,
|
||||
&ciphertext ) == 0, file, line );
|
||||
okx ( pubkey_random_len == 0, file, line );
|
||||
okx ( pubkey_decrypt ( pubkey, &test->private,
|
||||
asn1_built ( &ciphertext ),
|
||||
&plaintext ) == 0, file, line );
|
||||
@@ -140,8 +186,11 @@ void pubkey_sign_okx ( struct pubkey_sign_test *test, const char *file,
|
||||
&cursor ) == 0, file, line );
|
||||
|
||||
/* Test signing using private key */
|
||||
pubkey_random = test->random;
|
||||
pubkey_random_len = test->random_len;
|
||||
okx ( pubkey_sign ( pubkey, &test->private, digest, digestout,
|
||||
&builder ) == 0, file, line );
|
||||
okx ( pubkey_random_len == 0, file, line );
|
||||
okx ( builder.len != 0, file, line );
|
||||
okx ( asn1_compare ( asn1_built ( &builder ), &test->signature ) == 0,
|
||||
file, line );
|
||||
|
||||
+25
-10
@@ -15,14 +15,13 @@ struct pubkey_test {
|
||||
const struct asn1_cursor private;
|
||||
/** Public key */
|
||||
const struct asn1_cursor public;
|
||||
/** Random data input */
|
||||
const void *random;
|
||||
/** Random data input length */
|
||||
size_t random_len;
|
||||
/** 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.
|
||||
*/
|
||||
/** Ciphertext */
|
||||
const struct asn1_cursor ciphertext;
|
||||
};
|
||||
|
||||
@@ -34,6 +33,10 @@ struct pubkey_sign_test {
|
||||
const struct asn1_cursor private;
|
||||
/** Public key */
|
||||
const struct asn1_cursor public;
|
||||
/** Random data input */
|
||||
const void *random;
|
||||
/** Random data input length */
|
||||
size_t random_len;
|
||||
/** Plaintext */
|
||||
const void *plaintext;
|
||||
/** Plaintext length */
|
||||
@@ -50,6 +53,9 @@ struct pubkey_sign_test {
|
||||
/** Define inline public key data */
|
||||
#define PUBLIC(...) { __VA_ARGS__ }
|
||||
|
||||
/** Define inline random data */
|
||||
#define RANDOM(...) { __VA_ARGS__ }
|
||||
|
||||
/** Define inline plaintext data */
|
||||
#define PLAINTEXT(...) { __VA_ARGS__ }
|
||||
|
||||
@@ -66,14 +72,16 @@ struct pubkey_sign_test {
|
||||
* @v PUBKEY Public-key algorithm
|
||||
* @v PRIVATE Private key
|
||||
* @v PUBLIC Public key
|
||||
* @v RANDOM Random data
|
||||
* @v PLAINTEXT Plaintext
|
||||
* @v CIPHERTEXT Ciphertext
|
||||
* @ret test Encryption and decryption test
|
||||
*/
|
||||
#define PUBKEY_TEST( name, PUBKEY, PRIVATE, PUBLIC, PLAINTEXT, \
|
||||
CIPHERTEXT ) \
|
||||
#define PUBKEY_TEST( name, PUBKEY, PRIVATE, PUBLIC, RANDOM, PLAINTEXT, \
|
||||
CIPHERTEXT ) \
|
||||
static const uint8_t name ## _private[] = PRIVATE; \
|
||||
static const uint8_t name ## _public[] = PUBLIC; \
|
||||
static const uint8_t name ## _random[] = RANDOM; \
|
||||
static const uint8_t name ## _plaintext[] = PLAINTEXT; \
|
||||
static const uint8_t name ## _ciphertext[] = CIPHERTEXT; \
|
||||
static struct pubkey_test name = { \
|
||||
@@ -86,6 +94,8 @@ struct pubkey_sign_test {
|
||||
.data = name ## _public, \
|
||||
.len = sizeof ( name ## _public ), \
|
||||
}, \
|
||||
.random = name ## _random, \
|
||||
.random_len = sizeof ( name ## _random ), \
|
||||
.plaintext = { \
|
||||
.data = name ## _plaintext, \
|
||||
.len = sizeof ( name ## _plaintext ), \
|
||||
@@ -103,15 +113,17 @@ struct pubkey_sign_test {
|
||||
* @v PUBKEY Public-key algorithm
|
||||
* @v PRIVATE Private key
|
||||
* @v PUBLIC Public key
|
||||
* @v RANDOM Random data
|
||||
* @v PLAINTEXT Plaintext
|
||||
* @v DIGEST Digest algorithm
|
||||
* @v SIGNATURE Signature
|
||||
* @ret test Signature test
|
||||
*/
|
||||
#define PUBKEY_SIGN_TEST( name, PUBKEY, PRIVATE, PUBLIC, PLAINTEXT, \
|
||||
DIGEST, SIGNATURE ) \
|
||||
#define PUBKEY_SIGN_TEST( name, PUBKEY, PRIVATE, PUBLIC, RANDOM, \
|
||||
PLAINTEXT, DIGEST, SIGNATURE ) \
|
||||
static const uint8_t name ## _private[] = PRIVATE; \
|
||||
static const uint8_t name ## _public[] = PUBLIC; \
|
||||
static const uint8_t name ## _random[] = RANDOM; \
|
||||
static const uint8_t name ## _plaintext[] = PLAINTEXT; \
|
||||
static const uint8_t name ## _signature[] = SIGNATURE; \
|
||||
static struct pubkey_sign_test name = { \
|
||||
@@ -124,6 +136,8 @@ struct pubkey_sign_test {
|
||||
.data = name ## _public, \
|
||||
.len = sizeof ( name ## _public ), \
|
||||
}, \
|
||||
.random = name ## _random, \
|
||||
.random_len = sizeof ( name ## _random ), \
|
||||
.plaintext = name ## _plaintext, \
|
||||
.plaintext_len = sizeof ( name ## _plaintext ), \
|
||||
.digest = DIGEST, \
|
||||
@@ -133,6 +147,7 @@ struct pubkey_sign_test {
|
||||
}, \
|
||||
}
|
||||
|
||||
extern int pubkey_test_get_random ( void *data, size_t len );
|
||||
extern void pubkey_okx ( struct pubkey_test *test,
|
||||
const char *file, unsigned int line );
|
||||
extern void pubkey_sign_okx ( struct pubkey_sign_test *test,
|
||||
|
||||
@@ -87,6 +87,11 @@ PUBKEY_TEST ( hw_test, &rsa_algorithm,
|
||||
0x04, 0xf2, 0x82, 0xc4, 0x7b, 0x6a, 0x3e, 0xec, 0x53, 0x7a,
|
||||
0xe3, 0x4e, 0xa8, 0xc9, 0xf9, 0x1f, 0x2a, 0x13, 0x0d, 0x02,
|
||||
0x03, 0x01, 0x00, 0x01 ),
|
||||
RANDOM ( 0x87, 0x90, 0xdf, 0x03, 0x31, 0x20, 0x31, 0x63, 0x86, 0x30,
|
||||
0xb9, 0xb1, 0x99, 0x5e, 0xf8, 0x2b, 0xb7, 0x6b, 0x62, 0x56,
|
||||
0x8c, 0x2b, 0x88, 0xa1, 0x5b, 0x1e, 0x37, 0xaa, 0x12, 0xa6,
|
||||
0xf6, 0xe8, 0x3a, 0x41, 0x91, 0x70, 0x24, 0x3f, 0x89, 0x9b,
|
||||
0x6e, 0x81, 0x63, 0x8c, 0xe1, 0x63, 0x93, 0x19, 0x49 ),
|
||||
PLAINTEXT ( 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x20, 0x77, 0x6f, 0x72, 0x6c,
|
||||
0x64, 0x0a ),
|
||||
CIPHERTEXT ( 0x39, 0xff, 0x5c, 0x54, 0x65, 0x3e, 0x6a, 0xab, 0xc0, 0x62,
|
||||
@@ -144,6 +149,11 @@ PUBKEY_TEST ( hw_test_pkcs8, &rsa_algorithm,
|
||||
0x04, 0xf2, 0x82, 0xc4, 0x7b, 0x6a, 0x3e, 0xec, 0x53, 0x7a,
|
||||
0xe3, 0x4e, 0xa8, 0xc9, 0xf9, 0x1f, 0x2a, 0x13, 0x0d, 0x02,
|
||||
0x03, 0x01, 0x00, 0x01 ),
|
||||
RANDOM ( 0x87, 0x90, 0xdf, 0x03, 0x31, 0x20, 0x31, 0x63, 0x86, 0x30,
|
||||
0xb9, 0xb1, 0x99, 0x5e, 0xf8, 0x2b, 0xb7, 0x6b, 0x62, 0x56,
|
||||
0x8c, 0x2b, 0x88, 0xa1, 0x5b, 0x1e, 0x37, 0xaa, 0x12, 0xa6,
|
||||
0xf6, 0xe8, 0x3a, 0x41, 0x91, 0x70, 0x24, 0x3f, 0x89, 0x9b,
|
||||
0x6e, 0x81, 0x63, 0x8c, 0xe1, 0x63, 0x93, 0x19, 0x49 ),
|
||||
PLAINTEXT ( 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x20, 0x77, 0x6f, 0x72, 0x6c,
|
||||
0x64, 0x0a ),
|
||||
CIPHERTEXT ( 0x39, 0xff, 0x5c, 0x54, 0x65, 0x3e, 0x6a, 0xab, 0xc0, 0x62,
|
||||
@@ -198,6 +208,7 @@ PUBKEY_SIGN_TEST ( md5_test, &rsa_algorithm,
|
||||
0xf5, 0xb0, 0x63, 0xa0, 0x84, 0xc0, 0xaf, 0x4e, 0xbe, 0x6a,
|
||||
0xd3, 0x84, 0x3f, 0xec, 0x42, 0x17, 0xe9, 0x25, 0xe1, 0x02,
|
||||
0x03, 0x01, 0x00, 0x01 ),
|
||||
RANDOM(),
|
||||
PLAINTEXT ( 0x9d, 0x5b, 0x46, 0x42, 0x27, 0xc0, 0xf1, 0x4b, 0xe5, 0x9e,
|
||||
0xd3, 0x10, 0xa1, 0xeb, 0x16, 0xc3, 0xc6, 0x8f, 0x1a, 0x18,
|
||||
0x86, 0xc3, 0x92, 0x15, 0x2d, 0x65, 0xa0, 0x40, 0xe1, 0x3e,
|
||||
@@ -271,6 +282,7 @@ PUBKEY_SIGN_TEST ( sha1_test, &rsa_algorithm,
|
||||
0x24, 0x81, 0x4b, 0x4d, 0x48, 0x5a, 0xd2, 0x29, 0x14, 0xeb,
|
||||
0x38, 0xdd, 0x3e, 0xb5, 0x57, 0x45, 0x9b, 0xed, 0x33, 0x02,
|
||||
0x03, 0x01, 0x00, 0x01 ),
|
||||
RANDOM(),
|
||||
PLAINTEXT ( 0xf7, 0x42, 0x01, 0x57, 0x6b, 0x70, 0xcc, 0x4a, 0xdc, 0xed,
|
||||
0x12, 0x83, 0x3f, 0xef, 0x27, 0xc1, 0x3c, 0x85, 0xdd, 0x5e,
|
||||
0x0a, 0x34, 0x98, 0xf9, 0x21, 0xd3, 0x24, 0x2a, 0x5a, 0xb2,
|
||||
@@ -344,6 +356,7 @@ PUBKEY_SIGN_TEST ( sha256_test, &rsa_algorithm,
|
||||
0x35, 0x88, 0x3f, 0xde, 0xa2, 0xce, 0x46, 0x94, 0x30, 0xa9,
|
||||
0x76, 0xee, 0x25, 0xc5, 0x5d, 0xa6, 0xa6, 0x3a, 0xa5, 0x02,
|
||||
0x03, 0x01, 0x00, 0x01 ),
|
||||
RANDOM(),
|
||||
PLAINTEXT ( 0x60, 0xe7, 0xba, 0x9d, 0x5a, 0xe3, 0x2d, 0xfa, 0x5f, 0x47,
|
||||
0xdb, 0x93, 0x24, 0x2c, 0xc4, 0xe2, 0x61, 0xf3, 0x89, 0x4d,
|
||||
0x67, 0xad, 0xc8, 0xae, 0xf8, 0xe2, 0xfb, 0x52, 0x0f, 0x8d,
|
||||
@@ -378,12 +391,21 @@ PUBKEY_SIGN_TEST ( sha256_test, &rsa_algorithm,
|
||||
*
|
||||
*/
|
||||
static void rsa_test_exec ( void ) {
|
||||
int ( * saved_get_random ) ( void *data, size_t len );
|
||||
|
||||
/* Temporarily override rsa_get_random() */
|
||||
saved_get_random = rsa_get_random;
|
||||
rsa_get_random = pubkey_test_get_random;
|
||||
|
||||
/* Run tests */
|
||||
pubkey_ok ( &hw_test );
|
||||
pubkey_ok ( &hw_test_pkcs8 );
|
||||
pubkey_sign_ok ( &md5_test );
|
||||
pubkey_sign_ok ( &sha1_test );
|
||||
pubkey_sign_ok ( &sha256_test );
|
||||
|
||||
/* Restore rsa_get_random() */
|
||||
rsa_get_random = saved_get_random;
|
||||
}
|
||||
|
||||
/** RSA self-test */
|
||||
|
||||
Reference in New Issue
Block a user