Add fipsdriv mode rsa-derive.
authorWerner Koch <wk@gnupg.org>
Thu, 11 Dec 2008 14:54:25 +0000 (14:54 +0000)
committerWerner Koch <wk@gnupg.org>
Thu, 11 Dec 2008 14:54:25 +0000 (14:54 +0000)
tests/ChangeLog
tests/cavs_driver.pl
tests/fipsdrv.c

index 79701c8..205fdb2 100644 (file)
@@ -1,3 +1,8 @@
+2008-12-11  Werner Koch  <wk@g10code.com>
+
+       * fipsdrv.c (run_rsa_derive): New.
+       (main): Add mode rsa-derive.
+
 2008-12-10  Werner Koch  <wk@g10code.com>
 
        * basic.c (main): Check for error after running self-test in
index 739cd00..9b1da02 100755 (executable)
@@ -135,6 +135,24 @@ my %opt;
 # return en/decrypted data in hex form
 my $encdec;
 
+#
+# Derive an RSA key from the given X9.31 parameters.
+# $1: modulus size
+# $2: E   in hex form 
+# $3: Xp1 in hex form 
+# $4: Xp2 in hex form 
+# $5: Xp  in hex form 
+# $6: Xq1 in hex form 
+# $7: Xq2 in hex form 
+# $8: Xq  in hex form 
+# return: string with the calculated values in hex format, where each value
+#        is separated from the previous with a \n in the following order:
+#         P\n
+#         Q\n
+#         D\n
+my $rsa_derive;
+
+
 # Sign a message with RSA
 # $1: data to be signed in hex form
 # $2: Hash algo
@@ -358,6 +376,33 @@ sub libgcrypt_encdec($$$$$) {
 
 }
 
+sub libgcrypt_rsa_derive($$$$$$$$) {
+       my $n   = shift;
+        my $e   = shift;
+        my $xp1 = shift;
+        my $xp2 = shift;
+        my $xp  = shift;
+        my $xq1 = shift;
+        my $xq2 = shift;
+        my $xq  = shift;
+        my $sexp;
+        my @tmp;
+
+        $n = sprintf ("%u", $n);
+        $e = sprintf ("%u", $e);
+        $sexp = "(genkey(rsa(nbits " . sprintf ("%u:%s", length($n), $n) . ")"
+                . "(rsa-use-e " . sprintf ("%u:%s", length($e), $e) . ")"
+                . "(derive-parms"
+                . "(Xp1 #$xp1#)"
+                . "(Xp2 #$xp2#)"
+                . "(Xp  #$xp#)"
+                . "(Xq1 #$xq1#)"
+                . "(Xq2 #$xq2#)"
+                . "(Xq  #$xq#))))\n";
+
+        return pipe_through_program($sexp, "fipsdrv rsa-derive");
+}
+
 sub libgcrypt_rsa_sign($$$) {
        my $data = shift;
        my $hashalgo = shift;
index cdaadaf..79059b4 100644 (file)
@@ -164,6 +164,22 @@ showhex (const char *prefix, const void *buffer, size_t length)
     putc ('\n', stderr);
 }
 
