Add X9.31 signature support, mainly for FIPS140. Add new option to rsautl and

include options to use X9.31 in tests.
This commit is contained in:
Dr. Stephen Henson 2005-05-28 20:15:48 +00:00
parent 570357b7a8
commit e4c2c550b9
10 changed files with 297 additions and 27 deletions

View 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;

View 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)

View 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

View 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);

View 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"},

175
crypto/rsa/rsa_x931.c Normal file
View File

@ -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;
}

View 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",

View 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;

View 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;
}

View 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)