[crypto] Add support for RSA-PSS signature scheme

Add support for the RSA-PSS signature scheme as defined in RFC 8017
and required for TLS version 1.3.

Signature verification is deliberately implemented by first deriving
the salt value and then reconstructing the entire expected signature.
This is arguably inefficient since it involves two invocations of the
mask generation function when only one is required.  However, this
implementation approach keeps the code size minimal (since there is no
need to implement separate verification logic), and makes it provably
impossible to accidentally omit a verification step (such as checking
the leading zero bits or the fixed 0x01 or 0xbc bytes).  Since
signature verification is not a fast-path operation, the guaranteed
correctness is more valuable than a marginally faster execution.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
This commit is contained in:
Michael Brown
2026-05-06 22:14:17 +01:00
parent c8743b8c8e
commit 0c617b9132
3 changed files with 472 additions and 5 deletions
+190 -5
View File
@@ -24,10 +24,12 @@
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
FILE_SECBOOT ( PERMITTED );
#include <byteswap.h>
#include <stdint.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <strings.h>
#include <errno.h>
#include <ipxe/asn1.h>
#include <ipxe/crypto.h>
@@ -39,7 +41,7 @@ FILE_SECBOOT ( PERMITTED );
*
* RSA public-key cryptography
*
* RSA is documented in RFC 3447.
* RSA is documented in RFC 3447 and updated in RFC 8017.
*/
/* Disambiguate the various error causes */
@@ -68,6 +70,8 @@ struct rsa_context {
bigint_element_t *output0;
/** Temporary working space for modular exponentiation */
void *tmp;
/** Modulus MSB mask */
uint8_t mask;
};
/**
@@ -76,12 +80,14 @@ struct rsa_context {
* @v context RSA context
* @v digest Digest algorithm
* @v value Digest value
* @v reference Reference encoded digest (or NULL)
* @v encoded Encoded digest
* @ret rc Return status code
*/
typedef int ( rsa_encode_t ) ( struct rsa_context *context,
struct digest_algorithm *digest,
const void *value, void *encoded );
const void *value, const void *reference,
void *encoded );
/** Generate random data */
int ( * rsa_get_random ) ( void *data, size_t len ) = get_random_nz;
@@ -243,6 +249,7 @@ static int rsa_init ( struct rsa_context *context,
const struct asn1_cursor *key ) {
struct asn1_cursor modulus;
struct asn1_cursor exponent;
uint8_t msb;
int rc;
/* Initialise context */
@@ -260,6 +267,15 @@ static int rsa_init ( struct rsa_context *context,
DBGC ( context, "RSA %p exponent:\n", context );
DBGC_HDA ( context, 0, exponent.data, exponent.len );
/* Construct MSB mask */
msb = *( ( const uint8_t * ) modulus.data );
if ( ! msb ) {
DBGC ( context, "RSA %p invalid modulus MSB\n", context );
rc = -EINVAL;
goto err_msb;
}
context->mask = ( ( 1 << ( fls ( msb ) - 1 ) ) - 1 );
/* Allocate dynamic storage */
if ( ( rc = rsa_alloc ( context, modulus.len, exponent.len ) ) != 0 )
goto err_alloc;
@@ -274,6 +290,7 @@ static int rsa_init ( struct rsa_context *context,
rsa_free ( context );
err_alloc:
err_msb:
err_parse:
return rc;
}
@@ -470,12 +487,15 @@ static int rsa_pkcs1_decrypt ( const struct asn1_cursor *key,
* @v context RSA context
* @v digest Digest algorithm
* @v value Digest value
* @v reference Reference encoded digest (or NULL)
* @v encoded Encoded digest
* @ret rc Return status code
*/
static int rsa_pkcs1_encode ( struct rsa_context *context,
struct digest_algorithm *digest,
const void *value, void *encoded ) {
const void *value,
const void *reference __unused,
void *encoded ) {
struct rsa_digestinfo_prefix *prefix;
size_t digest_len = digest->digestsize;
uint8_t *temp = encoded;
@@ -523,6 +543,127 @@ static int rsa_pkcs1_encode ( struct rsa_context *context,
return 0;
}
/**
* Apply RSA PSS mask generation function
*
* @v digest Digest algorithm
* @v ctx Digest context buffer
* @v out Digest output buffer
* @v seed Mask seed
* @v xor XOR buffer
* @v len Length of XOR buffer
*/
static void rsa_xor_mask ( struct digest_algorithm *digest, void *ctx,
void *out, const void *seed, void *xor,
size_t len ) {
size_t digest_len = digest->digestsize;
const uint8_t *out_byte = out;
uint8_t *xor_byte = xor;
uint32_t counter = 0;
unsigned int i;
while ( len ) {
/* Generate output */
digest_init ( digest, ctx );
digest_update ( digest, ctx, seed, digest_len );
digest_update ( digest, ctx, &counter, sizeof ( counter ) );
digest_final ( digest, ctx, out );
/* XOR output into buffer */
for ( i = 0 ; len && ( i < digest_len ) ; i++, len-- )
*(xor_byte++) ^= out_byte[i];
/* Increment counter */
counter = htonl ( ntohl ( counter ) + 1 );
}
}
/**
* Encode digest using RSA PSS
*
* @v context RSA context
* @v digest Digest algorithm
* @v value Digest value
* @v reference Reference encoded digest (or NULL)
* @v encoded Encoded digest
* @ret rc Return status code
*/
static int rsa_pss_encode ( struct rsa_context *context,
struct digest_algorithm *digest,
const void *value, const void *reference,
void *encoded ) {
static uint8_t zero[8];
uint8_t ctx[ digest->ctxsize ];
uint8_t out[ digest->digestsize ];
size_t digest_len = digest->digestsize;
size_t mask_len;
size_t pad_len;
size_t min_len;
void *hash;
void *salt;
uint8_t *msb;
uint8_t *head;
uint8_t *tail;
int rc;
/* Sanity check */
min_len = ( sizeof ( *head ) + digest_len /* salt */ +
digest_len /* hash */ + sizeof ( *tail ) );
if ( context->max_len < min_len ) {
DBGC ( context, "RSA %p %s formatted digest value too long "
"(%zd bytes, max %zd)\n", context, digest->name,
min_len, context->max_len );
return -ERANGE;
}
DBGC ( context, "RSA %p encoding %s digest using PSS:\n",
context, digest->name );
DBGC_HDA ( context, 0, value, digest_len );
/* Split message into component parts */
pad_len = ( context->max_len - min_len );
msb = encoded;
head = ( msb + pad_len );
salt = ( head + sizeof ( *head ) );
hash = ( salt + digest_len );
tail = ( hash + digest_len );
mask_len = ( pad_len + sizeof ( *head ) + digest_len /* salt */ );
assert ( tail == ( encoded + context->max_len - 1 ) );
/* Generate or construct salt as applicable */
if ( reference ) {
memcpy ( encoded, reference, context->max_len );
rsa_xor_mask ( digest, ctx, out, hash, encoded, mask_len );
} else {
if ( ( rc = rsa_get_random ( salt, digest_len ) ) != 0 ) {
DBGC ( context, "RSA %p could not generate random "
"salt: %s\n", context, strerror ( rc ) );
return rc;
}
}
DBGC ( context, "RSA %p salt:\n", context );
DBGC_HDA ( context, 0, salt, digest_len );
/* Construct intermediate digest */
digest_init ( digest, ctx );
digest_update ( digest, ctx, zero, sizeof ( zero ) );
digest_update ( digest, ctx, value, digest_len );
digest_update ( digest, ctx, salt, digest_len );
digest_final ( digest, ctx, hash );
/* Construct message */
memset ( encoded, 0, pad_len );
*head = 0x01;
rsa_xor_mask ( digest, ctx, out, hash, encoded, mask_len );
*msb &= context->mask;
*tail = 0xbc;
DBGC ( context, "RSA %p encoded %s digest using PSS:\n",
context, digest->name );
DBGC_HDA ( context, 0, encoded, context->max_len );
return 0;
}
/**
* Sign digest value using RSA
*
@@ -552,7 +693,8 @@ static int rsa_sign ( const struct asn1_cursor *key,
goto err_grow;
/* Encode digest */
if ( ( rc = encode ( &context, digest, value, signature->data ) ) != 0 )
if ( ( rc = encode ( &context, digest, value, NULL,
signature->data ) ) != 0 )
goto err_encode;
/* Encipher the encoded digest */
@@ -624,7 +766,8 @@ static int rsa_verify ( const struct asn1_cursor *key,
*/
temp = context.output0;
actual = temp;
if ( ( rc = encode ( &context, digest, value, actual ) ) != 0 )
if ( ( rc = encode ( &context, digest, value, expected,
actual ) ) != 0 )
goto err_encode;
/* Verify the signature */
@@ -682,6 +825,38 @@ static int rsa_pkcs1_verify ( const struct asn1_cursor *key,
return rsa_verify ( key, digest, value, signature, rsa_pkcs1_encode );
}
/**
* Sign digest value using RSA PSS
*
* @v key Key
* @v digest Digest algorithm
* @v value Digest value
* @v signature Signature
* @ret rc Return status code
*/
static int rsa_pss_sign ( const struct asn1_cursor *key,
struct digest_algorithm *digest, const void *value,
struct asn1_builder *signature ) {
return rsa_sign ( key, digest, value, signature, rsa_pss_encode );
}
/**
* Verify signed digest value using RSA PSS
*
* @v key Key
* @v digest Digest algorithm
* @v value Digest value
* @v signature Signature
* @ret rc Return status code
*/
static int rsa_pss_verify ( const struct asn1_cursor *key,
struct digest_algorithm *digest, const void *value,
const struct asn1_cursor *signature ) {
return rsa_verify ( key, digest, value, signature, rsa_pss_encode );
}
/**
* Check for matching RSA public/private key pair
*
@@ -722,6 +897,16 @@ struct pubkey_algorithm rsa_algorithm = {
.match = rsa_match,
};
/** RSA-PSS public-key algorithm */
struct pubkey_algorithm rsa_pss_algorithm = {
.name = "rsa_pss",
.encrypt = pubkey_null_encrypt,
.decrypt = pubkey_null_decrypt,
.sign = rsa_pss_sign,
.verify = rsa_pss_verify,
.match = rsa_match,
};
/* Drag in objects via rsa_algorithm */
REQUIRING_SYMBOL ( rsa_algorithm );
+1
View File
@@ -57,6 +57,7 @@ struct rsa_digestinfo_prefix {
#define __rsa_digestinfo_prefix __table_entry ( RSA_DIGESTINFO_PREFIXES, 01 )
extern struct pubkey_algorithm rsa_algorithm;
extern struct pubkey_algorithm rsa_pss_algorithm;
extern int ( * rsa_get_random ) ( void *data, size_t len );
+281
View File
@@ -386,6 +386,284 @@ PUBKEY_SIGN_TEST ( sha256_test, &rsa_algorithm,
0x7d, 0x38, 0x37, 0xc4, 0xea, 0xdd, 0x3a, 0x6f, 0xa8, 0x65,
0x60, 0x73, 0x77, 0x3c ) );
/** Random message MD5 PSS signature test */
PUBKEY_SIGN_TEST ( pss_md5_test, &rsa_pss_algorithm,
PRIVATE ( 0x30, 0x82, 0x01, 0x54, 0x02, 0x01, 0x00, 0x30, 0x0d, 0x06,
0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01,
0x05, 0x00, 0x04, 0x82, 0x01, 0x3e, 0x30, 0x82, 0x01, 0x3a,
0x02, 0x01, 0x00, 0x02, 0x41, 0x00, 0xbb, 0x97, 0xe0, 0x15,
0x30, 0x45, 0x10, 0x75, 0x51, 0x91, 0x1b, 0x94, 0xd1, 0x4c,
0xb9, 0xa6, 0x73, 0x66, 0x26, 0x44, 0x12, 0x31, 0x1a, 0x86,
0xd6, 0x52, 0x6e, 0x27, 0x85, 0x9e, 0x6f, 0xef, 0x7b, 0x5b,
0x84, 0xeb, 0x88, 0x25, 0xcd, 0x4d, 0x6c, 0x83, 0x8e, 0x87,
0xac, 0x80, 0x9f, 0xc3, 0xda, 0xc7, 0x42, 0x1d, 0x46, 0xe6,
0xf4, 0xc8, 0x1f, 0x92, 0x6c, 0x0f, 0x62, 0x5a, 0x0a, 0x17,
0x02, 0x03, 0x01, 0x00, 0x01, 0x02, 0x40, 0x5a, 0xb0, 0x82,
0xa9, 0x5b, 0xab, 0x97, 0xd8, 0x4f, 0xb5, 0x8a, 0x12, 0xf8,
0xd8, 0x51, 0xcc, 0x11, 0x6f, 0xe9, 0xc1, 0xf0, 0xd5, 0x82,
0x50, 0x7b, 0x5e, 0x60, 0x58, 0x84, 0xf5, 0x62, 0x81, 0x1d,
0x1e, 0x3c, 0x49, 0xd4, 0xf6, 0x16, 0x8a, 0xf1, 0x01, 0xae,
0xa5, 0xcf, 0x8e, 0xfa, 0xba, 0x1b, 0xbe, 0xb9, 0x94, 0x3c,
0x90, 0x76, 0xe1, 0x69, 0x4a, 0x19, 0x34, 0xcf, 0xd7, 0x6e,
0xe1, 0x02, 0x21, 0x00, 0xe4, 0x4c, 0x57, 0xf2, 0xd9, 0x7f,
0x6b, 0xd5, 0x26, 0x03, 0xc9, 0x2e, 0xff, 0x85, 0x73, 0xd0,
0x13, 0xc6, 0x2c, 0x4f, 0x08, 0x23, 0xf7, 0x2b, 0x24, 0xba,
0xeb, 0xfc, 0xce, 0x66, 0x1a, 0x87, 0x02, 0x21, 0x00, 0xd2,
0x5b, 0x1b, 0xcf, 0x11, 0x67, 0xa4, 0xa9, 0xc9, 0x13, 0x5d,
0x1e, 0x30, 0xd1, 0x1a, 0xcc, 0x30, 0x7d, 0x94, 0x71, 0xc8,
0xb9, 0x06, 0x3e, 0x62, 0xaa, 0x8e, 0x19, 0xa9, 0xeb, 0xa7,
0xf1, 0x02, 0x20, 0x44, 0x07, 0x7f, 0xd9, 0xac, 0xf8, 0x2c,
0x60, 0xda, 0xb0, 0x1c, 0x1e, 0x36, 0x24, 0x45, 0x4b, 0x86,
0xe8, 0xf1, 0xc1, 0x27, 0x32, 0xd8, 0x6f, 0x71, 0xc5, 0x85,
0x96, 0xd2, 0xc6, 0x58, 0x37, 0x02, 0x20, 0x4f, 0x6f, 0x30,
0x35, 0x25, 0x71, 0x69, 0xf0, 0xe3, 0x89, 0x78, 0x64, 0x6a,
0x32, 0xcc, 0x57, 0xc7, 0x07, 0xe5, 0x02, 0x82, 0xb5, 0xbb,
0xf1, 0xda, 0xf8, 0x64, 0xe8, 0xb4, 0x0d, 0xd5, 0x41, 0x02,
0x21, 0x00, 0xb5, 0x90, 0xa2, 0x41, 0x82, 0x1e, 0x9f, 0x8e,
0x5d, 0x40, 0x1a, 0x37, 0x1f, 0x51, 0x92, 0x81, 0x24, 0x52,
0x7a, 0x56, 0xb5, 0xda, 0x28, 0x41, 0xf9, 0x18, 0x2b, 0xf2,
0x14, 0x88, 0xfd, 0x4e ),
PUBLIC ( 0x30, 0x5c, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x4b, 0x00,
0x30, 0x48, 0x02, 0x41, 0x00, 0xbb, 0x97, 0xe0, 0x15, 0x30,
0x45, 0x10, 0x75, 0x51, 0x91, 0x1b, 0x94, 0xd1, 0x4c, 0xb9,
0xa6, 0x73, 0x66, 0x26, 0x44, 0x12, 0x31, 0x1a, 0x86, 0xd6,
0x52, 0x6e, 0x27, 0x85, 0x9e, 0x6f, 0xef, 0x7b, 0x5b, 0x84,
0xeb, 0x88, 0x25, 0xcd, 0x4d, 0x6c, 0x83, 0x8e, 0x87, 0xac,
0x80, 0x9f, 0xc3, 0xda, 0xc7, 0x42, 0x1d, 0x46, 0xe6, 0xf4,
0xc8, 0x1f, 0x92, 0x6c, 0x0f, 0x62, 0x5a, 0x0a, 0x17, 0x02,
0x03, 0x01, 0x00, 0x01 ),
RANDOM ( 0x29, 0x0b, 0xe6, 0xb2, 0x60, 0xaa, 0xe2, 0x29, 0x4f, 0x0d,
0x93, 0xed, 0xfc, 0xe3, 0x45, 0x3e ),
PLAINTEXT ( 0x1f, 0x59, 0xbd, 0x02, 0x0c, 0xa3, 0x34, 0x98, 0xa9, 0x91,
0x24, 0xb1, 0x94, 0xe6, 0x8d, 0xda, 0x95, 0x3d, 0x6e, 0x52,
0x60, 0x66, 0x3d, 0xc4, 0x98, 0x53, 0x4a, 0x52, 0xf1, 0xd5,
0x69, 0x8b, 0xc9, 0x2c, 0x56, 0x2c, 0x81, 0xe6, 0x19, 0x0d,
0x08, 0xfe, 0xec, 0xa9, 0x2c, 0x7d, 0x08, 0xab, 0x37, 0x03,
0xe8, 0x5c, 0xd6, 0x95, 0xfb, 0xe1, 0xf9, 0xe7, 0xfb, 0x28,
0x88, 0x5c, 0x99, 0x48, 0x45, 0x90, 0xaa, 0xd3, 0x79, 0x5d,
0x20, 0xd3, 0x33, 0x99, 0xde, 0xe1, 0x0f, 0x60, 0xdd, 0x48,
0x6a, 0x68, 0x96, 0x6a, 0x09, 0x92, 0x8c, 0x3e, 0x52, 0xef,
0xfe, 0x15, 0x7b, 0x74, 0x7f, 0xbe, 0x02, 0xaa, 0x3e, 0x22,
0x1c, 0xfb, 0x4b, 0x05, 0x95, 0x12, 0x2c, 0x38, 0xdf, 0x92,
0x2a, 0xb0, 0x88, 0xf9, 0x64, 0xdc, 0xba, 0xa7, 0x89, 0x23,
0xed, 0xe7, 0xcb, 0x45, 0xc7, 0x7d, 0x28, 0xc1, 0xca, 0x0a,
0xea, 0x14, 0xac, 0x6f, 0x4e, 0xaf, 0x37, 0xb8, 0x0d, 0x91,
0xf9, 0xec, 0x2b, 0xdf, 0x55, 0xeb, 0x57, 0xe0, 0x1c, 0x2d,
0x7c, 0xdc, 0x00, 0xb8, 0x5e, 0x5b, 0xb1, 0xfe, 0x9c, 0xc1,
0x84, 0xc6, 0xbb, 0x68, 0x05, 0x57, 0xd3, 0xe7, 0x95, 0x78,
0x4e, 0x99, 0xd1, 0x34, 0xbc, 0x1d, 0x08, 0xc9, 0x09, 0xeb,
0x00, 0x62, 0x77, 0x3d, 0x7f, 0x16, 0x3b, 0x32, 0x72, 0x87,
0x2b, 0x4a, 0x61, 0x8b, 0x98, 0xa6, 0x7e, 0xa6, 0xea ),
&md5_algorithm,
SIGNATURE ( 0xb7, 0x30, 0xaf, 0xe9, 0xd0, 0x03, 0xf5, 0xfe, 0x20, 0x6b,
0x86, 0x24, 0x2b, 0xce, 0x6b, 0x17, 0x88, 0x39, 0xff, 0x8a,
0x38, 0xae, 0x9a, 0x94, 0x66, 0xe5, 0xeb, 0x31, 0x5e, 0xc4,
0xfd, 0xe7, 0x74, 0x94, 0x1e, 0xe2, 0x1d, 0x9b, 0x0d, 0x45,
0x6a, 0x45, 0x1c, 0x7d, 0x27, 0x64, 0xc1, 0x7e, 0x6f, 0x4f,
0x0e, 0x8e, 0x9b, 0x32, 0xbd, 0x49, 0x7c, 0x66, 0x01, 0xc8,
0xd4, 0x76, 0x24, 0xde ) );
/** Random message SHA-1 PSS signature test */
PUBKEY_SIGN_TEST ( pss_sha1_test, &rsa_pss_algorithm,
PRIVATE ( 0x30, 0x82, 0x01, 0x53, 0x02, 0x01, 0x00, 0x30, 0x0d, 0x06,
0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01,
0x05, 0x00, 0x04, 0x82, 0x01, 0x3d, 0x30, 0x82, 0x01, 0x39,
0x02, 0x01, 0x00, 0x02, 0x41, 0x00, 0xbb, 0x9c, 0xd1, 0x2f,
0x90, 0xcd, 0xa6, 0xb9, 0x18, 0x46, 0xa3, 0xe1, 0x8d, 0xa8,
0x69, 0x74, 0xb4, 0x27, 0xfe, 0x53, 0x07, 0xab, 0x2b, 0xc9,
0xe5, 0x79, 0x0b, 0xc3, 0xb1, 0x10, 0xb8, 0x8e, 0x5f, 0x77,
0x32, 0xec, 0xcb, 0xc8, 0x3b, 0xa4, 0x78, 0x88, 0x0c, 0x0b,
0x00, 0xd5, 0x20, 0x81, 0xa4, 0x32, 0xb3, 0xa7, 0x99, 0x7f,
0x5d, 0xb7, 0x6f, 0x0e, 0xde, 0xc9, 0xbf, 0xa2, 0xfc, 0xf7,
0x02, 0x03, 0x01, 0x00, 0x01, 0x02, 0x40, 0x27, 0xf5, 0xdb,
0xdc, 0x7c, 0xc4, 0x40, 0xd9, 0xb5, 0xe0, 0xfd, 0xf1, 0x01,
0xe2, 0x38, 0x2c, 0x02, 0x5f, 0x6e, 0x5d, 0x33, 0x09, 0xf3,
0x76, 0xba, 0x68, 0xd0, 0xe7, 0xaa, 0xa4, 0x3c, 0x1a, 0xc1,
0xbd, 0x58, 0xe1, 0x17, 0x64, 0x53, 0x99, 0x19, 0x9d, 0xff,
0x1d, 0x84, 0xf5, 0x54, 0xab, 0x91, 0xcd, 0x43, 0x0e, 0xdb,
0xdc, 0x6e, 0xf3, 0xcf, 0xcd, 0x1c, 0x1b, 0x8f, 0x52, 0x8b,
0x61, 0x02, 0x21, 0x00, 0xde, 0xf3, 0xc3, 0xf6, 0xc8, 0x94,
0x29, 0x48, 0xcf, 0xc2, 0xc8, 0x5c, 0x57, 0xbe, 0x33, 0x94,
0xf5, 0x69, 0x08, 0x39, 0xda, 0x88, 0x6a, 0x60, 0x5e, 0x3b,
0x2c, 0x0d, 0xdf, 0xac, 0x2b, 0xf1, 0x02, 0x21, 0x00, 0xd7,
0x6c, 0x0a, 0x11, 0x5a, 0x03, 0xba, 0xab, 0x60, 0x74, 0xd9,
0xd6, 0x03, 0xfb, 0x83, 0xce, 0x07, 0x68, 0x2e, 0x0a, 0x33,
0x78, 0x3a, 0x82, 0xca, 0x9b, 0x53, 0x10, 0x2c, 0x5d, 0x3f,
0x67, 0x02, 0x20, 0x56, 0x9d, 0xd3, 0x93, 0x2b, 0xc7, 0xcb,
0xe6, 0x3a, 0xb9, 0x0c, 0xc8, 0x3b, 0x5a, 0x6c, 0x85, 0xc1,
0x76, 0x05, 0xb9, 0x1c, 0x3a, 0x85, 0x41, 0x5d, 0x3a, 0x95,
0xd9, 0xe9, 0xfc, 0xe4, 0xb1, 0x02, 0x20, 0x40, 0xe0, 0x47,
0xb3, 0xec, 0x10, 0xfd, 0x71, 0xc9, 0x4d, 0xc7, 0xa0, 0xdd,
0x78, 0x2c, 0xbc, 0xaa, 0x9c, 0x64, 0x69, 0x2c, 0x11, 0x04,
0x46, 0x09, 0x70, 0x77, 0xb6, 0x82, 0x35, 0xde, 0xf7, 0x02,
0x20, 0x49, 0x78, 0xf9, 0xe8, 0x8b, 0xad, 0x62, 0x30, 0x3b,
0x81, 0xfa, 0x42, 0x37, 0xac, 0x01, 0x99, 0x12, 0x79, 0x18,
0x33, 0x45, 0xb3, 0x0c, 0x13, 0x8e, 0x03, 0xcf, 0xc2, 0x76,
0x55, 0x0b, 0x64 ),
PUBLIC ( 0x30, 0x5c, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x4b, 0x00,
0x30, 0x48, 0x02, 0x41, 0x00, 0xbb, 0x9c, 0xd1, 0x2f, 0x90,
0xcd, 0xa6, 0xb9, 0x18, 0x46, 0xa3, 0xe1, 0x8d, 0xa8, 0x69,
0x74, 0xb4, 0x27, 0xfe, 0x53, 0x07, 0xab, 0x2b, 0xc9, 0xe5,
0x79, 0x0b, 0xc3, 0xb1, 0x10, 0xb8, 0x8e, 0x5f, 0x77, 0x32,
0xec, 0xcb, 0xc8, 0x3b, 0xa4, 0x78, 0x88, 0x0c, 0x0b, 0x00,
0xd5, 0x20, 0x81, 0xa4, 0x32, 0xb3, 0xa7, 0x99, 0x7f, 0x5d,
0xb7, 0x6f, 0x0e, 0xde, 0xc9, 0xbf, 0xa2, 0xfc, 0xf7, 0x02,
0x03, 0x01, 0x00, 0x01 ),
RANDOM ( 0xa6, 0x3b, 0xfd, 0x57, 0x97, 0x56, 0xdc, 0x95, 0x2e, 0x0c,
0x90, 0x88, 0xc6, 0x6e, 0x6f, 0x1a, 0x5d, 0xf3, 0x0a, 0xb9 ),
PLAINTEXT ( 0x7a, 0x9f, 0xc2, 0x07, 0xf2, 0x20, 0x4f, 0x57, 0xd1, 0x58,
0x4b, 0xd4, 0x04, 0x85, 0x54, 0xeb, 0x56, 0x5b, 0xcd, 0x98,
0x0c, 0x6f, 0xd7, 0x42, 0x57, 0xea, 0x88, 0x23, 0x20, 0xb0,
0xc9, 0x49, 0xe1, 0x54, 0xbc, 0xee, 0xfc, 0x07, 0x44, 0x89,
0xd4, 0x2c, 0x04, 0xf8, 0x8d, 0xff, 0x65, 0x0f, 0xab, 0x10,
0x2a, 0xd1, 0xf1, 0xbf, 0x7a, 0xab, 0xc2, 0xda, 0xd4, 0x62,
0x54, 0xcb, 0x79, 0x74, 0x63, 0xa6, 0x44, 0xae, 0x8a, 0x2c,
0x94, 0x98, 0xc0, 0x60, 0x6d, 0xc6, 0xe7, 0xbc, 0x99, 0x76,
0xb6, 0x7c, 0x8c, 0xb7, 0x38, 0x46, 0x39, 0x9e, 0x75, 0x63,
0xf7, 0xba, 0x37, 0xbc, 0x60, 0x63, 0x39, 0x32, 0x28, 0x0e,
0xd0, 0x74, 0x39, 0xe0, 0x8e, 0x1e, 0x6c, 0xfa, 0x5d, 0xd1,
0x29, 0x5d, 0xd2, 0xbd, 0x43, 0x07, 0x64, 0x94, 0xf6, 0xf5,
0x09, 0x82, 0x7b, 0xcb, 0x9c, 0xfa, 0x07, 0x3f, 0xe8, 0xd6,
0x33, 0x1e, 0xae, 0xe4, 0x06, 0x3c, 0xfc, 0x99, 0xdf, 0xc5,
0x59, 0x0a, 0x22, 0xdf, 0x37, 0xf1, 0xd5, 0x4e, 0xa3, 0x03,
0x25, 0x84, 0xfc, 0x83, 0x37, 0x0f, 0x2b, 0xef, 0xfe, 0xbd,
0x0b, 0xd1, 0x5d, 0x8a, 0x88, 0x1b, 0x84, 0xc3, 0x2b, 0x16,
0x41, 0x08, 0x84, 0x33, 0x18, 0x50, 0xed, 0x0b, 0x3f, 0x9d,
0x4a, 0xe9, 0xc5, 0x71, 0x5a, 0x95, 0x9d, 0x08, 0x09, 0xa0,
0x82, 0x40, 0x42, 0x55, 0xf8, 0xbd, 0x47, 0x24, 0x72 ),
&sha1_algorithm,
SIGNATURE ( 0x6f, 0xa3, 0x23, 0x6e, 0xe2, 0x1f, 0x2c, 0x53, 0x74, 0xe7,
0x8d, 0xad, 0x55, 0xe2, 0xc6, 0xeb, 0x36, 0xea, 0xe9, 0x91,
0x01, 0x93, 0x7f, 0x43, 0xd9, 0x97, 0x51, 0x92, 0x84, 0x6e,
0x7e, 0xc9, 0xae, 0x2a, 0x98, 0x04, 0x52, 0x81, 0x73, 0x97,
0x02, 0x09, 0x7e, 0xf7, 0x16, 0xb1, 0x46, 0x8b, 0xbb, 0x86,
0xf1, 0x0f, 0x0e, 0x09, 0xf6, 0xd9, 0x0c, 0xb8, 0x8d, 0x92,
0xdf, 0x73, 0x27, 0x10 ) );
/** Random message SHA-256 PSS signature test */
PUBKEY_SIGN_TEST ( pss_sha256_test, &rsa_pss_algorithm,
PRIVATE ( 0x30, 0x82, 0x02, 0x77, 0x02, 0x01, 0x00, 0x30, 0x0d, 0x06,
0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01,
0x05, 0x00, 0x04, 0x82, 0x02, 0x61, 0x30, 0x82, 0x02, 0x5d,
0x02, 0x01, 0x00, 0x02, 0x81, 0x81, 0x00, 0xee, 0x09, 0x25,
0x9d, 0xcd, 0x13, 0xca, 0x86, 0xb0, 0xa3, 0x43, 0x8b, 0xdd,
0xc5, 0xa5, 0xf0, 0x08, 0x33, 0xc8, 0x94, 0x6c, 0x59, 0xb7,
0xe3, 0x74, 0x98, 0x62, 0x37, 0x3a, 0xf5, 0x2a, 0xda, 0xc6,
0x24, 0x8a, 0xeb, 0xb8, 0xdf, 0xf2, 0xac, 0x6c, 0xaf, 0xee,
0x87, 0x00, 0x40, 0x24, 0x7f, 0xaf, 0x7d, 0x54, 0x7a, 0x62,
0xee, 0x94, 0xb3, 0xf6, 0x9f, 0x57, 0x28, 0x30, 0x8d, 0x09,
0x15, 0xf5, 0x3b, 0x83, 0xde, 0x8f, 0x9e, 0x58, 0xaf, 0x8d,
0xdc, 0xa5, 0x49, 0x04, 0x7e, 0x5e, 0x60, 0x80, 0xd1, 0x06,
0x94, 0xb4, 0xe4, 0x91, 0xd1, 0x9a, 0x3e, 0x8d, 0xe5, 0xae,
0x5c, 0xfc, 0x16, 0x62, 0x1b, 0x7f, 0x64, 0x24, 0x71, 0x0f,
0x5e, 0x82, 0x35, 0x13, 0xbb, 0xbf, 0xb8, 0xb8, 0x80, 0xde,
0x1c, 0x8d, 0x1e, 0x1d, 0x5e, 0xcf, 0xd6, 0x37, 0xb9, 0xfd,
0x72, 0x86, 0x56, 0x4f, 0x7d, 0x02, 0x03, 0x01, 0x00, 0x01,
0x02, 0x81, 0x80, 0x56, 0x7c, 0xb4, 0x52, 0x35, 0xa5, 0x2f,
0x3c, 0xe9, 0x09, 0x29, 0x0d, 0xb4, 0xb2, 0x8f, 0xac, 0x3b,
0x0e, 0xb5, 0x9e, 0x58, 0x0f, 0xf1, 0x24, 0x8f, 0xc4, 0x9e,
0x4a, 0xfa, 0xfd, 0x01, 0x69, 0x23, 0xfd, 0x3b, 0x0c, 0x92,
0xcb, 0xab, 0xdc, 0xc2, 0x50, 0xda, 0x15, 0xeb, 0x1d, 0x63,
0x25, 0x91, 0x99, 0xb4, 0x0c, 0x13, 0xce, 0x23, 0xf1, 0x8f,
0x76, 0x2d, 0xb0, 0xc8, 0x93, 0x35, 0xed, 0x35, 0x08, 0xb0,
0x05, 0xf1, 0xa2, 0x40, 0x56, 0xa5, 0x0f, 0x9c, 0x3a, 0xaa,
0xaf, 0xd3, 0x68, 0x73, 0x39, 0x3f, 0x41, 0xc5, 0xca, 0x3b,
0x3f, 0x9e, 0x0a, 0xb7, 0x4c, 0x35, 0x54, 0x64, 0x36, 0x2f,
0xba, 0x72, 0x76, 0x58, 0x14, 0x70, 0x9a, 0x6f, 0xb2, 0x03,
0x05, 0x26, 0x4d, 0xd3, 0x38, 0xca, 0xec, 0xf6, 0x8c, 0x38,
0x8b, 0xf3, 0x72, 0x2a, 0xbd, 0x40, 0x48, 0xff, 0x87, 0x45,
0x01, 0x02, 0x41, 0x00, 0xfe, 0x99, 0x09, 0x6c, 0xc0, 0x0b,
0x53, 0xd5, 0x02, 0xf6, 0x43, 0x6b, 0xc8, 0xc5, 0xa7, 0xbb,
0x4d, 0xe0, 0x1d, 0xe2, 0xb8, 0xd8, 0x2f, 0x01, 0x9b, 0x2d,
0x5d, 0x32, 0x6e, 0xf6, 0xb7, 0xe2, 0x2d, 0xb3, 0xc3, 0xbd,
0x88, 0x1b, 0xc6, 0xbe, 0x2b, 0x9e, 0xd6, 0x44, 0x28, 0x4f,
0x3b, 0xc8, 0xf2, 0x0a, 0xc6, 0x05, 0x65, 0x7b, 0x02, 0xab,
0x60, 0x9e, 0xc2, 0x92, 0x3d, 0x87, 0x72, 0x71, 0x02, 0x41,
0x00, 0xef, 0x58, 0xc2, 0x46, 0x72, 0x0a, 0x1e, 0x16, 0x4d,
0x6c, 0x74, 0x12, 0xbd, 0xc7, 0xc9, 0x01, 0x3d, 0xc2, 0x7b,
0x43, 0x06, 0x32, 0x79, 0xd7, 0xae, 0x1c, 0x03, 0x41, 0xcc,
0x2f, 0xc3, 0xae, 0x81, 0xe4, 0x08, 0x5c, 0x50, 0xf6, 0x06,
0x06, 0xa3, 0xf2, 0x06, 0x00, 0x6a, 0x18, 0xec, 0xd7, 0xef,
0xca, 0xb8, 0x55, 0x67, 0xf1, 0xc7, 0x14, 0xc1, 0x86, 0x5c,
0xbd, 0x1c, 0x09, 0xdb, 0xcd, 0x02, 0x40, 0x02, 0xda, 0xf6,
0x87, 0x18, 0xb4, 0x47, 0xd1, 0x68, 0xc2, 0x18, 0x49, 0x7a,
0x2b, 0xf5, 0x50, 0x9d, 0x73, 0xf9, 0x01, 0xd4, 0xee, 0xdf,
0xc0, 0x15, 0xdc, 0x71, 0x62, 0x22, 0x6a, 0x73, 0xef, 0x7e,
0x71, 0xb8, 0xad, 0x44, 0x7c, 0x83, 0x43, 0x18, 0xbc, 0x24,
0x4d, 0x09, 0x62, 0xb2, 0x19, 0xf3, 0xd4, 0xf9, 0x19, 0x90,
0x64, 0xcb, 0xc7, 0xde, 0x42, 0x89, 0x8e, 0x18, 0x50, 0x8f,
0x91, 0x02, 0x41, 0x00, 0xd0, 0x9e, 0x39, 0xbf, 0xb3, 0x38,
0xb4, 0x5e, 0xd6, 0x1f, 0x38, 0xd0, 0xf9, 0x10, 0x01, 0x58,
0x8e, 0x9f, 0x4c, 0x56, 0xf0, 0x38, 0xe0, 0xd0, 0xa8, 0x56,
0x8c, 0x54, 0x36, 0x88, 0x4f, 0x74, 0x74, 0x8c, 0xf0, 0xe8,
0x9e, 0x3c, 0xc2, 0xa5, 0xd9, 0x12, 0x64, 0x3e, 0xca, 0x3b,
0x6d, 0x7d, 0x0d, 0xea, 0x51, 0x5f, 0x47, 0xd9, 0x8a, 0x9f,
0xc1, 0xca, 0xbe, 0x5c, 0xaa, 0xea, 0xc0, 0xe5, 0x02, 0x41,
0x00, 0xd4, 0xe6, 0x22, 0x12, 0x21, 0xa8, 0x37, 0x5e, 0xed,
0xcf, 0x4e, 0x68, 0xc3, 0x5b, 0x96, 0x2a, 0xae, 0xd2, 0x90,
0xf3, 0xf2, 0x2b, 0xd8, 0x12, 0x7f, 0x12, 0x19, 0xfe, 0x85,
0xf0, 0x50, 0x47, 0x69, 0x4d, 0xdd, 0x49, 0xa0, 0x94, 0xc2,
0xbb, 0x7b, 0xbc, 0x78, 0xf2, 0x66, 0xe4, 0xa2, 0x64, 0xfe,
0x21, 0x6e, 0xeb, 0x4d, 0x1f, 0x7f, 0xf6, 0xe2, 0x14, 0xda,
0xfa, 0x8d, 0xd6, 0x15, 0x49 ),
PUBLIC ( 0x30, 0x81, 0x9f, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48,
0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x81,
0x8d, 0x00, 0x30, 0x81, 0x89, 0x02, 0x81, 0x81, 0x00, 0xee,
0x09, 0x25, 0x9d, 0xcd, 0x13, 0xca, 0x86, 0xb0, 0xa3, 0x43,
0x8b, 0xdd, 0xc5, 0xa5, 0xf0, 0x08, 0x33, 0xc8, 0x94, 0x6c,
0x59, 0xb7, 0xe3, 0x74, 0x98, 0x62, 0x37, 0x3a, 0xf5, 0x2a,
0xda, 0xc6, 0x24, 0x8a, 0xeb, 0xb8, 0xdf, 0xf2, 0xac, 0x6c,
0xaf, 0xee, 0x87, 0x00, 0x40, 0x24, 0x7f, 0xaf, 0x7d, 0x54,
0x7a, 0x62, 0xee, 0x94, 0xb3, 0xf6, 0x9f, 0x57, 0x28, 0x30,
0x8d, 0x09, 0x15, 0xf5, 0x3b, 0x83, 0xde, 0x8f, 0x9e, 0x58,
0xaf, 0x8d, 0xdc, 0xa5, 0x49, 0x04, 0x7e, 0x5e, 0x60, 0x80,
0xd1, 0x06, 0x94, 0xb4, 0xe4, 0x91, 0xd1, 0x9a, 0x3e, 0x8d,
0xe5, 0xae, 0x5c, 0xfc, 0x16, 0x62, 0x1b, 0x7f, 0x64, 0x24,
0x71, 0x0f, 0x5e, 0x82, 0x35, 0x13, 0xbb, 0xbf, 0xb8, 0xb8,
0x80, 0xde, 0x1c, 0x8d, 0x1e, 0x1d, 0x5e, 0xcf, 0xd6, 0x37,
0xb9, 0xfd, 0x72, 0x86, 0x56, 0x4f, 0x7d, 0x02, 0x03, 0x01,
0x00, 0x01 ),
RANDOM ( 0x15, 0x53, 0xd2, 0x4c, 0xec, 0xd0, 0xdb, 0x7f, 0xe3, 0x84,
0xec, 0x50, 0xa0, 0x7a, 0xa6, 0xe1, 0x4e, 0xfb, 0x0d, 0xb1,
0xe5, 0xe2, 0x67, 0xc9, 0x36, 0xbf, 0x4e, 0x66, 0xe6, 0x62,
0x82, 0x0e ),
PLAINTEXT ( 0xa3, 0x76, 0xaa, 0x78, 0xa5, 0x7a, 0x0c, 0x1b, 0x32, 0x95,
0x21, 0x9c, 0x10, 0xdf, 0xfa, 0xe6, 0x74, 0xd4, 0x37, 0x8c,
0x60, 0x31, 0xbe, 0x89, 0x62, 0x62, 0x99, 0x05, 0xb7, 0x68,
0xc5, 0xab, 0x83, 0x4b, 0x53, 0x30, 0xd2, 0x42, 0x93, 0x3e,
0x43, 0xa9, 0x3d, 0xcf, 0x75, 0x88, 0x5b, 0x70, 0xa3, 0x5e,
0x62, 0x48, 0x2c, 0x8a, 0xf0, 0xb8, 0x7f, 0x71, 0x87, 0xab,
0x20, 0x89, 0xe7, 0x2e, 0x03, 0x7e, 0x1f, 0x24, 0xde, 0x42,
0xca, 0xbd, 0x3f, 0x81, 0x47, 0x0e, 0x63, 0x30, 0x54, 0xbe,
0xa5, 0x3d, 0xdd, 0xd5, 0x25, 0x04, 0x0c, 0xc6, 0x43, 0xeb,
0x13, 0x46, 0x82, 0x38, 0x58, 0x63, 0x37, 0x9b, 0xcd, 0x24,
0xe6, 0xa0, 0x53, 0x94, 0x80, 0xbd, 0xd8, 0x7b, 0x60, 0xa4,
0x81, 0x2f, 0x8e, 0xc8, 0xd6, 0xff, 0x60, 0xe2, 0x27, 0x83,
0x8a, 0x06, 0x69, 0x0e, 0x53, 0x13, 0x33, 0xb6, 0x08, 0x2d,
0xb1, 0xa0, 0x47, 0xa1, 0x51, 0xec, 0xdf, 0xba, 0x32, 0x69,
0x8a, 0x73, 0x0a, 0x31, 0xbe, 0xbf, 0x94, 0x2c, 0xd5, 0x9e,
0xcc, 0x26, 0xfe, 0x82, 0x0e, 0x21, 0x2c, 0x77, 0xd4, 0xac,
0x1e, 0xff, 0x40, 0x29, 0x94, 0x45, 0x1c, 0x2e, 0x5c, 0x38,
0x58, 0x3c, 0xc7, 0x58, 0x2a, 0x95, 0xc7, 0x40, 0xac, 0xa4,
0xf1, 0xf8, 0xaa, 0x3e, 0xec, 0xd6, 0xc4, 0x63, 0xae, 0xf1,
0x5c, 0xcc, 0x85, 0x28, 0x70, 0xb5, 0x95, 0x28, 0xd4 ),
&sha256_algorithm,
SIGNATURE ( 0x8c, 0x5e, 0x63, 0xf3, 0x6b, 0x28, 0x44, 0xd9, 0x44, 0x89,
0xfa, 0x4b, 0x89, 0x96, 0xb0, 0x1b, 0xa5, 0xf1, 0x74, 0x53,
0xe1, 0xb4, 0x31, 0xb1, 0xfb, 0x67, 0xd6, 0xdb, 0x2f, 0xd7,
0xdc, 0x23, 0xd9, 0x51, 0x04, 0x26, 0xbc, 0xef, 0xf8, 0x2a,
0x4c, 0xef, 0x03, 0x06, 0x7b, 0x21, 0xbc, 0xdf, 0xac, 0xcf,
0x39, 0xe3, 0x87, 0x9c, 0x59, 0x2a, 0x3f, 0x9c, 0x9b, 0x7e,
0x3a, 0xb3, 0x75, 0x82, 0xd6, 0x8d, 0x0f, 0xd6, 0x6b, 0xe3,
0xfe, 0x11, 0x3b, 0xba, 0xa5, 0x06, 0xf7, 0x55, 0xef, 0xd3,
0x0b, 0xc6, 0x3f, 0x90, 0xa0, 0x64, 0x38, 0x9a, 0x09, 0xae,
0xaf, 0x19, 0x6b, 0xcc, 0xf0, 0xd6, 0xb9, 0xfa, 0xe4, 0x7c,
0xd6, 0x58, 0x27, 0x2f, 0x73, 0x92, 0x62, 0x26, 0xec, 0xbd,
0xab, 0x81, 0xb2, 0x93, 0x26, 0xfe, 0x44, 0xb4, 0xc5, 0x07,
0x83, 0x02, 0x6e, 0x56, 0x60, 0x47, 0x1d, 0xbc ) );
/**
* Perform RSA self-tests
*
@@ -403,6 +681,9 @@ static void rsa_test_exec ( void ) {
pubkey_sign_ok ( &md5_test );
pubkey_sign_ok ( &sha1_test );
pubkey_sign_ok ( &sha256_test );
pubkey_sign_ok ( &pss_md5_test );
pubkey_sign_ok ( &pss_sha1_test );
pubkey_sign_ok ( &pss_sha256_test );
/* Restore rsa_get_random() */
rsa_get_random = saved_get_random;