Block low level public key signature operations in FIPS mode.

Update self tests for all modes and use EVP.

Update pairwise consistency checks.
This commit is contained in:
Dr. Stephen Henson 2007-04-06 00:30:24 +00:00
parent 1729dca9a8
commit a81f337331
24 changed files with 688 additions and 241 deletions

View file

@ -4,6 +4,15 @@
Changes between 0.9.8e and 0.9.8f-fips [xx XXX xxxx]
*) Rewrite self tests and pairwise tests to use EVP. Add more extensive
self tests for RSA in all digests and modes.
[Steve Henson]
*) New flags RSA_FIPS_METHOD and DSA_FIPS_METHOD to indicate a method is
allowed in FIPS mode. Disable direct low level RSA and DSA signature
operations in FIPS mode so all operations have to be made via EVP.
[Steve Henson]
*) New flag EVP_MD_FLAG_SVCTX which passes EVP_MD_CTX and key to underlying
sign/verify method. This permits the method to perform finalization
and signing itself and have access to the EVP_MD_CTX structure in case

View file

@ -101,6 +101,7 @@ int MAIN(int argc, char **argv)
EVP_PKEY *sigkey = NULL;
unsigned char *sigbuf = NULL;
int siglen = 0;
unsigned int sig_flags = 0;
char *passargin = NULL, *passin = NULL;
#ifndef OPENSSL_NO_ENGINE
char *engine=NULL;
@ -168,6 +169,27 @@ ERR_load_crypto_strings();
keyfile=*(++argv);
do_verify = 1;
}
else if (strcmp(*argv,"-x931") == 0)
sig_flags = EVP_MD_CTX_FLAG_PAD_X931;
else if (strcmp(*argv,"-pss_saltlen") == 0)
{
int saltlen;
if (--argc < 1) break;
saltlen=atoi(*(++argv));
if (saltlen == -1)
sig_flags = EVP_MD_CTX_FLAG_PSS_MREC;
else if (saltlen == -2)
sig_flags = EVP_MD_CTX_FLAG_PSS_MDLEN;
else if (saltlen < -2 || saltlen >= 0xFFFE)
{
BIO_printf(bio_err, "Invalid PSS salt length %d\n", saltlen);
goto end;
}
else
sig_flags = saltlen;
sig_flags <<= 16;
sig_flags |= EVP_MD_CTX_FLAG_PAD_PSS;
}
else if (strcmp(*argv,"-signature") == 0)
{
if (--argc < 1) break;
@ -360,6 +382,12 @@ ERR_load_crypto_strings();
EVP_MD_CTX_set_flags(md_ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
}
if (sig_flags)
{
EVP_MD_CTX *md_ctx;
BIO_get_md_ctx(bmd,&md_ctx);
EVP_MD_CTX_set_flags(md_ctx, sig_flags);
}
/* we use md as a filter, reading from 'in' */
if (!BIO_set_md(bmd,md))

View file

@ -97,12 +97,20 @@
* be used for all exponents.
*/
/* If this flag is set external DSA_METHOD callbacks are allowed in FIPS mode
* it is then the applications responsibility to ensure the external method
* is compliant.
/* If this flag is set the DSA method is FIPS compliant and can be used
* in FIPS mode. This is set in the validated module method. If an
* application sets this flag in its own methods it is its reposibility
* to ensure the result is compliant.
*/
#define DSA_FLAG_FIPS_EXTERNAL_METHOD_ALLOW 0x04
#define DSA_FLAG_FIPS_METHOD 0x0400
/* If this flag is set the operations normally disabled in FIPS mode are
* permitted it is then the applications responsibility to ensure that the
* usage is compliant.
*/
#define DSA_FLAG_NON_FIPS_ALLOW 0x0400
#ifdef OPENSSL_FIPS
#define FIPS_DSA_SIZE_T int
@ -287,6 +295,8 @@ void ERR_load_DSA_strings(void);
#define DSA_F_DSA_NEW_METHOD 103
#define DSA_F_DSA_PRINT 104
#define DSA_F_DSA_PRINT_FP 105
#define DSA_F_DSA_SET_DEFAULT_METHOD 115
#define DSA_F_DSA_SET_METHOD 116
#define DSA_F_DSA_SIGN 106
#define DSA_F_DSA_SIGN_SETUP 107
#define DSA_F_DSA_SIG_NEW 109
@ -299,6 +309,8 @@ void ERR_load_DSA_strings(void);
#define DSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE 100
#define DSA_R_MISSING_PARAMETERS 101
#define DSA_R_MODULUS_TOO_LARGE 103
#define DSA_R_NON_FIPS_METHOD 104
#define DSA_R_OPERATION_NOT_ALLOWED_IN_FIPS_MODE 105
#ifdef __cplusplus
}

View file

