Add X9.31 signature support, mainly for FIPS140. Add new option to rsautl and
authorDr. Stephen Henson <steve@openssl.org>
Sat, 28 May 2005 20:15:48 +0000 (20:15 +0000)
committerDr. Stephen Henson <steve@openssl.org>
Sat, 28 May 2005 20:15:48 +0000 (20:15 +0000)
include options to use X9.31 in tests.

apps/rsautl.c
crypto/rsa/Makefile
crypto/rsa/rsa.h
crypto/rsa/rsa_eay.c
crypto/rsa/rsa_err.c
crypto/rsa/rsa_x931.c [new file with mode: 0644]
fips/fipshashes.c
fips/rsa/fips_rsa_eay.c
fips/rsa/fips_rsastest.c
fips/rsa/fips_rsavtest.c

index 5db6fe7cd74ff9982fd5132554085c01dbf046dd..bdfbe31c14444c5cd298179c4825fcd835afc0fa 100644 (file)
@@ -3,7 +3,7 @@
  * project 2000.
  */
 /* ====================================================================
- * Copyright (c) 2000 The OpenSSL Project.  All rights reserved.
+ * Copyright (c) 2000-2005 The OpenSSL Project.  All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -147,6 +147,7 @@ int MAIN(int argc, char **argv)
                else if(!strcmp(*argv, "-oaep")) pad = RSA_PKCS1_OAEP_PADDING;
                else if(!strcmp(*argv, "-ssl")) pad = RSA_SSLV23_PADDING;
                else if(!strcmp(*argv, "-pkcs")) pad = RSA_PKCS1_PADDING;
+               else if(!strcmp(*argv, "-x931")) pad = RSA_X931_PADDING;
                else if(!strcmp(*argv, "-sign")) {
                        rsa_mode = RSA_SIGN;
                        need_priv = 1;
index f69e54771e979c71f6b19b2ba70051e61817b070..d0ba63c606a1e002bc11f0b19da2bc8a6be8c309 100644 (file)
@@ -24,10 +24,10 @@ APPS=
 LIB=$(TOP)/libcrypto.a
 LIBSRC= rsa_eay.c rsa_gen.c rsa_lib.c rsa_sign.c rsa_saos.c rsa_err.c \
        rsa_pk1.c rsa_ssl.c rsa_none.c rsa_oaep.c rsa_chk.c rsa_null.c \
-       rsa_pss.c rsa_asn1.c
+       rsa_pss.c rsa_x931.c rsa_asn1.c
 LIBOBJ= rsa_eay.o rsa_gen.o rsa_lib.o rsa_sign.o rsa_saos.o rsa_err.o \
        rsa_pk1.o rsa_ssl.o rsa_none.o rsa_oaep.o rsa_chk.o rsa_null.o \
-       rsa_pss.o rsa_asn1.o
+       rsa_pss.o rsa_x931.o rsa_asn1.o
 
 SRC= $(LIBSRC)
 
index cc7107b30e98de765bbb86331b952bdcf906484e..7e8d6d99a29877e81e6c262b0d27a17718f59243 100644 (file)
@@ -191,6 +191,7 @@ struct rsa_st
 #define RSA_SSLV23_PADDING     2
 #define RSA_NO_PADDING         3
 #define RSA_PKCS1_OAEP_PADDING 4
+#define RSA_X931_PADDING       5
 
 #define RSA_PKCS1_PADDING_SIZE 11
 
@@ -291,6 +292,11 @@ int RSA_padding_add_none(unsigned char *to,int tlen,
        const unsigned char *f,int fl);
 int RSA_padding_check_none(unsigned char *to,int tlen,
        const unsigned char *f,int fl,int rsa_len);
+int RSA_padding_add_X931(unsigned char *to,int tlen,
+       const unsigned char *f,int fl);
+int RSA_padding_check_X931(unsigned char *to,int tlen,
+       const unsigned char *f,int fl,int rsa_len);
+int RSA_X931_hash_id(int nid);
 
 int RSA_verify_PKCS1_PSS(RSA *rsa, const unsigned char *mHash,
                        const EVP_MD *Hash, const unsigned char *EM, int sLen);
@@ -330,11 +336,13 @@ void ERR_load_RSA_strings(void);
 #define RSA_F_RSA_PADDING_ADD_PKCS1_TYPE_1              108
 #define RSA_F_RSA_PADDING_ADD_PKCS1_TYPE_2              109
 #define RSA_F_RSA_PADDING_ADD_SSLV23                    110
+#define RSA_F_RSA_PADDING_ADD_X931                      127
 #define RSA_F_RSA_PADDING_CHECK_NONE                    111
 #define RSA_F_RSA_PADDING_CHECK_PKCS1_OAEP              122
 #define RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_1            112
 #define RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_2            113
 #define RSA_F_RSA_PADDING_CHECK_SSLV23                  114
+#define RSA_F_RSA_PADDING_CHECK_X931                    128
 #define RSA_F_RSA_PRINT                                         115
 #define RSA_F_RSA_PRINT_FP                              116
 #define RSA_F_RSA_SIGN                                  117
@@ -362,7 +370,10 @@ void ERR_load_RSA_strings(void);
 #define RSA_R_DMQ1_NOT_CONGRUENT_TO_D                   125
 #define RSA_R_D_E_NOT_CONGRUENT_TO_1                    123
 #define RSA_R_FIRST_OCTET_INVALID                       133
+#define RSA_R_INVALID_HEADER                            137
 #define RSA_R_INVALID_MESSAGE_LENGTH                    131
+#define RSA_R_INVALID_PADDING                           138
+#define RSA_R_INVALID_TRAILER                           139
 #define RSA_R_IQMP_NOT_INVERSE_OF_Q                     126
 #define RSA_R_KEY_SIZE_TOO_SMALL                        120
 #define RSA_R_LAST_OCTET_INVALID                        134
index ed2d0ad3741fc53c83a0e00a2946b0f619dbfdab..be4ac96ce334773c0173e261c0a5edb58fe262b2 100644 (file)
@@ -285,7 +285,7 @@ err:
 static int RSA_eay_private_encrypt(int flen, const unsigned char *from,
             unsigned char *to, RSA *rsa, int padding)
        {
-       BIGNUM f,ret;
+       BIGNUM f,ret, *res;
        int i,j,k,num=0,r= -1;
        unsigned char *buf=NULL;
        BN_CTX *ctx=NULL;
@@ -389,10 +389,21 @@ static int RSA_eay_private_encrypt(int flen, const unsigned char *from,
        if (blinding)
                if (!BN_BLINDING_invert(&ret, blinding, ctx)) goto err;
 
+       if (padding == RSA_X931_PADDING)
+               {
+               BN_sub(&f, rsa->n, &ret);
+               if (BN_cmp(&ret, &f))
+                       res = &f;
+               else
+                       res = &ret;
+               }
+       else
+               res = &ret;
+
        /* put in leading 0 bytes if the number is less than the
         * length of the modulus */
