Prechádzať zdrojové kódy

Merge pull request #612 from libtom/rsaaes_oaep_hashes

add possibility to use different hash algorithms in RSAES-OAEP
Steffen Jaeckel 2 rokov pred
rodič
commit
7e863d2142

+ 13 - 7
doc/crypt.tex

@@ -4190,7 +4190,8 @@ int pkcs_1_oaep_encode(
           unsigned long  modulus_bitlen,
              prng_state *prng,
                     int  prng_idx,
-                    int  hash_idx,
+                    int  mgf_hash,
+                    int  lparam_hash,
           unsigned char *out,
           unsigned long *outlen);
 \end{alltt}
@@ -4200,7 +4201,9 @@ tag that can be applied to the encoding.  This is useful to identify which syste
 \textit{lparam} can be set to \textbf{NULL}.
 
 OAEP encoding requires the length of the modulus in bits in order to calculate the size of the output.  This is passed as the parameter
-\textit{modulus\_bitlen}.  \textit{hash\_idx} is the index into the hash descriptor table of the hash desired.  PKCS \#1 allows any hash to be
+\textit{modulus\_bitlen}.  \textit{mgf\_hash} is the index into the hash descriptor table of the hash desired for the mask generation function (MGF).
+\textit{lparam\_hash} is the index into the hash descriptor table of the hash desired for the \textit{lparam}.  This value can also be set to $-1$
+to indicate usage of the same algorithm than for the MGF.  PKCS \#1 allows any hash to be
 used but both the encoder and decoder must use the same hash in order for this to succeed.  The size of hash output affects the maximum
  sized input message.  \textit{prng\_idx} and \textit{prng} are the random number generator arguments required to randomize the padding process.
 The padded message is stored in \textit{out} along with the length in \textit{outlen}.
@@ -4221,7 +4224,8 @@ int pkcs_1_oaep_decode(
     const unsigned char *lparam,
           unsigned long  lparamlen,
           unsigned long  modulus_bitlen,
-                    int  hash_idx,
+                    int  mgf_hash,
+                    int  lparam_hash,
           unsigned char *out,
           unsigned long *outlen,
                     int *res);