@ -61,6 +61,7 @@
#include <openssl/dsa.h>
#include <openssl/asn1.h>
#include <openssl/asn1t.h>
#include <openssl/fips.h>
/* Override the default new methods */
static int sig_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it)
@ -143,6 +144,13 @@ int DSA_sign(int type, const unsigned char *dgst, int dlen, unsigned char *sig,
unsigned int *siglen, DSA *dsa)
{
DSA_SIG *s;
#ifdef OPENSSL_FIPS
if(FIPS_mode() && !(dsa->flags & DSA_FLAG_NON_FIPS_ALLOW))
{
DSAerr(DSA_F_DSA_SIGN, DSA_R_OPERATION_NOT_ALLOWED_IN_FIPS_MODE);
return 0;
}
#endif
s=DSA_do_sign(dgst,dlen,dsa);
if (s == NULL)
{
@ -187,6 +195,13 @@ int DSA_verify(int type, const unsigned char *dgst, int dgst_len,
{
DSA_SIG *s;
int ret=-1;
#ifdef OPENSSL_FIPS
if(FIPS_mode() && !(dsa->flags & DSA_FLAG_NON_FIPS_ALLOW))
{
DSAerr(DSA_F_DSA_VERIFY, DSA_R_OPERATION_NOT_ALLOWED_IN_FIPS_MODE);
return 0;
}
#endif
s = DSA_SIG_new();
if (s == NULL) return(ret);

View file

@ -1,6 +1,6 @@
/* crypto/dsa/dsa_err.c */
/* ====================================================================
* Copyright (c) 1999-2005 The OpenSSL Project. All rights reserved.
* Copyright (c) 1999-2007 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
@ -78,6 +78,8 @@ static ERR_STRING_DATA DSA_str_functs[]=
{ERR_FUNC(DSA_F_DSA_NEW_METHOD), "DSA_new_method"},
{ERR_FUNC(DSA_F_DSA_PRINT), "DSA_print"},
{ERR_FUNC(DSA_F_DSA_PRINT_FP), "DSA_print_fp"},
{ERR_FUNC(DSA_F_DSA_SET_DEFAULT_METHOD), "DSA_set_default_method"},
{ERR_FUNC(DSA_F_DSA_SET_METHOD), "DSA_set_method"},
{ERR_FUNC(DSA_F_DSA_SIGN), "DSA_sign"},
{ERR_FUNC(DSA_F_DSA_SIGN_SETUP), "DSA_sign_setup"},
{ERR_FUNC(DSA_F_DSA_SIG_NEW), "DSA_SIG_new"},
@ -93,6 +95,8 @@ static ERR_STRING_DATA DSA_str_reasons[]=
{ERR_REASON(DSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE),"data too large for key size"},
{ERR_REASON(DSA_R_MISSING_PARAMETERS) ,"missing parameters"},
{ERR_REASON(DSA_R_MODULUS_TOO_LARGE) ,"modulus too large"},
{ERR_REASON(DSA_R_NON_FIPS_METHOD) ,"non fips method"},
{ERR_REASON(DSA_R_OPERATION_NOT_ALLOWED_IN_FIPS_MODE),"operation not allowed in fips mode"},
{0,NULL}
};

View file

@ -76,6 +76,14 @@ static const DSA_METHOD *default_DSA_method = NULL;
void DSA_set_default_method(const DSA_METHOD *meth)
{
#ifdef OPENSSL_FIPS
if (FIPS_mode() && !(meth->flags & DSA_FLAG_FIPS_METHOD))
{
DSAerr(DSA_F_DSA_SET_DEFAULT_METHOD, DSA_R_NON_FIPS_METHOD);
return;
}
#endif
default_DSA_method = meth;
}
@ -96,6 +104,13 @@ int DSA_set_method(DSA *dsa, const DSA_METHOD *meth)
/* NB: The caller is specifically setting a method, so it's not up to us
* to deal with which ENGINE it comes from. */
const DSA_METHOD *mtmp;
#ifdef OPENSSL_FIPS
if (FIPS_mode() && !(meth->flags & DSA_FLAG_FIPS_METHOD))
{
DSAerr(DSA_F_DSA_SET_METHOD, DSA_R_NON_FIPS_METHOD);
return 0;
}
#endif
mtmp = dsa->meth;
if (mtmp->finish) mtmp->finish(dsa);
#ifndef OPENSSL_NO_ENGINE
@ -147,6 +162,18 @@ DSA *DSA_new_method(ENGINE *engine)
}
}
#endif
#ifdef OPENSSL_FIPS
if (FIPS_mode() && !(ret->meth->flags & DSA_FLAG_FIPS_METHOD))
{
DSAerr(DSA_F_DSA_NEW_METHOD, DSA_R_NON_FIPS_METHOD);
#ifndef OPENSSL_NO_ENGINE
if (ret->engine)
ENGINE_finish(ret->engine);
#endif
OPENSSL_free(ret);
return NULL;
}
#endif
ret->pad=0;
ret->version=0;

View file

@ -69,9 +69,11 @@
DSA_SIG * DSA_do_sign(const unsigned char *dgst, int dlen, DSA *dsa)
{
#ifdef OPENSSL_FIPS
if(FIPS_mode() && !(dsa->flags & DSA_FLAG_FIPS_EXTERNAL_METHOD_ALLOW)
&& !FIPS_dsa_check(dsa))
if(FIPS_mode() && !(dsa->flags & DSA_FLAG_NON_FIPS_ALLOW))
{
DSAerr(DSA_F_DSA_DO_SIGN, DSA_R_OPERATION_NOT_ALLOWED_IN_FIPS_MODE);
return NULL;
}
#endif
return dsa->meth->dsa_do_sign(dgst, dlen, dsa);
}
@ -79,9 +81,11 @@ DSA_SIG * DSA_do_sign(const unsigned char *dgst, int dlen, DSA *dsa)
int DSA_sign_setup(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp)
{
#ifdef OPENSSL_FIPS
if(FIPS_mode() && !(dsa->flags & DSA_FLAG_FIPS_EXTERNAL_METHOD_ALLOW)
&& !FIPS_dsa_check(dsa))
if(FIPS_mode() && !(dsa->flags & DSA_FLAG_NON_FIPS_ALLOW))
{
DSAerr(DSA_F_DSA_SIGN_SETUP, DSA_R_OPERATION_NOT_ALLOWED_IN_FIPS_MODE);
return 0;
}
#endif
return dsa->meth->dsa_sign_setup(dsa, ctx_in, kinvp, rp);
}

View file

@ -71,9 +71,11 @@ int DSA_do_verify(const unsigned char *dgst, int dgst_len, DSA_SIG *sig,
DSA *dsa)
{
#ifdef OPENSSL_FIPS
if(FIPS_mode() && !(dsa->flags & DSA_FLAG_FIPS_EXTERNAL_METHOD_ALLOW)
&& !FIPS_dsa_check(dsa))
return -1;
if(FIPS_mode() && !(dsa->flags & DSA_FLAG_NON_FIPS_ALLOW))
{
DSAerr(DSA_F_DSA_DO_VERIFY, DSA_R_OPERATION_NOT_ALLOWED_IN_FIPS_MODE);
return 0;
}
#endif
return dsa->meth->dsa_do_verify(dgst, dgst_len, sig, dsa);
}

View file

@ -78,9 +78,11 @@ static ERR_STRING_DATA FIPS_str_functs[]=
{ERR_FUNC(FIPS_F_FIPS_CHECK_DSO), "FIPS_CHECK_DSO"},
{ERR_FUNC(FIPS_F_FIPS_CHECK_EXE), "FIPS_CHECK_EXE"},
{ERR_FUNC(FIPS_F_FIPS_CHECK_FINGERPRINT), "FIPS_CHECK_FINGERPRINT"},
{ERR_FUNC(FIPS_F_FIPS_CHECK_PK_SIG), "FIPS_CHECK_PK_SIG"},
{ERR_FUNC(FIPS_F_FIPS_CHECK_RSA), "FIPS_CHECK_RSA"},
{ERR_FUNC(FIPS_F_FIPS_DSA_CHECK), "FIPS_dsa_check"},
{ERR_FUNC(FIPS_F_FIPS_MODE_SET), "FIPS_mode_set"},
{ERR_FUNC(FIPS_F_FIPS_PKEY_SIGNATURE_TEST), "fips_pkey_signature_test"},
{ERR_FUNC(FIPS_F_FIPS_SELFTEST_AES), "FIPS_selftest_aes"},
{ERR_FUNC(FIPS_F_FIPS_SELFTEST_DES), "FIPS_selftest_des"},
{ERR_FUNC(FIPS_F_FIPS_SELFTEST_DSA), "FIPS_selftest_dsa"},
@ -113,6 +115,7 @@ static ERR_STRING_DATA FIPS_str_reasons[]=
{ERR_REASON(FIPS_R_RSA_DECRYPT_ERROR) ,"rsa decrypt error"},
{ERR_REASON(FIPS_R_RSA_ENCRYPT_ERROR) ,"rsa encrypt error"},
{ERR_REASON(FIPS_R_SELFTEST_FAILED) ,"selftest failed"},
{ERR_REASON(FIPS_R_TEST_FAILURE) ,"test failure"},
{ERR_REASON(FIPS_R_UNSUPPORTED_PLATFORM) ,"unsupported platform"},
{0,NULL}
};

View file

@ -74,6 +74,21 @@
#error RSA is disabled.
#endif
/* If this flag is set the RSA method is FIPS compliant and can be used
* in FIPS mode. This is set in the validated module method. If an
* application sets this flag in its own methods it is its reposibility
* to ensure the result is compliant.
*/
#define RSA_FLAG_FIPS_METHOD 0x0400
/* If this flag is set the operations normally disabled in FIPS mode are
* permitted it is then the applications responsibility to ensure that the
* usage is compliant.
*/
#define RSA_FLAG_NON_FIPS_ALLOW 0x0400
#ifdef OPENSSL_FIPS
#define FIPS_RSA_SIZE_T int
#endif
@ -420,7 +435,10 @@ void ERR_load_RSA_strings(void);
#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_PRIVATE_ENCRYPT 137
#define RSA_F_RSA_PUBLIC_DECRYPT 138
#define RSA_F_RSA_SETUP_BLINDING 136
#define RSA_F_RSA_SET_DEFAULT_METHOD 139
#define RSA_F_RSA_SIGN 117
#define RSA_F_RSA_SIGN_ASN1_OCTET_STRING 118
#define RSA_F_RSA_VERIFY 119
@ -454,10 +472,12 @@ void ERR_load_RSA_strings(void);
#define RSA_R_KEY_SIZE_TOO_SMALL 120
#define RSA_R_LAST_OCTET_INVALID 134
#define RSA_R_MODULUS_TOO_LARGE 105
#define RSA_R_NON_FIPS_METHOD 141
#define RSA_R_NO_PUBLIC_EXPONENT 140
#define RSA_R_NULL_BEFORE_BLOCK_MISSING 113
#define RSA_R_N_DOES_NOT_EQUAL_P_Q 127
#define RSA_R_OAEP_DECODING_ERROR 121
#define RSA_R_OPERATION_NOT_ALLOWED_IN_FIPS_MODE 142
#define RSA_R_PADDING_CHECK_FAILED 114
#define RSA_R_P_NOT_PRIME 128
#define RSA_R_Q_NOT_PRIME 129

View file

@ -80,6 +80,13 @@ RSA *RSA_new(void)
void RSA_set_default_method(const RSA_METHOD *meth)
{
#ifdef OPENSSL_FIPS
if (FIPS_mode() && !(meth->flags & RSA_FLAG_FIPS_METHOD))
{
RSAerr(RSA_F_RSA_SET_DEFAULT_METHOD, RSA_R_NON_FIPS_METHOD);
return;
}
#endif
default_RSA_meth = meth;
}
@ -111,6 +118,13 @@ int RSA_set_method(RSA *rsa, const RSA_METHOD *meth)
/* NB: The caller is specifically setting a method, so it's not up to us
* to deal with which ENGINE it comes from. */
const RSA_METHOD *mtmp;
#ifdef OPENSSL_FIPS
if (FIPS_mode() && !(meth->flags & RSA_FLAG_FIPS_METHOD))
{
RSAerr(RSA_F_RSA_SET_DEFAULT_METHOD, RSA_R_NON_FIPS_METHOD);
return 0;
}
#endif
mtmp = rsa->meth;
if (mtmp->finish) mtmp->finish(rsa);
#ifndef OPENSSL_NO_ENGINE
@ -163,6 +177,18 @@ RSA *RSA_new_method(ENGINE *engine)
}
}
#endif
#ifdef OPENSSL_FIPS
if (FIPS_mode() && !(ret->meth->flags & RSA_FLAG_FIPS_METHOD))
{
RSAerr(RSA_F_RSA_SET_DEFAULT_METHOD, RSA_R_NON_FIPS_METHOD);
#ifndef OPENSSL_NO_ENGINE
if (ret->engine)
ENGINE_finish(ret->engine);
#endif
OPENSSL_free(ret);
return NULL;
}
#endif
ret->pad=0;
ret->version=0;

View file

