From a81f3373318c67e763f51cba8f6b3dba219381f8 Mon Sep 17 00:00:00 2001 From: "Dr. Stephen Henson" Date: Fri, 6 Apr 2007 00:30:24 +0000 Subject: [PATCH] Block low level public key signature operations in FIPS mode. Update self tests for all modes and use EVP. Update pairwise consistency checks. --- CHANGES | 9 + apps/dgst.c | 28 +++ crypto/dsa/dsa.h | 20 +- crypto/dsa/dsa_asn1.c | 15 ++ crypto/dsa/dsa_err.c | 6 +- crypto/dsa/dsa_lib.c | 27 ++ crypto/dsa/dsa_sign.c | 12 +- crypto/dsa/dsa_vrf.c | 8 +- crypto/fips_err.h | 3 + crypto/rsa/rsa.h | 20 ++ crypto/rsa/rsa_eng.c | 26 ++ crypto/rsa/rsa_err.c | 7 +- crypto/rsa/rsa_lib.c | 14 ++ crypto/rsa/rsa_sign.c | 24 +- fips-1.0/dsa/fips_dsa_key.c | 31 +-- fips-1.0/dsa/fips_dsa_ossl.c | 7 +- fips-1.0/fips.c | 68 ++++++ fips-1.0/fips.h | 11 + fips-1.0/fips_locl.h | 1 - fips-1.0/fips_test_suite.c | 90 ++++--- fips-1.0/rsa/fips_rsa_eay.c | 2 +- fips-1.0/rsa/fips_rsa_gen.c | 73 ++---- fips-1.0/rsa/fips_rsa_selftest.c | 407 ++++++++++++++++++++++--------- fips-1.0/rsa/fips_rsa_sign.c | 20 +- 24 files changed, 688 insertions(+), 241 deletions(-) diff --git a/CHANGES b/CHANGES index 221ce1efd8..242bd71391 100644 --- a/CHANGES +++ b/CHANGES @@ -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 diff --git a/apps/dgst.c b/apps/dgst.c index 91d5c196cb..72ff877afb 100644 --- a/apps/dgst.c +++ b/apps/dgst.c @@ -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)) diff --git a/crypto/dsa/dsa.h b/crypto/dsa/dsa.h index 3b4c636d06..914f6c7195 100644 --- a/crypto/dsa/dsa.h +++ b/crypto/dsa/dsa.h @@ -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 } diff --git a/crypto/dsa/dsa_asn1.c b/crypto/dsa/dsa_asn1.c index be8913d1e7..0d10b0353e 100644 --- a/crypto/dsa/dsa_asn1.c +++ b/crypto/dsa/dsa_asn1.c @@ -61,6 +61,7 @@ #include #include #include +#include /* 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); diff --git a/crypto/dsa/dsa_err.c b/crypto/dsa/dsa_err.c index 768711994b..68663d85fd 100644 --- a/crypto/dsa/dsa_err.c +++ b/crypto/dsa/dsa_err.c @@ -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} }; diff --git a/crypto/dsa/dsa_lib.c b/crypto/dsa/dsa_lib.c index 3198ef94b3..7ac9dc8c89 100644 --- a/crypto/dsa/dsa_lib.c +++ b/crypto/dsa/dsa_lib.c @@ -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; diff --git a/crypto/dsa/dsa_sign.c b/crypto/dsa/dsa_sign.c index ff181aff9e..4fd22283c5 100644 --- a/crypto/dsa/dsa_sign.c +++ b/crypto/dsa/dsa_sign.c @@ -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); } diff --git a/crypto/dsa/dsa_vrf.c b/crypto/dsa/dsa_vrf.c index d2796d4e0c..dcceed2f8e 100644 --- a/crypto/dsa/dsa_vrf.c +++ b/crypto/dsa/dsa_vrf.c @@ -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); } diff --git a/crypto/fips_err.h b/crypto/fips_err.h index 96afed905e..9c07e9f725 100644 --- a/crypto/fips_err.h +++ b/crypto/fips_err.h @@ -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} }; diff --git a/crypto/rsa/rsa.h b/crypto/rsa/rsa.h index e36397bd5f..464b295f0d 100644 --- a/crypto/rsa/rsa.h +++ b/crypto/rsa/rsa.h @@ -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 diff --git a/crypto/rsa/rsa_eng.c b/crypto/rsa/rsa_eng.c index ce7157ffa4..03410423ff 100644 --- a/crypto/rsa/rsa_eng.c +++ b/crypto/rsa/rsa_eng.c @@ -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; diff --git a/crypto/rsa/rsa_err.c b/crypto/rsa/rsa_err.c index fe3ba1b44b..69a5db9459 100644 --- a/crypto/rsa/rsa_err.c +++ b/crypto/rsa/rsa_err.c @@ -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"}, diff --git a/crypto/rsa/rsa_lib.c b/crypto/rsa/rsa_lib.c index 5adb05e022..5714841f4c 100644 --- a/crypto/rsa/rsa_lib.c +++ b/crypto/rsa/rsa_lib.c @@ -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)); } diff --git a/crypto/rsa/rsa_sign.c b/crypto/rsa/rsa_sign.c index 71aabeea1b..5488c06f6d 100644 --- a/crypto/rsa/rsa_sign.c +++ b/crypto/rsa/rsa_sign.c @@ -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; diff --git a/fips-1.0/dsa/fips_dsa_key.c b/fips-1.0/dsa/fips_dsa_key.c index 9940d139fc..05c06ab67d 100644 --- a/fips-1.0/dsa/fips_dsa_key.c +++ b/fips-1.0/dsa/fips_dsa_key.c @@ -63,33 +63,28 @@ #include #include #include +#include #include #ifdef OPENSSL_FIPS static int dsa_builtin_keygen(DSA *dsa); -static int fips_check_dsa(DSA *dsa) - { - static const unsigned char str1[]="12345678901234567890"; - int r = 0; - DSA_SIG *sig; - - sig = DSA_do_sign(str1, 20, dsa); - - if (sig) +int fips_check_dsa(DSA *dsa) { - r = DSA_do_verify(str1, 20, sig, dsa); - DSA_SIG_free(sig); - } + EVP_PKEY pk; + unsigned char tbs[] = "DSA Pairwise Check Data"; + pk.type = EVP_PKEY_DSA; + pk.pkey.dsa = dsa; - if(r != 1) - { - FIPSerr(FIPS_F_FIPS_CHECK_DSA,FIPS_R_PAIRWISE_TEST_FAILED); - return 0; + if (!fips_pkey_signature_test(&pk, tbs, -1, + NULL, 0, EVP_dss1(), 0, NULL)) + { + FIPSerr(FIPS_F_FIPS_CHECK_RSA,FIPS_R_PAIRWISE_TEST_FAILED); + return 0; + } + return 1; } - return 1; - } int DSA_generate_key(DSA *dsa) { diff --git a/fips-1.0/dsa/fips_dsa_ossl.c b/fips-1.0/dsa/fips_dsa_ossl.c index eec80af364..c00a9c4c89 100644 --- a/fips-1.0/dsa/fips_dsa_ossl.c +++ b/fips-1.0/dsa/fips_dsa_ossl.c @@ -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; diff --git a/fips-1.0/fips.c b/fips-1.0/fips.c index 9f0e69842e..f75ea4661f 100644 --- a/fips-1.0/fips.c +++ b/fips-1.0/fips.c @@ -53,6 +53,7 @@ #include #include #include +#include #include #include #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 diff --git a/fips-1.0/fips.h b/fips-1.0/fips.h index 690149bc4f..bf810dfa8c 100644 --- a/fips-1.0/fips.h +++ b/fips-1.0/fips.h @@ -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 diff --git a/fips-1.0/fips_locl.h b/fips-1.0/fips_locl.h index bbddfaab82..cc91341bee 100644 --- a/fips-1.0/fips_locl.h +++ b/fips-1.0/fips_locl.h @@ -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); diff --git a/fips-1.0/fips_test_suite.c b/fips-1.0/fips_test_suite.c index 5e8a279c8d..856599aa32 100644 --- a/fips-1.0/fips_test_suite.c +++ b/fips-1.0/fips_test_suite.c @@ -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,16 +153,28 @@ 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) + + 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 (r != 1) return 0; - FIPS_rsa_free(key); - if (memcmp(input_ptext,ptext,sizeof(input_ptext) - 1)) - return 0; return 1; } diff --git a/fips-1.0/rsa/fips_rsa_eay.c b/fips-1.0/rsa/fips_rsa_eay.c index 69fdb8380a..45b3bd1b1a 100644 --- a/fips-1.0/rsa/fips_rsa_eay.c +++ b/fips-1.0/rsa/fips_rsa_eay.c @@ -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 */ diff --git a/fips-1.0/rsa/fips_rsa_gen.c b/fips-1.0/rsa/fips_rsa_gen.c index 7d9d78d5cc..7c23ef8357 100644 --- a/fips-1.0/rsa/fips_rsa_gen.c +++ b/fips-1.0/rsa/fips_rsa_gen.c @@ -65,75 +65,34 @@ #include #include #include +#include #include #include #include +#include #include #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"; - - if (RSA_size(rsa) > sizeof(tctext)) { - ctext = OPENSSL_malloc(RSA_size(rsa)); - ptext = OPENSSL_malloc(RSA_size(rsa)); - if (!ctext || !ptext) + const unsigned char tbs[] = "RSA Pairwise Check Data"; + EVP_PKEY pk; + pk.type = EVP_PKEY_RSA; + pk.pkey.rsa = rsa; + + 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,ERR_R_MALLOC_FAILURE); - goto error; + FIPSerr(FIPS_F_FIPS_CHECK_RSA,FIPS_R_PAIRWISE_TEST_FAILED); + return 0; } + return 1; } - - - /* 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)) - { - FIPSerr(FIPS_F_FIPS_CHECK_RSA,FIPS_R_PAIRWISE_TEST_FAILED); - goto error; - } - 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; - } static int rsa_builtin_keygen(RSA *rsa, int bits, BIGNUM *e_value, BN_GENCB *cb); diff --git a/fips-1.0/rsa/fips_rsa_selftest.c b/fips-1.0/rsa/fips_rsa_selftest.c index 7fd0ccb962..4cd4a1da0f 100644 --- a/fips-1.0/rsa/fips_rsa_selftest.c +++ b/fips-1.0/rsa/fips_rsa_selftest.c @@ -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 #include #include +#include #include #include @@ -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,110 +133,300 @@ 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: ... */ - - 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; - } + int ret = 0; + RSA *key = NULL; + EVP_PKEY pk; + key=FIPS_rsa_new(); + 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); - 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); - 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); - 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); - goto err; - } + 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; + 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; + 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; + 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; - ret = 1; - err: - FIPS_rsa_free(key); - return ret; - } + 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; + + err: + FIPS_rsa_free(key); + return ret; + } #endif /* def OPENSSL_FIPS */ diff --git a/fips-1.0/rsa/fips_rsa_sign.c b/fips-1.0/rsa/fips_rsa_sign.c index 49d3b5c854..a90da2ebcf 100644 --- a/fips-1.0/rsa/fips_rsa_sign.c +++ b/fips-1.0/rsa/fips_rsa_sign.c @@ -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; -- 2.25.1