diff options
Diffstat (limited to 'openssl/fips/rsa')
-rw-r--r-- | openssl/fips/rsa/Makefile | 215 | ||||
-rw-r--r-- | openssl/fips/rsa/fips_rsa_eay.c | 934 | ||||
-rw-r--r-- | openssl/fips/rsa/fips_rsa_gen.c | 310 | ||||
-rw-r--r-- | openssl/fips/rsa/fips_rsa_lib.c | 101 | ||||
-rw-r--r-- | openssl/fips/rsa/fips_rsa_selftest.c | 432 | ||||
-rw-r--r-- | openssl/fips/rsa/fips_rsa_sign.c | 554 | ||||
-rw-r--r-- | openssl/fips/rsa/fips_rsa_x931g.c | 280 | ||||
-rw-r--r-- | openssl/fips/rsa/fips_rsagtest.c | 390 | ||||
-rw-r--r-- | openssl/fips/rsa/fips_rsastest.c | 370 | ||||
-rw-r--r-- | openssl/fips/rsa/fips_rsavtest.c | 377 |
10 files changed, 3963 insertions, 0 deletions
diff --git a/openssl/fips/rsa/Makefile b/openssl/fips/rsa/Makefile new file mode 100644 index 000000000..da28c13aa --- /dev/null +++ b/openssl/fips/rsa/Makefile @@ -0,0 +1,215 @@ +# +# OpenSSL/fips/rsa/Makefile +# + +DIR= rsa +TOP= ../.. +CC= cc +INCLUDES= +CFLAG=-g +INSTALL_PREFIX= +OPENSSLDIR= /usr/local/ssl +INSTALLTOP=/usr/local/ssl +MAKEDEPPROG= makedepend +MAKEDEPEND= $(TOP)/util/domd $(TOP) -MD $(MAKEDEPPROG) +MAKEFILE= Makefile +AR= ar r + +CFLAGS= $(INCLUDES) $(CFLAG) + +GENERAL=Makefile +TEST= fips_rsavtest.c fips_rsastest.c fips_rsagtest.c +APPS= + +LIB=$(TOP)/libcrypto.a +LIBSRC=fips_rsa_eay.c fips_rsa_gen.c fips_rsa_selftest.c fips_rsa_x931g.c \ + fips_rsa_sign.c fips_rsa_lib.c +LIBOBJ=fips_rsa_eay.o fips_rsa_gen.o fips_rsa_selftest.o fips_rsa_x931g.o \ + fips_rsa_sign.o fips_rsa_lib.o + +SRC= $(LIBSRC) + +EXHEADER= +HEADER= $(EXHEADER) + +ALL= $(GENERAL) $(SRC) $(HEADER) + +top: + (cd $(TOP); $(MAKE) DIRS=fips FDIRS=$(DIR) sub_all) + +all: lib + +lib: $(LIBOBJ) + @echo $(LIBOBJ) > lib + +files: + $(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO + +links: + @$(PERL) $(TOP)/util/mklink.pl $(TOP)/include/openssl $(EXHEADER) + @$(PERL) $(TOP)/util/mklink.pl $(TOP)/test $(TEST) + @$(PERL) $(TOP)/util/mklink.pl $(TOP)/apps $(APPS) + +install: + @headerlist="$(EXHEADER)"; for i in $$headerlist; \ + do \ + (cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i; \ + chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i ); \ + done + +tags: + ctags $(SRC) + +tests: + +Q=../testvectors/rsa/req +A=../testvectors/rsa/rsp +Q62=../testvectors/rsa_salt_62/req +A62=../testvectors/rsa_salt_62/rsp + +fips_test: + -rm -rf $(A) $(A62) + mkdir $(A) $(A62) + if [ -f $(Q)/SigGen15.req ]; then $(TOP)/util/shlib_wrap.sh $(TOP)/test/fips_rsastest < $(Q)/SigGen15.req > $(A)/SigGen15.rsp; fi + if [ -f $(Q)/SigVer15.req ]; then $(TOP)/util/shlib_wrap.sh $(TOP)/test/fips_rsavtest < $(Q)/SigVer15.req > $(A)/SigVer15.rsp; fi + if [ -f $(Q)/SigGenPSS.req ]; then $(TOP)/util/shlib_wrap.sh $(TOP)/test/fips_rsastest -saltlen 0 < $(Q)/SigGenPSS.req > $(A)/SigGenPSS.rsp; fi + if [ -f $(Q)/SigVerPSS.req ]; then $(TOP)/util/shlib_wrap.sh $(TOP)/test/fips_rsavtest -saltlen 0 < $(Q)/SigVerPSS.req > $(A)/SigVerPSS.rsp; fi + if [ -f $(Q)/SigGenRSA.req ]; then $(TOP)/util/shlib_wrap.sh $(TOP)/test/fips_rsastest -x931 < $(Q)/SigGenRSA.req > $(A)/SigGenRSA.rsp; fi + if [ -f $(Q)/SigVerRSA.req ]; then $(TOP)/util/shlib_wrap.sh $(TOP)/test/fips_rsavtest -x931 < $(Q)/SigVerRSA.req > $(A)/SigVerRSA.rsp; fi + if [ -f $(Q62)/SigGenPSS.req ]; then $(TOP)/util/shlib_wrap.sh $(TOP)/test/fips_rsastest -saltlen 62 < $(Q62)/SigGenPSS.req >$(A62)/SigGenPSS.rsp; fi + if [ -f $(Q62)/SigVerPSS.req ]; then $(TOP)/util/shlib_wrap.sh $(TOP)/test/fips_rsavtest -saltlen 62 <$(Q62)/SigVerPSS.req >$(A62)/SigVerPSS.rsp; fi + if [ -f $(Q)/KeyGenRSA.req ]; then $(TOP)/util/shlib_wrap.sh $(TOP)/test/fips_rsagtest < $(Q)/KeyGenRSA.req > $(A)/KeyGenRSA.rsp; fi + +lint: + lint -DLINT $(INCLUDES) $(SRC)>fluff + +depend: + $(MAKEDEPEND) -- $(CFLAG) $(INCLUDES) $(DEPFLAG) -- $(SRC) $(TEST) + +dclean: + $(PERL) -pe 'if (/^# DO NOT DELETE THIS LINE/) {print; exit(0);}' $(MAKEFILE) >Makefile.new + mv -f Makefile.new $(MAKEFILE) + +clean: + rm -f *.o *.obj lib tags core .pure .nfs* *.old *.bak fluff +# DO NOT DELETE THIS LINE -- make depend depends on it. + +fips_rsa_eay.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h +fips_rsa_eay.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h +fips_rsa_eay.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h +fips_rsa_eay.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h +fips_rsa_eay.o: ../../include/openssl/opensslconf.h +fips_rsa_eay.o: ../../include/openssl/opensslv.h +fips_rsa_eay.o: ../../include/openssl/ossl_typ.h ../../include/openssl/rand.h +fips_rsa_eay.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h +fips_rsa_eay.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h +fips_rsa_eay.o: fips_rsa_eay.c +fips_rsa_gen.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h +fips_rsa_gen.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h +fips_rsa_gen.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h +fips_rsa_gen.o: ../../include/openssl/evp.h ../../include/openssl/fips.h +fips_rsa_gen.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h +fips_rsa_gen.o: ../../include/openssl/objects.h +fips_rsa_gen.o: ../../include/openssl/opensslconf.h +fips_rsa_gen.o: ../../include/openssl/opensslv.h +fips_rsa_gen.o: ../../include/openssl/ossl_typ.h ../../include/openssl/rsa.h +fips_rsa_gen.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h +fips_rsa_gen.o: ../../include/openssl/symhacks.h ../fips_locl.h fips_rsa_gen.c +fips_rsa_lib.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h +fips_rsa_lib.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h +fips_rsa_lib.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h +fips_rsa_lib.o: ../../include/openssl/evp.h ../../include/openssl/fips.h +fips_rsa_lib.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h +fips_rsa_lib.o: ../../include/openssl/objects.h +fips_rsa_lib.o: ../../include/openssl/opensslconf.h +fips_rsa_lib.o: ../../include/openssl/opensslv.h +fips_rsa_lib.o: ../../include/openssl/ossl_typ.h ../../include/openssl/rsa.h +fips_rsa_lib.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h +fips_rsa_lib.o: ../../include/openssl/symhacks.h fips_rsa_lib.c +fips_rsa_selftest.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h +fips_rsa_selftest.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h +fips_rsa_selftest.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h +fips_rsa_selftest.o: ../../include/openssl/evp.h ../../include/openssl/fips.h +fips_rsa_selftest.o: ../../include/openssl/lhash.h +fips_rsa_selftest.o: ../../include/openssl/obj_mac.h +fips_rsa_selftest.o: ../../include/openssl/objects.h +fips_rsa_selftest.o: ../../include/openssl/opensslconf.h +fips_rsa_selftest.o: ../../include/openssl/opensslv.h +fips_rsa_selftest.o: ../../include/openssl/ossl_typ.h +fips_rsa_selftest.o: ../../include/openssl/rsa.h +fips_rsa_selftest.o: ../../include/openssl/safestack.h +fips_rsa_selftest.o: ../../include/openssl/stack.h +fips_rsa_selftest.o: ../../include/openssl/symhacks.h fips_rsa_selftest.c +fips_rsa_sign.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h +fips_rsa_sign.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h +fips_rsa_sign.o: ../../include/openssl/err.h ../../include/openssl/evp.h +fips_rsa_sign.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h +fips_rsa_sign.o: ../../include/openssl/obj_mac.h +fips_rsa_sign.o: ../../include/openssl/objects.h +fips_rsa_sign.o: ../../include/openssl/opensslconf.h +fips_rsa_sign.o: ../../include/openssl/opensslv.h +fips_rsa_sign.o: ../../include/openssl/ossl_typ.h ../../include/openssl/rsa.h +fips_rsa_sign.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h +fips_rsa_sign.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h +fips_rsa_sign.o: fips_rsa_sign.c +fips_rsa_x931g.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h +fips_rsa_x931g.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h +fips_rsa_x931g.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h +fips_rsa_x931g.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h +fips_rsa_x931g.o: ../../include/openssl/opensslconf.h +fips_rsa_x931g.o: ../../include/openssl/opensslv.h +fips_rsa_x931g.o: ../../include/openssl/ossl_typ.h ../../include/openssl/rsa.h +fips_rsa_x931g.o: ../../include/openssl/safestack.h +fips_rsa_x931g.o: ../../include/openssl/stack.h +fips_rsa_x931g.o: ../../include/openssl/symhacks.h fips_rsa_x931g.c +fips_rsagtest.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h +fips_rsagtest.o: ../../include/openssl/bn.h ../../include/openssl/buffer.h +fips_rsagtest.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h +fips_rsagtest.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h +fips_rsagtest.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h +fips_rsagtest.o: ../../include/openssl/err.h ../../include/openssl/evp.h +fips_rsagtest.o: ../../include/openssl/fips.h ../../include/openssl/hmac.h +fips_rsagtest.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h +fips_rsagtest.o: ../../include/openssl/objects.h +fips_rsagtest.o: ../../include/openssl/opensslconf.h +fips_rsagtest.o: ../../include/openssl/opensslv.h +fips_rsagtest.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h +fips_rsagtest.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h +fips_rsagtest.o: ../../include/openssl/sha.h ../../include/openssl/stack.h +fips_rsagtest.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h +fips_rsagtest.o: ../../include/openssl/x509_vfy.h +fips_rsagtest.o: ../../include/openssl/x509v3.h ../fips_utl.h fips_rsagtest.c +fips_rsastest.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h +fips_rsastest.o: ../../include/openssl/bn.h ../../include/openssl/buffer.h +fips_rsastest.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h +fips_rsastest.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h +fips_rsastest.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h +fips_rsastest.o: ../../include/openssl/err.h ../../include/openssl/evp.h +fips_rsastest.o: ../../include/openssl/fips.h ../../include/openssl/hmac.h +fips_rsastest.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h +fips_rsastest.o: ../../include/openssl/objects.h +fips_rsastest.o: ../../include/openssl/opensslconf.h +fips_rsastest.o: ../../include/openssl/opensslv.h +fips_rsastest.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h +fips_rsastest.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h +fips_rsastest.o: ../../include/openssl/sha.h ../../include/openssl/stack.h +fips_rsastest.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h +fips_rsastest.o: ../../include/openssl/x509_vfy.h +fips_rsastest.o: ../../include/openssl/x509v3.h ../fips_utl.h fips_rsastest.c +fips_rsavtest.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h +fips_rsavtest.o: ../../include/openssl/bn.h ../../include/openssl/buffer.h +fips_rsavtest.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h +fips_rsavtest.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h +fips_rsavtest.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h +fips_rsavtest.o: ../../include/openssl/err.h ../../include/openssl/evp.h +fips_rsavtest.o: ../../include/openssl/fips.h ../../include/openssl/hmac.h +fips_rsavtest.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h +fips_rsavtest.o: ../../include/openssl/objects.h +fips_rsavtest.o: ../../include/openssl/opensslconf.h +fips_rsavtest.o: ../../include/openssl/opensslv.h +fips_rsavtest.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h +fips_rsavtest.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h +fips_rsavtest.o: ../../include/openssl/sha.h ../../include/openssl/stack.h +fips_rsavtest.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h +fips_rsavtest.o: ../../include/openssl/x509_vfy.h +fips_rsavtest.o: ../../include/openssl/x509v3.h ../fips_utl.h fips_rsavtest.c diff --git a/openssl/fips/rsa/fips_rsa_eay.c b/openssl/fips/rsa/fips_rsa_eay.c new file mode 100644 index 000000000..937a14e68 --- /dev/null +++ b/openssl/fips/rsa/fips_rsa_eay.c @@ -0,0 +1,934 @@ +/* crypto/rsa/rsa_eay.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include <stdio.h> +#include <openssl/bn.h> +#include <openssl/rsa.h> +#include <openssl/rand.h> +#include <openssl/err.h> +#include <openssl/fips.h> + +#if !defined(RSA_NULL) && defined(OPENSSL_FIPS) + +static int RSA_eay_public_encrypt(int flen, const unsigned char *from, + unsigned char *to, RSA *rsa,int padding); +static int RSA_eay_private_encrypt(int flen, const unsigned char *from, + unsigned char *to, RSA *rsa,int padding); +static int RSA_eay_public_decrypt(int flen, const unsigned char *from, + unsigned char *to, RSA *rsa,int padding); +static int RSA_eay_private_decrypt(int flen, const unsigned char *from, + unsigned char *to, RSA *rsa,int padding); +static int RSA_eay_mod_exp(BIGNUM *r0, const BIGNUM *i, RSA *rsa, BN_CTX *ctx); +static int RSA_eay_init(RSA *rsa); +static int RSA_eay_finish(RSA *rsa); +static RSA_METHOD rsa_pkcs1_eay_meth={ + "Eric Young's PKCS#1 RSA", + RSA_eay_public_encrypt, + RSA_eay_public_decrypt, /* signature verification */ + RSA_eay_private_encrypt, /* signing */ + RSA_eay_private_decrypt, + RSA_eay_mod_exp, + BN_mod_exp_mont, /* XXX probably we should not use Montgomery if e == 3 */ + RSA_eay_init, + RSA_eay_finish, + RSA_FLAG_FIPS_METHOD, /* flags */ + NULL, + 0, /* rsa_sign */ + 0, /* rsa_verify */ + NULL /* rsa_keygen */ + }; + +const RSA_METHOD *RSA_PKCS1_SSLeay(void) + { + return(&rsa_pkcs1_eay_meth); + } + +/* Usage example; + * MONT_HELPER(rsa, bn_ctx, p, rsa->flags & RSA_FLAG_CACHE_PRIVATE, goto err); + */ +#define MONT_HELPER(rsa, ctx, m, pre_cond, err_instr) \ + if((pre_cond) && ((rsa)->_method_mod_##m == NULL) && \ + !BN_MONT_CTX_set_locked(&((rsa)->_method_mod_##m), \ + CRYPTO_LOCK_RSA, \ + (rsa)->m, (ctx))) \ + err_instr + +static int RSA_eay_public_encrypt(int flen, const unsigned char *from, + unsigned char *to, RSA *rsa, int padding) + { + BIGNUM *f,*ret; + int i,j,k,num=0,r= -1; + unsigned char *buf=NULL; + BN_CTX *ctx=NULL; + + if(FIPS_selftest_failed()) + { + FIPSerr(FIPS_F_RSA_EAY_PUBLIC_ENCRYPT,FIPS_R_FIPS_SELFTEST_FAILED); + goto err; + } + + if (FIPS_mode() && (BN_num_bits(rsa->n) < OPENSSL_RSA_FIPS_MIN_MODULUS_BITS)) + { + RSAerr(RSA_F_RSA_EAY_PUBLIC_ENCRYPT, RSA_R_KEY_SIZE_TOO_SMALL); + return -1; + } + + if (BN_num_bits(rsa->n) > OPENSSL_RSA_MAX_MODULUS_BITS) + { + RSAerr(RSA_F_RSA_EAY_PUBLIC_ENCRYPT, RSA_R_MODULUS_TOO_LARGE); + return -1; + } + + if (BN_ucmp(rsa->n, rsa->e) <= 0) + { + RSAerr(RSA_F_RSA_EAY_PUBLIC_ENCRYPT, RSA_R_BAD_E_VALUE); + return -1; + } + + /* for large moduli, enforce exponent limit */ + if (BN_num_bits(rsa->n) > OPENSSL_RSA_SMALL_MODULUS_BITS) + { + if (BN_num_bits(rsa->e) > OPENSSL_RSA_MAX_PUBEXP_BITS) + { + RSAerr(RSA_F_RSA_EAY_PUBLIC_ENCRYPT, RSA_R_BAD_E_VALUE); + return -1; + } + } + + if ((ctx=BN_CTX_new()) == NULL) goto err; + BN_CTX_start(ctx); + f = BN_CTX_get(ctx); + ret = BN_CTX_get(ctx); + num=BN_num_bytes(rsa->n); + buf = OPENSSL_malloc(num); + if (!f || !ret || !buf) + { + RSAerr(RSA_F_RSA_EAY_PUBLIC_ENCRYPT,ERR_R_MALLOC_FAILURE); + goto err; + } + + switch (padding) + { + case RSA_PKCS1_PADDING: + i=RSA_padding_add_PKCS1_type_2(buf,num,from,flen); + break; +#ifndef OPENSSL_NO_SHA + case RSA_PKCS1_OAEP_PADDING: + i=RSA_padding_add_PKCS1_OAEP(buf,num,from,flen,NULL,0); + break; +#endif + case RSA_SSLV23_PADDING: + i=RSA_padding_add_SSLv23(buf,num,from,flen); + break; + case RSA_NO_PADDING: + i=RSA_padding_add_none(buf,num,from,flen); + break; + default: + RSAerr(RSA_F_RSA_EAY_PUBLIC_ENCRYPT,RSA_R_UNKNOWN_PADDING_TYPE); + goto err; + } + if (i <= 0) goto err; + + if (BN_bin2bn(buf,num,f) == NULL) goto err; + + if (BN_ucmp(f, rsa->n) >= 0) + { + /* usually the padding functions would catch this */ + RSAerr(RSA_F_RSA_EAY_PUBLIC_ENCRYPT,RSA_R_DATA_TOO_LARGE_FOR_MODULUS); + goto err; + } + + MONT_HELPER(rsa, ctx, n, rsa->flags & RSA_FLAG_CACHE_PUBLIC, goto err); + + if (!rsa->meth->bn_mod_exp(ret,f,rsa->e,rsa->n,ctx, + rsa->_method_mod_n)) goto err; + + /* put in leading 0 bytes if the number is less than the + * length of the modulus */ + j=BN_num_bytes(ret); + i=BN_bn2bin(ret,&(to[num-j])); + for (k=0; k<(num-i); k++) + to[k]=0; + + r=num; +err: + if (ctx != NULL) + { + BN_CTX_end(ctx); + BN_CTX_free(ctx); + } + if (buf != NULL) + { + OPENSSL_cleanse(buf,num); + OPENSSL_free(buf); + } + return(r); + } + +static BN_BLINDING *rsa_get_blinding(RSA *rsa, int *local, BN_CTX *ctx) +{ + BN_BLINDING *ret; + int got_write_lock = 0; + + CRYPTO_r_lock(CRYPTO_LOCK_RSA); + + if (rsa->blinding == NULL) + { + CRYPTO_r_unlock(CRYPTO_LOCK_RSA); + CRYPTO_w_lock(CRYPTO_LOCK_RSA); + got_write_lock = 1; + + if (rsa->blinding == NULL) + rsa->blinding = RSA_setup_blinding(rsa, ctx); + } + + ret = rsa->blinding; + if (ret == NULL) + goto err; + + if (BN_BLINDING_get_thread_id(ret) == CRYPTO_thread_id()) + { + /* rsa->blinding is ours! */ + + *local = 1; + } + else + { + /* resort to rsa->mt_blinding instead */ + + *local = 0; /* instructs rsa_blinding_convert(), rsa_blinding_invert() + * that the BN_BLINDING is shared, meaning that accesses + * require locks, and that the blinding factor must be + * stored outside the BN_BLINDING + */ + + if (rsa->mt_blinding == NULL) + { + if (!got_write_lock) + { + CRYPTO_r_unlock(CRYPTO_LOCK_RSA); + CRYPTO_w_lock(CRYPTO_LOCK_RSA); + got_write_lock = 1; + } + + if (rsa->mt_blinding == NULL) + rsa->mt_blinding = RSA_setup_blinding(rsa, ctx); + } + ret = rsa->mt_blinding; + } + + err: + if (got_write_lock) + CRYPTO_w_unlock(CRYPTO_LOCK_RSA); + else + CRYPTO_r_unlock(CRYPTO_LOCK_RSA); + return ret; +} + +static int rsa_blinding_convert(BN_BLINDING *b, int local, BIGNUM *f, + BIGNUM *r, BN_CTX *ctx) +{ + if (local) + return BN_BLINDING_convert_ex(f, NULL, b, ctx); + else + { + int ret; + CRYPTO_r_lock(CRYPTO_LOCK_RSA_BLINDING); + ret = BN_BLINDING_convert_ex(f, r, b, ctx); + CRYPTO_r_unlock(CRYPTO_LOCK_RSA_BLINDING); + return ret; + } +} + +static int rsa_blinding_invert(BN_BLINDING *b, int local, BIGNUM *f, + BIGNUM *r, BN_CTX *ctx) +{ + if (local) + return BN_BLINDING_invert_ex(f, NULL, b, ctx); + else + { + int ret; + CRYPTO_w_lock(CRYPTO_LOCK_RSA_BLINDING); + ret = BN_BLINDING_invert_ex(f, r, b, ctx); + CRYPTO_w_unlock(CRYPTO_LOCK_RSA_BLINDING); + return ret; + } +} + +/* signing */ +static int RSA_eay_private_encrypt(int flen, const unsigned char *from, + unsigned char *to, RSA *rsa, int padding) + { + BIGNUM *f, *ret, *br, *res; + int i,j,k,num=0,r= -1; + unsigned char *buf=NULL; + BN_CTX *ctx=NULL; + int local_blinding = 0; + BN_BLINDING *blinding = NULL; + + if(FIPS_selftest_failed()) + { + FIPSerr(FIPS_F_RSA_EAY_PRIVATE_ENCRYPT,FIPS_R_FIPS_SELFTEST_FAILED); + goto err; + } + + if (FIPS_mode() && (BN_num_bits(rsa->n) < OPENSSL_RSA_FIPS_MIN_MODULUS_BITS)) + { + RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT, RSA_R_KEY_SIZE_TOO_SMALL); + return -1; + } + + if ((ctx=BN_CTX_new()) == NULL) goto err; + BN_CTX_start(ctx); + f = BN_CTX_get(ctx); + br = BN_CTX_get(ctx); + ret = BN_CTX_get(ctx); + num = BN_num_bytes(rsa->n); + buf = OPENSSL_malloc(num); + if(!f || !ret || !buf) + { + RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT,ERR_R_MALLOC_FAILURE); + goto err; + } + + switch (padding) + { + case RSA_PKCS1_PADDING: + i=RSA_padding_add_PKCS1_type_1(buf,num,from,flen); + break; + case RSA_X931_PADDING: + i=RSA_padding_add_X931(buf,num,from,flen); + break; + case RSA_NO_PADDING: + i=RSA_padding_add_none(buf,num,from,flen); + break; + case RSA_SSLV23_PADDING: + default: + RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT,RSA_R_UNKNOWN_PADDING_TYPE); + goto err; + } + if (i <= 0) goto err; + + if (BN_bin2bn(buf,num,f) == NULL) goto err; + + if (BN_ucmp(f, rsa->n) >= 0) + { + /* usually the padding functions would catch this */ + RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT,RSA_R_DATA_TOO_LARGE_FOR_MODULUS); + goto err; + } + + if (!(rsa->flags & RSA_FLAG_NO_BLINDING)) + { + blinding = rsa_get_blinding(rsa, &local_blinding, ctx); + if (blinding == NULL) + { + RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT, ERR_R_INTERNAL_ERROR); + goto err; + } + } + + if (blinding != NULL) + if (!rsa_blinding_convert(blinding, local_blinding, f, br, ctx)) + goto err; + + if ( (rsa->flags & RSA_FLAG_EXT_PKEY) || + ((rsa->p != NULL) && + (rsa->q != NULL) && + (rsa->dmp1 != NULL) && + (rsa->dmq1 != NULL) && + (rsa->iqmp != NULL)) ) + { + if (!rsa->meth->rsa_mod_exp(ret, f, rsa, ctx)) goto err; + } + else + { + BIGNUM local_d; + BIGNUM *d = NULL; + + if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME)) + { + BN_init(&local_d); + d = &local_d; + BN_with_flags(d, rsa->d, BN_FLG_CONSTTIME); + } + else + d = rsa->d; + + MONT_HELPER(rsa, ctx, n, rsa->flags & RSA_FLAG_CACHE_PUBLIC, goto err); + + if (!rsa->meth->bn_mod_exp(ret,f,d,rsa->n,ctx, + rsa->_method_mod_n)) goto err; + } + + if (blinding) + if (!rsa_blinding_invert(blinding, local_blinding, ret, br, ctx)) + goto err; + + if (padding == RSA_X931_PADDING) + { + BN_sub(f, rsa->n, ret); + if (BN_cmp(ret, f)) + res = f; + else + res = ret; + } + else + res = ret; + + /* put in leading 0 bytes if the number is less than the + * length of the modulus */ + j=BN_num_bytes(res); + i=BN_bn2bin(res,&(to[num-j])); + for (k=0; k<(num-i); k++) + to[k]=0; + + r=num; +err: + if (ctx != NULL) + { + BN_CTX_end(ctx); + BN_CTX_free(ctx); + } + if (buf != NULL) + { + OPENSSL_cleanse(buf,num); + OPENSSL_free(buf); + } + return(r); + } + +static int RSA_eay_private_decrypt(int flen, const unsigned char *from, + unsigned char *to, RSA *rsa, int padding) + { + BIGNUM *f, *ret, *br; + int j,num=0,r= -1; + unsigned char *p; + unsigned char *buf=NULL; + BN_CTX *ctx=NULL; + int local_blinding = 0; + BN_BLINDING *blinding = NULL; + + if(FIPS_selftest_failed()) + { + FIPSerr(FIPS_F_RSA_EAY_PRIVATE_DECRYPT,FIPS_R_FIPS_SELFTEST_FAILED); + goto err; + } + + if (FIPS_mode() && (BN_num_bits(rsa->n) < OPENSSL_RSA_FIPS_MIN_MODULUS_BITS)) + { + RSAerr(RSA_F_RSA_EAY_PRIVATE_DECRYPT, RSA_R_KEY_SIZE_TOO_SMALL); + return -1; + } + + if((ctx = BN_CTX_new()) == NULL) goto err; + BN_CTX_start(ctx); + f = BN_CTX_get(ctx); + br = BN_CTX_get(ctx); + ret = BN_CTX_get(ctx); + num = BN_num_bytes(rsa->n); + buf = OPENSSL_malloc(num); + if(!f || !ret || !buf) + { + RSAerr(RSA_F_RSA_EAY_PRIVATE_DECRYPT,ERR_R_MALLOC_FAILURE); + goto err; + } + + /* This check was for equality but PGP does evil things + * and chops off the top '0' bytes */ + if (flen > num) + { + RSAerr(RSA_F_RSA_EAY_PRIVATE_DECRYPT,RSA_R_DATA_GREATER_THAN_MOD_LEN); + goto err; + } + + /* make data into a big number */ + if (BN_bin2bn(from,(int)flen,f) == NULL) goto err; + + if (BN_ucmp(f, rsa->n) >= 0) + { + RSAerr(RSA_F_RSA_EAY_PRIVATE_DECRYPT,RSA_R_DATA_TOO_LARGE_FOR_MODULUS); + goto err; + } + + if (!(rsa->flags & RSA_FLAG_NO_BLINDING)) + { + blinding = rsa_get_blinding(rsa, &local_blinding, ctx); + if (blinding == NULL) + { + RSAerr(RSA_F_RSA_EAY_PRIVATE_DECRYPT, ERR_R_INTERNAL_ERROR); + goto err; + } + } + + if (blinding != NULL) + if (!rsa_blinding_convert(blinding, local_blinding, f, br, ctx)) + goto err; + + /* do the decrypt */ + if ( (rsa->flags & RSA_FLAG_EXT_PKEY) || + ((rsa->p != NULL) && + (rsa->q != NULL) && + (rsa->dmp1 != NULL) && + (rsa->dmq1 != NULL) && + (rsa->iqmp != NULL)) ) + { + if (!rsa->meth->rsa_mod_exp(ret, f, rsa, ctx)) goto err; + } + else + { + BIGNUM local_d; + BIGNUM *d = NULL; + + if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME)) + { + d = &local_d; + BN_with_flags(d, rsa->d, BN_FLG_CONSTTIME); + } + else + d = rsa->d; + + MONT_HELPER(rsa, ctx, n, rsa->flags & RSA_FLAG_CACHE_PUBLIC, goto err); + if (!rsa->meth->bn_mod_exp(ret,f,d,rsa->n,ctx, + rsa->_method_mod_n)) + goto err; + } + + if (blinding) + if (!rsa_blinding_invert(blinding, local_blinding, ret, br, ctx)) + goto err; + + p=buf; + j=BN_bn2bin(ret,p); /* j is only used with no-padding mode */ + + switch (padding) + { + case RSA_PKCS1_PADDING: + r=RSA_padding_check_PKCS1_type_2(to,num,buf,j,num); + break; +#ifndef OPENSSL_NO_SHA + case RSA_PKCS1_OAEP_PADDING: + r=RSA_padding_check_PKCS1_OAEP(to,num,buf,j,num,NULL,0); + break; +#endif + case RSA_SSLV23_PADDING: + r=RSA_padding_check_SSLv23(to,num,buf,j,num); + break; + case RSA_NO_PADDING: + r=RSA_padding_check_none(to,num,buf,j,num); + break; + default: + RSAerr(RSA_F_RSA_EAY_PRIVATE_DECRYPT,RSA_R_UNKNOWN_PADDING_TYPE); + goto err; + } + if (r < 0) + RSAerr(RSA_F_RSA_EAY_PRIVATE_DECRYPT,RSA_R_PADDING_CHECK_FAILED); + +err: + if (ctx != NULL) + { + BN_CTX_end(ctx); + BN_CTX_free(ctx); + } + if (buf != NULL) + { + OPENSSL_cleanse(buf,num); + OPENSSL_free(buf); + } + return(r); + } + +/* signature verification */ +static int RSA_eay_public_decrypt(int flen, const unsigned char *from, + unsigned char *to, RSA *rsa, int padding) + { + BIGNUM *f,*ret; + int i,num=0,r= -1; + unsigned char *p; + unsigned char *buf=NULL; + BN_CTX *ctx=NULL; + + if(FIPS_selftest_failed()) + { + FIPSerr(FIPS_F_RSA_EAY_PUBLIC_DECRYPT,FIPS_R_FIPS_SELFTEST_FAILED); + goto err; + } + + if (FIPS_mode() && (BN_num_bits(rsa->n) < OPENSSL_RSA_FIPS_MIN_MODULUS_BITS)) + { + RSAerr(RSA_F_RSA_EAY_PUBLIC_DECRYPT, RSA_R_KEY_SIZE_TOO_SMALL); + return -1; + } + + if (BN_num_bits(rsa->n) > OPENSSL_RSA_MAX_MODULUS_BITS) + { + RSAerr(RSA_F_RSA_EAY_PUBLIC_DECRYPT, RSA_R_MODULUS_TOO_LARGE); + return -1; + } + + if (BN_ucmp(rsa->n, rsa->e) <= 0) + { + RSAerr(RSA_F_RSA_EAY_PUBLIC_DECRYPT, RSA_R_BAD_E_VALUE); + return -1; + } + + /* for large moduli, enforce exponent limit */ + if (BN_num_bits(rsa->n) > OPENSSL_RSA_SMALL_MODULUS_BITS) + { + if (BN_num_bits(rsa->e) > OPENSSL_RSA_MAX_PUBEXP_BITS) + { + RSAerr(RSA_F_RSA_EAY_PUBLIC_DECRYPT, RSA_R_BAD_E_VALUE); + return -1; + } + } + + if((ctx = BN_CTX_new()) == NULL) goto err; + BN_CTX_start(ctx); + f = BN_CTX_get(ctx); + ret = BN_CTX_get(ctx); + num=BN_num_bytes(rsa->n); + buf = OPENSSL_malloc(num); + if(!f || !ret || !buf) + { + RSAerr(RSA_F_RSA_EAY_PUBLIC_DECRYPT,ERR_R_MALLOC_FAILURE); + goto err; + } + + /* This check was for equality but PGP does evil things + * and chops off the top '0' bytes */ + if (flen > num) + { + RSAerr(RSA_F_RSA_EAY_PUBLIC_DECRYPT,RSA_R_DATA_GREATER_THAN_MOD_LEN); + goto err; + } + + if (BN_bin2bn(from,flen,f) == NULL) goto err; + + if (BN_ucmp(f, rsa->n) >= 0) + { + RSAerr(RSA_F_RSA_EAY_PUBLIC_DECRYPT,RSA_R_DATA_TOO_LARGE_FOR_MODULUS); + goto err; + } + + MONT_HELPER(rsa, ctx, n, rsa->flags & RSA_FLAG_CACHE_PUBLIC, goto err); + + if (!rsa->meth->bn_mod_exp(ret,f,rsa->e,rsa->n,ctx, + rsa->_method_mod_n)) goto err; + + if ((padding == RSA_X931_PADDING) && ((ret->d[0] & 0xf) != 12)) + BN_sub(ret, rsa->n, ret); + + p=buf; + i=BN_bn2bin(ret,p); + + switch (padding) + { + case RSA_PKCS1_PADDING: + r=RSA_padding_check_PKCS1_type_1(to,num,buf,i,num); + break; + case RSA_X931_PADDING: + r=RSA_padding_check_X931(to,num,buf,i,num); + break; + case RSA_NO_PADDING: + r=RSA_padding_check_none(to,num,buf,i,num); + break; + default: + RSAerr(RSA_F_RSA_EAY_PUBLIC_DECRYPT,RSA_R_UNKNOWN_PADDING_TYPE); + goto err; + } + if (r < 0) + RSAerr(RSA_F_RSA_EAY_PUBLIC_DECRYPT,RSA_R_PADDING_CHECK_FAILED); + +err: + if (ctx != NULL) + { + BN_CTX_end(ctx); + BN_CTX_free(ctx); + } + if (buf != NULL) + { + OPENSSL_cleanse(buf,num); + OPENSSL_free(buf); + } + return(r); + } + +static int RSA_eay_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx) + { + BIGNUM *r1,*m1,*vrfy; + BIGNUM local_dmp1,local_dmq1,local_c,local_r1; + BIGNUM *dmp1,*dmq1,*c,*pr1; + int bn_flags; + int ret=0; + + BN_CTX_start(ctx); + r1 = BN_CTX_get(ctx); + m1 = BN_CTX_get(ctx); + vrfy = BN_CTX_get(ctx); + + /* Make sure mod_inverse in montgomerey intialization use correct + * BN_FLG_CONSTTIME flag. + */ + bn_flags = rsa->p->flags; + if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME)) + { + rsa->p->flags |= BN_FLG_CONSTTIME; + } + MONT_HELPER(rsa, ctx, p, rsa->flags & RSA_FLAG_CACHE_PRIVATE, goto err); + /* We restore bn_flags back */ + rsa->p->flags = bn_flags; + + /* Make sure mod_inverse in montgomerey intialization use correct + * BN_FLG_CONSTTIME flag. + */ + bn_flags = rsa->q->flags; + if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME)) + { + rsa->q->flags |= BN_FLG_CONSTTIME; + } + MONT_HELPER(rsa, ctx, q, rsa->flags & RSA_FLAG_CACHE_PRIVATE, goto err); + /* We restore bn_flags back */ + rsa->q->flags = bn_flags; + + MONT_HELPER(rsa, ctx, n, rsa->flags & RSA_FLAG_CACHE_PUBLIC, goto err); + + /* compute I mod q */ + if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME)) + { + c = &local_c; + BN_with_flags(c, I, BN_FLG_CONSTTIME); + if (!BN_mod(r1,c,rsa->q,ctx)) goto err; + } + else + { + if (!BN_mod(r1,I,rsa->q,ctx)) goto err; + } + + /* compute r1^dmq1 mod q */ + if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME)) + { + dmq1 = &local_dmq1; + BN_with_flags(dmq1, rsa->dmq1, BN_FLG_CONSTTIME); + } + else + dmq1 = rsa->dmq1; + if (!rsa->meth->bn_mod_exp(m1,r1,dmq1,rsa->q,ctx, + rsa->_method_mod_q)) goto err; + + /* compute I mod p */ + if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME)) + { + c = &local_c; + BN_with_flags(c, I, BN_FLG_CONSTTIME); + if (!BN_mod(r1,c,rsa->p,ctx)) goto err; + } + else + { + if (!BN_mod(r1,I,rsa->p,ctx)) goto err; + } + + /* compute r1^dmp1 mod p */ + if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME)) + { + dmp1 = &local_dmp1; + BN_with_flags(dmp1, rsa->dmp1, BN_FLG_CONSTTIME); + } + else + dmp1 = rsa->dmp1; + if (!rsa->meth->bn_mod_exp(r0,r1,dmp1,rsa->p,ctx, + rsa->_method_mod_p)) goto err; + + if (!BN_sub(r0,r0,m1)) goto err; + /* This will help stop the size of r0 increasing, which does + * affect the multiply if it optimised for a power of 2 size */ + if (BN_is_negative(r0)) + if (!BN_add(r0,r0,rsa->p)) goto err; + + if (!BN_mul(r1,r0,rsa->iqmp,ctx)) goto err; + + /* Turn BN_FLG_CONSTTIME flag on before division operation */ + if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME)) + { + pr1 = &local_r1; + BN_with_flags(pr1, r1, BN_FLG_CONSTTIME); + } + else + pr1 = r1; + if (!BN_mod(r0,pr1,rsa->p,ctx)) goto err; + + /* If p < q it is occasionally possible for the correction of + * adding 'p' if r0 is negative above to leave the result still + * negative. This can break the private key operations: the following + * second correction should *always* correct this rare occurrence. + * This will *never* happen with OpenSSL generated keys because + * they ensure p > q [steve] + */ + if (BN_is_negative(r0)) + if (!BN_add(r0,r0,rsa->p)) goto err; + if (!BN_mul(r1,r0,rsa->q,ctx)) goto err; + if (!BN_add(r0,r1,m1)) goto err; + + if (rsa->e && rsa->n) + { + if (!rsa->meth->bn_mod_exp(vrfy,r0,rsa->e,rsa->n,ctx,rsa->_method_mod_n)) goto err; + /* If 'I' was greater than (or equal to) rsa->n, the operation + * will be equivalent to using 'I mod n'. However, the result of + * the verify will *always* be less than 'n' so we don't check + * for absolute equality, just congruency. */ + if (!BN_sub(vrfy, vrfy, I)) goto err; + if (!BN_mod(vrfy, vrfy, rsa->n, ctx)) goto err; + if (BN_is_negative(vrfy)) + if (!BN_add(vrfy, vrfy, rsa->n)) goto err; + if (!BN_is_zero(vrfy)) + { + /* 'I' and 'vrfy' aren't congruent mod n. Don't leak + * miscalculated CRT output, just do a raw (slower) + * mod_exp and return that instead. */ + + BIGNUM local_d; + BIGNUM *d = NULL; + + if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME)) + { + d = &local_d; + BN_with_flags(d, rsa->d, BN_FLG_CONSTTIME); + } + else + d = rsa->d; + if (!rsa->meth->bn_mod_exp(r0,I,d,rsa->n,ctx, + rsa->_method_mod_n)) goto err; + } + } + ret=1; +err: + BN_CTX_end(ctx); + return(ret); + } + +static int RSA_eay_init(RSA *rsa) + { + FIPS_selftest_check(); + rsa->flags|=RSA_FLAG_CACHE_PUBLIC|RSA_FLAG_CACHE_PRIVATE; + return(1); + } + +static int RSA_eay_finish(RSA *rsa) + { + if (rsa->_method_mod_n != NULL) + BN_MONT_CTX_free(rsa->_method_mod_n); + if (rsa->_method_mod_p != NULL) + BN_MONT_CTX_free(rsa->_method_mod_p); + if (rsa->_method_mod_q != NULL) + BN_MONT_CTX_free(rsa->_method_mod_q); + return(1); + } + +#endif diff --git a/openssl/fips/rsa/fips_rsa_gen.c b/openssl/fips/rsa/fips_rsa_gen.c new file mode 100644 index 000000000..90aaa2f09 --- /dev/null +++ b/openssl/fips/rsa/fips_rsa_gen.c @@ -0,0 +1,310 @@ +/* crypto/rsa/rsa_gen.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + + +/* NB: these functions have been "upgraded", the deprecated versions (which are + * compatibility wrappers using these functions) are in rsa_depr.c. + * - Geoff + */ + +#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> +#include "fips_locl.h" + +#ifdef OPENSSL_FIPS + +static int fips_rsa_pairwise_fail = 0; + +void FIPS_corrupt_rsa_keygen(void) + { + fips_rsa_pairwise_fail = 1; + } + +int fips_check_rsa(RSA *rsa) + { + const unsigned char tbs[] = "RSA Pairwise Check Data"; + unsigned char *ctbuf = NULL, *ptbuf = NULL; + int len, ret = 0; + EVP_PKEY pk; + pk.type = EVP_PKEY_RSA; + pk.pkey.rsa = rsa; + + /* Perform pairwise consistency signature test */ + 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)) + goto err; + /* Now perform pairwise consistency encrypt/decrypt test */ + ctbuf = OPENSSL_malloc(RSA_size(rsa)); + if (!ctbuf) + goto err; + + len = RSA_public_encrypt(sizeof(tbs) - 1, tbs, ctbuf, rsa, RSA_PKCS1_PADDING); + if (len <= 0) + goto err; + /* Check ciphertext doesn't match plaintext */ + if ((len == (sizeof(tbs) - 1)) && !memcmp(tbs, ctbuf, len)) + goto err; + ptbuf = OPENSSL_malloc(RSA_size(rsa)); + + if (!ptbuf) + goto err; + len = RSA_private_decrypt(len, ctbuf, ptbuf, rsa, RSA_PKCS1_PADDING); + if (len != (sizeof(tbs) - 1)) + goto err; + if (memcmp(ptbuf, tbs, len)) + goto err; + + ret = 1; + + if (!ptbuf) + goto err; + + err: + if (ret == 0) + { + fips_set_selftest_fail(); + FIPSerr(FIPS_F_FIPS_CHECK_RSA,FIPS_R_PAIRWISE_TEST_FAILED); + } + + if (ctbuf) + OPENSSL_free(ctbuf); + if (ptbuf) + OPENSSL_free(ptbuf); + + return ret; + } + +static int rsa_builtin_keygen(RSA *rsa, int bits, BIGNUM *e_value, BN_GENCB *cb); + +/* NB: this wrapper would normally be placed in rsa_lib.c and the static + * implementation would probably be in rsa_eay.c. Nonetheless, is kept here so + * that we don't introduce a new linker dependency. Eg. any application that + * wasn't previously linking object code related to key-generation won't have to + * now just because key-generation is part of RSA_METHOD. */ +int RSA_generate_key_ex(RSA *rsa, int bits, BIGNUM *e_value, BN_GENCB *cb) + { + if(rsa->meth->rsa_keygen) + return rsa->meth->rsa_keygen(rsa, bits, e_value, cb); + return rsa_builtin_keygen(rsa, bits, e_value, cb); + } + +static int rsa_builtin_keygen(RSA *rsa, int bits, BIGNUM *e_value, BN_GENCB *cb) + { + BIGNUM *r0=NULL,*r1=NULL,*r2=NULL,*r3=NULL,*tmp; + BIGNUM local_r0,local_d,local_p; + BIGNUM *pr0,*d,*p; + int bitsp,bitsq,ok= -1,n=0; + BN_CTX *ctx=NULL; + + if(FIPS_selftest_failed()) + { + FIPSerr(FIPS_F_RSA_BUILTIN_KEYGEN,FIPS_R_FIPS_SELFTEST_FAILED); + return 0; + } + + if (FIPS_mode() && (bits < OPENSSL_RSA_FIPS_MIN_MODULUS_BITS)) + { + FIPSerr(FIPS_F_RSA_BUILTIN_KEYGEN,FIPS_R_KEY_TOO_SHORT); + return 0; + } + + ctx=BN_CTX_new(); + if (ctx == NULL) goto err; + BN_CTX_start(ctx); + r0 = BN_CTX_get(ctx); + r1 = BN_CTX_get(ctx); + r2 = BN_CTX_get(ctx); + r3 = BN_CTX_get(ctx); + if (r3 == NULL) goto err; + + bitsp=(bits+1)/2; + bitsq=bits-bitsp; + + /* We need the RSA components non-NULL */ + if(!rsa->n && ((rsa->n=BN_new()) == NULL)) goto err; + if(!rsa->d && ((rsa->d=BN_new()) == NULL)) goto err; + if(!rsa->e && ((rsa->e=BN_new()) == NULL)) goto err; + if(!rsa->p && ((rsa->p=BN_new()) == NULL)) goto err; + if(!rsa->q && ((rsa->q=BN_new()) == NULL)) goto err; + if(!rsa->dmp1 && ((rsa->dmp1=BN_new()) == NULL)) goto err; + if(!rsa->dmq1 && ((rsa->dmq1=BN_new()) == NULL)) goto err; + if(!rsa->iqmp && ((rsa->iqmp=BN_new()) == NULL)) goto err; + + BN_copy(rsa->e, e_value); + + /* generate p and q */ + for (;;) + { + if(!BN_generate_prime_ex(rsa->p, bitsp, 0, NULL, NULL, cb)) + goto err; + if (!BN_sub(r2,rsa->p,BN_value_one())) goto err; + if (!BN_gcd(r1,r2,rsa->e,ctx)) goto err; + if (BN_is_one(r1)) break; + if(!BN_GENCB_call(cb, 2, n++)) + goto err; + } + if(!BN_GENCB_call(cb, 3, 0)) + goto err; + for (;;) + { + /* When generating ridiculously small keys, we can get stuck + * continually regenerating the same prime values. Check for + * this and bail if it happens 3 times. */ + unsigned int degenerate = 0; + do + { + if(!BN_generate_prime_ex(rsa->q, bitsq, 0, NULL, NULL, cb)) + goto err; + } while((BN_cmp(rsa->p, rsa->q) == 0) && (++degenerate < 3)); + if(degenerate == 3) + { + ok = 0; /* we set our own err */ + RSAerr(RSA_F_RSA_BUILTIN_KEYGEN,RSA_R_KEY_SIZE_TOO_SMALL); + goto err; + } + if (!BN_sub(r2,rsa->q,BN_value_one())) goto err; + if (!BN_gcd(r1,r2,rsa->e,ctx)) goto err; + if (BN_is_one(r1)) + break; + if(!BN_GENCB_call(cb, 2, n++)) + goto err; + } + if(!BN_GENCB_call(cb, 3, 1)) + goto err; + if (BN_cmp(rsa->p,rsa->q) < 0) + { + tmp=rsa->p; + rsa->p=rsa->q; + rsa->q=tmp; + } + + /* calculate n */ + if (!BN_mul(rsa->n,rsa->p,rsa->q,ctx)) goto err; + + /* calculate d */ + if (!BN_sub(r1,rsa->p,BN_value_one())) goto err; /* p-1 */ + if (!BN_sub(r2,rsa->q,BN_value_one())) goto err; /* q-1 */ + if (!BN_mul(r0,r1,r2,ctx)) goto err; /* (p-1)(q-1) */ + if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME)) + { + pr0 = &local_r0; + BN_with_flags(pr0, r0, BN_FLG_CONSTTIME); + } + else + pr0 = r0; + if (!BN_mod_inverse(rsa->d,rsa->e,pr0,ctx)) goto err; /* d */ + + /* set up d for correct BN_FLG_CONSTTIME flag */ + if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME)) + { + d = &local_d; + BN_with_flags(d, rsa->d, BN_FLG_CONSTTIME); + } + else + d = rsa->d; + + /* calculate d mod (p-1) */ + if (!BN_mod(rsa->dmp1,d,r1,ctx)) goto err; + + /* calculate d mod (q-1) */ + if (!BN_mod(rsa->dmq1,d,r2,ctx)) goto err; + + /* calculate inverse of q mod p */ + if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME)) + { + p = &local_p; + BN_with_flags(p, rsa->p, BN_FLG_CONSTTIME); + } + else + p = rsa->p; + if (!BN_mod_inverse(rsa->iqmp,rsa->q,p,ctx)) goto err; + + if (fips_rsa_pairwise_fail) + BN_add_word(rsa->n, 1); + + if(!fips_check_rsa(rsa)) + goto err; + + ok=1; +err: + if (ok == -1) + { + RSAerr(RSA_F_RSA_BUILTIN_KEYGEN,ERR_LIB_BN); + ok=0; + } + if (ctx != NULL) + { + BN_CTX_end(ctx); + BN_CTX_free(ctx); + } + + return ok; + } + +#endif diff --git a/openssl/fips/rsa/fips_rsa_lib.c b/openssl/fips/rsa/fips_rsa_lib.c new file mode 100644 index 000000000..a37ad3e54 --- /dev/null +++ b/openssl/fips/rsa/fips_rsa_lib.c @@ -0,0 +1,101 @@ +/* fips_rsa_sign.c */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 2007. + */ +/* ==================================================================== + * Copyright (c) 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 + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include <string.h> +#include <openssl/evp.h> +#include <openssl/rsa.h> +#include <openssl/bn.h> +#include <openssl/err.h> + +/* Minimal FIPS versions of FIPS_rsa_new() and FIPS_rsa_free: to + * reduce external dependencies. + */ + +RSA *FIPS_rsa_new(void) + { + RSA *ret; + ret = OPENSSL_malloc(sizeof(RSA)); + if (!ret) + return NULL; + memset(ret, 0, sizeof(RSA)); + ret->meth = RSA_PKCS1_SSLeay(); + if (ret->meth->init) + ret->meth->init(ret); + return ret; + } + +void FIPS_rsa_free(RSA *r) + { + if (!r) + return; + if (r->meth->finish) + r->meth->finish(r); + if (r->n != NULL) BN_clear_free(r->n); + if (r->e != NULL) BN_clear_free(r->e); + if (r->d != NULL) BN_clear_free(r->d); + if (r->p != NULL) BN_clear_free(r->p); + if (r->q != NULL) BN_clear_free(r->q); + if (r->dmp1 != NULL) BN_clear_free(r->dmp1); + if (r->dmq1 != NULL) BN_clear_free(r->dmq1); + if (r->iqmp != NULL) BN_clear_free(r->iqmp); + if (r->blinding != NULL) BN_BLINDING_free(r->blinding); + if (r->mt_blinding != NULL) BN_BLINDING_free(r->mt_blinding); + if (r->bignum_data != NULL) OPENSSL_free_locked(r->bignum_data); + OPENSSL_free(r); + } + diff --git a/openssl/fips/rsa/fips_rsa_selftest.c b/openssl/fips/rsa/fips_rsa_selftest.c new file mode 100644 index 000000000..bead61f57 --- /dev/null +++ b/openssl/fips/rsa/fips_rsa_selftest.c @@ -0,0 +1,432 @@ +/* ==================================================================== + * 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 + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include <string.h> +#include <openssl/err.h> +#include <openssl/fips.h> +#include <openssl/rsa.h> +#include <openssl/evp.h> +#include <openssl/bn.h> +#include <openssl/opensslconf.h> + +#ifdef OPENSSL_FIPS + +static unsigned char n[] = +"\x00\xBB\xF8\x2F\x09\x06\x82\xCE\x9C\x23\x38\xAC\x2B\x9D\xA8\x71" +"\xF7\x36\x8D\x07\xEE\xD4\x10\x43\xA4\x40\xD6\xB6\xF0\x74\x54\xF5" +"\x1F\xB8\xDF\xBA\xAF\x03\x5C\x02\xAB\x61\xEA\x48\xCE\xEB\x6F\xCD" +"\x48\x76\xED\x52\x0D\x60\xE1\xEC\x46\x19\x71\x9D\x8A\x5B\x8B\x80" +"\x7F\xAF\xB8\xE0\xA3\xDF\xC7\x37\x72\x3E\xE6\xB4\xB7\xD9\x3A\x25" +"\x84\xEE\x6A\x64\x9D\x06\x09\x53\x74\x88\x34\xB2\x45\x45\x98\x39" +"\x4E\xE0\xAA\xB1\x2D\x7B\x61\xA5\x1F\x52\x7A\x9A\x41\xF6\xC1\x68" +"\x7F\xE2\x53\x72\x98\xCA\x2A\x8F\x59\x46\xF8\xE5\xFD\x09\x1D\xBD" +"\xCB"; + + +static int setrsakey(RSA *key) + { + static const unsigned char e[] = "\x11"; + + static const unsigned char d[] = +"\x00\xA5\xDA\xFC\x53\x41\xFA\xF2\x89\xC4\xB9\x88\xDB\x30\xC1\xCD" +"\xF8\x3F\x31\x25\x1E\x06\x68\xB4\x27\x84\x81\x38\x01\x57\x96\x41" +"\xB2\x94\x10\xB3\xC7\x99\x8D\x6B\xC4\x65\x74\x5E\x5C\x39\x26\x69" +"\xD6\x87\x0D\xA2\xC0\x82\xA9\x39\xE3\x7F\xDC\xB8\x2E\xC9\x3E\xDA" +"\xC9\x7F\xF3\xAD\x59\x50\xAC\xCF\xBC\x11\x1C\x76\xF1\xA9\x52\x94" +"\x44\xE5\x6A\xAF\x68\xC5\x6C\x09\x2C\xD3\x8D\xC3\xBE\xF5\xD2\x0A" +"\x93\x99\x26\xED\x4F\x74\xA1\x3E\xDD\xFB\xE1\xA1\xCE\xCC\x48\x94" +"\xAF\x94\x28\xC2\xB7\xB8\x88\x3F\xE4\x46\x3A\x4B\xC8\x5B\x1C\xB3" +"\xC1"; + + static const unsigned char p[] = +"\x00\xEE\xCF\xAE\x81\xB1\xB9\xB3\xC9\x08\x81\x0B\x10\xA1\xB5\x60" +"\x01\x99\xEB\x9F\x44\xAE\xF4\xFD\xA4\x93\xB8\x1A\x9E\x3D\x84\xF6" +"\x32\x12\x4E\xF0\x23\x6E\x5D\x1E\x3B\x7E\x28\xFA\xE7\xAA\x04\x0A" +"\x2D\x5B\x25\x21\x76\x45\x9D\x1F\x39\x75\x41\xBA\x2A\x58\xFB\x65" +"\x99"; + + static const unsigned char q[] = +"\x00\xC9\x7F\xB1\xF0\x27\xF4\x53\xF6\x34\x12\x33\xEA\xAA\xD1\xD9" +"\x35\x3F\x6C\x42\xD0\x88\x66\xB1\xD0\x5A\x0F\x20\x35\x02\x8B\x9D" +"\x86\x98\x40\xB4\x16\x66\xB4\x2E\x92\xEA\x0D\xA3\xB4\x32\x04\xB5" +"\xCF\xCE\x33\x52\x52\x4D\x04\x16\xA5\xA4\x41\xE7\x00\xAF\x46\x15" +"\x03"; + + static const unsigned char dmp1[] = +"\x54\x49\x4C\xA6\x3E\xBA\x03\x37\xE4\xE2\x40\x23\xFC\xD6\x9A\x5A" +"\xEB\x07\xDD\xDC\x01\x83\xA4\xD0\xAC\x9B\x54\xB0\x51\xF2\xB1\x3E" +"\xD9\x49\x09\x75\xEA\xB7\x74\x14\xFF\x59\xC1\xF7\x69\x2E\x9A\x2E" +"\x20\x2B\x38\xFC\x91\x0A\x47\x41\x74\xAD\xC9\x3C\x1F\x67\xC9\x81"; + + static const unsigned char dmq1[] = +"\x47\x1E\x02\x90\xFF\x0A\xF0\x75\x03\x51\xB7\xF8\x78\x86\x4C\xA9" +"\x61\xAD\xBD\x3A\x8A\x7E\x99\x1C\x5C\x05\x56\xA9\x4C\x31\x46\xA7" +"\xF9\x80\x3F\x8F\x6F\x8A\xE3\x42\xE9\x31\xFD\x8A\xE4\x7A\x22\x0D" +"\x1B\x99\xA4\x95\x84\x98\x07\xFE\x39\xF9\x24\x5A\x98\x36\xDA\x3D"; + + static const unsigned char iqmp[] = +"\x00\xB0\x6C\x4F\xDA\xBB\x63\x01\x19\x8D\x26\x5B\xDB\xAE\x94\x23" +"\xB3\x80\xF2\x71\xF7\x34\x53\x88\x50\x93\x07\x7F\xCD\x39\xE2\x11" +"\x9F\xC9\x86\x32\x15\x4F\x58\x83\xB1\x67\xA9\x67\xBF\x40\x2B\x4E" +"\x9E\x2E\x0F\x96\x56\xE6\x98\xEA\x36\x66\xED\xFB\x25\x79\x80\x39" +"\xF7"; + + 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); + key->p = BN_bin2bn(p, sizeof(p)-1, key->p); + key->q = BN_bin2bn(q, sizeof(q)-1, key->q); + 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); + return 1; + } + +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 ret = 0; + RSA *key = NULL; + EVP_PKEY pk; + key=FIPS_rsa_new(); + setrsakey(key); + pk.type = EVP_PKEY_RSA; + pk.pkey.rsa = key; + + 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; + + 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; + + + 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/openssl/fips/rsa/fips_rsa_sign.c b/openssl/fips/rsa/fips_rsa_sign.c new file mode 100644 index 000000000..37364621d --- /dev/null +++ b/openssl/fips/rsa/fips_rsa_sign.c @@ -0,0 +1,554 @@ +/* fips_rsa_sign.c */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 2007. + */ +/* ==================================================================== + * Copyright (c) 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 + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include <string.h> +#include <openssl/evp.h> +#include <openssl/rsa.h> +#include <openssl/err.h> +#include <openssl/sha.h> + +#ifdef OPENSSL_FIPS + +/* FIPS versions of RSA_sign() and RSA_verify(). + * These will only have to deal with SHA* signatures and by including + * pregenerated encodings all ASN1 dependencies can be avoided + */ + +/* Standard encodings including NULL parameter */ + +static const unsigned char sha1_bin[] = { + 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x05, + 0x00, 0x04, 0x14 +}; + +static const unsigned char sha224_bin[] = { + 0x30, 0x2d, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, + 0x04, 0x02, 0x04, 0x05, 0x00, 0x04, 0x1c +}; + +static const unsigned char sha256_bin[] = { + 0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, + 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20 +}; + +static const unsigned char sha384_bin[] = { + 0x30, 0x41, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, + 0x04, 0x02, 0x02, 0x05, 0x00, 0x04, 0x30 +}; + +static const unsigned char sha512_bin[] = { + 0x30, 0x51, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, + 0x04, 0x02, 0x03, 0x05, 0x00, 0x04, 0x40 +}; + +/* Alternate encodings with absent parameters. We don't generate signature + * using this format but do tolerate received signatures of this form. + */ + +static unsigned char sha1_nn_bin[] = { + 0x30, 0x1f, 0x30, 0x07, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x04, + 0x14 +}; + +static unsigned char sha224_nn_bin[] = { + 0x30, 0x2b, 0x30, 0x0b, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, + 0x04, 0x02, 0x04, 0x04, 0x1c +}; + +static unsigned char sha256_nn_bin[] = { + 0x30, 0x2f, 0x30, 0x0b, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, + 0x04, 0x02, 0x01, 0x04, 0x20 +}; + +static unsigned char sha384_nn_bin[] = { + 0x30, 0x3f, 0x30, 0x0b, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, + 0x04, 0x02, 0x02, 0x04, 0x30 +}; + +static unsigned char sha512_nn_bin[] = { + 0x30, 0x4f, 0x30, 0x0b, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, + 0x04, 0x02, 0x03, 0x04, 0x40 +}; + + +static const unsigned char *fips_digestinfo_encoding(int nid, unsigned int *len) + { + switch (nid) + { + + case NID_sha1: + *len = sizeof(sha1_bin); + return sha1_bin; + + case NID_sha224: + *len = sizeof(sha224_bin); + return sha224_bin; + + case NID_sha256: + *len = sizeof(sha256_bin); + return sha256_bin; + + case NID_sha384: + *len = sizeof(sha384_bin); + return sha384_bin; + + case NID_sha512: + *len = sizeof(sha512_bin); + return sha512_bin; + + default: + return NULL; + + } + } + +static const unsigned char *fips_digestinfo_nn_encoding(int nid, unsigned int *len) + { + switch (nid) + { + + case NID_sha1: + *len = sizeof(sha1_nn_bin); + return sha1_nn_bin; + + case NID_sha224: + *len = sizeof(sha224_nn_bin); + return sha224_nn_bin; + + case NID_sha256: + *len = sizeof(sha256_nn_bin); + return sha256_nn_bin; + + case NID_sha384: + *len = sizeof(sha384_nn_bin); + return sha384_nn_bin; + + case NID_sha512: + *len = sizeof(sha512_nn_bin); + return sha512_nn_bin; + + default: + return NULL; + + } + } + +static int fips_rsa_sign(int type, const unsigned char *x, unsigned int y, + unsigned char *sigret, unsigned int *siglen, EVP_MD_SVCTX *sv) + { + int i=0,j,ret=0; + unsigned int dlen; + const unsigned char *der; + unsigned int m_len; + int pad_mode = sv->mctx->flags & EVP_MD_CTX_FLAG_PAD_MASK; + int rsa_pad_mode = 0; + RSA *rsa = sv->key; + /* Largest DigestInfo: 19 (max encoding) + max MD */ + unsigned char tmpdinfo[19 + EVP_MAX_MD_SIZE]; + unsigned char md[EVP_MAX_MD_SIZE + 1]; + + EVP_DigestFinal_ex(sv->mctx, md, &m_len); + + if((rsa->flags & RSA_FLAG_SIGN_VER) && rsa->meth->rsa_sign) + { + ret = rsa->meth->rsa_sign(type, md, m_len, + sigret, siglen, rsa); + goto done; + } + + if (pad_mode == EVP_MD_CTX_FLAG_PAD_X931) + { + int hash_id; + memcpy(tmpdinfo, md, m_len); + hash_id = RSA_X931_hash_id(M_EVP_MD_CTX_type(sv->mctx)); + if (hash_id == -1) + { + RSAerr(RSA_F_FIPS_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; + } + else if (pad_mode == EVP_MD_CTX_FLAG_PAD_PKCS1) + { + + der = fips_digestinfo_encoding(type, &dlen); + + if (!der) + { + RSAerr(RSA_F_FIPS_RSA_SIGN,RSA_R_UNKNOWN_ALGORITHM_TYPE); + return 0; + } + memcpy(tmpdinfo, der, dlen); + memcpy(tmpdinfo + dlen, md, m_len); + + i = dlen + m_len; + rsa_pad_mode = RSA_PKCS1_PADDING; + + } + else if (pad_mode == EVP_MD_CTX_FLAG_PAD_PSS) + { + unsigned char *sbuf; + int saltlen; + i = RSA_size(rsa); + sbuf = OPENSSL_malloc(RSA_size(rsa)); + saltlen = M_EVP_MD_CTX_FLAG_PSS_SALT(sv->mctx); + if (saltlen == EVP_MD_CTX_FLAG_PSS_MDLEN) + saltlen = -1; + else if (saltlen == EVP_MD_CTX_FLAG_PSS_MREC) + saltlen = -2; + if (!sbuf) + { + RSAerr(RSA_F_FIPS_RSA_SIGN,ERR_R_MALLOC_FAILURE); + goto psserr; + } + if (!RSA_padding_add_PKCS1_PSS(rsa, sbuf, md, + M_EVP_MD_CTX_md(sv->mctx), saltlen)) + goto psserr; + j=rsa->meth->rsa_priv_enc(i,sbuf,sigret,rsa,RSA_NO_PADDING); + if (j > 0) + { + ret=1; + *siglen=j; + } + psserr: + OPENSSL_cleanse(md,m_len); + OPENSSL_cleanse(sbuf, i); + OPENSSL_free(sbuf); + return ret; + } + + j=RSA_size(rsa); + if (i > (j-RSA_PKCS1_PADDING_SIZE)) + { + RSAerr(RSA_F_FIPS_RSA_SIGN,RSA_R_DIGEST_TOO_BIG_FOR_RSA_KEY); + goto done; + } + /* NB: call underlying method directly to avoid FIPS blocking */ + j=rsa->meth->rsa_priv_enc(i,tmpdinfo,sigret,rsa,rsa_pad_mode); + if (j > 0) + { + ret=1; + *siglen=j; + } + + done: + OPENSSL_cleanse(tmpdinfo,i); + OPENSSL_cleanse(md,m_len); + return ret; + } + +static int fips_rsa_verify(int dtype, + const unsigned char *x, unsigned int y, + unsigned char *sigbuf, unsigned int siglen, EVP_MD_SVCTX *sv) + { + int i,ret=0; + unsigned int dlen, diglen; + int pad_mode = sv->mctx->flags & EVP_MD_CTX_FLAG_PAD_MASK; + int rsa_pad_mode = 0; + unsigned char *s; + const unsigned char *der; + unsigned char dig[EVP_MAX_MD_SIZE]; + RSA *rsa = sv->key; + + if (siglen != (unsigned int)RSA_size(sv->key)) + { + RSAerr(RSA_F_FIPS_RSA_VERIFY,RSA_R_WRONG_SIGNATURE_LENGTH); + return(0); + } + + EVP_DigestFinal_ex(sv->mctx, dig, &diglen); + + if((rsa->flags & RSA_FLAG_SIGN_VER) && rsa->meth->rsa_verify) + { + return rsa->meth->rsa_verify(dtype, dig, diglen, + sigbuf, siglen, rsa); + } + + + s= OPENSSL_malloc((unsigned int)siglen); + if (s == NULL) + { + RSAerr(RSA_F_FIPS_RSA_VERIFY,ERR_R_MALLOC_FAILURE); + goto err; + } + if (pad_mode == EVP_MD_CTX_FLAG_PAD_X931) + rsa_pad_mode = RSA_X931_PADDING; + else if (pad_mode == EVP_MD_CTX_FLAG_PAD_PKCS1) + rsa_pad_mode = RSA_PKCS1_PADDING; + else if (pad_mode == EVP_MD_CTX_FLAG_PAD_PSS) + rsa_pad_mode = RSA_NO_PADDING; + + /* NB: call underlying method directly to avoid FIPS blocking */ + i=rsa->meth->rsa_pub_dec((int)siglen,sigbuf,s, rsa, rsa_pad_mode); + + if (i <= 0) goto err; + + if (pad_mode == EVP_MD_CTX_FLAG_PAD_X931) + { + int hash_id; + if (i != (int)(diglen + 1)) + { + RSAerr(RSA_F_FIPS_RSA_VERIFY,RSA_R_BAD_SIGNATURE); + goto err; + } + hash_id = RSA_X931_hash_id(M_EVP_MD_CTX_type(sv->mctx)); + if (hash_id == -1) + { + RSAerr(RSA_F_FIPS_RSA_VERIFY,RSA_R_UNKNOWN_ALGORITHM_TYPE); + goto err; + } + if (s[diglen] != (unsigned char)hash_id) + { + RSAerr(RSA_F_FIPS_RSA_VERIFY,RSA_R_BAD_SIGNATURE); + goto err; + } + if (memcmp(s, dig, diglen)) + { + RSAerr(RSA_F_FIPS_RSA_VERIFY,RSA_R_BAD_SIGNATURE); + goto err; + } + ret = 1; + } + else if (pad_mode == EVP_MD_CTX_FLAG_PAD_PKCS1) + { + + der = fips_digestinfo_encoding(dtype, &dlen); + + if (!der) + { + RSAerr(RSA_F_FIPS_RSA_VERIFY,RSA_R_UNKNOWN_ALGORITHM_TYPE); + return(0); + } + + /* Compare, DigestInfo length, DigestInfo header and finally + * digest value itself + */ + + /* If length mismatch try alternate encoding */ + if (i != (int)(dlen + diglen)) + der = fips_digestinfo_nn_encoding(dtype, &dlen); + + if ((i != (int)(dlen + diglen)) || memcmp(der, s, dlen) + || memcmp(s + dlen, dig, diglen)) + { + RSAerr(RSA_F_FIPS_RSA_VERIFY,RSA_R_BAD_SIGNATURE); + goto err; + } + ret = 1; + + } + else if (pad_mode == EVP_MD_CTX_FLAG_PAD_PSS) + { + int saltlen; + saltlen = M_EVP_MD_CTX_FLAG_PSS_SALT(sv->mctx); + if (saltlen == EVP_MD_CTX_FLAG_PSS_MDLEN) + saltlen = -1; + else if (saltlen == EVP_MD_CTX_FLAG_PSS_MREC) + saltlen = -2; + ret = RSA_verify_PKCS1_PSS(rsa, dig, M_EVP_MD_CTX_md(sv->mctx), + s, saltlen); + if (ret < 0) + ret = 0; + } +err: + if (s != NULL) + { + OPENSSL_cleanse(s, siglen); + OPENSSL_free(s); + } + return(ret); + } + +#define EVP_PKEY_RSA_fips_method \ + (evp_sign_method *)fips_rsa_sign, \ + (evp_verify_method *)fips_rsa_verify, \ + {EVP_PKEY_RSA,EVP_PKEY_RSA2,0,0} + +static int init(EVP_MD_CTX *ctx) + { return SHA1_Init(ctx->md_data); } + +static int update(EVP_MD_CTX *ctx,const void *data,size_t count) + { return SHA1_Update(ctx->md_data,data,count); } + +static int final(EVP_MD_CTX *ctx,unsigned char *md) + { return SHA1_Final(md,ctx->md_data); } + +static const EVP_MD sha1_md= + { + NID_sha1, + NID_sha1WithRSAEncryption, + SHA_DIGEST_LENGTH, + EVP_MD_FLAG_FIPS|EVP_MD_FLAG_SVCTX, + init, + update, + final, + NULL, + NULL, + EVP_PKEY_RSA_fips_method, + SHA_CBLOCK, + sizeof(EVP_MD *)+sizeof(SHA_CTX), + }; + +const EVP_MD *EVP_sha1(void) + { + return(&sha1_md); + } + +static int init224(EVP_MD_CTX *ctx) + { return SHA224_Init(ctx->md_data); } +static int init256(EVP_MD_CTX *ctx) + { return SHA256_Init(ctx->md_data); } +/* + * Even though there're separate SHA224_[Update|Final], we call + * SHA256 functions even in SHA224 context. This is what happens + * there anyway, so we can spare few CPU cycles:-) + */ +static int update256(EVP_MD_CTX *ctx,const void *data,size_t count) + { return SHA256_Update(ctx->md_data,data,count); } +static int final256(EVP_MD_CTX *ctx,unsigned char *md) + { return SHA256_Final(md,ctx->md_data); } + +static const EVP_MD sha224_md= + { + NID_sha224, + NID_sha224WithRSAEncryption, + SHA224_DIGEST_LENGTH, + EVP_MD_FLAG_FIPS|EVP_MD_FLAG_SVCTX, + init224, + update256, + final256, + NULL, + NULL, + EVP_PKEY_RSA_fips_method, + SHA256_CBLOCK, + sizeof(EVP_MD *)+sizeof(SHA256_CTX), + }; + +const EVP_MD *EVP_sha224(void) + { return(&sha224_md); } + +static const EVP_MD sha256_md= + { + NID_sha256, + NID_sha256WithRSAEncryption, + SHA256_DIGEST_LENGTH, + EVP_MD_FLAG_FIPS|EVP_MD_FLAG_SVCTX, + init256, + update256, + final256, + NULL, + NULL, + EVP_PKEY_RSA_fips_method, + SHA256_CBLOCK, + sizeof(EVP_MD *)+sizeof(SHA256_CTX), + }; + +const EVP_MD *EVP_sha256(void) + { return(&sha256_md); } + +static int init384(EVP_MD_CTX *ctx) + { return SHA384_Init(ctx->md_data); } +static int init512(EVP_MD_CTX *ctx) + { return SHA512_Init(ctx->md_data); } +/* See comment in SHA224/256 section */ +static int update512(EVP_MD_CTX *ctx,const void *data,size_t count) + { return SHA512_Update(ctx->md_data,data,count); } +static int final512(EVP_MD_CTX *ctx,unsigned char *md) + { return SHA512_Final(md,ctx->md_data); } + +static const EVP_MD sha384_md= + { + NID_sha384, + NID_sha384WithRSAEncryption, + SHA384_DIGEST_LENGTH, + EVP_MD_FLAG_FIPS|EVP_MD_FLAG_SVCTX, + init384, + update512, + final512, + NULL, + NULL, + EVP_PKEY_RSA_fips_method, + SHA512_CBLOCK, + sizeof(EVP_MD *)+sizeof(SHA512_CTX), + }; + +const EVP_MD *EVP_sha384(void) + { return(&sha384_md); } + +static const EVP_MD sha512_md= + { + NID_sha512, + NID_sha512WithRSAEncryption, + SHA512_DIGEST_LENGTH, + EVP_MD_FLAG_FIPS|EVP_MD_FLAG_SVCTX, + init512, + update512, + final512, + NULL, + NULL, + EVP_PKEY_RSA_fips_method, + SHA512_CBLOCK, + sizeof(EVP_MD *)+sizeof(SHA512_CTX), + }; + +const EVP_MD *EVP_sha512(void) + { return(&sha512_md); } + +#endif diff --git a/openssl/fips/rsa/fips_rsa_x931g.c b/openssl/fips/rsa/fips_rsa_x931g.c new file mode 100644 index 000000000..d9f9a8123 --- /dev/null +++ b/openssl/fips/rsa/fips_rsa_x931g.c @@ -0,0 +1,280 @@ +/* crypto/rsa/rsa_gen.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include <stdio.h> +#include <string.h> +#include <time.h> +#include <openssl/err.h> +#include <openssl/bn.h> +#include <openssl/rsa.h> +#include <openssl/fips.h> + +#ifdef OPENSSL_FIPS + +extern int fips_check_rsa(RSA *rsa); + + +/* X9.31 RSA key derivation and generation */ + +int RSA_X931_derive_ex(RSA *rsa, BIGNUM *p1, BIGNUM *p2, BIGNUM *q1, BIGNUM *q2, + const BIGNUM *Xp1, const BIGNUM *Xp2, const BIGNUM *Xp, + const BIGNUM *Xq1, const BIGNUM *Xq2, const BIGNUM *Xq, + const BIGNUM *e, BN_GENCB *cb) + { + BIGNUM *r0=NULL,*r1=NULL,*r2=NULL,*r3=NULL; + BN_CTX *ctx=NULL,*ctx2=NULL; + + if (!rsa) + goto err; + + ctx = BN_CTX_new(); + BN_CTX_start(ctx); + if (!ctx) + goto err; + + r0 = BN_CTX_get(ctx); + r1 = BN_CTX_get(ctx); + r2 = BN_CTX_get(ctx); + r3 = BN_CTX_get(ctx); + + if (r3 == NULL) + goto err; + if (!rsa->e) + { + rsa->e = BN_dup(e); + if (!rsa->e) + goto err; + } + else + e = rsa->e; + + /* If not all parameters present only calculate what we can. + * This allows test programs to output selective parameters. + */ + + if (Xp && !rsa->p) + { + rsa->p = BN_new(); + if (!rsa->p) + goto err; + + if (!BN_X931_derive_prime_ex(rsa->p, p1, p2, + Xp, Xp1, Xp2, e, ctx, cb)) + goto err; + } + + if (Xq && !rsa->q) + { + rsa->q = BN_new(); + if (!rsa->q) + goto err; + if (!BN_X931_derive_prime_ex(rsa->q, q1, q2, + Xq, Xq1, Xq2, e, ctx, cb)) + goto err; + } + + if (!rsa->p || !rsa->q) + { + BN_CTX_end(ctx); + BN_CTX_free(ctx); + return 2; + } + + /* Since both primes are set we can now calculate all remaining + * components. + */ + + /* calculate n */ + rsa->n=BN_new(); + if (rsa->n == NULL) + goto err; + if (!BN_mul(rsa->n,rsa->p,rsa->q,ctx)) + goto err; + + /* calculate d */ + if (!BN_sub(r1,rsa->p,BN_value_one())) + goto err; /* p-1 */ + if (!BN_sub(r2,rsa->q,BN_value_one())) + goto err; /* q-1 */ + if (!BN_mul(r0,r1,r2,ctx)) + goto err; /* (p-1)(q-1) */ + + if (!BN_gcd(r3, r1, r2, ctx)) + goto err; + + if (!BN_div(r0, NULL, r0, r3, ctx)) + goto err; /* LCM((p-1)(q-1)) */ + + ctx2 = BN_CTX_new(); + if (!ctx2) + goto err; + + rsa->d=BN_mod_inverse(NULL,rsa->e,r0,ctx2); /* d */ + if (rsa->d == NULL) + goto err; + + /* calculate d mod (p-1) */ + rsa->dmp1=BN_new(); + if (rsa->dmp1 == NULL) + goto err; + if (!BN_mod(rsa->dmp1,rsa->d,r1,ctx)) + goto err; + + /* calculate d mod (q-1) */ + rsa->dmq1=BN_new(); + if (rsa->dmq1 == NULL) + goto err; + if (!BN_mod(rsa->dmq1,rsa->d,r2,ctx)) + goto err; + + /* calculate inverse of q mod p */ + rsa->iqmp=BN_mod_inverse(NULL,rsa->q,rsa->p,ctx2); + + err: + if (ctx) + { + BN_CTX_end(ctx); + BN_CTX_free(ctx); + } + if (ctx2) + BN_CTX_free(ctx2); + /* If this is set all calls successful */ + if (rsa->iqmp != NULL) + return 1; + + return 0; + + } + +int RSA_X931_generate_key_ex(RSA *rsa, int bits, const BIGNUM *e, BN_GENCB *cb) + { + int ok = 0; + BIGNUM *Xp = NULL, *Xq = NULL; + BN_CTX *ctx = NULL; + + if (bits < OPENSSL_RSA_FIPS_MIN_MODULUS_BITS) + { + FIPSerr(FIPS_F_RSA_X931_GENERATE_KEY_EX,FIPS_R_KEY_TOO_SHORT); + return 0; + } + + if (bits & 0xff) + { + FIPSerr(FIPS_F_RSA_X931_GENERATE_KEY_EX,FIPS_R_INVALID_KEY_LENGTH); + return 0; + } + + if(FIPS_selftest_failed()) + { + FIPSerr(FIPS_F_RSA_X931_GENERATE_KEY_EX,FIPS_R_FIPS_SELFTEST_FAILED); + return 0; + } + + ctx = BN_CTX_new(); + if (!ctx) + goto error; + + BN_CTX_start(ctx); + Xp = BN_CTX_get(ctx); + Xq = BN_CTX_get(ctx); + if (!BN_X931_generate_Xpq(Xp, Xq, bits, ctx)) + goto error; + + rsa->p = BN_new(); + rsa->q = BN_new(); + if (!rsa->p || !rsa->q) + goto error; + + /* Generate two primes from Xp, Xq */ + + if (!BN_X931_generate_prime_ex(rsa->p, NULL, NULL, NULL, NULL, Xp, + e, ctx, cb)) + goto error; + + if (!BN_X931_generate_prime_ex(rsa->q, NULL, NULL, NULL, NULL, Xq, + e, ctx, cb)) + goto error; + + /* Since rsa->p and rsa->q are valid this call will just derive + * remaining RSA components. + */ + + if (!RSA_X931_derive_ex(rsa, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, e, cb)) + goto error; + + if(!fips_check_rsa(rsa)) + goto error; + + ok = 1; + + error: + if (ctx) + { + BN_CTX_end(ctx); + BN_CTX_free(ctx); + } + + if (ok) + return 1; + + return 0; + + } + +#endif diff --git a/openssl/fips/rsa/fips_rsagtest.c b/openssl/fips/rsa/fips_rsagtest.c new file mode 100644 index 000000000..33a3d7a48 --- /dev/null +++ b/openssl/fips/rsa/fips_rsagtest.c @@ -0,0 +1,390 @@ +/* fips_rsagtest.c */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 2005. + */ +/* ==================================================================== + * Copyright (c) 2005,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 + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include <stdio.h> +#include <ctype.h> +#include <string.h> +#include <openssl/bio.h> +#include <openssl/evp.h> +#include <openssl/hmac.h> +#include <openssl/err.h> +#include <openssl/rsa.h> +#include <openssl/bn.h> +#include <openssl/x509v3.h> + +#ifndef OPENSSL_FIPS + +int main(int argc, char *argv[]) +{ + printf("No FIPS RSA support\n"); + return(0); +} + +#else + +#include "fips_utl.h" + +int rsa_test(FILE *out, FILE *in); +static int rsa_printkey1(FILE *out, RSA *rsa, + BIGNUM *Xp1, BIGNUM *Xp2, BIGNUM *Xp, + BIGNUM *e); +static int rsa_printkey2(FILE *out, RSA *rsa, + BIGNUM *Xq1, BIGNUM *Xq2, BIGNUM *Xq); + +int main(int argc, char **argv) + { + FILE *in = NULL, *out = NULL; + + int ret = 1; + + if(!FIPS_mode_set(1)) + { + do_print_errors(); + goto end; + } + + if (argc == 1) + in = stdin; + else + in = fopen(argv[1], "r"); + + if (argc < 2) + out = stdout; + else + out = fopen(argv[2], "w"); + + if (!in) + { + fprintf(stderr, "FATAL input initialization error\n"); + goto end; + } + + if (!out) + { + fprintf(stderr, "FATAL output initialization error\n"); + goto end; + } + + if (!rsa_test(out, in)) + { + fprintf(stderr, "FATAL RSAGTEST file processing error\n"); + goto end; + } + else + ret = 0; + + end: + + if (ret) + do_print_errors(); + + if (in && (in != stdin)) + fclose(in); + if (out && (out != stdout)) + fclose(out); + + return ret; + + } + +#define RSA_TEST_MAXLINELEN 10240 + +int rsa_test(FILE *out, FILE *in) + { + char *linebuf, *olinebuf, *p, *q; + char *keyword, *value; + RSA *rsa = NULL; + BIGNUM *Xp1 = NULL, *Xp2 = NULL, *Xp = NULL; + BIGNUM *Xq1 = NULL, *Xq2 = NULL, *Xq = NULL; + BIGNUM *e = NULL; + int ret = 0; + int lnum = 0; + + olinebuf = OPENSSL_malloc(RSA_TEST_MAXLINELEN); + linebuf = OPENSSL_malloc(RSA_TEST_MAXLINELEN); + + if (!linebuf || !olinebuf) + goto error; + + while (fgets(olinebuf, RSA_TEST_MAXLINELEN, in)) + { + lnum++; + strcpy(linebuf, olinebuf); + keyword = linebuf; + /* Skip leading space */ + while (isspace((unsigned char)*keyword)) + keyword++; + + /* Look for = sign */ + p = strchr(linebuf, '='); + + /* If no = or starts with [ (for [foo = bar] line) just copy */ + if (!p || *keyword=='[') + { + if (fputs(olinebuf, out) < 0) + goto error; + continue; + } + + q = p - 1; + + /* Remove trailing space */ + while (isspace((unsigned char)*q)) + *q-- = 0; + + *p = 0; + value = p + 1; + + /* Remove leading space from value */ + while (isspace((unsigned char)*value)) + value++; + + /* Remove trailing space from value */ + p = value + strlen(value) - 1; + + while (*p == '\n' || isspace((unsigned char)*p)) + *p-- = 0; + + if (!strcmp(keyword, "xp1")) + { + if (Xp1 || !do_hex2bn(&Xp1,value)) + goto parse_error; + } + else if (!strcmp(keyword, "xp2")) + { + if (Xp2 || !do_hex2bn(&Xp2,value)) + goto parse_error; + } + else if (!strcmp(keyword, "Xp")) + { + if (Xp || !do_hex2bn(&Xp,value)) + goto parse_error; + } + else if (!strcmp(keyword, "xq1")) + { + if (Xq1 || !do_hex2bn(&Xq1,value)) + goto parse_error; + } + else if (!strcmp(keyword, "xq2")) + { + if (Xq2 || !do_hex2bn(&Xq2,value)) + goto parse_error; + } + else if (!strcmp(keyword, "Xq")) + { + if (Xq || !do_hex2bn(&Xq,value)) + goto parse_error; + } + else if (!strcmp(keyword, "e")) + { + if (e || !do_hex2bn(&e,value)) + goto parse_error; + } + else if (!strcmp(keyword, "p1")) + continue; + else if (!strcmp(keyword, "p2")) + continue; + else if (!strcmp(keyword, "p")) + continue; + else if (!strcmp(keyword, "q1")) + continue; + else if (!strcmp(keyword, "q2")) + continue; + else if (!strcmp(keyword, "q")) + continue; + else if (!strcmp(keyword, "n")) + continue; + else if (!strcmp(keyword, "d")) + continue; + else + goto parse_error; + + fputs(olinebuf, out); + + if (e && Xp1 && Xp2 && Xp) + { + rsa = FIPS_rsa_new(); + if (!rsa) + goto error; + if (!rsa_printkey1(out, rsa, Xp1, Xp2, Xp, e)) + goto error; + BN_free(Xp1); + Xp1 = NULL; + BN_free(Xp2); + Xp2 = NULL; + BN_free(Xp); + Xp = NULL; + BN_free(e); + e = NULL; + } + + if (rsa && Xq1 && Xq2 && Xq) + { + if (!rsa_printkey2(out, rsa, Xq1, Xq2, Xq)) + goto error; + BN_free(Xq1); + Xq1 = NULL; + BN_free(Xq2); + Xq2 = NULL; + BN_free(Xq); + Xq = NULL; + FIPS_rsa_free(rsa); + rsa = NULL; + } + } + + ret = 1; + + error: + + if (olinebuf) + OPENSSL_free(olinebuf); + if (linebuf) + OPENSSL_free(linebuf); + + if (Xp1) + BN_free(Xp1); + if (Xp2) + BN_free(Xp2); + if (Xp) + BN_free(Xp); + if (Xq1) + BN_free(Xq1); + if (Xq1) + BN_free(Xq1); + if (Xq2) + BN_free(Xq2); + if (Xq) + BN_free(Xq); + if (e) + BN_free(e); + if (rsa) + FIPS_rsa_free(rsa); + + return ret; + + parse_error: + + fprintf(stderr, "FATAL parse error processing line %d\n", lnum); + + goto error; + + } + +static int rsa_printkey1(FILE *out, RSA *rsa, + BIGNUM *Xp1, BIGNUM *Xp2, BIGNUM *Xp, + BIGNUM *e) + { + int ret = 0; + BIGNUM *p1 = NULL, *p2 = NULL; + p1 = BN_new(); + p2 = BN_new(); + if (!p1 || !p2) + goto error; + + if (!RSA_X931_derive_ex(rsa, p1, p2, NULL, NULL, Xp1, Xp2, Xp, + NULL, NULL, NULL, e, NULL)) + goto error; + + do_bn_print_name(out, "p1", p1); + do_bn_print_name(out, "p2", p2); + do_bn_print_name(out, "p", rsa->p); + + ret = 1; + + error: + if (p1) + BN_free(p1); + if (p2) + BN_free(p2); + + return ret; + } + +static int rsa_printkey2(FILE *out, RSA *rsa, + BIGNUM *Xq1, BIGNUM *Xq2, BIGNUM *Xq) + { + int ret = 0; + BIGNUM *q1 = NULL, *q2 = NULL; + q1 = BN_new(); + q2 = BN_new(); + if (!q1 || !q2) + goto error; + + if (!RSA_X931_derive_ex(rsa, NULL, NULL, q1, q2, NULL, NULL, NULL, + Xq1, Xq2, Xq, NULL, NULL)) + goto error; + + do_bn_print_name(out, "q1", q1); + do_bn_print_name(out, "q2", q2); + do_bn_print_name(out, "q", rsa->q); + do_bn_print_name(out, "n", rsa->n); + do_bn_print_name(out, "d", rsa->d); + + ret = 1; + + error: + if (q1) + BN_free(q1); + if (q2) + BN_free(q2); + + return ret; + } + +#endif diff --git a/openssl/fips/rsa/fips_rsastest.c b/openssl/fips/rsa/fips_rsastest.c new file mode 100644 index 000000000..16c174a2f --- /dev/null +++ b/openssl/fips/rsa/fips_rsastest.c @@ -0,0 +1,370 @@ +/* fips_rsastest.c */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 2005. + */ +/* ==================================================================== + * Copyright (c) 2005 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include <stdio.h> +#include <ctype.h> +#include <string.h> +#include <openssl/bio.h> +#include <openssl/evp.h> +#include <openssl/hmac.h> +#include <openssl/err.h> +#include <openssl/rsa.h> +#include <openssl/bn.h> +#include <openssl/x509v3.h> + +#ifndef OPENSSL_FIPS + +int main(int argc, char *argv[]) +{ + printf("No FIPS RSA support\n"); + return(0); +} + +#else + +#include "fips_utl.h" + +static int rsa_stest(FILE *out, FILE *in, int Saltlen); +static int rsa_printsig(FILE *out, RSA *rsa, const EVP_MD *dgst, + unsigned char *Msg, long Msglen, int Saltlen); + +int main(int argc, char **argv) + { + FILE *in = NULL, *out = NULL; + + int ret = 1, Saltlen = -1; + + if(!FIPS_mode_set(1)) + { + do_print_errors(); + goto end; + } + + if ((argc > 2) && !strcmp("-saltlen", argv[1])) + { + Saltlen = atoi(argv[2]); + if (Saltlen < 0) + { + fprintf(stderr, "FATAL: Invalid salt length\n"); + goto end; + } + argc -= 2; + argv += 2; + } + else if ((argc > 1) && !strcmp("-x931", argv[1])) + { + Saltlen = -2; + argc--; + argv++; + } + + if (argc == 1) + in = stdin; + else + in = fopen(argv[1], "r"); + + if (argc < 2) + out = stdout; + else + out = fopen(argv[2], "w"); + + if (!in) + { + fprintf(stderr, "FATAL input initialization error\n"); + goto end; + } + + if (!out) + { + fprintf(stderr, "FATAL output initialization error\n"); + goto end; + } + + if (!rsa_stest(out, in, Saltlen)) + { + fprintf(stderr, "FATAL RSASTEST file processing error\n"); + goto end; + } + else + ret = 0; + + end: + + if (ret) + do_print_errors(); + + if (in && (in != stdin)) + fclose(in); + if (out && (out != stdout)) + fclose(out); + + return ret; + + } + +#define RSA_TEST_MAXLINELEN 10240 + +int rsa_stest(FILE *out, FILE *in, int Saltlen) + { + char *linebuf, *olinebuf, *p, *q; + char *keyword, *value; + RSA *rsa = NULL; + const EVP_MD *dgst = NULL; + unsigned char *Msg = NULL; + long Msglen = -1; + int keylen = -1, current_keylen = -1; + int ret = 0; + int lnum = 0; + + olinebuf = OPENSSL_malloc(RSA_TEST_MAXLINELEN); + linebuf = OPENSSL_malloc(RSA_TEST_MAXLINELEN); + + if (!linebuf || !olinebuf) + goto error; + + while (fgets(olinebuf, RSA_TEST_MAXLINELEN, in)) + { + lnum++; + strcpy(linebuf, olinebuf); + keyword = linebuf; + /* Skip leading space */ + while (isspace((unsigned char)*keyword)) + keyword++; + + /* Look for = sign */ + p = strchr(linebuf, '='); + + /* If no = just copy */ + if (!p) + { + if (fputs(olinebuf, out) < 0) + goto error; + continue; + } + + q = p - 1; + + /* Remove trailing space */ + while (isspace((unsigned char)*q)) + *q-- = 0; + + *p = 0; + value = p + 1; + + /* Remove leading space from value */ + while (isspace((unsigned char)*value)) + value++; + + /* Remove trailing space from value */ + p = value + strlen(value) - 1; + + while (*p == '\n' || isspace((unsigned char)*p)) + *p-- = 0; + + /* Look for [mod = XXX] for key length */ + + if (!strcmp(keyword, "[mod")) + { + p = value + strlen(value) - 1; + if (*p != ']') + goto parse_error; + *p = 0; + keylen = atoi(value); + if (keylen < 0) + goto parse_error; + } + else if (!strcmp(keyword, "SHAAlg")) + { + if (!strcmp(value, "SHA1")) + dgst = EVP_sha1(); + else if (!strcmp(value, "SHA224")) + dgst = EVP_sha224(); + else if (!strcmp(value, "SHA256")) + dgst = EVP_sha256(); + else if (!strcmp(value, "SHA384")) + dgst = EVP_sha384(); + else if (!strcmp(value, "SHA512")) + dgst = EVP_sha512(); + else + { + fprintf(stderr, + "FATAL: unsupported algorithm \"%s\"\n", + value); + goto parse_error; + } + } + else if (!strcmp(keyword, "Msg")) + { + if (Msg) + goto parse_error; + if (strlen(value) & 1) + *(--value) = '0'; + Msg = hex2bin_m(value, &Msglen); + if (!Msg) + goto parse_error; + } + + fputs(olinebuf, out); + + /* If key length has changed, generate and output public + * key components of new RSA private key. + */ + + if (keylen != current_keylen) + { + BIGNUM *bn_e; + if (rsa) + FIPS_rsa_free(rsa); + rsa = FIPS_rsa_new(); + if (!rsa) + goto error; + bn_e = BN_new(); + if (!bn_e || !BN_set_word(bn_e, 0x1001)) + goto error; + if (!RSA_X931_generate_key_ex(rsa, keylen, bn_e, NULL)) + goto error; + BN_free(bn_e); + fputs("n = ", out); + do_bn_print(out, rsa->n); + fputs("\ne = ", out); + do_bn_print(out, rsa->e); + fputs("\n", out); + current_keylen = keylen; + } + + if (Msg && dgst) + { + if (!rsa_printsig(out, rsa, dgst, Msg, Msglen, + Saltlen)) + goto error; + OPENSSL_free(Msg); + Msg = NULL; + } + + } + + ret = 1; + + error: + + if (olinebuf) + OPENSSL_free(olinebuf); + if (linebuf) + OPENSSL_free(linebuf); + if (rsa) + FIPS_rsa_free(rsa); + + return ret; + + parse_error: + + fprintf(stderr, "FATAL parse error processing line %d\n", lnum); + + goto error; + + } + +static int rsa_printsig(FILE *out, RSA *rsa, const EVP_MD *dgst, + unsigned char *Msg, long Msglen, int Saltlen) + { + int ret = 0; + unsigned char *sigbuf = NULL; + int i, siglen; + /* EVP_PKEY structure */ + EVP_PKEY pk; + EVP_MD_CTX ctx; + pk.type = EVP_PKEY_RSA; + pk.pkey.rsa = rsa; + + siglen = RSA_size(rsa); + sigbuf = OPENSSL_malloc(siglen); + if (!sigbuf) + goto error; + + EVP_MD_CTX_init(&ctx); + + if (Saltlen >= 0) + { + M_EVP_MD_CTX_set_flags(&ctx, + EVP_MD_CTX_FLAG_PAD_PSS | (Saltlen << 16)); + } + else if (Saltlen == -2) + M_EVP_MD_CTX_set_flags(&ctx, EVP_MD_CTX_FLAG_PAD_X931); + if (!EVP_SignInit_ex(&ctx, dgst, NULL)) + goto error; + if (!EVP_SignUpdate(&ctx, Msg, Msglen)) + goto error; + if (!EVP_SignFinal(&ctx, sigbuf, (unsigned int *)&siglen, &pk)) + goto error; + + EVP_MD_CTX_cleanup(&ctx); + + fputs("S = ", out); + + for (i = 0; i < siglen; i++) + fprintf(out, "%02X", sigbuf[i]); + + fputs("\n", out); + + ret = 1; + + error: + + return ret; + } +#endif diff --git a/openssl/fips/rsa/fips_rsavtest.c b/openssl/fips/rsa/fips_rsavtest.c new file mode 100644 index 000000000..6340f190a --- /dev/null +++ b/openssl/fips/rsa/fips_rsavtest.c @@ -0,0 +1,377 @@ +/* fips_rsavtest.c */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 2005. + */ +/* ==================================================================== + * Copyright (c) 2005 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include <stdio.h> +#include <ctype.h> +#include <string.h> +#include <openssl/bio.h> +#include <openssl/evp.h> +#include <openssl/hmac.h> +#include <openssl/err.h> +#include <openssl/x509v3.h> +#include <openssl/bn.h> +#include <openssl/rsa.h> + +#ifndef OPENSSL_FIPS + +int main(int argc, char *argv[]) +{ + printf("No FIPS RSA support\n"); + return(0); +} + +#else + +#include "fips_utl.h" + +int rsa_test(FILE *out, FILE *in, int saltlen); +static int rsa_printver(FILE *out, + BIGNUM *n, BIGNUM *e, + const EVP_MD *dgst, + unsigned char *Msg, long Msglen, + unsigned char *S, long Slen, int Saltlen); + +int main(int argc, char **argv) + { + FILE *in = NULL, *out = NULL; + + int ret = 1; + int Saltlen = -1; + + if(!FIPS_mode_set(1)) + { + do_print_errors(); + goto end; + } + + if ((argc > 2) && !strcmp("-saltlen", argv[1])) + { + Saltlen = atoi(argv[2]); + if (Saltlen < 0) + { + fprintf(stderr, "FATAL: Invalid salt length\n"); + goto end; + } + argc -= 2; + argv += 2; + } + else if ((argc > 1) && !strcmp("-x931", argv[1])) + { + Saltlen = -2; + argc--; + argv++; + } + + if (argc == 1) + in = stdin; + else + in = fopen(argv[1], "r"); + + if (argc < 2) + out = stdout; + else + out = fopen(argv[2], "w"); + + if (!in) + { + fprintf(stderr, "FATAL input initialization error\n"); + goto end; + } + + if (!out) + { + fprintf(stderr, "FATAL output initialization error\n"); + goto end; + } + + if (!rsa_test(out, in, Saltlen)) + { + fprintf(stderr, "FATAL RSAVTEST file processing error\n"); + goto end; + } + else + ret = 0; + + end: + + if (ret) + do_print_errors(); + + if (in && (in != stdin)) + fclose(in); + if (out && (out != stdout)) + fclose(out); + + return ret; + + } + +#define RSA_TEST_MAXLINELEN 10240 + +int rsa_test(FILE *out, FILE *in, int Saltlen) + { + char *linebuf, *olinebuf, *p, *q; + char *keyword, *value; + const EVP_MD *dgst = NULL; + BIGNUM *n = NULL, *e = NULL; + unsigned char *Msg = NULL, *S = NULL; + long Msglen, Slen; + int ret = 0; + int lnum = 0; + + olinebuf = OPENSSL_malloc(RSA_TEST_MAXLINELEN); + linebuf = OPENSSL_malloc(RSA_TEST_MAXLINELEN); + + if (!linebuf || !olinebuf) + goto error; + + while (fgets(olinebuf, RSA_TEST_MAXLINELEN, in)) + { + lnum++; + strcpy(linebuf, olinebuf); + keyword = linebuf; + /* Skip leading space */ + while (isspace((unsigned char)*keyword)) + keyword++; + + /* Look for = sign */ + p = strchr(linebuf, '='); + + /* If no = or starts with [ (for [foo = bar] line) just copy */ + if (!p || *keyword=='[') + { + if (fputs(olinebuf, out) < 0) + goto error; + continue; + } + + q = p - 1; + + /* Remove trailing space */ + while (isspace((unsigned char)*q)) + *q-- = 0; + + *p = 0; + value = p + 1; + + /* Remove leading space from value */ + while (isspace((unsigned char)*value)) + value++; + + /* Remove trailing space from value */ + p = value + strlen(value) - 1; + + while (*p == '\n' || isspace((unsigned char)*p)) + *p-- = 0; + + if (!strcmp(keyword, "n")) + { + if (!do_hex2bn(&n,value)) + goto parse_error; + } + else if (!strcmp(keyword, "e")) + { + if (!do_hex2bn(&e,value)) + goto parse_error; + } + else if (!strcmp(keyword, "SHAAlg")) + { + if (!strcmp(value, "SHA1")) + dgst = EVP_sha1(); + else if (!strcmp(value, "SHA224")) + dgst = EVP_sha224(); + else if (!strcmp(value, "SHA256")) + dgst = EVP_sha256(); + else if (!strcmp(value, "SHA384")) + dgst = EVP_sha384(); + else if (!strcmp(value, "SHA512")) + dgst = EVP_sha512(); + else + { + fprintf(stderr, + "FATAL: unsupported algorithm \"%s\"\n", + value); + goto parse_error; + } + } + else if (!strcmp(keyword, "Msg")) + { + if (Msg) + goto parse_error; + if (strlen(value) & 1) + *(--value) = '0'; + Msg = hex2bin_m(value, &Msglen); + if (!Msg) + goto parse_error; + } + else if (!strcmp(keyword, "S")) + { + if (S) + goto parse_error; + if (strlen(value) & 1) + *(--value) = '0'; + S = hex2bin_m(value, &Slen); + if (!S) + goto parse_error; + } + else if (!strcmp(keyword, "Result")) + continue; + else + goto parse_error; + + fputs(olinebuf, out); + + if (n && e && Msg && S && dgst) + { + if (!rsa_printver(out, n, e, dgst, + Msg, Msglen, S, Slen, Saltlen)) + goto error; + OPENSSL_free(Msg); + Msg = NULL; + OPENSSL_free(S); + S = NULL; + } + + } + + + ret = 1; + + + error: + + if (olinebuf) + OPENSSL_free(olinebuf); + if (linebuf) + OPENSSL_free(linebuf); + if (n) + BN_free(n); + if (e) + BN_free(e); + + return ret; + + parse_error: + + fprintf(stderr, "FATAL parse error processing line %d\n", lnum); + + goto error; + + } + +static int rsa_printver(FILE *out, + BIGNUM *n, BIGNUM *e, + const EVP_MD *dgst, + unsigned char *Msg, long Msglen, + unsigned char *S, long Slen, int Saltlen) + { + int ret = 0, r; + /* Setup RSA and EVP_PKEY structures */ + RSA *rsa_pubkey = NULL; + EVP_PKEY pk; + EVP_MD_CTX ctx; + unsigned char *buf = NULL; + rsa_pubkey = FIPS_rsa_new(); + if (!rsa_pubkey) + goto error; + rsa_pubkey->n = BN_dup(n); + rsa_pubkey->e = BN_dup(e); + if (!rsa_pubkey->n || !rsa_pubkey->e) + goto error; + pk.type = EVP_PKEY_RSA; + pk.pkey.rsa = rsa_pubkey; + + EVP_MD_CTX_init(&ctx); + + if (Saltlen >= 0) + { + M_EVP_MD_CTX_set_flags(&ctx, + EVP_MD_CTX_FLAG_PAD_PSS | (Saltlen << 16)); + } + else if (Saltlen == -2) + M_EVP_MD_CTX_set_flags(&ctx, EVP_MD_CTX_FLAG_PAD_X931); + if (!EVP_VerifyInit_ex(&ctx, dgst, NULL)) + goto error; + if (!EVP_VerifyUpdate(&ctx, Msg, Msglen)) + goto error; + + r = EVP_VerifyFinal(&ctx, S, Slen, &pk); + + + EVP_MD_CTX_cleanup(&ctx); + + if (r < 0) + goto error; + ERR_clear_error(); + + if (r == 0) + fputs("Result = F\n", out); + else + fputs("Result = P\n", out); + + ret = 1; + + error: + if (rsa_pubkey) + FIPS_rsa_free(rsa_pubkey); + if (buf) + OPENSSL_free(buf); + + return ret; + } +#endif |