summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWerner Koch <wk@gnupg.org>2011-06-09 12:44:18 (GMT)
committerWerner Koch <wk@gnupg.org>2011-06-09 12:44:18 (GMT)
commit870b764bb551b726d4a88877533041a4680423db (patch)
tree87db469a0d1cc97fff102d0dad3801c5b641f0c0
parentce235fc29562666277ab72e2745636ffbe987fba (diff)
downloadlibgcrypt-870b764bb551b726d4a88877533041a4680423db.tar.gz
libgcrypt-870b764bb551b726d4a88877533041a4680423db.tar.xz
Add random-override parameter to the PK functions to allow better regression testing.
-rw-r--r--NEWS4
-rw-r--r--cipher/ChangeLog4
-rw-r--r--cipher/pubkey.c106
-rw-r--r--tests/ChangeLog6
-rw-r--r--tests/basic.c17
5 files changed, 126 insertions, 11 deletions
diff --git a/NEWS b/NEWS
index 6657d76..0522b1f 100644
--- a/NEWS
+++ b/NEWS
@@ -6,9 +6,9 @@ Noteworthy changes in version 1.5.x (unreleased)
* Support for WindowsCE.
- * Support ECDH.
+ * Support for ECDH.
- * Support OAEP.
+ * Support for OAEP and PSS methods as described by RFC-3447.
* gcry_sexp_build does now support opaque MPIs with "%m".
diff --git a/cipher/ChangeLog b/cipher/ChangeLog
index 735ba18..6642d09 100644
--- a/cipher/ChangeLog
+++ b/cipher/ChangeLog
@@ -1,5 +1,9 @@
2011-06-09 Werner Koch <wk@g10code.com>
+ * pubkey.c (oaep_encode, pss_encode): Add args RANDOM_OVERRIDE and
+ RANDOM_OVERRIDE_LEN.
+ (sexp_data_to_mpi): Extract new random-override parameter.
+
* pubkey.c (pss_encode, pss_verify): Use VALUE verbatim for MHASH.
(octet_string_from_mpi): Add arg SPACE.
diff --git a/cipher/pubkey.c b/cipher/pubkey.c
index c92d3ff..830f515 100644
--- a/cipher/pubkey.c
+++ b/cipher/pubkey.c
@@ -1092,6 +1092,10 @@ mgf1 (unsigned char *output, size_t outlen, unsigned char *seed, size_t seedlen,
string as label. On success the encoded ciphertext is returned at
R_RESULT.
+ If {RANDOM_OVERRIDE, RANDOM_OVERRIDE_LEN} is given it is used as
+ the seed instead of using a random string for it. This feature is
+ only useful for regression tests.
+
Here is figure 1 from the RFC depicting the process:
+----------+---------+-------+
@@ -1114,7 +1118,8 @@ mgf1 (unsigned char *output, size_t outlen, unsigned char *seed, size_t seedlen,
static gcry_err_code_t
oaep_encode (gcry_mpi_t *r_result, unsigned int nbits, int algo,
const unsigned char *value, size_t valuelen,
- const unsigned char *label, size_t labellen)
+ const unsigned char *label, size_t labellen,
+ const void *random_override, size_t random_override_len)
{
gcry_err_code_t rc = 0;
gcry_error_t err;
@@ -1165,7 +1170,17 @@ oaep_encode (gcry_mpi_t *r_result, unsigned int nbits, int algo,
/* Step 3d: Generate seed. We store it where the maskedSeed will go
later. */
- gcry_randomize (frame + 1, hlen, GCRY_STRONG_RANDOM);
+ if (random_override)
+ {
+ if (random_override_len != hlen)
+ {
+ gcry_free (frame);
+ return GPG_ERR_INV_ARG;
+ }
+ memcpy (frame + 1, random_override, hlen);
+ }
+ else
+ gcry_randomize (frame + 1, hlen, GCRY_STRONG_RANDOM);
/* Step 2e and 2f: Create maskedDB. */
{
@@ -1399,6 +1414,10 @@ oaep_decode (unsigned char **r_result, size_t *r_resultlen,
length of salt to be used. On success the result is stored as a
new MPI at R_RESULT. On error the value at R_RESULT is undefined.
+ If {RANDOM_OVERRIDE, RANDOM_OVERRIDE_LEN} is given it is used as
+ the salt instead of using a random string for the salt. This
+ feature is only useful for regression tests.
+
Here is figure 2 from the RFC (errata 595 applied) depicting the
process:
@@ -1430,8 +1449,8 @@ oaep_decode (unsigned char **r_result, size_t *r_resultlen,
*/
static gcry_err_code_t
pss_encode (gcry_mpi_t *r_result, unsigned int nbits, int algo,
- const unsigned char *value, size_t valuelen,
- int saltlen)
+ const unsigned char *value, size_t valuelen, int saltlen,
+ const void *random_override, size_t random_override_len)
{
gcry_err_code_t rc = 0;
gcry_error_t err;
@@ -1492,7 +1511,19 @@ pss_encode (gcry_mpi_t *r_result, unsigned int nbits, int algo,
/* Step 4: Create a salt. */
if (saltlen)
- gcry_randomize (salt, saltlen, GCRY_STRONG_RANDOM);
+ {
+ if (random_override)
+ {
+ if (random_override_len != saltlen)
+ {
+ rc = GPG_ERR_INV_ARG;
+ goto leave;
+ }
+ memcpy (salt, random_override, saltlen);
+ }
+ else
+ gcry_randomize (salt, saltlen, GCRY_STRONG_RANDOM);
+ }
/* Step 5 and 6: M' = Hash(Padding1 || mHash || salt). */
memset (buf, 0, 8); /* Padding. */
@@ -2412,6 +2443,7 @@ sexp_to_enc (gcry_sexp_t sexp, gcry_mpi_t **retarray, gcry_module_t *retalgo,
[(hash-algo <algo>)]
[(label <label>)]
[(salt-length <length>)]
+ [(random-override <data>)]
)
Either the VALUE or the HASH element must be present for use
@@ -2421,6 +2453,8 @@ sexp_to_enc (gcry_sexp_t sexp, gcry_mpi_t **retarray, gcry_module_t *retalgo,
SALT-LENGTH is for PSS.
+ RANDOM-OVERRIDE is used to replace random nonces in PSS for
+ regression testing.
*/
static gcry_err_code_t
sexp_data_to_mpi (gcry_sexp_t input, gcry_mpi_t *ret_mpi,
@@ -2537,6 +2571,8 @@ sexp_data_to_mpi (gcry_sexp_t input, gcry_mpi_t *ret_mpi,
else
{
gcry_sexp_t list;
+ void *random_override = NULL;
+ size_t random_override_len = 0;
/* Get HASH-ALGO. */
list = gcry_sexp_find_token (ldata, "hash-algo", 0);
@@ -2578,10 +2614,35 @@ sexp_data_to_mpi (gcry_sexp_t input, gcry_mpi_t *ret_mpi,
if (rc)
goto leave;
}
+ /* Get optional RANDOM-OVERRIDE. */
+ list = gcry_sexp_find_token (ldata, "random-override", 0);
+ if (list)
+ {
+ s = gcry_sexp_nth_data (list, 1, &n);
+ if (!s)
+ rc = GPG_ERR_NO_OBJ;
+ else if (n > 0)
+ {
+ random_override = gcry_malloc (n);
+ if (!random_override)
+ rc = gpg_err_code_from_syserror ();
+ else
+ {
+ memcpy (random_override, s, n);
+ random_override_len = n;
+ }
+ }
+ gcry_sexp_release (list);
+ if (rc)
+ goto leave;
+ }
rc = oaep_encode (ret_mpi, ctx->nbits, ctx->hash_algo,
value, valuelen,
- ctx->label, ctx->labellen);
+ ctx->label, ctx->labellen,
+ random_override, random_override_len);
+
+ gcry_free (random_override);
}
}
else if (ctx->encoding == PUBKEY_ENC_PSS && lhash
@@ -2595,6 +2656,8 @@ sexp_data_to_mpi (gcry_sexp_t input, gcry_mpi_t *ret_mpi,
{
const void * value;
size_t valuelen;
+ void *random_override = NULL;
+ size_t random_override_len = 0;
ctx->hash_algo = get_hash_algo (s, n);
@@ -2620,9 +2683,36 @@ sexp_data_to_mpi (gcry_sexp_t input, gcry_mpi_t *ret_mpi,
ctx->saltlen = (unsigned int)strtoul (s, NULL, 10);
gcry_sexp_release (list);
}
+
+ /* Get optional RANDOM-OVERRIDE. */
+ list = gcry_sexp_find_token (ldata, "random-override", 0);
+ if (list)
+ {
+ s = gcry_sexp_nth_data (list, 1, &n);
+ if (!s)
+ rc = GPG_ERR_NO_OBJ;
+ else if (n > 0)
+ {
+ random_override = gcry_malloc (n);
+ if (!random_override)
+ rc = gpg_err_code_from_syserror ();
+ else
+ {
+ memcpy (random_override, s, n);
+ random_override_len = n;
+ }
+ }
+ gcry_sexp_release (list);
+ if (rc)
+ goto leave;
+ }
+
+ /* Encode the data. */
rc = pss_encode (ret_mpi, ctx->nbits - 1, ctx->hash_algo,
- value, valuelen,
- ctx->saltlen);
+ value, valuelen, ctx->saltlen,
+ random_override, random_override_len);
+
+ gcry_free (random_override);
}
}
}
diff --git a/tests/ChangeLog b/tests/ChangeLog
index d70c963..8160ff8 100644
--- a/tests/ChangeLog
+++ b/tests/ChangeLog
@@ -1,3 +1,9 @@
+2011-06-09 Werner Koch <wk@g10code.com>
+
+ * basic.c (check_pubkey_sign): Add a test using random-override.
+ (check_pubkey_crypt): Ditto. Print ALGO in verbose mode.
+ (check_pubkey_grip): Silence unused parameter warning.
+
2011-06-03 Werner Koch <wk@g10code.com>
* basic.c (main): Add option --die.
diff --git a/tests/basic.c b/tests/basic.c
index 0c66938..95cc749 100644
--- a/tests/basic.c
+++ b/tests/basic.c
@@ -2340,6 +2340,11 @@ check_pubkey_sign (int n, gcry_sexp_t skey, gcry_sexp_t pkey, int algo)
" (hash sha1 #11223344556677889900AABBCCDDEEFF10203040#))\n",
GCRY_PK_RSA,
0 },
+ { "(data\n (flags pss)\n"
+ " (hash sha1 #11223344556677889900AABBCCDDEEFF10203040#)\n"
+ " (random-override #4253647587980912233445566778899019283747#))\n",
+ GCRY_PK_RSA,
+ 0 },
{ NULL }
};
@@ -2423,6 +2428,13 @@ check_pubkey_crypt (int n, gcry_sexp_t skey, gcry_sexp_t pkey, int algo)
1,
0,
0 },
+ { "(data\n (flags oaep)\n (hash-algo sha1)\n (label \"test\")\n"
+ " (value #11223344556677889900AA#)\n"
+ " (random-override #4253647587980912233445566778899019283747#))\n",
+ "(flags oaep)(hash-algo sha1)(label \"test\")",
+ 1,
+ 0,
+ 0 },
{ "(data\n (flags )\n" " (value #11223344556677889900AA#))\n",
NULL,
1,
@@ -2475,7 +2487,8 @@ check_pubkey_crypt (int n, gcry_sexp_t skey, gcry_sexp_t pkey, int algo)
for (dataidx = 0; datas[dataidx].data; dataidx++)
{
if (verbose)
- fprintf (stderr, " encryption/decryption test %d\n", dataidx);
+ fprintf (stderr, " encryption/decryption test %d (algo %d)\n",
+ dataidx, algo);
rc = gcry_sexp_sscan (&data, NULL, datas[dataidx].data,
strlen (datas[dataidx].data));
@@ -2563,6 +2576,8 @@ check_pubkey_grip (int n, const unsigned char *grip,
{
unsigned char sgrip[20], pgrip[20];
+ (void)algo;
+
if (!gcry_pk_get_keygrip (skey, sgrip))
die ("get keygrip for private RSA key failed\n");
if (!gcry_pk_get_keygrip (pkey, pgrip))