summaryrefslogtreecommitdiff
path: root/crypto/rsa
diff options
context:
space:
mode:
Diffstat (limited to 'crypto/rsa')
-rw-r--r--crypto/rsa/.cvsignore2
-rw-r--r--crypto/rsa/Makefile.ssl223
-rw-r--r--crypto/rsa/rsa.h163
-rw-r--r--crypto/rsa/rsa_ameth.c349
-rw-r--r--crypto/rsa/rsa_asn1.c18
-rw-r--r--crypto/rsa/rsa_depr.c5
-rw-r--r--crypto/rsa/rsa_eay.c530
-rw-r--r--crypto/rsa/rsa_err.c173
-rw-r--r--crypto/rsa/rsa_gen.c44
-rw-r--r--crypto/rsa/rsa_lib.c139
-rw-r--r--crypto/rsa/rsa_locl.h4
-rw-r--r--crypto/rsa/rsa_null.c14
-rw-r--r--crypto/rsa/rsa_oaep.c97
-rw-r--r--crypto/rsa/rsa_pmeth.c585
-rw-r--r--crypto/rsa/rsa_prn.c93
-rw-r--r--crypto/rsa/rsa_pss.c282
-rw-r--r--crypto/rsa/rsa_sign.c79
-rw-r--r--crypto/rsa/rsa_ssl.c2
-rw-r--r--crypto/rsa/rsa_test.c33
-rw-r--r--crypto/rsa/rsa_x931.c177
20 files changed, 2422 insertions, 590 deletions
diff --git a/crypto/rsa/.cvsignore b/crypto/rsa/.cvsignore
index c6d03a9dbc..439e6d3eb6 100644
--- a/crypto/rsa/.cvsignore
+++ b/crypto/rsa/.cvsignore
@@ -1,2 +1,4 @@
lib
Makefile.save
+*.flc
+semantic.cache
diff --git a/crypto/rsa/Makefile.ssl b/crypto/rsa/Makefile.ssl
deleted file mode 100644
index 3619331644..0000000000
--- a/crypto/rsa/Makefile.ssl
+++ /dev/null
@@ -1,223 +0,0 @@
-#
-# SSLeay/crypto/rsa/Makefile
-#
-
-DIR= rsa
-TOP= ../..
-CC= cc
-INCLUDES= -I.. -I$(TOP) -I../../include
-CFLAG=-g
-INSTALL_PREFIX=
-OPENSSLDIR= /usr/local/ssl
-INSTALLTOP=/usr/local/ssl
-MAKE= make -f Makefile.ssl
-MAKEDEPPROG= makedepend
-MAKEDEPEND= $(TOP)/util/domd $(TOP) -MD $(MAKEDEPPROG)
-MAKEFILE= Makefile.ssl
-AR= ar r
-
-CFLAGS= $(INCLUDES) $(CFLAG)
-
-GENERAL=Makefile
-TEST=rsa_test.c
-APPS=
-
-LIB=$(TOP)/libcrypto.a
-LIBSRC= rsa_eay.c rsa_gen.c rsa_lib.c rsa_sign.c rsa_saos.c rsa_err.c \
- rsa_pk1.c rsa_ssl.c rsa_none.c rsa_oaep.c rsa_chk.c rsa_null.c \
- rsa_asn1.c rsa_depr.c
-LIBOBJ= rsa_eay.o rsa_gen.o rsa_lib.o rsa_sign.o rsa_saos.o rsa_err.o \
- rsa_pk1.o rsa_ssl.o rsa_none.o rsa_oaep.o rsa_chk.o rsa_null.o \
- rsa_asn1.o rsa_depr.o
-
-SRC= $(LIBSRC)
-
-EXHEADER= rsa.h
-HEADER= $(EXHEADER)
-
-ALL= $(GENERAL) $(SRC) $(HEADER)
-
-top:
- (cd ../..; $(MAKE) DIRS=crypto SDIRS=$(DIR) sub_all)
-
-all: lib
-
-lib: $(LIBOBJ)
- $(AR) $(LIB) $(LIBOBJ)
- $(RANLIB) $(LIB) || echo Never mind.
- @touch lib
-
-files:
- $(PERL) $(TOP)/util/files.pl Makefile.ssl >> $(TOP)/MINFO
-
-links:
- @sh $(TOP)/util/point.sh Makefile.ssl Makefile
- @$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER)
- @$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST)
- @$(PERL) $(TOP)/util/mklink.pl ../../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:
-
-lint:
- lint -DLINT $(INCLUDES) $(SRC)>fluff
-
-depend:
- $(MAKEDEPEND) -- $(CFLAG) $(INCLUDES) $(DEPFLAG) -- $(PROGS) $(LIBSRC)
-
-dclean:
- $(PERL) -pe 'if (/^# DO NOT DELETE THIS LINE/) {print; exit(0);}' $(MAKEFILE) >Makefile.new
- mv -f Makefile.new $(MAKEFILE)
-
-clean:
- rm -f *.o */*.o *.obj lib tags core .pure .nfs* *.old *.bak fluff
-
-# DO NOT DELETE THIS LINE -- make depend depends on it.
-
-rsa_asn1.o: ../../e_os.h ../../include/openssl/asn1.h
-rsa_asn1.o: ../../include/openssl/asn1t.h ../../include/openssl/bio.h
-rsa_asn1.o: ../../include/openssl/bn.h ../../include/openssl/buffer.h
-rsa_asn1.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
-rsa_asn1.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
-rsa_asn1.o: ../../include/openssl/opensslconf.h
-rsa_asn1.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-rsa_asn1.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
-rsa_asn1.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-rsa_asn1.o: ../cryptlib.h rsa_asn1.c
-rsa_chk.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
-rsa_chk.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h
-rsa_chk.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
-rsa_chk.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
-rsa_chk.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-rsa_chk.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
-rsa_chk.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-rsa_chk.o: rsa_chk.c
-rsa_depr.o: ../../e_os.h ../../include/openssl/asn1.h
-rsa_depr.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
-rsa_depr.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
-rsa_depr.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
-rsa_depr.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
-rsa_depr.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-rsa_depr.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
-rsa_depr.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-rsa_depr.o: ../cryptlib.h rsa_depr.c
-rsa_eay.o: ../../e_os.h ../../include/openssl/asn1.h
-rsa_eay.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
-rsa_eay.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
-rsa_eay.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
-rsa_eay.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
-rsa_eay.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-rsa_eay.o: ../../include/openssl/rand.h ../../include/openssl/rsa.h
-rsa_eay.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-rsa_eay.o: ../../include/openssl/symhacks.h ../cryptlib.h rsa_eay.c
-rsa_err.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
-rsa_err.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
-rsa_err.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
-rsa_err.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
-rsa_err.o: ../../include/openssl/ossl_typ.h ../../include/openssl/rsa.h
-rsa_err.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-rsa_err.o: ../../include/openssl/symhacks.h rsa_err.c
-rsa_gen.o: ../../e_os.h ../../include/openssl/asn1.h
-rsa_gen.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
-rsa_gen.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
-rsa_gen.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
-rsa_gen.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
-rsa_gen.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-rsa_gen.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
-rsa_gen.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-rsa_gen.o: ../cryptlib.h rsa_gen.c
-rsa_lib.o: ../../e_os.h ../../include/openssl/asn1.h
-rsa_lib.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
-rsa_lib.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
-rsa_lib.o: ../../include/openssl/e_os2.h ../../include/openssl/engine.h
-rsa_lib.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
-rsa_lib.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
-rsa_lib.o: ../../include/openssl/ossl_typ.h ../../include/openssl/rand.h
-rsa_lib.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
-rsa_lib.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-rsa_lib.o: ../cryptlib.h rsa_lib.c
-rsa_none.o: ../../e_os.h ../../include/openssl/asn1.h
-rsa_none.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
-rsa_none.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
-rsa_none.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
-rsa_none.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
-rsa_none.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-rsa_none.o: ../../include/openssl/rand.h ../../include/openssl/rsa.h
-rsa_none.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-rsa_none.o: ../../include/openssl/symhacks.h ../cryptlib.h rsa_none.c
-rsa_null.o: ../../e_os.h ../../include/openssl/asn1.h
-rsa_null.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
-rsa_null.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
-rsa_null.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
-rsa_null.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
-rsa_null.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-rsa_null.o: ../../include/openssl/rand.h ../../include/openssl/rsa.h
-rsa_null.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-rsa_null.o: ../../include/openssl/symhacks.h ../cryptlib.h rsa_null.c
-rsa_oaep.o: ../../e_os.h ../../include/openssl/asn1.h
-rsa_oaep.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
-rsa_oaep.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
-rsa_oaep.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
-rsa_oaep.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
-rsa_oaep.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
-rsa_oaep.o: ../../include/openssl/opensslconf.h
-rsa_oaep.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-rsa_oaep.o: ../../include/openssl/rand.h ../../include/openssl/rsa.h
-rsa_oaep.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
-rsa_oaep.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-rsa_oaep.o: ../cryptlib.h rsa_oaep.c
-rsa_pk1.o: ../../e_os.h ../../include/openssl/asn1.h
-rsa_pk1.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
-rsa_pk1.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
-rsa_pk1.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
-rsa_pk1.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
-rsa_pk1.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-rsa_pk1.o: ../../include/openssl/rand.h ../../include/openssl/rsa.h
-rsa_pk1.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-rsa_pk1.o: ../../include/openssl/symhacks.h ../cryptlib.h rsa_pk1.c
-rsa_saos.o: ../../e_os.h ../../include/openssl/asn1.h
-rsa_saos.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
-rsa_saos.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
-rsa_saos.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
-rsa_saos.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
-rsa_saos.o: ../../include/openssl/err.h ../../include/openssl/evp.h
-rsa_saos.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
-rsa_saos.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
-rsa_saos.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-rsa_saos.o: ../../include/openssl/pkcs7.h ../../include/openssl/rsa.h
-rsa_saos.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
-rsa_saos.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-rsa_saos.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
-rsa_saos.o: ../cryptlib.h rsa_saos.c
-rsa_sign.o: ../../e_os.h ../../include/openssl/asn1.h
-rsa_sign.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
-rsa_sign.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
-rsa_sign.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
-rsa_sign.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
-rsa_sign.o: ../../include/openssl/err.h ../../include/openssl/evp.h
-rsa_sign.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
-rsa_sign.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
-rsa_sign.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-rsa_sign.o: ../../include/openssl/pkcs7.h ../../include/openssl/rsa.h
-rsa_sign.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
-rsa_sign.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-rsa_sign.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
-rsa_sign.o: ../cryptlib.h rsa_sign.c
-rsa_ssl.o: ../../e_os.h ../../include/openssl/asn1.h
-rsa_ssl.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
-rsa_ssl.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
-rsa_ssl.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
-rsa_ssl.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
-rsa_ssl.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-rsa_ssl.o: ../../include/openssl/rand.h ../../include/openssl/rsa.h
-rsa_ssl.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-rsa_ssl.o: ../../include/openssl/symhacks.h ../cryptlib.h rsa_ssl.c
diff --git a/crypto/rsa/rsa.h b/crypto/rsa/rsa.h
index 00a7873f92..cf74343657 100644
--- a/crypto/rsa/rsa.h
+++ b/crypto/rsa/rsa.h
@@ -117,7 +117,8 @@ struct rsa_meth_st
unsigned char *sigret, unsigned int *siglen, const RSA *rsa);
int (*rsa_verify)(int dtype,
const unsigned char *m, unsigned int m_length,
- unsigned char *sigbuf, unsigned int siglen, const RSA *rsa);
+ const unsigned char *sigbuf, unsigned int siglen,
+ const RSA *rsa);
/* If this callback is NULL, the builtin software RSA key-gen will be used. This
* is for behavioural compatibility whilst the code gets rewired, but one day
* it would be nice to assume there are no such things as "builtin software"
@@ -156,38 +157,98 @@ struct rsa_st
* NULL */
char *bignum_data;
BN_BLINDING *blinding;
+ BN_BLINDING *mt_blinding;
};
+#ifndef OPENSSL_RSA_MAX_MODULUS_BITS
+# define OPENSSL_RSA_MAX_MODULUS_BITS 16384
+#endif
+
+#ifndef OPENSSL_RSA_SMALL_MODULUS_BITS
+# define OPENSSL_RSA_SMALL_MODULUS_BITS 3072
+#endif
+#ifndef OPENSSL_RSA_MAX_PUBEXP_BITS
+# define OPENSSL_RSA_MAX_PUBEXP_BITS 64 /* exponent limit enforced for "large" modulus only */
+#endif
+
#define RSA_3 0x3L
#define RSA_F4 0x10001L
-#define RSA_METHOD_FLAG_NO_CHECK 0x01 /* don't check pub/private match */
+#define RSA_METHOD_FLAG_NO_CHECK 0x0001 /* don't check pub/private match */
-#define RSA_FLAG_CACHE_PUBLIC 0x02
-#define RSA_FLAG_CACHE_PRIVATE 0x04
-#define RSA_FLAG_BLINDING 0x08
-#define RSA_FLAG_THREAD_SAFE 0x10
+#define RSA_FLAG_CACHE_PUBLIC 0x0002
+#define RSA_FLAG_CACHE_PRIVATE 0x0004
+#define RSA_FLAG_BLINDING 0x0008
+#define RSA_FLAG_THREAD_SAFE 0x0010
/* This flag means the private key operations will be handled by rsa_mod_exp
* and that they do not depend on the private key components being present:
* for example a key stored in external hardware. Without this flag bn_mod_exp
* gets called when private key components are absent.
*/
-#define RSA_FLAG_EXT_PKEY 0x20
+#define RSA_FLAG_EXT_PKEY 0x0020
/* This flag in the RSA_METHOD enables the new rsa_sign, rsa_verify functions.
*/
-#define RSA_FLAG_SIGN_VER 0x40
+#define RSA_FLAG_SIGN_VER 0x0040
+
+#define RSA_FLAG_NO_BLINDING 0x0080 /* new with 0.9.6j and 0.9.7b; the built-in
+ * RSA implementation now uses blinding by
+ * default (ignoring RSA_FLAG_BLINDING),
+ * but other engines might not need it
+ */
+#define RSA_FLAG_NO_CONSTTIME 0x0100 /* new with 0.9.8f; the built-in RSA
+ * implementation now uses constant time
+ * operations by default in private key operations,
+ * e.g., constant time modular exponentiation,
+ * modular inverse without leaking branches,
+ * division without leaking branches. This
+ * flag disables these constant time
+ * operations and results in faster RSA
+ * private key operations.
+ */
+#ifndef OPENSSL_NO_DEPRECATED
+#define RSA_FLAG_NO_EXP_CONSTTIME RSA_FLAG_NO_CONSTTIME /* deprecated name for the flag*/
+ /* new with 0.9.7h; the built-in RSA
+ * implementation now uses constant time
+ * modular exponentiation for secret exponents
+ * by default. This flag causes the
+ * faster variable sliding window method to
+ * be used for all exponents.
+ */
+#endif
+
+
+#define EVP_PKEY_CTX_set_rsa_padding(ctx, pad) \
+ EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, -1, EVP_PKEY_CTRL_RSA_PADDING, \
+ pad, NULL)
+
+#define EVP_PKEY_CTX_set_rsa_pss_saltlen(ctx, len) \
+ EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, \
+ (EVP_PKEY_OP_SIGN|EVP_PKEY_OP_VERIFY), \
+ EVP_PKEY_CTRL_RSA_PSS_SALTLEN, \
+ len, NULL)
-#define RSA_FLAG_NO_BLINDING 0x80 /* new with 0.9.6j and 0.9.7b; the built-in
- * RSA implementation now uses blinding by
- * default (ignoring RSA_FLAG_BLINDING),
- * but other engines might not need it
- */
+#define EVP_PKEY_CTX_set_rsa_keygen_bits(ctx, bits) \
+ EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_KEYGEN, \
+ EVP_PKEY_CTRL_RSA_KEYGEN_BITS, bits, NULL)
+
+#define EVP_PKEY_CTX_set_rsa_keygen_pubexp(ctx, pubexp) \
+ EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_KEYGEN, \
+ EVP_PKEY_CTRL_RSA_KEYGEN_PUBEXP, 0, pubexp)
+
+#define EVP_PKEY_CTRL_RSA_PADDING (EVP_PKEY_ALG_CTRL + 1)
+#define EVP_PKEY_CTRL_RSA_PSS_SALTLEN (EVP_PKEY_ALG_CTRL + 2)
+
+#define EVP_PKEY_CTRL_RSA_KEYGEN_BITS (EVP_PKEY_ALG_CTRL + 3)
+#define EVP_PKEY_CTRL_RSA_KEYGEN_PUBEXP (EVP_PKEY_ALG_CTRL + 4)
#define RSA_PKCS1_PADDING 1
#define RSA_SSLV23_PADDING 2
#define RSA_NO_PADDING 3
#define RSA_PKCS1_OAEP_PADDING 4
+#define RSA_X931_PADDING 5
+/* EVP_PKEY_ only */
+#define RSA_PKCS1_PSS_PADDING 6
#define RSA_PKCS1_PADDING_SIZE 11
@@ -247,18 +308,28 @@ int RSA_print_fp(FILE *fp, const RSA *r,int offset);
int RSA_print(BIO *bp, const RSA *r,int offset);
#endif
-int i2d_RSA_NET(const RSA *a, unsigned char **pp, int (*cb)(), int sgckey);
-RSA *d2i_RSA_NET(RSA **a, const unsigned char **pp, long length, int (*cb)(), int sgckey);
-
-int i2d_Netscape_RSA(const RSA *a, unsigned char **pp, int (*cb)());
-RSA *d2i_Netscape_RSA(RSA **a, const unsigned char **pp, long length, int (*cb)());
+#ifndef OPENSSL_NO_RC4
+int i2d_RSA_NET(const RSA *a, unsigned char **pp,
+ int (*cb)(char *buf, int len, const char *prompt, int verify),
+ int sgckey);
+RSA *d2i_RSA_NET(RSA **a, const unsigned char **pp, long length,
+ int (*cb)(char *buf, int len, const char *prompt, int verify),
+ int sgckey);
+
+int i2d_Netscape_RSA(const RSA *a, unsigned char **pp,
+ int (*cb)(char *buf, int len, const char *prompt,
+ int verify));
+RSA *d2i_Netscape_RSA(RSA **a, const unsigned char **pp, long length,
+ int (*cb)(char *buf, int len, const char *prompt,
+ int verify));
+#endif
/* The following 2 functions sign and verify a X509_SIG ASN1 object
* inside PKCS#1 padded RSA encryption */
int RSA_sign(int type, const unsigned char *m, unsigned int m_length,
unsigned char *sigret, unsigned int *siglen, RSA *rsa);
int RSA_verify(int type, const unsigned char *m, unsigned int m_length,
- unsigned char *sigbuf, unsigned int siglen, RSA *rsa);
+ const unsigned char *sigbuf, unsigned int siglen, RSA *rsa);
/* The following 2 function sign and verify a ASN1_OCTET_STRING
* object inside PKCS#1 padded RSA encryption */
@@ -271,6 +342,7 @@ int RSA_verify_ASN1_OCTET_STRING(int type,
int RSA_blinding_on(RSA *rsa, BN_CTX *ctx);
void RSA_blinding_off(RSA *rsa);
+BN_BLINDING *RSA_setup_blinding(RSA *rsa, BN_CTX *ctx);
int RSA_padding_add_PKCS1_type_1(unsigned char *to,int tlen,
const unsigned char *f,int fl);
@@ -280,6 +352,8 @@ int RSA_padding_add_PKCS1_type_2(unsigned char *to,int tlen,
const unsigned char *f,int fl);
int RSA_padding_check_PKCS1_type_2(unsigned char *to,int tlen,
const unsigned char *f,int fl,int rsa_len);
+int PKCS1_MGF1(unsigned char *mask, long len,
+ const unsigned char *seed, long seedlen, const EVP_MD *dgst);
int RSA_padding_add_PKCS1_OAEP(unsigned char *to,int tlen,
const unsigned char *f,int fl,
const unsigned char *p,int pl);
@@ -294,6 +368,17 @@ int RSA_padding_add_none(unsigned char *to,int tlen,
const unsigned char *f,int fl);
int RSA_padding_check_none(unsigned char *to,int tlen,
const unsigned char *f,int fl,int rsa_len);
+int RSA_padding_add_X931(unsigned char *to,int tlen,
+ const unsigned char *f,int fl);
+int RSA_padding_check_X931(unsigned char *to,int tlen,
+ const unsigned char *f,int fl,int rsa_len);
+int RSA_X931_hash_id(int nid);
+
+int RSA_verify_PKCS1_PSS(RSA *rsa, const unsigned char *mHash,
+ const EVP_MD *Hash, const unsigned char *EM, int sLen);
+int RSA_padding_add_PKCS1_PSS(RSA *rsa, unsigned char *EM,
+ const unsigned char *mHash,
+ const EVP_MD *Hash, int sLen);
int RSA_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func);
@@ -312,31 +397,54 @@ void ERR_load_RSA_strings(void);
/* Error codes for the RSA functions. */
/* Function codes. */
+#define RSA_F_CHECK_PADDING_MD 140
+#define RSA_F_DO_RSA_PRINT 146
+#define RSA_F_INT_RSA_VERIFY 145
#define RSA_F_MEMORY_LOCK 100
+#define RSA_F_OLD_RSA_PRIV_DECODE 147
+#define RSA_F_PKEY_RSA_CTRL 143
+#define RSA_F_PKEY_RSA_CTRL_STR 144
+#define RSA_F_PKEY_RSA_SIGN 142
+#define RSA_F_PKEY_RSA_VERIFYRECOVER 141
+#define RSA_F_RSA_BUILTIN_KEYGEN 129
#define RSA_F_RSA_CHECK_KEY 123
#define RSA_F_RSA_EAY_PRIVATE_DECRYPT 101
#define RSA_F_RSA_EAY_PRIVATE_ENCRYPT 102
#define RSA_F_RSA_EAY_PUBLIC_DECRYPT 103
#define RSA_F_RSA_EAY_PUBLIC_ENCRYPT 104
#define RSA_F_RSA_GENERATE_KEY 105
+#define RSA_F_RSA_MEMORY_LOCK 130
#define RSA_F_RSA_NEW_METHOD 106
#define RSA_F_RSA_NULL 124
+#define RSA_F_RSA_NULL_MOD_EXP 131
+#define RSA_F_RSA_NULL_PRIVATE_DECRYPT 132
+#define RSA_F_RSA_NULL_PRIVATE_ENCRYPT 133
+#define RSA_F_RSA_NULL_PUBLIC_DECRYPT 134
+#define RSA_F_RSA_NULL_PUBLIC_ENCRYPT 135
#define RSA_F_RSA_PADDING_ADD_NONE 107
#define RSA_F_RSA_PADDING_ADD_PKCS1_OAEP 121
+#define RSA_F_RSA_PADDING_ADD_PKCS1_PSS 125
#define RSA_F_RSA_PADDING_ADD_PKCS1_TYPE_1 108
#define RSA_F_RSA_PADDING_ADD_PKCS1_TYPE_2 109
#define RSA_F_RSA_PADDING_ADD_SSLV23 110
+#define RSA_F_RSA_PADDING_ADD_X931 127
#define RSA_F_RSA_PADDING_CHECK_NONE 111
#define RSA_F_RSA_PADDING_CHECK_PKCS1_OAEP 122
#define RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_1 112
#define RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_2 113
#define RSA_F_RSA_PADDING_CHECK_SSLV23 114
+#define RSA_F_RSA_PADDING_CHECK_X931 128
#define RSA_F_RSA_PRINT 115
#define RSA_F_RSA_PRINT_FP 116
+#define RSA_F_RSA_PRIV_DECODE 137
+#define RSA_F_RSA_PRIV_ENCODE 138
+#define RSA_F_RSA_PUB_DECODE 139
+#define RSA_F_RSA_SETUP_BLINDING 136
#define RSA_F_RSA_SIGN 117
#define RSA_F_RSA_SIGN_ASN1_OCTET_STRING 118
#define RSA_F_RSA_VERIFY 119
#define RSA_F_RSA_VERIFY_ASN1_OCTET_STRING 120
+#define RSA_F_RSA_VERIFY_PKCS1_PSS 126
/* Reason codes. */
#define RSA_R_ALGORITHM_MISMATCH 100
@@ -356,20 +464,37 @@ void ERR_load_RSA_strings(void);
#define RSA_R_DMP1_NOT_CONGRUENT_TO_D 124
#define RSA_R_DMQ1_NOT_CONGRUENT_TO_D 125
#define RSA_R_D_E_NOT_CONGRUENT_TO_1 123
+#define RSA_R_FIRST_OCTET_INVALID 133
+#define RSA_R_ILLEGAL_OR_UNSUPPORTED_PADDING_MODE 144
+#define RSA_R_INVALID_DIGEST_LENGTH 143
+#define RSA_R_INVALID_HEADER 137
+#define RSA_R_INVALID_KEYBITS 145
#define RSA_R_INVALID_MESSAGE_LENGTH 131
+#define RSA_R_INVALID_PADDING 138
+#define RSA_R_INVALID_PADDING_MODE 141
+#define RSA_R_INVALID_PSS_SALTLEN 146
+#define RSA_R_INVALID_TRAILER 139
+#define RSA_R_INVALID_X931_DIGEST 142
#define RSA_R_IQMP_NOT_INVERSE_OF_Q 126
#define RSA_R_KEY_SIZE_TOO_SMALL 120
+#define RSA_R_LAST_OCTET_INVALID 134
+#define RSA_R_MODULUS_TOO_LARGE 105
+#define RSA_R_NO_PUBLIC_EXPONENT 140
#define RSA_R_NULL_BEFORE_BLOCK_MISSING 113
#define RSA_R_N_DOES_NOT_EQUAL_P_Q 127
#define RSA_R_OAEP_DECODING_ERROR 121
+#define RSA_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE 148
#define RSA_R_PADDING_CHECK_FAILED 114
#define RSA_R_P_NOT_PRIME 128
#define RSA_R_Q_NOT_PRIME 129
#define RSA_R_RSA_OPERATIONS_NOT_SUPPORTED 130
+#define RSA_R_SLEN_CHECK_FAILED 136
+#define RSA_R_SLEN_RECOVERY_FAILED 135
#define RSA_R_SSLV3_ROLLBACK_ATTACK 115
#define RSA_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD 116
#define RSA_R_UNKNOWN_ALGORITHM_TYPE 117
#define RSA_R_UNKNOWN_PADDING_TYPE 118
+#define RSA_R_VALUE_MISSING 147
#define RSA_R_WRONG_SIGNATURE_LENGTH 119
#ifdef __cplusplus
diff --git a/crypto/rsa/rsa_ameth.c b/crypto/rsa/rsa_ameth.c
new file mode 100644
index 0000000000..8c3209885e
--- /dev/null
+++ b/crypto/rsa/rsa_ameth.c
@@ -0,0 +1,349 @@
+/* crypto/rsa/rsa_ameth.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 2006.
+ */
+/* ====================================================================
+ * Copyright (c) 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
+ * licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ * nor may "OpenSSL" appear in their names without prior written
+ * permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ * acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com). This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/asn1t.h>
+#include <openssl/x509.h>
+#include <openssl/rsa.h>
+#include <openssl/bn.h>
+#ifndef OPENSSL_NO_CMS
+#include <openssl/cms.h>
+#endif
+#include "asn1_locl.h"
+
+static int rsa_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey)
+ {
+ unsigned char *penc = NULL;
+ int penclen;
+ penclen = i2d_RSAPublicKey(pkey->pkey.rsa, &penc);
+ if (penclen <= 0)
+ return 0;
+ if (X509_PUBKEY_set0_param(pk, OBJ_nid2obj(EVP_PKEY_RSA),
+ V_ASN1_NULL, NULL, penc, penclen))
+ return 1;
+
+ OPENSSL_free(penc);
+ return 0;
+ }
+
+static int rsa_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey)
+ {
+ const unsigned char *p;
+ int pklen;
+ RSA *rsa = NULL;
+ if (!X509_PUBKEY_get0_param(NULL, &p, &pklen, NULL, pubkey))
+ return 0;
+ if (!(rsa = d2i_RSAPublicKey(NULL, &p, pklen)))
+ {
+ RSAerr(RSA_F_RSA_PUB_DECODE, ERR_R_RSA_LIB);
+ return 0;
+ }
+ EVP_PKEY_assign_RSA (pkey, rsa);
+ return 1;
+ }
+
+static int rsa_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b)
+ {
+ if (BN_cmp(b->pkey.rsa->n,a->pkey.rsa->n) != 0
+ || BN_cmp(b->pkey.rsa->e,a->pkey.rsa->e) != 0)
+ return 0;
+ return 1;
+ }
+
+static int old_rsa_priv_decode(EVP_PKEY *pkey,
+ const unsigned char **pder, int derlen)
+ {
+ RSA *rsa;
+ if (!(rsa = d2i_RSAPrivateKey (NULL, pder, derlen)))
+ {
+ RSAerr(RSA_F_OLD_RSA_PRIV_DECODE, ERR_R_RSA_LIB);
+ return 0;
+ }
+ EVP_PKEY_assign_RSA(pkey, rsa);
+ return 1;
+ }
+
+static int old_rsa_priv_encode(const EVP_PKEY *pkey, unsigned char **pder)
+ {
+ return i2d_RSAPrivateKey(pkey->pkey.rsa, pder);
+ }
+
+static int rsa_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey)
+ {
+ unsigned char *rk = NULL;
+ int rklen;
+ rklen = i2d_RSAPrivateKey(pkey->pkey.rsa, &rk);
+
+ if (rklen <= 0)
+ {
+ RSAerr(RSA_F_RSA_PRIV_ENCODE,ERR_R_MALLOC_FAILURE);
+ return 0;
+ }
+
+ if (!PKCS8_pkey_set0(p8, OBJ_nid2obj(NID_rsaEncryption), 0,
+ V_ASN1_NULL, NULL, rk, rklen))
+ {
+ RSAerr(RSA_F_RSA_PRIV_ENCODE,ERR_R_MALLOC_FAILURE);
+ return 0;
+ }
+
+ return 1;
+ }
+
+static int rsa_priv_decode(EVP_PKEY *pkey, PKCS8_PRIV_KEY_INFO *p8)
+ {
+ const unsigned char *p;
+ int pklen;
+ if (!PKCS8_pkey_get0(NULL, &p, &pklen, NULL, p8))
+ return 0;
+ return old_rsa_priv_decode(pkey, &p, pklen);
+ }
+
+static int int_rsa_size(const EVP_PKEY *pkey)
+ {
+ return RSA_size(pkey->pkey.rsa);
+ }
+
+static int rsa_bits(const EVP_PKEY *pkey)
+ {
+ return BN_num_bits(pkey->pkey.rsa->n);
+ }
+
+static void int_rsa_free(EVP_PKEY *pkey)
+ {
+ RSA_free(pkey->pkey.rsa);
+ }
+
+
+static void update_buflen(const BIGNUM *b, size_t *pbuflen)
+ {
+ size_t i;
+ if (!b)
+ return;
+ if (*pbuflen < (i = (size_t)BN_num_bytes(b)))
+ *pbuflen = i;
+ }
+
+static int do_rsa_print(BIO *bp, const RSA *x, int off, int priv)
+ {
+ char *str;
+ const char *s;
+ unsigned char *m=NULL;
+ int ret=0, mod_len = 0;
+ size_t buf_len=0;
+
+ update_buflen(x->n, &buf_len);
+ update_buflen(x->e, &buf_len);
+
+ if (priv)
+ {
+ update_buflen(x->d, &buf_len);
+ update_buflen(x->p, &buf_len);
+ update_buflen(x->q, &buf_len);
+ update_buflen(x->dmp1, &buf_len);
+ update_buflen(x->dmq1, &buf_len);
+ update_buflen(x->iqmp, &buf_len);
+ }
+
+ m=(unsigned char *)OPENSSL_malloc(buf_len+10);
+ if (m == NULL)
+ {
+ RSAerr(RSA_F_DO_RSA_PRINT,ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+
+ if (x->n != NULL)
+ mod_len = BN_num_bits(x->n);
+
+ if(!BIO_indent(bp,off,128))
+ goto err;
+
+ if (priv && x->d)
+ {
+ if (BIO_printf(bp,"Private-Key: (%d bit)\n", mod_len)
+ <= 0) goto err;
+ str = "modulus:";
+ s = "publicExponent:";
+ }
+ else
+ {
+ if (BIO_printf(bp,"Public-Key: (%d bit)\n", mod_len)
+ <= 0) goto err;
+ str = "Modulus:";
+ s= "Exponent:";
+ }
+ if (!ASN1_bn_print(bp,str,x->n,m,off)) goto err;
+ if (!ASN1_bn_print(bp,s,x->e,m,off))
+ goto err;
+ if (priv)
+ {
+ if (!ASN1_bn_print(bp,"privateExponent:",x->d,m,off))
+ goto err;
+ if (!ASN1_bn_print(bp,"prime1:",x->p,m,off))
+ goto err;
+ if (!ASN1_bn_print(bp,"prime2:",x->q,m,off))
+ goto err;
+ if (!ASN1_bn_print(bp,"exponent1:",x->dmp1,m,off))
+ goto err;
+ if (!ASN1_bn_print(bp,"exponent2:",x->dmq1,m,off))
+ goto err;
+ if (!ASN1_bn_print(bp,"coefficient:",x->iqmp,m,off))
+ goto err;
+ }
+ ret=1;
+err:
+ if (m != NULL) OPENSSL_free(m);
+ return(ret);
+ }
+
+static int rsa_pub_print(BIO *bp, const EVP_PKEY *pkey, int indent,
+ ASN1_PCTX *ctx)
+ {
+ return do_rsa_print(bp, pkey->pkey.rsa, indent, 0);
+ }
+
+
+static int rsa_priv_print(BIO *bp, const EVP_PKEY *pkey, int indent,
+ ASN1_PCTX *ctx)
+ {
+ return do_rsa_print(bp, pkey->pkey.rsa, indent, 1);
+ }
+
+
+static int rsa_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2)
+ {
+ X509_ALGOR *alg = NULL;
+ switch (op)
+ {
+
+ case ASN1_PKEY_CTRL_PKCS7_SIGN:
+ if (arg1 == 0)
+ PKCS7_SIGNER_INFO_get0_algs(arg2, NULL, NULL, &alg);
+ break;
+
+ case ASN1_PKEY_CTRL_PKCS7_ENCRYPT:
+ if (arg1 == 0)
+ PKCS7_RECIP_INFO_get0_alg(arg2, &alg);
+ break;
+#ifndef OPENSSL_NO_CMS
+ case ASN1_PKEY_CTRL_CMS_SIGN:
+ if (arg1 == 0)
+ CMS_SignerInfo_get0_algs(arg2, NULL, NULL, NULL, &alg);
+ break;
+
+ case ASN1_PKEY_CTRL_CMS_ENVELOPE:
+ if (arg1 == 0)
+ CMS_RecipientInfo_ktri_get0_algs(arg2, NULL, NULL, &alg);
+ break;
+#endif
+
+ case ASN1_PKEY_CTRL_DEFAULT_MD_NID:
+ *(int *)arg2 = NID_sha1;
+ return 1;
+
+ default:
+ return -2;
+
+ }
+
+ if (alg)
+ X509_ALGOR_set0(alg, OBJ_nid2obj(NID_rsaEncryption),
+ V_ASN1_NULL, 0);
+
+ return 1;
+
+ }
+
+
+const EVP_PKEY_ASN1_METHOD rsa_asn1_meths[] =
+ {
+ {
+ EVP_PKEY_RSA,
+ EVP_PKEY_RSA,
+ ASN1_PKEY_SIGPARAM_NULL,
+
+ "RSA",
+ "OpenSSL RSA method",
+
+ rsa_pub_decode,
+ rsa_pub_encode,
+ rsa_pub_cmp,
+ rsa_pub_print,
+
+ rsa_priv_decode,
+ rsa_priv_encode,
+ rsa_priv_print,
+
+ int_rsa_size,
+ rsa_bits,
+
+ 0,0,0,0,0,0,
+
+ int_rsa_free,
+ rsa_pkey_ctrl,
+ old_rsa_priv_decode,
+ old_rsa_priv_encode
+ },
+
+ {
+ EVP_PKEY_RSA2,
+ EVP_PKEY_RSA,
+ ASN1_PKEY_ALIAS
+ }
+ };
diff --git a/crypto/rsa/rsa_asn1.c b/crypto/rsa/rsa_asn1.c
index 1455a7e0e4..4efca8cdc8 100644
--- a/crypto/rsa/rsa_asn1.c
+++ b/crypto/rsa/rsa_asn1.c
@@ -1,9 +1,9 @@
/* rsa_asn1.c */
-/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
* project 2000.
*/
/* ====================================================================
- * Copyright (c) 2000 The OpenSSL Project. All rights reserved.
+ * Copyright (c) 2000-2005 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -62,19 +62,9 @@
#include <openssl/rsa.h>
#include <openssl/asn1t.h>
-static ASN1_METHOD method={
- (int (*)()) i2d_RSAPrivateKey,
- (char *(*)())d2i_RSAPrivateKey,
- (char *(*)())RSA_new,
- (void (*)()) RSA_free};
-
-ASN1_METHOD *RSAPrivateKey_asn1_meth(void)
- {
- return(&method);
- }
-
/* Override the default free and new methods */
-static int rsa_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it)
+static int rsa_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
+ void *exarg)
{
if(operation == ASN1_OP_NEW_PRE) {
*pval = (ASN1_VALUE *)RSA_new();
diff --git a/crypto/rsa/rsa_depr.c b/crypto/rsa/rsa_depr.c
index 73fa6eea90..a859ded987 100644
--- a/crypto/rsa/rsa_depr.c
+++ b/crypto/rsa/rsa_depr.c
@@ -80,10 +80,11 @@ RSA *RSA_generate_key(int bits, unsigned long e_value,
/* The problem is when building with 8, 16, or 32 BN_ULONG,
* unsigned long can be larger */
- for (i=0; i<sizeof(unsigned long)*8; i++)
+ for (i=0; i<(int)sizeof(unsigned long)*8; i++)
{
if (e_value & (1UL<<i))
- BN_set_bit(e,i);
+ if (BN_set_bit(e,i) == 0)
+ goto err;
}
BN_GENCB_set_old(&cb, callback, cb_arg);
diff --git a/crypto/rsa/rsa_eay.c b/crypto/rsa/rsa_eay.c
index b66b4bc140..c5eaeeae6b 100644
--- a/crypto/rsa/rsa_eay.c
+++ b/crypto/rsa/rsa_eay.c
@@ -55,6 +55,59 @@
* 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 "cryptlib.h"
@@ -97,43 +150,6 @@ const RSA_METHOD *RSA_PKCS1_SSLeay(void)
return(&rsa_pkcs1_eay_meth);
}
-/* Static helper to reduce oodles of code duplication. As a slight
- * optimisation, the "MONT_HELPER() macro must be used as front-end to this
- * function, to prevent unnecessary function calls - there is an initial test
- * that is performed by the macro-generated code. */
-static int rsa_eay_mont_helper(BN_MONT_CTX **ptr, const BIGNUM *modulus, BN_CTX *ctx)
- {
- BN_MONT_CTX *bn_mont_ctx;
- if((bn_mont_ctx = BN_MONT_CTX_new()) == NULL)
- return 0;
- if(!BN_MONT_CTX_set(bn_mont_ctx, modulus, ctx))
- {
- BN_MONT_CTX_free(bn_mont_ctx);
- return 0;
- }
- if (*ptr == NULL) /* other thread may have finished first */
- {
- CRYPTO_w_lock(CRYPTO_LOCK_RSA);
- if (*ptr == NULL) /* check again in the lock to stop races */
- {
- *ptr = bn_mont_ctx;
- bn_mont_ctx = NULL;
- }
- CRYPTO_w_unlock(CRYPTO_LOCK_RSA);
- }
- if (bn_mont_ctx)
- BN_MONT_CTX_free(bn_mont_ctx);
- return 1;
- }
-/* 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) && \
- !rsa_eay_mont_helper(&((rsa)->_method_mod_##m), \
- (rsa)->m, (ctx))) \
- err_instr
-
static int RSA_eay_public_encrypt(int flen, const unsigned char *from,
unsigned char *to, RSA *rsa, int padding)
{
@@ -142,6 +158,28 @@ static int RSA_eay_public_encrypt(int flen, const unsigned char *from,
unsigned char *buf=NULL;
BN_CTX *ctx=NULL;
+ 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);
@@ -179,13 +217,15 @@ static int RSA_eay_public_encrypt(int flen, const unsigned char *from,
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->flags & RSA_FLAG_CACHE_PUBLIC)
+ if (!BN_MONT_CTX_set_locked(&rsa->_method_mod_n, CRYPTO_LOCK_RSA, rsa->n, ctx))
+ goto err;
if (!rsa->meth->bn_mod_exp(ret,f,rsa->e,rsa->n,ctx,
rsa->_method_mod_n)) goto err;
@@ -212,64 +252,103 @@ err:
return(r);
}
-static int rsa_eay_blinding(RSA *rsa, BN_CTX *ctx)
- {
- int ret = 1;
- CRYPTO_w_lock(CRYPTO_LOCK_RSA);
- /* Check again inside the lock - the macro's check is racey */
- if(rsa->blinding == NULL)
- ret = RSA_blinding_on(rsa, ctx);
- CRYPTO_w_unlock(CRYPTO_LOCK_RSA);
- return ret;
- }
+static BN_BLINDING *rsa_get_blinding(RSA *rsa, int *local, BN_CTX *ctx)
+{
+ BN_BLINDING *ret;
+ int got_write_lock = 0;
+ CRYPTO_THREADID cur;
-#define BLINDING_HELPER(rsa, ctx, err_instr) \
- do { \
- if((!((rsa)->flags & RSA_FLAG_NO_BLINDING)) && \
- ((rsa)->blinding == NULL) && \
- !rsa_eay_blinding(rsa, ctx)) \
- err_instr \
- } while(0)
+ CRYPTO_r_lock(CRYPTO_LOCK_RSA);
-static BN_BLINDING *setup_blinding(RSA *rsa, BN_CTX *ctx)
- {
- BIGNUM *A, *Ai;
- BN_BLINDING *ret = NULL;
+ if (rsa->blinding == NULL)
+ {
+ CRYPTO_r_unlock(CRYPTO_LOCK_RSA);
+ CRYPTO_w_lock(CRYPTO_LOCK_RSA);
+ got_write_lock = 1;
- /* added in OpenSSL 0.9.6j and 0.9.7b */
+ if (rsa->blinding == NULL)
+ rsa->blinding = RSA_setup_blinding(rsa, ctx);
+ }
- /* NB: similar code appears in RSA_blinding_on (rsa_lib.c);
- * this should be placed in a new function of its own, but for reasons
- * of binary compatibility can't */
+ ret = rsa->blinding;
+ if (ret == NULL)
+ goto err;
- BN_CTX_start(ctx);
- A = BN_CTX_get(ctx);
- if ((RAND_status() == 0) && rsa->d != NULL && rsa->d->d != NULL)
+ CRYPTO_THREADID_current(&cur);
+ if (!CRYPTO_THREADID_cmp(&cur, BN_BLINDING_thread_id(ret)))
{
- /* if PRNG is not properly seeded, resort to secret exponent as unpredictable seed */
- RAND_add(rsa->d->d, rsa->d->dmax * sizeof rsa->d->d[0], 0.0);
- if (!BN_pseudo_rand_range(A,rsa->n)) goto err;
+ /* rsa->blinding is ours! */
+
+ *local = 1;
}
else
{
- if (!BN_rand_range(A,rsa->n)) goto err;
+ /* 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;
}
- if ((Ai=BN_mod_inverse(NULL,A,rsa->n,ctx)) == NULL) goto err;
- if (!rsa->meth->bn_mod_exp(A,A,rsa->e,rsa->n,ctx,rsa->_method_mod_n))
- goto err;
- ret = BN_BLINDING_new(A,Ai,rsa->n);
- BN_free(Ai);
-err:
- BN_CTX_end(ctx);
+ 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;
+ BIGNUM *f, *ret, *br, *res;
int i,j,k,num=0,r= -1;
unsigned char *buf=NULL;
BN_CTX *ctx=NULL;
@@ -278,9 +357,10 @@ static int RSA_eay_private_encrypt(int flen, const unsigned char *from,
if ((ctx=BN_CTX_new()) == NULL) goto err;
BN_CTX_start(ctx);
- f = BN_CTX_get(ctx);
+ f = BN_CTX_get(ctx);
+ br = BN_CTX_get(ctx);
ret = BN_CTX_get(ctx);
- num=BN_num_bytes(rsa->n);
+ num = BN_num_bytes(rsa->n);
buf = OPENSSL_malloc(num);
if(!f || !ret || !buf)
{
@@ -293,6 +373,9 @@ static int RSA_eay_private_encrypt(int flen, const unsigned char *from,
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;
@@ -312,17 +395,9 @@ static int RSA_eay_private_encrypt(int flen, const unsigned char *from,
goto err;
}
- BLINDING_HELPER(rsa, ctx, goto err;);
- blinding = rsa->blinding;
-
- /* Now unless blinding is disabled, 'blinding' is non-NULL.
- * But the BN_BLINDING object may be owned by some other thread
- * (we don't want to keep it constant and we don't want to use
- * lots of locking to avoid race conditions, so only a single
- * thread can use it; other threads have to use local blinding
- * factors) */
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);
@@ -331,20 +406,8 @@ static int RSA_eay_private_encrypt(int flen, const unsigned char *from,
}
if (blinding != NULL)
- {
- if (blinding->thread_id != CRYPTO_thread_id())
- {
- /* we need a local one-time blinding factor */
-
- blinding = setup_blinding(rsa, ctx);
- if (blinding == NULL)
- goto err;
- local_blinding = 1;
- }
- }
-
- if (blinding)
- if (!BN_BLINDING_convert(f, blinding, ctx)) goto err;
+ if (!rsa_blinding_convert(blinding, local_blinding, f, br, ctx))
+ goto err;
if ( (rsa->flags & RSA_FLAG_EXT_PKEY) ||
((rsa->p != NULL) &&
@@ -352,21 +415,50 @@ static int RSA_eay_private_encrypt(int flen, const unsigned char *from,
(rsa->dmp1 != NULL) &&
(rsa->dmq1 != NULL) &&
(rsa->iqmp != NULL)) )
- { if (!rsa->meth->rsa_mod_exp(ret,f,rsa,ctx)) goto err; }
+ {
+ if (!rsa->meth->rsa_mod_exp(ret, f, rsa, ctx)) goto err;
+ }
else
{
- MONT_HELPER(rsa, ctx, n, rsa->flags & RSA_FLAG_CACHE_PUBLIC, goto err);
- if (!rsa->meth->bn_mod_exp(ret,f,rsa->d,rsa->n,ctx,
+ 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;
+
+ if (rsa->flags & RSA_FLAG_CACHE_PUBLIC)
+ if(!BN_MONT_CTX_set_locked(&rsa->_method_mod_n, CRYPTO_LOCK_RSA, rsa->n, ctx))
+ goto err;
+
+ if (!rsa->meth->bn_mod_exp(ret,f,d,rsa->n,ctx,
rsa->_method_mod_n)) goto err;
}
if (blinding)
- if (!BN_BLINDING_invert(ret, blinding, ctx)) goto err;
+ 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(ret);
- i=BN_bn2bin(ret,&(to[num-j]));
+ j=BN_num_bytes(res);
+ i=BN_bn2bin(res,&(to[num-j]));
for (k=0; k<(num-i); k++)
to[k]=0;
@@ -377,8 +469,6 @@ err:
BN_CTX_end(ctx);
BN_CTX_free(ctx);
}
- if (local_blinding)
- BN_BLINDING_free(blinding);
if (buf != NULL)
{
OPENSSL_cleanse(buf,num);
@@ -390,7 +480,7 @@ err:
static int RSA_eay_private_decrypt(int flen, const unsigned char *from,
unsigned char *to, RSA *rsa, int padding)
{
- BIGNUM *f,*ret;
+ BIGNUM *f, *ret, *br;
int j,num=0,r= -1;
unsigned char *p;
unsigned char *buf=NULL;
@@ -400,9 +490,10 @@ static int RSA_eay_private_decrypt(int flen, const unsigned char *from,
if((ctx = BN_CTX_new()) == NULL) goto err;
BN_CTX_start(ctx);
- f = BN_CTX_get(ctx);
+ f = BN_CTX_get(ctx);
+ br = BN_CTX_get(ctx);
ret = BN_CTX_get(ctx);
- num=BN_num_bytes(rsa->n);
+ num = BN_num_bytes(rsa->n);
buf = OPENSSL_malloc(num);
if(!f || !ret || !buf)
{
@@ -427,17 +518,9 @@ static int RSA_eay_private_decrypt(int flen, const unsigned char *from,
goto err;
}
- BLINDING_HELPER(rsa, ctx, goto err;);
- blinding = rsa->blinding;
-
- /* Now unless blinding is disabled, 'blinding' is non-NULL.
- * But the BN_BLINDING object may be owned by some other thread
- * (we don't want to keep it constant and we don't want to use
- * lots of locking to avoid race conditions, so only a single
- * thread can use it; other threads have to use local blinding
- * factors) */
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);
@@ -446,20 +529,8 @@ static int RSA_eay_private_decrypt(int flen, const unsigned char *from,
}
if (blinding != NULL)
- {
- if (blinding->thread_id != CRYPTO_thread_id())
- {
- /* we need a local one-time blinding factor */
-
- blinding = setup_blinding(rsa, ctx);
- if (blinding == NULL)
- goto err;
- local_blinding = 1;
- }
- }
-
- if (blinding)
- if (!BN_BLINDING_convert(f, blinding, ctx)) goto err;
+ if (!rsa_blinding_convert(blinding, local_blinding, f, br, ctx))
+ goto err;
/* do the decrypt */
if ( (rsa->flags & RSA_FLAG_EXT_PKEY) ||
@@ -468,17 +539,33 @@ static int RSA_eay_private_decrypt(int flen, const unsigned char *from,
(rsa->dmp1 != NULL) &&
(rsa->dmq1 != NULL) &&
(rsa->iqmp != NULL)) )
- { if (!rsa->meth->rsa_mod_exp(ret,f,rsa,ctx)) goto err; }
+ {
+ if (!rsa->meth->rsa_mod_exp(ret, f, rsa, ctx)) goto err;
+ }
else
{
- MONT_HELPER(rsa, ctx, n, rsa->flags & RSA_FLAG_CACHE_PUBLIC, goto err);
- if (!rsa->meth->bn_mod_exp(ret,f,rsa->d,rsa->n,ctx,
+ 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->flags & RSA_FLAG_CACHE_PUBLIC)
+ if (!BN_MONT_CTX_set_locked(&rsa->_method_mod_n, CRYPTO_LOCK_RSA, rsa->n, ctx))
+ goto err;
+ if (!rsa->meth->bn_mod_exp(ret,f,d,rsa->n,ctx,
rsa->_method_mod_n))
- goto err;
+ goto err;
}
if (blinding)
- if (!BN_BLINDING_invert(ret, blinding, ctx)) goto err;
+ 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 */
@@ -512,8 +599,6 @@ err:
BN_CTX_end(ctx);
BN_CTX_free(ctx);
}
- if (local_blinding)
- BN_BLINDING_free(blinding);
if (buf != NULL)
{
OPENSSL_cleanse(buf,num);
@@ -532,6 +617,28 @@ static int RSA_eay_public_decrypt(int flen, const unsigned char *from,
unsigned char *buf=NULL;
BN_CTX *ctx=NULL;
+ 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);
@@ -560,11 +667,16 @@ static int RSA_eay_public_decrypt(int flen, const unsigned char *from,
goto err;
}
- MONT_HELPER(rsa, ctx, n, rsa->flags & RSA_FLAG_CACHE_PUBLIC, goto err);
+ if (rsa->flags & RSA_FLAG_CACHE_PUBLIC)
+ if (!BN_MONT_CTX_set_locked(&rsa->_method_mod_n, CRYPTO_LOCK_RSA, rsa->n, ctx))
+ 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);
@@ -573,6 +685,9 @@ static int RSA_eay_public_decrypt(int flen, const unsigned char *from,
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;
@@ -600,6 +715,8 @@ err:
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 ret=0;
BN_CTX_start(ctx);
@@ -607,26 +724,106 @@ static int RSA_eay_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx)
m1 = BN_CTX_get(ctx);
vrfy = BN_CTX_get(ctx);
- MONT_HELPER(rsa, ctx, p, rsa->flags & RSA_FLAG_CACHE_PRIVATE, goto err);
- MONT_HELPER(rsa, ctx, q, rsa->flags & RSA_FLAG_CACHE_PRIVATE, goto err);
- MONT_HELPER(rsa, ctx, n, rsa->flags & RSA_FLAG_CACHE_PUBLIC, goto err);
+ {
+ BIGNUM local_p, local_q;
+ BIGNUM *p = NULL, *q = NULL;
+
+ /* Make sure BN_mod_inverse in Montgomery intialization uses the
+ * BN_FLG_CONSTTIME flag (unless RSA_FLAG_NO_CONSTTIME is set)
+ */
+ if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME))
+ {
+ BN_init(&local_p);
+ p = &local_p;
+ BN_with_flags(p, rsa->p, BN_FLG_CONSTTIME);
+
+ BN_init(&local_q);
+ q = &local_q;
+ BN_with_flags(q, rsa->q, BN_FLG_CONSTTIME);
+ }
+ else
+ {
+ p = rsa->p;
+ q = rsa->q;
+ }
+
+ if (rsa->flags & RSA_FLAG_CACHE_PRIVATE)
+ {
+ if (!BN_MONT_CTX_set_locked(&rsa->_method_mod_p, CRYPTO_LOCK_RSA, p, ctx))
+ goto err;
+ if (!BN_MONT_CTX_set_locked(&rsa->_method_mod_q, CRYPTO_LOCK_RSA, q, ctx))
+ goto err;
+ }
+ }
+
+ if (rsa->flags & RSA_FLAG_CACHE_PUBLIC)
+ if (!BN_MONT_CTX_set_locked(&rsa->_method_mod_n, CRYPTO_LOCK_RSA, rsa->n, ctx))
+ 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;
+ }
- if (!BN_mod(r1,I,rsa->q,ctx)) goto err;
- if (!rsa->meth->bn_mod_exp(m1,r1,rsa->dmq1,rsa->q,ctx,
+ /* 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;
- if (!BN_mod(r1,I,rsa->p,ctx)) goto err;
- if (!rsa->meth->bn_mod_exp(r0,r1,rsa->dmp1,rsa->p,ctx,
+ /* 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_get_sign(r0))
+ if (BN_is_negative(r0))
if (!BN_add(r0,r0,rsa->p)) goto err;
if (!BN_mul(r1,r0,rsa->iqmp,ctx)) goto err;
- if (!BN_mod(r0,r1,rsa->p,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
@@ -634,7 +831,7 @@ static int RSA_eay_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx)
* This will *never* happen with OpenSSL generated keys because
* they ensure p > q [steve]
*/
- if (BN_get_sign(r0))
+ 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;
@@ -648,14 +845,27 @@ static int RSA_eay_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx)
* 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_get_sign(vrfy))
+ 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. */
- if (!rsa->meth->bn_mod_exp(r0,I,rsa->d,rsa->n,ctx,
- rsa->_method_mod_n)) goto err;
+
+ 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:
diff --git a/crypto/rsa/rsa_err.c b/crypto/rsa/rsa_err.c
index a7766c3b76..cf9f1106b0 100644
--- a/crypto/rsa/rsa_err.c
+++ b/crypto/rsa/rsa_err.c
@@ -1,6 +1,6 @@
/* crypto/rsa/rsa_err.c */
/* ====================================================================
- * Copyright (c) 1999 The OpenSSL Project. All rights reserved.
+ * Copyright (c) 1999-2008 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
@@ -64,70 +64,114 @@
/* BEGIN ERROR CODES */
#ifndef OPENSSL_NO_ERR
+
+#define ERR_FUNC(func) ERR_PACK(ERR_LIB_RSA,func,0)
+#define ERR_REASON(reason) ERR_PACK(ERR_LIB_RSA,0,reason)
+
static ERR_STRING_DATA RSA_str_functs[]=
{
-{ERR_PACK(0,RSA_F_MEMORY_LOCK,0), "MEMORY_LOCK"},
-{ERR_PACK(0,RSA_F_RSA_CHECK_KEY,0), "RSA_check_key"},
-{ERR_PACK(0,RSA_F_RSA_EAY_PRIVATE_DECRYPT,0), "RSA_EAY_PRIVATE_DECRYPT"},
-{ERR_PACK(0,RSA_F_RSA_EAY_PRIVATE_ENCRYPT,0), "RSA_EAY_PRIVATE_ENCRYPT"},
-{ERR_PACK(0,RSA_F_RSA_EAY_PUBLIC_DECRYPT,0), "RSA_EAY_PUBLIC_DECRYPT"},
-{ERR_PACK(0,RSA_F_RSA_EAY_PUBLIC_ENCRYPT,0), "RSA_EAY_PUBLIC_ENCRYPT"},
-{ERR_PACK(0,RSA_F_RSA_GENERATE_KEY,0), "RSA_generate_key"},
-{ERR_PACK(0,RSA_F_RSA_NEW_METHOD,0), "RSA_new_method"},
-{ERR_PACK(0,RSA_F_RSA_NULL,0), "RSA_NULL"},
-{ERR_PACK(0,RSA_F_RSA_PADDING_ADD_NONE,0), "RSA_padding_add_none"},
-{ERR_PACK(0,RSA_F_RSA_PADDING_ADD_PKCS1_OAEP,0), "RSA_padding_add_PKCS1_OAEP"},
-{ERR_PACK(0,RSA_F_RSA_PADDING_ADD_PKCS1_TYPE_1,0), "RSA_padding_add_PKCS1_type_1"},
-{ERR_PACK(0,RSA_F_RSA_PADDING_ADD_PKCS1_TYPE_2,0), "RSA_padding_add_PKCS1_type_2"},
-{ERR_PACK(0,RSA_F_RSA_PADDING_ADD_SSLV23,0), "RSA_padding_add_SSLv23"},
-{ERR_PACK(0,RSA_F_RSA_PADDING_CHECK_NONE,0), "RSA_padding_check_none"},
-{ERR_PACK(0,RSA_F_RSA_PADDING_CHECK_PKCS1_OAEP,0), "RSA_padding_check_PKCS1_OAEP"},
-{ERR_PACK(0,RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_1,0), "RSA_padding_check_PKCS1_type_1"},
-{ERR_PACK(0,RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_2,0), "RSA_padding_check_PKCS1_type_2"},
-{ERR_PACK(0,RSA_F_RSA_PADDING_CHECK_SSLV23,0), "RSA_padding_check_SSLv23"},
-{ERR_PACK(0,RSA_F_RSA_PRINT,0), "RSA_print"},
-{ERR_PACK(0,RSA_F_RSA_PRINT_FP,0), "RSA_print_fp"},
-{ERR_PACK(0,RSA_F_RSA_SIGN,0), "RSA_sign"},
-{ERR_PACK(0,RSA_F_RSA_SIGN_ASN1_OCTET_STRING,0), "RSA_sign_ASN1_OCTET_STRING"},
-{ERR_PACK(0,RSA_F_RSA_VERIFY,0), "RSA_verify"},
-{ERR_PACK(0,RSA_F_RSA_VERIFY_ASN1_OCTET_STRING,0), "RSA_verify_ASN1_OCTET_STRING"},
+{ERR_FUNC(RSA_F_CHECK_PADDING_MD), "CHECK_PADDING_MD"},
+{ERR_FUNC(RSA_F_DO_RSA_PRINT), "DO_RSA_PRINT"},
+{ERR_FUNC(RSA_F_INT_RSA_VERIFY), "INT_RSA_VERIFY"},
+{ERR_FUNC(RSA_F_MEMORY_LOCK), "MEMORY_LOCK"},
+{ERR_FUNC(RSA_F_OLD_RSA_PRIV_DECODE), "OLD_RSA_PRIV_DECODE"},
+{ERR_FUNC(RSA_F_PKEY_RSA_CTRL), "PKEY_RSA_CTRL"},
+{ERR_FUNC(RSA_F_PKEY_RSA_CTRL_STR), "PKEY_RSA_CTRL_STR"},
+{ERR_FUNC(RSA_F_PKEY_RSA_SIGN), "PKEY_RSA_SIGN"},
+{ERR_FUNC(RSA_F_PKEY_RSA_VERIFYRECOVER), "PKEY_RSA_VERIFYRECOVER"},
+{ERR_FUNC(RSA_F_RSA_BUILTIN_KEYGEN), "RSA_BUILTIN_KEYGEN"},
+{ERR_FUNC(RSA_F_RSA_CHECK_KEY), "RSA_check_key"},
+{ERR_FUNC(RSA_F_RSA_EAY_PRIVATE_DECRYPT), "RSA_EAY_PRIVATE_DECRYPT"},
+{ERR_FUNC(RSA_F_RSA_EAY_PRIVATE_ENCRYPT), "RSA_EAY_PRIVATE_ENCRYPT"},
+{ERR_FUNC(RSA_F_RSA_EAY_PUBLIC_DECRYPT), "RSA_EAY_PUBLIC_DECRYPT"},
+{ERR_FUNC(RSA_F_RSA_EAY_PUBLIC_ENCRYPT), "RSA_EAY_PUBLIC_ENCRYPT"},
+{ERR_FUNC(RSA_F_RSA_GENERATE_KEY), "RSA_generate_key"},
+{ERR_FUNC(RSA_F_RSA_MEMORY_LOCK), "RSA_memory_lock"},
+{ERR_FUNC(RSA_F_RSA_NEW_METHOD), "RSA_new_method"},
+{ERR_FUNC(RSA_F_RSA_NULL), "RSA_NULL"},
+{ERR_FUNC(RSA_F_RSA_NULL_MOD_EXP), "RSA_NULL_MOD_EXP"},
+{ERR_FUNC(RSA_F_RSA_NULL_PRIVATE_DECRYPT), "RSA_NULL_PRIVATE_DECRYPT"},
+{ERR_FUNC(RSA_F_RSA_NULL_PRIVATE_ENCRYPT), "RSA_NULL_PRIVATE_ENCRYPT"},
+{ERR_FUNC(RSA_F_RSA_NULL_PUBLIC_DECRYPT), "RSA_NULL_PUBLIC_DECRYPT"},
+{ERR_FUNC(RSA_F_RSA_NULL_PUBLIC_ENCRYPT), "RSA_NULL_PUBLIC_ENCRYPT"},
+{ERR_FUNC(RSA_F_RSA_PADDING_ADD_NONE), "RSA_padding_add_none"},
+{ERR_FUNC(RSA_F_RSA_PADDING_ADD_PKCS1_OAEP), "RSA_padding_add_PKCS1_OAEP"},
+{ERR_FUNC(RSA_F_RSA_PADDING_ADD_PKCS1_PSS), "RSA_padding_add_PKCS1_PSS"},
+{ERR_FUNC(RSA_F_RSA_PADDING_ADD_PKCS1_TYPE_1), "RSA_padding_add_PKCS1_type_1"},
+{ERR_FUNC(RSA_F_RSA_PADDING_ADD_PKCS1_TYPE_2), "RSA_padding_add_PKCS1_type_2"},
+{ERR_FUNC(RSA_F_RSA_PADDING_ADD_SSLV23), "RSA_padding_add_SSLv23"},
+{ERR_FUNC(RSA_F_RSA_PADDING_ADD_X931), "RSA_padding_add_X931"},
+{ERR_FUNC(RSA_F_RSA_PADDING_CHECK_NONE), "RSA_padding_check_none"},
+{ERR_FUNC(RSA_F_RSA_PADDING_CHECK_PKCS1_OAEP), "RSA_padding_check_PKCS1_OAEP"},
+{ERR_FUNC(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_1), "RSA_padding_check_PKCS1_type_1"},
+{ERR_FUNC(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_2), "RSA_padding_check_PKCS1_type_2"},
+{ERR_FUNC(RSA_F_RSA_PADDING_CHECK_SSLV23), "RSA_padding_check_SSLv23"},
+{ERR_FUNC(RSA_F_RSA_PADDING_CHECK_X931), "RSA_padding_check_X931"},
+{ERR_FUNC(RSA_F_RSA_PRINT), "RSA_print"},
+{ERR_FUNC(RSA_F_RSA_PRINT_FP), "RSA_print_fp"},
+{ERR_FUNC(RSA_F_RSA_PRIV_DECODE), "RSA_PRIV_DECODE"},
+{ERR_FUNC(RSA_F_RSA_PRIV_ENCODE), "RSA_PRIV_ENCODE"},
+{ERR_FUNC(RSA_F_RSA_PUB_DECODE), "RSA_PUB_DECODE"},
+{ERR_FUNC(RSA_F_RSA_SETUP_BLINDING), "RSA_setup_blinding"},
+{ERR_FUNC(RSA_F_RSA_SIGN), "RSA_sign"},
+{ERR_FUNC(RSA_F_RSA_SIGN_ASN1_OCTET_STRING), "RSA_sign_ASN1_OCTET_STRING"},
+{ERR_FUNC(RSA_F_RSA_VERIFY), "RSA_verify"},
+{ERR_FUNC(RSA_F_RSA_VERIFY_ASN1_OCTET_STRING), "RSA_verify_ASN1_OCTET_STRING"},
+{ERR_FUNC(RSA_F_RSA_VERIFY_PKCS1_PSS), "RSA_verify_PKCS1_PSS"},
{0,NULL}
};
static ERR_STRING_DATA RSA_str_reasons[]=
{
-{RSA_R_ALGORITHM_MISMATCH ,"algorithm mismatch"},
-{RSA_R_BAD_E_VALUE ,"bad e value"},
-{RSA_R_BAD_FIXED_HEADER_DECRYPT ,"bad fixed header decrypt"},
-{RSA_R_BAD_PAD_BYTE_COUNT ,"bad pad byte count"},
-{RSA_R_BAD_SIGNATURE ,"bad signature"},
-{RSA_R_BLOCK_TYPE_IS_NOT_01 ,"block type is not 01"},
-{RSA_R_BLOCK_TYPE_IS_NOT_02 ,"block type is not 02"},
-{RSA_R_DATA_GREATER_THAN_MOD_LEN ,"data greater than mod len"},
-{RSA_R_DATA_TOO_LARGE ,"data too large"},
-{RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE ,"data too large for key size"},
-{RSA_R_DATA_TOO_LARGE_FOR_MODULUS ,"data too large for modulus"},
-{RSA_R_DATA_TOO_SMALL ,"data too small"},
-{RSA_R_DATA_TOO_SMALL_FOR_KEY_SIZE ,"data too small for key size"},
-{RSA_R_DIGEST_TOO_BIG_FOR_RSA_KEY ,"digest too big for rsa key"},
-{RSA_R_DMP1_NOT_CONGRUENT_TO_D ,"dmp1 not congruent to d"},
-{RSA_R_DMQ1_NOT_CONGRUENT_TO_D ,"dmq1 not congruent to d"},
-{RSA_R_D_E_NOT_CONGRUENT_TO_1 ,"d e not congruent to 1"},
-{RSA_R_INVALID_MESSAGE_LENGTH ,"invalid message length"},
-{RSA_R_IQMP_NOT_INVERSE_OF_Q ,"iqmp not inverse of q"},
-{RSA_R_KEY_SIZE_TOO_SMALL ,"key size too small"},
-{RSA_R_NULL_BEFORE_BLOCK_MISSING ,"null before block missing"},
-{RSA_R_N_DOES_NOT_EQUAL_P_Q ,"n does not equal p q"},
-{RSA_R_OAEP_DECODING_ERROR ,"oaep decoding error"},
-{RSA_R_PADDING_CHECK_FAILED ,"padding check failed"},
-{RSA_R_P_NOT_PRIME ,"p not prime"},
-{RSA_R_Q_NOT_PRIME ,"q not prime"},
-{RSA_R_RSA_OPERATIONS_NOT_SUPPORTED ,"rsa operations not supported"},
-{RSA_R_SSLV3_ROLLBACK_ATTACK ,"sslv3 rollback attack"},
-{RSA_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD,"the asn1 object identifier is not known for this md"},
-{RSA_R_UNKNOWN_ALGORITHM_TYPE ,"unknown algorithm type"},
-{RSA_R_UNKNOWN_PADDING_TYPE ,"unknown padding type"},
-{RSA_R_WRONG_SIGNATURE_LENGTH ,"wrong signature length"},
+{ERR_REASON(RSA_R_ALGORITHM_MISMATCH) ,"algorithm mismatch"},
+{ERR_REASON(RSA_R_BAD_E_VALUE) ,"bad e value"},
+{ERR_REASON(RSA_R_BAD_FIXED_HEADER_DECRYPT),"bad fixed header decrypt"},
+{ERR_REASON(RSA_R_BAD_PAD_BYTE_COUNT) ,"bad pad byte count"},
+{ERR_REASON(RSA_R_BAD_SIGNATURE) ,"bad signature"},
+{ERR_REASON(RSA_R_BLOCK_TYPE_IS_NOT_01) ,"block type is not 01"},
+{ERR_REASON(RSA_R_BLOCK_TYPE_IS_NOT_02) ,"block type is not 02"},
+{ERR_REASON(RSA_R_DATA_GREATER_THAN_MOD_LEN),"data greater than mod len"},
+{ERR_REASON(RSA_R_DATA_TOO_LARGE) ,"data too large"},
+{ERR_REASON(RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE),"data too large for key size"},
+{ERR_REASON(RSA_R_DATA_TOO_LARGE_FOR_MODULUS),"data too large for modulus"},
+{ERR_REASON(RSA_R_DATA_TOO_SMALL) ,"data too small"},
+{ERR_REASON(RSA_R_DATA_TOO_SMALL_FOR_KEY_SIZE),"data too small for key size"},
+{ERR_REASON(RSA_R_DIGEST_TOO_BIG_FOR_RSA_KEY),"digest too big for rsa key"},
+{ERR_REASON(RSA_R_DMP1_NOT_CONGRUENT_TO_D),"dmp1 not congruent to d"},
+{ERR_REASON(RSA_R_DMQ1_NOT_CONGRUENT_TO_D),"dmq1 not congruent to d"},
+{ERR_REASON(RSA_R_D_E_NOT_CONGRUENT_TO_1),"d e not congruent to 1"},
+{ERR_REASON(RSA_R_FIRST_OCTET_INVALID) ,"first octet invalid"},
+{ERR_REASON(RSA_R_ILLEGAL_OR_UNSUPPORTED_PADDING_MODE),"illegal or unsupported padding mode"},
+{ERR_REASON(RSA_R_INVALID_DIGEST_LENGTH) ,"invalid digest length"},
+{ERR_REASON(RSA_R_INVALID_HEADER) ,"invalid header"},
+{ERR_REASON(RSA_R_INVALID_KEYBITS) ,"invalid keybits"},
+{ERR_REASON(RSA_R_INVALID_MESSAGE_LENGTH),"invalid message length"},
+{ERR_REASON(RSA_R_INVALID_PADDING) ,"invalid padding"},
+{ERR_REASON(RSA_R_INVALID_PADDING_MODE) ,"invalid padding mode"},
+{ERR_REASON(RSA_R_INVALID_PSS_SALTLEN) ,"invalid pss saltlen"},
+{ERR_REASON(RSA_R_INVALID_TRAILER) ,"invalid trailer"},
+{ERR_REASON(RSA_R_INVALID_X931_DIGEST) ,"invalid x931 digest"},
+{ERR_REASON(RSA_R_IQMP_NOT_INVERSE_OF_Q) ,"iqmp not inverse of q"},
+{ERR_REASON(RSA_R_KEY_SIZE_TOO_SMALL) ,"key size too small"},
+{ERR_REASON(RSA_R_LAST_OCTET_INVALID) ,"last octet invalid"},
+{ERR_REASON(RSA_R_MODULUS_TOO_LARGE) ,"modulus too large"},
+{ERR_REASON(RSA_R_NO_PUBLIC_EXPONENT) ,"no public exponent"},
+{ERR_REASON(RSA_R_NULL_BEFORE_BLOCK_MISSING),"null before block missing"},
+{ERR_REASON(RSA_R_N_DOES_NOT_EQUAL_P_Q) ,"n does not equal p q"},
+{ERR_REASON(RSA_R_OAEP_DECODING_ERROR) ,"oaep decoding error"},
+{ERR_REASON(RSA_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE),"operation not supported for this keytype"},
+{ERR_REASON(RSA_R_PADDING_CHECK_FAILED) ,"padding check failed"},
+{ERR_REASON(RSA_R_P_NOT_PRIME) ,"p not prime"},
+{ERR_REASON(RSA_R_Q_NOT_PRIME) ,"q not prime"},
+{ERR_REASON(RSA_R_RSA_OPERATIONS_NOT_SUPPORTED),"rsa operations not supported"},
+{ERR_REASON(RSA_R_SLEN_CHECK_FAILED) ,"salt length check failed"},
+{ERR_REASON(RSA_R_SLEN_RECOVERY_FAILED) ,"salt length recovery failed"},
+{ERR_REASON(RSA_R_SSLV3_ROLLBACK_ATTACK) ,"sslv3 rollback attack"},
+{ERR_REASON(RSA_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD),"the asn1 object identifier is not known for this md"},
+{ERR_REASON(RSA_R_UNKNOWN_ALGORITHM_TYPE),"unknown algorithm type"},
+{ERR_REASON(RSA_R_UNKNOWN_PADDING_TYPE) ,"unknown padding type"},
+{ERR_REASON(RSA_R_VALUE_MISSING) ,"value missing"},
+{ERR_REASON(RSA_R_WRONG_SIGNATURE_LENGTH),"wrong signature length"},
{0,NULL}
};
@@ -135,15 +179,12 @@ static ERR_STRING_DATA RSA_str_reasons[]=
void ERR_load_RSA_strings(void)
{
- static int init=1;
-
- if (init)
- {
- init=0;
#ifndef OPENSSL_NO_ERR
- ERR_load_strings(ERR_LIB_RSA,RSA_str_functs);
- ERR_load_strings(ERR_LIB_RSA,RSA_str_reasons);
-#endif
+ if (ERR_func_error_string(RSA_str_functs[0].error) == NULL)
+ {
+ ERR_load_strings(0,RSA_str_functs);
+ ERR_load_strings(0,RSA_str_reasons);
}
+#endif
}
diff --git a/crypto/rsa/rsa_gen.c b/crypto/rsa/rsa_gen.c
index 8e3a5821d6..767f7ab682 100644
--- a/crypto/rsa/rsa_gen.c
+++ b/crypto/rsa/rsa_gen.c
@@ -85,6 +85,8 @@ int RSA_generate_key_ex(RSA *rsa, int bits, BIGNUM *e_value, BN_GENCB *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;
@@ -139,7 +141,7 @@ static int rsa_builtin_keygen(RSA *rsa, int bits, BIGNUM *e_value, BN_GENCB *cb)
if(degenerate == 3)
{
ok = 0; /* we set our own err */
- RSAerr(RSA_F_RSA_GENERATE_KEY,RSA_R_KEY_SIZE_TOO_SMALL);
+ 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;
@@ -165,26 +167,52 @@ static int rsa_builtin_keygen(RSA *rsa, int bits, BIGNUM *e_value, BN_GENCB *cb)
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_mod_inverse(rsa->d,rsa->e,r0,ctx)) goto err; /* d */
+ 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,rsa->d,r1,ctx)) goto err;
+ if (!BN_mod(rsa->dmp1,d,r1,ctx)) goto err;
/* calculate d mod (q-1) */
- if (!BN_mod(rsa->dmq1,rsa->d,r2,ctx)) goto err;
+ if (!BN_mod(rsa->dmq1,d,r2,ctx)) goto err;
/* calculate inverse of q mod p */
- if (!BN_mod_inverse(rsa->iqmp,rsa->q,rsa->p,ctx)) goto err;
+ 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;
ok=1;
err:
if (ok == -1)
{
- RSAerr(RSA_F_RSA_GENERATE_KEY,ERR_LIB_BN);
+ RSAerr(RSA_F_RSA_BUILTIN_KEYGEN,ERR_LIB_BN);
ok=0;
}
- BN_CTX_end(ctx);
- BN_CTX_free(ctx);
+ if (ctx != NULL)
+ {
+ BN_CTX_end(ctx);
+ BN_CTX_free(ctx);
+ }
return ok;
}
diff --git a/crypto/rsa/rsa_lib.c b/crypto/rsa/rsa_lib.c
index cba2dd66cd..de45088d76 100644
--- a/crypto/rsa/rsa_lib.c
+++ b/crypto/rsa/rsa_lib.c
@@ -67,7 +67,7 @@
#include <openssl/engine.h>
#endif
-const char *RSA_version="RSA" OPENSSL_VERSION_PTEXT;
+const char RSA_version[]="RSA" OPENSSL_VERSION_PTEXT;
static const RSA_METHOD *default_RSA_meth=NULL;
@@ -179,9 +179,19 @@ RSA *RSA_new_method(ENGINE *engine)
ret->_method_mod_p=NULL;
ret->_method_mod_q=NULL;
ret->blinding=NULL;
+ ret->mt_blinding=NULL;
ret->bignum_data=NULL;
ret->flags=ret->meth->flags;
- CRYPTO_new_ex_data(CRYPTO_EX_INDEX_RSA, ret, &ret->ex_data);
+ if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_RSA, ret, &ret->ex_data))
+ {
+#ifndef OPENSSL_NO_ENGINE
+ if (ret->engine)
+ ENGINE_finish(ret->engine);
+#endif
+ OPENSSL_free(ret);
+ return(NULL);
+ }
+
if ((ret->meth->init != NULL) && !ret->meth->init(ret))
{
#ifndef OPENSSL_NO_ENGINE
@@ -232,6 +242,7 @@ void RSA_free(RSA *r)
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);
}
@@ -314,59 +325,117 @@ void RSA_blinding_off(RSA *rsa)
rsa->flags |= RSA_FLAG_NO_BLINDING;
}
-int RSA_blinding_on(RSA *rsa, BN_CTX *p_ctx)
+int RSA_blinding_on(RSA *rsa, BN_CTX *ctx)
{
- BIGNUM *A,*Ai = NULL;
- BN_CTX *ctx;
int ret=0;
- if (p_ctx == NULL)
+ if (rsa->blinding != NULL)
+ RSA_blinding_off(rsa);
+
+ rsa->blinding = RSA_setup_blinding(rsa, ctx);
+ if (rsa->blinding == NULL)
+ goto err;
+
+ rsa->flags |= RSA_FLAG_BLINDING;
+ rsa->flags &= ~RSA_FLAG_NO_BLINDING;
+ ret=1;
+err:
+ return(ret);
+ }
+
+static BIGNUM *rsa_get_public_exp(const BIGNUM *d, const BIGNUM *p,
+ const BIGNUM *q, BN_CTX *ctx)
+{
+ BIGNUM *ret = NULL, *r0, *r1, *r2;
+
+ if (d == NULL || p == NULL || q == NULL)
+ return NULL;
+
+ BN_CTX_start(ctx);
+ r0 = BN_CTX_get(ctx);
+ r1 = BN_CTX_get(ctx);
+ r2 = BN_CTX_get(ctx);
+ if (r2 == NULL)
+ goto err;
+
+ if (!BN_sub(r1, p, BN_value_one())) goto err;
+ if (!BN_sub(r2, q, BN_value_one())) goto err;
+ if (!BN_mul(r0, r1, r2, ctx)) goto err;
+
+ ret = BN_mod_inverse(NULL, d, r0, ctx);
+err:
+ BN_CTX_end(ctx);
+ return ret;
+}
+
+BN_BLINDING *RSA_setup_blinding(RSA *rsa, BN_CTX *in_ctx)
+{
+ BIGNUM local_n;
+ BIGNUM *e,*n;
+ BN_CTX *ctx;
+ BN_BLINDING *ret = NULL;
+
+ if (in_ctx == NULL)
{
- if ((ctx=BN_CTX_new()) == NULL) goto err;
+ if ((ctx = BN_CTX_new()) == NULL) return 0;
}
else
- ctx=p_ctx;
+ ctx = in_ctx;
- /* XXXXX: Shouldn't this be RSA_blinding_off(rsa)? */
- if (rsa->blinding != NULL)
+ BN_CTX_start(ctx);
+ e = BN_CTX_get(ctx);
+ if (e == NULL)
{
- BN_BLINDING_free(rsa->blinding);
- rsa->blinding = NULL;
+ RSAerr(RSA_F_RSA_SETUP_BLINDING, ERR_R_MALLOC_FAILURE);
+ goto err;
}
- /* NB: similar code appears in setup_blinding (rsa_eay.c);
- * this should be placed in a new function of its own, but for reasons
- * of binary compatibility can't */
+ if (rsa->e == NULL)
+ {
+ e = rsa_get_public_exp(rsa->d, rsa->p, rsa->q, ctx);
+ if (e == NULL)
+ {
+ RSAerr(RSA_F_RSA_SETUP_BLINDING, RSA_R_NO_PUBLIC_EXPONENT);
+ goto err;
+ }
+ }
+ else
+ e = rsa->e;
- BN_CTX_start(ctx);
- A = BN_CTX_get(ctx);
+
if ((RAND_status() == 0) && rsa->d != NULL && rsa->d->d != NULL)
{
- /* if PRNG is not properly seeded, resort to secret exponent as unpredictable seed */
+ /* if PRNG is not properly seeded, resort to secret
+ * exponent as unpredictable seed */
RAND_add(rsa->d->d, rsa->d->dmax * sizeof rsa->d->d[0], 0.0);
- if (!BN_pseudo_rand_range(A,rsa->n)) goto err;
}
- else
+
+ if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME))
{
- if (!BN_rand_range(A,rsa->n)) goto err;
+ /* Set BN_FLG_CONSTTIME flag */
+ n = &local_n;
+ BN_with_flags(n, rsa->n, BN_FLG_CONSTTIME);
}
- if ((Ai=BN_mod_inverse(NULL,A,rsa->n,ctx)) == NULL) goto err;
+ else
+ n = rsa->n;
- if (!rsa->meth->bn_mod_exp(A,A,rsa->e,rsa->n,ctx,rsa->_method_mod_n))
+ ret = BN_BLINDING_create_param(NULL, e, n, ctx,
+ rsa->meth->bn_mod_exp, rsa->_method_mod_n);
+ if (ret == NULL)
+ {
+ RSAerr(RSA_F_RSA_SETUP_BLINDING, ERR_R_BN_LIB);
goto err;
- if ((rsa->blinding=BN_BLINDING_new(A,Ai,rsa->n)) == NULL) goto err;
- /* to make things thread-safe without excessive locking,
- * rsa->blinding will be used just by the current thread: */
- rsa->blinding->thread_id = CRYPTO_thread_id();
- rsa->flags |= RSA_FLAG_BLINDING;
- rsa->flags &= ~RSA_FLAG_NO_BLINDING;
- ret=1;
+ }
+ CRYPTO_THREADID_current(BN_BLINDING_thread_id(ret));
err:
- if (Ai != NULL) BN_free(Ai);
BN_CTX_end(ctx);
- if (ctx != p_ctx) BN_CTX_free(ctx);
- return(ret);
- }
+ if (in_ctx == NULL)
+ BN_CTX_free(ctx);
+ if(rsa->e == NULL)
+ BN_free(e);
+
+ return ret;
+}
int RSA_memory_lock(RSA *r)
{
@@ -389,7 +458,7 @@ int RSA_memory_lock(RSA *r)
j+= (*t[i])->top;
if ((p=OPENSSL_malloc_locked((off+j)*sizeof(BN_ULONG))) == NULL)
{
- RSAerr(RSA_F_MEMORY_LOCK,ERR_R_MALLOC_FAILURE);
+ RSAerr(RSA_F_RSA_MEMORY_LOCK,ERR_R_MALLOC_FAILURE);
return(0);
}
bn=(BIGNUM *)p;
diff --git a/crypto/rsa/rsa_locl.h b/crypto/rsa/rsa_locl.h
new file mode 100644
index 0000000000..f5d2d56628
--- /dev/null
+++ b/crypto/rsa/rsa_locl.h
@@ -0,0 +1,4 @@
+extern int int_rsa_verify(int dtype, const unsigned char *m, unsigned int m_len,
+ unsigned char *rm, size_t *prm_len,
+ const unsigned char *sigbuf, size_t siglen,
+ RSA *rsa);
diff --git a/crypto/rsa/rsa_null.c b/crypto/rsa/rsa_null.c
index 1bf70ca2a9..2f2202f142 100644
--- a/crypto/rsa/rsa_null.c
+++ b/crypto/rsa/rsa_null.c
@@ -1,5 +1,5 @@
/* rsa_null.c */
-/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
* project 1999.
*/
/* ====================================================================
@@ -107,35 +107,35 @@ const RSA_METHOD *RSA_null_method(void)
static int RSA_null_public_encrypt(int flen, const unsigned char *from,
unsigned char *to, RSA *rsa, int padding)
{
- RSAerr(RSA_F_RSA_NULL, RSA_R_RSA_OPERATIONS_NOT_SUPPORTED);
+ RSAerr(RSA_F_RSA_NULL_PUBLIC_ENCRYPT, RSA_R_RSA_OPERATIONS_NOT_SUPPORTED);
return -1;
}
static int RSA_null_private_encrypt(int flen, const unsigned char *from,
unsigned char *to, RSA *rsa, int padding)
{
- RSAerr(RSA_F_RSA_NULL, RSA_R_RSA_OPERATIONS_NOT_SUPPORTED);
+ RSAerr(RSA_F_RSA_NULL_PRIVATE_ENCRYPT, RSA_R_RSA_OPERATIONS_NOT_SUPPORTED);
return -1;
}
static int RSA_null_private_decrypt(int flen, const unsigned char *from,
unsigned char *to, RSA *rsa, int padding)
{
- RSAerr(RSA_F_RSA_NULL, RSA_R_RSA_OPERATIONS_NOT_SUPPORTED);
+ RSAerr(RSA_F_RSA_NULL_PRIVATE_DECRYPT, RSA_R_RSA_OPERATIONS_NOT_SUPPORTED);
return -1;
}
static int RSA_null_public_decrypt(int flen, const unsigned char *from,
unsigned char *to, RSA *rsa, int padding)
{
- RSAerr(RSA_F_RSA_NULL, RSA_R_RSA_OPERATIONS_NOT_SUPPORTED);
+ RSAerr(RSA_F_RSA_NULL_PUBLIC_DECRYPT, RSA_R_RSA_OPERATIONS_NOT_SUPPORTED);
return -1;
}
#if 0 /* not currently used */
static int RSA_null_mod_exp(BIGNUM *r0, BIGNUM *I, RSA *rsa)
{
- RSAerr(RSA_F_RSA_NULL, RSA_R_RSA_OPERATIONS_NOT_SUPPORTED);
+ ...err(RSA_F_RSA_NULL_MOD_EXP, RSA_R_RSA_OPERATIONS_NOT_SUPPORTED);
return -1;
}
#endif
@@ -149,5 +149,3 @@ static int RSA_null_finish(RSA *rsa)
{
return(1);
}
-
-
diff --git a/crypto/rsa/rsa_oaep.c b/crypto/rsa/rsa_oaep.c
index e3f7c608ec..553d212ebe 100644
--- a/crypto/rsa/rsa_oaep.c
+++ b/crypto/rsa/rsa_oaep.c
@@ -28,7 +28,7 @@
#include <openssl/rand.h>
#include <openssl/sha.h>
-int MGF1(unsigned char *mask, long len,
+static int MGF1(unsigned char *mask, long len,
const unsigned char *seed, long seedlen);
int RSA_padding_add_PKCS1_OAEP(unsigned char *to, int tlen,
@@ -52,18 +52,12 @@ int RSA_padding_add_PKCS1_OAEP(unsigned char *to, int tlen,
return 0;
}
- dbmask = OPENSSL_malloc(emlen - SHA_DIGEST_LENGTH);
- if (dbmask == NULL)
- {
- RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_OAEP, ERR_R_MALLOC_FAILURE);
- return 0;
- }
-
to[0] = 0;
seed = to + 1;
db = to + SHA_DIGEST_LENGTH + 1;
- EVP_Digest((void *)param, plen, db, NULL, EVP_sha1(), NULL);
+ if (!EVP_Digest((void *)param, plen, db, NULL, EVP_sha1(), NULL))
+ return 0;
memset(db + SHA_DIGEST_LENGTH, 0,
emlen - flen - 2 * SHA_DIGEST_LENGTH - 1);
db[emlen - flen - SHA_DIGEST_LENGTH - 1] = 0x01;
@@ -76,11 +70,20 @@ int RSA_padding_add_PKCS1_OAEP(unsigned char *to, int tlen,
20);
#endif
- MGF1(dbmask, emlen - SHA_DIGEST_LENGTH, seed, SHA_DIGEST_LENGTH);
+ dbmask = OPENSSL_malloc(emlen - SHA_DIGEST_LENGTH);
+ if (dbmask == NULL)
+ {
+ RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_OAEP, ERR_R_MALLOC_FAILURE);
+ return 0;
+ }
+
+ if (MGF1(dbmask, emlen - SHA_DIGEST_LENGTH, seed, SHA_DIGEST_LENGTH) < 0)
+ return 0;
for (i = 0; i < emlen - SHA_DIGEST_LENGTH; i++)
db[i] ^= dbmask[i];
- MGF1(seedmask, SHA_DIGEST_LENGTH, db, emlen - SHA_DIGEST_LENGTH);
+ if (MGF1(seedmask, SHA_DIGEST_LENGTH, db, emlen - SHA_DIGEST_LENGTH) < 0)
+ return 0;
for (i = 0; i < SHA_DIGEST_LENGTH; i++)
seed[i] ^= seedmask[i];
@@ -96,6 +99,7 @@ int RSA_padding_check_PKCS1_OAEP(unsigned char *to, int tlen,
const unsigned char *maskeddb;
int lzero;
unsigned char *db = NULL, seed[SHA_DIGEST_LENGTH], phash[SHA_DIGEST_LENGTH];
+ unsigned char *padded_from;
int bad = 0;
if (--num < 2 * SHA_DIGEST_LENGTH + 1)
@@ -106,8 +110,6 @@ int RSA_padding_check_PKCS1_OAEP(unsigned char *to, int tlen,
lzero = num - flen;
if (lzero < 0)
{
- /* lzero == -1 */
-
/* signalling this error immediately after detection might allow
* for side-channel attacks (e.g. timing if 'plen' is huge
* -- cf. James H. Manger, "A Chosen Ciphertext Attack on RSA Optimal
@@ -115,26 +117,37 @@ int RSA_padding_check_PKCS1_OAEP(unsigned char *to, int tlen,
* so we use a 'bad' flag */
bad = 1;
lzero = 0;
+ flen = num; /* don't overflow the memcpy to padded_from */
}
- maskeddb = from - lzero + SHA_DIGEST_LENGTH;
dblen = num - SHA_DIGEST_LENGTH;
- db = OPENSSL_malloc(dblen);
+ db = OPENSSL_malloc(dblen + num);
if (db == NULL)
{
- RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_OAEP, ERR_R_MALLOC_FAILURE);
+ RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_OAEP, ERR_R_MALLOC_FAILURE);
return -1;
}
- MGF1(seed, SHA_DIGEST_LENGTH, maskeddb, dblen);
- for (i = lzero; i < SHA_DIGEST_LENGTH; i++)
- seed[i] ^= from[i - lzero];
+ /* Always do this zero-padding copy (even when lzero == 0)
+ * to avoid leaking timing info about the value of lzero. */
+ padded_from = db + dblen;
+ memset(padded_from, 0, lzero);
+ memcpy(padded_from + lzero, from, flen);
+
+ maskeddb = padded_from + SHA_DIGEST_LENGTH;
+
+ if (MGF1(seed, SHA_DIGEST_LENGTH, maskeddb, dblen))
+ return -1;
+ for (i = 0; i < SHA_DIGEST_LENGTH; i++)
+ seed[i] ^= padded_from[i];
- MGF1(db, dblen, seed, SHA_DIGEST_LENGTH);
+ if (MGF1(db, dblen, seed, SHA_DIGEST_LENGTH))
+ return -1;
for (i = 0; i < dblen; i++)
db[i] ^= maskeddb[i];
- EVP_Digest((void *)param, plen, phash, NULL, EVP_sha1(), NULL);
+ if (!EVP_Digest((void *)param, plen, phash, NULL, EVP_sha1(), NULL))
+ return -1;
if (memcmp(db, phash, SHA_DIGEST_LENGTH) != 0 || bad)
goto decoding_err;
@@ -143,13 +156,13 @@ int RSA_padding_check_PKCS1_OAEP(unsigned char *to, int tlen,
for (i = SHA_DIGEST_LENGTH; i < dblen; i++)
if (db[i] != 0x00)
break;
- if (db[i] != 0x01 || i++ >= dblen)
+ if (i == dblen || db[i] != 0x01)
goto decoding_err;
else
{
/* everything looks OK */
- mlen = dblen - i;
+ mlen = dblen - ++i;
if (tlen < mlen)
{
RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_OAEP, RSA_R_DATA_TOO_LARGE);
@@ -170,37 +183,53 @@ decoding_err:
return -1;
}
-int MGF1(unsigned char *mask, long len,
- const unsigned char *seed, long seedlen)
+int PKCS1_MGF1(unsigned char *mask, long len,
+ const unsigned char *seed, long seedlen, const EVP_MD *dgst)
{
long i, outlen = 0;
unsigned char cnt[4];
EVP_MD_CTX c;
- unsigned char md[SHA_DIGEST_LENGTH];
+ unsigned char md[EVP_MAX_MD_SIZE];
+ int mdlen;
+ int rv = -1;
EVP_MD_CTX_init(&c);
+ mdlen = EVP_MD_size(dgst);
+ if (mdlen < 0)
+ goto err;
for (i = 0; outlen < len; i++)
{
cnt[0] = (unsigned char)((i >> 24) & 255);
cnt[1] = (unsigned char)((i >> 16) & 255);
cnt[2] = (unsigned char)((i >> 8)) & 255;
cnt[3] = (unsigned char)(i & 255);
- EVP_DigestInit_ex(&c,EVP_sha1(), NULL);
- EVP_DigestUpdate(&c, seed, seedlen);
- EVP_DigestUpdate(&c, cnt, 4);
- if (outlen + SHA_DIGEST_LENGTH <= len)
+ if (!EVP_DigestInit_ex(&c,dgst, NULL)
+ || !EVP_DigestUpdate(&c, seed, seedlen)
+ || !EVP_DigestUpdate(&c, cnt, 4))
+ goto err;
+ if (outlen + mdlen <= len)
{
- EVP_DigestFinal_ex(&c, mask + outlen, NULL);
- outlen += SHA_DIGEST_LENGTH;
+ if (!EVP_DigestFinal_ex(&c, mask + outlen, NULL))
+ goto err;
+ outlen += mdlen;
}
else
{
- EVP_DigestFinal_ex(&c, md, NULL);
+ if (!EVP_DigestFinal_ex(&c, md, NULL))
+ goto err;
memcpy(mask + outlen, md, len - outlen);
outlen = len;
}
}
+ rv = 0;
+ err:
EVP_MD_CTX_cleanup(&c);
- return 0;
+ return rv;
+ }
+
+static int MGF1(unsigned char *mask, long len, const unsigned char *seed,
+ long seedlen)
+ {
+ return PKCS1_MGF1(mask, len, seed, seedlen, EVP_sha1());
}
#endif
diff --git a/crypto/rsa/rsa_pmeth.c b/crypto/rsa/rsa_pmeth.c
new file mode 100644
index 0000000000..297e17cdcf
--- /dev/null
+++ b/crypto/rsa/rsa_pmeth.c
@@ -0,0 +1,585 @@
+/* crypto/rsa/rsa_pmeth.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 2006.
+ */
+/* ====================================================================
+ * Copyright (c) 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
+ * licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ * nor may "OpenSSL" appear in their names without prior written
+ * permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ * acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com). This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/asn1t.h>
+#include <openssl/x509.h>
+#include <openssl/rsa.h>
+#include <openssl/bn.h>
+#include <openssl/evp.h>
+#include "evp_locl.h"
+#include "rsa_locl.h"
+
+/* RSA pkey context structure */
+
+typedef struct
+ {
+ /* Key gen parameters */
+ int nbits;
+ BIGNUM *pub_exp;
+ /* Keygen callback info */
+ int gentmp[2];
+ /* RSA padding mode */
+ int pad_mode;
+ /* message digest */
+ const EVP_MD *md;
+ /* PSS/OAEP salt length */
+ int saltlen;
+ /* Temp buffer */
+ unsigned char *tbuf;
+ } RSA_PKEY_CTX;
+
+static int pkey_rsa_init(EVP_PKEY_CTX *ctx)
+ {
+ RSA_PKEY_CTX *rctx;
+ rctx = OPENSSL_malloc(sizeof(RSA_PKEY_CTX));
+ if (!rctx)
+ return 0;
+ rctx->nbits = 1024;
+ rctx->pub_exp = NULL;
+ rctx->pad_mode = RSA_PKCS1_PADDING;
+ rctx->md = NULL;
+ rctx->tbuf = NULL;
+
+ rctx->saltlen = -2;
+
+ ctx->data = rctx;
+ ctx->keygen_info = rctx->gentmp;
+ ctx->keygen_info_count = 2;
+
+ return 1;
+ }
+
+static int pkey_rsa_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src)
+ {
+ RSA_PKEY_CTX *dctx, *sctx;
+ if (!pkey_rsa_init(dst))
+ return 0;
+ sctx = src->data;
+ dctx = dst->data;
+ dctx->nbits = sctx->nbits;
+ if (sctx->pub_exp)
+ {
+ dctx->pub_exp = BN_dup(sctx->pub_exp);
+ if (!dctx->pub_exp)
+ return 0;
+ }
+ dctx->pad_mode = sctx->pad_mode;
+ dctx->md = sctx->md;
+ return 1;
+ }
+
+static int setup_tbuf(RSA_PKEY_CTX *ctx, EVP_PKEY_CTX *pk)
+ {
+ if (ctx->tbuf)
+ return 1;
+ ctx->tbuf = OPENSSL_malloc(EVP_PKEY_size(pk->pkey));
+ if (!ctx->tbuf)
+ return 0;
+ return 1;
+ }
+
+static void pkey_rsa_cleanup(EVP_PKEY_CTX *ctx)
+ {
+ RSA_PKEY_CTX *rctx = ctx->data;
+ if (rctx)
+ {
+ if (rctx->pub_exp)
+ BN_free(rctx->pub_exp);
+ if (rctx->tbuf)
+ OPENSSL_free(rctx->tbuf);
+ OPENSSL_free(rctx);
+ }
+ }
+
+static int pkey_rsa_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen,
+ const unsigned char *tbs, size_t tbslen)
+ {
+ int ret;
+ RSA_PKEY_CTX *rctx = ctx->data;
+ RSA *rsa = ctx->pkey->pkey.rsa;
+
+ if (rctx->md)
+ {
+ if (tbslen != (size_t)EVP_MD_size(rctx->md))
+ {
+ RSAerr(RSA_F_PKEY_RSA_SIGN,
+ RSA_R_INVALID_DIGEST_LENGTH);
+ return -1;
+ }
+ if (rctx->pad_mode == RSA_X931_PADDING)
+ {
+ if (!setup_tbuf(rctx, ctx))
+ return -1;
+ memcpy(rctx->tbuf, tbs, tbslen);
+ rctx->tbuf[tbslen] =
+ RSA_X931_hash_id(EVP_MD_type(rctx->md));
+ ret = RSA_private_encrypt(tbslen + 1, rctx->tbuf,
+ sig, rsa, RSA_X931_PADDING);
+ }
+ else if (rctx->pad_mode == RSA_PKCS1_PADDING)
+ {
+ unsigned int sltmp;
+ ret = RSA_sign(EVP_MD_type(rctx->md),
+ tbs, tbslen, sig, &sltmp, rsa);
+ if (ret <= 0)
+ return ret;
+ ret = sltmp;
+ }
+ else if (rctx->pad_mode == RSA_PKCS1_PSS_PADDING)
+ {
+ if (!setup_tbuf(rctx, ctx))
+ return -1;
+ if (!RSA_padding_add_PKCS1_PSS(rsa, rctx->tbuf, tbs,
+ rctx->md, rctx->saltlen))
+ return -1;
+ ret = RSA_private_encrypt(RSA_size(rsa), rctx->tbuf,
+ sig, rsa, RSA_NO_PADDING);
+ }
+ else
+ return -1;
+ }
+ else
+ ret = RSA_private_encrypt(tbslen, tbs, sig, ctx->pkey->pkey.rsa,
+ rctx->pad_mode);
+ if (ret < 0)
+ return ret;
+ *siglen = ret;
+ return 1;
+ }
+
+
+static int pkey_rsa_verifyrecover(EVP_PKEY_CTX *ctx,
+ unsigned char *rout, size_t *routlen,
+ const unsigned char *sig, size_t siglen)
+ {
+ int ret;
+ RSA_PKEY_CTX *rctx = ctx->data;
+
+ if (rctx->md)
+ {
+ if (rctx->pad_mode == RSA_X931_PADDING)
+ {
+ if (!setup_tbuf(rctx, ctx))
+ return -1;
+ ret = RSA_public_decrypt(siglen, sig,
+ rctx->tbuf, ctx->pkey->pkey.rsa,
+ RSA_X931_PADDING);
+ if (ret < 1)
+ return 0;
+ ret--;
+ if (rctx->tbuf[ret] !=
+ RSA_X931_hash_id(EVP_MD_type(rctx->md)))
+ {
+ RSAerr(RSA_F_PKEY_RSA_VERIFYRECOVER,
+ RSA_R_ALGORITHM_MISMATCH);
+ return 0;
+ }
+ if (ret != EVP_MD_size(rctx->md))
+ {
+ RSAerr(RSA_F_PKEY_RSA_VERIFYRECOVER,
+ RSA_R_INVALID_DIGEST_LENGTH);
+ return 0;
+ }
+ if (rout)
+ memcpy(rout, rctx->tbuf, ret);
+ }
+ else if (rctx->pad_mode == RSA_PKCS1_PADDING)
+ {
+ size_t sltmp;
+ ret = int_rsa_verify(EVP_MD_type(rctx->md),
+ NULL, 0, rout, &sltmp,
+ sig, siglen, ctx->pkey->pkey.rsa);
+ ret = sltmp;
+ }
+ else
+ return -1;
+ }
+ else
+ ret = RSA_public_decrypt(siglen, sig, rout, ctx->pkey->pkey.rsa,
+ rctx->pad_mode);
+ if (ret < 0)
+ return ret;
+ *routlen = ret;
+ return 1;
+ }
+
+static int pkey_rsa_verify(EVP_PKEY_CTX *ctx,
+ const unsigned char *sig, size_t siglen,
+ const unsigned char *tbs, size_t tbslen)
+ {
+ RSA_PKEY_CTX *rctx = ctx->data;
+ RSA *rsa = ctx->pkey->pkey.rsa;
+ size_t rslen;
+ if (rctx->md)
+ {
+ if (rctx->pad_mode == RSA_PKCS1_PADDING)
+ return RSA_verify(EVP_MD_type(rctx->md), tbs, tbslen,
+ sig, siglen, rsa);
+ if (rctx->pad_mode == RSA_X931_PADDING)
+ {
+ if (pkey_rsa_verifyrecover(ctx, NULL, &rslen,
+ sig, siglen) <= 0)
+ return 0;
+ }
+ else if (rctx->pad_mode == RSA_PKCS1_PSS_PADDING)
+ {
+ int ret;
+ if (!setup_tbuf(rctx, ctx))
+ return -1;
+ ret = RSA_public_decrypt(siglen, sig, rctx->tbuf,
+ rsa, RSA_NO_PADDING);
+ if (ret <= 0)
+ return 0;
+ ret = RSA_verify_PKCS1_PSS(rsa, tbs, rctx->md,
+ rctx->tbuf, rctx->saltlen);
+ if (ret <= 0)
+ return 0;
+ return 1;
+ }
+ else
+ return -1;
+ }
+ else
+ {
+ if (!setup_tbuf(rctx, ctx))
+ return -1;
+ rslen = RSA_public_decrypt(siglen, sig, rctx->tbuf,
+ rsa, rctx->pad_mode);
+ if (rslen == 0)
+ return 0;
+ }
+
+ if ((rslen != tbslen) || memcmp(tbs, rctx->tbuf, rslen))
+ return 0;
+
+ return 1;
+
+ }
+
+
+static int pkey_rsa_encrypt(EVP_PKEY_CTX *ctx,
+ unsigned char *out, size_t *outlen,
+ const unsigned char *in, size_t inlen)
+ {
+ int ret;
+ RSA_PKEY_CTX *rctx = ctx->data;
+ ret = RSA_public_encrypt(inlen, in, out, ctx->pkey->pkey.rsa,
+ rctx->pad_mode);
+ if (ret < 0)
+ return ret;
+ *outlen = ret;
+ return 1;
+ }
+
+static int pkey_rsa_decrypt(EVP_PKEY_CTX *ctx,
+ unsigned char *out, size_t *outlen,
+ const unsigned char *in, size_t inlen)
+ {
+ int ret;
+ RSA_PKEY_CTX *rctx = ctx->data;
+ ret = RSA_private_decrypt(inlen, in, out, ctx->pkey->pkey.rsa,
+ rctx->pad_mode);
+ if (ret < 0)
+ return ret;
+ *outlen = ret;
+ return 1;
+ }
+
+static int check_padding_md(const EVP_MD *md, int padding)
+ {
+ if (!md)
+ return 1;
+
+ if (padding == RSA_NO_PADDING)
+ {
+ RSAerr(RSA_F_CHECK_PADDING_MD, RSA_R_INVALID_PADDING_MODE);
+ return 0;
+ }
+
+ if (padding == RSA_X931_PADDING)
+ {
+ if (RSA_X931_hash_id(EVP_MD_type(md)) == -1)
+ {
+ RSAerr(RSA_F_CHECK_PADDING_MD,
+ RSA_R_INVALID_X931_DIGEST);
+ return 0;
+ }
+ return 1;
+ }
+
+ return 1;
+ }
+
+
+static int pkey_rsa_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
+ {
+ RSA_PKEY_CTX *rctx = ctx->data;
+ switch (type)
+ {
+ case EVP_PKEY_CTRL_RSA_PADDING:
+ if ((p1 >= RSA_PKCS1_PADDING) && (p1 <= RSA_PKCS1_PSS_PADDING))
+ {
+ if (!check_padding_md(rctx->md, p1))
+ return 0;
+ if (p1 == RSA_PKCS1_PSS_PADDING)
+ {
+ if (!(ctx->operation &
+ (EVP_PKEY_OP_SIGN | EVP_PKEY_OP_VERIFY)))
+ goto bad_pad;
+ if (!rctx->md)
+ rctx->md = EVP_sha1();
+ }
+ if (p1 == RSA_PKCS1_OAEP_PADDING)
+ {
+ if (!(ctx->operation & EVP_PKEY_OP_TYPE_CRYPT))
+ goto bad_pad;
+ if (!rctx->md)
+ rctx->md = EVP_sha1();
+ }
+ rctx->pad_mode = p1;
+ return 1;
+ }
+ bad_pad:
+ RSAerr(RSA_F_PKEY_RSA_CTRL,
+ RSA_R_ILLEGAL_OR_UNSUPPORTED_PADDING_MODE);
+ return -2;
+
+ case EVP_PKEY_CTRL_RSA_PSS_SALTLEN:
+ if (p1 < -2)
+ return -2;
+ if (rctx->pad_mode != RSA_PKCS1_PSS_PADDING)
+ {
+ RSAerr(RSA_F_PKEY_RSA_CTRL, RSA_R_INVALID_PSS_SALTLEN);
+ return -2;
+ }
+ rctx->saltlen = p1;
+ return 1;
+
+ case EVP_PKEY_CTRL_RSA_KEYGEN_BITS:
+ if (p1 < 256)
+ {
+ RSAerr(RSA_F_PKEY_RSA_CTRL, RSA_R_INVALID_KEYBITS);
+ return -2;
+ }
+ rctx->nbits = p1;
+ return 1;
+
+ case EVP_PKEY_CTRL_RSA_KEYGEN_PUBEXP:
+ if (!p2)
+ return -2;
+ rctx->pub_exp = p2;
+ return 1;
+
+ case EVP_PKEY_CTRL_MD:
+ if (!check_padding_md(p2, rctx->pad_mode))
+ return 0;
+ rctx->md = p2;
+ return 1;
+
+ case EVP_PKEY_CTRL_DIGESTINIT:
+ case EVP_PKEY_CTRL_PKCS7_ENCRYPT:
+ case EVP_PKEY_CTRL_PKCS7_DECRYPT:
+ case EVP_PKEY_CTRL_PKCS7_SIGN:
+#ifndef OPENSSL_NO_CMS
+ case EVP_PKEY_CTRL_CMS_ENCRYPT:
+ case EVP_PKEY_CTRL_CMS_DECRYPT:
+ case EVP_PKEY_CTRL_CMS_SIGN:
+#endif
+ return 1;
+ case EVP_PKEY_CTRL_PEER_KEY:
+ RSAerr(RSA_F_PKEY_RSA_CTRL,
+ RSA_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
+ return -2;
+
+ default:
+ return -2;
+
+ }
+ }
+
+static int pkey_rsa_ctrl_str(EVP_PKEY_CTX *ctx,
+ const char *type, const char *value)
+ {
+ if (!value)
+ {
+ RSAerr(RSA_F_PKEY_RSA_CTRL_STR, RSA_R_VALUE_MISSING);
+ return 0;
+ }
+ if (!strcmp(type, "rsa_padding_mode"))
+ {
+ int pm;
+ if (!strcmp(value, "pkcs1"))
+ pm = RSA_PKCS1_PADDING;
+ else if (!strcmp(value, "sslv23"))
+ pm = RSA_SSLV23_PADDING;
+ else if (!strcmp(value, "none"))
+ pm = RSA_NO_PADDING;
+ else if (!strcmp(value, "oeap"))
+ pm = RSA_PKCS1_OAEP_PADDING;
+ else if (!strcmp(value, "x931"))
+ pm = RSA_X931_PADDING;
+ else if (!strcmp(value, "pss"))
+ pm = RSA_PKCS1_PSS_PADDING;
+ else
+ {
+ RSAerr(RSA_F_PKEY_RSA_CTRL_STR,
+ RSA_R_UNKNOWN_PADDING_TYPE);
+ return -2;
+ }
+ return EVP_PKEY_CTX_set_rsa_padding(ctx, pm);
+ }
+
+ if (!strcmp(type, "rsa_pss_saltlen"))
+ {
+ int saltlen;
+ saltlen = atoi(value);
+ return EVP_PKEY_CTX_set_rsa_pss_saltlen(ctx, saltlen);
+ }
+
+ if (!strcmp(type, "rsa_keygen_bits"))
+ {
+ int nbits;
+ nbits = atoi(value);
+ return EVP_PKEY_CTX_set_rsa_keygen_bits(ctx, nbits);
+ }
+
+ if (!strcmp(type, "rsa_keygen_pubexp"))
+ {
+ int ret;
+ BIGNUM *pubexp = NULL;
+ if (!BN_asc2bn(&pubexp, value))
+ return 0;
+ ret = EVP_PKEY_CTX_set_rsa_keygen_pubexp(ctx, pubexp);
+ if (ret <= 0)
+ BN_free(pubexp);
+ return ret;
+ }
+
+ return -2;
+ }
+
+static int pkey_rsa_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
+ {
+ RSA *rsa = NULL;
+ RSA_PKEY_CTX *rctx = ctx->data;
+ BN_GENCB *pcb, cb;
+ int ret;
+ if (!rctx->pub_exp)
+ {
+ rctx->pub_exp = BN_new();
+ if (!rctx->pub_exp || !BN_set_word(rctx->pub_exp, RSA_F4))
+ return 0;
+ }
+ rsa = RSA_new();
+ if (!rsa)
+ return 0;
+ if (ctx->pkey_gencb)
+ {
+ pcb = &cb;
+ evp_pkey_set_cb_translate(pcb, ctx);
+ }
+ else
+ pcb = NULL;
+ ret = RSA_generate_key_ex(rsa, rctx->nbits, rctx->pub_exp, pcb);
+ if (ret > 0)
+ EVP_PKEY_assign_RSA(pkey, rsa);
+ else
+ RSA_free(rsa);
+ return ret;
+ }
+
+const EVP_PKEY_METHOD rsa_pkey_meth =
+ {
+ EVP_PKEY_RSA,
+ EVP_PKEY_FLAG_AUTOARGLEN,
+ pkey_rsa_init,
+ pkey_rsa_copy,
+ pkey_rsa_cleanup,
+
+ 0,0,
+
+ 0,
+ pkey_rsa_keygen,
+
+ 0,
+ pkey_rsa_sign,
+
+ 0,
+ pkey_rsa_verify,
+
+ 0,
+ pkey_rsa_verifyrecover,
+
+
+ 0,0,0,0,
+
+ 0,
+ pkey_rsa_encrypt,
+
+ 0,
+ pkey_rsa_decrypt,
+
+ 0,0,
+
+ pkey_rsa_ctrl,
+ pkey_rsa_ctrl_str
+
+
+ };
diff --git a/crypto/rsa/rsa_prn.c b/crypto/rsa/rsa_prn.c
new file mode 100644
index 0000000000..224db0fae5
--- /dev/null
+++ b/crypto/rsa/rsa_prn.c
@@ -0,0 +1,93 @@
+/* crypto/rsa/rsa_prn.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 2006.
+ */
+/* ====================================================================
+ * Copyright (c) 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
+ * licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ * nor may "OpenSSL" appear in their names without prior written
+ * permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ * acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com). This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/rsa.h>
+#include <openssl/evp.h>
+
+#ifndef OPENSSL_NO_FP_API
+int RSA_print_fp(FILE *fp, const RSA *x, int off)
+ {
+ BIO *b;
+ int ret;
+
+ if ((b=BIO_new(BIO_s_file())) == NULL)
+ {
+ RSAerr(RSA_F_RSA_PRINT_FP,ERR_R_BUF_LIB);
+ return(0);
+ }
+ BIO_set_fp(b,fp,BIO_NOCLOSE);
+ ret=RSA_print(b,x,off);
+ BIO_free(b);
+ return(ret);
+ }
+#endif
+
+int RSA_print(BIO *bp, const RSA *x, int off)
+ {
+ EVP_PKEY *pk;
+ int ret;
+ pk = EVP_PKEY_new();
+ if (!pk || !EVP_PKEY_set1_RSA(pk, (RSA *)x))
+ return 0;
+ ret = EVP_PKEY_print_private(bp, pk, off, NULL);
+ EVP_PKEY_free(pk);
+ return ret;
+ }
+
diff --git a/crypto/rsa/rsa_pss.c b/crypto/rsa/rsa_pss.c
new file mode 100644
index 0000000000..4efb8eddad
--- /dev/null
+++ b/crypto/rsa/rsa_pss.c
@@ -0,0 +1,282 @@
+/* rsa_pss.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 "cryptlib.h"
+#include <openssl/bn.h>
+#include <openssl/rsa.h>
+#include <openssl/evp.h>
+#include <openssl/rand.h>
+#include <openssl/sha.h>
+
+static const unsigned char zeroes[] = {0,0,0,0,0,0,0,0};
+
+#if defined(_MSC_VER) && defined(_ARM_)
+#pragma optimize("g", off)
+#endif
+
+int RSA_verify_PKCS1_PSS(RSA *rsa, const unsigned char *mHash,
+ const EVP_MD *Hash, const unsigned char *EM, int sLen)
+ {
+ int i;
+ int ret = 0;
+ int hLen, maskedDBLen, MSBits, emLen;
+ const unsigned char *H;
+ unsigned char *DB = NULL;
+ EVP_MD_CTX ctx;
+ unsigned char H_[EVP_MAX_MD_SIZE];
+ EVP_MD_CTX_init(&ctx);
+
+ hLen = EVP_MD_size(Hash);
+ if (hLen < 0)
+ goto err;
+ /*
+ * Negative sLen has special meanings:
+ * -1 sLen == hLen
+ * -2 salt length is autorecovered from signature
+ * -N reserved
+ */
+ if (sLen == -1) sLen = hLen;
+ else if (sLen == -2) sLen = -2;
+ else if (sLen < -2)
+ {
+ RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS, RSA_R_SLEN_CHECK_FAILED);
+ goto err;
+ }
+
+ MSBits = (BN_num_bits(rsa->n) - 1) & 0x7;
+ emLen = RSA_size(rsa);
+ if (EM[0] & (0xFF << MSBits))
+ {
+ RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS, RSA_R_FIRST_OCTET_INVALID);
+ goto err;
+ }
+ if (MSBits == 0)
+ {
+ EM++;
+ emLen--;
+ }
+ if (emLen < (hLen + sLen + 2)) /* sLen can be small negative */
+ {
+ RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS, RSA_R_DATA_TOO_LARGE);
+ goto err;
+ }
+ if (EM[emLen - 1] != 0xbc)
+ {
+ RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS, RSA_R_LAST_OCTET_INVALID);
+ goto err;
+ }
+ maskedDBLen = emLen - hLen - 1;
+ H = EM + maskedDBLen;
+ DB = OPENSSL_malloc(maskedDBLen);
+ if (!DB)
+ {
+ RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ if (PKCS1_MGF1(DB, maskedDBLen, H, hLen, Hash) < 0)
+ goto err;
+ for (i = 0; i < maskedDBLen; i++)
+ DB[i] ^= EM[i];
+ if (MSBits)
+ DB[0] &= 0xFF >> (8 - MSBits);
+ for (i = 0; DB[i] == 0 && i < (maskedDBLen-1); i++) ;
+ if (DB[i++] != 0x1)
+ {
+ RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS, RSA_R_SLEN_RECOVERY_FAILED);
+ goto err;
+ }
+ if (sLen >= 0 && (maskedDBLen - i) != sLen)
+ {
+ RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS, RSA_R_SLEN_CHECK_FAILED);
+ goto err;
+ }
+ if (!EVP_DigestInit_ex(&ctx, Hash, NULL)
+ || !EVP_DigestUpdate(&ctx, zeroes, sizeof zeroes)
+ || !EVP_DigestUpdate(&ctx, mHash, hLen))
+ goto err;
+ if (maskedDBLen - i)
+ {
+ if (!EVP_DigestUpdate(&ctx, DB + i, maskedDBLen - i))
+ goto err;
+ }
+ if (!EVP_DigestFinal(&ctx, H_, NULL))
+ goto err;
+ if (memcmp(H_, H, hLen))
+ {
+ RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS, RSA_R_BAD_SIGNATURE);
+ ret = 0;
+ }
+ else
+ ret = 1;
+
+ err:
+ if (DB)
+ OPENSSL_free(DB);
+ EVP_MD_CTX_cleanup(&ctx);
+
+ return ret;
+
+ }
+
+int RSA_padding_add_PKCS1_PSS(RSA *rsa, unsigned char *EM,
+ const unsigned char *mHash,
+ const EVP_MD *Hash, int sLen)
+ {
+ int i;
+ int ret = 0;
+ int hLen, maskedDBLen, MSBits, emLen;
+ unsigned char *H, *salt = NULL, *p;
+ EVP_MD_CTX ctx;
+
+ hLen = EVP_MD_size(Hash);
+ if (hLen < 0)
+ goto err;
+ /*
+ * Negative sLen has special meanings:
+ * -1 sLen == hLen
+ * -2 salt length is maximized
+ * -N reserved
+ */
+ if (sLen == -1) sLen = hLen;
+ else if (sLen == -2) sLen = -2;
+ else if (sLen < -2)
+ {
+ RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_PSS, RSA_R_SLEN_CHECK_FAILED);
+ goto err;
+ }
+
+ MSBits = (BN_num_bits(rsa->n) - 1) & 0x7;
+ emLen = RSA_size(rsa);
+ if (MSBits == 0)
+ {
+ *EM++ = 0;
+ emLen--;
+ }
+ if (sLen == -2)
+ {
+ sLen = emLen - hLen - 2;
+ }
+ else if (emLen < (hLen + sLen + 2))
+ {
+ RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_PSS,
+ RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE);
+ goto err;
+ }
+ if (sLen > 0)
+ {
+ salt = OPENSSL_malloc(sLen);
+ if (!salt)
+ {
+ RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_PSS,
+ ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ if (RAND_bytes(salt, sLen) <= 0)
+ goto err;
+ }
+ maskedDBLen = emLen - hLen - 1;
+ H = EM + maskedDBLen;
+ EVP_MD_CTX_init(&ctx);
+ if (!EVP_DigestInit_ex(&ctx, Hash, NULL)
+ || !EVP_DigestUpdate(&ctx, zeroes, sizeof zeroes)
+ || !EVP_DigestUpdate(&ctx, mHash, hLen))
+ goto err;
+ if (sLen && !EVP_DigestUpdate(&ctx, salt, sLen))
+ goto err;
+ if (!EVP_DigestFinal(&ctx, H, NULL))
+ goto err;
+ EVP_MD_CTX_cleanup(&ctx);
+
+ /* Generate dbMask in place then perform XOR on it */
+ if (PKCS1_MGF1(EM, maskedDBLen, H, hLen, Hash))
+ goto err;
+
+ p = EM;
+
+ /* Initial PS XORs with all zeroes which is a NOP so just update
+ * pointer. Note from a test above this value is guaranteed to
+ * be non-negative.
+ */
+ p += emLen - sLen - hLen - 2;
+ *p++ ^= 0x1;
+ if (sLen > 0)
+ {
+ for (i = 0; i < sLen; i++)
+ *p++ ^= salt[i];
+ }
+ if (MSBits)
+ EM[0] &= 0xFF >> (8 - MSBits);
+
+ /* H is already in place so just set final 0xbc */
+
+ EM[emLen - 1] = 0xbc;
+
+ ret = 1;
+
+ err:
+ if (salt)
+ OPENSSL_free(salt);
+
+ return ret;
+
+ }
+
+#if defined(_MSC_VER)
+#pragma optimize("",on)
+#endif
diff --git a/crypto/rsa/rsa_sign.c b/crypto/rsa/rsa_sign.c
index 9e7dfd1927..0be4ec7fb0 100644
--- a/crypto/rsa/rsa_sign.c
+++ b/crypto/rsa/rsa_sign.c
@@ -62,6 +62,7 @@
#include <openssl/rsa.h>
#include <openssl/objects.h>
#include <openssl/x509.h>
+#include "rsa_locl.h"
/* Size of an SSL signature: MD5+SHA1 */
#define SSL_SIG_LENGTH 36
@@ -76,7 +77,7 @@ int RSA_sign(int type, const unsigned char *m, unsigned int m_len,
const unsigned char *s = NULL;
X509_ALGOR algor;
ASN1_OCTET_STRING digest;
- if(rsa->flags & RSA_FLAG_SIGN_VER)
+ if((rsa->flags & RSA_FLAG_SIGN_VER) && rsa->meth->rsa_sign)
{
return rsa->meth->rsa_sign(type, m, m_len,
sigret, siglen, rsa);
@@ -142,8 +143,11 @@ int RSA_sign(int type, const unsigned char *m, unsigned int m_len,
return(ret);
}
-int RSA_verify(int dtype, const unsigned char *m, unsigned int m_len,
- unsigned char *sigbuf, unsigned int siglen, RSA *rsa)
+int int_rsa_verify(int dtype, const unsigned char *m,
+ unsigned int m_len,
+ unsigned char *rm, size_t *prm_len,
+ const unsigned char *sigbuf, size_t siglen,
+ RSA *rsa)
{
int i,ret=0,sigtype;
unsigned char *s;
@@ -151,24 +155,28 @@ int RSA_verify(int dtype, const unsigned char *m, unsigned int m_len,
if (siglen != (unsigned int)RSA_size(rsa))
{
- RSAerr(RSA_F_RSA_VERIFY,RSA_R_WRONG_SIGNATURE_LENGTH);
+ RSAerr(RSA_F_INT_RSA_VERIFY,RSA_R_WRONG_SIGNATURE_LENGTH);
return(0);
}
- if(rsa->flags & RSA_FLAG_SIGN_VER)
+ if((dtype == NID_md5_sha1) && rm)
{
- return rsa->meth->rsa_verify(dtype, m, m_len,
- sigbuf, siglen, rsa);
+ i = RSA_public_decrypt((int)siglen,
+ sigbuf,rm,rsa,RSA_PKCS1_PADDING);
+ if (i <= 0)
+ return 0;
+ *prm_len = i;
+ return 1;
}
s=(unsigned char *)OPENSSL_malloc((unsigned int)siglen);
if (s == NULL)
{
- RSAerr(RSA_F_RSA_VERIFY,ERR_R_MALLOC_FAILURE);
+ RSAerr(RSA_F_INT_RSA_VERIFY,ERR_R_MALLOC_FAILURE);
goto err;
}
if((dtype == NID_md5_sha1) && (m_len != SSL_SIG_LENGTH) ) {
- RSAerr(RSA_F_RSA_VERIFY,RSA_R_INVALID_MESSAGE_LENGTH);
+ RSAerr(RSA_F_INT_RSA_VERIFY,RSA_R_INVALID_MESSAGE_LENGTH);
goto err;
}
i=RSA_public_decrypt((int)siglen,sigbuf,s,rsa,RSA_PKCS1_PADDING);
@@ -178,13 +186,30 @@ int RSA_verify(int dtype, const unsigned char *m, unsigned int m_len,
/* Special case: SSL signature */
if(dtype == NID_md5_sha1) {
if((i != SSL_SIG_LENGTH) || memcmp(s, m, SSL_SIG_LENGTH))
- RSAerr(RSA_F_RSA_VERIFY,RSA_R_BAD_SIGNATURE);
+ RSAerr(RSA_F_INT_RSA_VERIFY,RSA_R_BAD_SIGNATURE);
else ret = 1;
} else {
const unsigned char *p=s;
sig=d2i_X509_SIG(NULL,&p,(long)i);
if (sig == NULL) goto err;
+
+ /* Excess data can be used to create forgeries */
+ if(p != s+i)
+ {
+ RSAerr(RSA_F_INT_RSA_VERIFY,RSA_R_BAD_SIGNATURE);
+ goto err;
+ }
+
+ /* Parameters to the signature algorithm can also be used to
+ create forgeries */
+ if(sig->algor->parameter
+ && ASN1_TYPE_get(sig->algor->parameter) != V_ASN1_NULL)
+ {
+ RSAerr(RSA_F_INT_RSA_VERIFY,RSA_R_BAD_SIGNATURE);
+ goto err;
+ }
+
sigtype=OBJ_obj2nid(sig->algor->algorithm);
@@ -207,15 +232,30 @@ int RSA_verify(int dtype, const unsigned char *m, unsigned int m_len,
}
else
{
- RSAerr(RSA_F_RSA_VERIFY,
+ RSAerr(RSA_F_INT_RSA_VERIFY,
RSA_R_ALGORITHM_MISMATCH);
goto err;
}
}
- if ( ((unsigned int)sig->digest->length != m_len) ||
+ if (rm)
+ {
+ const EVP_MD *md;
+ md = EVP_get_digestbynid(dtype);
+ if (md && (EVP_MD_size(md) != sig->digest->length))
+ RSAerr(RSA_F_INT_RSA_VERIFY,
+ RSA_R_INVALID_DIGEST_LENGTH);
+ else
+ {
+ memcpy(rm, sig->digest->data,
+ sig->digest->length);
+ *prm_len = sig->digest->length;
+ ret = 1;
+ }
+ }
+ else if (((unsigned int)sig->digest->length != m_len) ||
(memcmp(m,sig->digest->data,m_len) != 0))
{
- RSAerr(RSA_F_RSA_VERIFY,RSA_R_BAD_SIGNATURE);
+ RSAerr(RSA_F_INT_RSA_VERIFY,RSA_R_BAD_SIGNATURE);
}
else
ret=1;
@@ -230,3 +270,16 @@ err:
return(ret);
}
+int RSA_verify(int dtype, const unsigned char *m, unsigned int m_len,
+ const unsigned char *sigbuf, unsigned int siglen,
+ RSA *rsa)
+ {
+
+ if((rsa->flags & RSA_FLAG_SIGN_VER) && rsa->meth->rsa_verify)
+ {
+ return rsa->meth->rsa_verify(dtype, m, m_len,
+ sigbuf, siglen, rsa);
+ }
+
+ return int_rsa_verify(dtype, m, m_len, NULL, NULL, sigbuf, siglen, rsa);
+ }
diff --git a/crypto/rsa/rsa_ssl.c b/crypto/rsa/rsa_ssl.c
index ea72629494..cfeff15bc9 100644
--- a/crypto/rsa/rsa_ssl.c
+++ b/crypto/rsa/rsa_ssl.c
@@ -130,7 +130,7 @@ int RSA_padding_check_SSLv23(unsigned char *to, int tlen,
RSAerr(RSA_F_RSA_PADDING_CHECK_SSLV23,RSA_R_NULL_BEFORE_BLOCK_MISSING);
return(-1);
}
- for (k= -8; k<0; k++)
+ for (k = -9; k<-1; k++)
{
if (p[k] != 0x03) break;
}
diff --git a/crypto/rsa/rsa_test.c b/crypto/rsa/rsa_test.c
index 6f0a28aa25..c8705a0f6e 100644
--- a/crypto/rsa/rsa_test.c
+++ b/crypto/rsa/rsa_test.c
@@ -219,6 +219,7 @@ int main(int argc, char *argv[])
int plen;
int clen = 0;
int num;
+ int n;
CRYPTO_malloc_debug_init();
CRYPTO_dbg_set_options(V_CRYPTO_MDEBUG_ALL);
@@ -228,10 +229,10 @@ int main(int argc, char *argv[])
plen = sizeof(ptext_ex) - 1;
- for (v = 0; v < 3; v++)
+ for (v = 0; v < 6; v++)
{
key = RSA_new();
- switch (v) {
+ switch (v%3) {
case 0:
clen = key1(key, ctext_ex);
break;
@@ -242,6 +243,7 @@ int main(int argc, char *argv[])
clen = key3(key, ctext_ex);
break;
}
+ if (v/3 >= 1) key->flags |= RSA_FLAG_NO_CONSTTIME;
num = RSA_public_encrypt(plen, ptext_ex, ctext, key,
RSA_PKCS1_PADDING);
@@ -277,7 +279,7 @@ int main(int argc, char *argv[])
err=1;
goto next;
}
-
+
num = RSA_private_decrypt(num, ctext, ptext, key,
RSA_PKCS1_OAEP_PADDING);
if (num != plen || memcmp(ptext, ptext_ex, num) != 0)
@@ -286,10 +288,7 @@ int main(int argc, char *argv[])
err=1;
}
else if (memcmp(ctext, ctext_ex, num) == 0)
- {
printf("OAEP test vector %d passed!\n", v);
- goto next;
- }
/* Different ciphertexts (rsa_oaep.c without -DPKCS_TESTVECT).
Try decrypting ctext_ex */
@@ -304,12 +303,32 @@ int main(int argc, char *argv[])
}
else
printf("OAEP encryption/decryption ok\n");
+
+ /* Try decrypting corrupted ciphertexts */
+ for(n = 0 ; n < clen ; ++n)
+ {
+ int b;
+ unsigned char saved = ctext[n];
+ for(b = 0 ; b < 256 ; ++b)
+ {
+ if(b == saved)
+ continue;
+ ctext[n] = b;
+ num = RSA_private_decrypt(num, ctext, ptext, key,
+ RSA_PKCS1_OAEP_PADDING);
+ if(num > 0)
+ {
+ printf("Corrupt data decrypted!\n");
+ err = 1;
+ }
+ }
+ }
next:
RSA_free(key);
}
CRYPTO_cleanup_all_ex_data();
- ERR_remove_state(0);
+ ERR_remove_thread_state(NULL);
CRYPTO_mem_leaks_fp(stderr);
diff --git a/crypto/rsa/rsa_x931.c b/crypto/rsa/rsa_x931.c
new file mode 100644
index 0000000000..21548e37ed
--- /dev/null
+++ b/crypto/rsa/rsa_x931.c
@@ -0,0 +1,177 @@
+/* rsa_x931.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 "cryptlib.h"
+#include <openssl/bn.h>
+#include <openssl/rsa.h>
+#include <openssl/rand.h>
+#include <openssl/objects.h>
+
+int RSA_padding_add_X931(unsigned char *to, int tlen,
+ const unsigned char *from, int flen)
+ {
+ int j;
+ unsigned char *p;
+
+ /* Absolute minimum amount of padding is 1 header nibble, 1 padding
+ * nibble and 2 trailer bytes: but 1 hash if is already in 'from'.
+ */
+
+ j = tlen - flen - 2;
+
+ if (j < 0)
+ {
+ RSAerr(RSA_F_RSA_PADDING_ADD_X931,RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE);
+ return -1;
+ }
+
+ p=(unsigned char *)to;
+
+ /* If no padding start and end nibbles are in one byte */
+ if (j == 0)
+ *p++ = 0x6A;
+ else
+ {
+ *p++ = 0x6B;
+ if (j > 1)
+ {
+ memset(p, 0xBB, j - 1);
+ p += j - 1;
+ }
+ *p++ = 0xBA;
+ }
+ memcpy(p,from,(unsigned int)flen);
+ p += flen;
+ *p = 0xCC;
+ return(1);
+ }
+
+int RSA_padding_check_X931(unsigned char *to, int tlen,
+ const unsigned char *from, int flen, int num)
+ {
+ int i = 0,j;
+ const unsigned char *p;
+
+ p=from;
+ if ((num != flen) || ((*p != 0x6A) && (*p != 0x6B)))
+ {
+ RSAerr(RSA_F_RSA_PADDING_CHECK_X931,RSA_R_INVALID_HEADER);
+ return -1;
+ }
+
+ if (*p++ == 0x6B)
+ {
+ j=flen-3;
+ for (i = 0; i < j; i++)
+ {
+ unsigned char c = *p++;
+ if (c == 0xBA)
+ break;
+ if (c != 0xBB)
+ {
+ RSAerr(RSA_F_RSA_PADDING_CHECK_X931,
+ RSA_R_INVALID_PADDING);
+ return -1;
+ }
+ }
+
+ j -= i;
+
+ if (i == 0)
+ {
+ RSAerr(RSA_F_RSA_PADDING_CHECK_X931, RSA_R_INVALID_PADDING);
+ return -1;
+ }
+
+ }
+ else j = flen - 2;
+
+ if (p[j] != 0xCC)
+ {
+ RSAerr(RSA_F_RSA_PADDING_CHECK_X931, RSA_R_INVALID_TRAILER);
+ return -1;
+ }
+
+ memcpy(to,p,(unsigned int)j);
+
+ return(j);
+ }
+
+/* Translate between X931 hash ids and NIDs */
+
+int RSA_X931_hash_id(int nid)
+ {
+ switch (nid)
+ {
+ case NID_sha1:
+ return 0x33;
+
+ case NID_sha256:
+ return 0x34;
+
+ case NID_sha384:
+ return 0x36;
+
+ case NID_sha512:
+ return 0x35;
+
+ }
+ return -1;
+ }
+