+/* static void */
+/* show_sexp (const char *prefix, gcry_sexp_t a) */
+/* { */
+/*   char *buf; */
+/*   size_t size; */
+
+/*   if (prefix) */
+/*     fputs (prefix, stderr); */
+/*   size = gcry_sexp_sprint (a, GCRYSEXP_FMT_ADVANCED, NULL, 0); */
+/*   buf = gcry_xmalloc (size); */
+
+/*   gcry_sexp_sprint (a, GCRYSEXP_FMT_ADVANCED, buf, size); */
+/*   fprintf (stderr, "%.*s", (int)size, buf); */
+/*   gcry_free (buf); */
+/* } */
+
 
 /* Convert STRING consisting of hex characters into its binary
    representation and store that at BUFFER.  BUFFER needs to be of
@@ -1261,6 +1277,71 @@ run_hmac (int digest_algo, const void *key, size_t keylen,
   gcry_md_close (hd);
 }
 
+
+\f
+/* Derive an RSA key using the S-expression in (DATA,DATALEN).  This
+   S-expression is used directly as input to gcry_pk_genkey.  The
+   result is printed to stdout with one parameter per line in hex
+   format and in this order: p, q, d.  */
+static void
+run_rsa_derive (const void *data, size_t datalen)
+{
+  gpg_error_t err;
+  gcry_sexp_t s_keyspec, s_key, s_top, l1;
+  gcry_mpi_t mpi;
+  const char *parmlist;
+  int idx;
+
+  if (!datalen)
+    err = gpg_error (GPG_ERR_NO_DATA);
+  else
+    err = gcry_sexp_new (&s_keyspec, data, datalen, 1);
+  if (err)
+    die ("gcry_sexp_new failed for RSA key derive: %s\n",
+         gpg_strerror (err));
+
+  err = gcry_pk_genkey (&s_key, s_keyspec);
+  if (err)
+    die ("gcry_pk_genkey failed for RSA: %s\n", gpg_strerror (err));
+
+  gcry_sexp_release (s_keyspec);
+
+  /* P and Q might have been swapped but we need to to return them in
+     the proper order.  Build the parameter list accordingly.  */
+  parmlist = "pqd";
+  s_top = gcry_sexp_find_token (s_key, "misc-key-info", 0);
+  if (s_top)
+    {
+      l1 = gcry_sexp_find_token (s_top, "p-q-swapped", 0);
+      if (l1)
+        parmlist = "qpd";
+      gcry_sexp_release (l1);
+      gcry_sexp_release (s_top);
+    }
+
+  /* Parse and print the parameters.  */
+  l1 = gcry_sexp_find_token (s_key, "private-key", 0);
+  s_top = gcry_sexp_find_token (l1, "rsa", 0);
+  gcry_sexp_release (l1);
+  if (!s_top)
+    die ("private-key part not found in result\n");
+
+  for (idx=0; parmlist[idx]; idx++)
+    {
+      l1 = gcry_sexp_find_token (s_top, parmlist+idx, 1);
+      mpi = gcry_sexp_nth_mpi (l1, 1, GCRYMPI_FMT_USG);
+      gcry_sexp_release (l1);
+      if (!mpi)
+        die ("parameter %c missing in private-key\n", parmlist[idx]);
+      print_mpi_line (mpi, 1);
+      gcry_mpi_release (mpi);
+    }
+
+  gcry_sexp_release (s_top);
+  gcry_sexp_release (s_key);
+}
+
+
 \f
 static size_t
 compute_tag_length (size_t n)
@@ -1879,8 +1960,8 @@ usage (int show_help)
     ("Usage: " PGM " [OPTIONS] MODE [FILE]\n"
      "Run a crypto operation using hex encoded input and output.\n"
      "MODE:\n"
-     "  encrypt, decrypt, digest, random, hmac-sha, rsa-{gen,sign,verify},\n"
-     "  dsa-{pqg-gen,gen,sign,verify}\n"
+     "  encrypt, decrypt, digest, random, hmac-sha,\n"
+     "  rsa-{derive,gen,sign,verify}, dsa-{pqg-gen,gen,sign,verify}\n"
      "OPTIONS:\n"
      "  --verbose        Print additional information\n"
      "  --binary         Input and output is in binary form\n"
@@ -2041,6 +2122,10 @@ main (int argc, char **argv)
   if (!argc || argc > 2)
     usage (0);
   mode_string = *argv;
+
+  if (!strcmp (mode_string, "rsa-derive"))
+    binary_input = 1;
+
   if (argc == 2 && strcmp (argv[1], "-"))
     {
       input = fopen (argv[1], binary_input? "rb":"r");
@@ -2258,6 +2343,12 @@ main (int argc, char **argv)
 
       gcry_free (key_buffer);
     }
+  else if (!strcmp (mode_string, "rsa-derive"))
+    {
+      if (!data)
+        die ("no data available (do not use --chunk)\n");
+      run_rsa_derive (data, datalen);
+    }
   else if (!strcmp (mode_string, "rsa-gen"))
     {
       int keysize;