@@ -4230,8 +4234,8 @@ int pkcs_1_oaep_decode(
 This function decodes an OAEP encoded message and outputs the original message that was passed to the OAEP encoder.  \textit{msg} is the
 output of pkcs\_1\_oaep\_encode() of length \textit{msglen}.  \textit{lparam} is the same system variable passed to the OAEP encoder.  If it does not
 match what was used during encoding this function will not decode the packet.  \textit{modulus\_bitlen} is the size of the RSA modulus in bits
-and must match what was used during encoding.  Similarly the \textit{hash\_idx} index into the hash descriptor table must match what was used
-during encoding.
+and must match what was used during encoding.  Similarly the \textit{mgf\_hash} and \textit{lparam\_hash} indexes into the hash descriptor table must
+match what was used during encoding.
 
 If the function succeeds it decodes the OAEP encoded message into \textit{out} of length \textit{outlen} and stores a
 $1$ in \textit{res}.  If the packet is invalid it stores $0$ in \textit{res} and if the function fails for another reason
@@ -4426,7 +4430,8 @@ int rsa_encrypt_key_ex(
           unsigned long  lparamlen,
              prng_state *prng,
                     int  prng_idx,
-                    int  hash_idx,
+                    int  mgf_hash,
+                    int  lparam_hash,
                     int  padding,
                 rsa_key *key);
 \end{verbatim}
@@ -4447,7 +4452,8 @@ int rsa_decrypt_key(
           unsigned long *outlen,
     const unsigned char *lparam,
           unsigned long  lparamlen,
-                    int  hash_idx,
+                    int  mgf_hash,
+                    int  lparam_hash,
                     int *stat,
                 rsa_key *key);
 \end{verbatim}

+ 6 - 4
src/headers/tomcrypt_pk.h

@@ -57,10 +57,10 @@ void rsa_free(rsa_key *key);
 
 /* These use PKCS #1 v2.0 padding */
 #define rsa_encrypt_key(in, inlen, out, outlen, lparam, lparamlen, prng, prng_idx, hash_idx, key) \
-  rsa_encrypt_key_ex(in, inlen, out, outlen, lparam, lparamlen, prng, prng_idx, hash_idx, LTC_PKCS_1_OAEP, key)
+  rsa_encrypt_key_ex(in, inlen, out, outlen, lparam, lparamlen, prng, prng_idx, hash_idx, -1, LTC_PKCS_1_OAEP, key)
 
 #define rsa_decrypt_key(in, inlen, out, outlen, lparam, lparamlen, hash_idx, stat, key) \
-  rsa_decrypt_key_ex(in, inlen, out, outlen, lparam, lparamlen, hash_idx, LTC_PKCS_1_OAEP, stat, key)
+  rsa_decrypt_key_ex(in, inlen, out, outlen, lparam, lparamlen, hash_idx, -1, LTC_PKCS_1_OAEP, stat, key)
 
 #define rsa_sign_hash(in, inlen, out, outlen, prng, prng_idx, hash_idx, saltlen, key) \
   rsa_sign_hash_ex(in, inlen, out, outlen, LTC_PKCS_1_PSS, prng, prng_idx, hash_idx, saltlen, key)
@@ -76,13 +76,15 @@ int rsa_encrypt_key_ex(const unsigned char *in,       unsigned long  inlen,
                              unsigned char *out,      unsigned long *outlen,
                        const unsigned char *lparam,   unsigned long  lparamlen,
                              prng_state    *prng,     int            prng_idx,
-                             int            hash_idx, int            padding,
+                             int            mgf_hash, int            lparam_hash,
+                             int            padding,
                        const rsa_key       *key);
 
 int rsa_decrypt_key_ex(const unsigned char *in,             unsigned long  inlen,
                              unsigned char *out,            unsigned long *outlen,
                        const unsigned char *lparam,         unsigned long  lparamlen,
-                             int            hash_idx,       int            padding,
+                             int            mgf_hash,       int            lparam_hash,
+                             int            padding,
                              int           *stat,     const rsa_key       *key);
 
 int rsa_sign_hash_ex(const unsigned char *in,       unsigned long  inlen,

+ 4 - 2
src/headers/tomcrypt_pkcs.h

@@ -49,12 +49,14 @@ int pkcs_1_v1_5_decode(const unsigned char *msg,
 int pkcs_1_oaep_encode(const unsigned char *msg,    unsigned long msglen,
                        const unsigned char *lparam, unsigned long lparamlen,
                              unsigned long modulus_bitlen, prng_state *prng,
-                             int           prng_idx,         int  hash_idx,
+                             int           prng_idx,
+                             int           mgf_hash, int lparam_hash,
                              unsigned char *out,    unsigned long *outlen);
 
 int pkcs_1_oaep_decode(const unsigned char *msg,    unsigned long msglen,
                        const unsigned char *lparam, unsigned long lparamlen,
-                             unsigned long modulus_bitlen, int hash_idx,
+                             unsigned long modulus_bitlen,
+                             int           mgf_hash, int          lparam_hash,
                              unsigned char *out,    unsigned long *outlen,
                              int           *res);
 

+ 19 - 9
src/pk/pkcs1/pkcs_1_oaep_decode.c

@@ -16,7 +16,8 @@
    @param lparam           The session or system data (can be NULL)
    @param lparamlen        The length of the lparam
    @param modulus_bitlen   The bit length of the RSA modulus
-   @param hash_idx         The index of the hash desired
+   @param mgf_hash         The hash algorithm used for the MGF
+   @param lparam_hash      The hash algorithm used when hashing the lparam (can be -1)
    @param out              [out] Destination of decoding
    @param outlen           [in/out] The max size and resulting size of the decoding
    @param res              [out] Result of decoding, 1==valid, 0==invalid
@@ -24,13 +25,14 @@
 */
 int pkcs_1_oaep_decode(const unsigned char *msg,    unsigned long msglen,
                        const unsigned char *lparam, unsigned long lparamlen,
-                             unsigned long modulus_bitlen, int hash_idx,
+                             unsigned long modulus_bitlen,
+                             int mgf_hash, int lparam_hash,
                              unsigned char *out,    unsigned long *outlen,
                              int           *res)
 {
    unsigned char *DB, *seed, *mask;
    unsigned long hLen, x, y, modulus_len;
-   int           err, ret;
+   int           err, ret, lparam_hash_used;
 
    LTC_ARGCHK(msg    != NULL);
    LTC_ARGCHK(out    != NULL);
@@ -41,10 +43,18 @@ int pkcs_1_oaep_decode(const unsigned char *msg,    unsigned long msglen,
    *res = 0;
 
    /* test valid hash */
-   if ((err = hash_is_valid(hash_idx)) != CRYPT_OK) {
+   if ((err = hash_is_valid(mgf_hash)) != CRYPT_OK) {
       return err;
    }
-   hLen        = hash_descriptor[hash_idx].hashsize;
+   if (lparam_hash != -1) {
+      if ((err = hash_is_valid(lparam_hash)) != CRYPT_OK) {
+         return err;
+      }
+      lparam_hash_used = lparam_hash;
+   } else {
+      lparam_hash_used = mgf_hash;
+   }
+   hLen        = hash_descriptor[lparam_hash_used].hashsize;
    modulus_len = (modulus_bitlen >> 3) + (modulus_bitlen & 7 ? 1 : 0);
 
    /* test hash/message size */
@@ -94,7 +104,7 @@ int pkcs_1_oaep_decode(const unsigned char *msg,    unsigned long msglen,
    x += modulus_len - hLen - 1;
 
    /* compute MGF1 of maskedDB (hLen) */
-   if ((err = pkcs_1_mgf1(hash_idx, DB, modulus_len - hLen - 1, mask, hLen)) != CRYPT_OK) {
+   if ((err = pkcs_1_mgf1(mgf_hash, DB, modulus_len - hLen - 1, mask, hLen)) != CRYPT_OK) {
       goto LBL_ERR;
    }
 
@@ -104,7 +114,7 @@ int pkcs_1_oaep_decode(const unsigned char *msg,    unsigned long msglen,
    }
 
    /* compute MGF1 of seed (k - hlen - 1) */
-   if ((err = pkcs_1_mgf1(hash_idx, seed, hLen, mask, modulus_len - hLen - 1)) != CRYPT_OK) {
+   if ((err = pkcs_1_mgf1(mgf_hash, seed, hLen, mask, modulus_len - hLen - 1)) != CRYPT_OK) {
       goto LBL_ERR;
    }
 
@@ -118,12 +128,12 @@ int pkcs_1_oaep_decode(const unsigned char *msg,    unsigned long msglen,
    /* compute lhash and store it in seed [reuse temps!] */
    x = modulus_len;
    if (lparam != NULL) {
-      if ((err = hash_memory(hash_idx, lparam, lparamlen, seed, &x)) != CRYPT_OK) {
+      if ((err = hash_memory(lparam_hash_used, lparam, lparamlen, seed, &x)) != CRYPT_OK) {
          goto LBL_ERR;
       }
    } else {
       /* can't pass hash_memory a NULL so use DB with zero length */
-      if ((err = hash_memory(hash_idx, DB, 0, seed, &x)) != CRYPT_OK) {
+      if ((err = hash_memory(lparam_hash_used, DB, 0, seed, &x)) != CRYPT_OK) {
          goto LBL_ERR;
       }
    }

+ 17 - 8
src/pk/pkcs1/pkcs_1_oaep_encode.c

@@ -26,28 +26,37 @@
 int pkcs_1_oaep_encode(const unsigned char *msg,    unsigned long msglen,
                        const unsigned char *lparam, unsigned long lparamlen,
                              unsigned long modulus_bitlen, prng_state *prng,
-                             int           prng_idx,         int  hash_idx,
+                             int           prng_idx,
+                             int           mgf_hash, int lparam_hash,
                              unsigned char *out,    unsigned long *outlen)
 {
    unsigned char *DB, *seed, *mask;
    unsigned long hLen, x, y, modulus_len;
-   int           err;
+   int           err, lparam_hash_used;
 
    LTC_ARGCHK((msglen == 0) || (msg != NULL));
    LTC_ARGCHK(out    != NULL);
    LTC_ARGCHK(outlen != NULL);
 
    /* test valid hash */
-   if ((err = hash_is_valid(hash_idx)) != CRYPT_OK) {
+   if ((err = hash_is_valid(mgf_hash)) != CRYPT_OK) {
       return err;
    }
+   if (lparam_hash != -1) {
+      if ((err = hash_is_valid(lparam_hash)) != CRYPT_OK) {
+         return err;
+      }
+      lparam_hash_used = lparam_hash;
+   } else {
+      lparam_hash_used = mgf_hash;
+   }
 
    /* valid prng */
    if ((err = prng_is_valid(prng_idx)) != CRYPT_OK) {
       return err;
    }
 
-   hLen        = hash_descriptor[hash_idx].hashsize;
+   hLen        = hash_descriptor[lparam_hash_used].hashsize;
    modulus_len = (modulus_bitlen >> 3) + (modulus_bitlen & 7 ? 1 : 0);
 
    /* test message size */
@@ -76,12 +85,12 @@ int pkcs_1_oaep_encode(const unsigned char *msg,    unsigned long msglen,
    /* DB == lhash || PS || 0x01 || M, PS == k - mlen - 2hlen - 2 zeroes */
    x = modulus_len;
    if (lparam != NULL) {
-      if ((err = hash_memory(hash_idx, lparam, lparamlen, DB, &x)) != CRYPT_OK) {
+      if ((err = hash_memory(lparam_hash_used, lparam, lparamlen, DB, &x)) != CRYPT_OK) {
          goto LBL_ERR;
       }
    } else {
       /* can't pass hash_memory a NULL so use DB with zero length */
-      if ((err = hash_memory(hash_idx, DB, 0, DB, &x)) != CRYPT_OK) {
+      if ((err = hash_memory(lparam_hash_used, DB, 0, DB, &x)) != CRYPT_OK) {
          goto LBL_ERR;
       }
    }
@@ -108,7 +117,7 @@ int pkcs_1_oaep_encode(const unsigned char *msg,    unsigned long msglen,
    }
 
    /* compute MGF1 of seed (k - hlen - 1) */
-   if ((err = pkcs_1_mgf1(hash_idx, seed, hLen, mask, modulus_len - hLen - 1)) != CRYPT_OK) {
+   if ((err = pkcs_1_mgf1(mgf_hash, seed, hLen, mask, modulus_len - hLen - 1)) != CRYPT_OK) {
       goto LBL_ERR;
    }
 
@@ -118,7 +127,7 @@ int pkcs_1_oaep_encode(const unsigned char *msg,    unsigned long msglen,
    }
 
    /* compute MGF1 of maskedDB (hLen) */
-   if ((err = pkcs_1_mgf1(hash_idx, DB, modulus_len - hLen - 1, mask, hLen)) != CRYPT_OK) {
+   if ((err = pkcs_1_mgf1(mgf_hash, DB, modulus_len - hLen - 1, mask, hLen)) != CRYPT_OK) {
       goto LBL_ERR;
    }
 

+ 7 - 6
src/pk/rsa/rsa_decrypt_key.c

@@ -17,7 +17,8 @@
    @param outlen      [in/out] The max size and resulting size of the plaintext (octets)
    @param lparam      The system "lparam" value
    @param lparamlen   The length of the lparam value (octets)
-   @param hash_idx    The index of the hash desired
+   @param mgf_hash    The hash algorithm used for the MGF
+   @param lparam_hash The hash algorithm used when hashing the lparam (can be -1)
    @param padding     Type of padding (LTC_PKCS_1_OAEP or LTC_PKCS_1_V1_5)
    @param stat        [out] Result of the decryption, 1==valid, 0==invalid
    @param key         The corresponding private RSA key
@@ -26,7 +27,8 @@
 int rsa_decrypt_key_ex(const unsigned char *in,             unsigned long  inlen,
                              unsigned char *out,            unsigned long *outlen,
                        const unsigned char *lparam,         unsigned long  lparamlen,
-                             int            hash_idx,       int            padding,
+                             int            mgf_hash,       int            lparam_hash,
+                             int            padding,
                              int           *stat,     const rsa_key       *key)
 {
   unsigned long modulus_bitlen, modulus_bytelen, x;
@@ -43,7 +45,6 @@ int rsa_decrypt_key_ex(const unsigned char *in,             unsigned long  inlen
   *stat = 0;
 
   /* valid padding? */
-
   if ((padding != LTC_PKCS_1_V1_5) &&
       (padding != LTC_PKCS_1_OAEP)) {
     return CRYPT_PK_INVALID_PADDING;
@@ -51,7 +52,7 @@ int rsa_decrypt_key_ex(const unsigned char *in,             unsigned long  inlen
 
   if (padding == LTC_PKCS_1_OAEP) {
     /* valid hash ? */
-    if ((err = hash_is_valid(hash_idx)) != CRYPT_OK) {
+    if ((err = hash_is_valid(mgf_hash)) != CRYPT_OK) {
        return err;
     }
   }
@@ -80,8 +81,8 @@ int rsa_decrypt_key_ex(const unsigned char *in,             unsigned long  inlen
 
   if (padding == LTC_PKCS_1_OAEP) {
     /* now OAEP decode the packet */
-    err = pkcs_1_oaep_decode(tmp, x, lparam, lparamlen, modulus_bitlen, hash_idx,
-                             out, outlen, stat);
+    err = pkcs_1_oaep_decode(tmp, x, lparam, lparamlen, modulus_bitlen, mgf_hash,
+                             lparam_hash, out, outlen, stat);
   } else {
     /* now PKCS #1 v1.5 depad the packet */
     err = pkcs_1_v1_5_decode(tmp, x, LTC_PKCS_1_EME, modulus_bitlen, out, outlen, stat);

+ 5 - 4
src/pk/rsa/rsa_encrypt_key.c

@@ -28,7 +28,8 @@ int rsa_encrypt_key_ex(const unsigned char *in,       unsigned long  inlen,
                              unsigned char *out,      unsigned long *outlen,
                        const unsigned char *lparam,   unsigned long  lparamlen,
                              prng_state    *prng,     int            prng_idx,
-                             int            hash_idx, int            padding,
+                             int            mgf_hash, int            lparam_hash,
+                             int            padding,
                        const rsa_key       *key)
 {
   unsigned long modulus_bitlen, modulus_bytelen, x;
@@ -52,7 +53,7 @@ int rsa_encrypt_key_ex(const unsigned char *in,       unsigned long  inlen,
 
   if (padding == LTC_PKCS_1_OAEP) {
     /* valid hash? */
-    if ((err = hash_is_valid(hash_idx)) != CRYPT_OK) {
+    if ((err = hash_is_valid(mgf_hash)) != CRYPT_OK) {
        return err;
     }
   }
@@ -71,8 +72,8 @@ int rsa_encrypt_key_ex(const unsigned char *in,       unsigned long  inlen,
     /* OAEP pad the key */
     x = *outlen;
     if ((err = pkcs_1_oaep_encode(in, inlen, lparam,
-                                  lparamlen, modulus_bitlen, prng, prng_idx, hash_idx,
-                                  out, &x)) != CRYPT_OK) {
+                                  lparamlen, modulus_bitlen, prng, prng_idx, mgf_hash,
+                                  lparam_hash, out, &x)) != CRYPT_OK) {
        return err;
     }
   } else {

+ 2 - 2
tests/pkcs_1_eme_test.c

@@ -43,9 +43,9 @@ int pkcs_1_eme_test(void)
         unsigned long buflen = sizeof(buf), obuflen = sizeof(obuf);
         int stat;
         prng_descriptor[prng_idx].add_entropy(s->o2, s->o2_l, (void*)no_prng_desc);
-        DOX(rsa_encrypt_key_ex(s->o1, s->o1_l, obuf, &obuflen, NULL, 0, (void*)no_prng_desc, prng_idx, -1, LTC_PKCS_1_V1_5, key), s->name);
+        DOX(rsa_encrypt_key_ex(s->o1, s->o1_l, obuf, &obuflen, NULL, 0, (void*)no_prng_desc, prng_idx, -1, -1, LTC_PKCS_1_V1_5, key), s->name);
         COMPARE_TESTVECTOR(obuf, obuflen, s->o3, s->o3_l,s->name, j);
-        DOX(rsa_decrypt_key_ex(obuf, obuflen, buf, &buflen, NULL, 0, -1, LTC_PKCS_1_V1_5, &stat, key), s->name);
+        DOX(rsa_decrypt_key_ex(obuf, obuflen, buf, &buflen, NULL, 0, -1, -1, LTC_PKCS_1_V1_5, &stat, key), s->name);
         DOX(stat == 1?CRYPT_OK:CRYPT_FAIL_TESTVECTOR, s->name);
     } /* for */
 

+ 2 - 2
tests/pkcs_1_test.c

@@ -46,11 +46,11 @@ int pkcs_1_test(void)
 
       /* encode it */
       l1 = sizeof(buf[1]);
-      DO(pkcs_1_oaep_encode(buf[0], l3, lparam, lparamlen, modlen, &yarrow_prng, prng_idx, hash_idx, buf[1], &l1));
+      DO(pkcs_1_oaep_encode(buf[0], l3, lparam, lparamlen, modlen, &yarrow_prng, prng_idx, hash_idx, -1, buf[1], &l1));
 
       /* decode it */
       l2 = sizeof(buf[2]);
-      DO(pkcs_1_oaep_decode(buf[1], l1, lparam, lparamlen, modlen, hash_idx, buf[2], &l2, &res1));
+      DO(pkcs_1_oaep_decode(buf[1], l1, lparam, lparamlen, modlen, hash_idx, -1, buf[2], &l2, &res1));
 
       if (res1 != 1 || l2 != l3 || memcmp(buf[2], buf[0], l3) != 0) {
          fprintf(stderr, "Outsize == %lu, should have been %lu, res1 = %d, lparamlen = %lu, msg contents follow.\n", l2, l3, res1, lparamlen);

+ 62 - 43
tests/rsa_test.c

@@ -441,8 +441,8 @@ int rsa_test(void)
 {
    unsigned char in[1024], out[1024], tmp[3072];
    rsa_key       key, privKey, pubKey;
-   int           hash_idx, prng_idx, stat, stat2, i;
-   unsigned long rsa_msgsize, len, len2, len3, cnt, cnt2;
+   int           hash_idx, prng_idx, stat, stat2, i, mgf_hash, label_hash;
+   unsigned long rsa_msgsize, len, len2, len3, cnt, cnt2, max_msgsize;
    static unsigned char lparam[] = { 0x01, 0x02, 0x03, 0x04 };
    void* dP;
    unsigned char* p;
@@ -497,60 +497,79 @@ print_hex("q", tmp, len);
          rsa_free(&key);
       }
    }
+   /* make a random key/msg */
+   ENSURE(yarrow_read(in, 117, &yarrow_prng) == 117);
 
-   /* encrypt the key (without lparam) */
-   for (cnt = 0; cnt < 4; cnt++) {
-   for (rsa_msgsize = 0; rsa_msgsize <= 86; rsa_msgsize++) {
-      /* make a random key/msg */
-      ENSURE(yarrow_read(in, rsa_msgsize, &yarrow_prng) == rsa_msgsize);
-
-      len  = sizeof(out);
-      len2 = rsa_msgsize;
+#ifdef LTC_TEST_EXT
+   for (mgf_hash = 0; mgf_hash < TAB_SIZE; ++mgf_hash) {
+      if (hash_is_valid(mgf_hash) != CRYPT_OK)
+         continue;
+#else
+   {
+      mgf_hash = hash_idx;
+#endif
+      for (label_hash = 0; label_hash < TAB_SIZE; ++label_hash) {
+         if (hash_is_valid(label_hash) != CRYPT_OK)
+            continue;
+         if (2 * hash_descriptor[label_hash].hashsize > 126)
+            continue;
+         max_msgsize = 128 - (2 * hash_descriptor[label_hash].hashsize) - 2;
 
-      DO(rsa_encrypt_key(in, rsa_msgsize, out, &len, NULL, 0, &yarrow_prng, prng_idx, hash_idx, &key));
-      /* change a byte */
-      out[8] ^= 1;
-      SHOULD_FAIL(rsa_decrypt_key(out, len, tmp, &len2, NULL, 0, hash_idx, &stat2, &key));
-      /* change a byte back */
-      out[8] ^= 1;
-      ENSURE(len2 == rsa_msgsize);
+#if defined(LTC_TEST_DBG) && LTC_TEST_DBG > 1
+         fprintf(stderr, "Test MGF(%s), Labelhash(%s) with max_msgsize %lu\n", hash_descriptor[mgf_hash].name, hash_descriptor[label_hash].name, max_msgsize);
+#endif
+         /* encrypt the key (without lparam) */
+         for (rsa_msgsize = 0; rsa_msgsize <= max_msgsize; rsa_msgsize++) {
+
+            len  = sizeof(out);
+            len2 = rsa_msgsize;
+
+            DO(rsa_encrypt_key_ex(in, rsa_msgsize, out, &len, NULL, 0, &yarrow_prng, prng_idx, mgf_hash, label_hash, LTC_PKCS_1_OAEP, &key));
+            /* change a byte */
+            out[8] ^= 1;
+            SHOULD_FAIL(rsa_decrypt_key_ex(out, len, tmp, &len2, NULL, 0, mgf_hash, label_hash, LTC_PKCS_1_OAEP, &stat2, &key));
+            /* change a byte back */
+            out[8] ^= 1;
+            ENSURE(len2 == rsa_msgsize);
+
+            len2 = rsa_msgsize;
+            DO(rsa_decrypt_key_ex(out, len, tmp, &len2, NULL, 0, mgf_hash, label_hash, LTC_PKCS_1_OAEP, &stat, &key));
+            ENSUREX(stat == 1 && stat2 == 0, "rsa_decrypt_key (without lparam)");
+            DO(do_compare_testvector(tmp, len2, in, rsa_msgsize,  "rsa_decrypt_key (without lparam)", cnt << 8 | rsa_msgsize));
+         }
+
+         /* encrypt the key (with lparam) */
+         for (rsa_msgsize = 0; rsa_msgsize <= max_msgsize; rsa_msgsize++) {
+            len  = sizeof(out);
+            len2 = rsa_msgsize;
+            DO(rsa_encrypt_key_ex(rsa_msgsize ? in : NULL, rsa_msgsize, out, &len, lparam, sizeof(lparam), &yarrow_prng, prng_idx, mgf_hash, label_hash, LTC_PKCS_1_OAEP, &key));
+            /* change a byte */
+            out[8] ^= 1;
+            SHOULD_FAIL(rsa_decrypt_key_ex(out, len, tmp, &len2, lparam, sizeof(lparam), mgf_hash, label_hash, LTC_PKCS_1_OAEP, &stat2, &key));
+            ENSURE(len2 == rsa_msgsize);
+
+            /* change a byte back */
+            out[8] ^= 1;
+
+            len2 = rsa_msgsize;
+            DO(rsa_decrypt_key_ex(out, len, tmp, &len2, lparam, sizeof(lparam), mgf_hash, label_hash, LTC_PKCS_1_OAEP, &stat, &key));
+            ENSURE(stat == 1 && stat2 == 0);
+            DO(do_compare_testvector(tmp, len2, in, rsa_msgsize,  "rsa_decrypt_key (with lparam)", rsa_msgsize));
+         }
 
-      len2 = rsa_msgsize;
-      DO(rsa_decrypt_key(out, len, tmp, &len2, NULL, 0, hash_idx, &stat, &key));
-      ENSUREX(stat == 1 && stat2 == 0, "rsa_decrypt_key (without lparam)");
-      DO(do_compare_testvector(tmp, len2, in, rsa_msgsize,  "rsa_decrypt_key (without lparam)", cnt << 8 | rsa_msgsize));
-   }
+      }
    }
 
-   /* encrypt the key (with lparam) */
-   for (rsa_msgsize = 0; rsa_msgsize <= 86; rsa_msgsize++) {
-      len  = sizeof(out);
-      len2 = rsa_msgsize;
-      DO(rsa_encrypt_key(rsa_msgsize ? in : NULL, rsa_msgsize, out, &len, lparam, sizeof(lparam), &yarrow_prng, prng_idx, hash_idx, &key));
-      /* change a byte */
-      out[8] ^= 1;
-      SHOULD_FAIL(rsa_decrypt_key(out, len, tmp, &len2, lparam, sizeof(lparam), hash_idx, &stat2, &key));
-      ENSURE(len2 == rsa_msgsize);
 
-      /* change a byte back */
-      out[8] ^= 1;
-
-      len2 = rsa_msgsize;
-      DO(rsa_decrypt_key(out, len, tmp, &len2, lparam, sizeof(lparam), hash_idx, &stat, &key));
-      ENSURE(stat == 1 && stat2 == 0);
-      DO(do_compare_testvector(tmp, len2, in, rsa_msgsize,  "rsa_decrypt_key (with lparam)", rsa_msgsize));
-   }
 
    /* encrypt the key PKCS #1 v1.5 (payload from 1 to 117 bytes) */
    for (rsa_msgsize = 0; rsa_msgsize <= 117; rsa_msgsize++) {
       len  = sizeof(out);
       len2 = rsa_msgsize;
-      /* make a random key/msg */
-      ENSURE(yarrow_read(in, rsa_msgsize, &yarrow_prng) == rsa_msgsize);
-      DO(rsa_encrypt_key_ex(in, rsa_msgsize, out, &len, NULL, 0, &yarrow_prng, prng_idx, 0, LTC_PKCS_1_V1_5, &key));
+      DO(rsa_encrypt_key_ex(in, rsa_msgsize, out, &len, NULL, 0, &yarrow_prng, prng_idx, 0, -1, LTC_PKCS_1_V1_5, &key));
 
       len2 = rsa_msgsize;
-      DO(rsa_decrypt_key_ex(out, len, tmp, &len2, NULL, 0, 0, LTC_PKCS_1_V1_5, &stat, &key));
+      DO(rsa_decrypt_key_ex(out, len, tmp, &len2, NULL, 0, 0, -1, LTC_PKCS_1_V1_5, &stat, &key));
       ENSURE(stat == 1);
       DO(do_compare_testvector(tmp, len2, in, rsa_msgsize,  "rsa_decrypt_key_ex", rsa_msgsize));
    }