-       j=BN_num_bytes(&ret);
-       i=BN_bn2bin(&ret,&(to[num-j]));
+       j=BN_num_bytes(res);
+       i=BN_bn2bin(res,&(to[num-j]));
        for (k=0; k<(num-i); k++)
                to[k]=0;
 
@@ -606,6 +617,9 @@ static int RSA_eay_public_decrypt(int flen, const unsigned char *from,
        if (!rsa->meth->bn_mod_exp(&ret,&f,rsa->e,rsa->n,ctx,
                rsa->_method_mod_n)) goto err;
 
+       if ((padding == RSA_X931_PADDING) && ((ret.d[0] & 0xf) != 12))
+               BN_sub(&ret, rsa->n, &ret);
+
        p=buf;
        i=BN_bn2bin(&ret,p);
 
index 8cbbd05db3fc7576adcc53dca378280ee9e92c9b..5e8349dfcf91130245e12fb9f22378dc1aa648dd 100644 (file)
@@ -85,11 +85,13 @@ static ERR_STRING_DATA RSA_str_functs[]=
 {ERR_FUNC(RSA_F_RSA_PADDING_ADD_PKCS1_TYPE_1), "RSA_padding_add_PKCS1_type_1"},
 {ERR_FUNC(RSA_F_RSA_PADDING_ADD_PKCS1_TYPE_2), "RSA_padding_add_PKCS1_type_2"},
 {ERR_FUNC(RSA_F_RSA_PADDING_ADD_SSLV23),       "RSA_padding_add_SSLv23"},
+{ERR_FUNC(RSA_F_RSA_PADDING_ADD_X931), "RSA_padding_add_X931"},
 {ERR_FUNC(RSA_F_RSA_PADDING_CHECK_NONE),       "RSA_padding_check_none"},
 {ERR_FUNC(RSA_F_RSA_PADDING_CHECK_PKCS1_OAEP), "RSA_padding_check_PKCS1_OAEP"},
 {ERR_FUNC(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_1),       "RSA_padding_check_PKCS1_type_1"},
 {ERR_FUNC(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_2),       "RSA_padding_check_PKCS1_type_2"},
 {ERR_FUNC(RSA_F_RSA_PADDING_CHECK_SSLV23),     "RSA_padding_check_SSLv23"},
+{ERR_FUNC(RSA_F_RSA_PADDING_CHECK_X931),       "RSA_padding_check_X931"},
 {ERR_FUNC(RSA_F_RSA_PRINT),    "RSA_print"},
 {ERR_FUNC(RSA_F_RSA_PRINT_FP), "RSA_print_fp"},
 {ERR_FUNC(RSA_F_RSA_SIGN),     "RSA_sign"},
@@ -120,7 +122,10 @@ static ERR_STRING_DATA RSA_str_reasons[]=
 {ERR_REASON(RSA_R_DMQ1_NOT_CONGRUENT_TO_D),"dmq1 not congruent to d"},
 {ERR_REASON(RSA_R_D_E_NOT_CONGRUENT_TO_1),"d e not congruent to 1"},
 {ERR_REASON(RSA_R_FIRST_OCTET_INVALID)   ,"first octet invalid"},
+{ERR_REASON(RSA_R_INVALID_HEADER)        ,"invalid header"},
 {ERR_REASON(RSA_R_INVALID_MESSAGE_LENGTH),"invalid message length"},
+{ERR_REASON(RSA_R_INVALID_PADDING)       ,"invalid padding"},
+{ERR_REASON(RSA_R_INVALID_TRAILER)       ,"invalid trailer"},
 {ERR_REASON(RSA_R_IQMP_NOT_INVERSE_OF_Q) ,"iqmp not inverse of q"},
 {ERR_REASON(RSA_R_KEY_SIZE_TOO_SMALL)    ,"key size too small"},
 {ERR_REASON(RSA_R_LAST_OCTET_INVALID)    ,"last octet invalid"},
diff --git a/crypto/rsa/rsa_x931.c b/crypto/rsa/rsa_x931.c
new file mode 100644 (file)
index 0000000..ac3fde2
--- /dev/null
@@ -0,0 +1,175 @@
+/* rsa_x931.c */
+/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
+ * project 2005.
+ */
+/* ====================================================================
+ * Copyright (c) 2005 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/bn.h>
+#include <openssl/rsa.h>
+#include <openssl/rand.h>
+#include <openssl/objects.h>
+
+int RSA_padding_add_X931(unsigned char *to, int tlen,
+            const unsigned char *from, int flen)
+       {
+       int j;
+       unsigned char *p;
+
+       /* Absolute minimum amount of padding is 1 header nibble, 1 padding
+        * nibble and 2 trailer bytes: but 1 hash if is already in 'from'.
+        */
+
+       j = tlen - flen - 2;
+
+       if (j < 0)
+               {
+               RSAerr(RSA_F_RSA_PADDING_ADD_X931,RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE);
+               return -1;
+               }
+       
+       p=(unsigned char *)to;
+
+       /* If no padding start and end nibbles are in one byte */
+       if (j == 0)
+               *p++ = 0x6A;
+       else
+               {
+               *p++ = 0x6B;
+               if (j > 1)
+                       {
+                       memset(p, 0xBB, j - 1);
+                       p += j - 1;
+                       }
+               *p++ = 0xBA;
+               }
+       memcpy(p,from,(unsigned int)flen);
+       p += flen;
+       *p = 0xCC;
+       return(1);
+       }
+
+int RSA_padding_check_X931(unsigned char *to, int tlen,
+            const unsigned char *from, int flen, int num)
+       {
+       int i,j;
+       const unsigned char *p;
+
+       p=from;
+       if ((num != flen) || ((*p != 0x6A) && (*p != 0x6B)))
+               {
+               RSAerr(RSA_F_RSA_PADDING_CHECK_X931,RSA_R_INVALID_HEADER);
+               return -1;
+               }
+
+       j=flen-3;
+       if (*p++ == 0x6B)
+               {
+               for (i = 0; i < j; i++)
+                       {
+                       unsigned char c = *p++;
+                       if (c == 0xBA)
+                               break;
+                       if (c != 0xBB)
+                               {
+                               RSAerr(RSA_F_RSA_PADDING_CHECK_X931,
+                                       RSA_R_INVALID_PADDING);
+                               return -1;
+                               }
+                       }
+               }
+
+       j -= i;
+
+       if (i == 0)
+               {
+               RSAerr(RSA_F_RSA_PADDING_CHECK_X931, RSA_R_INVALID_PADDING);
+               return -1;
+               }
+
+       if (p[j] != 0xCC)
+               {
+               RSAerr(RSA_F_RSA_PADDING_CHECK_X931, RSA_R_INVALID_TRAILER);
+               return -1;
+               }
+
+       memcpy(to,p,(unsigned int)j);
+
+       return(j);
+       }
+
+/* Translate between X931 hash ids and NIDs */
+
+int RSA_X931_hash_id(int nid)
+       {
+       switch (nid)
+               {
+               case NID_sha1:
+               return 0x33;
+
+               case NID_sha256:
+               return 0x34;
+
+               case NID_sha384:
+               return 0x36;
+
+               case NID_sha512:
+               return 0x35;
+
+               }
+       return -1;
+       }
+
index cfe6cb7737714860cd3ffa6140b8a3ccc8c8badb..388ca9a60677d6822dcba8d6a12014851517f931 100644 (file)
@@ -21,7 +21,7 @@ const char * const FIPS_source_hashes[] = {
 "HMAC-SHA1(rand/fips_rand.c)= 7e3964447a81cfe4e75df981827d14a5fe0c2923",
 "HMAC-SHA1(rand/fips_rand.h)= bf009ea8963e79b1e414442ede9ae7010a03160b",
 "HMAC-SHA1(rand/fips_rand_selftest.c)= d9c8985e08feecefafe667ad0119d444b42f807c",
-"HMAC-SHA1(rsa/fips_rsa_eay.c)= cab2bd6ef3486dda631be44712ace391b534ad36",
+"HMAC-SHA1(rsa/fips_rsa_eay.c)= 2512f849a220daa083f346b10effdb2ee96d4395",
 "HMAC-SHA1(rsa/fips_rsa_gen.c)= af83b857d2be13d59e7f1516e6b1a25edd6369c3",
 "HMAC-SHA1(rsa/fips_rsa_selftest.c)= a9dc47bd1001f795d1565111d26433c300101e06",
 "HMAC-SHA1(sha/fips_sha1dgst.c)= 26e529d630b5e754b4a29bd1bb697e991e7fdc04",
index 9731464fa9ba564a50bb2faed91ecc265016b843..2d0d973f1ea7b30d99cf42abb6b857fca6387fa6 100644 (file)
@@ -293,7 +293,7 @@ err:
 static int RSA_eay_private_encrypt(FIPS_RSA_SIZE_T flen, const unsigned char *from,
             unsigned char *to, RSA *rsa, int padding)
        {
-       BIGNUM f,ret;
+       BIGNUM f,ret, *res;
        int i,j,k,num=0,r= -1;
        unsigned char *buf=NULL;
        BN_CTX *ctx=NULL;
@@ -319,6 +319,9 @@ static int RSA_eay_private_encrypt(FIPS_RSA_SIZE_T flen, const unsigned char *fr
        case RSA_NO_PADDING:
                i=RSA_padding_add_none(buf,num,from,flen);
                break;
+       case RSA_X931_PADDING:
+               i=RSA_padding_add_X931(buf,num,from,flen);
+               break;
        case RSA_SSLV23_PADDING:
        default:
                RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT,RSA_R_UNKNOWN_PADDING_TYPE);
@@ -397,10 +400,21 @@ static int RSA_eay_private_encrypt(FIPS_RSA_SIZE_T flen, const unsigned char *fr
        if (blinding)
                if (!BN_BLINDING_invert(&ret, blinding, ctx)) goto err;
 
+       if (padding == RSA_X931_PADDING)
+               {
+               BN_sub(&f, rsa->n, &ret);
+               if (BN_cmp(&ret, &f))
+                       res = &f;
+               else
+                       res = &ret;
+               }
+       else
+               res = &ret;
+
        /* put in leading 0 bytes if the number is less than the
         * length of the modulus */
-       j=BN_num_bytes(&ret);
-       i=BN_bn2bin(&ret,&(to[num-j]));
+       j=BN_num_bytes(res);
+       i=BN_bn2bin(res,&(to[num-j]));
        for (k=0; k<(num-i); k++)
                to[k]=0;
 
@@ -614,6 +628,9 @@ static int RSA_eay_public_decrypt(FIPS_RSA_SIZE_T flen, const unsigned char *fro
        if (!rsa->meth->bn_mod_exp(&ret,&f,rsa->e,rsa->n,ctx,
                rsa->_method_mod_n)) goto err;
 
+       if ((padding == RSA_X931_PADDING) && ((ret.d[0] & 0xf) != 12))
+               BN_sub(&ret, rsa->n, &ret);
+
        p=buf;
        i=BN_bn2bin(&ret,p);
 
@@ -622,6 +639,9 @@ static int RSA_eay_public_decrypt(FIPS_RSA_SIZE_T flen, const unsigned char *fro
        case RSA_PKCS1_PADDING:
                r=RSA_padding_check_PKCS1_type_1(to,num,buf,i,num);
                break;
+       case RSA_X931_PADDING:
+               r=RSA_padding_check_X931(to,num,buf,i,num);
+               break;
        case RSA_NO_PADDING:
                r=RSA_padding_check_none(to,num,buf,i,num);
                break;
index 4cd20349465f02b44188b61c5bb825790d77272f..7c5fa9c5988577076074a63dc4b24142110c9f59 100644 (file)
@@ -111,6 +111,12 @@ int main(int argc, char **argv)
                argc -= 2;
                argv += 2;
                }
+       else if ((argc > 1) && !strcmp("-x931", argv[1]))
+               {
+               Saltlen = -2;
+               argc--;
+               argv++;
+               }
 
        if (argc == 1)
                in = BIO_new_fp(stdin, BIO_NOCLOSE);
@@ -318,7 +324,7 @@ static int rsa_printsig(BIO *err, BIO *out, RSA *rsa, const EVP_MD *dgst,
        {
        int ret = 0;
        unsigned char *sigbuf = NULL;
-       unsigned int i, siglen;
+       int i, siglen;
        /* EVP_PKEY structure */
        EVP_PKEY *key = NULL;
        EVP_MD_CTX ctx;
@@ -335,24 +341,36 @@ static int rsa_printsig(BIO *err, BIO *out, RSA *rsa, const EVP_MD *dgst,
 
        EVP_MD_CTX_init(&ctx);
 
-       if (Saltlen >= 0)
+       if (Saltlen != -1)
                {
-               unsigned char mdtmp[EVP_MAX_MD_SIZE];
+               unsigned int mdlen;
+               unsigned char mdtmp[EVP_MAX_MD_SIZE + 1];
 
                if (!EVP_DigestInit_ex(&ctx, dgst, NULL))
                        goto error;
                if (!EVP_DigestUpdate(&ctx, Msg, Msglen))
                        goto error;
-               if (!EVP_DigestFinal(&ctx, mdtmp, NULL))
+               if (!EVP_DigestFinal(&ctx, mdtmp, &mdlen))
                        goto error;
-
-               if (!RSA_padding_add_PKCS1_PSS(rsa, sigbuf, mdtmp,
+       
+               if (Saltlen == -2)
+                       {
+                       mdtmp[mdlen] = RSA_X931_hash_id(EVP_MD_type(dgst));
+                       siglen = RSA_private_encrypt(mdlen + 1, mdtmp,
+                                       sigbuf, rsa, RSA_X931_PADDING);
+                       if (siglen <= 0)
+                               goto error;
+                       }
+               else
+                       {
+                       if (!RSA_padding_add_PKCS1_PSS(rsa, sigbuf, mdtmp,
                                                        dgst, Saltlen))
-                       goto error;
-               siglen = RSA_private_encrypt(siglen, sigbuf, sigbuf, rsa,
-                                               RSA_NO_PADDING);
-               if (siglen <= 0)
-                       goto error;
+                               goto error;
+                       siglen = RSA_private_encrypt(siglen, sigbuf, sigbuf,
+                                               rsa, RSA_NO_PADDING);
+                       if (siglen <= 0)
+                               goto error;
+                       }
                }
        else
                {
@@ -360,7 +378,7 @@ static int rsa_printsig(BIO *err, BIO *out, RSA *rsa, const EVP_MD *dgst,
                        goto error;
                if (!EVP_SignUpdate(&ctx, Msg, Msglen))
                        goto error;
-               if (!EVP_SignFinal(&ctx, sigbuf, &siglen, key))
+               if (!EVP_SignFinal(&ctx, sigbuf, (unsigned int *)&siglen, key))
                        goto error;
                }
 
index 8ca07ed6cd1876eff98b76b39b3bc0038bc2a4e8..c5b8e20704b5d58e80028599d212af75835b27e8 100644 (file)
@@ -115,6 +115,12 @@ int main(int argc, char **argv)
                argc -= 2;
                argv += 2;
                }
+       else if ((argc > 1) && !strcmp("-x931", argv[1]))
+               {
+               Saltlen = -2;
+               argc--;
+               argv++;
+               }
 
        if (argc == 1)
                in = BIO_new_fp(stdin, BIO_NOCLOSE);
@@ -340,22 +346,42 @@ static int rsa_printver(BIO *err, BIO *out,
 
        EVP_MD_CTX_init(&ctx);
 
-       if (Saltlen >= 0)
+       if (Saltlen != -1)
                {
+               int pad;
                unsigned char mdtmp[EVP_MAX_MD_SIZE];
                buf = OPENSSL_malloc(RSA_size(rsa_pubkey));
+               if (Saltlen == -2)
+                       pad = RSA_X931_PADDING;
+               else
+                       pad = RSA_NO_PADDING;
                if (!buf)
                        goto error;
-               r = RSA_public_decrypt(Slen, S, buf, rsa_pubkey,
-                                                       RSA_NO_PADDING);
+               r = RSA_public_decrypt(Slen, S, buf, rsa_pubkey, pad);
+
                if (r > 0)
                        {
+                       unsigned int mdlen;
                        EVP_DigestInit_ex(&ctx, dgst, NULL);
                        if (!EVP_DigestUpdate(&ctx, Msg, Msglen))
                                goto error;
-                       if (!EVP_DigestFinal_ex(&ctx, mdtmp, NULL))
+                       if (!EVP_DigestFinal_ex(&ctx, mdtmp, &mdlen))
                                goto error;
-                       r = RSA_verify_PKCS1_PSS(rsa_pubkey, mdtmp, dgst,
+                       if (pad == RSA_X931_PADDING)
+                               {
+                               if (r != mdlen + 1)
+                                       r = 0;
+                               else if (buf[mdlen] !=
+                                   RSA_X931_hash_id(EVP_MD_type(dgst)))
+                                       r = 0;
+                               else if (memcmp(buf, mdtmp, mdlen))
+                                       r = 0;
+                               else
+                                       r = 1;
+                               }
+                       else
+                               r = RSA_verify_PKCS1_PSS(rsa_pubkey,
+                                                       mdtmp, dgst,
                                                        buf, Saltlen);
                        }
                if (r < 0)