void *tmp;
};
+/** Generate random data */
+int ( * rsa_get_random ) ( void *data, size_t len ) = get_random_nz;
+
/**
* Identify RSA prefix
*
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;
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 )
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 );
extern struct pubkey_algorithm rsa_algorithm;
+extern int ( * rsa_get_random ) ( void *data, size_t len );
+
#endif /* _IPXE_RSA_H */
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,
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,
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,
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,
#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
*
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;
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 );
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 );
&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 );
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;
};
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 */
/** 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__ }
* @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 = { \
.data = name ## _public, \
.len = sizeof ( name ## _public ), \
}, \
+ .random = name ## _random, \
+ .random_len = sizeof ( name ## _random ), \
.plaintext = { \
.data = name ## _plaintext, \
.len = sizeof ( name ## _plaintext ), \
* @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 = { \
.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, \
}, \
}
+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,
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,
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,
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,
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,
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,
*
*/
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 */