@ -1,6 +1,6 @@
/* crypto/rsa/rsa_err.c */
/* ====================================================================
* Copyright (c) 1999-2005 The OpenSSL Project. All rights reserved.
* Copyright (c) 1999-2007 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
@ -101,7 +101,10 @@ static ERR_STRING_DATA RSA_str_functs[]=
{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_PRIVATE_ENCRYPT), "RSA_private_encrypt"},
{ERR_FUNC(RSA_F_RSA_PUBLIC_DECRYPT), "RSA_public_decrypt"},
{ERR_FUNC(RSA_F_RSA_SETUP_BLINDING), "RSA_setup_blinding"},
{ERR_FUNC(RSA_F_RSA_SET_DEFAULT_METHOD), "RSA_set_default_method"},
{ERR_FUNC(RSA_F_RSA_SIGN), "RSA_sign"},
{ERR_FUNC(RSA_F_RSA_SIGN_ASN1_OCTET_STRING), "RSA_sign_ASN1_OCTET_STRING"},
{ERR_FUNC(RSA_F_RSA_VERIFY), "RSA_verify"},
@ -138,10 +141,12 @@ static ERR_STRING_DATA RSA_str_reasons[]=
{ERR_REASON(RSA_R_KEY_SIZE_TOO_SMALL) ,"key size too small"},
{ERR_REASON(RSA_R_LAST_OCTET_INVALID) ,"last octet invalid"},
{ERR_REASON(RSA_R_MODULUS_TOO_LARGE) ,"modulus too large"},
{ERR_REASON(RSA_R_NON_FIPS_METHOD) ,"non fips method"},
{ERR_REASON(RSA_R_NO_PUBLIC_EXPONENT) ,"no public exponent"},
{ERR_REASON(RSA_R_NULL_BEFORE_BLOCK_MISSING),"null before block missing"},
{ERR_REASON(RSA_R_N_DOES_NOT_EQUAL_P_Q) ,"n does not equal p q"},
{ERR_REASON(RSA_R_OAEP_DECODING_ERROR) ,"oaep decoding error"},
{ERR_REASON(RSA_R_OPERATION_NOT_ALLOWED_IN_FIPS_MODE),"operation not allowed in fips mode"},
{ERR_REASON(RSA_R_PADDING_CHECK_FAILED) ,"padding check failed"},
{ERR_REASON(RSA_R_P_NOT_PRIME) ,"p not prime"},
{ERR_REASON(RSA_R_Q_NOT_PRIME) ,"q not prime"},

View file

@ -76,6 +76,13 @@ int RSA_public_encrypt(int flen, const unsigned char *from, unsigned char *to,
int RSA_private_encrypt(int flen, const unsigned char *from, unsigned char *to,
RSA *rsa, int padding)
{
#ifdef OPENSSL_FIPS
if(FIPS_mode() && !(rsa->flags & RSA_FLAG_NON_FIPS_ALLOW))
{
RSAerr(RSA_F_RSA_PRIVATE_ENCRYPT, RSA_R_OPERATION_NOT_ALLOWED_IN_FIPS_MODE);
return 0;
}
#endif
return(rsa->meth->rsa_priv_enc(flen, from, to, rsa, padding));
}
@ -88,6 +95,13 @@ int RSA_private_decrypt(int flen, const unsigned char *from, unsigned char *to,
int RSA_public_decrypt(int flen, const unsigned char *from, unsigned char *to,
RSA *rsa, int padding)
{
#ifdef OPENSSL_FIPS
if(FIPS_mode() && !(rsa->flags & RSA_FLAG_NON_FIPS_ALLOW))
{
RSAerr(RSA_F_RSA_PUBLIC_DECRYPT, RSA_R_OPERATION_NOT_ALLOWED_IN_FIPS_MODE);
return 0;
}
#endif
return(rsa->meth->rsa_pub_dec(flen, from, to, rsa, padding));
}

View file

@ -90,6 +90,14 @@ int RSA_sign(int type, const unsigned char *m, unsigned int m_len,
i = SSL_SIG_LENGTH;
s = m;
} else {
/* NB: in FIPS mode block anything that isn't a TLS signature */
#ifdef OPENSSL_FIPS
if(FIPS_mode() && !(rsa->flags & RSA_FLAG_NON_FIPS_ALLOW))
{
RSAerr(RSA_F_RSA_SIGN, RSA_R_OPERATION_NOT_ALLOWED_IN_FIPS_MODE);
return 0;
}
#endif
sig.algor= &algor;
sig.algor->algorithm=OBJ_nid2obj(type);
if (sig.algor->algorithm == NULL)
@ -167,10 +175,22 @@ int RSA_verify(int dtype, const unsigned char *m, unsigned int m_len,
RSAerr(RSA_F_RSA_VERIFY,ERR_R_MALLOC_FAILURE);
goto err;
}
if((dtype == NID_md5_sha1) && (m_len != SSL_SIG_LENGTH) ) {
if(dtype == NID_md5_sha1)
{
if (m_len != SSL_SIG_LENGTH)
{
RSAerr(RSA_F_RSA_VERIFY,RSA_R_INVALID_MESSAGE_LENGTH);
goto err;
}
}
/* NB: in FIPS mode block anything that isn't a TLS signature */
#ifdef OPENSSL_FIPS
else if(FIPS_mode() && !(rsa->flags & RSA_FLAG_NON_FIPS_ALLOW))
{
RSAerr(RSA_F_RSA_VERIFY, RSA_R_OPERATION_NOT_ALLOWED_IN_FIPS_MODE);
return 0;
}
#endif
i=RSA_public_decrypt((int)siglen,sigbuf,s,rsa,RSA_PKCS1_PADDING);
if (i <= 0) goto err;

View file

@ -63,29 +63,24 @@
#include <openssl/dsa.h>
#include <openssl/rand.h>
#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/fips.h>
#ifdef OPENSSL_FIPS
static int dsa_builtin_keygen(DSA *dsa);
static int fips_check_dsa(DSA *dsa)
int fips_check_dsa(DSA *dsa)
{
static const unsigned char str1[]="12345678901234567890";
int r = 0;
DSA_SIG *sig;
EVP_PKEY pk;
unsigned char tbs[] = "DSA Pairwise Check Data";
pk.type = EVP_PKEY_DSA;
pk.pkey.dsa = dsa;
sig = DSA_do_sign(str1, 20, dsa);
if (sig)
if (!fips_pkey_signature_test(&pk, tbs, -1,
NULL, 0, EVP_dss1(), 0, NULL))
{
r = DSA_do_verify(str1, 20, sig, dsa);
DSA_SIG_free(sig);
}
if(r != 1)
{
FIPSerr(FIPS_F_FIPS_CHECK_DSA,FIPS_R_PAIRWISE_TEST_FAILED);
FIPSerr(FIPS_F_FIPS_CHECK_RSA,FIPS_R_PAIRWISE_TEST_FAILED);
return 0;
}
return 1;

View file

@ -92,10 +92,10 @@ dsa_mod_exp,
dsa_bn_mod_exp,
dsa_init,
dsa_finish,
0,
DSA_FLAG_FIPS_METHOD,
NULL
};
#if 0
int FIPS_dsa_check(struct dsa_st *dsa)
{
if(dsa->meth != &openssl_dsa_meth || dsa->meth->dsa_do_sign != dsa_do_sign
@ -110,6 +110,7 @@ int FIPS_dsa_check(struct dsa_st *dsa)
}
return 1;
}
#endif
const DSA_METHOD *DSA_OpenSSL(void)
{
@ -153,7 +154,7 @@ static DSA_SIG *dsa_do_sign(const unsigned char *dgst, FIPS_DSA_SIZE_T dlen, DSA
ctx=BN_CTX_new();
if (ctx == NULL) goto err;
if (!DSA_sign_setup(dsa,ctx,&kinv,&r)) goto err;
if (!dsa->meth->dsa_sign_setup(dsa,ctx,&kinv,&r)) goto err;
if (BN_bin2bn(dgst,dlen,&m) == NULL) goto err;

View file

@ -53,6 +53,7 @@
#include <openssl/err.h>
#include <openssl/bio.h>
#include <openssl/hmac.h>
#include <openssl/rsa.h>
#include <string.h>
#include <limits.h>
#include "fips_locl.h"
@ -381,4 +382,71 @@ unsigned char *fips_signature_witness(void)
return FIPS_signature;
}
/* Generalized public key test routine. Signs and verifies the data
* supplied in tbs using mesage digest md and setting option digest
* flags md_flags. If the 'kat' parameter is not NULL it will
* additionally check the signature matches it: a known answer test
* The string "fail_str" is used for identification purposes in case
* of failure.
*/
int fips_pkey_signature_test(EVP_PKEY *pkey,
const unsigned char *tbs, int tbslen,
const unsigned char *kat, unsigned int katlen,
const EVP_MD *digest, unsigned int md_flags,
const char *fail_str)
{
int ret = 0;
unsigned char sigtmp[256], *sig = sigtmp;
unsigned int siglen;
EVP_MD_CTX mctx;
EVP_MD_CTX_init(&mctx);
if ((pkey->type == EVP_PKEY_RSA)
&& (RSA_size(pkey->pkey.rsa) > sizeof(sigtmp)))
{
sig = OPENSSL_malloc(RSA_size(pkey->pkey.rsa));
if (!sig)
{
FIPSerr(FIPS_F_FIPS_CHECK_PK_SIG,ERR_R_MALLOC_FAILURE);
return 0;
}
}
if (tbslen == -1)
tbslen = strlen((char *)tbs);
if (md_flags)
M_EVP_MD_CTX_set_flags(&mctx, md_flags);
if (!EVP_SignInit_ex(&mctx, digest, NULL))
goto error;
if (!EVP_SignUpdate(&mctx, tbs, tbslen))
goto error;
if (!EVP_SignFinal(&mctx, sig, &siglen, pkey))
goto error;
if (kat && ((siglen != katlen) || memcmp(kat, sig, katlen)))
goto error;
if (!EVP_VerifyInit_ex(&mctx, digest, NULL))
goto error;
if (!EVP_VerifyUpdate(&mctx, tbs, tbslen))
goto error;
ret = EVP_VerifyFinal(&mctx, sig, siglen, pkey);
error:
if (sig != sigtmp)
OPENSSL_free(sig);
EVP_MD_CTX_cleanup(&mctx);
if (ret != 1)
{
FIPSerr(FIPS_F_FIPS_PKEY_SIGNATURE_TEST,FIPS_R_TEST_FAILURE);
if (fail_str)
ERR_add_error_data(2, "Type=", fail_str);
return 0;
}
return 1;
}
#endif

View file

@ -56,6 +56,8 @@ extern "C" {
#endif
struct dsa_st;
struct evp_pkey_st;
struct env_md_st;
int FIPS_mode_set(int onoff);
int FIPS_mode(void);
@ -76,6 +78,12 @@ void FIPS_corrupt_rng(void);
int FIPS_selftest_rng(void);
int FIPS_selftest_hmac(void);
int fips_pkey_signature_test(struct evp_pkey_st *pkey,
const unsigned char *tbs, int tbslen,
const unsigned char *kat, unsigned int katlen,
const struct env_md_st *digest, unsigned int md_flags,
const char *fail_str);
/* BEGIN ERROR CODES */
/* The following lines are auto generated by the script mkerr.pl. Any changes
* made after this point may be overwritten when the script is next run.
@ -93,9 +101,11 @@ void ERR_load_FIPS_strings(void);
#define FIPS_F_FIPS_CHECK_DSO 120
#define FIPS_F_FIPS_CHECK_EXE 106
#define FIPS_F_FIPS_CHECK_FINGERPRINT 121
#define FIPS_F_FIPS_CHECK_PK_SIG 122
#define FIPS_F_FIPS_CHECK_RSA 115
#define FIPS_F_FIPS_DSA_CHECK 102
#define FIPS_F_FIPS_MODE_SET 105
#define FIPS_F_FIPS_PKEY_SIGNATURE_TEST 123
#define FIPS_F_FIPS_SELFTEST_AES 104
#define FIPS_F_FIPS_SELFTEST_DES 107
#define FIPS_F_FIPS_SELFTEST_DSA 109
@ -125,6 +135,7 @@ void ERR_load_FIPS_strings(void);
#define FIPS_R_RSA_DECRYPT_ERROR 115
#define FIPS_R_RSA_ENCRYPT_ERROR 116
#define FIPS_R_SELFTEST_FAILED 101
#define FIPS_R_TEST_FAILURE 117
#define FIPS_R_UNSUPPORTED_PLATFORM 113
#ifdef __cplusplus

View file

@ -53,7 +53,6 @@
extern "C" {
#endif
/* These are trampolines implemented in crypto/cryptlib.c */
void fips_w_lock(void);
void fips_w_unlock(void);
void fips_r_lock(void);

View file

@ -82,49 +82,69 @@ static int FIPS_des_test()
return 1;
}
/* DSA: generate key and sign a known digest, then verify the signature
* against the digest
*/
/*
* DSA: generate keys and sign, verify input plaintext.
*/
static int FIPS_dsa_test()
{
DSA *dsa = NULL;
EVP_PKEY pk;
unsigned char dgst[] = "etaonrishdlc";
DSA_SIG *sig = NULL;
unsigned char buf[60];
unsigned int slen;
int r = 0;
EVP_MD_CTX mctx;
ERR_clear_error();
EVP_MD_CTX_init(&mctx);
dsa = FIPS_dsa_new();
if (!dsa)
return 0;
goto end;
if (!DSA_generate_parameters_ex(dsa, 512,NULL,0,NULL,NULL,NULL))
return 0;
goto end;
if (!DSA_generate_key(dsa))
return 0;
sig = DSA_do_sign(dgst,sizeof(dgst) - 1,dsa);
if (sig)
{
r = DSA_do_verify(dgst,sizeof(dgst) - 1,sig,dsa);
DSA_SIG_free(sig);
}
goto end;
pk.type = EVP_PKEY_DSA;
pk.pkey.dsa = dsa;
if (!EVP_SignInit_ex(&mctx, EVP_dss1(), NULL))
goto end;
if (!EVP_SignUpdate(&mctx, dgst, sizeof(dgst) - 1))
goto end;
if (!EVP_SignFinal(&mctx, buf, &slen, &pk))
goto end;
if (!EVP_VerifyInit_ex(&mctx, EVP_dss1(), NULL))
goto end;
if (!EVP_VerifyUpdate(&mctx, dgst, sizeof(dgst) - 1))
goto end;
r = EVP_VerifyFinal(&mctx, buf, slen, &pk);
end:
EVP_MD_CTX_cleanup(&mctx);
if (dsa)
FIPS_dsa_free(dsa);
if (r != 1)
return 0;
FIPS_dsa_free(dsa);
return 1;
}
/* RSA: generate keys and encrypt and decrypt known plaintext, verify result
* matches the original plaintext
*/
/*
* RSA: generate keys and sign, verify input plaintext.
*/
static int FIPS_rsa_test()
{
RSA *key;
unsigned char input_ptext[] = "etaonrishdlc";
unsigned char ctext[256];
unsigned char ptext[256];
unsigned char buf[256];
unsigned int slen;
BIGNUM *bn;
int n;
EVP_MD_CTX mctx;
EVP_PKEY pk;
int r;
ERR_clear_error();
EVP_MD_CTX_init(&mctx);
key = FIPS_rsa_new();
bn = BN_new();
if (!key || !bn)
@ -133,15 +153,27 @@ static int FIPS_rsa_test()
if (!RSA_generate_key_ex(key, 1024,bn,NULL))
return 0;
BN_free(bn);
n = RSA_size(key);
n = RSA_public_encrypt(sizeof(input_ptext) - 1,input_ptext,ctext,key,RSA_PKCS1_PADDING);
if (n < 0)
return 0;
n = RSA_private_decrypt(n,ctext,ptext,key,RSA_PKCS1_PADDING);
if (n < 0)
return 0;
pk.type = EVP_PKEY_RSA;
pk.pkey.rsa = key;
if (!EVP_SignInit_ex(&mctx, EVP_sha1(), NULL))
goto end;
if (!EVP_SignUpdate(&mctx, input_ptext, sizeof(input_ptext) - 1))
goto end;
if (!EVP_SignFinal(&mctx, buf, &slen, &pk))
goto end;
if (!EVP_VerifyInit_ex(&mctx, EVP_sha1(), NULL))
goto end;
if (!EVP_VerifyUpdate(&mctx, input_ptext, sizeof(input_ptext) - 1))
goto end;
r = EVP_VerifyFinal(&mctx, buf, slen, &pk);
end:
EVP_MD_CTX_cleanup(&mctx);
if (key)
FIPS_rsa_free(key);
if (memcmp(input_ptext,ptext,sizeof(input_ptext) - 1))
if (r != 1)
return 0;
return 1;
}

View file

@ -139,7 +139,7 @@ static RSA_METHOD rsa_pkcs1_eay_meth={
BN_mod_exp_mont, /* XXX probably we should not use Montgomery if e == 3 */
RSA_eay_init,
RSA_eay_finish,
0, /* flags */
RSA_FLAG_FIPS_METHOD, /* flags */
NULL,
0, /* rsa_sign */
0, /* rsa_verify */

View file

@ -65,74 +65,33 @@
#include <stdio.h>
#include <time.h>
#include <string.h>
#include <openssl/crypto.h>
#include <openssl/bn.h>
#include <openssl/rsa.h>
#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/fips.h>
#ifdef OPENSSL_FIPS
int fips_check_rsa(RSA *rsa)
{
int n, ret = 0;
unsigned char tctext[256], *ctext = tctext;
unsigned char tptext[256], *ptext = tptext;
/* The longest we can have with PKCS#1 v1.5 padding and a 512 bit key,
* namely 512/8-11-1 = 52 bytes */
static const unsigned char original_ptext[] =
"\x01\x23\x45\x67\x89\xab\xcd\xef\x01\x23\x45\x67\x89\xab\xcd\xef"
"\x01\x23\x45\x67\x89\xab\xcd\xef\x01\x23\x45\x67\x89\xab\xcd\xef"
"\x01\x23\x45\x67\x89\xab\xcd\xef\x01\x23\x45\x67\x89\xab\xcd\xef"
"\x01\x23\x45\x67";
const unsigned char tbs[] = "RSA Pairwise Check Data";
EVP_PKEY pk;
pk.type = EVP_PKEY_RSA;
pk.pkey.rsa = rsa;
if (RSA_size(rsa) > sizeof(tctext))
{
ctext = OPENSSL_malloc(RSA_size(rsa));
ptext = OPENSSL_malloc(RSA_size(rsa));
if (!ctext || !ptext)
{
FIPSerr(FIPS_F_FIPS_CHECK_RSA,ERR_R_MALLOC_FAILURE);
goto error;
}
}
/* this will fail for keys shorter than 512 bits */
n=RSA_private_encrypt(sizeof(original_ptext)-1,original_ptext,ctext,rsa,
RSA_PKCS1_PADDING);
if(n < 0)
{
FIPSerr(FIPS_F_FIPS_CHECK_RSA,FIPS_R_RSA_ENCRYPT_ERROR);
goto error;
}
if(!memcmp(ctext,original_ptext,n))
if (!fips_pkey_signature_test(&pk, tbs, -1,
NULL, 0, EVP_sha1(), EVP_MD_CTX_FLAG_PAD_PKCS1, NULL)
|| !fips_pkey_signature_test(&pk, tbs, -1,
NULL, 0, EVP_sha1(), EVP_MD_CTX_FLAG_PAD_X931, NULL)
|| !fips_pkey_signature_test(&pk, tbs, -1,
NULL, 0, EVP_sha1(), EVP_MD_CTX_FLAG_PAD_PSS, NULL))
{
FIPSerr(FIPS_F_FIPS_CHECK_RSA,FIPS_R_PAIRWISE_TEST_FAILED);
goto error;
return 0;
}
n=RSA_public_decrypt(n,ctext,ptext,rsa,RSA_PKCS1_PADDING);
if(n < 0)
{
FIPSerr(FIPS_F_FIPS_CHECK_RSA,FIPS_R_RSA_DECRYPT_ERROR);
goto error;
}
if(n != sizeof(original_ptext)-1 || memcmp(ptext,original_ptext,n))
{
FIPSerr(FIPS_F_FIPS_CHECK_RSA,FIPS_R_PAIRWISE_TEST_FAILED);
goto error;
}
ret = 1;
error:
if (RSA_size(rsa) > sizeof(tctext))
{
OPENSSL_free(ctext);
OPENSSL_free(ptext);
}
return ret;
return 1;
}
static int rsa_builtin_keygen(RSA *rsa, int bits, BIGNUM *e_value, BN_GENCB *cb);

View file

@ -1,5 +1,5 @@
/* ====================================================================
* Copyright (c) 2003 The OpenSSL Project. All rights reserved.
* Copyright (c) 2003-2007 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
@ -51,6 +51,7 @@
#include <openssl/err.h>
#include <openssl/fips.h>
#include <openssl/rsa.h>
#include <openssl/evp.h>
#include <openssl/fips_sha.h>
#include <openssl/opensslconf.h>
@ -68,7 +69,7 @@ static unsigned char n[] =
"\xCB";
static int setrsakey(RSA *key, unsigned char *c)
static int setrsakey(RSA *key)
{
static const unsigned char e[] = "\x11";
@ -116,16 +117,6 @@ static int setrsakey(RSA *key, unsigned char *c)
"\x9E\x2E\x0F\x96\x56\xE6\x98\xEA\x36\x66\xED\xFB\x25\x79\x80\x39"
"\xF7";
static const unsigned char ctext_ex[] =
"\x42\x4b\xc9\x51\x61\xd4\xca\xa0\x18\x6c\x4d\xca\x61\x8f\x2d\x07"
"\x8c\x63\xc5\x6b\xa2\x4c\x32\xb1\xda\xb7\xdd\x32\xb6\x51\x68\xc3"
"\x6e\x98\x46\xd6\xbb\x1a\xd5\x99\x05\x92\x7c\xd7\xbc\x08\x9e\xe4"
"\xc3\x70\x4d\xe6\x99\x7e\x61\x31\x07\x7a\x19\xdb\x3e\x11\xfa\x3d"
"\x7c\x61\xd7\x78\x14\x3f\x05\x16\xa0\xc4\xbf\xcd\xee\xca\x67\x4c"
"\x80\x4e\xca\x43\x2f\x35\x43\x58\xa7\x50\x7e\x3e\x52\x82\xab\xac"
"\xa6\x50\xe8\x39\x9f\xe0\x7f\x58\x1d\x1b\x90\x93\x04\xec\xb3\xf9"
"\x24\xd3\x75\x3e\x39\xd1\x14\xc6\x33\xce\xd6\xee\x20\x47\xec\xe4";
key->n = BN_bin2bn(n, sizeof(n)-1, key->n);
key->e = BN_bin2bn(e, sizeof(e)-1, key->e);
key->d = BN_bin2bn(d, sizeof(d)-1, key->d);
@ -134,9 +125,7 @@ static int setrsakey(RSA *key, unsigned char *c)
key->dmp1 = BN_bin2bn(dmp1, sizeof(dmp1)-1, key->dmp1);
key->dmq1 = BN_bin2bn(dmq1, sizeof(dmq1)-1, key->dmq1);
key->iqmp = BN_bin2bn(iqmp, sizeof(iqmp)-1, key->iqmp);
memcpy(c, ctext_ex, sizeof(ctext_ex) - 1);
return (sizeof(ctext_ex) - 1);
return 1;
}
void FIPS_corrupt_rsa()
@ -144,104 +133,294 @@ void FIPS_corrupt_rsa()
n[0]++;
}
/* Known Answer Test (KAT) data for the above RSA private key signing
* kat_tbs.
*/
static const unsigned char kat_tbs[] = "OpenSSL FIPS 140-2 Public Key RSA KAT";
static const unsigned char kat_RSA_PSS_SHA1[] = {
0x2D, 0xAF, 0x6E, 0xC2, 0x98, 0xFB, 0x8A, 0xA1, 0xB9, 0x46, 0xDA, 0x0F,
0x01, 0x1E, 0x37, 0x93, 0xC2, 0x55, 0x27, 0xE4, 0x1D, 0xD2, 0x90, 0xBB,
0xF4, 0xBF, 0x4A, 0x74, 0x39, 0x51, 0xBB, 0xE8, 0x0C, 0xB7, 0xF8, 0xD3,
0xD1, 0xDF, 0xE7, 0xBE, 0x80, 0x05, 0xC3, 0xB5, 0xC7, 0x83, 0xD5, 0x4C,
0x7F, 0x49, 0xFB, 0x3F, 0x29, 0x9B, 0xE1, 0x12, 0x51, 0x60, 0xD0, 0xA7,
0x0D, 0xA9, 0x28, 0x56, 0x73, 0xD9, 0x07, 0xE3, 0x5E, 0x3F, 0x9B, 0xF5,
0xB6, 0xF3, 0xF2, 0x5E, 0x74, 0xC9, 0x83, 0x81, 0x47, 0xF0, 0xC5, 0x45,
0x0A, 0xE9, 0x8E, 0x38, 0xD7, 0x18, 0xC6, 0x2A, 0x0F, 0xF8, 0xB7, 0x31,
0xD6, 0x55, 0xE4, 0x66, 0x78, 0x81, 0xD4, 0xE6, 0xDB, 0x9F, 0xBA, 0xE8,
0x23, 0xB5, 0x7F, 0xDC, 0x08, 0xEA, 0xD5, 0x26, 0x1E, 0x20, 0x25, 0x84,
0x26, 0xC6, 0x79, 0xC9, 0x9B, 0x3D, 0x7E, 0xA9
};
static const unsigned char kat_RSA_PSS_SHA224[] = {
0x39, 0x4A, 0x6A, 0x20, 0xBC, 0xE9, 0x33, 0xED, 0xEF, 0xC5, 0x58, 0xA7,
0xFE, 0x81, 0xC4, 0x36, 0x50, 0x9A, 0x2C, 0x82, 0x98, 0x08, 0x95, 0xFA,
0xB1, 0x9E, 0xD2, 0x55, 0x61, 0x87, 0x21, 0x59, 0x87, 0x7B, 0x1F, 0x57,
0x30, 0x9D, 0x0D, 0x4A, 0x06, 0xEB, 0x52, 0x37, 0x55, 0x54, 0x1C, 0x89,
0x83, 0x75, 0x59, 0x65, 0x64, 0x90, 0x2E, 0x16, 0xCC, 0x86, 0x05, 0xEE,
0xB1, 0xE6, 0x7B, 0xBA, 0x16, 0x75, 0x0D, 0x0C, 0x64, 0x0B, 0xAB, 0x22,
0x15, 0x78, 0x6B, 0x6F, 0xA4, 0xFB, 0x77, 0x40, 0x64, 0x62, 0xD1, 0xB5,
0x37, 0x1E, 0xE0, 0x3D, 0xA8, 0xF9, 0xD2, 0xBD, 0xAA, 0x38, 0x24, 0x49,
0x58, 0xD2, 0x74, 0x85, 0xF4, 0xB5, 0x93, 0x8E, 0xF5, 0x03, 0xEA, 0x2D,
0xC8, 0x52, 0xFA, 0xCF, 0x7E, 0x35, 0xB0, 0x6A, 0xAF, 0x95, 0xC0, 0x00,
0x54, 0x76, 0x3D, 0x0C, 0x9C, 0xB2, 0xEE, 0xC0
};
static const unsigned char kat_RSA_PSS_SHA256[] = {
0x6D, 0x3D, 0xBE, 0x8F, 0x60, 0x6D, 0x25, 0x14, 0xF0, 0x31, 0xE3, 0x89,
0x00, 0x97, 0xFA, 0x99, 0x71, 0x28, 0xE5, 0x10, 0x25, 0x9A, 0xF3, 0x8F,
0x7B, 0xC5, 0xA8, 0x4A, 0x74, 0x51, 0x36, 0xE2, 0x8D, 0x7D, 0x73, 0x28,
0xC1, 0x77, 0xC6, 0x27, 0x97, 0x00, 0x8B, 0x00, 0xA3, 0x96, 0x73, 0x4E,
0x7D, 0x2E, 0x2C, 0x34, 0x68, 0x8C, 0x8E, 0xDF, 0x9D, 0x49, 0x47, 0x05,
0xAB, 0xF5, 0x01, 0xD6, 0x81, 0x47, 0x70, 0xF5, 0x1D, 0x6D, 0x26, 0xBA,
0x2F, 0x7A, 0x54, 0x53, 0x4E, 0xED, 0x71, 0xD9, 0x5A, 0xF3, 0xDA, 0xB6,
0x0B, 0x47, 0x34, 0xAF, 0x90, 0xDC, 0xC8, 0xD9, 0x6F, 0x56, 0xCD, 0x9F,
0x21, 0xB7, 0x7E, 0xAD, 0x7C, 0x2F, 0x75, 0x50, 0x47, 0x12, 0xE4, 0x6D,
0x5F, 0xB7, 0x01, 0xDF, 0xC3, 0x11, 0x6C, 0xA9, 0x9E, 0x49, 0xB9, 0xF6,
0x72, 0xF4, 0xF6, 0xEF, 0x88, 0x1E, 0x2D, 0x1C
};
static const unsigned char kat_RSA_PSS_SHA384[] = {
0x40, 0xFB, 0xA1, 0x21, 0xF4, 0xB2, 0x40, 0x9A, 0xB4, 0x31, 0xA8, 0xF2,
0xEC, 0x1C, 0xC4, 0xC8, 0x7C, 0x22, 0x65, 0x9C, 0x57, 0x45, 0xCD, 0x5E,
0x86, 0x00, 0xF7, 0x25, 0x78, 0xDE, 0xDC, 0x7A, 0x71, 0x44, 0x9A, 0xCD,
0xAA, 0x25, 0xF4, 0xB2, 0xFC, 0xF0, 0x75, 0xD9, 0x2F, 0x78, 0x23, 0x7F,
0x6F, 0x02, 0xEF, 0xC1, 0xAF, 0xA6, 0x28, 0x16, 0x31, 0xDC, 0x42, 0x6C,
0xB2, 0x44, 0xE5, 0x4D, 0x66, 0xA2, 0xE6, 0x71, 0xF3, 0xAC, 0x4F, 0xFB,
0x91, 0xCA, 0xF5, 0x70, 0xEF, 0x6B, 0x9D, 0xA4, 0xEF, 0xD9, 0x3D, 0x2F,
0x3A, 0xBE, 0x89, 0x38, 0x59, 0x01, 0xBA, 0xDA, 0x32, 0xAD, 0x42, 0x89,
0x98, 0x8B, 0x39, 0x44, 0xF0, 0xFC, 0x38, 0xAC, 0x87, 0x1F, 0xCA, 0x6F,
0x48, 0xF6, 0xAE, 0xD7, 0x45, 0xEE, 0xAE, 0x88, 0x0E, 0x60, 0xF4, 0x55,
0x48, 0x44, 0xEE, 0x1F, 0x90, 0x18, 0x4B, 0xF1
};
static const unsigned char kat_RSA_PSS_SHA512[] = {
0x07, 0x1E, 0xD8, 0xD5, 0x05, 0xE8, 0xE6, 0xE6, 0x57, 0xAE, 0x63, 0x8C,
0xC6, 0x83, 0xB7, 0xA0, 0x59, 0xBB, 0xF2, 0xC6, 0x8F, 0x12, 0x53, 0x9A,
0x9B, 0x54, 0x9E, 0xB3, 0xC1, 0x1D, 0x23, 0x4D, 0x51, 0xED, 0x9E, 0xDD,
0x4B, 0xF3, 0x46, 0x9B, 0x6B, 0xF6, 0x7C, 0x24, 0x60, 0x79, 0x23, 0x39,
0x01, 0x1C, 0x51, 0xCB, 0xD8, 0xE9, 0x9A, 0x01, 0x67, 0x5F, 0xFE, 0xD7,
0x7C, 0xE3, 0x7F, 0xED, 0xDB, 0x87, 0xBB, 0xF0, 0x3D, 0x78, 0x55, 0x61,
0x57, 0xE3, 0x0F, 0xE3, 0xD2, 0x9D, 0x0C, 0x2A, 0x20, 0xB0, 0x85, 0x13,
0xC5, 0x47, 0x34, 0x0D, 0x32, 0x15, 0xC8, 0xAE, 0x9A, 0x6A, 0x39, 0x63,
0x2D, 0x60, 0xF5, 0x4C, 0xDF, 0x8A, 0x48, 0x4B, 0xBF, 0xF4, 0xA8, 0xFE,
0x76, 0xF2, 0x32, 0x1B, 0x9C, 0x7C, 0xCA, 0xFE, 0x7F, 0x80, 0xC2, 0x88,
0x5C, 0x97, 0x70, 0xB4, 0x26, 0xC9, 0x14, 0x8B
};
static const unsigned char kat_RSA_SHA1[] = {
0x71, 0xEE, 0x1A, 0xC0, 0xFE, 0x01, 0x93, 0x54, 0x79, 0x5C, 0xF2, 0x4C,
0x4A, 0xFD, 0x1A, 0x05, 0x8F, 0x64, 0xB1, 0x6D, 0x61, 0x33, 0x8D, 0x9B,
0xE7, 0xFD, 0x60, 0xA3, 0x83, 0xB5, 0xA3, 0x51, 0x55, 0x77, 0x90, 0xCF,
0xDC, 0x22, 0x37, 0x8E, 0xD0, 0xE1, 0xAE, 0x09, 0xE3, 0x3D, 0x1E, 0xF8,
0x80, 0xD1, 0x8B, 0xC2, 0xEC, 0x0A, 0xD7, 0x6B, 0x88, 0x8B, 0x8B, 0xA1,
0x20, 0x22, 0xBE, 0x59, 0x5B, 0xE0, 0x23, 0x24, 0xA1, 0x49, 0x30, 0xBA,
0xA9, 0x9E, 0xE8, 0xB1, 0x8A, 0x62, 0x16, 0xBF, 0x4E, 0xCA, 0x2E, 0x4E,
0xBC, 0x29, 0xA8, 0x67, 0x13, 0xB7, 0x9F, 0x1D, 0x04, 0x44, 0xE5, 0x5F,
0x35, 0x07, 0x11, 0xBC, 0xED, 0x19, 0x37, 0x21, 0xCF, 0x23, 0x48, 0x1F,
0x72, 0x05, 0xDE, 0xE6, 0xE8, 0x7F, 0x33, 0x8A, 0x76, 0x4B, 0x2F, 0x95,
0xDF, 0xF1, 0x5F, 0x84, 0x80, 0xD9, 0x46, 0xB4
};
static const unsigned char kat_RSA_SHA224[] = {
0x62, 0xAA, 0x79, 0xA9, 0x18, 0x0E, 0x5F, 0x8C, 0xBB, 0xB7, 0x15, 0xF9,
0x25, 0xBB, 0xFA, 0xD4, 0x3A, 0x34, 0xED, 0x9E, 0xA0, 0xA9, 0x18, 0x8D,
0x5B, 0x55, 0x9A, 0x7E, 0x1E, 0x08, 0x08, 0x60, 0xC5, 0x1A, 0xC5, 0x89,
0x08, 0xE2, 0x1B, 0xBD, 0x62, 0x50, 0x17, 0x76, 0x30, 0x2C, 0x9E, 0xCD,
0xA4, 0x02, 0xAD, 0xB1, 0x6D, 0x44, 0x6D, 0xD5, 0xC6, 0x45, 0x41, 0xE5,
0xEE, 0x1F, 0x8D, 0x7E, 0x08, 0x16, 0xA6, 0xE1, 0x5E, 0x0B, 0xA9, 0xCC,
0xDB, 0x59, 0x55, 0x87, 0x09, 0x25, 0x70, 0x86, 0x84, 0x02, 0xC6, 0x3B,
0x0B, 0x44, 0x4C, 0x46, 0x95, 0xF4, 0xF8, 0x5A, 0x91, 0x28, 0x3E, 0xB2,
0x58, 0x2E, 0x06, 0x45, 0x49, 0xE0, 0x92, 0xE2, 0xC0, 0x66, 0xE6, 0x35,
0xD9, 0x79, 0x7F, 0x17, 0x5E, 0x02, 0x73, 0x04, 0x77, 0x82, 0xE6, 0xDC,
0x40, 0x21, 0x89, 0x8B, 0x37, 0x3E, 0x1E, 0x8D
};
static const unsigned char kat_RSA_SHA256[] = {
0x0D, 0x55, 0xE2, 0xAA, 0x81, 0xDB, 0x8E, 0x82, 0x05, 0x17, 0xA5, 0x23,
0xE7, 0x3B, 0x1D, 0xAF, 0xFB, 0x8C, 0xD0, 0x81, 0x20, 0x7B, 0xAA, 0x23,
0x92, 0x87, 0x8C, 0xD1, 0x53, 0x85, 0x16, 0xDC, 0xBE, 0xAD, 0x6F, 0x35,
0x98, 0x2D, 0x69, 0x84, 0xBF, 0xD9, 0x8A, 0x01, 0x17, 0x58, 0xB2, 0x6E,
0x2C, 0x44, 0x9B, 0x90, 0xF1, 0xFB, 0x51, 0xE8, 0x6A, 0x90, 0x2D, 0x18,
0x0E, 0xC0, 0x90, 0x10, 0x24, 0xA9, 0x1D, 0xB3, 0x58, 0x7A, 0x91, 0x30,
0xBE, 0x22, 0xC7, 0xD3, 0xEC, 0xC3, 0x09, 0x5D, 0xBF, 0xE2, 0x80, 0x3A,
0x7C, 0x85, 0xB4, 0xBC, 0xD1, 0xE9, 0xF0, 0x5C, 0xDE, 0x81, 0xA6, 0x38,
0xB8, 0x42, 0xBB, 0x86, 0xC5, 0x9D, 0xCE, 0x7C, 0x2C, 0xEE, 0xD1, 0xDA,
0x27, 0x48, 0x2B, 0xF5, 0xAB, 0xB9, 0xF7, 0x80, 0xD1, 0x90, 0x27, 0x90,
0xBD, 0x44, 0x97, 0x60, 0xCD, 0x57, 0xC0, 0x7A
};
static const unsigned char kat_RSA_SHA384[] = {
0x1D, 0xE3, 0x6A, 0xDD, 0x27, 0x4C, 0xC0, 0xA5, 0x27, 0xEF, 0xE6, 0x1F,
0xD2, 0x91, 0x68, 0x59, 0x04, 0xAE, 0xBD, 0x99, 0x63, 0x56, 0x47, 0xC7,
0x6F, 0x22, 0x16, 0x48, 0xD0, 0xF9, 0x18, 0xA9, 0xCA, 0xFA, 0x5D, 0x5C,
0xA7, 0x65, 0x52, 0x8A, 0xC8, 0x44, 0x7E, 0x86, 0x5D, 0xA9, 0xA6, 0x55,
0x65, 0x3E, 0xD9, 0x2D, 0x02, 0x38, 0xA8, 0x79, 0x28, 0x7F, 0xB6, 0xCF,
0x82, 0xDD, 0x7E, 0x55, 0xE1, 0xB1, 0xBC, 0xE2, 0x19, 0x2B, 0x30, 0xC2,
0x1B, 0x2B, 0xB0, 0x82, 0x46, 0xAC, 0x4B, 0xD1, 0xE2, 0x7D, 0xEB, 0x8C,
0xFF, 0x95, 0xE9, 0x6A, 0x1C, 0x3D, 0x4D, 0xBF, 0x8F, 0x8B, 0x9C, 0xCD,
0xEA, 0x85, 0xEE, 0x00, 0xDC, 0x1C, 0xA7, 0xEB, 0xD0, 0x8F, 0x99, 0xF1,
0x16, 0x28, 0x24, 0x64, 0x04, 0x39, 0x2D, 0x58, 0x1E, 0x37, 0xDC, 0x04,
0xBD, 0x31, 0xA2, 0x2F, 0xB3, 0x35, 0x56, 0xBF
};
static const unsigned char kat_RSA_SHA512[] = {
0x69, 0x52, 0x1B, 0x51, 0x5E, 0x06, 0xCA, 0x9B, 0x16, 0x51, 0x5D, 0xCF,
0x49, 0x25, 0x4A, 0xA1, 0x6A, 0x77, 0x4C, 0x36, 0x40, 0xF8, 0xB2, 0x9A,
0x15, 0xEA, 0x5C, 0xE5, 0xE6, 0x82, 0xE0, 0x86, 0x82, 0x6B, 0x32, 0xF1,
0x04, 0xC1, 0x5A, 0x1A, 0xED, 0x1E, 0x9A, 0xB6, 0x4C, 0x54, 0x9F, 0xD8,
0x8D, 0xCC, 0xAC, 0x8A, 0xBB, 0x9C, 0x82, 0x3F, 0xA6, 0x53, 0x62, 0xB5,
0x80, 0xE2, 0xBC, 0xDD, 0x67, 0x2B, 0xD9, 0x3F, 0xE4, 0x75, 0x92, 0x6B,
0xAF, 0x62, 0x7C, 0x52, 0xF0, 0xEE, 0x33, 0xDF, 0x1B, 0x1D, 0x47, 0xE6,
0x59, 0x56, 0xA5, 0xB9, 0x5C, 0xE6, 0x77, 0x78, 0x16, 0x63, 0x84, 0x05,
0x6F, 0x0E, 0x2B, 0x31, 0x9D, 0xF7, 0x7F, 0xB2, 0x64, 0x71, 0xE0, 0x2D,
0x3E, 0x62, 0xCE, 0xB5, 0x3F, 0x88, 0xDF, 0x2D, 0xAB, 0x98, 0x65, 0x91,
0xDF, 0x70, 0x14, 0xA5, 0x3F, 0x36, 0xAB, 0x84
};
static const unsigned char kat_RSA_X931_SHA1[] = {
0x86, 0xB4, 0x18, 0xBA, 0xD1, 0x80, 0xB6, 0x7C, 0x42, 0x45, 0x4D, 0xDF,
0xE9, 0x2D, 0xE1, 0x83, 0x5F, 0xB5, 0x2F, 0xC9, 0xCD, 0xC4, 0xB2, 0x75,
0x80, 0xA4, 0xF1, 0x4A, 0xE7, 0x83, 0x12, 0x1E, 0x1E, 0x14, 0xB8, 0xAC,
0x35, 0xE2, 0xAA, 0x0B, 0x5C, 0xF8, 0x38, 0x4D, 0x04, 0xEE, 0xA9, 0x97,
0x70, 0xFB, 0x5E, 0xE7, 0xB7, 0xE3, 0x62, 0x23, 0x4B, 0x38, 0xBE, 0xD6,
0x53, 0x15, 0xF7, 0xDF, 0x87, 0xB4, 0x0E, 0xCC, 0xB1, 0x1A, 0x11, 0x19,
0xEE, 0x51, 0xCC, 0x92, 0xDD, 0xBC, 0x63, 0x29, 0x63, 0x0C, 0x59, 0xD7,
0x6F, 0x4C, 0x3C, 0x37, 0x5B, 0x37, 0x03, 0x61, 0x7D, 0x24, 0x1C, 0x99,
0x48, 0xAF, 0x82, 0xFE, 0x32, 0x41, 0x9B, 0xB2, 0xDB, 0xEA, 0xED, 0x76,
0x8E, 0x6E, 0xCA, 0x7E, 0x4E, 0x14, 0xBA, 0x30, 0x84, 0x1C, 0xB3, 0x67,
0xA3, 0x29, 0x80, 0x70, 0x54, 0x68, 0x7D, 0x49
};
static const unsigned char kat_RSA_X931_SHA256[] = {
0x7E, 0xA2, 0x77, 0xFE, 0xB8, 0x54, 0x8A, 0xC7, 0x7F, 0x64, 0x54, 0x89,
0xE5, 0x52, 0x15, 0x8E, 0x52, 0x96, 0x4E, 0xA6, 0x58, 0x92, 0x1C, 0xDD,
0xEA, 0xA2, 0x2D, 0x5C, 0xD1, 0x62, 0x00, 0x49, 0x05, 0x95, 0x73, 0xCF,
0x16, 0x76, 0x68, 0xF6, 0xC6, 0x5E, 0x80, 0xB8, 0xB8, 0x7B, 0xC8, 0x9B,
0xC6, 0x53, 0x88, 0x26, 0x20, 0x88, 0x73, 0xB6, 0x13, 0xB8, 0xF0, 0x4B,
0x00, 0x85, 0xF3, 0xDD, 0x07, 0x50, 0xEB, 0x20, 0xC4, 0x38, 0x0E, 0x98,
0xAD, 0x4E, 0x49, 0x2C, 0xD7, 0x65, 0xA5, 0x19, 0x0E, 0x59, 0x01, 0xEC,
0x7E, 0x75, 0x89, 0x69, 0x2E, 0x63, 0x76, 0x85, 0x46, 0x8D, 0xA0, 0x8C,
0x33, 0x1D, 0x82, 0x8C, 0x03, 0xEA, 0x69, 0x88, 0x35, 0xA1, 0x42, 0xBD,
0x21, 0xED, 0x8D, 0xBC, 0xBC, 0xDB, 0x30, 0xFF, 0x86, 0xF0, 0x5B, 0xDC,
0xE3, 0xE2, 0xE8, 0x0A, 0x0A, 0x29, 0x94, 0x80
};
static const unsigned char kat_RSA_X931_SHA384[] = {
0x5C, 0x7D, 0x96, 0x35, 0xEC, 0x7E, 0x11, 0x38, 0xBB, 0x7B, 0xEC, 0x7B,
0xF2, 0x82, 0x8E, 0x99, 0xBD, 0xEF, 0xD8, 0xAE, 0xD7, 0x39, 0x37, 0xCB,
0xE6, 0x4F, 0x5E, 0x0A, 0x13, 0xE4, 0x2E, 0x40, 0xB9, 0xBE, 0x2E, 0xE3,
0xEF, 0x78, 0x83, 0x18, 0x44, 0x35, 0x9C, 0x8E, 0xD7, 0x4A, 0x63, 0xF6,
0x57, 0xC2, 0xB0, 0x08, 0x51, 0x73, 0xCF, 0xCA, 0x99, 0x66, 0xEE, 0x31,
0xD8, 0x69, 0xE9, 0xAB, 0x13, 0x27, 0x7B, 0x41, 0x1E, 0x6D, 0x8D, 0xF1,
0x3E, 0x9C, 0x35, 0x95, 0x58, 0xDD, 0x2B, 0xD5, 0xA0, 0x60, 0x41, 0x79,
0x24, 0x22, 0xE4, 0xB7, 0xBF, 0x47, 0x53, 0xF6, 0x34, 0xD5, 0x7C, 0xFF,
0x0E, 0x09, 0xEE, 0x2E, 0xE2, 0x37, 0xB9, 0xDE, 0xC5, 0x12, 0x44, 0x35,
0xEF, 0x01, 0xE6, 0x5E, 0x39, 0x31, 0x2D, 0x71, 0xA5, 0xDC, 0xC6, 0x6D,
0xE2, 0xCD, 0x85, 0xDB, 0x73, 0x82, 0x65, 0x28
};
static const unsigned char kat_RSA_X931_SHA512[] = {
0xA6, 0x65, 0xA2, 0x77, 0x4F, 0xB3, 0x86, 0xCB, 0x64, 0x3A, 0xC1, 0x63,
0xFC, 0xA1, 0xAA, 0xCB, 0x9B, 0x79, 0xDD, 0x4B, 0xE1, 0xD9, 0xDA, 0xAC,
0xE7, 0x47, 0x09, 0xB2, 0x11, 0x4B, 0x8A, 0xAA, 0x05, 0x9E, 0x77, 0xD7,
0x3A, 0xBD, 0x5E, 0x53, 0x09, 0x4A, 0xE6, 0x0F, 0x5E, 0xF9, 0x14, 0x28,
0xA0, 0x99, 0x74, 0x64, 0x70, 0x4E, 0xF2, 0xE3, 0xFA, 0xC7, 0xF8, 0xC5,
0x6E, 0x2B, 0x79, 0x96, 0x0D, 0x0C, 0xC8, 0x10, 0x34, 0x53, 0xD2, 0xAF,
0x17, 0x0E, 0xE0, 0xBF, 0x79, 0xF6, 0x04, 0x72, 0x10, 0xE0, 0xF6, 0xD0,
0xCE, 0x8A, 0x6F, 0xA1, 0x95, 0x89, 0xBF, 0x58, 0x8F, 0x46, 0x5F, 0x09,
0x9F, 0x09, 0xCA, 0x84, 0x15, 0x85, 0xE0, 0xED, 0x04, 0x2D, 0xFB, 0x7C,
0x36, 0x35, 0x21, 0x31, 0xC3, 0xFD, 0x92, 0x42, 0x11, 0x30, 0x71, 0x1B,
0x60, 0x83, 0x18, 0x88, 0xA3, 0xF5, 0x59, 0xC3
};
int FIPS_selftest_rsa()
{
int clen, ret = 0;
RSA *key;
unsigned char expected_ctext[256];
unsigned char ctext[256];
unsigned char ptext[256];
static const unsigned char original_ptext[] =
"\x01\x23\x45\x67\x89\xab\xcd\xef\x12\x34\x56\x78\x9a\xbc\xde\xf0"
"\x23\x45\x67\x89\xab\xcd\xef\x12\x34\x56\x78\x9a\xbc\xde\xf0\x12"
"\x45\x67\x89\xab\xcd\xef\x12\x34\x56\x78\x9a\xbc\xde\xf0\x12\x34"
"\x67\x89\xab\xcd\xef\x12\x34\x56\x78\x9a\xbc\xde\xf0\x12\x34\x56"
"\x89\xab\xcd\xef\x12\x34\x56\x78\x9a\xbc\xde\xf0\x12\x34\x56\x78"
"\xab\xcd\xef\x12\x34\x56\x78\x9a\xbc\xde\xf0\x12\x34\x56\x78\x9a"
"\xcd\xef\x12\x34\x56\x78\x9a\xbc\xde\xf0\x12\x34\x56\x78\x9a\xbc"
"\xef\x12\x34\x56\x78\x9a\xbc\xde\xf0\x12\x34\x56\x78\x9a\xbc\xde"
"\xf0\x12\x34\x56\x78\x9a\xbc\xde\xf0\x12\x34\x56\x78\x9a\xbc\xde";
unsigned char md[SHA_DIGEST_LENGTH];
static const unsigned char mdkat[SHA_DIGEST_LENGTH] =
"\x2d\x57\x1d\x6f\x5c\x37\xf9\xf0\x3b\xb4\x3c\xe8\x2c\x4c\xb3\x04"
"\x75\xa2\x0e\xfb";
static const unsigned char ctextkat[] =
"\x3e\xc5\x0a\xbe\x29\xa2\xca\x9a\x35\x14\x17\x26\xa4\x0f\xa3\x03"
"\x65\xb5\x37\xf5\x6a\xaa\xb\xf\x2c\x0d\x8\xc0\x73\x8\x3c\x88\x85"
"\x36\x68\x16\xfe\x2f\x59\x77\x7e\x2a\x76\x9a\xc7\x27\x19\x9b\x54"
"\x14\x87\xf3\xe0\xce\x1e\x68\x10\x40\x14\xac\xbc\xe6\x6f\x26\x1f"
"\x55\xd1\x15\x81\x48\x10\xf4\x89\xe5\x67\x52\x42\x87\x04\x74\x4e"
"\x96\x14\x7c\x53\xc9\x1e\x84\x11\x7d\x7d\x23\xbd\xff\x6c\xcb\x00"
"\x96\x2e\x7d\xfb\x47\xea\x78\xcd\xd8\x04\x3a\x98\x06\x13\x68\x39"
"\xa1\xe2\xbc\x9f\x64\xc7\x62\xf0\x74\x4d\x42\xe0\x0b\xcf\x24\x48";
int i;
/* Perform pairwise consistency test by: ... */
int ret = 0;
RSA *key = NULL;
EVP_PKEY pk;
key=FIPS_rsa_new();
clen=setrsakey(key,expected_ctext);
/* ...1) apply public key to plaintext, resulting ciphertext must be
* different
*/
i=RSA_public_encrypt(128,original_ptext,ctext,key,
RSA_NO_PADDING);
if(i != clen || memcmp(ctext,expected_ctext,i))
{
FIPSerr(FIPS_F_FIPS_SELFTEST_RSA,FIPS_R_SELFTEST_FAILED);
goto err;
}
if(!memcmp(ctext,original_ptext,i))
{
FIPSerr(FIPS_F_FIPS_SELFTEST_RSA,FIPS_R_SELFTEST_FAILED);
goto err;
}
/* ...2) apply private key to ciphertext and compare result to
* original plaintext; results must be equal
*/
i=RSA_private_decrypt(i,ctext,ptext,key,RSA_NO_PADDING);
if(i != 128 || memcmp(ptext,original_ptext,i))
{
FIPSerr(FIPS_F_FIPS_SELFTEST_RSA,FIPS_R_SELFTEST_FAILED);
goto err;
}
setrsakey(key);
pk.type = EVP_PKEY_RSA;
pk.pkey.rsa = key;
/* Perform sign and verify Known Answer Test by... */
if (!fips_pkey_signature_test(&pk, kat_tbs, sizeof(kat_tbs) - 1,
kat_RSA_SHA1, sizeof(kat_RSA_SHA1),
EVP_sha1(), EVP_MD_CTX_FLAG_PAD_PKCS1,
"RSA SHA1 PKCS#1"))
goto err;
if (!fips_pkey_signature_test(&pk, kat_tbs, sizeof(kat_tbs) - 1,
kat_RSA_SHA224, sizeof(kat_RSA_SHA224),
EVP_sha224(), EVP_MD_CTX_FLAG_PAD_PKCS1,
"RSA SHA224 PKCS#1"))
goto err;
if (!fips_pkey_signature_test(&pk, kat_tbs, sizeof(kat_tbs) - 1,
kat_RSA_SHA256, sizeof(kat_RSA_SHA256),
EVP_sha256(), EVP_MD_CTX_FLAG_PAD_PKCS1,
"RSA SHA256 PKCS#1"))
goto err;
if (!fips_pkey_signature_test(&pk, kat_tbs, sizeof(kat_tbs) - 1,
kat_RSA_SHA384, sizeof(kat_RSA_SHA384),
EVP_sha384(), EVP_MD_CTX_FLAG_PAD_PKCS1,
"RSA SHA384 PKCS#1"))
goto err;
if (!fips_pkey_signature_test(&pk, kat_tbs, sizeof(kat_tbs) - 1,
kat_RSA_SHA512, sizeof(kat_RSA_SHA512),
EVP_sha512(), EVP_MD_CTX_FLAG_PAD_PKCS1,
"RSA SHA512 PKCS#1"))
goto err;
/* ...1) using the same RSA key to encrypt the SHA-1 hash of a
* plaintext value larger than the RSA key size
*/
if (RSA_size(key) >= sizeof(original_ptext) - 1)
{
FIPSerr(FIPS_F_FIPS_SELFTEST_RSA,FIPS_R_SELFTEST_FAILED);
if (!fips_pkey_signature_test(&pk, kat_tbs, sizeof(kat_tbs) - 1,
kat_RSA_PSS_SHA1, sizeof(kat_RSA_PSS_SHA1),
EVP_sha1(), EVP_MD_CTX_FLAG_PAD_PSS,
"RSA SHA1 PSS"))
goto err;
}
/* ...2) then generate the SHA-1 digest of plaintext, and compare the
* digest to the Known Answer (note here we duplicate the SHA-1 KAT)
*/
SHA1(original_ptext,sizeof(original_ptext) - 1,md);
if(memcmp(md,mdkat,SHA_DIGEST_LENGTH))
{
FIPSerr(FIPS_F_FIPS_SELFTEST_SHA,FIPS_R_SELFTEST_FAILED);
if (!fips_pkey_signature_test(&pk, kat_tbs, sizeof(kat_tbs) - 1,
kat_RSA_PSS_SHA224, sizeof(kat_RSA_PSS_SHA224),
EVP_sha224(), EVP_MD_CTX_FLAG_PAD_PSS,
"RSA SHA224 PSS"))
goto err;
}
/* ...3) then encrypt the digest, and compare the ciphertext
* to the Known Answer
*/
i=RSA_private_encrypt(sizeof(md),md,ctext,key,RSA_PKCS1_PADDING);
if(i != clen || memcmp(ctextkat,ctext,i))
{
FIPSerr(FIPS_F_FIPS_SELFTEST_RSA,FIPS_R_SELFTEST_FAILED);
if (!fips_pkey_signature_test(&pk, kat_tbs, sizeof(kat_tbs) - 1,
kat_RSA_PSS_SHA256, sizeof(kat_RSA_PSS_SHA256),
EVP_sha256(), EVP_MD_CTX_FLAG_PAD_PSS,
"RSA SHA256 PSS"))
goto err;
}
/* ...4) and finally decrypt the signed digest and compare with
* the original Known Answer
*/
i=RSA_public_decrypt(i,ctext,md,key,RSA_PKCS1_PADDING);
if(i != sizeof(md) || memcmp(mdkat,md,i))
{
FIPSerr(FIPS_F_FIPS_SELFTEST_RSA,FIPS_R_SELFTEST_FAILED);
if (!fips_pkey_signature_test(&pk, kat_tbs, sizeof(kat_tbs) - 1,
kat_RSA_PSS_SHA384, sizeof(kat_RSA_PSS_SHA384),
EVP_sha384(), EVP_MD_CTX_FLAG_PAD_PSS,
"RSA SHA384 PSS"))
goto err;
}
if (!fips_pkey_signature_test(&pk, kat_tbs, sizeof(kat_tbs) - 1,
kat_RSA_PSS_SHA512, sizeof(kat_RSA_PSS_SHA512),
EVP_sha512(), EVP_MD_CTX_FLAG_PAD_PSS,
"RSA SHA512 PSS"))
goto err;
if (!fips_pkey_signature_test(&pk, kat_tbs, sizeof(kat_tbs) - 1,
kat_RSA_X931_SHA1, sizeof(kat_RSA_X931_SHA1),
EVP_sha1(), EVP_MD_CTX_FLAG_PAD_X931,
"RSA SHA1 X931"))
goto err;
/* NB: SHA224 not supported in X9.31 */
if (!fips_pkey_signature_test(&pk, kat_tbs, sizeof(kat_tbs) - 1,
kat_RSA_X931_SHA256, sizeof(kat_RSA_X931_SHA256),
EVP_sha256(), EVP_MD_CTX_FLAG_PAD_X931,
"RSA SHA256 X931"))
goto err;
if (!fips_pkey_signature_test(&pk, kat_tbs, sizeof(kat_tbs) - 1,
kat_RSA_X931_SHA384, sizeof(kat_RSA_X931_SHA384),
EVP_sha384(), EVP_MD_CTX_FLAG_PAD_X931,
"RSA SHA384 X931"))
goto err;
if (!fips_pkey_signature_test(&pk, kat_tbs, sizeof(kat_tbs) - 1,
kat_RSA_X931_SHA512, sizeof(kat_RSA_X931_SHA512),
EVP_sha512(), EVP_MD_CTX_FLAG_PAD_X931,
"RSA SHA512 X931"))
goto err;
ret = 1;

View file

@ -151,8 +151,15 @@ static int fips_rsa_sign(int type, const unsigned char *x, unsigned int y,
if (pad_mode == EVP_MD_CTX_FLAG_PAD_X931)
{
int hash_id;
memcpy(tmpdinfo, md, m_len);
tmpdinfo[m_len] = RSA_X931_hash_id(M_EVP_MD_CTX_type(sv->mctx));
hash_id = RSA_X931_hash_id(M_EVP_MD_CTX_type(sv->mctx));
if (hash_id == -1)
{
RSAerr(RSA_F_RSA_SIGN,RSA_R_UNKNOWN_ALGORITHM_TYPE);
return 0;
}
tmpdinfo[m_len] = (unsigned char)hash_id;
i = m_len + 1;
rsa_pad_mode = RSA_X931_PADDING;
}
@ -164,7 +171,7 @@ static int fips_rsa_sign(int type, const unsigned char *x, unsigned int y,
if (!der)
{
RSAerr(RSA_F_RSA_SIGN,RSA_R_UNKNOWN_ALGORITHM_TYPE);
return(0);
return 0;
}
memcpy(tmpdinfo, der, dlen);
memcpy(tmpdinfo + dlen, md, m_len);
@ -273,12 +280,19 @@ static int fips_rsa_verify(int dtype,
if (pad_mode == EVP_MD_CTX_FLAG_PAD_X931)
{
int hash_id;
if (i != (int)(diglen + 1))
{
RSAerr(RSA_F_RSA_VERIFY,RSA_R_BAD_SIGNATURE);
goto err;
}
if (s[diglen] != RSA_X931_hash_id(M_EVP_MD_CTX_type(sv->mctx)))
hash_id = RSA_X931_hash_id(M_EVP_MD_CTX_type(sv->mctx));
if (hash_id == -1)
{
RSAerr(RSA_F_RSA_SIGN,RSA_R_UNKNOWN_ALGORITHM_TYPE);
goto err;
}
if (s[diglen] != (unsigned char)hash_id)
{
RSAerr(RSA_F_RSA_VERIFY,RSA_R_BAD_SIGNATURE);
goto err;