LCOV - code coverage report
Current view: top level - tests - pkcs1v2.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 222 339 65.5 %
Date: 2016-12-01 18:32:04 Functions: 7 11 63.6 %

          Line data    Source code
       1             : /* pkcs1v2.c - Test OAEP and PSS padding
       2             :  * Copyright (C) 2011 Free Software Foundation, Inc.
       3             :  *
       4             :  * This file is part of Libgcrypt.
       5             :  *
       6             :  * Libgcrypt is free software; you can redistribute it and/or modify
       7             :  * it under the terms of the GNU Lesser General Public License as
       8             :  * published by the Free Software Foundation; either version 2.1 of
       9             :  * the License, or (at your option) any later version.
      10             :  *
      11             :  * Libgcrypt is distributed in the hope that it will be useful,
      12             :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      13             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      14             :  * GNU Lesser General Public License for more details.
      15             :  *
      16             :  * You should have received a copy of the GNU Lesser General Public
      17             :  * License along with this program; if not, see <http://www.gnu.org/licenses/>.
      18             :  */
      19             : 
      20             : #ifdef HAVE_CONFIG_H
      21             : # include <config.h>
      22             : #endif
      23             : #include <stdio.h>
      24             : #include <stdlib.h>
      25             : #include <string.h>
      26             : #include <stdarg.h>
      27             : 
      28             : #ifdef _GCRYPT_IN_LIBGCRYPT
      29             : # include "../src/gcrypt-int.h"
      30             : #else
      31             : # include <gcrypt.h>
      32             : #endif
      33             : 
      34             : 
      35             : #define my_isascii(c) (!((c) & 0x80))
      36             : #define digitp(p)   (*(p) >= '0' && *(p) <= '9')
      37             : #define hexdigitp(a) (digitp (a)                     \
      38             :                       || (*(a) >= 'A' && *(a) <= 'F')  \
      39             :                       || (*(a) >= 'a' && *(a) <= 'f'))
      40             : #define xtoi_1(p)   (*(p) <= '9'? (*(p)- '0'): \
      41             :                      *(p) <= 'F'? (*(p)-'A'+10):(*(p)-'a'+10))
      42             : #define xtoi_2(p)   ((xtoi_1(p) * 16) + xtoi_1((p)+1))
      43             : #define DIM(v)               (sizeof(v)/sizeof((v)[0]))
      44             : #define DIMof(type,member)   DIM(((type *)0)->member)
      45             : 
      46             : static int verbose;
      47             : static int die_on_error;
      48             : static int error_count;
      49             : 
      50             : 
      51             : static void
      52           0 : info (const char *format, ...)
      53             : {
      54             :   va_list arg_ptr;
      55             : 
      56           0 :   va_start (arg_ptr, format);
      57           0 :   vfprintf (stderr, format, arg_ptr);
      58           0 :   va_end (arg_ptr);
      59           0 : }
      60             : 
      61             : static void
      62           0 : fail (const char *format, ...)
      63             : {
      64             :   va_list arg_ptr;
      65             : 
      66           0 :   va_start (arg_ptr, format);
      67           0 :   vfprintf (stderr, format, arg_ptr);
      68           0 :   va_end (arg_ptr);
      69           0 :   error_count++;
      70           0 :   if (die_on_error)
      71           0 :     exit (1);
      72           0 : }
      73             : 
      74             : static void
      75           0 : die (const char *format, ...)
      76             : {
      77             :   va_list arg_ptr;
      78             : 
      79           0 :   va_start (arg_ptr, format);
      80           0 :   vfprintf (stderr, format, arg_ptr);
      81           0 :   va_end (arg_ptr);
      82           0 :   exit (1);
      83             : }
      84             : 
      85             : static void
      86           0 : show_sexp (const char *prefix, gcry_sexp_t a)
      87             : {
      88             :   char *buf;
      89             :   size_t size;
      90             : 
      91           0 :   if (prefix)
      92           0 :     fputs (prefix, stderr);
      93           0 :   size = gcry_sexp_sprint (a, GCRYSEXP_FMT_ADVANCED, NULL, 0);
      94           0 :   buf = gcry_xmalloc (size);
      95             : 
      96           0 :   gcry_sexp_sprint (a, GCRYSEXP_FMT_ADVANCED, buf, size);
      97           0 :   fprintf (stderr, "%.*s", (int)size, buf);
      98           0 :   gcry_free (buf);
      99           0 : }
     100             : 
     101             : 
     102             : /* Convert STRING consisting of hex characters into its binary
     103             :    representation and return it as an allocated buffer. The valid
     104             :    length of the buffer is returned at R_LENGTH.  The string is
     105             :    delimited by end of string.  The function returns NULL on
     106             :    error.  */
     107             : static void *
     108        3510 : data_from_hex (const char *string, size_t *r_length)
     109             : {
     110             :   const char *s;
     111             :   unsigned char *buffer;
     112             :   size_t length;
     113             : 
     114        3510 :   buffer = gcry_xmalloc (strlen(string)/2+1);
     115        3510 :   length = 0;
     116      360019 :   for (s=string; *s; s +=2 )
     117             :     {
     118      356509 :       if (!hexdigitp (s) || !hexdigitp (s+1))
     119           0 :         die ("error parsing hex string `%s'\n", string);
     120      356509 :       ((unsigned char*)buffer)[length++] = xtoi_2 (s);
     121             :     }
     122        3510 :   *r_length = length;
     123        3510 :   return buffer;
     124             : }
     125             : 
     126             : 
     127             : static int
     128        1080 : extract_cmp_data (gcry_sexp_t sexp, const char *name, const char *expected,
     129             :                   const char *description)
     130             : {
     131             :   gcry_sexp_t l1;
     132             :   const void *a;
     133             :   size_t alen;
     134             :   void *b;
     135             :   size_t blen;
     136        1080 :   int rc = 0;
     137             : 
     138        1080 :   l1 = gcry_sexp_find_token (sexp, name, 0);
     139        1080 :   a = gcry_sexp_nth_data (l1, 1, &alen);
     140        1080 :   b = data_from_hex (expected, &blen);
     141        1080 :   if (!a)
     142             :     {
     143           0 :       info ("%s: parameter \"%s\" missing in key\n", description, name);
     144           0 :       rc = 1;
     145             :     }
     146        1080 :   else if ( alen != blen || memcmp (a, b, alen) )
     147             :     {
     148           0 :       info ("%s: parameter \"%s\" does not match expected value\n",
     149             :             description, name);
     150           0 :       rc = 1;
     151             :     }
     152        1080 :   gcry_free (b);
     153        1080 :   gcry_sexp_release (l1);
     154        1080 :   return rc;
     155             : }
     156             : 
     157             : 
     158             : /* Check against the OAEP test vectors from
     159             :    ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-1/pkcs-1v2-1d2-vec.zip .  */
     160             : static void
     161           1 : check_oaep (void)
     162             : {
     163             : #include "pkcs1v2-oaep.h"
     164             :   gpg_error_t err;
     165             :   int tno, mno;
     166             : 
     167          11 :   for (tno = 0; tno < DIM (tbl); tno++)
     168             :     {
     169             :       void *rsa_n, *rsa_e, *rsa_d;
     170             :       size_t rsa_n_len, rsa_e_len, rsa_d_len;
     171             :       gcry_sexp_t sec_key, pub_key;
     172             : 
     173          10 :       if (verbose > 1)
     174           0 :         info ("(%s)\n", tbl[tno].desc);
     175             : 
     176          10 :       rsa_n = data_from_hex (tbl[tno].n, &rsa_n_len);
     177          10 :       rsa_e = data_from_hex (tbl[tno].e, &rsa_e_len);
     178          10 :       rsa_d = data_from_hex (tbl[tno].d, &rsa_d_len);
     179          10 :       err = gcry_sexp_build (&sec_key, NULL,
     180             :                              "(private-key (rsa (n %b)(e %b)(d %b)))",
     181             :                              (int)rsa_n_len, rsa_n,
     182             :                              (int)rsa_e_len, rsa_e,
     183             :                              (int)rsa_d_len, rsa_d);
     184          10 :       if (err)
     185           0 :         die ("constructing private key failed: %s\n", gpg_strerror (err));
     186          10 :       err = gcry_sexp_build (&pub_key, NULL,
     187             :                              "(public-key (rsa (n %b)(e %b)))",
     188             :                              (int)rsa_n_len, rsa_n,
     189             :                              (int)rsa_e_len, rsa_e);
     190          10 :       if (err)
     191           0 :         die ("constructing public key failed: %s\n", gpg_strerror (err));
     192          10 :       gcry_free (rsa_n);
     193          10 :       gcry_free (rsa_e);
     194          10 :       gcry_free (rsa_d);
     195             : 
     196          70 :       for (mno = 0; mno < DIM (tbl[0].m); mno++)
     197             :         {
     198             :           void *mesg, *seed, *encr;
     199             :           size_t mesg_len, seed_len, encr_len;
     200             :           gcry_sexp_t plain, ciph;
     201             : 
     202          60 :           if (verbose)
     203           0 :             info ("running test: %s\n", tbl[tno].m[mno].desc);
     204             : 
     205          60 :           mesg = data_from_hex (tbl[tno].m[mno].mesg, &mesg_len);
     206          60 :           seed = data_from_hex (tbl[tno].m[mno].seed, &seed_len);
     207             : 
     208          60 :           err = gcry_sexp_build (&plain, NULL,
     209             :                                  "(data (flags oaep)(hash-algo sha1)"
     210             :                                  "(value %b)(random-override %b))",
     211             :                                  (int)mesg_len, mesg,
     212             :                                  (int)seed_len, seed);
     213          60 :           if (err)
     214           0 :             die ("constructing plain data failed: %s\n", gpg_strerror (err));
     215          60 :           gcry_free (mesg);
     216          60 :           gcry_free (seed);
     217             : 
     218          60 :           err = gcry_pk_encrypt (&ciph, plain, pub_key);
     219          60 :           if (err)
     220             :             {
     221           0 :               show_sexp ("plain:\n", ciph);
     222           0 :               fail ("gcry_pk_encrypt failed: %s\n", gpg_strerror (err));
     223             :             }
     224             :           else
     225             :             {
     226          60 :               if (extract_cmp_data (ciph, "a", tbl[tno].m[mno].encr,
     227             :                                     tbl[tno].m[mno].desc))
     228             :                 {
     229           0 :                   show_sexp ("encrypt result:\n", ciph);
     230           0 :                   fail ("mismatch in gcry_pk_encrypt\n");
     231             :                 }
     232          60 :               gcry_sexp_release (ciph);
     233          60 :               ciph = NULL;
     234             :             }
     235          60 :           gcry_sexp_release (plain);
     236          60 :           plain = NULL;
     237             : 
     238             :           /* Now test the decryption.  */
     239          60 :           seed = data_from_hex (tbl[tno].m[mno].seed, &seed_len);
     240          60 :           encr = data_from_hex (tbl[tno].m[mno].encr, &encr_len);
     241             : 
     242          60 :           err = gcry_sexp_build (&ciph, NULL,
     243             :                                  "(enc-val (flags oaep)(hash-algo sha1)"
     244             :                                  "(random-override %b)"
     245             :                                  "(rsa (a %b)))",
     246             :                                  (int)seed_len, seed,
     247             :                                  (int)encr_len, encr);
     248          60 :           if (err)
     249           0 :             die ("constructing cipher data failed: %s\n", gpg_strerror (err));
     250          60 :           gcry_free (encr);
     251          60 :           gcry_free (seed);
     252             : 
     253          60 :           err = gcry_pk_decrypt (&plain, ciph, sec_key);
     254          60 :           if (err)
     255             :             {
     256           0 :               show_sexp ("ciph:\n", ciph);
     257           0 :               fail ("gcry_pk_decrypt failed: %s\n", gpg_strerror (err));
     258             :             }
     259             :           else
     260             :             {
     261          60 :               if (extract_cmp_data (plain, "value", tbl[tno].m[mno].mesg,
     262             :                                     tbl[tno].m[mno].desc))
     263             :                 {
     264           0 :                   show_sexp ("decrypt result:\n", plain);
     265           0 :                   fail ("mismatch in gcry_pk_decrypt\n");
     266             :                 }
     267          60 :               gcry_sexp_release (plain);
     268          60 :               plain = NULL;
     269             :             }
     270          60 :           gcry_sexp_release (ciph);
     271          60 :           ciph = NULL;
     272             :         }
     273             : 
     274          10 :       gcry_sexp_release (sec_key);
     275          10 :       gcry_sexp_release (pub_key);
     276             :     }
     277           1 : }
     278             : 
     279             : 
     280             : /* Check against the PSS test vectors from
     281             :    ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-1/pkcs-1v2-1d2-vec.zip .  */
     282             : static void
     283           1 : check_pss (void)
     284             : {
     285             : #include "pkcs1v2-pss.h"
     286             :   gpg_error_t err;
     287             :   int tno, mno;
     288             : 
     289          11 :   for (tno = 0; tno < DIM (tbl); tno++)
     290             :     {
     291             :       void *rsa_n, *rsa_e, *rsa_d;
     292             :       size_t rsa_n_len, rsa_e_len, rsa_d_len;
     293             :       gcry_sexp_t sec_key, pub_key;
     294             : 
     295          10 :       if (verbose > 1)
     296           0 :         info ("(%s)\n", tbl[tno].desc);
     297             : 
     298          10 :       rsa_n = data_from_hex (tbl[tno].n, &rsa_n_len);
     299          10 :       rsa_e = data_from_hex (tbl[tno].e, &rsa_e_len);
     300          10 :       rsa_d = data_from_hex (tbl[tno].d, &rsa_d_len);
     301          10 :       err = gcry_sexp_build (&sec_key, NULL,
     302             :                              "(private-key (rsa (n %b)(e %b)(d %b)))",
     303             :                              (int)rsa_n_len, rsa_n,
     304             :                              (int)rsa_e_len, rsa_e,
     305             :                              (int)rsa_d_len, rsa_d);
     306          10 :       if (err)
     307           0 :         die ("constructing private key failed: %s\n", gpg_strerror (err));
     308          10 :       err = gcry_sexp_build (&pub_key, NULL,
     309             :                              "(public-key (rsa (n %b)(e %b)))",
     310             :                              (int)rsa_n_len, rsa_n,
     311             :                              (int)rsa_e_len, rsa_e);
     312          10 :       if (err)
     313           0 :         die ("constructing public key failed: %s\n", gpg_strerror (err));
     314          10 :       gcry_free (rsa_n);
     315          10 :       gcry_free (rsa_e);
     316          10 :       gcry_free (rsa_d);
     317             : 
     318          70 :       for (mno = 0; mno < DIM (tbl[0].m); mno++)
     319             :         {
     320             :           void *mesg, *salt, *sign;
     321             :           size_t mesg_len, salt_len, sign_len;
     322             :           gcry_sexp_t sigtmpl, sig;
     323             :           char mhash[20];
     324             : 
     325          60 :           if (verbose)
     326           0 :             info ("running test: %s\n", tbl[tno].m[mno].desc);
     327             : 
     328          60 :           mesg = data_from_hex (tbl[tno].m[mno].mesg, &mesg_len);
     329          60 :           salt = data_from_hex (tbl[tno].m[mno].salt, &salt_len);
     330             : 
     331          60 :           gcry_md_hash_buffer (GCRY_MD_SHA1, mhash, mesg, mesg_len);
     332          60 :           err = gcry_sexp_build (&sigtmpl, NULL,
     333             :                                  "(data (flags pss)"
     334             :                                  "(hash sha1 %b)"
     335             :                                  "(random-override %b))",
     336             :                                  20, mhash,
     337             :                                  (int)salt_len, salt);
     338          60 :           if (err)
     339           0 :             die ("constructing sig template failed: %s\n", gpg_strerror (err));
     340          60 :           gcry_free (mesg);
     341          60 :           gcry_free (salt);
     342             : 
     343          60 :           err = gcry_pk_sign (&sig, sigtmpl, sec_key);
     344          60 :           if (err)
     345             :             {
     346           0 :               show_sexp ("sigtmpl:\n", sigtmpl);
     347           0 :               fail ("gcry_pk_sign failed: %s\n", gpg_strerror (err));
     348             :             }
     349             :           else
     350             :             {
     351          60 :               if (extract_cmp_data (sig, "s", tbl[tno].m[mno].sign,
     352             :                                     tbl[tno].m[mno].desc))
     353             :                 {
     354           0 :                   show_sexp ("sign result:\n", sig);
     355           0 :                   fail ("mismatch in gcry_pk_sign\n");
     356             :                 }
     357          60 :               gcry_sexp_release (sig);
     358          60 :               sig = NULL;
     359             :             }
     360          60 :           gcry_sexp_release (sigtmpl);
     361          60 :           sigtmpl = NULL;
     362             : 
     363             :           /* Now test the verification.  */
     364          60 :           salt = data_from_hex (tbl[tno].m[mno].salt, &salt_len);
     365          60 :           sign = data_from_hex (tbl[tno].m[mno].sign, &sign_len);
     366             : 
     367          60 :           err = gcry_sexp_build (&sig, NULL,
     368             :                                  "(sig-val(rsa(s %b)))",
     369             :                                  (int)sign_len, sign);
     370          60 :           if (err)
     371           0 :             die ("constructing verify data failed: %s\n", gpg_strerror (err));
     372          60 :           err = gcry_sexp_build (&sigtmpl, NULL,
     373             :                                  "(data (flags pss)"
     374             :                                  "(hash sha1 %b)"
     375             :                                  "(random-override %b))",
     376             :                                  20, mhash,
     377             :                                  (int)salt_len, salt);
     378          60 :           if (err)
     379           0 :             die ("constructing verify tmpl failed: %s\n", gpg_strerror (err));
     380          60 :           gcry_free (sign);
     381          60 :           gcry_free (salt);
     382             : 
     383          60 :           err = gcry_pk_verify (sig, sigtmpl, pub_key);
     384          60 :           if (err)
     385             :             {
     386           0 :               show_sexp ("sig:\n", sig);
     387           0 :               show_sexp ("sigtmpl:\n", sigtmpl);
     388           0 :               fail ("gcry_pk_verify failed: %s\n", gpg_strerror (err));
     389             :             }
     390          60 :           gcry_sexp_release (sig);
     391          60 :           sig = NULL;
     392          60 :           gcry_sexp_release (sigtmpl);
     393          60 :           sigtmpl = NULL;
     394             :         }
     395             : 
     396          10 :       gcry_sexp_release (sec_key);
     397          10 :       gcry_sexp_release (pub_key);
     398             :     }
     399           1 : }
     400             : 
     401             : 
     402             : /* Check against PKCS#1 v1.5 encryption test  vectors as found at
     403             :    ftp://ftp.rsa.com/pub/rsalabs/tmp/pkcs1v15crypt-vectors.txt .  */
     404             : static void
     405           1 : check_v15crypt (void)
     406             : {
     407             : #include "pkcs1v2-v15c.h"
     408             :   gpg_error_t err;
     409             :   int tno, mno;
     410             : 
     411          16 :   for (tno = 0; tno < DIM (tbl); tno++)
     412             :     {
     413             :       void *rsa_n, *rsa_e, *rsa_d;
     414             :       size_t rsa_n_len, rsa_e_len, rsa_d_len;
     415             :       gcry_sexp_t sec_key, pub_key;
     416             : 
     417          15 :       if (verbose > 1)
     418           0 :         info ("(%s)\n", tbl[tno].desc);
     419             : 
     420          15 :       rsa_n = data_from_hex (tbl[tno].n, &rsa_n_len);
     421          15 :       rsa_e = data_from_hex (tbl[tno].e, &rsa_e_len);
     422          15 :       rsa_d = data_from_hex (tbl[tno].d, &rsa_d_len);
     423          15 :       err = gcry_sexp_build (&sec_key, NULL,
     424             :                              "(private-key (rsa (n %b)(e %b)(d %b)))",
     425             :                              (int)rsa_n_len, rsa_n,
     426             :                              (int)rsa_e_len, rsa_e,
     427             :                              (int)rsa_d_len, rsa_d);
     428          15 :       if (err)
     429           0 :         die ("constructing private key failed: %s\n", gpg_strerror (err));
     430          15 :       err = gcry_sexp_build (&pub_key, NULL,
     431             :                              "(public-key (rsa (n %b)(e %b)))",
     432             :                              (int)rsa_n_len, rsa_n,
     433             :                              (int)rsa_e_len, rsa_e);
     434          15 :       if (err)
     435           0 :         die ("constructing public key failed: %s\n", gpg_strerror (err));
     436          15 :       gcry_free (rsa_n);
     437          15 :       gcry_free (rsa_e);
     438          15 :       gcry_free (rsa_d);
     439             : 
     440         315 :       for (mno = 0; mno < DIM (tbl[0].m); mno++)
     441             :         {
     442             :           void *mesg, *seed, *encr;
     443             :           size_t mesg_len, seed_len, encr_len;
     444             :           gcry_sexp_t plain, ciph;
     445             : 
     446         300 :           if (verbose)
     447           0 :             info ("running test: %s\n", tbl[tno].m[mno].desc);
     448             : 
     449         300 :           mesg = data_from_hex (tbl[tno].m[mno].mesg, &mesg_len);
     450         300 :           seed = data_from_hex (tbl[tno].m[mno].seed, &seed_len);
     451             : 
     452         300 :           err = gcry_sexp_build (&plain, NULL,
     453             :                                  "(data (flags pkcs1)(hash-algo sha1)"
     454             :                                  "(value %b)(random-override %b))",
     455             :                                  (int)mesg_len, mesg,
     456             :                                  (int)seed_len, seed);
     457         300 :           if (err)
     458           0 :             die ("constructing plain data failed: %s\n", gpg_strerror (err));
     459         300 :           gcry_free (mesg);
     460         300 :           gcry_free (seed);
     461             : 
     462         300 :           err = gcry_pk_encrypt (&ciph, plain, pub_key);
     463         300 :           if (err)
     464             :             {
     465           0 :               show_sexp ("plain:\n", ciph);
     466           0 :               fail ("gcry_pk_encrypt failed: %s\n", gpg_strerror (err));
     467             :             }
     468             :           else
     469             :             {
     470         300 :               if (extract_cmp_data (ciph, "a", tbl[tno].m[mno].encr,
     471             :                                     tbl[tno].m[mno].desc))
     472             :                 {
     473           0 :                   show_sexp ("encrypt result:\n", ciph);
     474           0 :                   fail ("mismatch in gcry_pk_encrypt\n");
     475             :                 }
     476         300 :               gcry_sexp_release (ciph);
     477         300 :               ciph = NULL;
     478             :             }
     479         300 :           gcry_sexp_release (plain);
     480         300 :           plain = NULL;
     481             : 
     482             :           /* Now test the decryption.  */
     483         300 :           seed = data_from_hex (tbl[tno].m[mno].seed, &seed_len);
     484         300 :           encr = data_from_hex (tbl[tno].m[mno].encr, &encr_len);
     485             : 
     486         300 :           err = gcry_sexp_build (&ciph, NULL,
     487             :                                  "(enc-val (flags pkcs1)(hash-algo sha1)"
     488             :                                  "(random-override %b)"
     489             :                                  "(rsa (a %b)))",
     490             :                                  (int)seed_len, seed,
     491             :                                  (int)encr_len, encr);
     492         300 :           if (err)
     493           0 :             die ("constructing cipher data failed: %s\n", gpg_strerror (err));
     494         300 :           gcry_free (encr);
     495         300 :           gcry_free (seed);
     496             : 
     497         300 :           err = gcry_pk_decrypt (&plain, ciph, sec_key);
     498         300 :           if (err)
     499             :             {
     500           0 :               show_sexp ("ciph:\n", ciph);
     501           0 :               fail ("gcry_pk_decrypt failed: %s\n", gpg_strerror (err));
     502             :             }
     503             :           else
     504             :             {
     505         300 :               if (extract_cmp_data (plain, "value", tbl[tno].m[mno].mesg,
     506             :                                     tbl[tno].m[mno].desc))
     507             :                 {
     508           0 :                   show_sexp ("decrypt result:\n", plain);
     509           0 :                   fail ("mismatch in gcry_pk_decrypt\n");
     510             :                 }
     511         300 :               gcry_sexp_release (plain);
     512         300 :               plain = NULL;
     513             :             }
     514         300 :           gcry_sexp_release (ciph);
     515         300 :           ciph = NULL;
     516             :         }
     517             : 
     518          15 :       gcry_sexp_release (sec_key);
     519          15 :       gcry_sexp_release (pub_key);
     520             :     }
     521           1 : }
     522             : 
     523             : 
     524             : /* Check against PKCS#1 v1.5 signature test vectors as found at
     525             :    ftp://ftp.rsa.com/pub/rsalabs/tmp/pkcs1v15sign-vectors.txt .  */
     526             : static void
     527           1 : check_v15sign (void)
     528             : {
     529             : #include "pkcs1v2-v15s.h"
     530             :   gpg_error_t err;
     531             :   int tno, mno;
     532             : 
     533          16 :   for (tno = 0; tno < DIM (tbl); tno++)
     534             :     {
     535             :       void *rsa_n, *rsa_e, *rsa_d;
     536             :       size_t rsa_n_len, rsa_e_len, rsa_d_len;
     537             :       gcry_sexp_t sec_key, pub_key;
     538             : 
     539          15 :       if (verbose > 1)
     540           0 :         info ("(%s)\n", tbl[tno].desc);
     541             : 
     542          15 :       rsa_n = data_from_hex (tbl[tno].n, &rsa_n_len);
     543          15 :       rsa_e = data_from_hex (tbl[tno].e, &rsa_e_len);
     544          15 :       rsa_d = data_from_hex (tbl[tno].d, &rsa_d_len);
     545          15 :       err = gcry_sexp_build (&sec_key, NULL,
     546             :                              "(private-key (rsa (n %b)(e %b)(d %b)))",
     547             :                              (int)rsa_n_len, rsa_n,
     548             :                              (int)rsa_e_len, rsa_e,
     549             :                              (int)rsa_d_len, rsa_d);
     550          15 :       if (err)
     551           0 :         die ("constructing private key failed: %s\n", gpg_strerror (err));
     552          15 :       err = gcry_sexp_build (&pub_key, NULL,
     553             :                              "(public-key (rsa (n %b)(e %b)))",
     554             :                              (int)rsa_n_len, rsa_n,
     555             :                              (int)rsa_e_len, rsa_e);
     556          15 :       if (err)
     557           0 :         die ("constructing public key failed: %s\n", gpg_strerror (err));
     558          15 :       gcry_free (rsa_n);
     559          15 :       gcry_free (rsa_e);
     560          15 :       gcry_free (rsa_d);
     561             : 
     562         315 :       for (mno = 0; mno < DIM (tbl[0].m); mno++)
     563             :         {
     564             :           void *mesg, *sign;
     565             :           size_t mesg_len, sign_len;
     566             :           gcry_sexp_t sigtmpl, sig;
     567             :           char mhash[20];
     568             : 
     569         300 :           if (verbose)
     570           0 :             info ("running test: %s\n", tbl[tno].m[mno].desc);
     571             : 
     572         300 :           mesg = data_from_hex (tbl[tno].m[mno].mesg, &mesg_len);
     573             : 
     574         300 :           gcry_md_hash_buffer (GCRY_MD_SHA1, mhash, mesg, mesg_len);
     575         300 :           err = gcry_sexp_build (&sigtmpl, NULL,
     576             :                                  "(data (flags pkcs1)"
     577             :                                  "(hash sha1 %b))",
     578             :                                  20, mhash);
     579         300 :           if (err)
     580           0 :             die ("constructing sig template failed: %s\n", gpg_strerror (err));
     581         300 :           gcry_free (mesg);
     582             : 
     583         300 :           err = gcry_pk_sign (&sig, sigtmpl, sec_key);
     584         300 :           if (err)
     585             :             {
     586           0 :               show_sexp ("sigtmpl:\n", sigtmpl);
     587           0 :               fail ("gcry_pk_sign failed: %s\n", gpg_strerror (err));
     588             :             }
     589             :           else
     590             :             {
     591         300 :               if (extract_cmp_data (sig, "s", tbl[tno].m[mno].sign,
     592             :                                     tbl[tno].m[mno].desc))
     593             :                 {
     594           0 :                   show_sexp ("sign result:\n", sig);
     595           0 :                   fail ("mismatch in gcry_pk_sign\n");
     596             :                 }
     597         300 :               gcry_sexp_release (sig);
     598         300 :               sig = NULL;
     599             :             }
     600         300 :           gcry_sexp_release (sigtmpl);
     601         300 :           sigtmpl = NULL;
     602             : 
     603             :           /* Now test the verification.  */
     604         300 :           sign = data_from_hex (tbl[tno].m[mno].sign, &sign_len);
     605             : 
     606         300 :           err = gcry_sexp_build (&sig, NULL,
     607             :                                  "(sig-val(rsa(s %b)))",
     608             :                                  (int)sign_len, sign);
     609         300 :           if (err)
     610           0 :             die ("constructing verify data failed: %s\n", gpg_strerror (err));
     611         300 :           err = gcry_sexp_build (&sigtmpl, NULL,
     612             :                                  "(data (flags pkcs1)"
     613             :                                  "(hash sha1 %b))",
     614             :                                  20, mhash);
     615         300 :           if (err)
     616           0 :             die ("constructing verify tmpl failed: %s\n", gpg_strerror (err));
     617         300 :           gcry_free (sign);
     618             : 
     619         300 :           err = gcry_pk_verify (sig, sigtmpl, pub_key);
     620         300 :           if (err)
     621             :             {
     622           0 :               show_sexp ("sig:\n", sig);
     623           0 :               show_sexp ("sigtmpl:\n", sigtmpl);
     624           0 :               fail ("gcry_pk_verify failed: %s\n", gpg_strerror (err));
     625             :             }
     626         300 :           gcry_sexp_release (sig);
     627         300 :           sig = NULL;
     628         300 :           gcry_sexp_release (sigtmpl);
     629         300 :           sigtmpl = NULL;
     630             :         }
     631             : 
     632          15 :       gcry_sexp_release (sec_key);
     633          15 :       gcry_sexp_release (pub_key);
     634             :     }
     635           1 : }
     636             : 
     637             : 
     638             : int
     639           1 : main (int argc, char **argv)
     640             : {
     641           1 :   int last_argc = -1;
     642           1 :   int debug = 0;
     643           1 :   int run_oaep = 0;
     644           1 :   int run_pss = 0;
     645           1 :   int run_v15c = 0;
     646           1 :   int run_v15s = 0;
     647             : 
     648           1 :   if (argc)
     649           1 :     { argc--; argv++; }
     650             : 
     651           2 :   while (argc && last_argc != argc )
     652             :     {
     653           0 :       last_argc = argc;
     654           0 :       if (!strcmp (*argv, "--"))
     655             :         {
     656           0 :           argc--; argv++;
     657           0 :           break;
     658             :         }
     659           0 :       else if (!strcmp (*argv, "--verbose"))
     660             :         {
     661           0 :           verbose++;
     662           0 :           argc--; argv++;
     663             :         }
     664           0 :       else if (!strcmp (*argv, "--debug"))
     665             :         {
     666           0 :           verbose = 2;
     667           0 :           debug = 1;
     668           0 :           argc--; argv++;
     669             :         }
     670           0 :       else if (!strcmp (*argv, "--die"))
     671             :         {
     672           0 :           die_on_error = 1;
     673           0 :           argc--; argv++;
     674             :         }
     675           0 :       else if (!strcmp (*argv, "--oaep"))
     676             :         {
     677           0 :           run_oaep = 1;
     678           0 :           argc--; argv++;
     679             :         }
     680           0 :       else if (!strcmp (*argv, "--pss"))
     681             :         {
     682           0 :           run_pss = 1;
     683           0 :           argc--; argv++;
     684             :         }
     685           0 :       else if (!strcmp (*argv, "--v15c"))
     686             :         {
     687           0 :           run_v15c = 1;
     688           0 :           argc--; argv++;
     689             :         }
     690           0 :       else if (!strcmp (*argv, "--v15s"))
     691             :         {
     692           0 :           run_v15s = 1;
     693           0 :           argc--; argv++;
     694             :         }
     695             :     }
     696             : 
     697           1 :   if (!run_oaep && !run_pss && !run_v15c && !run_v15s)
     698           1 :     run_oaep = run_pss = run_v15c = run_v15s = 1;
     699             : 
     700           1 :   gcry_control (GCRYCTL_SET_VERBOSITY, (int)verbose);
     701           1 :   gcry_control (GCRYCTL_DISABLE_SECMEM, 0);
     702           1 :   if (!gcry_check_version ("1.5.0"))
     703           0 :     die ("version mismatch\n");
     704           1 :   gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
     705           1 :   if (debug)
     706           0 :     gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1u, 0);
     707             :   /* No valuable keys are create, so we can speed up our RNG. */
     708           1 :   gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0);
     709             : 
     710           1 :   if (run_oaep)
     711           1 :     check_oaep ();
     712           1 :   if (run_pss)
     713           1 :     check_pss ();
     714           1 :   if (run_v15c)
     715           1 :     check_v15crypt ();
     716           1 :   if (run_v15s)
     717           1 :     check_v15sign ();
     718             : 
     719           1 :   if (verbose)
     720           0 :     fprintf (stderr, "\nAll tests completed.  Errors: %i\n", error_count);
     721             : 
     722           1 :   return error_count ? 1 : 0;
     723             : }

Generated by: LCOV version 1.11