]> git.ipfire.org Git - thirdparty/ipxe.git/commitdiff
[crypto] Add support for RSA-PSS signature scheme 1705/head
authorMichael Brown <mcb30@ipxe.org>
Wed, 6 May 2026 21:14:17 +0000 (22:14 +0100)
committerMichael Brown <mcb30@ipxe.org>
Wed, 6 May 2026 21:14:41 +0000 (22:14 +0100)
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>
src/crypto/rsa.c
src/include/ipxe/rsa.h
src/tests/rsa_test.c

index 8bd72a61ce7c2684003c5ff3c17e927668040444..e62eb02a4c50330e44c3eab25f0778fa3b03a6e6 100644 (file)
 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 );
 
index 289743c40d1ab5b4a9cfef5fcce5fde7fa3812e0..b61ac20744e5ff5be25daa6b9cabe02d48b3043b 100644 (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 );
 
index 871c8461f85bb99cdf41e540f831e93ffa732109..9f35e05315d8d9396982eca91a302d7ddb44a023 100644 (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;