From a0fdc9ec41594852f67ec77dfad9cb06bacc4186 Mon Sep 17 00:00:00 2001 From: djm <> Date: Fri, 9 Jan 2009 12:14:11 +0000 Subject: import openssl-0.9.8j --- src/lib/libcrypto/aes/aes.h | 4 + src/lib/libcrypto/aes/aes_cbc.c | 2 + src/lib/libcrypto/aes/aes_core.c | 8 + src/lib/libcrypto/aes/asm/aes-586.pl | 3 +- src/lib/libcrypto/aes/asm/aes-x86_64.pl | 7 +- src/lib/libcrypto/asn1/a_mbstr.c | 2 +- src/lib/libcrypto/asn1/a_sign.c | 7 +- src/lib/libcrypto/asn1/a_strex.c | 2 +- src/lib/libcrypto/asn1/a_strnid.c | 2 +- src/lib/libcrypto/asn1/a_verify.c | 7 +- src/lib/libcrypto/asn1/asn1_gen.c | 2 +- src/lib/libcrypto/asn1/asn1t.h | 2 +- src/lib/libcrypto/asn1/asn_mime.c | 2 + src/lib/libcrypto/asn1/asn_moid.c | 2 +- src/lib/libcrypto/asn1/asn_pack.c | 2 +- src/lib/libcrypto/asn1/nsseq.c | 2 +- src/lib/libcrypto/asn1/p5_pbe.c | 2 +- src/lib/libcrypto/asn1/p5_pbev2.c | 2 +- src/lib/libcrypto/asn1/p8_pkey.c | 2 +- src/lib/libcrypto/asn1/t_bitst.c | 2 +- src/lib/libcrypto/asn1/t_crl.c | 2 +- src/lib/libcrypto/asn1/t_spki.c | 2 +- src/lib/libcrypto/asn1/t_x509.c | 11 +- src/lib/libcrypto/asn1/t_x509a.c | 2 +- src/lib/libcrypto/asn1/tasn_dec.c | 2 +- src/lib/libcrypto/asn1/tasn_enc.c | 2 +- src/lib/libcrypto/asn1/tasn_fre.c | 2 +- src/lib/libcrypto/asn1/tasn_new.c | 2 +- src/lib/libcrypto/asn1/tasn_prn.c | 2 +- src/lib/libcrypto/asn1/tasn_typ.c | 2 +- src/lib/libcrypto/asn1/tasn_utl.c | 2 +- src/lib/libcrypto/asn1/x_algor.c | 2 +- src/lib/libcrypto/asn1/x_bignum.c | 2 +- src/lib/libcrypto/asn1/x_exten.c | 2 +- src/lib/libcrypto/asn1/x_long.c | 2 +- src/lib/libcrypto/asn1/x_x509a.c | 2 +- src/lib/libcrypto/bf/bf_skey.c | 7 +- src/lib/libcrypto/bf/blowfish.h | 4 +- src/lib/libcrypto/bio/bss_bio.c | 2 +- src/lib/libcrypto/bio/bss_dgram.c | 64 ++- src/lib/libcrypto/bio/bss_file.c | 2 +- src/lib/libcrypto/bn/bn.h | 15 +- src/lib/libcrypto/bn/bn_div.c | 15 +- src/lib/libcrypto/bn/bn_gf2m.c | 6 +- src/lib/libcrypto/bn/bn_lib.c | 19 - src/lib/libcrypto/bn/bn_nist.c | 776 ++++++++++++++++++------------- src/lib/libcrypto/bn/bn_rand.c | 6 +- src/lib/libcrypto/bn/bn_shift.c | 2 +- src/lib/libcrypto/bn/bn_x931p.c | 40 +- src/lib/libcrypto/buffer/buf_str.c | 116 +++++ src/lib/libcrypto/buffer/buffer.c | 58 --- src/lib/libcrypto/camellia/camellia.h | 5 + src/lib/libcrypto/camellia/cmll_misc.c | 13 + src/lib/libcrypto/cast/c_skey.c | 7 +- src/lib/libcrypto/cast/cast.h | 4 +- src/lib/libcrypto/cms/cms_sd.c | 2 +- src/lib/libcrypto/cms/cms_smime.c | 9 +- src/lib/libcrypto/comp/c_zlib.c | 4 +- src/lib/libcrypto/conf/conf_mall.c | 4 +- src/lib/libcrypto/conf/conf_mod.c | 2 +- src/lib/libcrypto/conf/conf_sap.c | 2 +- src/lib/libcrypto/cryptlib.c | 351 +++----------- src/lib/libcrypto/cryptlib.h | 1 - src/lib/libcrypto/crypto.h | 85 +++- src/lib/libcrypto/des/des_enc.c | 4 + src/lib/libcrypto/des/ecb_enc.c | 47 -- src/lib/libcrypto/des/enc_read.c | 4 + src/lib/libcrypto/des/enc_writ.c | 4 + src/lib/libcrypto/des/set_key.c | 9 + src/lib/libcrypto/dh/dh.h | 11 + src/lib/libcrypto/dh/dh_asn1.c | 2 +- src/lib/libcrypto/dh/dh_check.c | 4 + src/lib/libcrypto/dh/dh_err.c | 6 +- src/lib/libcrypto/dh/dh_gen.c | 4 + src/lib/libcrypto/dh/dh_key.c | 4 + src/lib/libcrypto/dsa/dsa.h | 39 ++ src/lib/libcrypto/dsa/dsa_asn1.c | 82 +++- src/lib/libcrypto/dsa/dsa_err.c | 10 +- src/lib/libcrypto/dsa/dsa_gen.c | 3 + src/lib/libcrypto/dsa/dsa_key.c | 4 + src/lib/libcrypto/dsa/dsa_lib.c | 49 +- src/lib/libcrypto/dsa/dsa_ossl.c | 3 + src/lib/libcrypto/dsa/dsa_sign.c | 31 +- src/lib/libcrypto/dsa/dsa_vrf.c | 32 +- src/lib/libcrypto/ec/ec_key.c | 16 +- src/lib/libcrypto/engine/eng_all.c | 3 + src/lib/libcrypto/engine/eng_cnf.c | 11 +- src/lib/libcrypto/engine/eng_err.c | 3 +- src/lib/libcrypto/engine/eng_int.h | 2 + src/lib/libcrypto/engine/eng_padlock.c | 4 +- src/lib/libcrypto/engine/eng_pkey.c | 42 ++ src/lib/libcrypto/engine/engine.h | 16 + src/lib/libcrypto/err/err.c | 781 ++------------------------------ src/lib/libcrypto/err/err.h | 12 +- src/lib/libcrypto/err/err_all.c | 13 + src/lib/libcrypto/err/err_prn.c | 70 ++- src/lib/libcrypto/err/openssl.ec | 2 + src/lib/libcrypto/evp/bio_md.c | 9 +- src/lib/libcrypto/evp/digest.c | 154 ++++++- src/lib/libcrypto/evp/e_aes.c | 35 +- src/lib/libcrypto/evp/e_camellia.c | 2 +- src/lib/libcrypto/evp/e_des.c | 9 +- src/lib/libcrypto/evp/e_des3.c | 29 +- src/lib/libcrypto/evp/e_null.c | 2 +- src/lib/libcrypto/evp/e_rc4.c | 1 + src/lib/libcrypto/evp/evp.h | 80 ++++ src/lib/libcrypto/evp/evp_enc.c | 267 +++-------- src/lib/libcrypto/evp/evp_err.c | 16 +- src/lib/libcrypto/evp/evp_lib.c | 39 +- src/lib/libcrypto/evp/evp_locl.h | 30 +- src/lib/libcrypto/evp/evp_pbe.c | 2 +- src/lib/libcrypto/evp/evp_pkey.c | 2 +- src/lib/libcrypto/evp/m_dss.c | 2 +- src/lib/libcrypto/evp/m_dss1.c | 3 + src/lib/libcrypto/evp/m_md4.c | 1 + src/lib/libcrypto/evp/m_md5.c | 1 + src/lib/libcrypto/evp/m_sha1.c | 7 +- src/lib/libcrypto/evp/names.c | 7 + src/lib/libcrypto/evp/p5_crpt.c | 2 +- src/lib/libcrypto/evp/p5_crpt2.c | 2 +- src/lib/libcrypto/evp/p_sign.c | 24 +- src/lib/libcrypto/evp/p_verify.c | 26 +- src/lib/libcrypto/hmac/hmac.c | 10 + src/lib/libcrypto/hmac/hmac.h | 1 + src/lib/libcrypto/idea/idea.h | 3 + src/lib/libcrypto/md32_common.h | 2 +- src/lib/libcrypto/md4/md4.h | 3 + src/lib/libcrypto/md4/md4_dgst.c | 7 +- src/lib/libcrypto/md5/md5.h | 3 + src/lib/libcrypto/md5/md5_dgst.c | 7 +- src/lib/libcrypto/mem_dbg.c | 28 +- src/lib/libcrypto/o_init.c | 86 ++++ src/lib/libcrypto/objects/obj_dat.pl | 4 +- src/lib/libcrypto/objects/obj_mac.num | 68 +++ src/lib/libcrypto/objects/objects.txt | 108 ++++- src/lib/libcrypto/ocsp/ocsp_asn.c | 2 +- src/lib/libcrypto/ocsp/ocsp_ht.c | 5 +- src/lib/libcrypto/ocsp/ocsp_srv.c | 2 +- src/lib/libcrypto/ocsp/ocsp_vfy.c | 2 +- src/lib/libcrypto/opensslv.h | 6 +- src/lib/libcrypto/ossl_typ.h | 4 + src/lib/libcrypto/pem/pem.h | 1 + src/lib/libcrypto/pem/pem_all.c | 174 +++++++ src/lib/libcrypto/pem/pem_lib.c | 3 + src/lib/libcrypto/pem/pem_x509.c | 2 +- src/lib/libcrypto/pem/pem_xaux.c | 2 +- src/lib/libcrypto/pkcs12/p12_add.c | 2 +- src/lib/libcrypto/pkcs12/p12_asn.c | 2 +- src/lib/libcrypto/pkcs12/p12_attr.c | 2 +- src/lib/libcrypto/pkcs12/p12_crpt.c | 2 +- src/lib/libcrypto/pkcs12/p12_crt.c | 39 +- src/lib/libcrypto/pkcs12/p12_decr.c | 2 +- src/lib/libcrypto/pkcs12/p12_init.c | 2 +- src/lib/libcrypto/pkcs12/p12_key.c | 2 +- src/lib/libcrypto/pkcs12/p12_kiss.c | 2 +- src/lib/libcrypto/pkcs12/p12_mutl.c | 2 +- src/lib/libcrypto/pkcs12/p12_npas.c | 2 +- src/lib/libcrypto/pkcs12/p12_p8d.c | 2 +- src/lib/libcrypto/pkcs12/p12_p8e.c | 2 +- src/lib/libcrypto/pkcs12/p12_utl.c | 2 +- src/lib/libcrypto/pkcs12/pkcs12.h | 2 +- src/lib/libcrypto/pkcs7/pk7_asn1.c | 2 +- src/lib/libcrypto/pkcs7/pk7_attr.c | 2 +- src/lib/libcrypto/pkcs7/pk7_mime.c | 2 +- src/lib/libcrypto/pkcs7/pk7_smime.c | 3 +- src/lib/libcrypto/rand/rand.h | 29 +- src/lib/libcrypto/rand/rand_err.c | 20 +- src/lib/libcrypto/rand/rand_lib.c | 71 ++- src/lib/libcrypto/rand/randfile.c | 66 ++- src/lib/libcrypto/rc2/rc2.h | 4 +- src/lib/libcrypto/rc2/rc2_skey.c | 17 + src/lib/libcrypto/rc4/asm/rc4-x86_64.pl | 2 + src/lib/libcrypto/rc4/rc4.h | 3 + src/lib/libcrypto/rc4/rc4_skey.c | 16 +- src/lib/libcrypto/ripemd/ripemd.h | 4 +- src/lib/libcrypto/ripemd/rmd_dgst.c | 7 +- src/lib/libcrypto/ripemd/rmd_locl.h | 2 +- src/lib/libcrypto/rsa/rsa.h | 41 ++ src/lib/libcrypto/rsa/rsa_asn1.c | 2 +- src/lib/libcrypto/rsa/rsa_eay.c | 41 +- src/lib/libcrypto/rsa/rsa_err.c | 10 +- src/lib/libcrypto/rsa/rsa_gen.c | 3 + src/lib/libcrypto/rsa/rsa_lib.c | 272 +---------- src/lib/libcrypto/rsa/rsa_oaep.c | 2 +- src/lib/libcrypto/rsa/rsa_pss.c | 6 +- src/lib/libcrypto/rsa/rsa_sign.c | 24 +- src/lib/libcrypto/rsa/rsa_ssl.c | 2 +- src/lib/libcrypto/rsa/rsa_x931.c | 2 +- src/lib/libcrypto/sha/asm/sha1-586.pl | 2 +- src/lib/libcrypto/sha/sha.h | 3 + src/lib/libcrypto/sha/sha1_one.c | 2 +- src/lib/libcrypto/sha/sha1dgst.c | 4 + src/lib/libcrypto/sha/sha256.c | 10 + src/lib/libcrypto/sha/sha512.c | 12 +- src/lib/libcrypto/sha/sha_locl.h | 7 + src/lib/libcrypto/stack/safestack.h | 44 ++ src/lib/libcrypto/ui/ui_openssl.c | 2 + src/lib/libcrypto/util/mkerr.pl | 3 +- src/lib/libcrypto/x509/by_dir.c | 4 + src/lib/libcrypto/x509/x509_att.c | 12 +- src/lib/libcrypto/x509/x509_cmp.c | 8 +- src/lib/libcrypto/x509/x509_trs.c | 2 +- src/lib/libcrypto/x509/x509_vfy.c | 12 +- src/lib/libcrypto/x509/x509_vpm.c | 2 +- src/lib/libcrypto/x509/x509cset.c | 2 +- src/lib/libcrypto/x509/x509spki.c | 2 +- src/lib/libcrypto/x509v3/ext_dat.h | 2 +- src/lib/libcrypto/x509v3/pcy_cache.c | 2 +- src/lib/libcrypto/x509v3/pcy_data.c | 10 +- src/lib/libcrypto/x509v3/pcy_int.h | 2 +- src/lib/libcrypto/x509v3/pcy_lib.c | 2 +- src/lib/libcrypto/x509v3/pcy_map.c | 2 +- src/lib/libcrypto/x509v3/pcy_node.c | 2 +- src/lib/libcrypto/x509v3/pcy_tree.c | 20 +- src/lib/libcrypto/x509v3/v3_akey.c | 2 +- src/lib/libcrypto/x509v3/v3_akeya.c | 2 +- src/lib/libcrypto/x509v3/v3_alt.c | 5 +- src/lib/libcrypto/x509v3/v3_bcons.c | 2 +- src/lib/libcrypto/x509v3/v3_bitst.c | 2 +- src/lib/libcrypto/x509v3/v3_conf.c | 2 +- src/lib/libcrypto/x509v3/v3_cpols.c | 2 +- src/lib/libcrypto/x509v3/v3_crld.c | 2 +- src/lib/libcrypto/x509v3/v3_enum.c | 2 +- src/lib/libcrypto/x509v3/v3_extku.c | 2 +- src/lib/libcrypto/x509v3/v3_genn.c | 2 +- src/lib/libcrypto/x509v3/v3_ia5.c | 2 +- src/lib/libcrypto/x509v3/v3_info.c | 2 +- src/lib/libcrypto/x509v3/v3_int.c | 2 +- src/lib/libcrypto/x509v3/v3_lib.c | 2 +- src/lib/libcrypto/x509v3/v3_ncons.c | 2 +- src/lib/libcrypto/x509v3/v3_ocsp.c | 2 +- src/lib/libcrypto/x509v3/v3_pcons.c | 2 +- src/lib/libcrypto/x509v3/v3_pku.c | 2 +- src/lib/libcrypto/x509v3/v3_pmaps.c | 2 +- src/lib/libcrypto/x509v3/v3_prn.c | 2 +- src/lib/libcrypto/x509v3/v3_purp.c | 8 +- src/lib/libcrypto/x509v3/v3_skey.c | 2 +- src/lib/libcrypto/x509v3/v3_sxnet.c | 2 +- src/lib/libcrypto/x509v3/v3_utl.c | 23 +- src/lib/libcrypto/x509v3/x509v3.h | 6 +- src/lib/libssl/d1_clnt.c | 3 +- src/lib/libssl/d1_enc.c | 19 +- src/lib/libssl/d1_lib.c | 1 + src/lib/libssl/d1_pkt.c | 22 +- src/lib/libssl/d1_srvr.c | 6 +- src/lib/libssl/dtls1.h | 7 + src/lib/libssl/s23_clnt.c | 16 + src/lib/libssl/s23_srvr.c | 9 + src/lib/libssl/s3_clnt.c | 52 ++- src/lib/libssl/s3_lib.c | 40 +- src/lib/libssl/s3_pkt.c | 16 +- src/lib/libssl/s3_srvr.c | 42 +- src/lib/libssl/ssl.h | 16 +- src/lib/libssl/ssl_asn1.c | 2 +- src/lib/libssl/ssl_ciph.c | 13 + src/lib/libssl/ssl_err.c | 5 +- src/lib/libssl/ssl_lib.c | 36 ++ src/lib/libssl/ssl_locl.h | 8 +- src/lib/libssl/ssl_sess.c | 22 + src/lib/libssl/t1_enc.c | 42 +- src/lib/libssl/t1_lib.c | 14 +- src/lib/libssl/test/CAss.cnf | 2 +- src/lib/libssl/test/Uss.cnf | 2 +- 263 files changed, 3222 insertions(+), 2494 deletions(-) create mode 100644 src/lib/libcrypto/buffer/buf_str.c create mode 100644 src/lib/libcrypto/o_init.c diff --git a/src/lib/libcrypto/aes/aes.h b/src/lib/libcrypto/aes/aes.h index baf0222d49..450f2b4051 100644 --- a/src/lib/libcrypto/aes/aes.h +++ b/src/lib/libcrypto/aes/aes.h @@ -66,6 +66,10 @@ #define AES_MAXNR 14 #define AES_BLOCK_SIZE 16 +#ifdef OPENSSL_FIPS +#define FIPS_AES_SIZE_T int +#endif + #ifdef __cplusplus extern "C" { #endif diff --git a/src/lib/libcrypto/aes/aes_cbc.c b/src/lib/libcrypto/aes/aes_cbc.c index d2ba6bcdb4..373864cd4b 100644 --- a/src/lib/libcrypto/aes/aes_cbc.c +++ b/src/lib/libcrypto/aes/aes_cbc.c @@ -59,6 +59,7 @@ #include #include "aes_locl.h" +#if !defined(OPENSSL_FIPS_AES_ASM) void AES_cbc_encrypt(const unsigned char *in, unsigned char *out, const unsigned long length, const AES_KEY *key, unsigned char *ivec, const int enc) { @@ -129,3 +130,4 @@ void AES_cbc_encrypt(const unsigned char *in, unsigned char *out, } } } +#endif diff --git a/src/lib/libcrypto/aes/aes_core.c b/src/lib/libcrypto/aes/aes_core.c index 3a80e18b0a..cffdd4daec 100644 --- a/src/lib/libcrypto/aes/aes_core.c +++ b/src/lib/libcrypto/aes/aes_core.c @@ -37,6 +37,10 @@ #include #include +#ifdef OPENSSL_FIPS +#include +#endif + #include "aes_locl.h" /* @@ -631,6 +635,10 @@ int AES_set_encrypt_key(const unsigned char *userKey, const int bits, int i = 0; u32 temp; +#ifdef OPENSSL_FIPS + FIPS_selftest_check(); +#endif + if (!userKey || !key) return -1; if (bits != 128 && bits != 192 && bits != 256) diff --git a/src/lib/libcrypto/aes/asm/aes-586.pl b/src/lib/libcrypto/aes/asm/aes-586.pl index 89fa261794..3bc46a968e 100644 --- a/src/lib/libcrypto/aes/asm/aes-586.pl +++ b/src/lib/libcrypto/aes/asm/aes-586.pl @@ -955,8 +955,9 @@ my $mark=&DWP(60+240,"esp"); #copy of aes_key->rounds &align (4); &set_label("enc_tail"); - &push ($key eq "edi" ? $key : ""); # push ivp + &mov ($s0,$key eq "edi" ? $key : ""); &mov ($key,$_out); # load out + &push ($s0); # push ivp &mov ($s1,16); &sub ($s1,$s2); &cmp ($key,$acc); # compare with inp diff --git a/src/lib/libcrypto/aes/asm/aes-x86_64.pl b/src/lib/libcrypto/aes/asm/aes-x86_64.pl index 44e0bf8cae..f616f1751f 100755 --- a/src/lib/libcrypto/aes/asm/aes-x86_64.pl +++ b/src/lib/libcrypto/aes/asm/aes-x86_64.pl @@ -1198,19 +1198,20 @@ AES_cbc_encrypt: ret .align 4 .Lcbc_enc_tail: - cmp $inp,$out - je .Lcbc_enc_in_place + mov %rax,%r11 + mov %rcx,%r12 mov %r10,%rcx mov $inp,%rsi mov $out,%rdi .long 0xF689A4F3 # rep movsb -.Lcbc_enc_in_place: mov \$16,%rcx # zero tail sub %r10,%rcx xor %rax,%rax .long 0xF689AAF3 # rep stosb mov $out,$inp # this is not a mistake! movq \$16,$_len # len=16 + mov %r11,%rax + mov %r12,%rcx jmp .Lcbc_enc_loop # one more spin... #----------------------------- DECRYPT -----------------------------# .align 16 diff --git a/src/lib/libcrypto/asn1/a_mbstr.c b/src/lib/libcrypto/asn1/a_mbstr.c index 2d4800a22a..1bcd046893 100644 --- a/src/lib/libcrypto/asn1/a_mbstr.c +++ b/src/lib/libcrypto/asn1/a_mbstr.c @@ -1,5 +1,5 @@ /* a_mbstr.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. */ /* ==================================================================== diff --git a/src/lib/libcrypto/asn1/a_sign.c b/src/lib/libcrypto/asn1/a_sign.c index 1081950518..4dee45fbb8 100644 --- a/src/lib/libcrypto/asn1/a_sign.c +++ b/src/lib/libcrypto/asn1/a_sign.c @@ -267,7 +267,12 @@ int ASN1_item_sign(const ASN1_ITEM *it, X509_ALGOR *algor1, X509_ALGOR *algor2, goto err; } - EVP_SignInit_ex(&ctx,type, NULL); + if (!EVP_SignInit_ex(&ctx,type, NULL)) + { + outl=0; + ASN1err(ASN1_F_ASN1_ITEM_SIGN,ERR_R_EVP_LIB); + goto err; + } EVP_SignUpdate(&ctx,(unsigned char *)buf_in,inl); if (!EVP_SignFinal(&ctx,(unsigned char *)buf_out, (unsigned int *)&outl,pkey)) diff --git a/src/lib/libcrypto/asn1/a_strex.c b/src/lib/libcrypto/asn1/a_strex.c index c2dbb6f9a5..7fc14d3296 100644 --- a/src/lib/libcrypto/asn1/a_strex.c +++ b/src/lib/libcrypto/asn1/a_strex.c @@ -1,5 +1,5 @@ /* a_strex.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. */ /* ==================================================================== diff --git a/src/lib/libcrypto/asn1/a_strnid.c b/src/lib/libcrypto/asn1/a_strnid.c index 613bbc4a7d..fe515b52ba 100644 --- a/src/lib/libcrypto/asn1/a_strnid.c +++ b/src/lib/libcrypto/asn1/a_strnid.c @@ -1,5 +1,5 @@ /* a_strnid.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. */ /* ==================================================================== diff --git a/src/lib/libcrypto/asn1/a_verify.c b/src/lib/libcrypto/asn1/a_verify.c index fdce6e4380..da3efaaf8d 100644 --- a/src/lib/libcrypto/asn1/a_verify.c +++ b/src/lib/libcrypto/asn1/a_verify.c @@ -100,7 +100,12 @@ int ASN1_verify(i2d_of_void *i2d, X509_ALGOR *a, ASN1_BIT_STRING *signature, p=buf_in; i2d(data,&p); - EVP_VerifyInit_ex(&ctx,type, NULL); + if (!EVP_VerifyInit_ex(&ctx,type, NULL)) + { + ASN1err(ASN1_F_ASN1_VERIFY,ERR_R_EVP_LIB); + ret=0; + goto err; + } EVP_VerifyUpdate(&ctx,(unsigned char *)buf_in,inl); OPENSSL_cleanse(buf_in,(unsigned int)inl); diff --git a/src/lib/libcrypto/asn1/asn1_gen.c b/src/lib/libcrypto/asn1/asn1_gen.c index 26c832781e..2da38292c8 100644 --- a/src/lib/libcrypto/asn1/asn1_gen.c +++ b/src/lib/libcrypto/asn1/asn1_gen.c @@ -1,5 +1,5 @@ /* asn1_gen.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 2002. */ /* ==================================================================== diff --git a/src/lib/libcrypto/asn1/asn1t.h b/src/lib/libcrypto/asn1/asn1t.h index bf315e65ed..ac14f9415b 100644 --- a/src/lib/libcrypto/asn1/asn1t.h +++ b/src/lib/libcrypto/asn1/asn1t.h @@ -1,5 +1,5 @@ /* asn1t.h */ -/* 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. */ /* ==================================================================== diff --git a/src/lib/libcrypto/asn1/asn_mime.c b/src/lib/libcrypto/asn1/asn_mime.c index fe7c4ec7ab..bc80b20d63 100644 --- a/src/lib/libcrypto/asn1/asn_mime.c +++ b/src/lib/libcrypto/asn1/asn_mime.c @@ -526,6 +526,8 @@ int SMIME_text(BIO *in, BIO *out) sk_MIME_HEADER_pop_free(headers, mime_hdr_free); while ((len = BIO_read(in, iobuf, sizeof(iobuf))) > 0) BIO_write(out, iobuf, len); + if (len < 0) + return 0; return 1; } diff --git a/src/lib/libcrypto/asn1/asn_moid.c b/src/lib/libcrypto/asn1/asn_moid.c index 9132350f10..1ea6a59248 100644 --- a/src/lib/libcrypto/asn1/asn_moid.c +++ b/src/lib/libcrypto/asn1/asn_moid.c @@ -1,5 +1,5 @@ /* asn_moid.c */ -/* Written by Stephen Henson (shenson@bigfoot.com) for the OpenSSL +/* Written by Stephen Henson (steve@openssl.org) for the OpenSSL * project 2001. */ /* ==================================================================== diff --git a/src/lib/libcrypto/asn1/asn_pack.c b/src/lib/libcrypto/asn1/asn_pack.c index e8b671b7b5..f1a5a05632 100644 --- a/src/lib/libcrypto/asn1/asn_pack.c +++ b/src/lib/libcrypto/asn1/asn_pack.c @@ -1,5 +1,5 @@ /* asn_pack.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. */ /* ==================================================================== diff --git a/src/lib/libcrypto/asn1/nsseq.c b/src/lib/libcrypto/asn1/nsseq.c index 50e2d4d07a..e551c57d59 100644 --- a/src/lib/libcrypto/asn1/nsseq.c +++ b/src/lib/libcrypto/asn1/nsseq.c @@ -1,5 +1,5 @@ /* nsseq.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. */ /* ==================================================================== diff --git a/src/lib/libcrypto/asn1/p5_pbe.c b/src/lib/libcrypto/asn1/p5_pbe.c index da91170094..c4582f8041 100644 --- a/src/lib/libcrypto/asn1/p5_pbe.c +++ b/src/lib/libcrypto/asn1/p5_pbe.c @@ -1,5 +1,5 @@ /* p5_pbe.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. */ /* ==================================================================== diff --git a/src/lib/libcrypto/asn1/p5_pbev2.c b/src/lib/libcrypto/asn1/p5_pbev2.c index c834a38ddf..2b0516afee 100644 --- a/src/lib/libcrypto/asn1/p5_pbev2.c +++ b/src/lib/libcrypto/asn1/p5_pbev2.c @@ -1,5 +1,5 @@ /* p5_pbev2.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-2004. */ /* ==================================================================== diff --git a/src/lib/libcrypto/asn1/p8_pkey.c b/src/lib/libcrypto/asn1/p8_pkey.c index 24b409132f..0a1957556e 100644 --- a/src/lib/libcrypto/asn1/p8_pkey.c +++ b/src/lib/libcrypto/asn1/p8_pkey.c @@ -1,5 +1,5 @@ /* p8_pkey.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. */ /* ==================================================================== diff --git a/src/lib/libcrypto/asn1/t_bitst.c b/src/lib/libcrypto/asn1/t_bitst.c index 397332d9b8..2e59a25fa1 100644 --- a/src/lib/libcrypto/asn1/t_bitst.c +++ b/src/lib/libcrypto/asn1/t_bitst.c @@ -1,5 +1,5 @@ /* t_bitst.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. */ /* ==================================================================== diff --git a/src/lib/libcrypto/asn1/t_crl.c b/src/lib/libcrypto/asn1/t_crl.c index 929b3e5904..bdb244c015 100644 --- a/src/lib/libcrypto/asn1/t_crl.c +++ b/src/lib/libcrypto/asn1/t_crl.c @@ -1,5 +1,5 @@ /* t_crl.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. */ /* ==================================================================== diff --git a/src/lib/libcrypto/asn1/t_spki.c b/src/lib/libcrypto/asn1/t_spki.c index c2a5797dd8..a73369b949 100644 --- a/src/lib/libcrypto/asn1/t_spki.c +++ b/src/lib/libcrypto/asn1/t_spki.c @@ -1,5 +1,5 @@ /* t_spki.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. */ /* ==================================================================== diff --git a/src/lib/libcrypto/asn1/t_x509.c b/src/lib/libcrypto/asn1/t_x509.c index eb776b7b3b..8b09e5890f 100644 --- a/src/lib/libcrypto/asn1/t_x509.c +++ b/src/lib/libcrypto/asn1/t_x509.c @@ -393,8 +393,9 @@ int ASN1_GENERALIZEDTIME_print(BIO *bp, ASN1_GENERALIZEDTIME *tm) d= (v[6]-'0')*10+(v[7]-'0'); h= (v[8]-'0')*10+(v[9]-'0'); m= (v[10]-'0')*10+(v[11]-'0'); - if ( (v[12] >= '0') && (v[12] <= '9') && - (v[13] >= '0') && (v[13] <= '9')) + if (tm->length >= 14 && + (v[12] >= '0') && (v[12] <= '9') && + (v[13] >= '0') && (v[13] <= '9')) s= (v[12]-'0')*10+(v[13]-'0'); if (BIO_printf(bp,"%s %2d %02d:%02d:%02d %d%s", @@ -428,8 +429,9 @@ int ASN1_UTCTIME_print(BIO *bp, ASN1_UTCTIME *tm) d= (v[4]-'0')*10+(v[5]-'0'); h= (v[6]-'0')*10+(v[7]-'0'); m= (v[8]-'0')*10+(v[9]-'0'); - if ( (v[10] >= '0') && (v[10] <= '9') && - (v[11] >= '0') && (v[11] <= '9')) + if (tm->length >=12 && + (v[10] >= '0') && (v[10] <= '9') && + (v[11] >= '0') && (v[11] <= '9')) s= (v[10]-'0')*10+(v[11]-'0'); if (BIO_printf(bp,"%s %2d %02d:%02d:%02d %d%s", @@ -501,4 +503,3 @@ err: OPENSSL_free(b); return(ret); } - diff --git a/src/lib/libcrypto/asn1/t_x509a.c b/src/lib/libcrypto/asn1/t_x509a.c index ffbbfb51f4..8b18801a17 100644 --- a/src/lib/libcrypto/asn1/t_x509a.c +++ b/src/lib/libcrypto/asn1/t_x509a.c @@ -1,5 +1,5 @@ /* t_x509a.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. */ /* ==================================================================== diff --git a/src/lib/libcrypto/asn1/tasn_dec.c b/src/lib/libcrypto/asn1/tasn_dec.c index 0ee406231e..ced641698e 100644 --- a/src/lib/libcrypto/asn1/tasn_dec.c +++ b/src/lib/libcrypto/asn1/tasn_dec.c @@ -1,5 +1,5 @@ /* tasn_dec.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. */ /* ==================================================================== diff --git a/src/lib/libcrypto/asn1/tasn_enc.c b/src/lib/libcrypto/asn1/tasn_enc.c index be19b36acd..2721f904a6 100644 --- a/src/lib/libcrypto/asn1/tasn_enc.c +++ b/src/lib/libcrypto/asn1/tasn_enc.c @@ -1,5 +1,5 @@ /* tasn_enc.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. */ /* ==================================================================== diff --git a/src/lib/libcrypto/asn1/tasn_fre.c b/src/lib/libcrypto/asn1/tasn_fre.c index bb7c1e2af4..d7c017fa1d 100644 --- a/src/lib/libcrypto/asn1/tasn_fre.c +++ b/src/lib/libcrypto/asn1/tasn_fre.c @@ -1,5 +1,5 @@ /* tasn_fre.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. */ /* ==================================================================== diff --git a/src/lib/libcrypto/asn1/tasn_new.c b/src/lib/libcrypto/asn1/tasn_new.c index 531dad365c..5c6a2ebd4d 100644 --- a/src/lib/libcrypto/asn1/tasn_new.c +++ b/src/lib/libcrypto/asn1/tasn_new.c @@ -1,5 +1,5 @@ /* tasn_new.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. */ /* ==================================================================== diff --git a/src/lib/libcrypto/asn1/tasn_prn.c b/src/lib/libcrypto/asn1/tasn_prn.c index 719639b511..b9c96a6dbe 100644 --- a/src/lib/libcrypto/asn1/tasn_prn.c +++ b/src/lib/libcrypto/asn1/tasn_prn.c @@ -1,5 +1,5 @@ /* tasn_prn.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. */ /* ==================================================================== diff --git a/src/lib/libcrypto/asn1/tasn_typ.c b/src/lib/libcrypto/asn1/tasn_typ.c index 6f17f1bec7..6252213d15 100644 --- a/src/lib/libcrypto/asn1/tasn_typ.c +++ b/src/lib/libcrypto/asn1/tasn_typ.c @@ -1,5 +1,5 @@ /* tasn_typ.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. */ /* ==================================================================== diff --git a/src/lib/libcrypto/asn1/tasn_utl.c b/src/lib/libcrypto/asn1/tasn_utl.c index 34d520b180..ca9ec7a32f 100644 --- a/src/lib/libcrypto/asn1/tasn_utl.c +++ b/src/lib/libcrypto/asn1/tasn_utl.c @@ -1,5 +1,5 @@ /* tasn_utl.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. */ /* ==================================================================== diff --git a/src/lib/libcrypto/asn1/x_algor.c b/src/lib/libcrypto/asn1/x_algor.c index 33533aba86..99e53429b7 100644 --- a/src/lib/libcrypto/asn1/x_algor.c +++ b/src/lib/libcrypto/asn1/x_algor.c @@ -1,5 +1,5 @@ /* x_algor.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. */ /* ==================================================================== diff --git a/src/lib/libcrypto/asn1/x_bignum.c b/src/lib/libcrypto/asn1/x_bignum.c index 869c05d931..9cf3204a1b 100644 --- a/src/lib/libcrypto/asn1/x_bignum.c +++ b/src/lib/libcrypto/asn1/x_bignum.c @@ -1,5 +1,5 @@ /* x_bignum.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. */ /* ==================================================================== diff --git a/src/lib/libcrypto/asn1/x_exten.c b/src/lib/libcrypto/asn1/x_exten.c index 1732e66712..3a21239926 100644 --- a/src/lib/libcrypto/asn1/x_exten.c +++ b/src/lib/libcrypto/asn1/x_exten.c @@ -1,5 +1,5 @@ /* x_exten.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. */ /* ==================================================================== diff --git a/src/lib/libcrypto/asn1/x_long.c b/src/lib/libcrypto/asn1/x_long.c index 0db233cb95..bf35457c1f 100644 --- a/src/lib/libcrypto/asn1/x_long.c +++ b/src/lib/libcrypto/asn1/x_long.c @@ -1,5 +1,5 @@ /* x_long.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. */ /* ==================================================================== diff --git a/src/lib/libcrypto/asn1/x_x509a.c b/src/lib/libcrypto/asn1/x_x509a.c index 13db5fd03f..b603f82de7 100644 --- a/src/lib/libcrypto/asn1/x_x509a.c +++ b/src/lib/libcrypto/asn1/x_x509a.c @@ -1,5 +1,5 @@ /* a_x509a.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. */ /* ==================================================================== diff --git a/src/lib/libcrypto/bf/bf_skey.c b/src/lib/libcrypto/bf/bf_skey.c index 3673cdee6e..6ac2aeb279 100644 --- a/src/lib/libcrypto/bf/bf_skey.c +++ b/src/lib/libcrypto/bf/bf_skey.c @@ -59,10 +59,15 @@ #include #include #include +#include +#ifdef OPENSSL_FIPS +#include +#endif + #include "bf_locl.h" #include "bf_pi.h" -void BF_set_key(BF_KEY *key, int len, const unsigned char *data) +FIPS_NON_FIPS_VCIPHER_Init(BF) { int i; BF_LONG *p,ri,in[2]; diff --git a/src/lib/libcrypto/bf/blowfish.h b/src/lib/libcrypto/bf/blowfish.h index cd49e85ab2..d24ffccb65 100644 --- a/src/lib/libcrypto/bf/blowfish.h +++ b/src/lib/libcrypto/bf/blowfish.h @@ -104,7 +104,9 @@ typedef struct bf_key_st BF_LONG S[4*256]; } BF_KEY; - +#ifdef OPENSSL_FIPS +void private_BF_set_key(BF_KEY *key, int len, const unsigned char *data); +#endif void BF_set_key(BF_KEY *key, int len, const unsigned char *data); void BF_encrypt(BF_LONG *data,const BF_KEY *key); diff --git a/src/lib/libcrypto/bio/bss_bio.c b/src/lib/libcrypto/bio/bss_bio.c index 0f9f0955b4..76bd48e767 100644 --- a/src/lib/libcrypto/bio/bss_bio.c +++ b/src/lib/libcrypto/bio/bss_bio.c @@ -919,6 +919,6 @@ int BIO_nwrite(BIO *bio, char **buf, int num) ret = BIO_ctrl(bio, BIO_C_NWRITE, num, buf); if (ret > 0) - bio->num_read += ret; + bio->num_write += ret; return ret; } diff --git a/src/lib/libcrypto/bio/bss_dgram.c b/src/lib/libcrypto/bio/bss_dgram.c index ea2c3fff63..c3da6dc82f 100644 --- a/src/lib/libcrypto/bio/bss_dgram.c +++ b/src/lib/libcrypto/bio/bss_dgram.c @@ -82,7 +82,7 @@ static int dgram_new(BIO *h); static int dgram_free(BIO *data); static int dgram_clear(BIO *bio); -int BIO_dgram_should_retry(int s); +static int BIO_dgram_should_retry(int s); static BIO_METHOD methods_dgramp= { @@ -345,30 +345,90 @@ static long dgram_ctrl(BIO *b, int cmd, long num, void *ptr) memcpy(&(data->peer), to, sizeof(struct sockaddr)); break; +#if defined(SO_RCVTIMEO) case BIO_CTRL_DGRAM_SET_RECV_TIMEOUT: +#ifdef OPENSSL_SYS_WINDOWS + { + struct timeval *tv = (struct timeval *)ptr; + int timeout = tv->tv_sec * 1000 + tv->tv_usec/1000; + if (setsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO, + (void*)&timeout, sizeof(timeout)) < 0) + { perror("setsockopt"); ret = -1; } + } +#else if ( setsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO, ptr, sizeof(struct timeval)) < 0) { perror("setsockopt"); ret = -1; } +#endif break; case BIO_CTRL_DGRAM_GET_RECV_TIMEOUT: +#ifdef OPENSSL_SYS_WINDOWS + { + int timeout, sz = sizeof(timeout); + struct timeval *tv = (struct timeval *)ptr; + if (getsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO, + (void*)&timeout, &sz) < 0) + { perror("getsockopt"); ret = -1; } + else + { + tv->tv_sec = timeout / 1000; + tv->tv_usec = (timeout % 1000) * 1000; + ret = sizeof(*tv); + } + } +#else if ( getsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO, ptr, (void *)&ret) < 0) { perror("getsockopt"); ret = -1; } +#endif break; +#endif +#if defined(SO_SNDTIMEO) case BIO_CTRL_DGRAM_SET_SEND_TIMEOUT: +#ifdef OPENSSL_SYS_WINDOWS + { + struct timeval *tv = (struct timeval *)ptr; + int timeout = tv->tv_sec * 1000 + tv->tv_usec/1000; + if (setsockopt(b->num, SOL_SOCKET, SO_SNDTIMEO, + (void*)&timeout, sizeof(timeout)) < 0) + { perror("setsockopt"); ret = -1; } + } +#else if ( setsockopt(b->num, SOL_SOCKET, SO_SNDTIMEO, ptr, sizeof(struct timeval)) < 0) { perror("setsockopt"); ret = -1; } +#endif break; case BIO_CTRL_DGRAM_GET_SEND_TIMEOUT: +#ifdef OPENSSL_SYS_WINDOWS + { + int timeout, sz = sizeof(timeout); + struct timeval *tv = (struct timeval *)ptr; + if (getsockopt(b->num, SOL_SOCKET, SO_SNDTIMEO, + (void*)&timeout, &sz) < 0) + { perror("getsockopt"); ret = -1; } + else + { + tv->tv_sec = timeout / 1000; + tv->tv_usec = (timeout % 1000) * 1000; + ret = sizeof(*tv); + } + } +#else if ( getsockopt(b->num, SOL_SOCKET, SO_SNDTIMEO, ptr, (void *)&ret) < 0) { perror("getsockopt"); ret = -1; } +#endif break; +#endif case BIO_CTRL_DGRAM_GET_SEND_TIMER_EXP: /* fall-through */ case BIO_CTRL_DGRAM_GET_RECV_TIMER_EXP: +#ifdef OPENSSL_SYS_WINDOWS + if ( data->_errno == WSAETIMEDOUT) +#else if ( data->_errno == EAGAIN) +#endif { ret = 1; data->_errno = 0; @@ -403,7 +463,7 @@ static int dgram_puts(BIO *bp, const char *str) return(ret); } -int BIO_dgram_should_retry(int i) +static int BIO_dgram_should_retry(int i) { int err; diff --git a/src/lib/libcrypto/bio/bss_file.c b/src/lib/libcrypto/bio/bss_file.c index 4df9927c43..9ad46fa081 100644 --- a/src/lib/libcrypto/bio/bss_file.c +++ b/src/lib/libcrypto/bio/bss_file.c @@ -279,7 +279,7 @@ static long MS_CALLBACK file_ctrl(BIO *b, int cmd, long num, void *ptr) #endif { #if defined(OPENSSL_SYS_WINDOWS) - int fd = fileno((FILE*)ptr); + int fd = _fileno((FILE*)ptr); if (num & BIO_FP_TEXT) _setmode(fd,_O_TEXT); else diff --git a/src/lib/libcrypto/bn/bn.h b/src/lib/libcrypto/bn/bn.h index 6d754d5547..f1719a5877 100644 --- a/src/lib/libcrypto/bn/bn.h +++ b/src/lib/libcrypto/bn/bn.h @@ -408,8 +408,8 @@ BIGNUM *BN_CTX_get(BN_CTX *ctx); void BN_CTX_end(BN_CTX *ctx); int BN_rand(BIGNUM *rnd, int bits, int top,int bottom); int BN_pseudo_rand(BIGNUM *rnd, int bits, int top,int bottom); -int BN_rand_range(BIGNUM *rnd, BIGNUM *range); -int BN_pseudo_rand_range(BIGNUM *rnd, BIGNUM *range); +int BN_rand_range(BIGNUM *rnd, const BIGNUM *range); +int BN_pseudo_rand_range(BIGNUM *rnd, const BIGNUM *range); int BN_num_bits(const BIGNUM *a); int BN_num_bits_word(BN_ULONG); BIGNUM *BN_new(void); @@ -531,6 +531,17 @@ int BN_is_prime_ex(const BIGNUM *p,int nchecks, BN_CTX *ctx, BN_GENCB *cb); int BN_is_prime_fasttest_ex(const BIGNUM *p,int nchecks, BN_CTX *ctx, int do_trial_division, BN_GENCB *cb); +int BN_X931_generate_Xpq(BIGNUM *Xp, BIGNUM *Xq, int nbits, BN_CTX *ctx); + +int BN_X931_derive_prime_ex(BIGNUM *p, BIGNUM *p1, BIGNUM *p2, + const BIGNUM *Xp, const BIGNUM *Xp1, const BIGNUM *Xp2, + const BIGNUM *e, BN_CTX *ctx, BN_GENCB *cb); +int BN_X931_generate_prime_ex(BIGNUM *p, BIGNUM *p1, BIGNUM *p2, + BIGNUM *Xp1, BIGNUM *Xp2, + const BIGNUM *Xp, + const BIGNUM *e, BN_CTX *ctx, + BN_GENCB *cb); + BN_MONT_CTX *BN_MONT_CTX_new(void ); void BN_MONT_CTX_init(BN_MONT_CTX *ctx); int BN_mod_mul_montgomery(BIGNUM *r,const BIGNUM *a,const BIGNUM *b, diff --git a/src/lib/libcrypto/bn/bn_div.c b/src/lib/libcrypto/bn/bn_div.c index 8655eb118e..1e8e57626b 100644 --- a/src/lib/libcrypto/bn/bn_div.c +++ b/src/lib/libcrypto/bn/bn_div.c @@ -187,6 +187,17 @@ int BN_div(BIGNUM *dv, BIGNUM *rm, const BIGNUM *num, const BIGNUM *divisor, BN_ULONG d0,d1; int num_n,div_n; + /* Invalid zero-padding would have particularly bad consequences + * in the case of 'num', so don't just rely on bn_check_top() for this one + * (bn_check_top() works only for BN_DEBUG builds) */ + if (num->top > 0 && num->d[num->top - 1] == 0) + { + BNerr(BN_F_BN_DIV,BN_R_NOT_INITIALIZED); + return 0; + } + + bn_check_top(num); + if ((BN_get_flags(num, BN_FLG_CONSTTIME) != 0) || (BN_get_flags(divisor, BN_FLG_CONSTTIME) != 0)) { return BN_div_no_branch(dv, rm, num, divisor, ctx); @@ -194,7 +205,7 @@ int BN_div(BIGNUM *dv, BIGNUM *rm, const BIGNUM *num, const BIGNUM *divisor, bn_check_top(dv); bn_check_top(rm); - bn_check_top(num); + /* bn_check_top(num); */ /* 'num' has been checked already */ bn_check_top(divisor); if (BN_is_zero(divisor)) @@ -419,7 +430,7 @@ static int BN_div_no_branch(BIGNUM *dv, BIGNUM *rm, const BIGNUM *num, bn_check_top(dv); bn_check_top(rm); - bn_check_top(num); + /* bn_check_top(num); */ /* 'num' has been checked in BN_div() */ bn_check_top(divisor); if (BN_is_zero(divisor)) diff --git a/src/lib/libcrypto/bn/bn_gf2m.c b/src/lib/libcrypto/bn/bn_gf2m.c index 6a793857e1..306f029f27 100644 --- a/src/lib/libcrypto/bn/bn_gf2m.c +++ b/src/lib/libcrypto/bn/bn_gf2m.c @@ -384,7 +384,11 @@ int BN_GF2m_mod_arr(BIGNUM *r, const BIGNUM *a, const unsigned int p[]) if (zz == 0) break; d1 = BN_BITS2 - d0; - if (d0) z[dN] = (z[dN] << d1) >> d1; /* clear up the top d1 bits */ + /* clear up the top d1 bits */ + if (d0) + z[dN] = (z[dN] << d1) >> d1; + else + z[dN] = 0; z[0] ^= zz; /* reduction t^0 component */ for (k = 1; p[k] != 0; k++) diff --git a/src/lib/libcrypto/bn/bn_lib.c b/src/lib/libcrypto/bn/bn_lib.c index 2649b8c538..32a8fbaf51 100644 --- a/src/lib/libcrypto/bn/bn_lib.c +++ b/src/lib/libcrypto/bn/bn_lib.c @@ -139,25 +139,6 @@ const BIGNUM *BN_value_one(void) return(&const_one); } -char *BN_options(void) - { - static int init=0; - static char data[16]; - - if (!init) - { - init++; -#ifdef BN_LLONG - BIO_snprintf(data,sizeof data,"bn(%d,%d)", - (int)sizeof(BN_ULLONG)*8,(int)sizeof(BN_ULONG)*8); -#else - BIO_snprintf(data,sizeof data,"bn(%d,%d)", - (int)sizeof(BN_ULONG)*8,(int)sizeof(BN_ULONG)*8); -#endif - } - return(data); - } - int BN_num_bits_word(BN_ULONG l) { static const char bits[256]={ diff --git a/src/lib/libcrypto/bn/bn_nist.c b/src/lib/libcrypto/bn/bn_nist.c index e14232fdbb..2ca5b01391 100644 --- a/src/lib/libcrypto/bn/bn_nist.c +++ b/src/lib/libcrypto/bn/bn_nist.c @@ -59,109 +59,266 @@ #include "bn_lcl.h" #include "cryptlib.h" + #define BN_NIST_192_TOP (192+BN_BITS2-1)/BN_BITS2 #define BN_NIST_224_TOP (224+BN_BITS2-1)/BN_BITS2 #define BN_NIST_256_TOP (256+BN_BITS2-1)/BN_BITS2 #define BN_NIST_384_TOP (384+BN_BITS2-1)/BN_BITS2 #define BN_NIST_521_TOP (521+BN_BITS2-1)/BN_BITS2 +/* pre-computed tables are "carry-less" values of modulus*(i+1) */ #if BN_BITS2 == 64 -static const BN_ULONG _nist_p_192[] = - {0xFFFFFFFFFFFFFFFFULL,0xFFFFFFFFFFFFFFFEULL, - 0xFFFFFFFFFFFFFFFFULL}; -static const BN_ULONG _nist_p_224[] = +static const BN_ULONG _nist_p_192[][BN_NIST_192_TOP] = { + {0xFFFFFFFFFFFFFFFFULL,0xFFFFFFFFFFFFFFFEULL,0xFFFFFFFFFFFFFFFFULL}, + {0xFFFFFFFFFFFFFFFEULL,0xFFFFFFFFFFFFFFFDULL,0xFFFFFFFFFFFFFFFFULL}, + {0xFFFFFFFFFFFFFFFDULL,0xFFFFFFFFFFFFFFFCULL,0xFFFFFFFFFFFFFFFFULL} + }; +static const BN_ULONG _nist_p_192_sqr[] = { + 0x0000000000000001ULL,0x0000000000000002ULL,0x0000000000000001ULL, + 0xFFFFFFFFFFFFFFFEULL,0xFFFFFFFFFFFFFFFDULL,0xFFFFFFFFFFFFFFFFULL + }; +static const BN_ULONG _nist_p_224[][BN_NIST_224_TOP] = { {0x0000000000000001ULL,0xFFFFFFFF00000000ULL, - 0xFFFFFFFFFFFFFFFFULL,0x00000000FFFFFFFFULL}; -static const BN_ULONG _nist_p_256[] = + 0xFFFFFFFFFFFFFFFFULL,0x00000000FFFFFFFFULL}, + {0x0000000000000002ULL,0xFFFFFFFE00000000ULL, + 0xFFFFFFFFFFFFFFFFULL,0x00000001FFFFFFFFULL} /* this one is "carry-full" */ + }; +static const BN_ULONG _nist_p_224_sqr[] = { + 0x0000000000000001ULL,0xFFFFFFFE00000000ULL, + 0xFFFFFFFFFFFFFFFFULL,0x0000000200000000ULL, + 0x0000000000000000ULL,0xFFFFFFFFFFFFFFFEULL, + 0xFFFFFFFFFFFFFFFFULL + }; +static const BN_ULONG _nist_p_256[][BN_NIST_256_TOP] = { {0xFFFFFFFFFFFFFFFFULL,0x00000000FFFFFFFFULL, - 0x0000000000000000ULL,0xFFFFFFFF00000001ULL}; -static const BN_ULONG _nist_p_384[] = - {0x00000000FFFFFFFFULL,0xFFFFFFFF00000000ULL, - 0xFFFFFFFFFFFFFFFEULL,0xFFFFFFFFFFFFFFFFULL, - 0xFFFFFFFFFFFFFFFFULL,0xFFFFFFFFFFFFFFFFULL}; + 0x0000000000000000ULL,0xFFFFFFFF00000001ULL}, + {0xFFFFFFFFFFFFFFFEULL,0x00000001FFFFFFFFULL, + 0x0000000000000000ULL,0xFFFFFFFE00000002ULL}, + {0xFFFFFFFFFFFFFFFDULL,0x00000002FFFFFFFFULL, + 0x0000000000000000ULL,0xFFFFFFFD00000003ULL}, + {0xFFFFFFFFFFFFFFFCULL,0x00000003FFFFFFFFULL, + 0x0000000000000000ULL,0xFFFFFFFC00000004ULL}, + {0xFFFFFFFFFFFFFFFBULL,0x00000004FFFFFFFFULL, + 0x0000000000000000ULL,0xFFFFFFFB00000005ULL}, + }; +static const BN_ULONG _nist_p_256_sqr[] = { + 0x0000000000000001ULL,0xFFFFFFFE00000000ULL, + 0xFFFFFFFFFFFFFFFFULL,0x00000001FFFFFFFEULL, + 0x00000001FFFFFFFEULL,0x00000001FFFFFFFEULL, + 0xFFFFFFFE00000001ULL,0xFFFFFFFE00000002ULL + }; +static const BN_ULONG _nist_p_384[][BN_NIST_384_TOP] = { + {0x00000000FFFFFFFFULL,0xFFFFFFFF00000000ULL,0xFFFFFFFFFFFFFFFEULL, + 0xFFFFFFFFFFFFFFFFULL,0xFFFFFFFFFFFFFFFFULL,0xFFFFFFFFFFFFFFFFULL}, + {0x00000001FFFFFFFEULL,0xFFFFFFFE00000000ULL,0xFFFFFFFFFFFFFFFDULL, + 0xFFFFFFFFFFFFFFFFULL,0xFFFFFFFFFFFFFFFFULL,0xFFFFFFFFFFFFFFFFULL}, + {0x00000002FFFFFFFDULL,0xFFFFFFFD00000000ULL,0xFFFFFFFFFFFFFFFCULL, + 0xFFFFFFFFFFFFFFFFULL,0xFFFFFFFFFFFFFFFFULL,0xFFFFFFFFFFFFFFFFULL}, + {0x00000003FFFFFFFCULL,0xFFFFFFFC00000000ULL,0xFFFFFFFFFFFFFFFBULL, + 0xFFFFFFFFFFFFFFFFULL,0xFFFFFFFFFFFFFFFFULL,0xFFFFFFFFFFFFFFFFULL}, + {0x00000004FFFFFFFBULL,0xFFFFFFFB00000000ULL,0xFFFFFFFFFFFFFFFAULL, + 0xFFFFFFFFFFFFFFFFULL,0xFFFFFFFFFFFFFFFFULL,0xFFFFFFFFFFFFFFFFULL}, + }; +static const BN_ULONG _nist_p_384_sqr[] = { + 0xFFFFFFFE00000001ULL,0x0000000200000000ULL,0xFFFFFFFE00000000ULL, + 0x0000000200000000ULL,0x0000000000000001ULL,0x0000000000000000ULL, + 0x00000001FFFFFFFEULL,0xFFFFFFFE00000000ULL,0xFFFFFFFFFFFFFFFDULL, + 0xFFFFFFFFFFFFFFFFULL,0xFFFFFFFFFFFFFFFFULL,0xFFFFFFFFFFFFFFFFULL + }; static const BN_ULONG _nist_p_521[] = {0xFFFFFFFFFFFFFFFFULL,0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL,0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL,0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL,0xFFFFFFFFFFFFFFFFULL, 0x00000000000001FFULL}; +static const BN_ULONG _nist_p_521_sqr[] = { + 0x0000000000000001ULL,0x0000000000000000ULL,0x0000000000000000ULL, + 0x0000000000000000ULL,0x0000000000000000ULL,0x0000000000000000ULL, + 0x0000000000000000ULL,0x0000000000000000ULL,0xFFFFFFFFFFFFFC00ULL, + 0xFFFFFFFFFFFFFFFFULL,0xFFFFFFFFFFFFFFFFULL,0xFFFFFFFFFFFFFFFFULL, + 0xFFFFFFFFFFFFFFFFULL,0xFFFFFFFFFFFFFFFFULL,0xFFFFFFFFFFFFFFFFULL, + 0xFFFFFFFFFFFFFFFFULL,0x000000000003FFFFULL + }; #elif BN_BITS2 == 32 -static const BN_ULONG _nist_p_192[] = {0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFE, - 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF}; -static const BN_ULONG _nist_p_224[] = {0x00000001,0x00000000,0x00000000, - 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF}; -static const BN_ULONG _nist_p_256[] = {0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, - 0x00000000,0x00000000,0x00000000,0x00000001,0xFFFFFFFF}; -static const BN_ULONG _nist_p_384[] = {0xFFFFFFFF,0x00000000,0x00000000, - 0xFFFFFFFF,0xFFFFFFFE,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, - 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF}; +static const BN_ULONG _nist_p_192[][BN_NIST_192_TOP] = { + {0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFE,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF}, + {0xFFFFFFFE,0xFFFFFFFF,0xFFFFFFFD,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF}, + {0xFFFFFFFD,0xFFFFFFFF,0xFFFFFFFC,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF} + }; +static const BN_ULONG _nist_p_192_sqr[] = { + 0x00000001,0x00000000,0x00000002,0x00000000,0x00000001,0x00000000, + 0xFFFFFFFE,0xFFFFFFFF,0xFFFFFFFD,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF + }; +static const BN_ULONG _nist_p_224[][BN_NIST_224_TOP] = { + {0x00000001,0x00000000,0x00000000,0xFFFFFFFF, + 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF}, + {0x00000002,0x00000000,0x00000000,0xFFFFFFFE, + 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF} + }; +static const BN_ULONG _nist_p_224_sqr[] = { + 0x00000001,0x00000000,0x00000000,0xFFFFFFFE, + 0xFFFFFFFF,0xFFFFFFFF,0x00000000,0x00000002, + 0x00000000,0x00000000,0xFFFFFFFE,0xFFFFFFFF, + 0xFFFFFFFF,0xFFFFFFFF + }; +static const BN_ULONG _nist_p_256[][BN_NIST_256_TOP] = { + {0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0x00000000, + 0x00000000,0x00000000,0x00000001,0xFFFFFFFF}, + {0xFFFFFFFE,0xFFFFFFFF,0xFFFFFFFF,0x00000001, + 0x00000000,0x00000000,0x00000002,0xFFFFFFFE}, + {0xFFFFFFFD,0xFFFFFFFF,0xFFFFFFFF,0x00000002, + 0x00000000,0x00000000,0x00000003,0xFFFFFFFD}, + {0xFFFFFFFC,0xFFFFFFFF,0xFFFFFFFF,0x00000003, + 0x00000000,0x00000000,0x00000004,0xFFFFFFFC}, + {0xFFFFFFFB,0xFFFFFFFF,0xFFFFFFFF,0x00000004, + 0x00000000,0x00000000,0x00000005,0xFFFFFFFB}, + }; +static const BN_ULONG _nist_p_256_sqr[] = { + 0x00000001,0x00000000,0x00000000,0xFFFFFFFE, + 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFE,0x00000001, + 0xFFFFFFFE,0x00000001,0xFFFFFFFE,0x00000001, + 0x00000001,0xFFFFFFFE,0x00000002,0xFFFFFFFE + }; +static const BN_ULONG _nist_p_384[][BN_NIST_384_TOP] = { + {0xFFFFFFFF,0x00000000,0x00000000,0xFFFFFFFF,0xFFFFFFFE,0xFFFFFFFF, + 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF}, + {0xFFFFFFFE,0x00000001,0x00000000,0xFFFFFFFE,0xFFFFFFFD,0xFFFFFFFF, + 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF}, + {0xFFFFFFFD,0x00000002,0x00000000,0xFFFFFFFD,0xFFFFFFFC,0xFFFFFFFF, + 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF}, + {0xFFFFFFFC,0x00000003,0x00000000,0xFFFFFFFC,0xFFFFFFFB,0xFFFFFFFF, + 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF}, + {0xFFFFFFFB,0x00000004,0x00000000,0xFFFFFFFB,0xFFFFFFFA,0xFFFFFFFF, + 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF}, + }; +static const BN_ULONG _nist_p_384_sqr[] = { + 0x00000001,0xFFFFFFFE,0x00000000,0x00000002,0x00000000,0xFFFFFFFE, + 0x00000000,0x00000002,0x00000001,0x00000000,0x00000000,0x00000000, + 0xFFFFFFFE,0x00000001,0x00000000,0xFFFFFFFE,0xFFFFFFFD,0xFFFFFFFF, + 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF + }; static const BN_ULONG _nist_p_521[] = {0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, 0xFFFFFFFF,0x000001FF}; +static const BN_ULONG _nist_p_521_sqr[] = { + 0x00000001,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000, + 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000, + 0x00000000,0x00000000,0x00000000,0x00000000,0xFFFFFC00,0xFFFFFFFF, + 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, + 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, + 0xFFFFFFFF,0xFFFFFFFF,0x0003FFFF + }; +#else +#error "unsupported BN_BITS2" #endif + +static const BIGNUM _bignum_nist_p_192 = + { + (BN_ULONG *)_nist_p_192[0], + BN_NIST_192_TOP, + BN_NIST_192_TOP, + 0, + BN_FLG_STATIC_DATA + }; + +static const BIGNUM _bignum_nist_p_224 = + { + (BN_ULONG *)_nist_p_224[0], + BN_NIST_224_TOP, + BN_NIST_224_TOP, + 0, + BN_FLG_STATIC_DATA + }; + +static const BIGNUM _bignum_nist_p_256 = + { + (BN_ULONG *)_nist_p_256[0], + BN_NIST_256_TOP, + BN_NIST_256_TOP, + 0, + BN_FLG_STATIC_DATA + }; + +static const BIGNUM _bignum_nist_p_384 = + { + (BN_ULONG *)_nist_p_384[0], + BN_NIST_384_TOP, + BN_NIST_384_TOP, + 0, + BN_FLG_STATIC_DATA + }; + +static const BIGNUM _bignum_nist_p_521 = + { + (BN_ULONG *)_nist_p_521, + BN_NIST_521_TOP, + BN_NIST_521_TOP, + 0, + BN_FLG_STATIC_DATA + }; + + const BIGNUM *BN_get0_nist_prime_192(void) { - static BIGNUM const_nist_192 = { (BN_ULONG *)_nist_p_192, - BN_NIST_192_TOP, BN_NIST_192_TOP, 0, BN_FLG_STATIC_DATA }; - return &const_nist_192; + return &_bignum_nist_p_192; } const BIGNUM *BN_get0_nist_prime_224(void) { - static BIGNUM const_nist_224 = { (BN_ULONG *)_nist_p_224, - BN_NIST_224_TOP, BN_NIST_224_TOP, 0, BN_FLG_STATIC_DATA }; - return &const_nist_224; + return &_bignum_nist_p_224; } const BIGNUM *BN_get0_nist_prime_256(void) { - static BIGNUM const_nist_256 = { (BN_ULONG *)_nist_p_256, - BN_NIST_256_TOP, BN_NIST_256_TOP, 0, BN_FLG_STATIC_DATA }; - return &const_nist_256; + return &_bignum_nist_p_256; } const BIGNUM *BN_get0_nist_prime_384(void) { - static BIGNUM const_nist_384 = { (BN_ULONG *)_nist_p_384, - BN_NIST_384_TOP, BN_NIST_384_TOP, 0, BN_FLG_STATIC_DATA }; - return &const_nist_384; + return &_bignum_nist_p_384; } const BIGNUM *BN_get0_nist_prime_521(void) { - static BIGNUM const_nist_521 = { (BN_ULONG *)_nist_p_521, - BN_NIST_521_TOP, BN_NIST_521_TOP, 0, BN_FLG_STATIC_DATA }; - return &const_nist_521; + return &_bignum_nist_p_521; } -#define BN_NIST_ADD_ONE(a) while (!(*(a)=(*(a)+1)&BN_MASK2)) ++(a); static void nist_cp_bn_0(BN_ULONG *buf, BN_ULONG *a, int top, int max) - { + { int i; - BN_ULONG *_tmp1 = (buf), *_tmp2 = (a); - for (i = (top); i != 0; i--) - *_tmp1++ = *_tmp2++; - for (i = (max) - (top); i != 0; i--) - *_tmp1++ = (BN_ULONG) 0; - } + BN_ULONG *_tmp1 = (buf), *_tmp2 = (a); + +#ifdef BN_DEBUG + OPENSSL_assert(top <= max); +#endif + for (i = (top); i != 0; i--) + *_tmp1++ = *_tmp2++; + for (i = (max) - (top); i != 0; i--) + *_tmp1++ = (BN_ULONG) 0; + } static void nist_cp_bn(BN_ULONG *buf, BN_ULONG *a, int top) - { + { int i; - BN_ULONG *_tmp1 = (buf), *_tmp2 = (a); - for (i = (top); i != 0; i--) - *_tmp1++ = *_tmp2++; - } + BN_ULONG *_tmp1 = (buf), *_tmp2 = (a); + for (i = (top); i != 0; i--) + *_tmp1++ = *_tmp2++; + } #if BN_BITS2 == 64 #define bn_cp_64(to, n, from, m) (to)[n] = (m>=0)?((from)[m]):0; #define bn_64_set_0(to, n) (to)[n] = (BN_ULONG)0; -/* TBD */ -#define bn_cp_32(to, n, from, m) (to)[n] = (m>=0)?((from)[m]):0; -#define bn_32_set_0(to, n) (to)[n] = (BN_ULONG)0; +/* + * two following macros are implemented under assumption that they + * are called in a sequence with *ascending* n, i.e. as they are... + */ +#define bn_cp_32_naked(to, n, from, m) (((n)&1)?(to[(n)/2]|=((m)&1)?(from[(m)/2]&BN_MASK2h):(from[(m)/2]<<32))\ + :(to[(n)/2] =((m)&1)?(from[(m)/2]>>32):(from[(m)/2]&BN_MASK2l))) +#define bn_32_set_0(to, n) (((n)&1)?(to[(n)/2]&=BN_MASK2l):(to[(n)/2]=0)); +#define bn_cp_32(to,n,from,m) ((m)>=0)?bn_cp_32_naked(to,n,from,m):bn_32_set_0(to,n) #else #define bn_cp_64(to, n, from, m) \ { \ @@ -182,9 +339,9 @@ static void nist_cp_bn(BN_ULONG *buf, BN_ULONG *a, int top) #define nist_set_192(to, from, a1, a2, a3) \ { \ - if (a3 != 0) bn_cp_64(to, 0, from, (a3) - 3) else bn_64_set_0(to, 0)\ + bn_cp_64(to, 0, from, (a3) - 3) \ bn_cp_64(to, 1, from, (a2) - 3) \ - if (a1 != 0) bn_cp_64(to, 2, from, (a1) - 3) else bn_64_set_0(to, 2)\ + bn_cp_64(to, 2, from, (a1) - 3) \ } int BN_nist_mod_192(BIGNUM *r, const BIGNUM *a, const BIGNUM *field, @@ -198,6 +355,16 @@ int BN_nist_mod_192(BIGNUM *r, const BIGNUM *a, const BIGNUM *field, c_d[BN_NIST_192_TOP], *res; size_t mask; + static const BIGNUM _bignum_nist_p_192_sqr = { + (BN_ULONG *)_nist_p_192_sqr, + sizeof(_nist_p_192_sqr)/sizeof(_nist_p_192_sqr[0]), + sizeof(_nist_p_192_sqr)/sizeof(_nist_p_192_sqr[0]), + 0,BN_FLG_STATIC_DATA }; + + field = &_bignum_nist_p_192; /* just to make sure */ + + if (BN_is_negative(a) || BN_ucmp(a,&_bignum_nist_p_192_sqr)>=0) + return BN_nnmod(r, a, field, ctx); i = BN_ucmp(field, a); if (i == 0) @@ -208,9 +375,6 @@ int BN_nist_mod_192(BIGNUM *r, const BIGNUM *a, const BIGNUM *field, else if (i > 0) return (r == a) ? 1 : (BN_copy(r ,a) != NULL); - if (top == BN_NIST_192_TOP) - return BN_usub(r, a, field); - if (r != a) { if (!bn_wexpand(r, BN_NIST_192_TOP)) @@ -224,23 +388,26 @@ int BN_nist_mod_192(BIGNUM *r, const BIGNUM *a, const BIGNUM *field, nist_cp_bn_0(buf, a_d + BN_NIST_192_TOP, top - BN_NIST_192_TOP, BN_NIST_192_TOP); nist_set_192(t_d, buf, 0, 3, 3); - carry = bn_add_words(r_d, r_d, t_d, BN_NIST_192_TOP); - mask = 0-(size_t)bn_sub_words(c_d,r_d,_nist_p_192,BN_NIST_192_TOP); - mask = ~mask | (0-(size_t)carry); - res = (BN_ULONG *)(((size_t)c_d&mask) | ((size_t)r_d&~mask)); - + carry = (int)bn_add_words(r_d, r_d, t_d, BN_NIST_192_TOP); nist_set_192(t_d, buf, 4, 4, 0); - carry = bn_add_words(r_d, res, t_d, BN_NIST_192_TOP); - mask = 0-(size_t)bn_sub_words(c_d,r_d,_nist_p_192,BN_NIST_192_TOP); - mask = ~mask | (0-(size_t)carry); - res = (BN_ULONG *)(((size_t)c_d&mask) | ((size_t)r_d&~mask)); - + carry += (int)bn_add_words(r_d, r_d, t_d, BN_NIST_192_TOP); nist_set_192(t_d, buf, 5, 5, 5) - carry = bn_add_words(r_d, res, t_d, BN_NIST_192_TOP); - mask = 0-(size_t)bn_sub_words(c_d,r_d,_nist_p_192,BN_NIST_192_TOP); - mask = ~mask | (0-(size_t)carry); - res = (BN_ULONG *)(((size_t)c_d&mask) | ((size_t)r_d&~mask)); + carry += (int)bn_add_words(r_d, r_d, t_d, BN_NIST_192_TOP); + if (carry > 0) + carry = (int)bn_sub_words(r_d,r_d,_nist_p_192[carry-1],BN_NIST_192_TOP); + else + carry = 1; + + /* + * we need 'if (carry==0 || result>=modulus) result-=modulus;' + * as comparison implies subtraction, we can write + * 'tmp=result-modulus; if (!carry || !borrow) result=tmp;' + * this is what happens below, but without explicit if:-) a. + */ + mask = 0-(size_t)bn_sub_words(c_d,r_d,_nist_p_192[0],BN_NIST_192_TOP); + mask &= 0-(size_t)carry; + res = (BN_ULONG *)(((size_t)c_d&~mask) | ((size_t)r_d&mask)); nist_cp_bn(r_d, res, BN_NIST_192_TOP); r->top = BN_NIST_192_TOP; bn_correct_top(r); @@ -248,21 +415,22 @@ int BN_nist_mod_192(BIGNUM *r, const BIGNUM *a, const BIGNUM *field, return 1; } +typedef BN_ULONG (*bn_addsub_f)(BN_ULONG *,const BN_ULONG *,const BN_ULONG *,int); + #define nist_set_224(to, from, a1, a2, a3, a4, a5, a6, a7) \ { \ - if (a7 != 0) bn_cp_32(to, 0, from, (a7) - 7) else bn_32_set_0(to, 0)\ - if (a6 != 0) bn_cp_32(to, 1, from, (a6) - 7) else bn_32_set_0(to, 1)\ - if (a5 != 0) bn_cp_32(to, 2, from, (a5) - 7) else bn_32_set_0(to, 2)\ - if (a4 != 0) bn_cp_32(to, 3, from, (a4) - 7) else bn_32_set_0(to, 3)\ - if (a3 != 0) bn_cp_32(to, 4, from, (a3) - 7) else bn_32_set_0(to, 4)\ - if (a2 != 0) bn_cp_32(to, 5, from, (a2) - 7) else bn_32_set_0(to, 5)\ - if (a1 != 0) bn_cp_32(to, 6, from, (a1) - 7) else bn_32_set_0(to, 6)\ + bn_cp_32(to, 0, from, (a7) - 7) \ + bn_cp_32(to, 1, from, (a6) - 7) \ + bn_cp_32(to, 2, from, (a5) - 7) \ + bn_cp_32(to, 3, from, (a4) - 7) \ + bn_cp_32(to, 4, from, (a3) - 7) \ + bn_cp_32(to, 5, from, (a2) - 7) \ + bn_cp_32(to, 6, from, (a1) - 7) \ } int BN_nist_mod_224(BIGNUM *r, const BIGNUM *a, const BIGNUM *field, BN_CTX *ctx) { -#if BN_BITS2 == 32 int top = a->top, i; int carry; BN_ULONG *r_d, *a_d = a->d; @@ -271,6 +439,18 @@ int BN_nist_mod_224(BIGNUM *r, const BIGNUM *a, const BIGNUM *field, c_d[BN_NIST_224_TOP], *res; size_t mask; + union { bn_addsub_f f; size_t p; } u; + static const BIGNUM _bignum_nist_p_224_sqr = { + (BN_ULONG *)_nist_p_224_sqr, + sizeof(_nist_p_224_sqr)/sizeof(_nist_p_224_sqr[0]), + sizeof(_nist_p_224_sqr)/sizeof(_nist_p_224_sqr[0]), + 0,BN_FLG_STATIC_DATA }; + + + field = &_bignum_nist_p_224; /* just to make sure */ + + if (BN_is_negative(a) || BN_ucmp(a,&_bignum_nist_p_224_sqr)>=0) + return BN_nnmod(r, a, field, ctx); i = BN_ucmp(field, a); if (i == 0) @@ -281,9 +461,6 @@ int BN_nist_mod_224(BIGNUM *r, const BIGNUM *a, const BIGNUM *field, else if (i > 0) return (r == a)? 1 : (BN_copy(r ,a) != NULL); - if (top == BN_NIST_224_TOP) - return BN_usub(r, a, field); - if (r != a) { if (!bn_wexpand(r, BN_NIST_224_TOP)) @@ -294,67 +471,77 @@ int BN_nist_mod_224(BIGNUM *r, const BIGNUM *a, const BIGNUM *field, else r_d = a_d; +#if BN_BITS2==64 + /* copy upper 256 bits of 448 bit number ... */ + nist_cp_bn_0(t_d, a_d + (BN_NIST_224_TOP-1), top - (BN_NIST_224_TOP-1), BN_NIST_224_TOP); + /* ... and right shift by 32 to obtain upper 224 bits */ + nist_set_224(buf, t_d, 14, 13, 12, 11, 10, 9, 8); + /* truncate lower part to 224 bits too */ + r_d[BN_NIST_224_TOP-1] &= BN_MASK2l; +#else nist_cp_bn_0(buf, a_d + BN_NIST_224_TOP, top - BN_NIST_224_TOP, BN_NIST_224_TOP); - +#endif nist_set_224(t_d, buf, 10, 9, 8, 7, 0, 0, 0); - carry = bn_add_words(r_d, r_d, t_d, BN_NIST_224_TOP); - mask = 0-(size_t)bn_sub_words(c_d,r_d,_nist_p_224,BN_NIST_224_TOP); - mask = ~mask | (0-(size_t)carry); - res = (BN_ULONG *)(((size_t)c_d&mask) | ((size_t)r_d&~mask)); - + carry = (int)bn_add_words(r_d, r_d, t_d, BN_NIST_224_TOP); nist_set_224(t_d, buf, 0, 13, 12, 11, 0, 0, 0); - carry = bn_add_words(r_d, res, t_d, BN_NIST_224_TOP); - mask = 0-(size_t)bn_sub_words(c_d,r_d,_nist_p_224,BN_NIST_224_TOP); - mask = ~mask | (0-(size_t)carry); - res = (BN_ULONG *)(((size_t)c_d&mask) | ((size_t)r_d&~mask)); - + carry += (int)bn_add_words(r_d, r_d, t_d, BN_NIST_224_TOP); nist_set_224(t_d, buf, 13, 12, 11, 10, 9, 8, 7); -#if BRANCH_FREE - carry = bn_sub_words(r_d, res, t_d, BN_NIST_224_TOP); - bn_add_words(c_d,r_d,_nist_p_224,BN_NIST_224_TOP); - mask = 0-(size_t)carry; - res = (BN_ULONG *)(((size_t)c_d&mask) | ((size_t)r_d&~mask)); -#else - if (bn_sub_words(r_d, res, t_d, BN_NIST_224_TOP)) - bn_add_words(r_d,r_d,_nist_p_224,BN_NIST_224_TOP); -#endif + carry -= (int)bn_sub_words(r_d, r_d, t_d, BN_NIST_224_TOP); nist_set_224(t_d, buf, 0, 0, 0, 0, 13, 12, 11); -#if BRANCH_FREE - carry = bn_sub_words(r_d, res, t_d, BN_NIST_224_TOP); - bn_add_words(c_d,r_d,_nist_p_224,BN_NIST_224_TOP); - mask = 0-(size_t)carry; - res = (BN_ULONG *)(((size_t)c_d&mask) | ((size_t)r_d&~mask)); + carry -= (int)bn_sub_words(r_d, r_d, t_d, BN_NIST_224_TOP); - nist_cp_bn(r_d, res, BN_NIST_224_TOP); -#else - if (bn_sub_words(r_d, r_d, t_d, BN_NIST_224_TOP)) - bn_add_words(r_d,r_d,_nist_p_224,BN_NIST_224_TOP); +#if BN_BITS2==64 + carry = (int)(r_d[BN_NIST_224_TOP-1]>>32); +#endif + u.f = bn_sub_words; + if (carry > 0) + { + carry = (int)bn_sub_words(r_d,r_d,_nist_p_224[carry-1],BN_NIST_224_TOP); +#if BN_BITS2==64 + carry=(int)(~(r_d[BN_NIST_224_TOP-1]>>32))&1; #endif + } + else if (carry < 0) + { + /* it's a bit more comlicated logic in this case. + * if bn_add_words yields no carry, then result + * has to be adjusted by unconditionally *adding* + * the modulus. but if it does, then result has + * to be compared to the modulus and conditionally + * adjusted by *subtracting* the latter. */ + carry = (int)bn_add_words(r_d,r_d,_nist_p_224[-carry-1],BN_NIST_224_TOP); + mask = 0-(size_t)carry; + u.p = ((size_t)bn_sub_words&mask) | ((size_t)bn_add_words&~mask); + } + else + carry = 1; + + /* otherwise it's effectively same as in BN_nist_mod_192... */ + mask = 0-(size_t)(*u.f)(c_d,r_d,_nist_p_224[0],BN_NIST_224_TOP); + mask &= 0-(size_t)carry; + res = (BN_ULONG *)(((size_t)c_d&~mask) | ((size_t)r_d&mask)); + nist_cp_bn(r_d, res, BN_NIST_224_TOP); r->top = BN_NIST_224_TOP; bn_correct_top(r); return 1; -#else /* BN_BITS!=32 */ - return 0; -#endif } #define nist_set_256(to, from, a1, a2, a3, a4, a5, a6, a7, a8) \ { \ - if (a8 != 0) bn_cp_32(to, 0, from, (a8) - 8) else bn_32_set_0(to, 0)\ - if (a7 != 0) bn_cp_32(to, 1, from, (a7) - 8) else bn_32_set_0(to, 1)\ - if (a6 != 0) bn_cp_32(to, 2, from, (a6) - 8) else bn_32_set_0(to, 2)\ - if (a5 != 0) bn_cp_32(to, 3, from, (a5) - 8) else bn_32_set_0(to, 3)\ - if (a4 != 0) bn_cp_32(to, 4, from, (a4) - 8) else bn_32_set_0(to, 4)\ - if (a3 != 0) bn_cp_32(to, 5, from, (a3) - 8) else bn_32_set_0(to, 5)\ - if (a2 != 0) bn_cp_32(to, 6, from, (a2) - 8) else bn_32_set_0(to, 6)\ - if (a1 != 0) bn_cp_32(to, 7, from, (a1) - 8) else bn_32_set_0(to, 7)\ + bn_cp_32(to, 0, from, (a8) - 8) \ + bn_cp_32(to, 1, from, (a7) - 8) \ + bn_cp_32(to, 2, from, (a6) - 8) \ + bn_cp_32(to, 3, from, (a5) - 8) \ + bn_cp_32(to, 4, from, (a4) - 8) \ + bn_cp_32(to, 5, from, (a3) - 8) \ + bn_cp_32(to, 6, from, (a2) - 8) \ + bn_cp_32(to, 7, from, (a1) - 8) \ } int BN_nist_mod_256(BIGNUM *r, const BIGNUM *a, const BIGNUM *field, BN_CTX *ctx) { -#if BN_BITS2 == 32 int i, top = a->top; int carry = 0; register BN_ULONG *a_d = a->d, *r_d; @@ -363,6 +550,17 @@ int BN_nist_mod_256(BIGNUM *r, const BIGNUM *a, const BIGNUM *field, c_d[BN_NIST_256_TOP], *res; size_t mask; + union { bn_addsub_f f; size_t p; } u; + static const BIGNUM _bignum_nist_p_256_sqr = { + (BN_ULONG *)_nist_p_256_sqr, + sizeof(_nist_p_256_sqr)/sizeof(_nist_p_256_sqr[0]), + sizeof(_nist_p_256_sqr)/sizeof(_nist_p_256_sqr[0]), + 0,BN_FLG_STATIC_DATA }; + + field = &_bignum_nist_p_256; /* just to make sure */ + + if (BN_is_negative(a) || BN_ucmp(a,&_bignum_nist_p_256_sqr)>=0) + return BN_nnmod(r, a, field, ctx); i = BN_ucmp(field, a); if (i == 0) @@ -373,9 +571,6 @@ int BN_nist_mod_256(BIGNUM *r, const BIGNUM *a, const BIGNUM *field, else if (i > 0) return (r == a)? 1 : (BN_copy(r ,a) != NULL); - if (top == BN_NIST_256_TOP) - return BN_usub(r, a, field); - if (r != a) { if (!bn_wexpand(r, BN_NIST_256_TOP)) @@ -391,111 +586,84 @@ int BN_nist_mod_256(BIGNUM *r, const BIGNUM *a, const BIGNUM *field, /*S1*/ nist_set_256(t_d, buf, 15, 14, 13, 12, 11, 0, 0, 0); /*S2*/ - nist_set_256(c_d,buf, 0, 15, 14, 13, 12, 0, 0, 0); - carry = bn_add_words(t_d, t_d, c_d, BN_NIST_256_TOP); - mask = 0-(size_t)bn_sub_words(c_d,t_d,_nist_p_256,BN_NIST_256_TOP); - mask = ~mask | (0-(size_t)carry); - res = (BN_ULONG *)(((size_t)c_d&mask) | ((size_t)t_d&~mask)); - - carry = bn_add_words(t_d, res, res, BN_NIST_256_TOP); - mask = 0-(size_t)bn_sub_words(c_d,t_d,_nist_p_256,BN_NIST_256_TOP); - mask = ~mask | (0-(size_t)carry); - res = (BN_ULONG *)(((size_t)c_d&mask) | ((size_t)t_d&~mask)); - - carry = bn_add_words(r_d, r_d, res, BN_NIST_256_TOP); - mask = 0-(size_t)bn_sub_words(c_d,r_d,_nist_p_256,BN_NIST_256_TOP); - mask = ~mask | (0-(size_t)carry); - res = (BN_ULONG *)(((size_t)c_d&mask) | ((size_t)r_d&~mask)); - + nist_set_256(c_d, buf, 0, 15, 14, 13, 12, 0, 0, 0); + carry = (int)bn_add_words(t_d, t_d, c_d, BN_NIST_256_TOP); + /* left shift */ + { + register BN_ULONG *ap,t,c; + ap = t_d; + c=0; + for (i = BN_NIST_256_TOP; i != 0; --i) + { + t= *ap; + *(ap++)=((t<<1)|c)&BN_MASK2; + c=(t & BN_TBIT)?1:0; + } + carry <<= 1; + carry |= c; + } + carry += (int)bn_add_words(r_d, r_d, t_d, BN_NIST_256_TOP); /*S3*/ nist_set_256(t_d, buf, 15, 14, 0, 0, 0, 10, 9, 8); - carry = bn_add_words(r_d, res, t_d, BN_NIST_256_TOP); - mask = 0-(size_t)bn_sub_words(c_d,r_d,_nist_p_256,BN_NIST_256_TOP); - mask = ~mask | (0-(size_t)carry); - res = (BN_ULONG *)(((size_t)c_d&mask) | ((size_t)r_d&~mask)); - + carry += (int)bn_add_words(r_d, r_d, t_d, BN_NIST_256_TOP); /*S4*/ nist_set_256(t_d, buf, 8, 13, 15, 14, 13, 11, 10, 9); - carry = bn_add_words(r_d, res, t_d, BN_NIST_256_TOP); - mask = 0-(size_t)bn_sub_words(c_d,r_d,_nist_p_256,BN_NIST_256_TOP); - mask = ~mask | (0-(size_t)carry); - res = (BN_ULONG *)(((size_t)c_d&mask) | ((size_t)r_d&~mask)); - + carry += (int)bn_add_words(r_d, r_d, t_d, BN_NIST_256_TOP); /*D1*/ nist_set_256(t_d, buf, 10, 8, 0, 0, 0, 13, 12, 11); -#if BRANCH_FREE - carry = bn_sub_words(r_d, res, t_d, BN_NIST_256_TOP); - bn_add_words(c_d,r_d,_nist_p_256,BN_NIST_256_TOP); - mask = 0-(size_t)carry; - res = (BN_ULONG *)(((size_t)c_d&mask) | ((size_t)r_d&~mask)); -#else - if (bn_sub_words(r_d, res, t_d, BN_NIST_256_TOP)) - bn_add_words(r_d,r_d,_nist_p_256,BN_NIST_256_TOP); -#endif + carry -= (int)bn_sub_words(r_d, r_d, t_d, BN_NIST_256_TOP); /*D2*/ nist_set_256(t_d, buf, 11, 9, 0, 0, 15, 14, 13, 12); -#if BRANCH_FREE - carry = bn_sub_words(r_d, res, t_d, BN_NIST_256_TOP); - bn_add_words(c_d,r_d,_nist_p_256,BN_NIST_256_TOP); - mask = 0-(size_t)carry; - res = (BN_ULONG *)(((size_t)c_d&mask) | ((size_t)r_d&~mask)); -#else - if (bn_sub_words(r_d, r_d, t_d, BN_NIST_256_TOP)) - bn_add_words(r_d,r_d,_nist_p_256,BN_NIST_256_TOP); -#endif + carry -= (int)bn_sub_words(r_d, r_d, t_d, BN_NIST_256_TOP); /*D3*/ nist_set_256(t_d, buf, 12, 0, 10, 9, 8, 15, 14, 13); -#if BRANCH_FREE - carry = bn_sub_words(r_d, res, t_d, BN_NIST_256_TOP); - bn_add_words(c_d,r_d,_nist_p_256,BN_NIST_256_TOP); - mask = 0-(size_t)carry; - res = (BN_ULONG *)(((size_t)c_d&mask) | ((size_t)r_d&~mask)); -#else - if (bn_sub_words(r_d, r_d, t_d, BN_NIST_256_TOP)) - bn_add_words(r_d,r_d,_nist_p_256,BN_NIST_256_TOP); -#endif + carry -= (int)bn_sub_words(r_d, r_d, t_d, BN_NIST_256_TOP); /*D4*/ nist_set_256(t_d, buf, 13, 0, 11, 10, 9, 0, 15, 14); -#if BRANCH_FREE - carry = bn_sub_words(r_d, res, t_d, BN_NIST_256_TOP); - bn_add_words(c_d,r_d,_nist_p_256,BN_NIST_256_TOP); - mask = 0-(size_t)carry; - res = (BN_ULONG *)(((size_t)c_d&mask) | ((size_t)r_d&~mask)); + carry -= (int)bn_sub_words(r_d, r_d, t_d, BN_NIST_256_TOP); - nist_cp_bn(r_d, res, BN_NIST_384_TOP); -#else - if (bn_sub_words(r_d, r_d, t_d, BN_NIST_256_TOP)) - bn_add_words(r_d,r_d,_nist_p_256,BN_NIST_256_TOP); -#endif + /* see BN_nist_mod_224 for explanation */ + u.f = bn_sub_words; + if (carry > 0) + carry = (int)bn_sub_words(r_d,r_d,_nist_p_256[carry-1],BN_NIST_256_TOP); + else if (carry < 0) + { + carry = (int)bn_add_words(r_d,r_d,_nist_p_256[-carry-1],BN_NIST_256_TOP); + mask = 0-(size_t)carry; + u.p = ((size_t)bn_sub_words&mask) | ((size_t)bn_add_words&~mask); + } + else + carry = 1; + + mask = 0-(size_t)(*u.f)(c_d,r_d,_nist_p_256[0],BN_NIST_256_TOP); + mask &= 0-(size_t)carry; + res = (BN_ULONG *)(((size_t)c_d&~mask) | ((size_t)r_d&mask)); + nist_cp_bn(r_d, res, BN_NIST_256_TOP); r->top = BN_NIST_256_TOP; bn_correct_top(r); return 1; -#else /* BN_BITS!=32 */ - return 0; -#endif } #define nist_set_384(to,from,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12) \ { \ - if (a12 != 0) bn_cp_32(to, 0, from, (a12) - 12) else bn_32_set_0(to, 0)\ - if (a11 != 0) bn_cp_32(to, 1, from, (a11) - 12) else bn_32_set_0(to, 1)\ - if (a10 != 0) bn_cp_32(to, 2, from, (a10) - 12) else bn_32_set_0(to, 2)\ - if (a9 != 0) bn_cp_32(to, 3, from, (a9) - 12) else bn_32_set_0(to, 3)\ - if (a8 != 0) bn_cp_32(to, 4, from, (a8) - 12) else bn_32_set_0(to, 4)\ - if (a7 != 0) bn_cp_32(to, 5, from, (a7) - 12) else bn_32_set_0(to, 5)\ - if (a6 != 0) bn_cp_32(to, 6, from, (a6) - 12) else bn_32_set_0(to, 6)\ - if (a5 != 0) bn_cp_32(to, 7, from, (a5) - 12) else bn_32_set_0(to, 7)\ - if (a4 != 0) bn_cp_32(to, 8, from, (a4) - 12) else bn_32_set_0(to, 8)\ - if (a3 != 0) bn_cp_32(to, 9, from, (a3) - 12) else bn_32_set_0(to, 9)\ - if (a2 != 0) bn_cp_32(to, 10, from, (a2) - 12) else bn_32_set_0(to, 10)\ - if (a1 != 0) bn_cp_32(to, 11, from, (a1) - 12) else bn_32_set_0(to, 11)\ + bn_cp_32(to, 0, from, (a12) - 12) \ + bn_cp_32(to, 1, from, (a11) - 12) \ + bn_cp_32(to, 2, from, (a10) - 12) \ + bn_cp_32(to, 3, from, (a9) - 12) \ + bn_cp_32(to, 4, from, (a8) - 12) \ + bn_cp_32(to, 5, from, (a7) - 12) \ + bn_cp_32(to, 6, from, (a6) - 12) \ + bn_cp_32(to, 7, from, (a5) - 12) \ + bn_cp_32(to, 8, from, (a4) - 12) \ + bn_cp_32(to, 9, from, (a3) - 12) \ + bn_cp_32(to, 10, from, (a2) - 12) \ + bn_cp_32(to, 11, from, (a1) - 12) \ } int BN_nist_mod_384(BIGNUM *r, const BIGNUM *a, const BIGNUM *field, BN_CTX *ctx) { -#if BN_BITS2 == 32 int i, top = a->top; int carry = 0; register BN_ULONG *r_d, *a_d = a->d; @@ -504,6 +672,18 @@ int BN_nist_mod_384(BIGNUM *r, const BIGNUM *a, const BIGNUM *field, c_d[BN_NIST_384_TOP], *res; size_t mask; + union { bn_addsub_f f; size_t p; } u; + static const BIGNUM _bignum_nist_p_384_sqr = { + (BN_ULONG *)_nist_p_384_sqr, + sizeof(_nist_p_384_sqr)/sizeof(_nist_p_384_sqr[0]), + sizeof(_nist_p_384_sqr)/sizeof(_nist_p_384_sqr[0]), + 0,BN_FLG_STATIC_DATA }; + + + field = &_bignum_nist_p_384; /* just to make sure */ + + if (BN_is_negative(a) || BN_ucmp(a,&_bignum_nist_p_384_sqr)>=0) + return BN_nnmod(r, a, field, ctx); i = BN_ucmp(field, a); if (i == 0) @@ -514,9 +694,6 @@ int BN_nist_mod_384(BIGNUM *r, const BIGNUM *a, const BIGNUM *field, else if (i > 0) return (r == a)? 1 : (BN_copy(r ,a) != NULL); - if (top == BN_NIST_384_TOP) - return BN_usub(r, a, field); - if (r != a) { if (!bn_wexpand(r, BN_NIST_384_TOP)) @@ -544,149 +721,116 @@ int BN_nist_mod_384(BIGNUM *r, const BIGNUM *a, const BIGNUM *field, } *ap=c; } - carry = bn_add_words(r_d+(128/BN_BITS2), r_d+(128/BN_BITS2), + carry = (int)bn_add_words(r_d+(128/BN_BITS2), r_d+(128/BN_BITS2), t_d, BN_NIST_256_TOP); - /* - * we need if (result>=modulus) subtract(result,modulus); - * in n-bit space this can be expressed as - * if (carry || result>=modulus) subtract(result,modulus); - * the catch is that comparison implies subtraction and - * therefore one can write tmp=subtract(result,modulus); - * and then if(carry || !borrow) result=tmp; this's what - * happens below, but without explicit if:-) a. - */ - mask = 0-(size_t)bn_sub_words(c_d,r_d,_nist_p_384,BN_NIST_384_TOP); - mask = ~mask | (0-(size_t)carry); - res = (BN_ULONG *)(((size_t)c_d&mask) | ((size_t)r_d&~mask)); - /*S2 */ - carry = bn_add_words(r_d, res, buf, BN_NIST_384_TOP); - mask = 0-(size_t)bn_sub_words(c_d,r_d,_nist_p_384,BN_NIST_384_TOP); - mask = ~mask | (0-(size_t)carry); - res = (BN_ULONG *)(((size_t)c_d&mask) | ((size_t)r_d&~mask)); - + carry += (int)bn_add_words(r_d, r_d, buf, BN_NIST_384_TOP); /*S3*/ nist_set_384(t_d,buf,20,19,18,17,16,15,14,13,12,23,22,21); - carry = bn_add_words(r_d, res, t_d, BN_NIST_384_TOP); - mask = 0-(size_t)bn_sub_words(c_d,r_d,_nist_p_384,BN_NIST_384_TOP); - mask = ~mask | (0-(size_t)carry); - res = (BN_ULONG *)(((size_t)c_d&mask) | ((size_t)r_d&~mask)); - + carry += (int)bn_add_words(r_d, r_d, t_d, BN_NIST_384_TOP); /*S4*/ nist_set_384(t_d,buf,19,18,17,16,15,14,13,12,20,0,23,0); - carry = bn_add_words(r_d, res, t_d, BN_NIST_384_TOP); - mask = 0-(size_t)bn_sub_words(c_d,r_d,_nist_p_384,BN_NIST_384_TOP); - mask = ~mask | (0-(size_t)carry); - res = (BN_ULONG *)(((size_t)c_d&mask) | ((size_t)r_d&~mask)); - + carry += (int)bn_add_words(r_d, r_d, t_d, BN_NIST_384_TOP); /*S5*/ nist_set_384(t_d, buf,0,0,0,0,23,22,21,20,0,0,0,0); - carry = bn_add_words(r_d, res, t_d, BN_NIST_384_TOP); - mask = 0-(size_t)bn_sub_words(c_d,r_d,_nist_p_384,BN_NIST_384_TOP); - mask = ~mask | (0-(size_t)carry); - res = (BN_ULONG *)(((size_t)c_d&mask) | ((size_t)r_d&~mask)); - + carry += (int)bn_add_words(r_d, r_d, t_d, BN_NIST_384_TOP); /*S6*/ nist_set_384(t_d,buf,0,0,0,0,0,0,23,22,21,0,0,20); - carry = bn_add_words(r_d, res, t_d, BN_NIST_384_TOP); - mask = 0-(size_t)bn_sub_words(c_d,r_d,_nist_p_384,BN_NIST_384_TOP); - mask = ~mask | (0-(size_t)carry); - res = (BN_ULONG *)(((size_t)c_d&mask) | ((size_t)r_d&~mask)); - + carry += (int)bn_add_words(r_d, r_d, t_d, BN_NIST_384_TOP); /*D1*/ nist_set_384(t_d,buf,22,21,20,19,18,17,16,15,14,13,12,23); -#if BRANCH_FREE - carry = bn_sub_words(r_d, res, t_d, BN_NIST_384_TOP); - bn_add_words(c_d,r_d,_nist_p_384,BN_NIST_384_TOP); - mask = 0-(size_t)carry; - res = (BN_ULONG *)(((size_t)c_d&mask) | ((size_t)r_d&~mask)); -#else - if (bn_sub_words(r_d, res, t_d, BN_NIST_384_TOP)) - bn_add_words(r_d,r_d,_nist_p_384,BN_NIST_384_TOP); -#endif + carry -= (int)bn_sub_words(r_d, r_d, t_d, BN_NIST_384_TOP); /*D2*/ nist_set_384(t_d,buf,0,0,0,0,0,0,0,23,22,21,20,0); -#if BRANCH_FREE - carry = bn_sub_words(r_d, res, t_d, BN_NIST_384_TOP); - bn_add_words(c_d,r_d,_nist_p_384,BN_NIST_384_TOP); - mask = 0-(size_t)carry; - res = (BN_ULONG *)(((size_t)c_d&mask) | ((size_t)r_d&~mask)); -#else - if (bn_sub_words(r_d, r_d, t_d, BN_NIST_384_TOP)) - bn_add_words(r_d,r_d,_nist_p_384,BN_NIST_384_TOP); -#endif + carry -= (int)bn_sub_words(r_d, r_d, t_d, BN_NIST_384_TOP); /*D3*/ nist_set_384(t_d,buf,0,0,0,0,0,0,0,23,23,0,0,0); -#if BRANCH_FREE - carry = bn_sub_words(r_d, res, t_d, BN_NIST_384_TOP); - bn_add_words(c_d,r_d,_nist_p_384,BN_NIST_384_TOP); - mask = 0-(size_t)carry; - res = (BN_ULONG *)(((size_t)c_d&mask) | ((size_t)r_d&~mask)); + carry -= (int)bn_sub_words(r_d, r_d, t_d, BN_NIST_384_TOP); + + /* see BN_nist_mod_224 for explanation */ + u.f = bn_sub_words; + if (carry > 0) + carry = (int)bn_sub_words(r_d,r_d,_nist_p_384[carry-1],BN_NIST_384_TOP); + else if (carry < 0) + { + carry = (int)bn_add_words(r_d,r_d,_nist_p_384[-carry-1],BN_NIST_384_TOP); + mask = 0-(size_t)carry; + u.p = ((size_t)bn_sub_words&mask) | ((size_t)bn_add_words&~mask); + } + else + carry = 1; + mask = 0-(size_t)(*u.f)(c_d,r_d,_nist_p_384[0],BN_NIST_384_TOP); + mask &= 0-(size_t)carry; + res = (BN_ULONG *)(((size_t)c_d&~mask) | ((size_t)r_d&mask)); nist_cp_bn(r_d, res, BN_NIST_384_TOP); -#else - if (bn_sub_words(r_d, r_d, t_d, BN_NIST_384_TOP)) - bn_add_words(r_d,r_d,_nist_p_384,BN_NIST_384_TOP); -#endif r->top = BN_NIST_384_TOP; bn_correct_top(r); return 1; -#else /* BN_BITS!=32 */ - return 0; -#endif } +#define BN_NIST_521_RSHIFT (521%BN_BITS2) +#define BN_NIST_521_LSHIFT (BN_BITS2-BN_NIST_521_RSHIFT) +#define BN_NIST_521_TOP_MASK ((BN_ULONG)BN_MASK2>>BN_NIST_521_LSHIFT) + int BN_nist_mod_521(BIGNUM *r, const BIGNUM *a, const BIGNUM *field, BN_CTX *ctx) { -#if BN_BITS2 == 64 -#define BN_NIST_521_TOP_MASK (BN_ULONG)0x1FF -#elif BN_BITS2 == 32 -#define BN_NIST_521_TOP_MASK (BN_ULONG)0x1FF -#endif - int top, ret = 0; - BN_ULONG *r_d; - BIGNUM *tmp; - - /* check whether a reduction is necessary */ - top = a->top; - if (top < BN_NIST_521_TOP || ( top == BN_NIST_521_TOP && - (!(a->d[BN_NIST_521_TOP-1] & ~(BN_NIST_521_TOP_MASK))))) - return (r == a)? 1 : (BN_copy(r ,a) != NULL); + int top = a->top, i; + BN_ULONG *r_d, *a_d = a->d, + t_d[BN_NIST_521_TOP], + val,tmp,*res; + size_t mask; + static const BIGNUM _bignum_nist_p_521_sqr = { + (BN_ULONG *)_nist_p_521_sqr, + sizeof(_nist_p_521_sqr)/sizeof(_nist_p_521_sqr[0]), + sizeof(_nist_p_521_sqr)/sizeof(_nist_p_521_sqr[0]), + 0,BN_FLG_STATIC_DATA }; - BN_CTX_start(ctx); - tmp = BN_CTX_get(ctx); - if (!tmp) - goto err; + field = &_bignum_nist_p_521; /* just to make sure */ - if (!bn_wexpand(tmp, BN_NIST_521_TOP)) - goto err; - nist_cp_bn(tmp->d, a->d, BN_NIST_521_TOP); + if (BN_is_negative(a) || BN_ucmp(a,&_bignum_nist_p_521_sqr)>=0) + return BN_nnmod(r, a, field, ctx); - tmp->top = BN_NIST_521_TOP; - tmp->d[BN_NIST_521_TOP-1] &= BN_NIST_521_TOP_MASK; - bn_correct_top(tmp); + i = BN_ucmp(field, a); + if (i == 0) + { + BN_zero(r); + return 1; + } + else if (i > 0) + return (r == a)? 1 : (BN_copy(r ,a) != NULL); - if (!BN_rshift(r, a, 521)) - goto err; + if (r != a) + { + if (!bn_wexpand(r,BN_NIST_521_TOP)) + return 0; + r_d = r->d; + nist_cp_bn(r_d,a_d, BN_NIST_521_TOP); + } + else + r_d = a_d; - if (!BN_uadd(r, tmp, r)) - goto err; - top = r->top; - r_d = r->d; - if (top == BN_NIST_521_TOP && - (r_d[BN_NIST_521_TOP-1] & ~(BN_NIST_521_TOP_MASK))) + /* upper 521 bits, copy ... */ + nist_cp_bn_0(t_d,a_d + (BN_NIST_521_TOP-1), top - (BN_NIST_521_TOP-1),BN_NIST_521_TOP); + /* ... and right shift */ + for (val=t_d[0],i=0; id[BN_NIST_521_TOP-1] &= BN_NIST_521_TOP_MASK; + tmp = val>>BN_NIST_521_RSHIFT; + val = t_d[i+1]; + t_d[i] = (tmp | val<>BN_NIST_521_RSHIFT; + /* lower 521 bits */ + r_d[i] &= BN_NIST_521_TOP_MASK; + + bn_add_words(r_d,r_d,t_d,BN_NIST_521_TOP); + mask = 0-(size_t)bn_sub_words(t_d,r_d,_nist_p_521,BN_NIST_521_TOP); + res = (BN_ULONG *)(((size_t)t_d&~mask) | ((size_t)r_d&mask)); + nist_cp_bn(r_d,res,BN_NIST_521_TOP); + r->top = BN_NIST_521_TOP; bn_correct_top(r); - ret = 1; -err: - BN_CTX_end(ctx); - - bn_check_top(r); - return ret; + return 1; } diff --git a/src/lib/libcrypto/bn/bn_rand.c b/src/lib/libcrypto/bn/bn_rand.c index f51830b12b..b376c28ff3 100644 --- a/src/lib/libcrypto/bn/bn_rand.c +++ b/src/lib/libcrypto/bn/bn_rand.c @@ -227,7 +227,7 @@ int BN_bntest_rand(BIGNUM *rnd, int bits, int top, int bottom) /* random number r: 0 <= r < range */ -static int bn_rand_range(int pseudo, BIGNUM *r, BIGNUM *range) +static int bn_rand_range(int pseudo, BIGNUM *r, const BIGNUM *range) { int (*bn_rand)(BIGNUM *, int, int, int) = pseudo ? BN_pseudo_rand : BN_rand; int n; @@ -294,12 +294,12 @@ static int bn_rand_range(int pseudo, BIGNUM *r, BIGNUM *range) } -int BN_rand_range(BIGNUM *r, BIGNUM *range) +int BN_rand_range(BIGNUM *r, const BIGNUM *range) { return bn_rand_range(0, r, range); } -int BN_pseudo_rand_range(BIGNUM *r, BIGNUM *range) +int BN_pseudo_rand_range(BIGNUM *r, const BIGNUM *range) { return bn_rand_range(1, r, range); } diff --git a/src/lib/libcrypto/bn/bn_shift.c b/src/lib/libcrypto/bn/bn_shift.c index de9312dce2..c4d301afc4 100644 --- a/src/lib/libcrypto/bn/bn_shift.c +++ b/src/lib/libcrypto/bn/bn_shift.c @@ -177,7 +177,7 @@ int BN_rshift(BIGNUM *r, const BIGNUM *a, int n) nw=n/BN_BITS2; rb=n%BN_BITS2; lb=BN_BITS2-rb; - if (nw > a->top || a->top == 0) + if (nw >= a->top || a->top == 0) { BN_zero(r); return(1); diff --git a/src/lib/libcrypto/bn/bn_x931p.c b/src/lib/libcrypto/bn/bn_x931p.c index c64410dd3a..04c5c874ec 100644 --- a/src/lib/libcrypto/bn/bn_x931p.c +++ b/src/lib/libcrypto/bn/bn_x931p.c @@ -1,5 +1,5 @@ /* bn_x931p.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 2005. */ /* ==================================================================== @@ -59,18 +59,15 @@ #include #include -#ifdef OPENSSL_FIPS - /* X9.31 routines for prime derivation */ - /* X9.31 prime derivation. This is used to generate the primes pi * (p1, p2, q1, q2) from a parameter Xpi by checking successive odd * integers. */ static int bn_x931_derive_pi(BIGNUM *pi, const BIGNUM *Xpi, BN_CTX *ctx, - void (*cb)(int, int, void *), void *cb_arg) + BN_GENCB *cb) { int i = 0; if (!BN_copy(pi, Xpi)) @@ -80,16 +77,14 @@ static int bn_x931_derive_pi(BIGNUM *pi, const BIGNUM *Xpi, BN_CTX *ctx, for(;;) { i++; - if (cb) - cb(0, i, cb_arg); + BN_GENCB_call(cb, 0, i); /* NB 27 MR is specificed in X9.31 */ - if (BN_is_prime_fasttest(pi, 27, cb, ctx, cb_arg, 1)) + if (BN_is_prime_fasttest_ex(pi, 27, ctx, 1, cb)) break; if (!BN_add_word(pi, 2)) return 0; } - if (cb) - cb(2, i, cb_arg); + BN_GENCB_call(cb, 2, i); return 1; } @@ -98,10 +93,9 @@ static int bn_x931_derive_pi(BIGNUM *pi, const BIGNUM *Xpi, BN_CTX *ctx, * not NULL they will be returned too: this is needed for testing. */ -int BN_X931_derive_prime(BIGNUM *p, BIGNUM *p1, BIGNUM *p2, - void (*cb)(int, int, void *), void *cb_arg, +int BN_X931_derive_prime_ex(BIGNUM *p, BIGNUM *p1, BIGNUM *p2, const BIGNUM *Xp, const BIGNUM *Xp1, const BIGNUM *Xp2, - const BIGNUM *e, BN_CTX *ctx) + const BIGNUM *e, BN_CTX *ctx, BN_GENCB *cb) { int ret = 0; @@ -124,10 +118,10 @@ int BN_X931_derive_prime(BIGNUM *p, BIGNUM *p1, BIGNUM *p2, pm1 = BN_CTX_get(ctx); - if (!bn_x931_derive_pi(p1, Xp1, ctx, cb, cb_arg)) + if (!bn_x931_derive_pi(p1, Xp1, ctx, cb)) goto err; - if (!bn_x931_derive_pi(p2, Xp2, ctx, cb, cb_arg)) + if (!bn_x931_derive_pi(p2, Xp2, ctx, cb)) goto err; if (!BN_mul(p1p2, p1, p2, ctx)) @@ -166,8 +160,7 @@ int BN_X931_derive_prime(BIGNUM *p, BIGNUM *p1, BIGNUM *p2, for (;;) { int i = 1; - if (cb) - cb(0, i++, cb_arg); + BN_GENCB_call(cb, 0, i++); if (!BN_copy(pm1, p)) goto err; if (!BN_sub_word(pm1, 1)) @@ -179,14 +172,13 @@ int BN_X931_derive_prime(BIGNUM *p, BIGNUM *p1, BIGNUM *p2, * offering similar or better guarantees 50 MR is considerably * better. */ - && BN_is_prime_fasttest(p, 50, cb, ctx, cb_arg, 1)) + && BN_is_prime_fasttest_ex(p, 50, ctx, 1, cb)) break; if (!BN_add(p, p, p1p2)) goto err; } - if (cb) - cb(3, 0, cb_arg); + BN_GENCB_call(cb, 3, 0); ret = 1; @@ -248,11 +240,11 @@ int BN_X931_generate_Xpq(BIGNUM *Xp, BIGNUM *Xq, int nbits, BN_CTX *ctx) * are generated using the previous function and supplied as input. */ -int BN_X931_generate_prime(BIGNUM *p, BIGNUM *p1, BIGNUM *p2, +int BN_X931_generate_prime_ex(BIGNUM *p, BIGNUM *p1, BIGNUM *p2, BIGNUM *Xp1, BIGNUM *Xp2, const BIGNUM *Xp, const BIGNUM *e, BN_CTX *ctx, - void (*cb)(int, int, void *), void *cb_arg) + BN_GENCB *cb) { int ret = 0; @@ -266,8 +258,7 @@ int BN_X931_generate_prime(BIGNUM *p, BIGNUM *p1, BIGNUM *p2, goto error; if (!BN_rand(Xp2, 101, 0, 0)) goto error; - if (!BN_X931_derive_prime(p, p1, p2, cb, cb_arg, - Xp, Xp1, Xp2, e, ctx)) + if (!BN_X931_derive_prime_ex(p, p1, p2, Xp, Xp1, Xp2, e, ctx, cb)) goto error; ret = 1; @@ -279,4 +270,3 @@ int BN_X931_generate_prime(BIGNUM *p, BIGNUM *p1, BIGNUM *p2, } -#endif diff --git a/src/lib/libcrypto/buffer/buf_str.c b/src/lib/libcrypto/buffer/buf_str.c new file mode 100644 index 0000000000..28dd1e401e --- /dev/null +++ b/src/lib/libcrypto/buffer/buf_str.c @@ -0,0 +1,116 @@ +/* crypto/buffer/buf_str.c */ +/* ==================================================================== + * Copyright (c) 2007 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include "cryptlib.h" +#include + +char *BUF_strdup(const char *str) + { + if (str == NULL) return(NULL); + return BUF_strndup(str, strlen(str)); + } + +char *BUF_strndup(const char *str, size_t siz) + { + char *ret; + + if (str == NULL) return(NULL); + + ret=OPENSSL_malloc(siz+1); + if (ret == NULL) + { + BUFerr(BUF_F_BUF_STRNDUP,ERR_R_MALLOC_FAILURE); + return(NULL); + } + BUF_strlcpy(ret,str,siz+1); + return(ret); + } + +void *BUF_memdup(const void *data, size_t siz) + { + void *ret; + + if (data == NULL) return(NULL); + + ret=OPENSSL_malloc(siz); + if (ret == NULL) + { + BUFerr(BUF_F_BUF_MEMDUP,ERR_R_MALLOC_FAILURE); + return(NULL); + } + return memcpy(ret, data, siz); + } + +size_t BUF_strlcpy(char *dst, const char *src, size_t size) + { + size_t l = 0; + for(; size > 1 && *src; size--) + { + *dst++ = *src++; + l++; + } + if (size) + *dst = '\0'; + return l + strlen(src); + } + +size_t BUF_strlcat(char *dst, const char *src, size_t size) + { + size_t l = 0; + for(; size > 0 && *dst; size--, dst++) + l++; + return l + BUF_strlcpy(dst, src, size); + } diff --git a/src/lib/libcrypto/buffer/buffer.c b/src/lib/libcrypto/buffer/buffer.c index 3bf03c7eff..b3e947771d 100644 --- a/src/lib/libcrypto/buffer/buffer.c +++ b/src/lib/libcrypto/buffer/buffer.c @@ -161,61 +161,3 @@ int BUF_MEM_grow_clean(BUF_MEM *str, int len) } return(len); } - -char *BUF_strdup(const char *str) - { - if (str == NULL) return(NULL); - return BUF_strndup(str, strlen(str)); - } - -char *BUF_strndup(const char *str, size_t siz) - { - char *ret; - - if (str == NULL) return(NULL); - - ret=OPENSSL_malloc(siz+1); - if (ret == NULL) - { - BUFerr(BUF_F_BUF_STRNDUP,ERR_R_MALLOC_FAILURE); - return(NULL); - } - BUF_strlcpy(ret,str,siz+1); - return(ret); - } - -void *BUF_memdup(const void *data, size_t siz) - { - void *ret; - - if (data == NULL) return(NULL); - - ret=OPENSSL_malloc(siz); - if (ret == NULL) - { - BUFerr(BUF_F_BUF_MEMDUP,ERR_R_MALLOC_FAILURE); - return(NULL); - } - return memcpy(ret, data, siz); - } - -size_t BUF_strlcpy(char *dst, const char *src, size_t size) - { - size_t l = 0; - for(; size > 1 && *src; size--) - { - *dst++ = *src++; - l++; - } - if (size) - *dst = '\0'; - return l + strlen(src); - } - -size_t BUF_strlcat(char *dst, const char *src, size_t size) - { - size_t l = 0; - for(; size > 0 && *dst; size--, dst++) - l++; - return l + BUF_strlcpy(dst, src, size); - } diff --git a/src/lib/libcrypto/camellia/camellia.h b/src/lib/libcrypto/camellia/camellia.h index 3c8a359543..b8a8b6e10b 100644 --- a/src/lib/libcrypto/camellia/camellia.h +++ b/src/lib/libcrypto/camellia/camellia.h @@ -87,6 +87,11 @@ struct camellia_key_st typedef struct camellia_key_st CAMELLIA_KEY; +#ifdef OPENSSL_FIPS +int private_Camellia_set_key(const unsigned char *userKey, const int bits, + CAMELLIA_KEY *key); +#endif + int Camellia_set_key(const unsigned char *userKey, const int bits, CAMELLIA_KEY *key); diff --git a/src/lib/libcrypto/camellia/cmll_misc.c b/src/lib/libcrypto/camellia/cmll_misc.c index f1047b54e0..2cd7aba9bb 100644 --- a/src/lib/libcrypto/camellia/cmll_misc.c +++ b/src/lib/libcrypto/camellia/cmll_misc.c @@ -52,11 +52,24 @@ #include #include #include "cmll_locl.h" +#include +#ifdef OPENSSL_FIPS +#include +#endif const char CAMELLIA_version[]="CAMELLIA" OPENSSL_VERSION_PTEXT; int Camellia_set_key(const unsigned char *userKey, const int bits, CAMELLIA_KEY *key) +#ifdef OPENSSL_FIPS + { + if (FIPS_mode()) + FIPS_BAD_ABORT(CAMELLIA) + return private_Camellia_set_key(userKey, bits, key); + } +int private_Camellia_set_key(const unsigned char *userKey, const int bits, + CAMELLIA_KEY *key) +#endif { if (!userKey || !key) { diff --git a/src/lib/libcrypto/cast/c_skey.c b/src/lib/libcrypto/cast/c_skey.c index 76e40005c9..68e690a60c 100644 --- a/src/lib/libcrypto/cast/c_skey.c +++ b/src/lib/libcrypto/cast/c_skey.c @@ -57,6 +57,11 @@ */ #include +#include +#ifdef OPENSSL_FIPS +#include +#endif + #include "cast_lcl.h" #include "cast_s.h" @@ -72,7 +77,7 @@ #define S6 CAST_S_table6 #define S7 CAST_S_table7 -void CAST_set_key(CAST_KEY *key, int len, const unsigned char *data) +FIPS_NON_FIPS_VCIPHER_Init(CAST) { CAST_LONG x[16]; CAST_LONG z[16]; diff --git a/src/lib/libcrypto/cast/cast.h b/src/lib/libcrypto/cast/cast.h index 90b45b950a..1faf5806aa 100644 --- a/src/lib/libcrypto/cast/cast.h +++ b/src/lib/libcrypto/cast/cast.h @@ -83,7 +83,9 @@ typedef struct cast_key_st int short_key; /* Use reduced rounds for short key */ } CAST_KEY; - +#ifdef OPENSSL_FIPS +void private_CAST_set_key(CAST_KEY *key, int len, const unsigned char *data); +#endif void CAST_set_key(CAST_KEY *key, int len, const unsigned char *data); void CAST_ecb_encrypt(const unsigned char *in,unsigned char *out,CAST_KEY *key, int enc); diff --git a/src/lib/libcrypto/cms/cms_sd.c b/src/lib/libcrypto/cms/cms_sd.c index 591bfbec33..cdac3b870d 100644 --- a/src/lib/libcrypto/cms/cms_sd.c +++ b/src/lib/libcrypto/cms/cms_sd.c @@ -830,7 +830,7 @@ int CMS_SignerInfo_verify(CMS_SignerInfo *si) cms_fixup_mctx(&mctx, si->pkey); r = EVP_VerifyFinal(&mctx, si->signature->data, si->signature->length, si->pkey); - if (!r) + if (r <= 0) CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY, CMS_R_VERIFICATION_FAILURE); err: EVP_MD_CTX_cleanup(&mctx); diff --git a/src/lib/libcrypto/cms/cms_smime.c b/src/lib/libcrypto/cms/cms_smime.c index f79c504e91..b9463f9abb 100644 --- a/src/lib/libcrypto/cms/cms_smime.c +++ b/src/lib/libcrypto/cms/cms_smime.c @@ -68,7 +68,10 @@ static int cms_copy_content(BIO *out, BIO *in, unsigned int flags) if (out == NULL) tmpout = BIO_new(BIO_s_null()); else if (flags & CMS_TEXT) + { tmpout = BIO_new(BIO_s_mem()); + BIO_set_mem_eof_return(tmpout, 0); + } else tmpout = out; @@ -89,11 +92,13 @@ static int cms_copy_content(BIO *out, BIO *in, unsigned int flags) if (!BIO_get_cipher_status(in)) goto err; } + if (i < 0) + goto err; break; } - if (tmpout) - BIO_write(tmpout, buf, i); + if (tmpout && (BIO_write(tmpout, buf, i) != i)) + goto err; } if(flags & CMS_TEXT) diff --git a/src/lib/libcrypto/comp/c_zlib.c b/src/lib/libcrypto/comp/c_zlib.c index 0f34597e70..eccfd09137 100644 --- a/src/lib/libcrypto/comp/c_zlib.c +++ b/src/lib/libcrypto/comp/c_zlib.c @@ -727,6 +727,7 @@ static long bio_zlib_ctrl(BIO *b, int cmd, long num, void *ptr) case BIO_CTRL_RESET: ctx->ocount = 0; ctx->odone = 0; + ret = 1; break; case BIO_CTRL_FLUSH: @@ -771,7 +772,7 @@ static long bio_zlib_ctrl(BIO *b, int cmd, long num, void *ptr) } ctx->obufsize = obs; } - + ret = 1; break; case BIO_C_DO_STATE_MACHINE: @@ -783,7 +784,6 @@ static long bio_zlib_ctrl(BIO *b, int cmd, long num, void *ptr) default: ret = BIO_ctrl(b->next_bio, cmd, num, ptr); break; - } return ret; diff --git a/src/lib/libcrypto/conf/conf_mall.c b/src/lib/libcrypto/conf/conf_mall.c index 4ba40cf44c..1cc1fd5534 100644 --- a/src/lib/libcrypto/conf/conf_mall.c +++ b/src/lib/libcrypto/conf/conf_mall.c @@ -1,5 +1,5 @@ /* conf_mall.c */ -/* Written by Stephen Henson (shenson@bigfoot.com) for the OpenSSL +/* Written by Stephen Henson (steve@openssl.org) for the OpenSSL * project 2001. */ /* ==================================================================== @@ -63,6 +63,7 @@ #include #include #include +#include #ifndef OPENSSL_NO_ENGINE #include #endif @@ -76,5 +77,6 @@ void OPENSSL_load_builtin_modules(void) #ifndef OPENSSL_NO_ENGINE ENGINE_add_conf_module(); #endif + EVP_add_alg_module(); } diff --git a/src/lib/libcrypto/conf/conf_mod.c b/src/lib/libcrypto/conf/conf_mod.c index 628e8333a6..ee9c677d9b 100644 --- a/src/lib/libcrypto/conf/conf_mod.c +++ b/src/lib/libcrypto/conf/conf_mod.c @@ -1,5 +1,5 @@ /* conf_mod.c */ -/* Written by Stephen Henson (shenson@bigfoot.com) for the OpenSSL +/* Written by Stephen Henson (steve@openssl.org) for the OpenSSL * project 2001. */ /* ==================================================================== diff --git a/src/lib/libcrypto/conf/conf_sap.c b/src/lib/libcrypto/conf/conf_sap.c index 9c53bac1a8..760dc2632d 100644 --- a/src/lib/libcrypto/conf/conf_sap.c +++ b/src/lib/libcrypto/conf/conf_sap.c @@ -1,5 +1,5 @@ /* conf_sap.c */ -/* Written by Stephen Henson (shenson@bigfoot.com) for the OpenSSL +/* Written by Stephen Henson (steve@openssl.org) for the OpenSSL * project 2001. */ /* ==================================================================== diff --git a/src/lib/libcrypto/cryptlib.c b/src/lib/libcrypto/cryptlib.c index 8c68623828..8f9e88e403 100644 --- a/src/lib/libcrypto/cryptlib.c +++ b/src/lib/libcrypto/cryptlib.c @@ -121,275 +121,17 @@ static double SSLeay_MSVC5_hack=0.0; /* and for VC1.5 */ #endif -DECLARE_STACK_OF(CRYPTO_dynlock) -IMPLEMENT_STACK_OF(CRYPTO_dynlock) - -/* real #defines in crypto.h, keep these upto date */ -static const char* const lock_names[CRYPTO_NUM_LOCKS] = - { - "<>", - "err", - "ex_data", - "x509", - "x509_info", - "x509_pkey", - "x509_crl", - "x509_req", - "dsa", - "rsa", - "evp_pkey", - "x509_store", - "ssl_ctx", - "ssl_cert", - "ssl_session", - "ssl_sess_cert", - "ssl", - "ssl_method", - "rand", - "rand2", - "debug_malloc", - "BIO", - "gethostbyname", - "getservbyname", - "readdir", - "RSA_blinding", - "dh", - "debug_malloc2", - "dso", - "dynlock", - "engine", - "ui", - "ecdsa", - "ec", - "ecdh", - "bn", - "ec_pre_comp", - "store", - "comp", -#if CRYPTO_NUM_LOCKS != 39 -# error "Inconsistency between crypto.h and cryptlib.c" -#endif - }; - -/* This is for applications to allocate new type names in the non-dynamic - array of lock names. These are numbered with positive numbers. */ -static STACK *app_locks=NULL; - -/* For applications that want a more dynamic way of handling threads, the - following stack is used. These are externally numbered with negative - numbers. */ -static STACK_OF(CRYPTO_dynlock) *dyn_locks=NULL; - - static void (MS_FAR *locking_callback)(int mode,int type, const char *file,int line)=NULL; static int (MS_FAR *add_lock_callback)(int *pointer,int amount, int type,const char *file,int line)=NULL; static unsigned long (MS_FAR *id_callback)(void)=NULL; -static struct CRYPTO_dynlock_value *(MS_FAR *dynlock_create_callback) - (const char *file,int line)=NULL; -static void (MS_FAR *dynlock_lock_callback)(int mode, - struct CRYPTO_dynlock_value *l, const char *file,int line)=NULL; -static void (MS_FAR *dynlock_destroy_callback)(struct CRYPTO_dynlock_value *l, - const char *file,int line)=NULL; - -int CRYPTO_get_new_lockid(char *name) - { - char *str; - int i; - -#if defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_WIN16) - /* A hack to make Visual C++ 5.0 work correctly when linking as - * a DLL using /MT. Without this, the application cannot use - * and floating point printf's. - * It also seems to be needed for Visual C 1.5 (win16) */ - SSLeay_MSVC5_hack=(double)name[0]*(double)name[1]; -#endif - - if ((app_locks == NULL) && ((app_locks=sk_new_null()) == NULL)) - { - CRYPTOerr(CRYPTO_F_CRYPTO_GET_NEW_LOCKID,ERR_R_MALLOC_FAILURE); - return(0); - } - if ((str=BUF_strdup(name)) == NULL) - { - CRYPTOerr(CRYPTO_F_CRYPTO_GET_NEW_LOCKID,ERR_R_MALLOC_FAILURE); - return(0); - } - i=sk_push(app_locks,str); - if (!i) - OPENSSL_free(str); - else - i+=CRYPTO_NUM_LOCKS; /* gap of one :-) */ - return(i); - } int CRYPTO_num_locks(void) { return CRYPTO_NUM_LOCKS; } -int CRYPTO_get_new_dynlockid(void) - { - int i = 0; - CRYPTO_dynlock *pointer = NULL; - - if (dynlock_create_callback == NULL) - { - CRYPTOerr(CRYPTO_F_CRYPTO_GET_NEW_DYNLOCKID,CRYPTO_R_NO_DYNLOCK_CREATE_CALLBACK); - return(0); - } - CRYPTO_w_lock(CRYPTO_LOCK_DYNLOCK); - if ((dyn_locks == NULL) - && ((dyn_locks=sk_CRYPTO_dynlock_new_null()) == NULL)) - { - CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK); - CRYPTOerr(CRYPTO_F_CRYPTO_GET_NEW_DYNLOCKID,ERR_R_MALLOC_FAILURE); - return(0); - } - CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK); - - pointer = (CRYPTO_dynlock *)OPENSSL_malloc(sizeof(CRYPTO_dynlock)); - if (pointer == NULL) - { - CRYPTOerr(CRYPTO_F_CRYPTO_GET_NEW_DYNLOCKID,ERR_R_MALLOC_FAILURE); - return(0); - } - pointer->references = 1; - pointer->data = dynlock_create_callback(__FILE__,__LINE__); - if (pointer->data == NULL) - { - OPENSSL_free(pointer); - CRYPTOerr(CRYPTO_F_CRYPTO_GET_NEW_DYNLOCKID,ERR_R_MALLOC_FAILURE); - return(0); - } - - CRYPTO_w_lock(CRYPTO_LOCK_DYNLOCK); - /* First, try to find an existing empty slot */ - i=sk_CRYPTO_dynlock_find(dyn_locks,NULL); - /* If there was none, push, thereby creating a new one */ - if (i == -1) - /* Since sk_push() returns the number of items on the - stack, not the location of the pushed item, we need - to transform the returned number into a position, - by decreasing it. */ - i=sk_CRYPTO_dynlock_push(dyn_locks,pointer) - 1; - else - /* If we found a place with a NULL pointer, put our pointer - in it. */ - (void)sk_CRYPTO_dynlock_set(dyn_locks,i,pointer); - CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK); - - if (i == -1) - { - dynlock_destroy_callback(pointer->data,__FILE__,__LINE__); - OPENSSL_free(pointer); - } - else - i += 1; /* to avoid 0 */ - return -i; - } - -void CRYPTO_destroy_dynlockid(int i) - { - CRYPTO_dynlock *pointer = NULL; - if (i) - i = -i-1; - if (dynlock_destroy_callback == NULL) - return; - - CRYPTO_w_lock(CRYPTO_LOCK_DYNLOCK); - - if (dyn_locks == NULL || i >= sk_CRYPTO_dynlock_num(dyn_locks)) - { - CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK); - return; - } - pointer = sk_CRYPTO_dynlock_value(dyn_locks, i); - if (pointer != NULL) - { - --pointer->references; -#ifdef REF_CHECK - if (pointer->references < 0) - { - fprintf(stderr,"CRYPTO_destroy_dynlockid, bad reference count\n"); - abort(); - } - else -#endif - if (pointer->references <= 0) - { - (void)sk_CRYPTO_dynlock_set(dyn_locks, i, NULL); - } - else - pointer = NULL; - } - CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK); - - if (pointer) - { - dynlock_destroy_callback(pointer->data,__FILE__,__LINE__); - OPENSSL_free(pointer); - } - } - -struct CRYPTO_dynlock_value *CRYPTO_get_dynlock_value(int i) - { - CRYPTO_dynlock *pointer = NULL; - if (i) - i = -i-1; - - CRYPTO_w_lock(CRYPTO_LOCK_DYNLOCK); - - if (dyn_locks != NULL && i < sk_CRYPTO_dynlock_num(dyn_locks)) - pointer = sk_CRYPTO_dynlock_value(dyn_locks, i); - if (pointer) - pointer->references++; - - CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK); - - if (pointer) - return pointer->data; - return NULL; - } - -struct CRYPTO_dynlock_value *(*CRYPTO_get_dynlock_create_callback(void)) - (const char *file,int line) - { - return(dynlock_create_callback); - } - -void (*CRYPTO_get_dynlock_lock_callback(void))(int mode, - struct CRYPTO_dynlock_value *l, const char *file,int line) - { - return(dynlock_lock_callback); - } - -void (*CRYPTO_get_dynlock_destroy_callback(void)) - (struct CRYPTO_dynlock_value *l, const char *file,int line) - { - return(dynlock_destroy_callback); - } - -void CRYPTO_set_dynlock_create_callback(struct CRYPTO_dynlock_value *(*func) - (const char *file, int line)) - { - dynlock_create_callback=func; - } - -void CRYPTO_set_dynlock_lock_callback(void (*func)(int mode, - struct CRYPTO_dynlock_value *l, const char *file, int line)) - { - dynlock_lock_callback=func; - } - -void CRYPTO_set_dynlock_destroy_callback(void (*func) - (struct CRYPTO_dynlock_value *l, const char *file, int line)) - { - dynlock_destroy_callback=func; - } - - void (*CRYPTO_get_locking_callback(void))(int mode,int type,const char *file, int line) { @@ -445,6 +187,14 @@ unsigned long CRYPTO_thread_id(void) return(ret); } +static void (*do_dynlock_cb)(int mode, int type, const char *file, int line); + +void int_CRYPTO_set_do_dynlock_callback( + void (*dyn_cb)(int mode, int type, const char *file, int line)) + { + do_dynlock_cb = dyn_cb; + } + void CRYPTO_lock(int mode, int type, const char *file, int line) { #ifdef LOCK_DEBUG @@ -472,17 +222,8 @@ void CRYPTO_lock(int mode, int type, const char *file, int line) #endif if (type < 0) { - if (dynlock_lock_callback != NULL) - { - struct CRYPTO_dynlock_value *pointer - = CRYPTO_get_dynlock_value(type); - - OPENSSL_assert(pointer != NULL); - - dynlock_lock_callback(mode, pointer, file, line); - - CRYPTO_destroy_dynlockid(type); - } + if (do_dynlock_cb) + do_dynlock_cb(mode, type, file, line); } else if (locking_callback != NULL) @@ -527,21 +268,9 @@ int CRYPTO_add_lock(int *pointer, int amount, int type, const char *file, return(ret); } -const char *CRYPTO_get_lock_name(int type) - { - if (type < 0) - return("dynamic"); - else if (type < CRYPTO_NUM_LOCKS) - return(lock_names[type]); - else if (type-CRYPTO_NUM_LOCKS > sk_num(app_locks)) - return("ERROR"); - else - return(sk_value(app_locks,type-CRYPTO_NUM_LOCKS)); - } - #if defined(__i386) || defined(__i386__) || defined(_M_IX86) || \ defined(__INTEL__) || \ - defined(__x86_64) || defined(__x86_64__) || defined(_M_AMD64) + defined(__x86_64) || defined(__x86_64__) || defined(_M_AMD64) || defined(_M_X64) unsigned long OPENSSL_ia32cap_P=0; unsigned long *OPENSSL_ia32cap_loc(void) { return &OPENSSL_ia32cap_P; } @@ -577,6 +306,62 @@ void OPENSSL_cpuid_setup(void) {} #endif #if (defined(_WIN32) || defined(__CYGWIN__)) && defined(_WINDLL) + +#ifdef OPENSSL_FIPS + +#include +#if defined(__GNUC__) && __GNUC__>=2 +static int DllInit(void) __attribute__((constructor)); +#elif defined(_MSC_VER) +static int DllInit(void); +# ifdef _WIN64 +# pragma section(".CRT$XCU",read) + __declspec(allocate(".CRT$XCU")) +# else +# pragma data_seg(".CRT$XCU") +# endif + static int (*p)(void) = DllInit; +# pragma data_seg() +#endif + +static int DllInit(void) +{ +#if defined(_WIN32_WINNT) + union { int(*f)(void); BYTE *p; } t = { DllInit }; + HANDLE hModuleSnap = INVALID_HANDLE_VALUE; + IMAGE_DOS_HEADER *dos_header; + IMAGE_NT_HEADERS *nt_headers; + MODULEENTRY32 me32 = {sizeof(me32)}; + + hModuleSnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE,0); + if (hModuleSnap != INVALID_HANDLE_VALUE && + Module32First(hModuleSnap,&me32)) do + { + if (t.p >= me32.modBaseAddr && + t.p < me32.modBaseAddr+me32.modBaseSize) + { + dos_header=(IMAGE_DOS_HEADER *)me32.modBaseAddr; + if (dos_header->e_magic==IMAGE_DOS_SIGNATURE) + { + nt_headers=(IMAGE_NT_HEADERS *) + ((BYTE *)dos_header+dos_header->e_lfanew); + if (nt_headers->Signature==IMAGE_NT_SIGNATURE && + me32.modBaseAddr!=(BYTE*)nt_headers->OptionalHeader.ImageBase) + OPENSSL_NONPIC_relocated=1; + } + break; + } + } while (Module32Next(hModuleSnap,&me32)); + + if (hModuleSnap != INVALID_HANDLE_VALUE) + CloseHandle(hModuleSnap); +#endif + OPENSSL_cpuid_setup(); + return 0; +} + +#else + #ifdef __CYGWIN__ /* pick DLL_[PROCESS|THREAD]_[ATTACH|DETACH] definitions */ #include @@ -620,6 +405,8 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, } #endif +#endif + #if defined(_WIN32) && !defined(__CYGWIN__) #include diff --git a/src/lib/libcrypto/cryptlib.h b/src/lib/libcrypto/cryptlib.h index 5ceaa964b5..fc249c57f3 100644 --- a/src/lib/libcrypto/cryptlib.h +++ b/src/lib/libcrypto/cryptlib.h @@ -103,7 +103,6 @@ extern unsigned long OPENSSL_ia32cap_P; void OPENSSL_showfatal(const char *,...); void *OPENSSL_stderr(void); extern int OPENSSL_NONPIC_relocated; -int OPENSSL_isservice(void); #ifdef __cplusplus } diff --git a/src/lib/libcrypto/crypto.h b/src/lib/libcrypto/crypto.h index d2b5ffe332..0e4fb0723c 100644 --- a/src/lib/libcrypto/crypto.h +++ b/src/lib/libcrypto/crypto.h @@ -219,7 +219,13 @@ typedef struct openssl_item_st #define CRYPTO_LOCK_EC_PRE_COMP 36 #define CRYPTO_LOCK_STORE 37 #define CRYPTO_LOCK_COMP 38 +#ifndef OPENSSL_FIPS #define CRYPTO_NUM_LOCKS 39 +#else +#define CRYPTO_LOCK_FIPS 39 +#define CRYPTO_LOCK_FIPS2 40 +#define CRYPTO_NUM_LOCKS 41 +#endif #define CRYPTO_LOCK 1 #define CRYPTO_UNLOCK 2 @@ -341,14 +347,7 @@ DECLARE_STACK_OF(CRYPTO_EX_DATA_FUNCS) /* Set standard debugging functions (not done by default * unless CRYPTO_MDEBUG is defined) */ -#define CRYPTO_malloc_debug_init() do {\ - CRYPTO_set_mem_debug_functions(\ - CRYPTO_dbg_malloc,\ - CRYPTO_dbg_realloc,\ - CRYPTO_dbg_free,\ - CRYPTO_dbg_set_options,\ - CRYPTO_dbg_get_options);\ - } while(0) +void CRYPTO_malloc_debug_init(void); int CRYPTO_mem_ctrl(int mode); int CRYPTO_is_mem_check_on(void); @@ -363,6 +362,7 @@ int CRYPTO_is_mem_check_on(void); #define is_MemCheck_on() CRYPTO_is_mem_check_on() #define OPENSSL_malloc(num) CRYPTO_malloc((int)num,__FILE__,__LINE__) +#define OPENSSL_strdup(str) CRYPTO_strdup((str),__FILE__,__LINE__) #define OPENSSL_realloc(addr,num) \ CRYPTO_realloc((char *)addr,(int)num,__FILE__,__LINE__) #define OPENSSL_realloc_clean(addr,old_num,num) \ @@ -427,6 +427,9 @@ const char *CRYPTO_get_lock_name(int type); int CRYPTO_add_lock(int *pointer,int amount,int type, const char *file, int line); +void int_CRYPTO_set_do_dynlock_callback( + void (*do_dynlock_cb)(int mode, int type, const char *file, int line)); + int CRYPTO_get_new_dynlockid(void); void CRYPTO_destroy_dynlockid(int i); struct CRYPTO_dynlock_value *CRYPTO_get_dynlock_value(int i); @@ -451,6 +454,10 @@ int CRYPTO_set_mem_debug_functions(void (*m)(void *,int,const char *,int,int), void (*f)(void *,int), void (*so)(long), long (*go)(void)); +void CRYPTO_set_mem_info_functions( + int (*push_info_fn)(const char *info, const char *file, int line), + int (*pop_info_fn)(void), + int (*remove_all_info_fn)(void)); void CRYPTO_get_mem_functions(void *(**m)(size_t),void *(**r)(void *, size_t), void (**f)(void *)); void CRYPTO_get_locked_mem_functions(void *(**m)(size_t), void (**f)(void *)); void CRYPTO_get_mem_ex_functions(void *(**m)(size_t,const char *,int), @@ -467,6 +474,7 @@ void CRYPTO_get_mem_debug_functions(void (**m)(void *,int,const char *,int,int), void *CRYPTO_malloc_locked(int num, const char *file, int line); void CRYPTO_free_locked(void *); void *CRYPTO_malloc(int num, const char *file, int line); +char *CRYPTO_strdup(const char *str, const char *file, int line); void CRYPTO_free(void *); void *CRYPTO_realloc(void *addr,int num, const char *file, int line); void *CRYPTO_realloc_clean(void *addr,int old_num,int num,const char *file, @@ -506,6 +514,9 @@ void CRYPTO_dbg_free(void *addr,int before_p); void CRYPTO_dbg_set_options(long bits); long CRYPTO_dbg_get_options(void); +int CRYPTO_dbg_push_info(const char *info, const char *file, int line); +int CRYPTO_dbg_pop_info(void); +int CRYPTO_dbg_remove_all_info(void); #ifndef OPENSSL_NO_FP_API void CRYPTO_mem_leaks_fp(FILE *); @@ -521,6 +532,61 @@ void OpenSSLDie(const char *file,int line,const char *assertion); unsigned long *OPENSSL_ia32cap_loc(void); #define OPENSSL_ia32cap (*(OPENSSL_ia32cap_loc())) +int OPENSSL_isservice(void); + +#ifdef OPENSSL_FIPS +#define FIPS_ERROR_IGNORED(alg) OpenSSLDie(__FILE__, __LINE__, \ + alg " previous FIPS forbidden algorithm error ignored"); + +#define FIPS_BAD_ABORT(alg) OpenSSLDie(__FILE__, __LINE__, \ + #alg " Algorithm forbidden in FIPS mode"); + +#ifdef OPENSSL_FIPS_STRICT +#define FIPS_BAD_ALGORITHM(alg) FIPS_BAD_ABORT(alg) +#else +#define FIPS_BAD_ALGORITHM(alg) \ + { \ + FIPSerr(FIPS_F_HASH_FINAL,FIPS_R_NON_FIPS_METHOD); \ + ERR_add_error_data(2, "Algorithm=", #alg); \ + return 0; \ + } +#endif + +/* Low level digest API blocking macro */ + +#define FIPS_NON_FIPS_MD_Init(alg) \ + int alg##_Init(alg##_CTX *c) \ + { \ + if (FIPS_mode()) \ + FIPS_BAD_ALGORITHM(alg) \ + return private_##alg##_Init(c); \ + } \ + int private_##alg##_Init(alg##_CTX *c) + +/* For ciphers the API often varies from cipher to cipher and each needs to + * be treated as a special case. Variable key length ciphers (Blowfish, RC4, + * CAST) however are very similar and can use a blocking macro. + */ + +#define FIPS_NON_FIPS_VCIPHER_Init(alg) \ + void alg##_set_key(alg##_KEY *key, int len, const unsigned char *data) \ + { \ + if (FIPS_mode()) \ + FIPS_BAD_ABORT(alg) \ + private_##alg##_set_key(key, len, data); \ + } \ + void private_##alg##_set_key(alg##_KEY *key, int len, \ + const unsigned char *data) + +#else + +#define FIPS_NON_FIPS_VCIPHER_Init(alg) \ + void alg##_set_key(alg##_KEY *key, int len, const unsigned char *data) + +#define FIPS_NON_FIPS_MD_Init(alg) \ + int alg##_Init(alg##_CTX *c) + +#endif /* def OPENSSL_FIPS */ /* BEGIN ERROR CODES */ /* The following lines are auto generated by the script mkerr.pl. Any changes @@ -528,6 +594,9 @@ unsigned long *OPENSSL_ia32cap_loc(void); */ void ERR_load_CRYPTO_strings(void); +#define OPENSSL_HAVE_INIT 1 +void OPENSSL_init(void); + /* Error codes for the CRYPTO functions. */ /* Function codes. */ diff --git a/src/lib/libcrypto/des/des_enc.c b/src/lib/libcrypto/des/des_enc.c index 1c37ab96d3..cf71965aca 100644 --- a/src/lib/libcrypto/des/des_enc.c +++ b/src/lib/libcrypto/des/des_enc.c @@ -289,6 +289,8 @@ void DES_decrypt3(DES_LONG *data, DES_key_schedule *ks1, #ifndef DES_DEFAULT_OPTIONS +#if !defined(OPENSSL_FIPS_DES_ASM) + #undef CBC_ENC_C__DONT_UPDATE_IV #include "ncbc_enc.c" /* DES_ncbc_encrypt */ @@ -404,4 +406,6 @@ void DES_ede3_cbc_encrypt(const unsigned char *input, unsigned char *output, tin[0]=tin[1]=0; } +#endif + #endif /* DES_DEFAULT_OPTIONS */ diff --git a/src/lib/libcrypto/des/ecb_enc.c b/src/lib/libcrypto/des/ecb_enc.c index 00d5b91e8c..75ae6cf8bb 100644 --- a/src/lib/libcrypto/des/ecb_enc.c +++ b/src/lib/libcrypto/des/ecb_enc.c @@ -57,54 +57,7 @@ */ #include "des_locl.h" -#include "des_ver.h" #include "spr.h" -#include -#include - -OPENSSL_GLOBAL const char libdes_version[]="libdes" OPENSSL_VERSION_PTEXT; -OPENSSL_GLOBAL const char DES_version[]="DES" OPENSSL_VERSION_PTEXT; - -const char *DES_options(void) - { - static int init=1; - static char buf[32]; - - if (init) - { - const char *ptr,*unroll,*risc,*size; - -#ifdef DES_PTR - ptr="ptr"; -#else - ptr="idx"; -#endif -#if defined(DES_RISC1) || defined(DES_RISC2) -#ifdef DES_RISC1 - risc="risc1"; -#endif -#ifdef DES_RISC2 - risc="risc2"; -#endif -#else - risc="cisc"; -#endif -#ifdef DES_UNROLL - unroll="16"; -#else - unroll="4"; -#endif - if (sizeof(DES_LONG) != sizeof(long)) - size="int"; - else - size="long"; - BIO_snprintf(buf,sizeof buf,"des(%s,%s,%s,%s)",ptr,risc,unroll, - size); - init=0; - } - return(buf); - } - void DES_ecb_encrypt(const_DES_cblock *input, DES_cblock *output, DES_key_schedule *ks, int enc) diff --git a/src/lib/libcrypto/des/enc_read.c b/src/lib/libcrypto/des/enc_read.c index c70fb686b8..e7da2ec66b 100644 --- a/src/lib/libcrypto/des/enc_read.c +++ b/src/lib/libcrypto/des/enc_read.c @@ -147,7 +147,11 @@ int DES_enc_read(int fd, void *buf, int len, DES_key_schedule *sched, /* first - get the length */ while (net_num < HDRSIZE) { +#ifndef _WIN32 i=read(fd,(void *)&(net[net_num]),HDRSIZE-net_num); +#else + i=_read(fd,(void *)&(net[net_num]),HDRSIZE-net_num); +#endif #ifdef EINTR if ((i == -1) && (errno == EINTR)) continue; #endif diff --git a/src/lib/libcrypto/des/enc_writ.c b/src/lib/libcrypto/des/enc_writ.c index af5b8c2349..c2f032c9a6 100644 --- a/src/lib/libcrypto/des/enc_writ.c +++ b/src/lib/libcrypto/des/enc_writ.c @@ -153,7 +153,11 @@ int DES_enc_write(int fd, const void *_buf, int len, { /* eay 26/08/92 I was not doing writing from where we * got up to. */ +#ifndef _WIN32 i=write(fd,(void *)&(outbuf[j]),outnum-j); +#else + i=_write(fd,(void *)&(outbuf[j]),outnum-j); +#endif if (i == -1) { #ifdef EINTR diff --git a/src/lib/libcrypto/des/set_key.c b/src/lib/libcrypto/des/set_key.c index a43ef3c881..c0806d593c 100644 --- a/src/lib/libcrypto/des/set_key.c +++ b/src/lib/libcrypto/des/set_key.c @@ -64,6 +64,10 @@ * 1.0 First working version */ #include "des_locl.h" +#ifdef OPENSSL_FIPS +#include +#endif + OPENSSL_IMPLEMENT_GLOBAL(int,DES_check_key); /* defaults to false */ @@ -349,6 +353,10 @@ void DES_set_key_unchecked(const_DES_cblock *key, DES_key_schedule *schedule) k = &schedule->ks->deslong[0]; in = &(*key)[0]; +#ifdef OPENSSL_FIPS + FIPS_selftest_check(); +#endif + c2l(in,c); c2l(in,d); @@ -405,3 +413,4 @@ void des_fixup_key_parity(des_cblock *key) des_set_odd_parity(key); } */ + diff --git a/src/lib/libcrypto/dh/dh.h b/src/lib/libcrypto/dh/dh.h index ccdf35ae1c..10475ac4b3 100644 --- a/src/lib/libcrypto/dh/dh.h +++ b/src/lib/libcrypto/dh/dh.h @@ -77,6 +77,8 @@ # define OPENSSL_DH_MAX_MODULUS_BITS 10000 #endif +#define OPENSSL_DH_FIPS_MIN_MODULUS_BITS 1024 + #define DH_FLAG_CACHE_MONT_P 0x01 #define DH_FLAG_NO_EXP_CONSTTIME 0x02 /* new with 0.9.7h; the built-in DH * implementation now uses constant time @@ -167,6 +169,11 @@ struct dh_st const DH_METHOD *DH_OpenSSL(void); +#ifdef OPENSSL_FIPS +DH * FIPS_dh_new(void); +void FIPS_dh_free(DH *dh); +#endif + void DH_set_default_method(const DH_METHOD *meth); const DH_METHOD *DH_get_default_method(void); int DH_set_method(DH *dh, const DH_METHOD *meth); @@ -218,6 +225,9 @@ void ERR_load_DH_strings(void); #define DH_F_DHPARAMS_PRINT 100 #define DH_F_DHPARAMS_PRINT_FP 101 #define DH_F_DH_BUILTIN_GENPARAMS 106 +#define DH_F_DH_COMPUTE_KEY 107 +#define DH_F_DH_GENERATE_KEY 108 +#define DH_F_DH_GENERATE_PARAMETERS 109 #define DH_F_DH_NEW_METHOD 105 #define DH_F_GENERATE_KEY 103 #define DH_F_GENERATE_PARAMETERS 104 @@ -225,6 +235,7 @@ void ERR_load_DH_strings(void); /* Reason codes. */ #define DH_R_BAD_GENERATOR 101 #define DH_R_INVALID_PUBKEY 102 +#define DH_R_KEY_SIZE_TOO_SMALL 104 #define DH_R_MODULUS_TOO_LARGE 103 #define DH_R_NO_PRIVATE_VALUE 100 diff --git a/src/lib/libcrypto/dh/dh_asn1.c b/src/lib/libcrypto/dh/dh_asn1.c index 769b5b68c5..76740af2bd 100644 --- a/src/lib/libcrypto/dh/dh_asn1.c +++ b/src/lib/libcrypto/dh/dh_asn1.c @@ -1,5 +1,5 @@ /* dh_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. */ /* ==================================================================== diff --git a/src/lib/libcrypto/dh/dh_check.c b/src/lib/libcrypto/dh/dh_check.c index b846913004..316cb9221d 100644 --- a/src/lib/libcrypto/dh/dh_check.c +++ b/src/lib/libcrypto/dh/dh_check.c @@ -70,6 +70,8 @@ * should hold. */ +#ifndef OPENSSL_FIPS + int DH_check(const DH *dh, int *ret) { int ok=0; @@ -140,3 +142,5 @@ err: if (q != NULL) BN_free(q); return(ok); } + +#endif diff --git a/src/lib/libcrypto/dh/dh_err.c b/src/lib/libcrypto/dh/dh_err.c index a2d8196ecb..13263c81c1 100644 --- a/src/lib/libcrypto/dh/dh_err.c +++ b/src/lib/libcrypto/dh/dh_err.c @@ -1,6 +1,6 @@ /* crypto/dh/dh_err.c */ /* ==================================================================== - * Copyright (c) 1999-2005 The OpenSSL Project. All rights reserved. + * Copyright (c) 1999-2007 The OpenSSL Project. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -74,6 +74,9 @@ static ERR_STRING_DATA DH_str_functs[]= {ERR_FUNC(DH_F_DHPARAMS_PRINT), "DHparams_print"}, {ERR_FUNC(DH_F_DHPARAMS_PRINT_FP), "DHparams_print_fp"}, {ERR_FUNC(DH_F_DH_BUILTIN_GENPARAMS), "DH_BUILTIN_GENPARAMS"}, +{ERR_FUNC(DH_F_DH_COMPUTE_KEY), "DH_compute_key"}, +{ERR_FUNC(DH_F_DH_GENERATE_KEY), "DH_generate_key"}, +{ERR_FUNC(DH_F_DH_GENERATE_PARAMETERS), "DH_generate_parameters"}, {ERR_FUNC(DH_F_DH_NEW_METHOD), "DH_new_method"}, {ERR_FUNC(DH_F_GENERATE_KEY), "GENERATE_KEY"}, {ERR_FUNC(DH_F_GENERATE_PARAMETERS), "GENERATE_PARAMETERS"}, @@ -84,6 +87,7 @@ static ERR_STRING_DATA DH_str_reasons[]= { {ERR_REASON(DH_R_BAD_GENERATOR) ,"bad generator"}, {ERR_REASON(DH_R_INVALID_PUBKEY) ,"invalid public key"}, +{ERR_REASON(DH_R_KEY_SIZE_TOO_SMALL) ,"key size too small"}, {ERR_REASON(DH_R_MODULUS_TOO_LARGE) ,"modulus too large"}, {ERR_REASON(DH_R_NO_PRIVATE_VALUE) ,"no private value"}, {0,NULL} diff --git a/src/lib/libcrypto/dh/dh_gen.c b/src/lib/libcrypto/dh/dh_gen.c index cfd5b11868..999e1deb40 100644 --- a/src/lib/libcrypto/dh/dh_gen.c +++ b/src/lib/libcrypto/dh/dh_gen.c @@ -66,6 +66,8 @@ #include #include +#ifndef OPENSSL_FIPS + static int dh_builtin_genparams(DH *ret, int prime_len, int generator, BN_GENCB *cb); int DH_generate_parameters_ex(DH *ret, int prime_len, int generator, BN_GENCB *cb) @@ -173,3 +175,5 @@ err: } return ok; } + +#endif diff --git a/src/lib/libcrypto/dh/dh_key.c b/src/lib/libcrypto/dh/dh_key.c index e7db440342..79dd331863 100644 --- a/src/lib/libcrypto/dh/dh_key.c +++ b/src/lib/libcrypto/dh/dh_key.c @@ -62,6 +62,8 @@ #include #include +#ifndef OPENSSL_FIPS + static int generate_key(DH *dh); static int compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh); static int dh_bn_mod_exp(const DH *dh, BIGNUM *r, @@ -261,3 +263,5 @@ static int dh_finish(DH *dh) BN_MONT_CTX_free(dh->method_mont_p); return(1); } + +#endif diff --git a/src/lib/libcrypto/dsa/dsa.h b/src/lib/libcrypto/dsa/dsa.h index 3a8fe5b56b..702c50d6dc 100644 --- a/src/lib/libcrypto/dsa/dsa.h +++ b/src/lib/libcrypto/dsa/dsa.h @@ -88,6 +88,8 @@ # define OPENSSL_DSA_MAX_MODULUS_BITS 10000 #endif +#define OPENSSL_DSA_FIPS_MIN_MODULUS_BITS 1024 + #define DSA_FLAG_CACHE_MONT_P 0x01 #define DSA_FLAG_NO_EXP_CONSTTIME 0x02 /* new with 0.9.7h; the built-in DSA * implementation now uses constant time @@ -97,6 +99,25 @@ * be used for all exponents. */ +/* If this flag is set the DSA method is FIPS compliant and can be used + * in FIPS mode. This is set in the validated module method. If an + * application sets this flag in its own methods it is its reposibility + * to ensure the result is compliant. + */ + +#define DSA_FLAG_FIPS_METHOD 0x0400 + +/* If this flag is set the operations normally disabled in FIPS mode are + * permitted it is then the applications responsibility to ensure that the + * usage is compliant. + */ + +#define DSA_FLAG_NON_FIPS_ALLOW 0x0400 + +#ifdef OPENSSL_FIPS +#define FIPS_DSA_SIZE_T int +#endif + #ifdef __cplusplus extern "C" { #endif @@ -189,6 +210,11 @@ void DSA_set_default_method(const DSA_METHOD *); const DSA_METHOD *DSA_get_default_method(void); int DSA_set_method(DSA *dsa, const DSA_METHOD *); +#ifdef OPENSSL_FIPS +DSA * FIPS_dsa_new(void); +void FIPS_dsa_free (DSA *r); +#endif + DSA * DSA_new(void); DSA * DSA_new_method(ENGINE *engine); void DSA_free (DSA *r); @@ -249,6 +275,11 @@ int DSA_print_fp(FILE *bp, const DSA *x, int off); DH *DSA_dup_DH(const DSA *r); #endif +#ifdef OPENSSL_FIPS +int FIPS_dsa_sig_encode(unsigned char *out, DSA_SIG *sig); +int FIPS_dsa_sig_decode(DSA_SIG *sig, const unsigned char *in, int inlen); +#endif + /* BEGIN ERROR CODES */ /* The following lines are auto generated by the script mkerr.pl. Any changes * made after this point may be overwritten when the script is next run. @@ -261,11 +292,16 @@ void ERR_load_DSA_strings(void); #define DSA_F_D2I_DSA_SIG 110 #define DSA_F_DSAPARAMS_PRINT 100 #define DSA_F_DSAPARAMS_PRINT_FP 101 +#define DSA_F_DSA_BUILTIN_KEYGEN 119 +#define DSA_F_DSA_BUILTIN_PARAMGEN 118 #define DSA_F_DSA_DO_SIGN 112 #define DSA_F_DSA_DO_VERIFY 113 +#define DSA_F_DSA_GENERATE_PARAMETERS 117 #define DSA_F_DSA_NEW_METHOD 103 #define DSA_F_DSA_PRINT 104 #define DSA_F_DSA_PRINT_FP 105 +#define DSA_F_DSA_SET_DEFAULT_METHOD 115 +#define DSA_F_DSA_SET_METHOD 116 #define DSA_F_DSA_SIGN 106 #define DSA_F_DSA_SIGN_SETUP 107 #define DSA_F_DSA_SIG_NEW 109 @@ -276,8 +312,11 @@ void ERR_load_DSA_strings(void); /* Reason codes. */ #define DSA_R_BAD_Q_VALUE 102 #define DSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE 100 +#define DSA_R_KEY_SIZE_TOO_SMALL 106 #define DSA_R_MISSING_PARAMETERS 101 #define DSA_R_MODULUS_TOO_LARGE 103 +#define DSA_R_NON_FIPS_METHOD 104 +#define DSA_R_OPERATION_NOT_ALLOWED_IN_FIPS_MODE 105 #ifdef __cplusplus } diff --git a/src/lib/libcrypto/dsa/dsa_asn1.c b/src/lib/libcrypto/dsa/dsa_asn1.c index 23fce555aa..0645facb4b 100644 --- a/src/lib/libcrypto/dsa/dsa_asn1.c +++ b/src/lib/libcrypto/dsa/dsa_asn1.c @@ -1,5 +1,5 @@ /* dsa_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. */ /* ==================================================================== @@ -61,6 +61,11 @@ #include #include #include +#include +#ifdef OPENSSL_FIPS +#include +#endif + /* Override the default new methods */ static int sig_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it) @@ -83,7 +88,7 @@ ASN1_SEQUENCE_cb(DSA_SIG, sig_cb) = { ASN1_SIMPLE(DSA_SIG, s, CBIGNUM) } ASN1_SEQUENCE_END_cb(DSA_SIG, DSA_SIG) -IMPLEMENT_ASN1_FUNCTIONS_const(DSA_SIG) +IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(DSA_SIG,DSA_SIG,DSA_SIG) /* Override the default free and new methods */ static int dsa_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it) @@ -138,3 +143,76 @@ ASN1_CHOICE_cb(DSAPublicKey, dsa_cb) = { } ASN1_CHOICE_END_cb(DSA, DSAPublicKey, write_params) IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(DSA, DSAPublicKey, DSAPublicKey) + +int DSA_sign(int type, const unsigned char *dgst, int dlen, unsigned char *sig, + unsigned int *siglen, DSA *dsa) + { + DSA_SIG *s; +#ifdef OPENSSL_FIPS + if(FIPS_mode() && !(dsa->flags & DSA_FLAG_NON_FIPS_ALLOW)) + { + DSAerr(DSA_F_DSA_SIGN, DSA_R_OPERATION_NOT_ALLOWED_IN_FIPS_MODE); + return 0; + } +#endif + s=DSA_do_sign(dgst,dlen,dsa); + if (s == NULL) + { + *siglen=0; + return(0); + } + *siglen=i2d_DSA_SIG(s,&sig); + DSA_SIG_free(s); + return(1); + } + +int DSA_size(const DSA *r) + { + int ret,i; + ASN1_INTEGER bs; + unsigned char buf[4]; /* 4 bytes looks really small. + However, i2d_ASN1_INTEGER() will not look + beyond the first byte, as long as the second + parameter is NULL. */ + + i=BN_num_bits(r->q); + bs.length=(i+7)/8; + bs.data=buf; + bs.type=V_ASN1_INTEGER; + /* If the top bit is set the asn1 encoding is 1 larger. */ + buf[0]=0xff; + + i=i2d_ASN1_INTEGER(&bs,NULL); + i+=i; /* r and s */ + ret=ASN1_object_size(1,i,V_ASN1_SEQUENCE); + return(ret); + } + +/* data has already been hashed (probably with SHA or SHA-1). */ +/* returns + * 1: correct signature + * 0: incorrect signature + * -1: error + */ +int DSA_verify(int type, const unsigned char *dgst, int dgst_len, + const unsigned char *sigbuf, int siglen, DSA *dsa) + { + DSA_SIG *s; + int ret=-1; +#ifdef OPENSSL_FIPS + if(FIPS_mode() && !(dsa->flags & DSA_FLAG_NON_FIPS_ALLOW)) + { + DSAerr(DSA_F_DSA_VERIFY, DSA_R_OPERATION_NOT_ALLOWED_IN_FIPS_MODE); + return 0; + } +#endif + + s = DSA_SIG_new(); + if (s == NULL) return(ret); + if (d2i_DSA_SIG(&s,&sigbuf,siglen) == NULL) goto err; + ret=DSA_do_verify(dgst,dgst_len,s,dsa); +err: + DSA_SIG_free(s); + return(ret); + } + diff --git a/src/lib/libcrypto/dsa/dsa_err.c b/src/lib/libcrypto/dsa/dsa_err.c index 768711994b..872839af94 100644 --- a/src/lib/libcrypto/dsa/dsa_err.c +++ b/src/lib/libcrypto/dsa/dsa_err.c @@ -1,6 +1,6 @@ /* crypto/dsa/dsa_err.c */ /* ==================================================================== - * Copyright (c) 1999-2005 The OpenSSL Project. All rights reserved. + * Copyright (c) 1999-2007 The OpenSSL Project. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -73,11 +73,16 @@ static ERR_STRING_DATA DSA_str_functs[]= {ERR_FUNC(DSA_F_D2I_DSA_SIG), "d2i_DSA_SIG"}, {ERR_FUNC(DSA_F_DSAPARAMS_PRINT), "DSAparams_print"}, {ERR_FUNC(DSA_F_DSAPARAMS_PRINT_FP), "DSAparams_print_fp"}, +{ERR_FUNC(DSA_F_DSA_BUILTIN_KEYGEN), "DSA_BUILTIN_KEYGEN"}, +{ERR_FUNC(DSA_F_DSA_BUILTIN_PARAMGEN), "DSA_BUILTIN_PARAMGEN"}, {ERR_FUNC(DSA_F_DSA_DO_SIGN), "DSA_do_sign"}, {ERR_FUNC(DSA_F_DSA_DO_VERIFY), "DSA_do_verify"}, +{ERR_FUNC(DSA_F_DSA_GENERATE_PARAMETERS), "DSA_generate_parameters"}, {ERR_FUNC(DSA_F_DSA_NEW_METHOD), "DSA_new_method"}, {ERR_FUNC(DSA_F_DSA_PRINT), "DSA_print"}, {ERR_FUNC(DSA_F_DSA_PRINT_FP), "DSA_print_fp"}, +{ERR_FUNC(DSA_F_DSA_SET_DEFAULT_METHOD), "DSA_set_default_method"}, +{ERR_FUNC(DSA_F_DSA_SET_METHOD), "DSA_set_method"}, {ERR_FUNC(DSA_F_DSA_SIGN), "DSA_sign"}, {ERR_FUNC(DSA_F_DSA_SIGN_SETUP), "DSA_sign_setup"}, {ERR_FUNC(DSA_F_DSA_SIG_NEW), "DSA_SIG_new"}, @@ -91,8 +96,11 @@ static ERR_STRING_DATA DSA_str_reasons[]= { {ERR_REASON(DSA_R_BAD_Q_VALUE) ,"bad q value"}, {ERR_REASON(DSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE),"data too large for key size"}, +{ERR_REASON(DSA_R_KEY_SIZE_TOO_SMALL) ,"key size too small"}, {ERR_REASON(DSA_R_MISSING_PARAMETERS) ,"missing parameters"}, {ERR_REASON(DSA_R_MODULUS_TOO_LARGE) ,"modulus too large"}, +{ERR_REASON(DSA_R_NON_FIPS_METHOD) ,"non fips method"}, +{ERR_REASON(DSA_R_OPERATION_NOT_ALLOWED_IN_FIPS_MODE),"operation not allowed in fips mode"}, {0,NULL} }; diff --git a/src/lib/libcrypto/dsa/dsa_gen.c b/src/lib/libcrypto/dsa/dsa_gen.c index ca0b86a6cf..6f1728e3cf 100644 --- a/src/lib/libcrypto/dsa/dsa_gen.c +++ b/src/lib/libcrypto/dsa/dsa_gen.c @@ -82,6 +82,8 @@ #include #include +#ifndef OPENSSL_FIPS + static int dsa_builtin_paramgen(DSA *ret, int bits, unsigned char *seed_in, int seed_len, int *counter_ret, unsigned long *h_ret, BN_GENCB *cb); @@ -320,3 +322,4 @@ err: return ok; } #endif +#endif diff --git a/src/lib/libcrypto/dsa/dsa_key.c b/src/lib/libcrypto/dsa/dsa_key.c index c4aa86bc6d..5e39124230 100644 --- a/src/lib/libcrypto/dsa/dsa_key.c +++ b/src/lib/libcrypto/dsa/dsa_key.c @@ -64,6 +64,8 @@ #include #include +#ifndef OPENSSL_FIPS + static int dsa_builtin_keygen(DSA *dsa); int DSA_generate_key(DSA *dsa) @@ -126,3 +128,5 @@ err: return(ok); } #endif + +#endif diff --git a/src/lib/libcrypto/dsa/dsa_lib.c b/src/lib/libcrypto/dsa/dsa_lib.c index e9b75902db..7ac9dc8c89 100644 --- a/src/lib/libcrypto/dsa/dsa_lib.c +++ b/src/lib/libcrypto/dsa/dsa_lib.c @@ -76,6 +76,14 @@ static const DSA_METHOD *default_DSA_method = NULL; void DSA_set_default_method(const DSA_METHOD *meth) { +#ifdef OPENSSL_FIPS + if (FIPS_mode() && !(meth->flags & DSA_FLAG_FIPS_METHOD)) + { + DSAerr(DSA_F_DSA_SET_DEFAULT_METHOD, DSA_R_NON_FIPS_METHOD); + return; + } +#endif + default_DSA_method = meth; } @@ -96,6 +104,13 @@ int DSA_set_method(DSA *dsa, const DSA_METHOD *meth) /* NB: The caller is specifically setting a method, so it's not up to us * to deal with which ENGINE it comes from. */ const DSA_METHOD *mtmp; +#ifdef OPENSSL_FIPS + if (FIPS_mode() && !(meth->flags & DSA_FLAG_FIPS_METHOD)) + { + DSAerr(DSA_F_DSA_SET_METHOD, DSA_R_NON_FIPS_METHOD); + return 0; + } +#endif mtmp = dsa->meth; if (mtmp->finish) mtmp->finish(dsa); #ifndef OPENSSL_NO_ENGINE @@ -147,6 +162,18 @@ DSA *DSA_new_method(ENGINE *engine) } } #endif +#ifdef OPENSSL_FIPS + if (FIPS_mode() && !(ret->meth->flags & DSA_FLAG_FIPS_METHOD)) + { + DSAerr(DSA_F_DSA_NEW_METHOD, DSA_R_NON_FIPS_METHOD); +#ifndef OPENSSL_NO_ENGINE + if (ret->engine) + ENGINE_finish(ret->engine); +#endif + OPENSSL_free(ret); + return NULL; + } +#endif ret->pad=0; ret->version=0; @@ -233,28 +260,6 @@ int DSA_up_ref(DSA *r) return ((i > 1) ? 1 : 0); } -int DSA_size(const DSA *r) - { - int ret,i; - ASN1_INTEGER bs; - unsigned char buf[4]; /* 4 bytes looks really small. - However, i2d_ASN1_INTEGER() will not look - beyond the first byte, as long as the second - parameter is NULL. */ - - i=BN_num_bits(r->q); - bs.length=(i+7)/8; - bs.data=buf; - bs.type=V_ASN1_INTEGER; - /* If the top bit is set the asn1 encoding is 1 larger. */ - buf[0]=0xff; - - i=i2d_ASN1_INTEGER(&bs,NULL); - i+=i; /* r and s */ - ret=ASN1_object_size(1,i,V_ASN1_SEQUENCE); - return(ret); - } - int DSA_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func, CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func) { diff --git a/src/lib/libcrypto/dsa/dsa_ossl.c b/src/lib/libcrypto/dsa/dsa_ossl.c index 75ff7cc4af..412cf1d88b 100644 --- a/src/lib/libcrypto/dsa/dsa_ossl.c +++ b/src/lib/libcrypto/dsa/dsa_ossl.c @@ -65,6 +65,8 @@ #include #include +#ifndef OPENSSL_FIPS + static DSA_SIG *dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa); static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp); static int dsa_do_verify(const unsigned char *dgst, int dgst_len, DSA_SIG *sig, @@ -391,3 +393,4 @@ static int dsa_finish(DSA *dsa) return(1); } +#endif diff --git a/src/lib/libcrypto/dsa/dsa_sign.c b/src/lib/libcrypto/dsa/dsa_sign.c index 89205026f0..4cfbbe57a8 100644 --- a/src/lib/libcrypto/dsa/dsa_sign.c +++ b/src/lib/libcrypto/dsa/dsa_sign.c @@ -64,29 +64,32 @@ #include #include #include +#ifdef OPENSSL_FIPS +#include +#endif -DSA_SIG * DSA_do_sign(const unsigned char *dgst, int dlen, DSA *dsa) - { - return dsa->meth->dsa_do_sign(dgst, dlen, dsa); - } -int DSA_sign(int type, const unsigned char *dgst, int dlen, unsigned char *sig, - unsigned int *siglen, DSA *dsa) +DSA_SIG * DSA_do_sign(const unsigned char *dgst, int dlen, DSA *dsa) { - DSA_SIG *s; - s=DSA_do_sign(dgst,dlen,dsa); - if (s == NULL) +#ifdef OPENSSL_FIPS + if(FIPS_mode() && !(dsa->flags & DSA_FLAG_NON_FIPS_ALLOW)) { - *siglen=0; - return(0); + DSAerr(DSA_F_DSA_DO_SIGN, DSA_R_OPERATION_NOT_ALLOWED_IN_FIPS_MODE); + return NULL; } - *siglen=i2d_DSA_SIG(s,&sig); - DSA_SIG_free(s); - return(1); +#endif + return dsa->meth->dsa_do_sign(dgst, dlen, dsa); } int DSA_sign_setup(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp) { +#ifdef OPENSSL_FIPS + if(FIPS_mode() && !(dsa->flags & DSA_FLAG_NON_FIPS_ALLOW)) + { + DSAerr(DSA_F_DSA_SIGN_SETUP, DSA_R_OPERATION_NOT_ALLOWED_IN_FIPS_MODE); + return 0; + } +#endif return dsa->meth->dsa_sign_setup(dsa, ctx_in, kinvp, rp); } diff --git a/src/lib/libcrypto/dsa/dsa_vrf.c b/src/lib/libcrypto/dsa/dsa_vrf.c index c4aeddd056..c75e423048 100644 --- a/src/lib/libcrypto/dsa/dsa_vrf.c +++ b/src/lib/libcrypto/dsa/dsa_vrf.c @@ -64,31 +64,21 @@ #include #include #include +#ifdef OPENSSL_FIPS +#include +#endif + #include int DSA_do_verify(const unsigned char *dgst, int dgst_len, DSA_SIG *sig, DSA *dsa) { +#ifdef OPENSSL_FIPS + if(FIPS_mode() && !(dsa->flags & DSA_FLAG_NON_FIPS_ALLOW)) + { + DSAerr(DSA_F_DSA_DO_VERIFY, DSA_R_OPERATION_NOT_ALLOWED_IN_FIPS_MODE); + return 0; + } +#endif return dsa->meth->dsa_do_verify(dgst, dgst_len, sig, dsa); } - -/* data has already been hashed (probably with SHA or SHA-1). */ -/* returns - * 1: correct signature - * 0: incorrect signature - * -1: error - */ -int DSA_verify(int type, const unsigned char *dgst, int dgst_len, - const unsigned char *sigbuf, int siglen, DSA *dsa) - { - DSA_SIG *s; - int ret=-1; - - s = DSA_SIG_new(); - if (s == NULL) return(ret); - if (d2i_DSA_SIG(&s,&sigbuf,siglen) == NULL) goto err; - ret=DSA_do_verify(dgst,dgst_len,s,dsa); -err: - DSA_SIG_free(s); - return(ret); - } diff --git a/src/lib/libcrypto/ec/ec_key.c b/src/lib/libcrypto/ec/ec_key.c index 3d6c900b95..12fb0e6d6d 100644 --- a/src/lib/libcrypto/ec/ec_key.c +++ b/src/lib/libcrypto/ec/ec_key.c @@ -296,7 +296,7 @@ int EC_KEY_check_key(const EC_KEY *eckey) { int ok = 0; BN_CTX *ctx = NULL; - BIGNUM *order = NULL; + const BIGNUM *order = NULL; EC_POINT *point = NULL; if (!eckey || !eckey->group || !eckey->pub_key) @@ -307,8 +307,6 @@ int EC_KEY_check_key(const EC_KEY *eckey) if ((ctx = BN_CTX_new()) == NULL) goto err; - if ((order = BN_new()) == NULL) - goto err; if ((point = EC_POINT_new(eckey->group)) == NULL) goto err; @@ -319,17 +317,13 @@ int EC_KEY_check_key(const EC_KEY *eckey) goto err; } /* testing whether pub_key * order is the point at infinity */ - if (!EC_GROUP_get_order(eckey->group, order, ctx)) + order = &eckey->group->order; + if (BN_is_zero(order)) { ECerr(EC_F_EC_KEY_CHECK_KEY, EC_R_INVALID_GROUP_ORDER); goto err; } - if (!EC_POINT_copy(point, eckey->pub_key)) - { - ECerr(EC_F_EC_KEY_CHECK_KEY, ERR_R_EC_LIB); - goto err; - } - if (!EC_POINT_mul(eckey->group, point, order, NULL, NULL, ctx)) + if (!EC_POINT_mul(eckey->group, point, NULL, eckey->pub_key, order, ctx)) { ECerr(EC_F_EC_KEY_CHECK_KEY, ERR_R_EC_LIB); goto err; @@ -366,8 +360,6 @@ int EC_KEY_check_key(const EC_KEY *eckey) err: if (ctx != NULL) BN_CTX_free(ctx); - if (order != NULL) - BN_free(order); if (point != NULL) EC_POINT_free(point); return(ok); diff --git a/src/lib/libcrypto/engine/eng_all.c b/src/lib/libcrypto/engine/eng_all.c index 8599046717..d29cd57dc2 100644 --- a/src/lib/libcrypto/engine/eng_all.c +++ b/src/lib/libcrypto/engine/eng_all.c @@ -107,6 +107,9 @@ void ENGINE_load_builtin_engines(void) #if defined(__OpenBSD__) || defined(__FreeBSD__) ENGINE_load_cryptodev(); #endif +#if defined(OPENSSL_SYS_WIN32) && !defined(OPENSSL_NO_CAPIENG) + ENGINE_load_capi(); +#endif #endif } diff --git a/src/lib/libcrypto/engine/eng_cnf.c b/src/lib/libcrypto/engine/eng_cnf.c index a97e01e619..08066cea59 100644 --- a/src/lib/libcrypto/engine/eng_cnf.c +++ b/src/lib/libcrypto/engine/eng_cnf.c @@ -1,5 +1,5 @@ /* eng_cnf.c */ -/* Written by Stephen Henson (shenson@bigfoot.com) for the OpenSSL +/* Written by Stephen Henson (steve@openssl.org) for the OpenSSL * project 2001. */ /* ==================================================================== @@ -98,6 +98,8 @@ static int int_engine_configure(char *name, char *value, const CONF *cnf) CONF_VALUE *ecmd; char *ctrlname, *ctrlvalue; ENGINE *e = NULL; + int soft = 0; + name = skip_dot(name); #ifdef ENGINE_CONF_DEBUG fprintf(stderr, "Configuring engine %s\n", name); @@ -125,6 +127,8 @@ static int int_engine_configure(char *name, char *value, const CONF *cnf) /* Override engine name to use */ if (!strcmp(ctrlname, "engine_id")) name = ctrlvalue; + else if (!strcmp(ctrlname, "soft_load")) + soft = 1; /* Load a dynamic ENGINE */ else if (!strcmp(ctrlname, "dynamic_path")) { @@ -147,6 +151,11 @@ static int int_engine_configure(char *name, char *value, const CONF *cnf) if (!e) { e = ENGINE_by_id(name); + if (!e && soft) + { + ERR_clear_error(); + return 1; + } if (!e) return 0; } diff --git a/src/lib/libcrypto/engine/eng_err.c b/src/lib/libcrypto/engine/eng_err.c index 369f2e22d3..574ffbb5c0 100644 --- a/src/lib/libcrypto/engine/eng_err.c +++ b/src/lib/libcrypto/engine/eng_err.c @@ -1,6 +1,6 @@ /* crypto/engine/eng_err.c */ /* ==================================================================== - * Copyright (c) 1999-2005 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 @@ -92,6 +92,7 @@ static ERR_STRING_DATA ENGINE_str_functs[]= {ERR_FUNC(ENGINE_F_ENGINE_LIST_REMOVE), "ENGINE_LIST_REMOVE"}, {ERR_FUNC(ENGINE_F_ENGINE_LOAD_PRIVATE_KEY), "ENGINE_load_private_key"}, {ERR_FUNC(ENGINE_F_ENGINE_LOAD_PUBLIC_KEY), "ENGINE_load_public_key"}, +{ERR_FUNC(ENGINE_F_ENGINE_LOAD_SSL_CLIENT_CERT), "ENGINE_load_ssl_client_cert"}, {ERR_FUNC(ENGINE_F_ENGINE_NEW), "ENGINE_new"}, {ERR_FUNC(ENGINE_F_ENGINE_REMOVE), "ENGINE_remove"}, {ERR_FUNC(ENGINE_F_ENGINE_SET_DEFAULT_STRING), "ENGINE_set_default_string"}, diff --git a/src/lib/libcrypto/engine/eng_int.h b/src/lib/libcrypto/engine/eng_int.h index a5b1edebf4..a66f107a44 100644 --- a/src/lib/libcrypto/engine/eng_int.h +++ b/src/lib/libcrypto/engine/eng_int.h @@ -170,6 +170,8 @@ struct engine_st ENGINE_LOAD_KEY_PTR load_privkey; ENGINE_LOAD_KEY_PTR load_pubkey; + ENGINE_SSL_CLIENT_CERT_PTR load_ssl_client_cert; + const ENGINE_CMD_DEFN *cmd_defns; int flags; /* reference count on the structure itself */ diff --git a/src/lib/libcrypto/engine/eng_padlock.c b/src/lib/libcrypto/engine/eng_padlock.c index 1ba9d85db4..743558ab33 100644 --- a/src/lib/libcrypto/engine/eng_padlock.c +++ b/src/lib/libcrypto/engine/eng_padlock.c @@ -234,8 +234,8 @@ padlock_bind_fn(ENGINE *e, const char *id) return 1; } -IMPLEMENT_DYNAMIC_CHECK_FN (); -IMPLEMENT_DYNAMIC_BIND_FN (padlock_bind_fn); +IMPLEMENT_DYNAMIC_CHECK_FN () +IMPLEMENT_DYNAMIC_BIND_FN (padlock_bind_fn) #endif /* DYNAMIC_ENGINE */ /* ===== Here comes the "real" engine ===== */ diff --git a/src/lib/libcrypto/engine/eng_pkey.c b/src/lib/libcrypto/engine/eng_pkey.c index bc8b21abec..1dfa2e3664 100644 --- a/src/lib/libcrypto/engine/eng_pkey.c +++ b/src/lib/libcrypto/engine/eng_pkey.c @@ -69,6 +69,13 @@ int ENGINE_set_load_pubkey_function(ENGINE *e, ENGINE_LOAD_KEY_PTR loadpub_f) return 1; } +int ENGINE_set_load_ssl_client_cert_function(ENGINE *e, + ENGINE_SSL_CLIENT_CERT_PTR loadssl_f) + { + e->load_ssl_client_cert = loadssl_f; + return 1; + } + ENGINE_LOAD_KEY_PTR ENGINE_get_load_privkey_function(const ENGINE *e) { return e->load_privkey; @@ -79,6 +86,11 @@ ENGINE_LOAD_KEY_PTR ENGINE_get_load_pubkey_function(const ENGINE *e) return e->load_pubkey; } +ENGINE_SSL_CLIENT_CERT_PTR ENGINE_get_ssl_client_cert_function(const ENGINE *e) + { + return e->load_ssl_client_cert; + } + /* API functions to load public/private keys */ EVP_PKEY *ENGINE_load_private_key(ENGINE *e, const char *key_id, @@ -152,3 +164,33 @@ EVP_PKEY *ENGINE_load_public_key(ENGINE *e, const char *key_id, } return pkey; } + +int ENGINE_load_ssl_client_cert(ENGINE *e, SSL *s, + STACK_OF(X509_NAME) *ca_dn, X509 **pcert, EVP_PKEY **ppkey, + STACK_OF(X509) **pother, UI_METHOD *ui_method, void *callback_data) + { + + if(e == NULL) + { + ENGINEerr(ENGINE_F_ENGINE_LOAD_SSL_CLIENT_CERT, + ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); + if(e->funct_ref == 0) + { + CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); + ENGINEerr(ENGINE_F_ENGINE_LOAD_SSL_CLIENT_CERT, + ENGINE_R_NOT_INITIALISED); + return 0; + } + CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); + if (!e->load_ssl_client_cert) + { + ENGINEerr(ENGINE_F_ENGINE_LOAD_SSL_CLIENT_CERT, + ENGINE_R_NO_LOAD_FUNCTION); + return 0; + } + return e->load_ssl_client_cert(e, s, ca_dn, pcert, ppkey, pother, + ui_method, callback_data); + } diff --git a/src/lib/libcrypto/engine/engine.h b/src/lib/libcrypto/engine/engine.h index 3ec59338ff..f503595ece 100644 --- a/src/lib/libcrypto/engine/engine.h +++ b/src/lib/libcrypto/engine/engine.h @@ -93,6 +93,8 @@ #include #endif +#include + #include #include @@ -278,6 +280,9 @@ typedef int (*ENGINE_CTRL_FUNC_PTR)(ENGINE *, int, long, void *, void (*f)(void) /* Generic load_key function pointer */ typedef EVP_PKEY * (*ENGINE_LOAD_KEY_PTR)(ENGINE *, const char *, UI_METHOD *ui_method, void *callback_data); +typedef int (*ENGINE_SSL_CLIENT_CERT_PTR)(ENGINE *, SSL *ssl, + STACK_OF(X509_NAME) *ca_dn, X509 **pcert, EVP_PKEY **pkey, + STACK_OF(X509) **pother, UI_METHOD *ui_method, void *callback_data); /* These callback types are for an ENGINE's handler for cipher and digest logic. * These handlers have these prototypes; * int foo(ENGINE *e, const EVP_CIPHER **cipher, const int **nids, int nid); @@ -334,6 +339,9 @@ void ENGINE_load_ubsec(void); void ENGINE_load_cryptodev(void); void ENGINE_load_padlock(void); void ENGINE_load_builtin_engines(void); +#ifndef OPENSSL_NO_CAPIENG +void ENGINE_load_capi(void); +#endif /* Get and set global flags (ENGINE_TABLE_FLAG_***) for the implementation * "registry" handling. */ @@ -459,6 +467,8 @@ int ENGINE_set_finish_function(ENGINE *e, ENGINE_GEN_INT_FUNC_PTR finish_f); int ENGINE_set_ctrl_function(ENGINE *e, ENGINE_CTRL_FUNC_PTR ctrl_f); int ENGINE_set_load_privkey_function(ENGINE *e, ENGINE_LOAD_KEY_PTR loadpriv_f); int ENGINE_set_load_pubkey_function(ENGINE *e, ENGINE_LOAD_KEY_PTR loadpub_f); +int ENGINE_set_load_ssl_client_cert_function(ENGINE *e, + ENGINE_SSL_CLIENT_CERT_PTR loadssl_f); int ENGINE_set_ciphers(ENGINE *e, ENGINE_CIPHERS_PTR f); int ENGINE_set_digests(ENGINE *e, ENGINE_DIGESTS_PTR f); int ENGINE_set_flags(ENGINE *e, int flags); @@ -494,6 +504,7 @@ ENGINE_GEN_INT_FUNC_PTR ENGINE_get_finish_function(const ENGINE *e); ENGINE_CTRL_FUNC_PTR ENGINE_get_ctrl_function(const ENGINE *e); ENGINE_LOAD_KEY_PTR ENGINE_get_load_privkey_function(const ENGINE *e); ENGINE_LOAD_KEY_PTR ENGINE_get_load_pubkey_function(const ENGINE *e); +ENGINE_SSL_CLIENT_CERT_PTR ENGINE_get_ssl_client_cert_function(const ENGINE *e); ENGINE_CIPHERS_PTR ENGINE_get_ciphers(const ENGINE *e); ENGINE_DIGESTS_PTR ENGINE_get_digests(const ENGINE *e); const EVP_CIPHER *ENGINE_get_cipher(ENGINE *e, int nid); @@ -529,6 +540,10 @@ EVP_PKEY *ENGINE_load_private_key(ENGINE *e, const char *key_id, UI_METHOD *ui_method, void *callback_data); EVP_PKEY *ENGINE_load_public_key(ENGINE *e, const char *key_id, UI_METHOD *ui_method, void *callback_data); +int ENGINE_load_ssl_client_cert(ENGINE *e, SSL *s, + STACK_OF(X509_NAME) *ca_dn, X509 **pcert, EVP_PKEY **ppkey, + STACK_OF(X509) **pother, + UI_METHOD *ui_method, void *callback_data); /* This returns a pointer for the current ENGINE structure that * is (by default) performing any RSA operations. The value returned @@ -723,6 +738,7 @@ void ERR_load_ENGINE_strings(void); #define ENGINE_F_ENGINE_LIST_REMOVE 121 #define ENGINE_F_ENGINE_LOAD_PRIVATE_KEY 150 #define ENGINE_F_ENGINE_LOAD_PUBLIC_KEY 151 +#define ENGINE_F_ENGINE_LOAD_SSL_CLIENT_CERT 192 #define ENGINE_F_ENGINE_NEW 122 #define ENGINE_F_ENGINE_REMOVE 123 #define ENGINE_F_ENGINE_SET_DEFAULT_STRING 189 diff --git a/src/lib/libcrypto/err/err.c b/src/lib/libcrypto/err/err.c index b6ff070e8f..292404a2fb 100644 --- a/src/lib/libcrypto/err/err.c +++ b/src/lib/libcrypto/err/err.c @@ -119,479 +119,9 @@ #include #include -static void err_load_strings(int lib, ERR_STRING_DATA *str); - -static void ERR_STATE_free(ERR_STATE *s); -#ifndef OPENSSL_NO_ERR -static ERR_STRING_DATA ERR_str_libraries[]= - { -{ERR_PACK(ERR_LIB_NONE,0,0) ,"unknown library"}, -{ERR_PACK(ERR_LIB_SYS,0,0) ,"system library"}, -{ERR_PACK(ERR_LIB_BN,0,0) ,"bignum routines"}, -{ERR_PACK(ERR_LIB_RSA,0,0) ,"rsa routines"}, -{ERR_PACK(ERR_LIB_DH,0,0) ,"Diffie-Hellman routines"}, -{ERR_PACK(ERR_LIB_EVP,0,0) ,"digital envelope routines"}, -{ERR_PACK(ERR_LIB_BUF,0,0) ,"memory buffer routines"}, -{ERR_PACK(ERR_LIB_OBJ,0,0) ,"object identifier routines"}, -{ERR_PACK(ERR_LIB_PEM,0,0) ,"PEM routines"}, -{ERR_PACK(ERR_LIB_DSA,0,0) ,"dsa routines"}, -{ERR_PACK(ERR_LIB_X509,0,0) ,"x509 certificate routines"}, -{ERR_PACK(ERR_LIB_ASN1,0,0) ,"asn1 encoding routines"}, -{ERR_PACK(ERR_LIB_CONF,0,0) ,"configuration file routines"}, -{ERR_PACK(ERR_LIB_CRYPTO,0,0) ,"common libcrypto routines"}, -{ERR_PACK(ERR_LIB_EC,0,0) ,"elliptic curve routines"}, -{ERR_PACK(ERR_LIB_SSL,0,0) ,"SSL routines"}, -{ERR_PACK(ERR_LIB_BIO,0,0) ,"BIO routines"}, -{ERR_PACK(ERR_LIB_PKCS7,0,0) ,"PKCS7 routines"}, -{ERR_PACK(ERR_LIB_X509V3,0,0) ,"X509 V3 routines"}, -{ERR_PACK(ERR_LIB_PKCS12,0,0) ,"PKCS12 routines"}, -{ERR_PACK(ERR_LIB_RAND,0,0) ,"random number generator"}, -{ERR_PACK(ERR_LIB_DSO,0,0) ,"DSO support routines"}, -{ERR_PACK(ERR_LIB_ENGINE,0,0) ,"engine routines"}, -{ERR_PACK(ERR_LIB_OCSP,0,0) ,"OCSP routines"}, -{ERR_PACK(ERR_LIB_CMS,0,0) ,"CMS routines"}, -{0,NULL}, - }; - -static ERR_STRING_DATA ERR_str_functs[]= - { - {ERR_PACK(0,SYS_F_FOPEN,0), "fopen"}, - {ERR_PACK(0,SYS_F_CONNECT,0), "connect"}, - {ERR_PACK(0,SYS_F_GETSERVBYNAME,0), "getservbyname"}, - {ERR_PACK(0,SYS_F_SOCKET,0), "socket"}, - {ERR_PACK(0,SYS_F_IOCTLSOCKET,0), "ioctlsocket"}, - {ERR_PACK(0,SYS_F_BIND,0), "bind"}, - {ERR_PACK(0,SYS_F_LISTEN,0), "listen"}, - {ERR_PACK(0,SYS_F_ACCEPT,0), "accept"}, -#ifdef OPENSSL_SYS_WINDOWS - {ERR_PACK(0,SYS_F_WSASTARTUP,0), "WSAstartup"}, -#endif - {ERR_PACK(0,SYS_F_OPENDIR,0), "opendir"}, - {ERR_PACK(0,SYS_F_FREAD,0), "fread"}, - {0,NULL}, - }; - -static ERR_STRING_DATA ERR_str_reasons[]= - { -{ERR_R_SYS_LIB ,"system lib"}, -{ERR_R_BN_LIB ,"BN lib"}, -{ERR_R_RSA_LIB ,"RSA lib"}, -{ERR_R_DH_LIB ,"DH lib"}, -{ERR_R_EVP_LIB ,"EVP lib"}, -{ERR_R_BUF_LIB ,"BUF lib"}, -{ERR_R_OBJ_LIB ,"OBJ lib"}, -{ERR_R_PEM_LIB ,"PEM lib"}, -{ERR_R_DSA_LIB ,"DSA lib"}, -{ERR_R_X509_LIB ,"X509 lib"}, -{ERR_R_ASN1_LIB ,"ASN1 lib"}, -{ERR_R_CONF_LIB ,"CONF lib"}, -{ERR_R_CRYPTO_LIB ,"CRYPTO lib"}, -{ERR_R_EC_LIB ,"EC lib"}, -{ERR_R_SSL_LIB ,"SSL lib"}, -{ERR_R_BIO_LIB ,"BIO lib"}, -{ERR_R_PKCS7_LIB ,"PKCS7 lib"}, -{ERR_R_X509V3_LIB ,"X509V3 lib"}, -{ERR_R_PKCS12_LIB ,"PKCS12 lib"}, -{ERR_R_RAND_LIB ,"RAND lib"}, -{ERR_R_DSO_LIB ,"DSO lib"}, -{ERR_R_ENGINE_LIB ,"ENGINE lib"}, -{ERR_R_OCSP_LIB ,"OCSP lib"}, - -{ERR_R_NESTED_ASN1_ERROR ,"nested asn1 error"}, -{ERR_R_BAD_ASN1_OBJECT_HEADER ,"bad asn1 object header"}, -{ERR_R_BAD_GET_ASN1_OBJECT_CALL ,"bad get asn1 object call"}, -{ERR_R_EXPECTING_AN_ASN1_SEQUENCE ,"expecting an asn1 sequence"}, -{ERR_R_ASN1_LENGTH_MISMATCH ,"asn1 length mismatch"}, -{ERR_R_MISSING_ASN1_EOS ,"missing asn1 eos"}, - -{ERR_R_FATAL ,"fatal"}, -{ERR_R_MALLOC_FAILURE ,"malloc failure"}, -{ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED ,"called a function you should not call"}, -{ERR_R_PASSED_NULL_PARAMETER ,"passed a null parameter"}, -{ERR_R_INTERNAL_ERROR ,"internal error"}, -{ERR_R_DISABLED ,"called a function that was disabled at compile-time"}, - -{0,NULL}, - }; -#endif - - -/* Define the predeclared (but externally opaque) "ERR_FNS" type */ -struct st_ERR_FNS - { - /* Works on the "error_hash" string table */ - LHASH *(*cb_err_get)(int create); - void (*cb_err_del)(void); - ERR_STRING_DATA *(*cb_err_get_item)(const ERR_STRING_DATA *); - ERR_STRING_DATA *(*cb_err_set_item)(ERR_STRING_DATA *); - ERR_STRING_DATA *(*cb_err_del_item)(ERR_STRING_DATA *); - /* Works on the "thread_hash" error-state table */ - LHASH *(*cb_thread_get)(int create); - void (*cb_thread_release)(LHASH **hash); - ERR_STATE *(*cb_thread_get_item)(const ERR_STATE *); - ERR_STATE *(*cb_thread_set_item)(ERR_STATE *); - void (*cb_thread_del_item)(const ERR_STATE *); - /* Returns the next available error "library" numbers */ - int (*cb_get_next_lib)(void); - }; - -/* Predeclarations of the "err_defaults" functions */ -static LHASH *int_err_get(int create); -static void int_err_del(void); -static ERR_STRING_DATA *int_err_get_item(const ERR_STRING_DATA *); -static ERR_STRING_DATA *int_err_set_item(ERR_STRING_DATA *); -static ERR_STRING_DATA *int_err_del_item(ERR_STRING_DATA *); -static LHASH *int_thread_get(int create); -static void int_thread_release(LHASH **hash); -static ERR_STATE *int_thread_get_item(const ERR_STATE *); -static ERR_STATE *int_thread_set_item(ERR_STATE *); -static void int_thread_del_item(const ERR_STATE *); -static int int_err_get_next_lib(void); -/* The static ERR_FNS table using these defaults functions */ -static const ERR_FNS err_defaults = - { - int_err_get, - int_err_del, - int_err_get_item, - int_err_set_item, - int_err_del_item, - int_thread_get, - int_thread_release, - int_thread_get_item, - int_thread_set_item, - int_thread_del_item, - int_err_get_next_lib - }; - -/* The replacable table of ERR_FNS functions we use at run-time */ -static const ERR_FNS *err_fns = NULL; - -/* Eg. rather than using "err_get()", use "ERRFN(err_get)()". */ -#define ERRFN(a) err_fns->cb_##a - -/* The internal state used by "err_defaults" - as such, the setting, reading, - * creating, and deleting of this data should only be permitted via the - * "err_defaults" functions. This way, a linked module can completely defer all - * ERR state operation (together with requisite locking) to the implementations - * and state in the loading application. */ -static LHASH *int_error_hash = NULL; -static LHASH *int_thread_hash = NULL; -static int int_thread_hash_references = 0; -static int int_err_library_number= ERR_LIB_USER; - -/* Internal function that checks whether "err_fns" is set and if not, sets it to - * the defaults. */ -static void err_fns_check(void) - { - if (err_fns) return; - - CRYPTO_w_lock(CRYPTO_LOCK_ERR); - if (!err_fns) - err_fns = &err_defaults; - CRYPTO_w_unlock(CRYPTO_LOCK_ERR); - } - -/* API functions to get or set the underlying ERR functions. */ - -const ERR_FNS *ERR_get_implementation(void) - { - err_fns_check(); - return err_fns; - } - -int ERR_set_implementation(const ERR_FNS *fns) - { - int ret = 0; - - CRYPTO_w_lock(CRYPTO_LOCK_ERR); - /* It's too late if 'err_fns' is non-NULL. BTW: not much point setting - * an error is there?! */ - if (!err_fns) - { - err_fns = fns; - ret = 1; - } - CRYPTO_w_unlock(CRYPTO_LOCK_ERR); - return ret; - } - -/* These are the callbacks provided to "lh_new()" when creating the LHASH tables - * internal to the "err_defaults" implementation. */ - -/* static unsigned long err_hash(ERR_STRING_DATA *a); */ -static unsigned long err_hash(const void *a_void); -/* static int err_cmp(ERR_STRING_DATA *a, ERR_STRING_DATA *b); */ -static int err_cmp(const void *a_void, const void *b_void); -/* static unsigned long pid_hash(ERR_STATE *pid); */ -static unsigned long pid_hash(const void *pid_void); -/* static int pid_cmp(ERR_STATE *a,ERR_STATE *pid); */ -static int pid_cmp(const void *a_void,const void *pid_void); -static unsigned long get_error_values(int inc,int top,const char **file,int *line, - const char **data,int *flags); - -/* The internal functions used in the "err_defaults" implementation */ - -static LHASH *int_err_get(int create) - { - LHASH *ret = NULL; - - CRYPTO_w_lock(CRYPTO_LOCK_ERR); - if (!int_error_hash && create) - { - CRYPTO_push_info("int_err_get (err.c)"); - int_error_hash = lh_new(err_hash, err_cmp); - CRYPTO_pop_info(); - } - if (int_error_hash) - ret = int_error_hash; - CRYPTO_w_unlock(CRYPTO_LOCK_ERR); - - return ret; - } - -static void int_err_del(void) - { - CRYPTO_w_lock(CRYPTO_LOCK_ERR); - if (int_error_hash) - { - lh_free(int_error_hash); - int_error_hash = NULL; - } - CRYPTO_w_unlock(CRYPTO_LOCK_ERR); - } - -static ERR_STRING_DATA *int_err_get_item(const ERR_STRING_DATA *d) - { - ERR_STRING_DATA *p; - LHASH *hash; - - err_fns_check(); - hash = ERRFN(err_get)(0); - if (!hash) - return NULL; - - CRYPTO_r_lock(CRYPTO_LOCK_ERR); - p = (ERR_STRING_DATA *)lh_retrieve(hash, d); - CRYPTO_r_unlock(CRYPTO_LOCK_ERR); - - return p; - } - -static ERR_STRING_DATA *int_err_set_item(ERR_STRING_DATA *d) - { - ERR_STRING_DATA *p; - LHASH *hash; - - err_fns_check(); - hash = ERRFN(err_get)(1); - if (!hash) - return NULL; - - CRYPTO_w_lock(CRYPTO_LOCK_ERR); - p = (ERR_STRING_DATA *)lh_insert(hash, d); - CRYPTO_w_unlock(CRYPTO_LOCK_ERR); - - return p; - } - -static ERR_STRING_DATA *int_err_del_item(ERR_STRING_DATA *d) - { - ERR_STRING_DATA *p; - LHASH *hash; - - err_fns_check(); - hash = ERRFN(err_get)(0); - if (!hash) - return NULL; - - CRYPTO_w_lock(CRYPTO_LOCK_ERR); - p = (ERR_STRING_DATA *)lh_delete(hash, d); - CRYPTO_w_unlock(CRYPTO_LOCK_ERR); - - return p; - } - -static LHASH *int_thread_get(int create) - { - LHASH *ret = NULL; - - CRYPTO_w_lock(CRYPTO_LOCK_ERR); - if (!int_thread_hash && create) - { - CRYPTO_push_info("int_thread_get (err.c)"); - int_thread_hash = lh_new(pid_hash, pid_cmp); - CRYPTO_pop_info(); - } - if (int_thread_hash) - { - int_thread_hash_references++; - ret = int_thread_hash; - } - CRYPTO_w_unlock(CRYPTO_LOCK_ERR); - return ret; - } - -static void int_thread_release(LHASH **hash) - { - int i; - - if (hash == NULL || *hash == NULL) - return; - - i = CRYPTO_add(&int_thread_hash_references, -1, CRYPTO_LOCK_ERR); - -#ifdef REF_PRINT - fprintf(stderr,"%4d:%s\n",int_thread_hash_references,"ERR"); -#endif - if (i > 0) return; -#ifdef REF_CHECK - if (i < 0) - { - fprintf(stderr,"int_thread_release, bad reference count\n"); - abort(); /* ok */ - } -#endif - *hash = NULL; - } - -static ERR_STATE *int_thread_get_item(const ERR_STATE *d) - { - ERR_STATE *p; - LHASH *hash; - - err_fns_check(); - hash = ERRFN(thread_get)(0); - if (!hash) - return NULL; - - CRYPTO_r_lock(CRYPTO_LOCK_ERR); - p = (ERR_STATE *)lh_retrieve(hash, d); - CRYPTO_r_unlock(CRYPTO_LOCK_ERR); - - ERRFN(thread_release)(&hash); - return p; - } - -static ERR_STATE *int_thread_set_item(ERR_STATE *d) - { - ERR_STATE *p; - LHASH *hash; - - err_fns_check(); - hash = ERRFN(thread_get)(1); - if (!hash) - return NULL; - - CRYPTO_w_lock(CRYPTO_LOCK_ERR); - p = (ERR_STATE *)lh_insert(hash, d); - CRYPTO_w_unlock(CRYPTO_LOCK_ERR); - - ERRFN(thread_release)(&hash); - return p; - } - -static void int_thread_del_item(const ERR_STATE *d) - { - ERR_STATE *p; - LHASH *hash; - - err_fns_check(); - hash = ERRFN(thread_get)(0); - if (!hash) - return; - - CRYPTO_w_lock(CRYPTO_LOCK_ERR); - p = (ERR_STATE *)lh_delete(hash, d); - /* make sure we don't leak memory */ - if (int_thread_hash_references == 1 - && int_thread_hash && (lh_num_items(int_thread_hash) == 0)) - { - lh_free(int_thread_hash); - int_thread_hash = NULL; - } - CRYPTO_w_unlock(CRYPTO_LOCK_ERR); - - ERRFN(thread_release)(&hash); - if (p) - ERR_STATE_free(p); - } - -static int int_err_get_next_lib(void) - { - int ret; - - CRYPTO_w_lock(CRYPTO_LOCK_ERR); - ret = int_err_library_number++; - CRYPTO_w_unlock(CRYPTO_LOCK_ERR); - - return ret; - } - - -#ifndef OPENSSL_NO_ERR -#define NUM_SYS_STR_REASONS 127 -#define LEN_SYS_STR_REASON 32 - -static ERR_STRING_DATA SYS_str_reasons[NUM_SYS_STR_REASONS + 1]; -/* SYS_str_reasons is filled with copies of strerror() results at - * initialization. - * 'errno' values up to 127 should cover all usual errors, - * others will be displayed numerically by ERR_error_string. - * It is crucial that we have something for each reason code - * that occurs in ERR_str_reasons, or bogus reason strings - * will be returned for SYSerr(), which always gets an errno - * value and never one of those 'standard' reason codes. */ - -static void build_SYS_str_reasons(void) - { - /* OPENSSL_malloc cannot be used here, use static storage instead */ - static char strerror_tab[NUM_SYS_STR_REASONS][LEN_SYS_STR_REASON]; - int i; - static int init = 1; - - CRYPTO_r_lock(CRYPTO_LOCK_ERR); - if (!init) - { - CRYPTO_r_unlock(CRYPTO_LOCK_ERR); - return; - } - - CRYPTO_r_unlock(CRYPTO_LOCK_ERR); - CRYPTO_w_lock(CRYPTO_LOCK_ERR); - if (!init) - { - CRYPTO_w_unlock(CRYPTO_LOCK_ERR); - return; - } - - for (i = 1; i <= NUM_SYS_STR_REASONS; i++) - { - ERR_STRING_DATA *str = &SYS_str_reasons[i - 1]; - - str->error = (unsigned long)i; - if (str->string == NULL) - { - char (*dest)[LEN_SYS_STR_REASON] = &(strerror_tab[i - 1]); - char *src = strerror(i); - if (src != NULL) - { - strncpy(*dest, src, sizeof *dest); - (*dest)[sizeof *dest - 1] = '\0'; - str->string = *dest; - } - } - if (str->string == NULL) - str->string = "unknown"; - } - - /* Now we still have SYS_str_reasons[NUM_SYS_STR_REASONS] = {0, NULL}, - * as required by ERR_load_strings. */ - - init = 0; - - CRYPTO_w_unlock(CRYPTO_LOCK_ERR); - } -#endif +static unsigned long get_error_values(int inc,int top, + const char **file,int *line, + const char **data,int *flags); #define err_clear_data(p,i) \ do { \ @@ -613,68 +143,6 @@ static void build_SYS_str_reasons(void) (p)->err_line[i]= -1; \ } while(0) -static void ERR_STATE_free(ERR_STATE *s) - { - int i; - - if (s == NULL) - return; - - for (i=0; ierror) - { - if (lib) - str->error|=ERR_PACK(lib,0,0); - ERRFN(err_set_item)(str); - str++; - } - } - -void ERR_load_strings(int lib, ERR_STRING_DATA *str) - { - ERR_load_ERR_strings(); - err_load_strings(lib, str); - } - -void ERR_unload_strings(int lib, ERR_STRING_DATA *str) - { - while (str->error) - { - if (lib) - str->error|=ERR_PACK(lib,0,0); - ERRFN(err_del_item)(str); - str++; - } - } - -void ERR_free_strings(void) - { - err_fns_check(); - ERRFN(err_del)(); - } - -/********************************************************/ - void ERR_put_error(int lib, int func, int reason, const char *file, int line) { @@ -829,218 +297,6 @@ static unsigned long get_error_values(int inc, int top, const char **file, int * return ret; } -void ERR_error_string_n(unsigned long e, char *buf, size_t len) - { - char lsbuf[64], fsbuf[64], rsbuf[64]; - const char *ls,*fs,*rs; - unsigned long l,f,r; - - l=ERR_GET_LIB(e); - f=ERR_GET_FUNC(e); - r=ERR_GET_REASON(e); - - ls=ERR_lib_error_string(e); - fs=ERR_func_error_string(e); - rs=ERR_reason_error_string(e); - - if (ls == NULL) - BIO_snprintf(lsbuf, sizeof(lsbuf), "lib(%lu)", l); - if (fs == NULL) - BIO_snprintf(fsbuf, sizeof(fsbuf), "func(%lu)", f); - if (rs == NULL) - BIO_snprintf(rsbuf, sizeof(rsbuf), "reason(%lu)", r); - - BIO_snprintf(buf, len,"error:%08lX:%s:%s:%s", e, ls?ls:lsbuf, - fs?fs:fsbuf, rs?rs:rsbuf); - if (strlen(buf) == len-1) - { - /* output may be truncated; make sure we always have 5 - * colon-separated fields, i.e. 4 colons ... */ -#define NUM_COLONS 4 - if (len > NUM_COLONS) /* ... if possible */ - { - int i; - char *s = buf; - - for (i = 0; i < NUM_COLONS; i++) - { - char *colon = strchr(s, ':'); - if (colon == NULL || colon > &buf[len-1] - NUM_COLONS + i) - { - /* set colon no. i at last possible position - * (buf[len-1] is the terminating 0)*/ - colon = &buf[len-1] - NUM_COLONS + i; - *colon = ':'; - } - s = colon + 1; - } - } - } - } - -/* BAD for multi-threading: uses a local buffer if ret == NULL */ -/* ERR_error_string_n should be used instead for ret != NULL - * as ERR_error_string cannot know how large the buffer is */ -char *ERR_error_string(unsigned long e, char *ret) - { - static char buf[256]; - - if (ret == NULL) ret=buf; - ERR_error_string_n(e, ret, 256); - - return ret; - } - -LHASH *ERR_get_string_table(void) - { - err_fns_check(); - return ERRFN(err_get)(0); - } - -LHASH *ERR_get_err_state_table(void) - { - err_fns_check(); - return ERRFN(thread_get)(0); - } - -void ERR_release_err_state_table(LHASH **hash) - { - err_fns_check(); - ERRFN(thread_release)(hash); - } - -const char *ERR_lib_error_string(unsigned long e) - { - ERR_STRING_DATA d,*p; - unsigned long l; - - err_fns_check(); - l=ERR_GET_LIB(e); - d.error=ERR_PACK(l,0,0); - p=ERRFN(err_get_item)(&d); - return((p == NULL)?NULL:p->string); - } - -const char *ERR_func_error_string(unsigned long e) - { - ERR_STRING_DATA d,*p; - unsigned long l,f; - - err_fns_check(); - l=ERR_GET_LIB(e); - f=ERR_GET_FUNC(e); - d.error=ERR_PACK(l,f,0); - p=ERRFN(err_get_item)(&d); - return((p == NULL)?NULL:p->string); - } - -const char *ERR_reason_error_string(unsigned long e) - { - ERR_STRING_DATA d,*p=NULL; - unsigned long l,r; - - err_fns_check(); - l=ERR_GET_LIB(e); - r=ERR_GET_REASON(e); - d.error=ERR_PACK(l,0,r); - p=ERRFN(err_get_item)(&d); - if (!p) - { - d.error=ERR_PACK(0,0,r); - p=ERRFN(err_get_item)(&d); - } - return((p == NULL)?NULL:p->string); - } - -/* static unsigned long err_hash(ERR_STRING_DATA *a) */ -static unsigned long err_hash(const void *a_void) - { - unsigned long ret,l; - - l=((const ERR_STRING_DATA *)a_void)->error; - ret=l^ERR_GET_LIB(l)^ERR_GET_FUNC(l); - return(ret^ret%19*13); - } - -/* static int err_cmp(ERR_STRING_DATA *a, ERR_STRING_DATA *b) */ -static int err_cmp(const void *a_void, const void *b_void) - { - return((int)(((const ERR_STRING_DATA *)a_void)->error - - ((const ERR_STRING_DATA *)b_void)->error)); - } - -/* static unsigned long pid_hash(ERR_STATE *a) */ -static unsigned long pid_hash(const void *a_void) - { - return(((const ERR_STATE *)a_void)->pid*13); - } - -/* static int pid_cmp(ERR_STATE *a, ERR_STATE *b) */ -static int pid_cmp(const void *a_void, const void *b_void) - { - return((int)((long)((const ERR_STATE *)a_void)->pid - - (long)((const ERR_STATE *)b_void)->pid)); - } - -void ERR_remove_state(unsigned long pid) - { - ERR_STATE tmp; - - err_fns_check(); - if (pid == 0) - pid=(unsigned long)CRYPTO_thread_id(); - tmp.pid=pid; - /* thread_del_item automatically destroys the LHASH if the number of - * items reaches zero. */ - ERRFN(thread_del_item)(&tmp); - } - -ERR_STATE *ERR_get_state(void) - { - static ERR_STATE fallback; - ERR_STATE *ret,tmp,*tmpp=NULL; - int i; - unsigned long pid; - - err_fns_check(); - pid=(unsigned long)CRYPTO_thread_id(); - tmp.pid=pid; - ret=ERRFN(thread_get_item)(&tmp); - - /* ret == the error state, if NULL, make a new one */ - if (ret == NULL) - { - ret=(ERR_STATE *)OPENSSL_malloc(sizeof(ERR_STATE)); - if (ret == NULL) return(&fallback); - ret->pid=pid; - ret->top=0; - ret->bottom=0; - for (i=0; ierr_data[i]=NULL; - ret->err_data_flags[i]=0; - } - tmpp = ERRFN(thread_set_item)(ret); - /* To check if insertion failed, do a get. */ - if (ERRFN(thread_get_item)(ret) != ret) - { - ERR_STATE_free(ret); /* could not insert it */ - return(&fallback); - } - /* If a race occured in this function and we came second, tmpp - * is the first one that we just replaced. */ - if (tmpp) - ERR_STATE_free(tmpp); - } - return ret; - } - -int ERR_get_next_error_library(void) - { - err_fns_check(); - return ERRFN(get_next_lib)(); - } - void ERR_set_error_data(char *data, int flags) { ERR_STATE *es; @@ -1127,3 +383,34 @@ int ERR_pop_to_mark(void) es->err_flags[es->top]&=~ERR_FLAG_MARK; return 1; } + +#ifdef OPENSSL_FIPS + +static ERR_STATE *fget_state(void) + { + static ERR_STATE fstate; + return &fstate; + } + +ERR_STATE *(*get_state_func)(void) = fget_state; +void (*remove_state_func)(unsigned long pid); + +ERR_STATE *ERR_get_state(void) + { + return get_state_func(); + } + +void int_ERR_set_state_func(ERR_STATE *(*get_func)(void), + void (*remove_func)(unsigned long pid)) + { + get_state_func = get_func; + remove_state_func = remove_func; + } + +void ERR_remove_state(unsigned long pid) + { + if (remove_state_func) + remove_state_func(pid); + } + +#endif diff --git a/src/lib/libcrypto/err/err.h b/src/lib/libcrypto/err/err.h index bf28fce492..dcac415231 100644 --- a/src/lib/libcrypto/err/err.h +++ b/src/lib/libcrypto/err/err.h @@ -140,7 +140,9 @@ typedef struct err_state_st #define ERR_LIB_ECDSA 42 #define ERR_LIB_ECDH 43 #define ERR_LIB_STORE 44 -#define ERR_LIB_CMS 45 +#define ERR_LIB_FIPS 45 +#define ERR_LIB_CMS 46 +#define ERR_LIB_JPAKE 47 #define ERR_LIB_USER 128 @@ -172,7 +174,9 @@ typedef struct err_state_st #define ECDSAerr(f,r) ERR_PUT_error(ERR_LIB_ECDSA,(f),(r),__FILE__,__LINE__) #define ECDHerr(f,r) ERR_PUT_error(ERR_LIB_ECDH,(f),(r),__FILE__,__LINE__) #define STOREerr(f,r) ERR_PUT_error(ERR_LIB_STORE,(f),(r),__FILE__,__LINE__) +#define FIPSerr(f,r) ERR_PUT_error(ERR_LIB_FIPS,(f),(r),__FILE__,__LINE__) #define CMSerr(f,r) ERR_PUT_error(ERR_LIB_CMS,(f),(r),__FILE__,__LINE__) +#define JPAKEerr(f,r) ERR_PUT_error(ERR_LIB_JPAKE,(f),(r),__FILE__,__LINE__) /* Borland C seems too stupid to be able to shift and do longs in * the pre-processor :-( */ @@ -304,6 +308,12 @@ int ERR_get_next_error_library(void); int ERR_set_mark(void); int ERR_pop_to_mark(void); +#ifdef OPENSSL_FIPS +void int_ERR_set_state_func(ERR_STATE *(*get_func)(void), + void (*remove_func)(unsigned long pid)); +void int_ERR_lib_init(void); +#endif + /* Already defined in ossl_typ.h */ /* typedef struct st_ERR_FNS ERR_FNS; */ /* An application can use this function and provide the return value to loaded diff --git a/src/lib/libcrypto/err/err_all.c b/src/lib/libcrypto/err/err_all.c index 5813060ce2..f21a5276ed 100644 --- a/src/lib/libcrypto/err/err_all.c +++ b/src/lib/libcrypto/err/err_all.c @@ -94,9 +94,16 @@ #include #include #include +#ifdef OPENSSL_FIPS +#include +#endif + #ifndef OPENSSL_NO_CMS #include #endif +#ifndef OPENSSL_NO_JPAKE +#include +#endif void ERR_load_crypto_strings(void) { @@ -141,8 +148,14 @@ void ERR_load_crypto_strings(void) #endif ERR_load_OCSP_strings(); ERR_load_UI_strings(); +#ifdef OPENSSL_FIPS + ERR_load_FIPS_strings(); +#endif #ifndef OPENSSL_NO_CMS ERR_load_CMS_strings(); #endif +#ifndef OPENSSL_NO_JPAKE + ERR_load_JPAKE_strings(); +#endif #endif } diff --git a/src/lib/libcrypto/err/err_prn.c b/src/lib/libcrypto/err/err_prn.c index 2224a901e5..4cdf342fa6 100644 --- a/src/lib/libcrypto/err/err_prn.c +++ b/src/lib/libcrypto/err/err_prn.c @@ -86,12 +86,7 @@ void ERR_print_errors_cb(int (*cb)(const char *str, size_t len, void *u), #ifndef OPENSSL_NO_FP_API static int print_fp(const char *str, size_t len, void *fp) { - BIO bio; - - BIO_set(&bio,BIO_s_file()); - BIO_set_fp(&bio,fp,BIO_NOCLOSE); - - return BIO_printf(&bio, "%s", str); + return fwrite(str, 1, len, fp); } void ERR_print_errors_fp(FILE *fp) { @@ -99,13 +94,64 @@ void ERR_print_errors_fp(FILE *fp) } #endif -static int print_bio(const char *str, size_t len, void *bp) +void ERR_error_string_n(unsigned long e, char *buf, size_t len) { - return BIO_write((BIO *)bp, str, len); + char lsbuf[64], fsbuf[64], rsbuf[64]; + const char *ls,*fs,*rs; + unsigned long l,f,r; + + l=ERR_GET_LIB(e); + f=ERR_GET_FUNC(e); + r=ERR_GET_REASON(e); + + ls=ERR_lib_error_string(e); + fs=ERR_func_error_string(e); + rs=ERR_reason_error_string(e); + + if (ls == NULL) + BIO_snprintf(lsbuf, sizeof(lsbuf), "lib(%lu)", l); + if (fs == NULL) + BIO_snprintf(fsbuf, sizeof(fsbuf), "func(%lu)", f); + if (rs == NULL) + BIO_snprintf(rsbuf, sizeof(rsbuf), "reason(%lu)", r); + + BIO_snprintf(buf, len,"error:%08lX:%s:%s:%s", e, ls?ls:lsbuf, + fs?fs:fsbuf, rs?rs:rsbuf); + if (strlen(buf) == len-1) + { + /* output may be truncated; make sure we always have 5 + * colon-separated fields, i.e. 4 colons ... */ +#define NUM_COLONS 4 + if (len > NUM_COLONS) /* ... if possible */ + { + int i; + char *s = buf; + + for (i = 0; i < NUM_COLONS; i++) + { + char *colon = strchr(s, ':'); + if (colon == NULL || colon > &buf[len-1] - NUM_COLONS + i) + { + /* set colon no. i at last possible position + * (buf[len-1] is the terminating 0)*/ + colon = &buf[len-1] - NUM_COLONS + i; + *colon = ':'; + } + s = colon + 1; + } + } + } } -void ERR_print_errors(BIO *bp) + +/* BAD for multi-threading: uses a local buffer if ret == NULL */ +/* ERR_error_string_n should be used instead for ret != NULL + * as ERR_error_string cannot know how large the buffer is */ +char *ERR_error_string(unsigned long e, char *ret) { - ERR_print_errors_cb(print_bio, bp); - } + static char buf[256]; + + if (ret == NULL) ret=buf; + ERR_error_string_n(e, ret, 256); - + return ret; + } diff --git a/src/lib/libcrypto/err/openssl.ec b/src/lib/libcrypto/err/openssl.ec index 1938f081ac..868826624d 100644 --- a/src/lib/libcrypto/err/openssl.ec +++ b/src/lib/libcrypto/err/openssl.ec @@ -31,7 +31,9 @@ L COMP crypto/comp/comp.h crypto/comp/comp_err.c L ECDSA crypto/ecdsa/ecdsa.h crypto/ecdsa/ecs_err.c L ECDH crypto/ecdh/ecdh.h crypto/ecdh/ech_err.c L STORE crypto/store/store.h crypto/store/str_err.c +L FIPS fips/fips.h crypto/fips_err.h L CMS crypto/cms/cms.h crypto/cms/cms_err.c +L JPAKE crypto/jpake/jpake.h crypto/jpake/jpake_err.c # additional header files to be scanned for function names L NONE crypto/x509/x509_vfy.h NONE diff --git a/src/lib/libcrypto/evp/bio_md.c b/src/lib/libcrypto/evp/bio_md.c index d648ac6da6..ed5c1135fd 100644 --- a/src/lib/libcrypto/evp/bio_md.c +++ b/src/lib/libcrypto/evp/bio_md.c @@ -192,13 +192,8 @@ static long md_ctrl(BIO *b, int cmd, long num, void *ptr) ret=0; break; case BIO_C_GET_MD_CTX: - if (b->init) - { - pctx=ptr; - *pctx=ctx; - } - else - ret=0; + pctx=ptr; + *pctx=ctx; break; case BIO_C_SET_MD_CTX: if (b->init) diff --git a/src/lib/libcrypto/evp/digest.c b/src/lib/libcrypto/evp/digest.c index 762e6d3450..3bc2d1295c 100644 --- a/src/lib/libcrypto/evp/digest.c +++ b/src/lib/libcrypto/evp/digest.c @@ -116,6 +116,7 @@ #ifndef OPENSSL_NO_ENGINE #include #endif +#include "evp_locl.h" void EVP_MD_CTX_init(EVP_MD_CTX *ctx) { @@ -137,18 +138,77 @@ int EVP_DigestInit(EVP_MD_CTX *ctx, const EVP_MD *type) return EVP_DigestInit_ex(ctx, type, NULL); } -int EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *impl) +#ifdef OPENSSL_FIPS + +/* The purpose of these is to trap programs that attempt to use non FIPS + * algorithms in FIPS mode and ignore the errors. + */ + +static int bad_init(EVP_MD_CTX *ctx) + { FIPS_ERROR_IGNORED("Digest init"); return 0;} + +static int bad_update(EVP_MD_CTX *ctx,const void *data,size_t count) + { FIPS_ERROR_IGNORED("Digest update"); return 0;} + +static int bad_final(EVP_MD_CTX *ctx,unsigned char *md) + { FIPS_ERROR_IGNORED("Digest Final"); return 0;} + +static const EVP_MD bad_md = { - EVP_MD_CTX_clear_flags(ctx,EVP_MD_CTX_FLAG_CLEANED); + 0, + 0, + 0, + 0, + bad_init, + bad_update, + bad_final, + NULL, + NULL, + NULL, + 0, + {0,0,0,0}, + }; + +#endif + #ifndef OPENSSL_NO_ENGINE - /* Whether it's nice or not, "Inits" can be used on "Final"'d contexts - * so this context may already have an ENGINE! Try to avoid releasing - * the previous handle, re-querying for an ENGINE, and having a - * reinitialisation, when it may all be unecessary. */ - if (ctx->engine && ctx->digest && (!type || - (type && (type->type == ctx->digest->type)))) - goto skip_to_init; - if (type) + +#ifdef OPENSSL_FIPS + +static int do_engine_null(ENGINE *impl) { return 0;} +static int do_evp_md_engine_null(EVP_MD_CTX *ctx, + const EVP_MD **ptype, ENGINE *impl) + { return 1; } + +static int (*do_engine_init)(ENGINE *impl) + = do_engine_null; + +static int (*do_engine_finish)(ENGINE *impl) + = do_engine_null; + +static int (*do_evp_md_engine) + (EVP_MD_CTX *ctx, const EVP_MD **ptype, ENGINE *impl) + = do_evp_md_engine_null; + +void int_EVP_MD_set_engine_callbacks( + int (*eng_md_init)(ENGINE *impl), + int (*eng_md_fin)(ENGINE *impl), + int (*eng_md_evp) + (EVP_MD_CTX *ctx, const EVP_MD **ptype, ENGINE *impl)) + { + do_engine_init = eng_md_init; + do_engine_finish = eng_md_fin; + do_evp_md_engine = eng_md_evp; + } + +#else + +#define do_engine_init ENGINE_init +#define do_engine_finish ENGINE_finish + +static int do_evp_md_engine(EVP_MD_CTX *ctx, const EVP_MD **ptype, ENGINE *impl) + { + if (*ptype) { /* Ensure an ENGINE left lying around from last time is cleared * (the previous check attempted to avoid this if the same @@ -159,25 +219,25 @@ int EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *impl) { if (!ENGINE_init(impl)) { - EVPerr(EVP_F_EVP_DIGESTINIT_EX,EVP_R_INITIALIZATION_ERROR); + EVPerr(EVP_F_DO_EVP_MD_ENGINE,EVP_R_INITIALIZATION_ERROR); return 0; } } else /* Ask if an ENGINE is reserved for this job */ - impl = ENGINE_get_digest_engine(type->type); + impl = ENGINE_get_digest_engine((*ptype)->type); if(impl) { /* There's an ENGINE for this job ... (apparently) */ - const EVP_MD *d = ENGINE_get_digest(impl, type->type); + const EVP_MD *d = ENGINE_get_digest(impl, (*ptype)->type); if(!d) { /* Same comment from evp_enc.c */ - EVPerr(EVP_F_EVP_DIGESTINIT_EX,EVP_R_INITIALIZATION_ERROR); + EVPerr(EVP_F_DO_EVP_MD_ENGINE,EVP_R_INITIALIZATION_ERROR); return 0; } /* We'll use the ENGINE's private digest definition */ - type = d; + *ptype = d; /* Store the ENGINE functional reference so we know * 'type' came from an ENGINE and we need to release * it when done. */ @@ -189,12 +249,52 @@ int EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *impl) else if(!ctx->digest) { - EVPerr(EVP_F_EVP_DIGESTINIT_EX,EVP_R_NO_DIGEST_SET); + EVPerr(EVP_F_DO_EVP_MD_ENGINE,EVP_R_NO_DIGEST_SET); return 0; } + return 1; + } + +#endif + +#endif + +int EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *impl) + { + M_EVP_MD_CTX_clear_flags(ctx,EVP_MD_CTX_FLAG_CLEANED); +#ifdef OPENSSL_FIPS + if(FIPS_selftest_failed()) + { + FIPSerr(FIPS_F_EVP_DIGESTINIT_EX,FIPS_R_FIPS_SELFTEST_FAILED); + ctx->digest = &bad_md; + return 0; + } +#endif +#ifndef OPENSSL_NO_ENGINE + /* Whether it's nice or not, "Inits" can be used on "Final"'d contexts + * so this context may already have an ENGINE! Try to avoid releasing + * the previous handle, re-querying for an ENGINE, and having a + * reinitialisation, when it may all be unecessary. */ + if (ctx->engine && ctx->digest && (!type || + (type && (type->type == ctx->digest->type)))) + goto skip_to_init; + if (!do_evp_md_engine(ctx, &type, impl)) + return 0; #endif if (ctx->digest != type) { +#ifdef OPENSSL_FIPS + if (FIPS_mode()) + { + if (!(type->flags & EVP_MD_FLAG_FIPS) + && !(ctx->flags & EVP_MD_CTX_FLAG_NON_FIPS_ALLOW)) + { + EVPerr(EVP_F_EVP_DIGESTINIT_EX, EVP_R_DISABLED_FOR_FIPS); + ctx->digest = &bad_md; + return 0; + } + } +#endif if (ctx->digest && ctx->digest->ctx_size) OPENSSL_free(ctx->md_data); ctx->digest=type; @@ -202,7 +302,7 @@ int EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *impl) ctx->md_data=OPENSSL_malloc(type->ctx_size); } #ifndef OPENSSL_NO_ENGINE -skip_to_init: + skip_to_init: #endif return ctx->digest->init(ctx); } @@ -210,6 +310,9 @@ skip_to_init: int EVP_DigestUpdate(EVP_MD_CTX *ctx, const void *data, size_t count) { +#ifdef OPENSSL_FIPS + FIPS_selftest_check(); +#endif return ctx->digest->update(ctx,data,count); } @@ -226,6 +329,9 @@ int EVP_DigestFinal(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *size) int EVP_DigestFinal_ex(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *size) { int ret; +#ifdef OPENSSL_FIPS + FIPS_selftest_check(); +#endif OPENSSL_assert(ctx->digest->md_size <= EVP_MAX_MD_SIZE); ret=ctx->digest->final(ctx,md); @@ -234,7 +340,7 @@ int EVP_DigestFinal_ex(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *size) if (ctx->digest->cleanup) { ctx->digest->cleanup(ctx); - EVP_MD_CTX_set_flags(ctx,EVP_MD_CTX_FLAG_CLEANED); + M_EVP_MD_CTX_set_flags(ctx,EVP_MD_CTX_FLAG_CLEANED); } memset(ctx->md_data,0,ctx->digest->ctx_size); return ret; @@ -256,7 +362,7 @@ int EVP_MD_CTX_copy_ex(EVP_MD_CTX *out, const EVP_MD_CTX *in) } #ifndef OPENSSL_NO_ENGINE /* Make sure it's safe to copy a digest context using an ENGINE */ - if (in->engine && !ENGINE_init(in->engine)) + if (in->engine && !do_engine_init(in->engine)) { EVPerr(EVP_F_EVP_MD_CTX_COPY_EX,ERR_R_ENGINE_LIB); return 0; @@ -266,7 +372,7 @@ int EVP_MD_CTX_copy_ex(EVP_MD_CTX *out, const EVP_MD_CTX *in) if (out->digest == in->digest) { tmp_buf = out->md_data; - EVP_MD_CTX_set_flags(out,EVP_MD_CTX_FLAG_REUSE); + M_EVP_MD_CTX_set_flags(out,EVP_MD_CTX_FLAG_REUSE); } else tmp_buf = NULL; EVP_MD_CTX_cleanup(out); @@ -292,7 +398,7 @@ int EVP_Digest(const void *data, size_t count, int ret; EVP_MD_CTX_init(&ctx); - EVP_MD_CTX_set_flags(&ctx,EVP_MD_CTX_FLAG_ONESHOT); + M_EVP_MD_CTX_set_flags(&ctx,EVP_MD_CTX_FLAG_ONESHOT); ret=EVP_DigestInit_ex(&ctx, type, impl) && EVP_DigestUpdate(&ctx, data, count) && EVP_DigestFinal_ex(&ctx, md, size); @@ -314,10 +420,10 @@ int EVP_MD_CTX_cleanup(EVP_MD_CTX *ctx) * because sometimes only copies of the context are ever finalised. */ if (ctx->digest && ctx->digest->cleanup - && !EVP_MD_CTX_test_flags(ctx,EVP_MD_CTX_FLAG_CLEANED)) + && !M_EVP_MD_CTX_test_flags(ctx,EVP_MD_CTX_FLAG_CLEANED)) ctx->digest->cleanup(ctx); if (ctx->digest && ctx->digest->ctx_size && ctx->md_data - && !EVP_MD_CTX_test_flags(ctx, EVP_MD_CTX_FLAG_REUSE)) + && !M_EVP_MD_CTX_test_flags(ctx, EVP_MD_CTX_FLAG_REUSE)) { OPENSSL_cleanse(ctx->md_data,ctx->digest->ctx_size); OPENSSL_free(ctx->md_data); @@ -326,7 +432,7 @@ int EVP_MD_CTX_cleanup(EVP_MD_CTX *ctx) if(ctx->engine) /* The EVP_MD we used belongs to an ENGINE, release the * functional reference we held for this reason. */ - ENGINE_finish(ctx->engine); + do_engine_finish(ctx->engine); #endif memset(ctx,'\0',sizeof *ctx); diff --git a/src/lib/libcrypto/evp/e_aes.c b/src/lib/libcrypto/evp/e_aes.c index bd6c0a3a62..c9a5ee8d75 100644 --- a/src/lib/libcrypto/evp/e_aes.c +++ b/src/lib/libcrypto/evp/e_aes.c @@ -69,32 +69,29 @@ typedef struct IMPLEMENT_BLOCK_CIPHER(aes_128, ks, AES, EVP_AES_KEY, NID_aes_128, 16, 16, 16, 128, - 0, aes_init_key, NULL, - EVP_CIPHER_set_asn1_iv, - EVP_CIPHER_get_asn1_iv, - NULL) + EVP_CIPH_FLAG_FIPS|EVP_CIPH_FLAG_DEFAULT_ASN1, + aes_init_key, + NULL, NULL, NULL, NULL) IMPLEMENT_BLOCK_CIPHER(aes_192, ks, AES, EVP_AES_KEY, NID_aes_192, 16, 24, 16, 128, - 0, aes_init_key, NULL, - EVP_CIPHER_set_asn1_iv, - EVP_CIPHER_get_asn1_iv, - NULL) + EVP_CIPH_FLAG_FIPS|EVP_CIPH_FLAG_DEFAULT_ASN1, + aes_init_key, + NULL, NULL, NULL, NULL) IMPLEMENT_BLOCK_CIPHER(aes_256, ks, AES, EVP_AES_KEY, NID_aes_256, 16, 32, 16, 128, - 0, aes_init_key, NULL, - EVP_CIPHER_set_asn1_iv, - EVP_CIPHER_get_asn1_iv, - NULL) + EVP_CIPH_FLAG_FIPS|EVP_CIPH_FLAG_DEFAULT_ASN1, + aes_init_key, + NULL, NULL, NULL, NULL) -#define IMPLEMENT_AES_CFBR(ksize,cbits) IMPLEMENT_CFBR(aes,AES,EVP_AES_KEY,ks,ksize,cbits,16) +#define IMPLEMENT_AES_CFBR(ksize,cbits,flags) IMPLEMENT_CFBR(aes,AES,EVP_AES_KEY,ks,ksize,cbits,16,flags) -IMPLEMENT_AES_CFBR(128,1) -IMPLEMENT_AES_CFBR(192,1) -IMPLEMENT_AES_CFBR(256,1) +IMPLEMENT_AES_CFBR(128,1,EVP_CIPH_FLAG_FIPS) +IMPLEMENT_AES_CFBR(192,1,EVP_CIPH_FLAG_FIPS) +IMPLEMENT_AES_CFBR(256,1,EVP_CIPH_FLAG_FIPS) -IMPLEMENT_AES_CFBR(128,8) -IMPLEMENT_AES_CFBR(192,8) -IMPLEMENT_AES_CFBR(256,8) +IMPLEMENT_AES_CFBR(128,8,EVP_CIPH_FLAG_FIPS) +IMPLEMENT_AES_CFBR(192,8,EVP_CIPH_FLAG_FIPS) +IMPLEMENT_AES_CFBR(256,8,EVP_CIPH_FLAG_FIPS) static int aes_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, const unsigned char *iv, int enc) diff --git a/src/lib/libcrypto/evp/e_camellia.c b/src/lib/libcrypto/evp/e_camellia.c index a7b40d1c60..365d397164 100644 --- a/src/lib/libcrypto/evp/e_camellia.c +++ b/src/lib/libcrypto/evp/e_camellia.c @@ -93,7 +93,7 @@ IMPLEMENT_BLOCK_CIPHER(camellia_256, ks, Camellia, EVP_CAMELLIA_KEY, EVP_CIPHER_get_asn1_iv, NULL) -#define IMPLEMENT_CAMELLIA_CFBR(ksize,cbits) IMPLEMENT_CFBR(camellia,Camellia,EVP_CAMELLIA_KEY,ks,ksize,cbits,16) +#define IMPLEMENT_CAMELLIA_CFBR(ksize,cbits) IMPLEMENT_CFBR(camellia,Camellia,EVP_CAMELLIA_KEY,ks,ksize,cbits,16,0) IMPLEMENT_CAMELLIA_CFBR(128,1) IMPLEMENT_CAMELLIA_CFBR(192,1) diff --git a/src/lib/libcrypto/evp/e_des.c b/src/lib/libcrypto/evp/e_des.c index 856323648c..04376df232 100644 --- a/src/lib/libcrypto/evp/e_des.c +++ b/src/lib/libcrypto/evp/e_des.c @@ -129,18 +129,21 @@ static int des_cfb8_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, } BLOCK_CIPHER_defs(des, DES_key_schedule, NID_des, 8, 8, 8, 64, - EVP_CIPH_RAND_KEY, des_init_key, NULL, + EVP_CIPH_RAND_KEY, + des_init_key, NULL, EVP_CIPHER_set_asn1_iv, EVP_CIPHER_get_asn1_iv, des_ctrl) BLOCK_CIPHER_def_cfb(des,DES_key_schedule,NID_des,8,8,1, - EVP_CIPH_RAND_KEY, des_init_key,NULL, + EVP_CIPH_RAND_KEY, + des_init_key, NULL, EVP_CIPHER_set_asn1_iv, EVP_CIPHER_get_asn1_iv,des_ctrl) BLOCK_CIPHER_def_cfb(des,DES_key_schedule,NID_des,8,8,8, - EVP_CIPH_RAND_KEY,des_init_key,NULL, + EVP_CIPH_RAND_KEY, + des_init_key,NULL, EVP_CIPHER_set_asn1_iv, EVP_CIPHER_get_asn1_iv,des_ctrl) diff --git a/src/lib/libcrypto/evp/e_des3.c b/src/lib/libcrypto/evp/e_des3.c index ac148efab2..f910af19b1 100644 --- a/src/lib/libcrypto/evp/e_des3.c +++ b/src/lib/libcrypto/evp/e_des3.c @@ -111,8 +111,7 @@ static int des_ede_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, #ifdef KSSL_DEBUG { int i; - char *cp; - printf("des_ede_cbc_cipher(ctx=%lx, buflen=%d)\n", ctx, ctx->buf_len); + printf("des_ede_cbc_cipher(ctx=%lx, buflen=%d)\n", (unsigned long)ctx, ctx->buf_len); printf("\t iv= "); for(i=0;i<8;i++) printf("%02X",ctx->iv[i]); @@ -164,9 +163,9 @@ static int des_ede3_cfb8_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, } BLOCK_CIPHER_defs(des_ede, DES_EDE_KEY, NID_des_ede, 8, 16, 8, 64, - EVP_CIPH_RAND_KEY, des_ede_init_key, NULL, - EVP_CIPHER_set_asn1_iv, - EVP_CIPHER_get_asn1_iv, + EVP_CIPH_RAND_KEY|EVP_CIPH_FLAG_FIPS|EVP_CIPH_FLAG_DEFAULT_ASN1, + des_ede_init_key, + NULL, NULL, NULL, des3_ctrl) #define des_ede3_cfb64_cipher des_ede_cfb64_cipher @@ -175,21 +174,21 @@ BLOCK_CIPHER_defs(des_ede, DES_EDE_KEY, NID_des_ede, 8, 16, 8, 64, #define des_ede3_ecb_cipher des_ede_ecb_cipher BLOCK_CIPHER_defs(des_ede3, DES_EDE_KEY, NID_des_ede3, 8, 24, 8, 64, - EVP_CIPH_RAND_KEY, des_ede3_init_key, NULL, - EVP_CIPHER_set_asn1_iv, - EVP_CIPHER_get_asn1_iv, + EVP_CIPH_RAND_KEY|EVP_CIPH_FLAG_FIPS|EVP_CIPH_FLAG_DEFAULT_ASN1, + des_ede3_init_key, + NULL, NULL, NULL, des3_ctrl) BLOCK_CIPHER_def_cfb(des_ede3,DES_EDE_KEY,NID_des_ede3,24,8,1, - EVP_CIPH_RAND_KEY, des_ede3_init_key,NULL, - EVP_CIPHER_set_asn1_iv, - EVP_CIPHER_get_asn1_iv, + EVP_CIPH_RAND_KEY|EVP_CIPH_FLAG_FIPS|EVP_CIPH_FLAG_DEFAULT_ASN1, + des_ede3_init_key, + NULL, NULL, NULL, des3_ctrl) BLOCK_CIPHER_def_cfb(des_ede3,DES_EDE_KEY,NID_des_ede3,24,8,8, - EVP_CIPH_RAND_KEY, des_ede3_init_key,NULL, - EVP_CIPHER_set_asn1_iv, - EVP_CIPHER_get_asn1_iv, + EVP_CIPH_RAND_KEY|EVP_CIPH_FLAG_FIPS|EVP_CIPH_FLAG_DEFAULT_ASN1, + des_ede3_init_key, + NULL, NULL, NULL, des3_ctrl) static int des_ede_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, @@ -216,7 +215,7 @@ static int des_ede3_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, #ifdef KSSL_DEBUG { int i; - printf("des_ede3_init_key(ctx=%lx)\n", ctx); + printf("des_ede3_init_key(ctx=%lx)\n", (unsigned long)ctx); printf("\tKEY= "); for(i=0;i<24;i++) printf("%02X",key[i]); printf("\n"); printf("\t IV= "); diff --git a/src/lib/libcrypto/evp/e_null.c b/src/lib/libcrypto/evp/e_null.c index 5205259f18..0872d733e4 100644 --- a/src/lib/libcrypto/evp/e_null.c +++ b/src/lib/libcrypto/evp/e_null.c @@ -69,7 +69,7 @@ static const EVP_CIPHER n_cipher= { NID_undef, 1,0,0, - 0, + EVP_CIPH_FLAG_FIPS, null_init_key, null_cipher, NULL, diff --git a/src/lib/libcrypto/evp/e_rc4.c b/src/lib/libcrypto/evp/e_rc4.c index 67af850bea..55baad7446 100644 --- a/src/lib/libcrypto/evp/e_rc4.c +++ b/src/lib/libcrypto/evp/e_rc4.c @@ -64,6 +64,7 @@ #include #include #include +#include "evp_locl.h" /* FIXME: surely this is available elsewhere? */ #define EVP_RC4_KEY_SIZE 16 diff --git a/src/lib/libcrypto/evp/evp.h b/src/lib/libcrypto/evp/evp.h index bdd3b7ecaa..79c097181f 100644 --- a/src/lib/libcrypto/evp/evp.h +++ b/src/lib/libcrypto/evp/evp.h @@ -75,6 +75,10 @@ #include #endif +#ifdef OPENSSL_FIPS +#include +#endif + /* #define EVP_RC2_KEY_SIZE 16 #define EVP_RC4_KEY_SIZE 16 @@ -250,9 +254,19 @@ typedef int evp_verify_method(int type,const unsigned char *m, unsigned int m_length,const unsigned char *sigbuf, unsigned int siglen, void *key); +typedef struct + { + EVP_MD_CTX *mctx; + void *key; + } EVP_MD_SVCTX; + #define EVP_MD_FLAG_ONESHOT 0x0001 /* digest can only handle a single * block */ +#define EVP_MD_FLAG_FIPS 0x0400 /* Note if suitable for use in FIPS mode */ + +#define EVP_MD_FLAG_SVCTX 0x0800 /* pass EVP_MD_SVCTX to sign/verify */ + #define EVP_PKEY_NULL_method NULL,NULL,{0,0,0,0} #ifndef OPENSSL_NO_DSA @@ -303,6 +317,17 @@ struct env_md_ctx_st * cleaned */ #define EVP_MD_CTX_FLAG_REUSE 0x0004 /* Don't free up ctx->md_data * in EVP_MD_CTX_cleanup */ +#define EVP_MD_CTX_FLAG_NON_FIPS_ALLOW 0x0008 /* Allow use of non FIPS digest + * in FIPS mode */ + +#define EVP_MD_CTX_FLAG_PAD_MASK 0xF0 /* RSA mode to use */ +#define EVP_MD_CTX_FLAG_PAD_PKCS1 0x00 /* PKCS#1 v1.5 mode */ +#define EVP_MD_CTX_FLAG_PAD_X931 0x10 /* X9.31 mode */ +#define EVP_MD_CTX_FLAG_PAD_PSS 0x20 /* PSS mode */ +#define M_EVP_MD_CTX_FLAG_PSS_SALT(ctx) \ + ((ctx->flags>>16) &0xFFFF) /* seed length */ +#define EVP_MD_CTX_FLAG_PSS_MDLEN 0xFFFF /* salt len same as digest */ +#define EVP_MD_CTX_FLAG_PSS_MREC 0xFFFE /* salt max or auto recovered */ struct evp_cipher_st { @@ -347,6 +372,14 @@ struct evp_cipher_st #define EVP_CIPH_NO_PADDING 0x100 /* cipher handles random key generation */ #define EVP_CIPH_RAND_KEY 0x200 +/* Note if suitable for use in FIPS mode */ +#define EVP_CIPH_FLAG_FIPS 0x400 +/* Allow non FIPS cipher in FIPS mode */ +#define EVP_CIPH_FLAG_NON_FIPS_ALLOW 0x800 +/* Allow use default ASN1 get/set iv */ +#define EVP_CIPH_FLAG_DEFAULT_ASN1 0x1000 +/* Buffer length in bits not bytes: CFB1 mode only */ +#define EVP_CIPH_FLAG_LENGTH_BITS 0x2000 /* ctrl() values */ @@ -429,6 +462,18 @@ typedef int (EVP_PBE_KEYGEN)(EVP_CIPHER_CTX *ctx, const char *pass, int passlen, #define EVP_get_cipherbynid(a) EVP_get_cipherbyname(OBJ_nid2sn(a)) #define EVP_get_cipherbyobj(a) EVP_get_cipherbynid(OBJ_obj2nid(a)) +/* Macros to reduce FIPS dependencies: do NOT use in applications */ +#define M_EVP_MD_size(e) ((e)->md_size) +#define M_EVP_MD_block_size(e) ((e)->block_size) +#define M_EVP_MD_CTX_set_flags(ctx,flgs) ((ctx)->flags|=(flgs)) +#define M_EVP_MD_CTX_clear_flags(ctx,flgs) ((ctx)->flags&=~(flgs)) +#define M_EVP_MD_CTX_test_flags(ctx,flgs) ((ctx)->flags&(flgs)) +#define M_EVP_MD_type(e) ((e)->type) +#define M_EVP_MD_CTX_type(e) M_EVP_MD_type(M_EVP_MD_CTX_md(e)) +#define M_EVP_MD_CTX_md(e) ((e)->digest) + +#define M_EVP_CIPHER_CTX_set_flags(ctx,flgs) ((ctx)->flags|=(flgs)) + int EVP_MD_type(const EVP_MD *md); #define EVP_MD_nid(e) EVP_MD_type(e) #define EVP_MD_name(e) OBJ_nid2sn(EVP_MD_nid(e)) @@ -524,6 +569,10 @@ int EVP_BytesToKey(const EVP_CIPHER *type,const EVP_MD *md, const unsigned char *salt, const unsigned char *data, int datal, int count, unsigned char *key,unsigned char *iv); +void EVP_CIPHER_CTX_set_flags(EVP_CIPHER_CTX *ctx, int flags); +void EVP_CIPHER_CTX_clear_flags(EVP_CIPHER_CTX *ctx, int flags); +int EVP_CIPHER_CTX_test_flags(const EVP_CIPHER_CTX *ctx,int flags); + int EVP_EncryptInit(EVP_CIPHER_CTX *ctx,const EVP_CIPHER *cipher, const unsigned char *key, const unsigned char *iv); int EVP_EncryptInit_ex(EVP_CIPHER_CTX *ctx,const EVP_CIPHER *cipher, ENGINE *impl, @@ -879,6 +928,24 @@ int EVP_PBE_alg_add(int nid, const EVP_CIPHER *cipher, const EVP_MD *md, EVP_PBE_KEYGEN *keygen); void EVP_PBE_cleanup(void); +#ifdef OPENSSL_FIPS +#ifndef OPENSSL_NO_ENGINE +void int_EVP_MD_set_engine_callbacks( + int (*eng_md_init)(ENGINE *impl), + int (*eng_md_fin)(ENGINE *impl), + int (*eng_md_evp) + (EVP_MD_CTX *ctx, const EVP_MD **ptype, ENGINE *impl)); +void int_EVP_MD_init_engine_callbacks(void); +void int_EVP_CIPHER_set_engine_callbacks( + int (*eng_ciph_fin)(ENGINE *impl), + int (*eng_ciph_evp) + (EVP_CIPHER_CTX *ctx, const EVP_CIPHER **pciph, ENGINE *impl)); +void int_EVP_CIPHER_init_engine_callbacks(void); +#endif +#endif + +void EVP_add_alg_module(void); + /* BEGIN ERROR CODES */ /* The following lines are auto generated by the script mkerr.pl. Any changes * made after this point may be overwritten when the script is next run. @@ -889,16 +956,23 @@ void ERR_load_EVP_strings(void); /* Function codes. */ #define EVP_F_AES_INIT_KEY 133 +#define EVP_F_ALG_MODULE_INIT 138 #define EVP_F_CAMELLIA_INIT_KEY 159 #define EVP_F_D2I_PKEY 100 +#define EVP_F_DO_EVP_ENC_ENGINE 140 +#define EVP_F_DO_EVP_ENC_ENGINE_FULL 141 +#define EVP_F_DO_EVP_MD_ENGINE 139 +#define EVP_F_DO_EVP_MD_ENGINE_FULL 142 #define EVP_F_DSAPKEY2PKCS8 134 #define EVP_F_DSA_PKEY2PKCS8 135 #define EVP_F_ECDSA_PKEY2PKCS8 129 #define EVP_F_ECKEY_PKEY2PKCS8 132 +#define EVP_F_EVP_CIPHERINIT 137 #define EVP_F_EVP_CIPHERINIT_EX 123 #define EVP_F_EVP_CIPHER_CTX_CTRL 124 #define EVP_F_EVP_CIPHER_CTX_SET_KEY_LENGTH 122 #define EVP_F_EVP_DECRYPTFINAL_EX 101 +#define EVP_F_EVP_DIGESTINIT 136 #define EVP_F_EVP_DIGESTINIT_EX 128 #define EVP_F_EVP_ENCRYPTFINAL_EX 127 #define EVP_F_EVP_MD_CTX_COPY_EX 110 @@ -940,15 +1014,20 @@ void ERR_load_EVP_strings(void); #define EVP_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH 138 #define EVP_R_DECODE_ERROR 114 #define EVP_R_DIFFERENT_KEY_TYPES 101 +#define EVP_R_DISABLED_FOR_FIPS 144 #define EVP_R_ENCODE_ERROR 115 +#define EVP_R_ERROR_LOADING_SECTION 145 +#define EVP_R_ERROR_SETTING_FIPS_MODE 146 #define EVP_R_EVP_PBE_CIPHERINIT_ERROR 119 #define EVP_R_EXPECTING_AN_RSA_KEY 127 #define EVP_R_EXPECTING_A_DH_KEY 128 #define EVP_R_EXPECTING_A_DSA_KEY 129 #define EVP_R_EXPECTING_A_ECDSA_KEY 141 #define EVP_R_EXPECTING_A_EC_KEY 142 +#define EVP_R_FIPS_MODE_NOT_SUPPORTED 147 #define EVP_R_INITIALIZATION_ERROR 134 #define EVP_R_INPUT_NOT_INITIALIZED 111 +#define EVP_R_INVALID_FIPS_MODE 148 #define EVP_R_INVALID_KEY_LENGTH 130 #define EVP_R_IV_TOO_LARGE 102 #define EVP_R_KEYGEN_FAILURE 120 @@ -960,6 +1039,7 @@ void ERR_load_EVP_strings(void); #define EVP_R_NO_VERIFY_FUNCTION_CONFIGURED 105 #define EVP_R_PKCS8_UNKNOWN_BROKEN_TYPE 117 #define EVP_R_PUBLIC_KEY_NOT_RSA 106 +#define EVP_R_UNKNOWN_OPTION 149 #define EVP_R_UNKNOWN_PBE_ALGORITHM 121 #define EVP_R_UNSUPORTED_NUMBER_OF_ROUNDS 135 #define EVP_R_UNSUPPORTED_CIPHER 107 diff --git a/src/lib/libcrypto/evp/evp_enc.c b/src/lib/libcrypto/evp/evp_enc.c index a1904993bf..30e0ca4d9f 100644 --- a/src/lib/libcrypto/evp/evp_enc.c +++ b/src/lib/libcrypto/evp/evp_enc.c @@ -66,13 +66,15 @@ #endif #include "evp_locl.h" -const char EVP_version[]="EVP" OPENSSL_VERSION_PTEXT; +#ifdef OPENSSL_FIPS + #define M_do_cipher(ctx, out, in, inl) \ + EVP_Cipher(ctx,out,in,inl) +#else + #define M_do_cipher(ctx, out, in, inl) \ + ctx->cipher->do_cipher(ctx,out,in,inl) +#endif -void EVP_CIPHER_CTX_init(EVP_CIPHER_CTX *ctx) - { - memset(ctx,0,sizeof(EVP_CIPHER_CTX)); - /* ctx->cipher=NULL; */ - } +const char EVP_version[]="EVP" OPENSSL_VERSION_PTEXT; EVP_CIPHER_CTX *EVP_CIPHER_CTX_new(void) { @@ -90,144 +92,6 @@ int EVP_CipherInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, return EVP_CipherInit_ex(ctx,cipher,NULL,key,iv,enc); } -int EVP_CipherInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, ENGINE *impl, - const unsigned char *key, const unsigned char *iv, int enc) - { - if (enc == -1) - enc = ctx->encrypt; - else - { - if (enc) - enc = 1; - ctx->encrypt = enc; - } -#ifndef OPENSSL_NO_ENGINE - /* Whether it's nice or not, "Inits" can be used on "Final"'d contexts - * so this context may already have an ENGINE! Try to avoid releasing - * the previous handle, re-querying for an ENGINE, and having a - * reinitialisation, when it may all be unecessary. */ - if (ctx->engine && ctx->cipher && (!cipher || - (cipher && (cipher->nid == ctx->cipher->nid)))) - goto skip_to_init; -#endif - if (cipher) - { - /* Ensure a context left lying around from last time is cleared - * (the previous check attempted to avoid this if the same - * ENGINE and EVP_CIPHER could be used). */ - EVP_CIPHER_CTX_cleanup(ctx); - - /* Restore encrypt field: it is zeroed by cleanup */ - ctx->encrypt = enc; -#ifndef OPENSSL_NO_ENGINE - if(impl) - { - if (!ENGINE_init(impl)) - { - EVPerr(EVP_F_EVP_CIPHERINIT_EX, EVP_R_INITIALIZATION_ERROR); - return 0; - } - } - else - /* Ask if an ENGINE is reserved for this job */ - impl = ENGINE_get_cipher_engine(cipher->nid); - if(impl) - { - /* There's an ENGINE for this job ... (apparently) */ - const EVP_CIPHER *c = ENGINE_get_cipher(impl, cipher->nid); - if(!c) - { - /* One positive side-effect of US's export - * control history, is that we should at least - * be able to avoid using US mispellings of - * "initialisation"? */ - EVPerr(EVP_F_EVP_CIPHERINIT_EX, EVP_R_INITIALIZATION_ERROR); - return 0; - } - /* We'll use the ENGINE's private cipher definition */ - cipher = c; - /* Store the ENGINE functional reference so we know - * 'cipher' came from an ENGINE and we need to release - * it when done. */ - ctx->engine = impl; - } - else - ctx->engine = NULL; -#endif - - ctx->cipher=cipher; - if (ctx->cipher->ctx_size) - { - ctx->cipher_data=OPENSSL_malloc(ctx->cipher->ctx_size); - if (!ctx->cipher_data) - { - EVPerr(EVP_F_EVP_CIPHERINIT_EX, ERR_R_MALLOC_FAILURE); - return 0; - } - } - else - { - ctx->cipher_data = NULL; - } - ctx->key_len = cipher->key_len; - ctx->flags = 0; - if(ctx->cipher->flags & EVP_CIPH_CTRL_INIT) - { - if(!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_INIT, 0, NULL)) - { - EVPerr(EVP_F_EVP_CIPHERINIT_EX, EVP_R_INITIALIZATION_ERROR); - return 0; - } - } - } - else if(!ctx->cipher) - { - EVPerr(EVP_F_EVP_CIPHERINIT_EX, EVP_R_NO_CIPHER_SET); - return 0; - } -#ifndef OPENSSL_NO_ENGINE -skip_to_init: -#endif - /* we assume block size is a power of 2 in *cryptUpdate */ - OPENSSL_assert(ctx->cipher->block_size == 1 - || ctx->cipher->block_size == 8 - || ctx->cipher->block_size == 16); - - if(!(EVP_CIPHER_CTX_flags(ctx) & EVP_CIPH_CUSTOM_IV)) { - switch(EVP_CIPHER_CTX_mode(ctx)) { - - case EVP_CIPH_STREAM_CIPHER: - case EVP_CIPH_ECB_MODE: - break; - - case EVP_CIPH_CFB_MODE: - case EVP_CIPH_OFB_MODE: - - ctx->num = 0; - - case EVP_CIPH_CBC_MODE: - - OPENSSL_assert(EVP_CIPHER_CTX_iv_length(ctx) <= - (int)sizeof(ctx->iv)); - if(iv) memcpy(ctx->oiv, iv, EVP_CIPHER_CTX_iv_length(ctx)); - memcpy(ctx->iv, ctx->oiv, EVP_CIPHER_CTX_iv_length(ctx)); - break; - - default: - return 0; - break; - } - } - - if(key || (ctx->cipher->flags & EVP_CIPH_ALWAYS_CALL_INIT)) { - if(!ctx->cipher->init(ctx,key,iv,enc)) return 0; - } - ctx->buf_len=0; - ctx->final_used=0; - ctx->block_mask=ctx->cipher->block_size-1; - return 1; - } - int EVP_CipherUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl, const unsigned char *in, int inl) { @@ -279,10 +143,15 @@ int EVP_EncryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl, { int i,j,bl; - OPENSSL_assert(inl > 0); + if (inl <= 0) + { + *outl = 0; + return inl == 0; + } + if(ctx->buf_len == 0 && (inl&(ctx->block_mask)) == 0) { - if(ctx->cipher->do_cipher(ctx,out,in,inl)) + if(M_do_cipher(ctx,out,in,inl)) { *outl=inl; return 1; @@ -309,7 +178,7 @@ int EVP_EncryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl, { j=bl-i; memcpy(&(ctx->buf[i]),in,j); - if(!ctx->cipher->do_cipher(ctx,out,ctx->buf,bl)) return 0; + if(!M_do_cipher(ctx,out,ctx->buf,bl)) return 0; inl-=j; in+=j; out+=bl; @@ -322,7 +191,7 @@ int EVP_EncryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl, inl-=i; if (inl > 0) { - if(!ctx->cipher->do_cipher(ctx,out,in,inl)) return 0; + if(!M_do_cipher(ctx,out,in,inl)) return 0; *outl+=inl; } @@ -366,7 +235,7 @@ int EVP_EncryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl) n=b-bl; for (i=bl; ibuf[i]=n; - ret=ctx->cipher->do_cipher(ctx,out,ctx->buf,b); + ret=M_do_cipher(ctx,out,ctx->buf,b); if(ret) @@ -381,10 +250,10 @@ int EVP_DecryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl, int fix_len; unsigned int b; - if (inl == 0) + if (inl <= 0) { - *outl=0; - return 1; + *outl = 0; + return inl == 0; } if (ctx->flags & EVP_CIPH_NO_PADDING) @@ -488,28 +357,6 @@ void EVP_CIPHER_CTX_free(EVP_CIPHER_CTX *ctx) } } -int EVP_CIPHER_CTX_cleanup(EVP_CIPHER_CTX *c) - { - if (c->cipher != NULL) - { - if(c->cipher->cleanup && !c->cipher->cleanup(c)) - return 0; - /* Cleanse cipher context data */ - if (c->cipher_data) - OPENSSL_cleanse(c->cipher_data, c->cipher->ctx_size); - } - if (c->cipher_data) - OPENSSL_free(c->cipher_data); -#ifndef OPENSSL_NO_ENGINE - if (c->engine) - /* The EVP_CIPHER we used belongs to an ENGINE, release the - * functional reference we held for this reason. */ - ENGINE_finish(c->engine); -#endif - memset(c,0,sizeof(EVP_CIPHER_CTX)); - return 1; - } - int EVP_CIPHER_CTX_set_key_length(EVP_CIPHER_CTX *c, int keylen) { if(c->cipher->flags & EVP_CIPH_CUSTOM_KEY_LENGTH) @@ -531,27 +378,6 @@ int EVP_CIPHER_CTX_set_padding(EVP_CIPHER_CTX *ctx, int pad) return 1; } -int EVP_CIPHER_CTX_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr) -{ - int ret; - if(!ctx->cipher) { - EVPerr(EVP_F_EVP_CIPHER_CTX_CTRL, EVP_R_NO_CIPHER_SET); - return 0; - } - - if(!ctx->cipher->ctrl) { - EVPerr(EVP_F_EVP_CIPHER_CTX_CTRL, EVP_R_CTRL_NOT_IMPLEMENTED); - return 0; - } - - ret = ctx->cipher->ctrl(ctx, type, arg, ptr); - if(ret == -1) { - EVPerr(EVP_F_EVP_CIPHER_CTX_CTRL, EVP_R_CTRL_OPERATION_NOT_IMPLEMENTED); - return 0; - } - return ret; -} - int EVP_CIPHER_CTX_rand_key(EVP_CIPHER_CTX *ctx, unsigned char *key) { if (ctx->cipher->flags & EVP_CIPH_RAND_KEY) @@ -561,3 +387,54 @@ int EVP_CIPHER_CTX_rand_key(EVP_CIPHER_CTX *ctx, unsigned char *key) return 1; } +#ifndef OPENSSL_NO_ENGINE + +#ifdef OPENSSL_FIPS + +static int do_evp_enc_engine_full(EVP_CIPHER_CTX *ctx, const EVP_CIPHER **pcipher, ENGINE *impl) + { + if(impl) + { + if (!ENGINE_init(impl)) + { + EVPerr(EVP_F_DO_EVP_ENC_ENGINE_FULL, EVP_R_INITIALIZATION_ERROR); + return 0; + } + } + else + /* Ask if an ENGINE is reserved for this job */ + impl = ENGINE_get_cipher_engine((*pcipher)->nid); + if(impl) + { + /* There's an ENGINE for this job ... (apparently) */ + const EVP_CIPHER *c = ENGINE_get_cipher(impl, (*pcipher)->nid); + if(!c) + { + /* One positive side-effect of US's export + * control history, is that we should at least + * be able to avoid using US mispellings of + * "initialisation"? */ + EVPerr(EVP_F_DO_EVP_ENC_ENGINE_FULL, EVP_R_INITIALIZATION_ERROR); + return 0; + } + /* We'll use the ENGINE's private cipher definition */ + *pcipher = c; + /* Store the ENGINE functional reference so we know + * 'cipher' came from an ENGINE and we need to release + * it when done. */ + ctx->engine = impl; + } + else + ctx->engine = NULL; + return 1; + } + +void int_EVP_CIPHER_init_engine_callbacks(void) + { + int_EVP_CIPHER_set_engine_callbacks( + ENGINE_finish, do_evp_enc_engine_full); + } + +#endif + +#endif diff --git a/src/lib/libcrypto/evp/evp_err.c b/src/lib/libcrypto/evp/evp_err.c index e8c9e8de9c..b5b900d4fe 100644 --- a/src/lib/libcrypto/evp/evp_err.c +++ b/src/lib/libcrypto/evp/evp_err.c @@ -1,6 +1,6 @@ /* crypto/evp/evp_err.c */ /* ==================================================================== - * Copyright (c) 1999-2005 The OpenSSL Project. All rights reserved. + * Copyright (c) 1999-2007 The OpenSSL Project. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -71,16 +71,23 @@ static ERR_STRING_DATA EVP_str_functs[]= { {ERR_FUNC(EVP_F_AES_INIT_KEY), "AES_INIT_KEY"}, +{ERR_FUNC(EVP_F_ALG_MODULE_INIT), "ALG_MODULE_INIT"}, {ERR_FUNC(EVP_F_CAMELLIA_INIT_KEY), "CAMELLIA_INIT_KEY"}, {ERR_FUNC(EVP_F_D2I_PKEY), "D2I_PKEY"}, +{ERR_FUNC(EVP_F_DO_EVP_ENC_ENGINE), "DO_EVP_ENC_ENGINE"}, +{ERR_FUNC(EVP_F_DO_EVP_ENC_ENGINE_FULL), "DO_EVP_ENC_ENGINE_FULL"}, +{ERR_FUNC(EVP_F_DO_EVP_MD_ENGINE), "DO_EVP_MD_ENGINE"}, +{ERR_FUNC(EVP_F_DO_EVP_MD_ENGINE_FULL), "DO_EVP_MD_ENGINE_FULL"}, {ERR_FUNC(EVP_F_DSAPKEY2PKCS8), "DSAPKEY2PKCS8"}, {ERR_FUNC(EVP_F_DSA_PKEY2PKCS8), "DSA_PKEY2PKCS8"}, {ERR_FUNC(EVP_F_ECDSA_PKEY2PKCS8), "ECDSA_PKEY2PKCS8"}, {ERR_FUNC(EVP_F_ECKEY_PKEY2PKCS8), "ECKEY_PKEY2PKCS8"}, +{ERR_FUNC(EVP_F_EVP_CIPHERINIT), "EVP_CipherInit"}, {ERR_FUNC(EVP_F_EVP_CIPHERINIT_EX), "EVP_CipherInit_ex"}, {ERR_FUNC(EVP_F_EVP_CIPHER_CTX_CTRL), "EVP_CIPHER_CTX_ctrl"}, {ERR_FUNC(EVP_F_EVP_CIPHER_CTX_SET_KEY_LENGTH), "EVP_CIPHER_CTX_set_key_length"}, {ERR_FUNC(EVP_F_EVP_DECRYPTFINAL_EX), "EVP_DecryptFinal_ex"}, +{ERR_FUNC(EVP_F_EVP_DIGESTINIT), "EVP_DigestInit"}, {ERR_FUNC(EVP_F_EVP_DIGESTINIT_EX), "EVP_DigestInit_ex"}, {ERR_FUNC(EVP_F_EVP_ENCRYPTFINAL_EX), "EVP_EncryptFinal_ex"}, {ERR_FUNC(EVP_F_EVP_MD_CTX_COPY_EX), "EVP_MD_CTX_copy_ex"}, @@ -125,15 +132,20 @@ static ERR_STRING_DATA EVP_str_reasons[]= {ERR_REASON(EVP_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH),"data not multiple of block length"}, {ERR_REASON(EVP_R_DECODE_ERROR) ,"decode error"}, {ERR_REASON(EVP_R_DIFFERENT_KEY_TYPES) ,"different key types"}, +{ERR_REASON(EVP_R_DISABLED_FOR_FIPS) ,"disabled for fips"}, {ERR_REASON(EVP_R_ENCODE_ERROR) ,"encode error"}, +{ERR_REASON(EVP_R_ERROR_LOADING_SECTION) ,"error loading section"}, +{ERR_REASON(EVP_R_ERROR_SETTING_FIPS_MODE),"error setting fips mode"}, {ERR_REASON(EVP_R_EVP_PBE_CIPHERINIT_ERROR),"evp pbe cipherinit error"}, {ERR_REASON(EVP_R_EXPECTING_AN_RSA_KEY) ,"expecting an rsa key"}, {ERR_REASON(EVP_R_EXPECTING_A_DH_KEY) ,"expecting a dh key"}, {ERR_REASON(EVP_R_EXPECTING_A_DSA_KEY) ,"expecting a dsa key"}, {ERR_REASON(EVP_R_EXPECTING_A_ECDSA_KEY) ,"expecting a ecdsa key"}, {ERR_REASON(EVP_R_EXPECTING_A_EC_KEY) ,"expecting a ec key"}, +{ERR_REASON(EVP_R_FIPS_MODE_NOT_SUPPORTED),"fips mode not supported"}, {ERR_REASON(EVP_R_INITIALIZATION_ERROR) ,"initialization error"}, {ERR_REASON(EVP_R_INPUT_NOT_INITIALIZED) ,"input not initialized"}, +{ERR_REASON(EVP_R_INVALID_FIPS_MODE) ,"invalid fips mode"}, {ERR_REASON(EVP_R_INVALID_KEY_LENGTH) ,"invalid key length"}, {ERR_REASON(EVP_R_IV_TOO_LARGE) ,"iv too large"}, {ERR_REASON(EVP_R_KEYGEN_FAILURE) ,"keygen failure"}, @@ -145,6 +157,8 @@ static ERR_STRING_DATA EVP_str_reasons[]= {ERR_REASON(EVP_R_NO_VERIFY_FUNCTION_CONFIGURED),"no verify function configured"}, {ERR_REASON(EVP_R_PKCS8_UNKNOWN_BROKEN_TYPE),"pkcs8 unknown broken type"}, {ERR_REASON(EVP_R_PUBLIC_KEY_NOT_RSA) ,"public key not rsa"}, +{ERR_REASON(EVP_R_SEED_KEY_SETUP_FAILED) ,"seed key setup failed"}, +{ERR_REASON(EVP_R_UNKNOWN_OPTION) ,"unknown option"}, {ERR_REASON(EVP_R_UNKNOWN_PBE_ALGORITHM) ,"unknown pbe algorithm"}, {ERR_REASON(EVP_R_UNSUPORTED_NUMBER_OF_ROUNDS),"unsuported number of rounds"}, {ERR_REASON(EVP_R_UNSUPPORTED_CIPHER) ,"unsupported cipher"}, diff --git a/src/lib/libcrypto/evp/evp_lib.c b/src/lib/libcrypto/evp/evp_lib.c index edb28ef38e..174cf6c594 100644 --- a/src/lib/libcrypto/evp/evp_lib.c +++ b/src/lib/libcrypto/evp/evp_lib.c @@ -67,6 +67,8 @@ int EVP_CIPHER_param_to_asn1(EVP_CIPHER_CTX *c, ASN1_TYPE *type) if (c->cipher->set_asn1_parameters != NULL) ret=c->cipher->set_asn1_parameters(c,type); + else if (c->cipher->flags & EVP_CIPH_FLAG_DEFAULT_ASN1) + ret=EVP_CIPHER_set_asn1_iv(c, type); else ret=-1; return(ret); @@ -78,6 +80,8 @@ int EVP_CIPHER_asn1_to_param(EVP_CIPHER_CTX *c, ASN1_TYPE *type) if (c->cipher->get_asn1_parameters != NULL) ret=c->cipher->get_asn1_parameters(c,type); + else if (c->cipher->flags & EVP_CIPH_FLAG_DEFAULT_ASN1) + ret=EVP_CIPHER_get_asn1_iv(c, type); else ret=-1; return(ret); @@ -178,11 +182,6 @@ int EVP_CIPHER_CTX_block_size(const EVP_CIPHER_CTX *ctx) return ctx->cipher->block_size; } -int EVP_Cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, unsigned int inl) - { - return ctx->cipher->do_cipher(ctx,out,in,inl); - } - const EVP_CIPHER *EVP_CIPHER_CTX_cipher(const EVP_CIPHER_CTX *ctx) { return ctx->cipher; @@ -193,11 +192,6 @@ unsigned long EVP_CIPHER_flags(const EVP_CIPHER *cipher) return cipher->flags; } -unsigned long EVP_CIPHER_CTX_flags(const EVP_CIPHER_CTX *ctx) - { - return ctx->cipher->flags; - } - void *EVP_CIPHER_CTX_get_app_data(const EVP_CIPHER_CTX *ctx) { return ctx->app_data; @@ -213,11 +207,6 @@ int EVP_CIPHER_iv_length(const EVP_CIPHER *cipher) return cipher->iv_len; } -int EVP_CIPHER_CTX_iv_length(const EVP_CIPHER_CTX *ctx) - { - return ctx->cipher->iv_len; - } - int EVP_CIPHER_key_length(const EVP_CIPHER *cipher) { return cipher->key_len; @@ -228,11 +217,6 @@ int EVP_CIPHER_CTX_key_length(const EVP_CIPHER_CTX *ctx) return ctx->key_len; } -int EVP_CIPHER_nid(const EVP_CIPHER *cipher) - { - return cipher->nid; - } - int EVP_CIPHER_CTX_nid(const EVP_CIPHER_CTX *ctx) { return ctx->cipher->nid; @@ -277,3 +261,18 @@ int EVP_MD_CTX_test_flags(const EVP_MD_CTX *ctx, int flags) { return (ctx->flags & flags); } + +void EVP_CIPHER_CTX_set_flags(EVP_CIPHER_CTX *ctx, int flags) + { + ctx->flags |= flags; + } + +void EVP_CIPHER_CTX_clear_flags(EVP_CIPHER_CTX *ctx, int flags) + { + ctx->flags &= ~flags; + } + +int EVP_CIPHER_CTX_test_flags(const EVP_CIPHER_CTX *ctx, int flags) + { + return (ctx->flags & flags); + } diff --git a/src/lib/libcrypto/evp/evp_locl.h b/src/lib/libcrypto/evp/evp_locl.h index 073b0adcff..eabcc96f30 100644 --- a/src/lib/libcrypto/evp/evp_locl.h +++ b/src/lib/libcrypto/evp/evp_locl.h @@ -1,5 +1,5 @@ /* evp_locl.h */ -/* 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. */ /* ==================================================================== @@ -92,7 +92,7 @@ static int cname##_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const uns #define BLOCK_CIPHER_func_cfb(cname, cprefix, cbits, kstruct, ksched) \ static int cname##_cfb##cbits##_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, unsigned int inl) \ {\ - cprefix##_cfb##cbits##_encrypt(in, out, (long)(cbits==1?inl*8:inl), &((kstruct *)ctx->cipher_data)->ksched, ctx->iv, &ctx->num, ctx->encrypt);\ + cprefix##_cfb##cbits##_encrypt(in, out, (long)((cbits==1) && !(ctx->flags & EVP_CIPH_FLAG_LENGTH_BITS) ?inl*8:inl), &((kstruct *)ctx->cipher_data)->ksched, ctx->iv, &ctx->num, ctx->encrypt);\ return 1;\ } @@ -226,11 +226,27 @@ const EVP_CIPHER *EVP_##cname##_ecb(void) { return &cname##_ecb; } #define EVP_C_DATA(kstruct, ctx) ((kstruct *)(ctx)->cipher_data) -#define IMPLEMENT_CFBR(cipher,cprefix,kstruct,ksched,keysize,cbits,iv_len) \ +#define IMPLEMENT_CFBR(cipher,cprefix,kstruct,ksched,keysize,cbits,iv_len,fl) \ BLOCK_CIPHER_func_cfb(cipher##_##keysize,cprefix,cbits,kstruct,ksched) \ BLOCK_CIPHER_def_cfb(cipher##_##keysize,kstruct, \ NID_##cipher##_##keysize, keysize/8, iv_len, cbits, \ - 0, cipher##_init_key, NULL, \ - EVP_CIPHER_set_asn1_iv, \ - EVP_CIPHER_get_asn1_iv, \ - NULL) + (fl)|EVP_CIPH_FLAG_DEFAULT_ASN1, \ + cipher##_init_key, NULL, NULL, NULL, NULL) + +#ifdef OPENSSL_FIPS +#define RC2_set_key private_RC2_set_key +#define RC4_set_key private_RC4_set_key +#define CAST_set_key private_CAST_set_key +#define RC5_32_set_key private_RC5_32_set_key +#define BF_set_key private_BF_set_key +#define Camellia_set_key private_Camellia_set_key +#define idea_set_encrypt_key private_idea_set_encrypt_key + +#define MD5_Init private_MD5_Init +#define MD4_Init private_MD4_Init +#define MD2_Init private_MD2_Init +#define MDC2_Init private_MDC2_Init +#define SHA_Init private_SHA_Init + +#endif + diff --git a/src/lib/libcrypto/evp/evp_pbe.c b/src/lib/libcrypto/evp/evp_pbe.c index c26d2de0f3..5e830be65f 100644 --- a/src/lib/libcrypto/evp/evp_pbe.c +++ b/src/lib/libcrypto/evp/evp_pbe.c @@ -1,5 +1,5 @@ /* evp_pbe.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. */ /* ==================================================================== diff --git a/src/lib/libcrypto/evp/evp_pkey.c b/src/lib/libcrypto/evp/evp_pkey.c index 0147f3e02a..10d9e9e772 100644 --- a/src/lib/libcrypto/evp/evp_pkey.c +++ b/src/lib/libcrypto/evp/evp_pkey.c @@ -1,5 +1,5 @@ /* evp_pkey.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. */ /* ==================================================================== diff --git a/src/lib/libcrypto/evp/m_dss.c b/src/lib/libcrypto/evp/m_dss.c index a948c77fa4..6b0c0aa7a3 100644 --- a/src/lib/libcrypto/evp/m_dss.c +++ b/src/lib/libcrypto/evp/m_dss.c @@ -81,7 +81,7 @@ static const EVP_MD dsa_md= NID_dsaWithSHA, NID_dsaWithSHA, SHA_DIGEST_LENGTH, - 0, + EVP_MD_FLAG_FIPS, init, update, final, diff --git a/src/lib/libcrypto/evp/m_dss1.c b/src/lib/libcrypto/evp/m_dss1.c index c12e13972b..da8babc147 100644 --- a/src/lib/libcrypto/evp/m_dss1.c +++ b/src/lib/libcrypto/evp/m_dss1.c @@ -68,6 +68,8 @@ #include #endif +#ifndef OPENSSL_FIPS + static int init(EVP_MD_CTX *ctx) { return SHA1_Init(ctx->md_data); } @@ -98,3 +100,4 @@ const EVP_MD *EVP_dss1(void) return(&dss1_md); } #endif +#endif diff --git a/src/lib/libcrypto/evp/m_md4.c b/src/lib/libcrypto/evp/m_md4.c index 1e0b7c5b42..5cd2ab5ade 100644 --- a/src/lib/libcrypto/evp/m_md4.c +++ b/src/lib/libcrypto/evp/m_md4.c @@ -58,6 +58,7 @@ #include #include "cryptlib.h" +#include "evp_locl.h" #ifndef OPENSSL_NO_MD4 diff --git a/src/lib/libcrypto/evp/m_md5.c b/src/lib/libcrypto/evp/m_md5.c index 63c142119e..6455829671 100644 --- a/src/lib/libcrypto/evp/m_md5.c +++ b/src/lib/libcrypto/evp/m_md5.c @@ -62,6 +62,7 @@ #ifndef OPENSSL_NO_MD5 #include +#include "evp_locl.h" #include #include #include diff --git a/src/lib/libcrypto/evp/m_sha1.c b/src/lib/libcrypto/evp/m_sha1.c index 4679b1c463..471ec30be0 100644 --- a/src/lib/libcrypto/evp/m_sha1.c +++ b/src/lib/libcrypto/evp/m_sha1.c @@ -68,6 +68,8 @@ #include #endif +#ifndef OPENSSL_FIPS + static int init(EVP_MD_CTX *ctx) { return SHA1_Init(ctx->md_data); } @@ -97,7 +99,6 @@ const EVP_MD *EVP_sha1(void) { return(&sha1_md); } -#endif #ifndef OPENSSL_NO_SHA256 static int init224(EVP_MD_CTX *ctx) @@ -202,3 +203,7 @@ static const EVP_MD sha512_md= const EVP_MD *EVP_sha512(void) { return(&sha512_md); } #endif /* ifndef OPENSSL_NO_SHA512 */ + +#endif + +#endif diff --git a/src/lib/libcrypto/evp/names.c b/src/lib/libcrypto/evp/names.c index 88c1e780dd..e2e04c3570 100644 --- a/src/lib/libcrypto/evp/names.c +++ b/src/lib/libcrypto/evp/names.c @@ -66,6 +66,10 @@ int EVP_add_cipher(const EVP_CIPHER *c) { int r; +#ifdef OPENSSL_FIPS + OPENSSL_init(); +#endif + r=OBJ_NAME_add(OBJ_nid2sn(c->nid),OBJ_NAME_TYPE_CIPHER_METH,(const char *)c); if (r == 0) return(0); r=OBJ_NAME_add(OBJ_nid2ln(c->nid),OBJ_NAME_TYPE_CIPHER_METH,(const char *)c); @@ -77,6 +81,9 @@ int EVP_add_digest(const EVP_MD *md) int r; const char *name; +#ifdef OPENSSL_FIPS + OPENSSL_init(); +#endif name=OBJ_nid2sn(md->type); r=OBJ_NAME_add(name,OBJ_NAME_TYPE_MD_METH,(const char *)md); if (r == 0) return(0); diff --git a/src/lib/libcrypto/evp/p5_crpt.c b/src/lib/libcrypto/evp/p5_crpt.c index 48d50014a0..2a265fdee2 100644 --- a/src/lib/libcrypto/evp/p5_crpt.c +++ b/src/lib/libcrypto/evp/p5_crpt.c @@ -1,5 +1,5 @@ /* p5_crpt.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. */ /* ==================================================================== diff --git a/src/lib/libcrypto/evp/p5_crpt2.c b/src/lib/libcrypto/evp/p5_crpt2.c index c969d5a206..6bec77baf9 100644 --- a/src/lib/libcrypto/evp/p5_crpt2.c +++ b/src/lib/libcrypto/evp/p5_crpt2.c @@ -1,5 +1,5 @@ /* p5_crpt2.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. */ /* ==================================================================== diff --git a/src/lib/libcrypto/evp/p_sign.c b/src/lib/libcrypto/evp/p_sign.c index e4ae5906f5..bf41a0db68 100644 --- a/src/lib/libcrypto/evp/p_sign.c +++ b/src/lib/libcrypto/evp/p_sign.c @@ -84,10 +84,6 @@ int EVP_SignFinal(EVP_MD_CTX *ctx, unsigned char *sigret, unsigned int *siglen, MS_STATIC EVP_MD_CTX tmp_ctx; *siglen=0; - EVP_MD_CTX_init(&tmp_ctx); - EVP_MD_CTX_copy_ex(&tmp_ctx,ctx); - EVP_DigestFinal_ex(&tmp_ctx,&(m[0]),&m_len); - EVP_MD_CTX_cleanup(&tmp_ctx); for (i=0; i<4; i++) { v=ctx->digest->required_pkey_type[i]; @@ -108,7 +104,23 @@ int EVP_SignFinal(EVP_MD_CTX *ctx, unsigned char *sigret, unsigned int *siglen, EVPerr(EVP_F_EVP_SIGNFINAL,EVP_R_NO_SIGN_FUNCTION_CONFIGURED); return(0); } - return(ctx->digest->sign(ctx->digest->type,m,m_len,sigret,siglen, - pkey->pkey.ptr)); + EVP_MD_CTX_init(&tmp_ctx); + EVP_MD_CTX_copy_ex(&tmp_ctx,ctx); + if (ctx->digest->flags & EVP_MD_FLAG_SVCTX) + { + EVP_MD_SVCTX sctmp; + sctmp.mctx = &tmp_ctx; + sctmp.key = pkey->pkey.ptr; + i = ctx->digest->sign(ctx->digest->type, + NULL, -1, sigret, siglen, &sctmp); + } + else + { + EVP_DigestFinal_ex(&tmp_ctx,&(m[0]),&m_len); + i = ctx->digest->sign(ctx->digest->type,m,m_len,sigret,siglen, + pkey->pkey.ptr); + } + EVP_MD_CTX_cleanup(&tmp_ctx); + return i; } diff --git a/src/lib/libcrypto/evp/p_verify.c b/src/lib/libcrypto/evp/p_verify.c index 21a40a375e..2d46dffe7e 100644 --- a/src/lib/libcrypto/evp/p_verify.c +++ b/src/lib/libcrypto/evp/p_verify.c @@ -85,17 +85,29 @@ int EVP_VerifyFinal(EVP_MD_CTX *ctx, const unsigned char *sigbuf, EVPerr(EVP_F_EVP_VERIFYFINAL,EVP_R_WRONG_PUBLIC_KEY_TYPE); return(-1); } - EVP_MD_CTX_init(&tmp_ctx); - EVP_MD_CTX_copy_ex(&tmp_ctx,ctx); - EVP_DigestFinal_ex(&tmp_ctx,&(m[0]),&m_len); - EVP_MD_CTX_cleanup(&tmp_ctx); - if (ctx->digest->verify == NULL) + if (ctx->digest->verify == NULL) { EVPerr(EVP_F_EVP_VERIFYFINAL,EVP_R_NO_VERIFY_FUNCTION_CONFIGURED); return(0); } - return(ctx->digest->verify(ctx->digest->type,m,m_len, - sigbuf,siglen,pkey->pkey.ptr)); + EVP_MD_CTX_init(&tmp_ctx); + EVP_MD_CTX_copy_ex(&tmp_ctx,ctx); + if (ctx->digest->flags & EVP_MD_FLAG_SVCTX) + { + EVP_MD_SVCTX sctmp; + sctmp.mctx = &tmp_ctx; + sctmp.key = pkey->pkey.ptr; + i = ctx->digest->verify(ctx->digest->type, + NULL, -1, sigbuf, siglen, &sctmp); + } + else + { + EVP_DigestFinal_ex(&tmp_ctx,&(m[0]),&m_len); + i = ctx->digest->verify(ctx->digest->type,m,m_len, + sigbuf,siglen,pkey->pkey.ptr); + } + EVP_MD_CTX_cleanup(&tmp_ctx); + return i; } diff --git a/src/lib/libcrypto/hmac/hmac.c b/src/lib/libcrypto/hmac/hmac.c index c45e001492..cbc1c76a57 100644 --- a/src/lib/libcrypto/hmac/hmac.c +++ b/src/lib/libcrypto/hmac/hmac.c @@ -61,6 +61,8 @@ #include "cryptlib.h" #include +#ifndef OPENSSL_FIPS + void HMAC_Init_ex(HMAC_CTX *ctx, const void *key, int len, const EVP_MD *md, ENGINE *impl) { @@ -171,3 +173,11 @@ unsigned char *HMAC(const EVP_MD *evp_md, const void *key, int key_len, return(md); } +void HMAC_CTX_set_flags(HMAC_CTX *ctx, unsigned long flags) + { + EVP_MD_CTX_set_flags(&ctx->i_ctx, flags); + EVP_MD_CTX_set_flags(&ctx->o_ctx, flags); + EVP_MD_CTX_set_flags(&ctx->md_ctx, flags); + } + +#endif diff --git a/src/lib/libcrypto/hmac/hmac.h b/src/lib/libcrypto/hmac/hmac.h index 719fc408ac..fc38ffb52b 100644 --- a/src/lib/libcrypto/hmac/hmac.h +++ b/src/lib/libcrypto/hmac/hmac.h @@ -100,6 +100,7 @@ unsigned char *HMAC(const EVP_MD *evp_md, const void *key, int key_len, const unsigned char *d, size_t n, unsigned char *md, unsigned int *md_len); +void HMAC_CTX_set_flags(HMAC_CTX *ctx, unsigned long flags); #ifdef __cplusplus } diff --git a/src/lib/libcrypto/idea/idea.h b/src/lib/libcrypto/idea/idea.h index bf97a37e39..a137d4cbce 100644 --- a/src/lib/libcrypto/idea/idea.h +++ b/src/lib/libcrypto/idea/idea.h @@ -83,6 +83,9 @@ typedef struct idea_key_st const char *idea_options(void); void idea_ecb_encrypt(const unsigned char *in, unsigned char *out, IDEA_KEY_SCHEDULE *ks); +#ifdef OPENSSL_FIPS +void private_idea_set_encrypt_key(const unsigned char *key, IDEA_KEY_SCHEDULE *ks); +#endif void idea_set_encrypt_key(const unsigned char *key, IDEA_KEY_SCHEDULE *ks); void idea_set_decrypt_key(const IDEA_KEY_SCHEDULE *ek, IDEA_KEY_SCHEDULE *dk); void idea_cbc_encrypt(const unsigned char *in, unsigned char *out, diff --git a/src/lib/libcrypto/md32_common.h b/src/lib/libcrypto/md32_common.h index 089c450290..61bcd9786f 100644 --- a/src/lib/libcrypto/md32_common.h +++ b/src/lib/libcrypto/md32_common.h @@ -301,7 +301,7 @@ int HASH_UPDATE (HASH_CTX *c, const void *data_, size_t len) { p=(unsigned char *)c->data; - if ((n+len) >= HASH_CBLOCK) + if (len >= HASH_CBLOCK || len+n >= HASH_CBLOCK) { memcpy (p+n,data,HASH_CBLOCK-n); HASH_BLOCK_DATA_ORDER (c,p,1); diff --git a/src/lib/libcrypto/md4/md4.h b/src/lib/libcrypto/md4/md4.h index 5598c93a4f..ba1fe4a6ee 100644 --- a/src/lib/libcrypto/md4/md4.h +++ b/src/lib/libcrypto/md4/md4.h @@ -105,6 +105,9 @@ typedef struct MD4state_st unsigned int num; } MD4_CTX; +#ifdef OPENSSL_FIPS +int private_MD4_Init(MD4_CTX *c); +#endif int MD4_Init(MD4_CTX *c); int MD4_Update(MD4_CTX *c, const void *data, size_t len); int MD4_Final(unsigned char *md, MD4_CTX *c); diff --git a/src/lib/libcrypto/md4/md4_dgst.c b/src/lib/libcrypto/md4/md4_dgst.c index cfef94af39..0f5448601d 100644 --- a/src/lib/libcrypto/md4/md4_dgst.c +++ b/src/lib/libcrypto/md4/md4_dgst.c @@ -59,6 +59,11 @@ #include #include "md4_locl.h" #include +#include +#ifdef OPENSSL_FIPS +#include +#endif + const char MD4_version[]="MD4" OPENSSL_VERSION_PTEXT; @@ -70,7 +75,7 @@ const char MD4_version[]="MD4" OPENSSL_VERSION_PTEXT; #define INIT_DATA_C (unsigned long)0x98badcfeL #define INIT_DATA_D (unsigned long)0x10325476L -int MD4_Init(MD4_CTX *c) +FIPS_NON_FIPS_MD_Init(MD4) { c->A=INIT_DATA_A; c->B=INIT_DATA_B; diff --git a/src/lib/libcrypto/md5/md5.h b/src/lib/libcrypto/md5/md5.h index dbdc0e1abc..0761f84a27 100644 --- a/src/lib/libcrypto/md5/md5.h +++ b/src/lib/libcrypto/md5/md5.h @@ -105,6 +105,9 @@ typedef struct MD5state_st unsigned int num; } MD5_CTX; +#ifdef OPENSSL_FIPS +int private_MD5_Init(MD5_CTX *c); +#endif int MD5_Init(MD5_CTX *c); int MD5_Update(MD5_CTX *c, const void *data, size_t len); int MD5_Final(unsigned char *md, MD5_CTX *c); diff --git a/src/lib/libcrypto/md5/md5_dgst.c b/src/lib/libcrypto/md5/md5_dgst.c index b96e332ba4..47bb9020ee 100644 --- a/src/lib/libcrypto/md5/md5_dgst.c +++ b/src/lib/libcrypto/md5/md5_dgst.c @@ -59,6 +59,11 @@ #include #include "md5_locl.h" #include +#include +#ifdef OPENSSL_FIPS +#include +#endif + const char MD5_version[]="MD5" OPENSSL_VERSION_PTEXT; @@ -70,7 +75,7 @@ const char MD5_version[]="MD5" OPENSSL_VERSION_PTEXT; #define INIT_DATA_C (unsigned long)0x98badcfeL #define INIT_DATA_D (unsigned long)0x10325476L -int MD5_Init(MD5_CTX *c) +FIPS_NON_FIPS_MD_Init(MD5) { c->A=INIT_DATA_A; c->B=INIT_DATA_B; diff --git a/src/lib/libcrypto/mem_dbg.c b/src/lib/libcrypto/mem_dbg.c index 8316485217..dfeb084799 100644 --- a/src/lib/libcrypto/mem_dbg.c +++ b/src/lib/libcrypto/mem_dbg.c @@ -330,7 +330,7 @@ static APP_INFO *pop_info(void) return(ret); } -int CRYPTO_push_info_(const char *info, const char *file, int line) +int CRYPTO_dbg_push_info(const char *info, const char *file, int line) { APP_INFO *ami, *amim; int ret=0; @@ -380,7 +380,7 @@ int CRYPTO_push_info_(const char *info, const char *file, int line) return(ret); } -int CRYPTO_pop_info(void) +int CRYPTO_dbg_pop_info(void) { int ret=0; @@ -395,7 +395,7 @@ int CRYPTO_pop_info(void) return(ret); } -int CRYPTO_remove_all_info(void) +int CRYPTO_dbg_remove_all_info(void) { int ret=0; @@ -793,3 +793,25 @@ void CRYPTO_mem_leaks_cb(CRYPTO_MEM_LEAK_CB *cb) lh_doall_arg(mh, LHASH_DOALL_ARG_FN(cb_leak), &cb); CRYPTO_w_unlock(CRYPTO_LOCK_MALLOC2); } + +void CRYPTO_malloc_debug_init(void) + { + CRYPTO_set_mem_debug_functions( + CRYPTO_dbg_malloc, + CRYPTO_dbg_realloc, + CRYPTO_dbg_free, + CRYPTO_dbg_set_options, + CRYPTO_dbg_get_options); + CRYPTO_set_mem_info_functions( + CRYPTO_dbg_push_info, + CRYPTO_dbg_pop_info, + CRYPTO_dbg_remove_all_info); + } + +char *CRYPTO_strdup(const char *str, const char *file, int line) + { + char *ret = CRYPTO_malloc(strlen(str)+1, file, line); + + strcpy(ret, str); + return ret; + } diff --git a/src/lib/libcrypto/o_init.c b/src/lib/libcrypto/o_init.c new file mode 100644 index 0000000000..00ed65a6cf --- /dev/null +++ b/src/lib/libcrypto/o_init.c @@ -0,0 +1,86 @@ +/* o_init.c */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project. + */ +/* ==================================================================== + * Copyright (c) 2007 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * 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 +#include + +/* Perform any essential OpenSSL initialization operations. + * Currently only sets FIPS callbacks + */ + +void OPENSSL_init(void) + { +#ifdef OPENSSL_FIPS + static int done = 0; + if (!done) + { + int_ERR_lib_init(); +#ifdef CRYPTO_MDEBUG + CRYPTO_malloc_debug_init(); +#endif +#ifdef OPENSSL_ENGINE + int_EVP_MD_init_engine_callbacks(); + int_EVP_CIPHER_init_engine_callbacks(); + int_RAND_init_engine_callbacks(); +#endif + done = 1; + } +#endif + } + + diff --git a/src/lib/libcrypto/objects/obj_dat.pl b/src/lib/libcrypto/objects/obj_dat.pl index 8a09a46ee6..7de2f77afd 100644 --- a/src/lib/libcrypto/objects/obj_dat.pl +++ b/src/lib/libcrypto/objects/obj_dat.pl @@ -2,7 +2,9 @@ # fixes bug in floating point emulation on sparc64 when # this script produces off-by-one output on sparc64 -use integer; +eval 'use integer;'; + +print STDERR "Warning: perl module integer not found.\n" if ($@); sub obj_cmp { diff --git a/src/lib/libcrypto/objects/obj_mac.num b/src/lib/libcrypto/objects/obj_mac.num index 47815b1e4e..e3f56bc52c 100644 --- a/src/lib/libcrypto/objects/obj_mac.num +++ b/src/lib/libcrypto/objects/obj_mac.num @@ -788,3 +788,71 @@ id_ct_asciiTextWithCRLF 787 id_aes128_wrap 788 id_aes192_wrap 789 id_aes256_wrap 790 +ecdsa_with_Recommended 791 +ecdsa_with_Specified 792 +ecdsa_with_SHA224 793 +ecdsa_with_SHA256 794 +ecdsa_with_SHA384 795 +ecdsa_with_SHA512 796 +hmacWithMD5 797 +hmacWithSHA224 798 +hmacWithSHA256 799 +hmacWithSHA384 800 +hmacWithSHA512 801 +dsa_with_SHA224 802 +dsa_with_SHA256 803 +whirlpool 804 +cryptopro 805 +cryptocom 806 +id_GostR3411_94_with_GostR3410_2001 807 +id_GostR3411_94_with_GostR3410_94 808 +id_GostR3411_94 809 +id_HMACGostR3411_94 810 +id_GostR3410_2001 811 +id_GostR3410_94 812 +id_Gost28147_89 813 +gost89_cnt 814 +id_Gost28147_89_MAC 815 +id_GostR3411_94_prf 816 +id_GostR3410_2001DH 817 +id_GostR3410_94DH 818 +id_Gost28147_89_CryptoPro_KeyMeshing 819 +id_Gost28147_89_None_KeyMeshing 820 +id_GostR3411_94_TestParamSet 821 +id_GostR3411_94_CryptoProParamSet 822 +id_Gost28147_89_TestParamSet 823 +id_Gost28147_89_CryptoPro_A_ParamSet 824 +id_Gost28147_89_CryptoPro_B_ParamSet 825 +id_Gost28147_89_CryptoPro_C_ParamSet 826 +id_Gost28147_89_CryptoPro_D_ParamSet 827 +id_Gost28147_89_CryptoPro_Oscar_1_1_ParamSet 828 +id_Gost28147_89_CryptoPro_Oscar_1_0_ParamSet 829 +id_Gost28147_89_CryptoPro_RIC_1_ParamSet 830 +id_GostR3410_94_TestParamSet 831 +id_GostR3410_94_CryptoPro_A_ParamSet 832 +id_GostR3410_94_CryptoPro_B_ParamSet 833 +id_GostR3410_94_CryptoPro_C_ParamSet 834 +id_GostR3410_94_CryptoPro_D_ParamSet 835 +id_GostR3410_94_CryptoPro_XchA_ParamSet 836 +id_GostR3410_94_CryptoPro_XchB_ParamSet 837 +id_GostR3410_94_CryptoPro_XchC_ParamSet 838 +id_GostR3410_2001_TestParamSet 839 +id_GostR3410_2001_CryptoPro_A_ParamSet 840 +id_GostR3410_2001_CryptoPro_B_ParamSet 841 +id_GostR3410_2001_CryptoPro_C_ParamSet 842 +id_GostR3410_2001_CryptoPro_XchA_ParamSet 843 +id_GostR3410_2001_CryptoPro_XchB_ParamSet 844 +id_GostR3410_94_a 845 +id_GostR3410_94_aBis 846 +id_GostR3410_94_b 847 +id_GostR3410_94_bBis 848 +id_Gost28147_89_cc 849 +id_GostR3410_94_cc 850 +id_GostR3410_2001_cc 851 +id_GostR3411_94_with_GostR3410_94_cc 852 +id_GostR3411_94_with_GostR3410_2001_cc 853 +id_GostR3410_2001_ParamSet_cc 854 +hmac 855 +LocalKeySet 856 +freshest_crl 857 +id_on_permanentIdentifier 858 diff --git a/src/lib/libcrypto/objects/objects.txt b/src/lib/libcrypto/objects/objects.txt index 34c8d1d647..a6a811b8e7 100644 --- a/src/lib/libcrypto/objects/objects.txt +++ b/src/lib/libcrypto/objects/objects.txt @@ -79,6 +79,12 @@ X9-62_primeCurve 7 : prime256v1 !Alias id-ecSigType ansi-X9-62 4 !global X9-62_id-ecSigType 1 : ecdsa-with-SHA1 +X9-62_id-ecSigType 2 : ecdsa-with-Recommended +X9-62_id-ecSigType 3 : ecdsa-with-Specified +ecdsa-with-Specified 1 : ecdsa-with-SHA224 +ecdsa-with-Specified 2 : ecdsa-with-SHA256 +ecdsa-with-Specified 3 : ecdsa-with-SHA384 +ecdsa-with-Specified 4 : ecdsa-with-SHA512 # SECG curve OIDs from "SEC 2: Recommended Elliptic Curve Domain Parameters" # (http://www.secg.org/) @@ -313,6 +319,7 @@ pkcs9 20 : : friendlyName pkcs9 21 : : localKeyID !Cname ms-csp-name 1 3 6 1 4 1 311 17 1 : CSPName : Microsoft CSP Name +1 3 6 1 4 1 311 17 2 : LocalKeySet : Microsoft Local Key set !Alias certTypes pkcs9 22 certTypes 1 : : x509Certificate certTypes 2 : : sdsiCertificate @@ -348,7 +355,15 @@ rsadsi 2 2 : MD2 : md2 rsadsi 2 4 : MD4 : md4 rsadsi 2 5 : MD5 : md5 : MD5-SHA1 : md5-sha1 +rsadsi 2 6 : : hmacWithMD5 rsadsi 2 7 : : hmacWithSHA1 + +# From RFC4231 +rsadsi 2 8 : : hmacWithSHA224 +rsadsi 2 9 : : hmacWithSHA256 +rsadsi 2 10 : : hmacWithSHA384 +rsadsi 2 11 : : hmacWithSHA512 + rsadsi 3 2 : RC2-CBC : rc2-cbc : RC2-ECB : rc2-ecb !Cname rc2-cfb64 @@ -542,6 +557,7 @@ id-cmc 24 : id-cmc-confirmCertAcceptance # other names id-on 1 : id-on-personalData +id-on 3 : id-on-permanentIdentifier : Permanent Identifier # personal data attributes id-pda 1 : id-pda-dateOfBirth @@ -711,6 +727,8 @@ id-ce 35 : authorityKeyIdentifier : X509v3 Authority Key Identifier id-ce 36 : policyConstraints : X509v3 Policy Constraints !Cname ext-key-usage id-ce 37 : extendedKeyUsage : X509v3 Extended Key Usage +!Cname freshest-crl +id-ce 46 : freshestCRL : X509v3 Freshest CRL !Cname inhibit-any-policy id-ce 54 : inhibitAnyPolicy : X509v3 Inhibit Any Policy !Cname target-information @@ -833,6 +851,11 @@ nist_hashalgs 2 : SHA384 : sha384 nist_hashalgs 3 : SHA512 : sha512 nist_hashalgs 4 : SHA224 : sha224 +# OIDs for dsa-with-sha224 and dsa-with-sha256 +!Alias dsa_with_sha2 nistAlgorithms 3 +dsa_with_sha2 1 : dsa_with_SHA224 +dsa_with_sha2 2 : dsa_with_SHA256 + # Hold instruction CRL entry extension !Cname hold-instruction-code id-ce 23 : holdInstructionCode : Hold Instruction Code @@ -1070,13 +1093,93 @@ rsadsi 1 1 6 : rsaOAEPEncryptionSET : Oakley-EC2N-3 : ipsec3 : Oakley-EC2N-4 : ipsec4 +iso 0 10118 3 0 55 : whirlpool + +# GOST OIDs + +member-body 643 2 2 : cryptopro +member-body 643 2 9 : cryptocom + +cryptopro 3 : id-GostR3411-94-with-GostR3410-2001 : GOST R 34.11-94 with GOST R 34.10-2001 +cryptopro 4 : id-GostR3411-94-with-GostR3410-94 : GOST R 34.11-94 with GOST R 34.10-94 +!Cname id-GostR3411-94 +cryptopro 9 : md_gost94 : GOST R 34.11-94 +cryptopro 10 : id-HMACGostR3411-94 : HMAC GOST 34.11-94 +!Cname id-GostR3410-2001 +cryptopro 19 : gost2001 : GOST R 34.10-2001 +!Cname id-GostR3410-94 +cryptopro 20 : gost94 : GOST R 34.10-94 +!Cname id-Gost28147-89 +cryptopro 21 : gost89 : GOST 28147-89 + : gost89-cnt +!Cname id-Gost28147-89-MAC +cryptopro 22 : gost-mac : GOST 28147-89 MAC +!Cname id-GostR3411-94-prf +cryptopro 23 : prf-gostr3411-94 : GOST R 34.11-94 PRF +cryptopro 98 : id-GostR3410-2001DH : GOST R 34.10-2001 DH +cryptopro 99 : id-GostR3410-94DH : GOST R 34.10-94 DH + +cryptopro 14 1 : id-Gost28147-89-CryptoPro-KeyMeshing +cryptopro 14 0 : id-Gost28147-89-None-KeyMeshing + +# GOST parameter set OIDs + +cryptopro 30 0 : id-GostR3411-94-TestParamSet +cryptopro 30 1 : id-GostR3411-94-CryptoProParamSet + +cryptopro 31 0 : id-Gost28147-89-TestParamSet +cryptopro 31 1 : id-Gost28147-89-CryptoPro-A-ParamSet +cryptopro 31 2 : id-Gost28147-89-CryptoPro-B-ParamSet +cryptopro 31 3 : id-Gost28147-89-CryptoPro-C-ParamSet +cryptopro 31 4 : id-Gost28147-89-CryptoPro-D-ParamSet +cryptopro 31 5 : id-Gost28147-89-CryptoPro-Oscar-1-1-ParamSet +cryptopro 31 6 : id-Gost28147-89-CryptoPro-Oscar-1-0-ParamSet +cryptopro 31 7 : id-Gost28147-89-CryptoPro-RIC-1-ParamSet + +cryptopro 32 0 : id-GostR3410-94-TestParamSet +cryptopro 32 2 : id-GostR3410-94-CryptoPro-A-ParamSet +cryptopro 32 3 : id-GostR3410-94-CryptoPro-B-ParamSet +cryptopro 32 4 : id-GostR3410-94-CryptoPro-C-ParamSet +cryptopro 32 5 : id-GostR3410-94-CryptoPro-D-ParamSet + +cryptopro 33 1 : id-GostR3410-94-CryptoPro-XchA-ParamSet +cryptopro 33 2 : id-GostR3410-94-CryptoPro-XchB-ParamSet +cryptopro 33 3 : id-GostR3410-94-CryptoPro-XchC-ParamSet + +cryptopro 35 0 : id-GostR3410-2001-TestParamSet +cryptopro 35 1 : id-GostR3410-2001-CryptoPro-A-ParamSet +cryptopro 35 2 : id-GostR3410-2001-CryptoPro-B-ParamSet +cryptopro 35 3 : id-GostR3410-2001-CryptoPro-C-ParamSet + +cryptopro 36 0 : id-GostR3410-2001-CryptoPro-XchA-ParamSet +cryptopro 36 1 : id-GostR3410-2001-CryptoPro-XchB-ParamSet + +id-GostR3410-94 1 : id-GostR3410-94-a +id-GostR3410-94 2 : id-GostR3410-94-aBis +id-GostR3410-94 3 : id-GostR3410-94-b +id-GostR3410-94 4 : id-GostR3410-94-bBis + +# Cryptocom LTD GOST OIDs + +cryptocom 1 6 1 : id-Gost28147-89-cc : GOST 28147-89 Cryptocom ParamSet +!Cname id-GostR3410-94-cc +cryptocom 1 5 3 : gost94cc : GOST 34.10-94 Cryptocom +!Cname id-GostR3410-2001-cc +cryptocom 1 5 4 : gost2001cc : GOST 34.10-2001 Cryptocom + +cryptocom 1 3 3 : id-GostR3411-94-with-GostR3410-94-cc : GOST R 34.11-94 with GOST R 34.10-94 Cryptocom +cryptocom 1 3 4 : id-GostR3411-94-with-GostR3410-2001-cc : GOST R 34.11-94 with GOST R 34.10-2001 Cryptocom + +cryptocom 1 8 1 : id-GostR3410-2001-ParamSet-cc : GOST R 3410-2001 Parameter Set Cryptocom # Definitions for Camellia cipher - CBC MODE + 1 2 392 200011 61 1 1 1 2 : CAMELLIA-128-CBC : camellia-128-cbc 1 2 392 200011 61 1 1 1 3 : CAMELLIA-192-CBC : camellia-192-cbc 1 2 392 200011 61 1 1 1 4 : CAMELLIA-256-CBC : camellia-256-cbc # Definitions for Camellia cipher - ECB, CFB, OFB MODE + !Alias ntt-ds 0 3 4401 5 !Alias camellia ntt-ds 3 1 9 @@ -1107,7 +1210,6 @@ camellia 44 : CAMELLIA-256-CFB : camellia-256-cfb : CAMELLIA-192-CFB8 : camellia-192-cfb8 : CAMELLIA-256-CFB8 : camellia-256-cfb8 - # Definitions for SEED cipher - ECB, CBC, OFB mode member-body 410 200004 : KISA : kisa @@ -1117,3 +1219,7 @@ kisa 1 4 : SEED-CBC : seed-cbc kisa 1 5 : SEED-CFB : seed-cfb !Cname seed-ofb128 kisa 1 6 : SEED-OFB : seed-ofb + +# There is no OID that just denotes "HMAC" oddly enough... + + : HMAC : hmac diff --git a/src/lib/libcrypto/ocsp/ocsp_asn.c b/src/lib/libcrypto/ocsp/ocsp_asn.c index 39b7a1c568..bfe892ac70 100644 --- a/src/lib/libcrypto/ocsp/ocsp_asn.c +++ b/src/lib/libcrypto/ocsp/ocsp_asn.c @@ -1,5 +1,5 @@ /* ocsp_asn.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. */ /* ==================================================================== diff --git a/src/lib/libcrypto/ocsp/ocsp_ht.c b/src/lib/libcrypto/ocsp/ocsp_ht.c index a8e569b74a..6abb30b2c0 100644 --- a/src/lib/libcrypto/ocsp/ocsp_ht.c +++ b/src/lib/libcrypto/ocsp/ocsp_ht.c @@ -1,5 +1,5 @@ /* ocsp_ht.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 2006. */ /* ==================================================================== @@ -56,11 +56,12 @@ * */ -#include #include #include #include #include +#include "e_os.h" +#include #include #include #include diff --git a/src/lib/libcrypto/ocsp/ocsp_srv.c b/src/lib/libcrypto/ocsp/ocsp_srv.c index fffa134e75..1c606dd0b6 100644 --- a/src/lib/libcrypto/ocsp/ocsp_srv.c +++ b/src/lib/libcrypto/ocsp/ocsp_srv.c @@ -1,5 +1,5 @@ /* ocsp_srv.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 2001. */ /* ==================================================================== diff --git a/src/lib/libcrypto/ocsp/ocsp_vfy.c b/src/lib/libcrypto/ocsp/ocsp_vfy.c index 23ea41c847..4a0c3870d8 100644 --- a/src/lib/libcrypto/ocsp/ocsp_vfy.c +++ b/src/lib/libcrypto/ocsp/ocsp_vfy.c @@ -1,5 +1,5 @@ /* ocsp_vfy.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. */ /* ==================================================================== diff --git a/src/lib/libcrypto/opensslv.h b/src/lib/libcrypto/opensslv.h index b308894f18..09687b5136 100644 --- a/src/lib/libcrypto/opensslv.h +++ b/src/lib/libcrypto/opensslv.h @@ -25,11 +25,11 @@ * (Prior to 0.9.5a beta1, a different scheme was used: MMNNFFRBB for * major minor fix final patch/beta) */ -#define OPENSSL_VERSION_NUMBER 0x0090808fL +#define OPENSSL_VERSION_NUMBER 0x009080afL #ifdef OPENSSL_FIPS -#define OPENSSL_VERSION_TEXT "OpenSSL 0.9.8h-fips 28 May 2008" +#define OPENSSL_VERSION_TEXT "OpenSSL 0.9.8j-fips 07 Jan 2009" #else -#define OPENSSL_VERSION_TEXT "OpenSSL 0.9.8h 28 May 2008" +#define OPENSSL_VERSION_TEXT "OpenSSL 0.9.8j 07 Jan 2009" #endif #define OPENSSL_VERSION_PTEXT " part of " OPENSSL_VERSION_TEXT diff --git a/src/lib/libcrypto/ossl_typ.h b/src/lib/libcrypto/ossl_typ.h index 345fb1dc4d..0e7a380880 100644 --- a/src/lib/libcrypto/ossl_typ.h +++ b/src/lib/libcrypto/ossl_typ.h @@ -100,6 +100,8 @@ typedef int ASN1_NULL; #undef X509_EXTENSIONS #undef X509_CERT_PAIR #undef PKCS7_ISSUER_AND_SERIAL +#undef OCSP_REQUEST +#undef OCSP_RESPONSE #endif #ifdef BIGNUM @@ -140,6 +142,8 @@ typedef struct X509_crl_st X509_CRL; typedef struct X509_name_st X509_NAME; typedef struct x509_store_st X509_STORE; typedef struct x509_store_ctx_st X509_STORE_CTX; +typedef struct ssl_st SSL; +typedef struct ssl_ctx_st SSL_CTX; typedef struct v3_ext_ctx X509V3_CTX; typedef struct conf_st CONF; diff --git a/src/lib/libcrypto/pem/pem.h b/src/lib/libcrypto/pem/pem.h index 670afa670b..6f8e01544b 100644 --- a/src/lib/libcrypto/pem/pem.h +++ b/src/lib/libcrypto/pem/pem.h @@ -125,6 +125,7 @@ extern "C" { #define PEM_STRING_DSA "DSA PRIVATE KEY" #define PEM_STRING_DSA_PUBLIC "DSA PUBLIC KEY" #define PEM_STRING_PKCS7 "PKCS7" +#define PEM_STRING_PKCS7_SIGNED "PKCS #7 SIGNED DATA" #define PEM_STRING_PKCS8 "ENCRYPTED PRIVATE KEY" #define PEM_STRING_PKCS8INF "PRIVATE KEY" #define PEM_STRING_DHPARAMS "DH PARAMETERS" diff --git a/src/lib/libcrypto/pem/pem_all.c b/src/lib/libcrypto/pem/pem_all.c index 66cbc7eb82..69dd19bf2e 100644 --- a/src/lib/libcrypto/pem/pem_all.c +++ b/src/lib/libcrypto/pem/pem_all.c @@ -194,7 +194,49 @@ RSA *PEM_read_RSAPrivateKey(FILE *fp, RSA **rsa, pem_password_cb *cb, #endif +#ifdef OPENSSL_FIPS + +int PEM_write_bio_RSAPrivateKey(BIO *bp, RSA *x, const EVP_CIPHER *enc, + unsigned char *kstr, int klen, + pem_password_cb *cb, void *u) +{ + EVP_PKEY *k; + int ret; + k = EVP_PKEY_new(); + if (!k) + return 0; + EVP_PKEY_set1_RSA(k, x); + + ret = PEM_write_bio_PrivateKey(bp, k, enc, kstr, klen, cb, u); + EVP_PKEY_free(k); + return ret; +} + +#ifndef OPENSSL_NO_FP_API +int PEM_write_RSAPrivateKey(FILE *fp, RSA *x, const EVP_CIPHER *enc, + unsigned char *kstr, int klen, + pem_password_cb *cb, void *u) +{ + EVP_PKEY *k; + int ret; + k = EVP_PKEY_new(); + if (!k) + return 0; + + EVP_PKEY_set1_RSA(k, x); + + ret = PEM_write_PrivateKey(fp, k, enc, kstr, klen, cb, u); + EVP_PKEY_free(k); + return ret; +} +#endif + +#else + IMPLEMENT_PEM_write_cb_const(RSAPrivateKey, RSA, PEM_STRING_RSA, RSAPrivateKey) + +#endif + IMPLEMENT_PEM_rw_const(RSAPublicKey, RSA, PEM_STRING_RSA_PUBLIC, RSAPublicKey) IMPLEMENT_PEM_rw(RSA_PUBKEY, RSA, PEM_STRING_PUBLIC, RSA_PUBKEY) @@ -224,7 +266,47 @@ DSA *PEM_read_bio_DSAPrivateKey(BIO *bp, DSA **dsa, pem_password_cb *cb, return pkey_get_dsa(pktmp, dsa); } +#ifdef OPENSSL_FIPS + +int PEM_write_bio_DSAPrivateKey(BIO *bp, DSA *x, const EVP_CIPHER *enc, + unsigned char *kstr, int klen, + pem_password_cb *cb, void *u) +{ + EVP_PKEY *k; + int ret; + k = EVP_PKEY_new(); + if (!k) + return 0; + EVP_PKEY_set1_DSA(k, x); + + ret = PEM_write_bio_PrivateKey(bp, k, enc, kstr, klen, cb, u); + EVP_PKEY_free(k); + return ret; +} + +#ifndef OPENSSL_NO_FP_API +int PEM_write_DSAPrivateKey(FILE *fp, DSA *x, const EVP_CIPHER *enc, + unsigned char *kstr, int klen, + pem_password_cb *cb, void *u) +{ + EVP_PKEY *k; + int ret; + k = EVP_PKEY_new(); + if (!k) + return 0; + EVP_PKEY_set1_DSA(k, x); + ret = PEM_write_PrivateKey(fp, k, enc, kstr, klen, cb, u); + EVP_PKEY_free(k); + return ret; +} +#endif + +#else + IMPLEMENT_PEM_write_cb_const(DSAPrivateKey, DSA, PEM_STRING_DSA, DSAPrivateKey) + +#endif + IMPLEMENT_PEM_rw(DSA_PUBKEY, DSA, PEM_STRING_PUBLIC, DSA_PUBKEY) #ifndef OPENSSL_NO_FP_API @@ -270,8 +352,49 @@ EC_KEY *PEM_read_bio_ECPrivateKey(BIO *bp, EC_KEY **key, pem_password_cb *cb, IMPLEMENT_PEM_rw_const(ECPKParameters, EC_GROUP, PEM_STRING_ECPARAMETERS, ECPKParameters) + + +#ifdef OPENSSL_FIPS + +int PEM_write_bio_ECPrivateKey(BIO *bp, EC_KEY *x, const EVP_CIPHER *enc, + unsigned char *kstr, int klen, + pem_password_cb *cb, void *u) +{ + EVP_PKEY *k; + int ret; + k = EVP_PKEY_new(); + if (!k) + return 0; + EVP_PKEY_set1_EC_KEY(k, x); + + ret = PEM_write_bio_PrivateKey(bp, k, enc, kstr, klen, cb, u); + EVP_PKEY_free(k); + return ret; +} + +#ifndef OPENSSL_NO_FP_API +int PEM_write_ECPrivateKey(FILE *fp, EC_KEY *x, const EVP_CIPHER *enc, + unsigned char *kstr, int klen, + pem_password_cb *cb, void *u) +{ + EVP_PKEY *k; + int ret; + k = EVP_PKEY_new(); + if (!k) + return 0; + EVP_PKEY_set1_EC_KEY(k, x); + ret = PEM_write_PrivateKey(fp, k, enc, kstr, klen, cb, u); + EVP_PKEY_free(k); + return ret; +} +#endif + +#else + IMPLEMENT_PEM_write_cb(ECPrivateKey, EC_KEY, PEM_STRING_ECPRIVATEKEY, ECPrivateKey) +#endif + IMPLEMENT_PEM_rw(EC_PUBKEY, EC_KEY, PEM_STRING_PUBLIC, EC_PUBKEY) #ifndef OPENSSL_NO_FP_API @@ -301,8 +424,59 @@ IMPLEMENT_PEM_rw_const(DHparams, DH, PEM_STRING_DHPARAMS, DHparams) * (When reading, parameter PEM_STRING_EVP_PKEY is a wildcard for anything * appropriate.) */ + +#ifdef OPENSSL_FIPS + +static const char *pkey_str(EVP_PKEY *x) + { + switch (x->type) + { + case EVP_PKEY_RSA: + return PEM_STRING_RSA; + + case EVP_PKEY_DSA: + return PEM_STRING_DSA; + + case EVP_PKEY_EC: + return PEM_STRING_ECPRIVATEKEY; + + default: + return NULL; + } + } + + +int PEM_write_bio_PrivateKey(BIO *bp, EVP_PKEY *x, const EVP_CIPHER *enc, + unsigned char *kstr, int klen, + pem_password_cb *cb, void *u) + { + if (FIPS_mode()) + return PEM_write_bio_PKCS8PrivateKey(bp, x, enc, + (char *)kstr, klen, cb, u); + else + return PEM_ASN1_write_bio((i2d_of_void *)i2d_PrivateKey, + pkey_str(x), bp,(char *)x,enc,kstr,klen,cb,u); + } + +#ifndef OPENSSL_NO_FP_API +int PEM_write_PrivateKey(FILE *fp, EVP_PKEY *x, const EVP_CIPHER *enc, + unsigned char *kstr, int klen, + pem_password_cb *cb, void *u) + { + if (FIPS_mode()) + return PEM_write_PKCS8PrivateKey(fp, x, enc, + (char *)kstr, klen, cb, u); + else + return PEM_ASN1_write((i2d_of_void *)i2d_PrivateKey, + pkey_str(x), fp,(char *)x,enc,kstr,klen,cb,u); + } +#endif + +#else IMPLEMENT_PEM_write_cb(PrivateKey, EVP_PKEY, ((x->type == EVP_PKEY_DSA)?PEM_STRING_DSA:\ (x->type == EVP_PKEY_RSA)?PEM_STRING_RSA:PEM_STRING_ECPRIVATEKEY), PrivateKey) +#endif + IMPLEMENT_PEM_rw(PUBKEY, EVP_PKEY, PEM_STRING_PUBLIC, PUBKEY) diff --git a/src/lib/libcrypto/pem/pem_lib.c b/src/lib/libcrypto/pem/pem_lib.c index 9bae4c8850..cbafefe416 100644 --- a/src/lib/libcrypto/pem/pem_lib.c +++ b/src/lib/libcrypto/pem/pem_lib.c @@ -216,6 +216,9 @@ static int check_pem(const char *nm, const char *name) if(!strcmp(nm, PEM_STRING_X509) && !strcmp(name, PEM_STRING_PKCS7)) return 1; + if(!strcmp(nm, PEM_STRING_PKCS7_SIGNED) && + !strcmp(name, PEM_STRING_PKCS7)) return 1; + return 0; } diff --git a/src/lib/libcrypto/pem/pem_x509.c b/src/lib/libcrypto/pem/pem_x509.c index 19f88d8d3a..3f709f13e6 100644 --- a/src/lib/libcrypto/pem/pem_x509.c +++ b/src/lib/libcrypto/pem/pem_x509.c @@ -1,5 +1,5 @@ /* pem_x509.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 2001. */ /* ==================================================================== diff --git a/src/lib/libcrypto/pem/pem_xaux.c b/src/lib/libcrypto/pem/pem_xaux.c index 63ce660cf1..7cc7491009 100644 --- a/src/lib/libcrypto/pem/pem_xaux.c +++ b/src/lib/libcrypto/pem/pem_xaux.c @@ -1,5 +1,5 @@ /* pem_xaux.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 2001. */ /* ==================================================================== diff --git a/src/lib/libcrypto/pkcs12/p12_add.c b/src/lib/libcrypto/pkcs12/p12_add.c index 41bdc00551..1f3e378f5c 100644 --- a/src/lib/libcrypto/pkcs12/p12_add.c +++ b/src/lib/libcrypto/pkcs12/p12_add.c @@ -1,5 +1,5 @@ /* p12_add.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. */ /* ==================================================================== diff --git a/src/lib/libcrypto/pkcs12/p12_asn.c b/src/lib/libcrypto/pkcs12/p12_asn.c index a3739fee1a..6e27633817 100644 --- a/src/lib/libcrypto/pkcs12/p12_asn.c +++ b/src/lib/libcrypto/pkcs12/p12_asn.c @@ -1,5 +1,5 @@ /* p12_asn.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. */ /* ==================================================================== diff --git a/src/lib/libcrypto/pkcs12/p12_attr.c b/src/lib/libcrypto/pkcs12/p12_attr.c index 026cf3826a..68d6c5ad15 100644 --- a/src/lib/libcrypto/pkcs12/p12_attr.c +++ b/src/lib/libcrypto/pkcs12/p12_attr.c @@ -1,5 +1,5 @@ /* p12_attr.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. */ /* ==================================================================== diff --git a/src/lib/libcrypto/pkcs12/p12_crpt.c b/src/lib/libcrypto/pkcs12/p12_crpt.c index 3ad33c49d8..f8b952e27e 100644 --- a/src/lib/libcrypto/pkcs12/p12_crpt.c +++ b/src/lib/libcrypto/pkcs12/p12_crpt.c @@ -1,5 +1,5 @@ /* p12_crpt.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. */ /* ==================================================================== diff --git a/src/lib/libcrypto/pkcs12/p12_crt.c b/src/lib/libcrypto/pkcs12/p12_crt.c index dbafda17b6..e863de52ce 100644 --- a/src/lib/libcrypto/pkcs12/p12_crt.c +++ b/src/lib/libcrypto/pkcs12/p12_crt.c @@ -1,5 +1,5 @@ /* p12_crt.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. */ /* ==================================================================== @@ -59,10 +59,27 @@ #include #include "cryptlib.h" #include +#ifdef OPENSSL_FIPS +#include +#endif + static int pkcs12_add_bag(STACK_OF(PKCS12_SAFEBAG) **pbags, PKCS12_SAFEBAG *bag); +static int copy_bag_attr(PKCS12_SAFEBAG *bag, EVP_PKEY *pkey, int nid) + { + int idx; + X509_ATTRIBUTE *attr; + idx = EVP_PKEY_get_attr_by_NID(pkey, nid, -1); + if (idx < 0) + return 1; + attr = EVP_PKEY_get_attr(pkey, idx); + if (!X509at_add1_attr(&bag->attrib, attr)) + return 0; + return 1; + } + PKCS12 *PKCS12_create(char *pass, char *name, EVP_PKEY *pkey, X509 *cert, STACK_OF(X509) *ca, int nid_key, int nid_cert, int iter, int mac_iter, int keytype) @@ -77,7 +94,14 @@ PKCS12 *PKCS12_create(char *pass, char *name, EVP_PKEY *pkey, X509 *cert, /* Set defaults */ if (!nid_cert) + { +#ifdef OPENSSL_FIPS + if (FIPS_mode()) + nid_cert = NID_pbe_WithSHA1And3_Key_TripleDES_CBC; + else +#endif nid_cert = NID_pbe_WithSHA1And40BitRC2_CBC; + } if (!nid_key) nid_key = NID_pbe_WithSHA1And3_Key_TripleDES_CBC; if (!iter) @@ -122,20 +146,15 @@ PKCS12 *PKCS12_create(char *pass, char *name, EVP_PKEY *pkey, X509 *cert, if (pkey) { - int cspidx; bag = PKCS12_add_key(&bags, pkey, keytype, iter, nid_key, pass); if (!bag) goto err; - cspidx = EVP_PKEY_get_attr_by_NID(pkey, NID_ms_csp_name, -1); - if (cspidx >= 0) - { - X509_ATTRIBUTE *cspattr; - cspattr = EVP_PKEY_get_attr(pkey, cspidx); - if (!X509at_add1_attr(&bag->attrib, cspattr)) - goto err; - } + if (!copy_bag_attr(bag, pkey, NID_ms_csp_name)) + goto err; + if (!copy_bag_attr(bag, pkey, NID_LocalKeySet)) + goto err; if(name && !PKCS12_add_friendlyname(bag, name, -1)) goto err; diff --git a/src/lib/libcrypto/pkcs12/p12_decr.c b/src/lib/libcrypto/pkcs12/p12_decr.c index 74c961a92b..ba77dbbe32 100644 --- a/src/lib/libcrypto/pkcs12/p12_decr.c +++ b/src/lib/libcrypto/pkcs12/p12_decr.c @@ -1,5 +1,5 @@ /* p12_decr.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. */ /* ==================================================================== diff --git a/src/lib/libcrypto/pkcs12/p12_init.c b/src/lib/libcrypto/pkcs12/p12_init.c index 6bdc132631..d4d84b056a 100644 --- a/src/lib/libcrypto/pkcs12/p12_init.c +++ b/src/lib/libcrypto/pkcs12/p12_init.c @@ -1,5 +1,5 @@ /* p12_init.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. */ /* ==================================================================== diff --git a/src/lib/libcrypto/pkcs12/p12_key.c b/src/lib/libcrypto/pkcs12/p12_key.c index 18e72d0a1b..9e57eee4a4 100644 --- a/src/lib/libcrypto/pkcs12/p12_key.c +++ b/src/lib/libcrypto/pkcs12/p12_key.c @@ -1,5 +1,5 @@ /* p12_key.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. */ /* ==================================================================== diff --git a/src/lib/libcrypto/pkcs12/p12_kiss.c b/src/lib/libcrypto/pkcs12/p12_kiss.c index c2ee2cc6f3..5c4c6ec988 100644 --- a/src/lib/libcrypto/pkcs12/p12_kiss.c +++ b/src/lib/libcrypto/pkcs12/p12_kiss.c @@ -1,5 +1,5 @@ /* p12_kiss.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. */ /* ==================================================================== diff --git a/src/lib/libcrypto/pkcs12/p12_mutl.c b/src/lib/libcrypto/pkcs12/p12_mutl.c index c408cc8ab8..70bfef6e5d 100644 --- a/src/lib/libcrypto/pkcs12/p12_mutl.c +++ b/src/lib/libcrypto/pkcs12/p12_mutl.c @@ -1,5 +1,5 @@ /* p12_mutl.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. */ /* ==================================================================== diff --git a/src/lib/libcrypto/pkcs12/p12_npas.c b/src/lib/libcrypto/pkcs12/p12_npas.c index 48eacc5c49..47e5e9c377 100644 --- a/src/lib/libcrypto/pkcs12/p12_npas.c +++ b/src/lib/libcrypto/pkcs12/p12_npas.c @@ -1,5 +1,5 @@ /* p12_npas.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. */ /* ==================================================================== diff --git a/src/lib/libcrypto/pkcs12/p12_p8d.c b/src/lib/libcrypto/pkcs12/p12_p8d.c index 3c6f377933..deba81e4a9 100644 --- a/src/lib/libcrypto/pkcs12/p12_p8d.c +++ b/src/lib/libcrypto/pkcs12/p12_p8d.c @@ -1,5 +1,5 @@ /* p12_p8d.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 2001. */ /* ==================================================================== diff --git a/src/lib/libcrypto/pkcs12/p12_p8e.c b/src/lib/libcrypto/pkcs12/p12_p8e.c index 3d47956652..bf20a77b4c 100644 --- a/src/lib/libcrypto/pkcs12/p12_p8e.c +++ b/src/lib/libcrypto/pkcs12/p12_p8e.c @@ -1,5 +1,5 @@ /* p12_p8e.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 2001. */ /* ==================================================================== diff --git a/src/lib/libcrypto/pkcs12/p12_utl.c b/src/lib/libcrypto/pkcs12/p12_utl.c index 243ec76be9..ca30ac4f6d 100644 --- a/src/lib/libcrypto/pkcs12/p12_utl.c +++ b/src/lib/libcrypto/pkcs12/p12_utl.c @@ -1,5 +1,5 @@ /* p12_utl.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. */ /* ==================================================================== diff --git a/src/lib/libcrypto/pkcs12/pkcs12.h b/src/lib/libcrypto/pkcs12/pkcs12.h index a2d7e359a0..4bee605dc0 100644 --- a/src/lib/libcrypto/pkcs12/pkcs12.h +++ b/src/lib/libcrypto/pkcs12/pkcs12.h @@ -1,5 +1,5 @@ /* pkcs12.h */ -/* 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. */ /* ==================================================================== diff --git a/src/lib/libcrypto/pkcs7/pk7_asn1.c b/src/lib/libcrypto/pkcs7/pk7_asn1.c index 77931feeb4..1f70d31386 100644 --- a/src/lib/libcrypto/pkcs7/pk7_asn1.c +++ b/src/lib/libcrypto/pkcs7/pk7_asn1.c @@ -1,5 +1,5 @@ /* pk7_asn.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. */ /* ==================================================================== diff --git a/src/lib/libcrypto/pkcs7/pk7_attr.c b/src/lib/libcrypto/pkcs7/pk7_attr.c index 735c8800e1..d549717169 100644 --- a/src/lib/libcrypto/pkcs7/pk7_attr.c +++ b/src/lib/libcrypto/pkcs7/pk7_attr.c @@ -1,5 +1,5 @@ /* pk7_attr.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 2001. */ /* ==================================================================== diff --git a/src/lib/libcrypto/pkcs7/pk7_mime.c b/src/lib/libcrypto/pkcs7/pk7_mime.c index 17b68992f7..bf190360d7 100644 --- a/src/lib/libcrypto/pkcs7/pk7_mime.c +++ b/src/lib/libcrypto/pkcs7/pk7_mime.c @@ -1,5 +1,5 @@ /* pk7_mime.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. */ /* ==================================================================== diff --git a/src/lib/libcrypto/pkcs7/pk7_smime.c b/src/lib/libcrypto/pkcs7/pk7_smime.c index 5c6b0fe24b..c34db1d6fe 100644 --- a/src/lib/libcrypto/pkcs7/pk7_smime.c +++ b/src/lib/libcrypto/pkcs7/pk7_smime.c @@ -1,5 +1,5 @@ /* pk7_smime.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. */ /* ==================================================================== @@ -282,6 +282,7 @@ int PKCS7_verify(PKCS7 *p7, STACK_OF(X509) *certs, X509_STORE *store, PKCS7err(PKCS7_F_PKCS7_VERIFY,ERR_R_MALLOC_FAILURE); goto err; } + BIO_set_mem_eof_return(tmpout, 0); } else tmpout = out; /* We now have to 'read' from p7bio to calculate digests etc. */ diff --git a/src/lib/libcrypto/rand/rand.h b/src/lib/libcrypto/rand/rand.h index ac6c021763..ea89153cba 100644 --- a/src/lib/libcrypto/rand/rand.h +++ b/src/lib/libcrypto/rand/rand.h @@ -72,7 +72,7 @@ extern "C" { #endif #if defined(OPENSSL_FIPS) -#define FIPS_RAND_SIZE_T size_t +#define FIPS_RAND_SIZE_T int #endif /* Already defined in ossl_typ.h */ @@ -111,6 +111,15 @@ int RAND_query_egd_bytes(const char *path, unsigned char *buf, int bytes); int RAND_egd(const char *path); int RAND_egd_bytes(const char *path,int bytes); int RAND_poll(void); +#ifndef OPENSSL_NO_ENGINE +#ifdef OPENSSL_FIPS +void int_RAND_init_engine_callbacks(void); +void int_RAND_set_callbacks( + int (*set_rand_func)(const RAND_METHOD *meth, + const RAND_METHOD **pmeth), + const RAND_METHOD *(*get_rand_func)(const RAND_METHOD **pmeth)); +#endif +#endif #if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_WIN32) @@ -128,11 +137,29 @@ void ERR_load_RAND_strings(void); /* Error codes for the RAND functions. */ /* Function codes. */ +#define RAND_F_ENG_RAND_GET_RAND_METHOD 108 +#define RAND_F_FIPS_RAND 103 +#define RAND_F_FIPS_RAND_BYTES 102 +#define RAND_F_FIPS_RAND_GET_RAND_METHOD 109 +#define RAND_F_FIPS_RAND_SET_DT 106 +#define RAND_F_FIPS_SET_DT 104 +#define RAND_F_FIPS_SET_PRNG_SEED 107 +#define RAND_F_FIPS_SET_TEST_MODE 105 #define RAND_F_RAND_GET_RAND_METHOD 101 #define RAND_F_SSLEAY_RAND_BYTES 100 /* Reason codes. */ +#define RAND_R_NON_FIPS_METHOD 105 +#define RAND_R_NOT_IN_TEST_MODE 106 +#define RAND_R_NO_KEY_SET 107 +#define RAND_R_PRNG_ASKING_FOR_TOO_MUCH 101 +#define RAND_R_PRNG_ERROR 108 +#define RAND_R_PRNG_KEYED 109 +#define RAND_R_PRNG_NOT_REKEYED 102 +#define RAND_R_PRNG_NOT_RESEEDED 103 #define RAND_R_PRNG_NOT_SEEDED 100 +#define RAND_R_PRNG_SEED_MUST_NOT_MATCH_KEY 110 +#define RAND_R_PRNG_STUCK 104 #ifdef __cplusplus } diff --git a/src/lib/libcrypto/rand/rand_err.c b/src/lib/libcrypto/rand/rand_err.c index 386934dcd1..829fb44d77 100644 --- a/src/lib/libcrypto/rand/rand_err.c +++ b/src/lib/libcrypto/rand/rand_err.c @@ -1,6 +1,6 @@ /* crypto/rand/rand_err.c */ /* ==================================================================== - * Copyright (c) 1999-2005 The OpenSSL Project. All rights reserved. + * Copyright (c) 1999-2007 The OpenSSL Project. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -70,6 +70,14 @@ static ERR_STRING_DATA RAND_str_functs[]= { +{ERR_FUNC(RAND_F_ENG_RAND_GET_RAND_METHOD), "ENG_RAND_GET_RAND_METHOD"}, +{ERR_FUNC(RAND_F_FIPS_RAND), "FIPS_RAND"}, +{ERR_FUNC(RAND_F_FIPS_RAND_BYTES), "FIPS_RAND_BYTES"}, +{ERR_FUNC(RAND_F_FIPS_RAND_GET_RAND_METHOD), "FIPS_RAND_GET_RAND_METHOD"}, +{ERR_FUNC(RAND_F_FIPS_RAND_SET_DT), "FIPS_RAND_SET_DT"}, +{ERR_FUNC(RAND_F_FIPS_SET_DT), "FIPS_SET_DT"}, +{ERR_FUNC(RAND_F_FIPS_SET_PRNG_SEED), "FIPS_SET_PRNG_SEED"}, +{ERR_FUNC(RAND_F_FIPS_SET_TEST_MODE), "FIPS_SET_TEST_MODE"}, {ERR_FUNC(RAND_F_RAND_GET_RAND_METHOD), "RAND_get_rand_method"}, {ERR_FUNC(RAND_F_SSLEAY_RAND_BYTES), "SSLEAY_RAND_BYTES"}, {0,NULL} @@ -77,7 +85,17 @@ static ERR_STRING_DATA RAND_str_functs[]= static ERR_STRING_DATA RAND_str_reasons[]= { +{ERR_REASON(RAND_R_NON_FIPS_METHOD) ,"non fips method"}, +{ERR_REASON(RAND_R_NOT_IN_TEST_MODE) ,"not in test mode"}, +{ERR_REASON(RAND_R_NO_KEY_SET) ,"no key set"}, +{ERR_REASON(RAND_R_PRNG_ASKING_FOR_TOO_MUCH),"prng asking for too much"}, +{ERR_REASON(RAND_R_PRNG_ERROR) ,"prng error"}, +{ERR_REASON(RAND_R_PRNG_KEYED) ,"prng keyed"}, +{ERR_REASON(RAND_R_PRNG_NOT_REKEYED) ,"prng not rekeyed"}, +{ERR_REASON(RAND_R_PRNG_NOT_RESEEDED) ,"prng not reseeded"}, {ERR_REASON(RAND_R_PRNG_NOT_SEEDED) ,"PRNG not seeded"}, +{ERR_REASON(RAND_R_PRNG_SEED_MUST_NOT_MATCH_KEY),"prng seed must not match key"}, +{ERR_REASON(RAND_R_PRNG_STUCK) ,"prng stuck"}, {0,NULL} }; diff --git a/src/lib/libcrypto/rand/rand_lib.c b/src/lib/libcrypto/rand/rand_lib.c index 513e338985..da6b4e0e86 100644 --- a/src/lib/libcrypto/rand/rand_lib.c +++ b/src/lib/libcrypto/rand/rand_lib.c @@ -60,15 +60,82 @@ #include #include "cryptlib.h" #include +#include "rand_lcl.h" +#ifdef OPENSSL_FIPS +#include +#include +#endif + #ifndef OPENSSL_NO_ENGINE #include #endif +static const RAND_METHOD *default_RAND_meth = NULL; + +#ifdef OPENSSL_FIPS + +static int fips_RAND_set_rand_method(const RAND_METHOD *meth, + const RAND_METHOD **pmeth) + { + *pmeth = meth; + return 1; + } + +static const RAND_METHOD *fips_RAND_get_rand_method(const RAND_METHOD **pmeth) + { + if (!*pmeth) + { + if(FIPS_mode()) + *pmeth=FIPS_rand_method(); + else + *pmeth = RAND_SSLeay(); + } + + if(FIPS_mode() + && *pmeth != FIPS_rand_check()) + { + RANDerr(RAND_F_FIPS_RAND_GET_RAND_METHOD,RAND_R_NON_FIPS_METHOD); + return 0; + } + + return *pmeth; + } + +static int (*RAND_set_rand_method_func)(const RAND_METHOD *meth, + const RAND_METHOD **pmeth) + = fips_RAND_set_rand_method; +static const RAND_METHOD *(*RAND_get_rand_method_func) + (const RAND_METHOD **pmeth) + = fips_RAND_get_rand_method; + +#ifndef OPENSSL_NO_ENGINE +void int_RAND_set_callbacks( + int (*set_rand_func)(const RAND_METHOD *meth, + const RAND_METHOD **pmeth), + const RAND_METHOD *(*get_rand_func) + (const RAND_METHOD **pmeth)) + { + RAND_set_rand_method_func = set_rand_func; + RAND_get_rand_method_func = get_rand_func; + } +#endif + +int RAND_set_rand_method(const RAND_METHOD *meth) + { + return RAND_set_rand_method_func(meth, &default_RAND_meth); + } + +const RAND_METHOD *RAND_get_rand_method(void) + { + return RAND_get_rand_method_func(&default_RAND_meth); + } + +#else + #ifndef OPENSSL_NO_ENGINE /* non-NULL if default_RAND_meth is ENGINE-provided */ static ENGINE *funct_ref =NULL; #endif -static const RAND_METHOD *default_RAND_meth = NULL; int RAND_set_rand_method(const RAND_METHOD *meth) { @@ -129,6 +196,8 @@ int RAND_set_rand_engine(ENGINE *engine) } #endif +#endif + void RAND_cleanup(void) { const RAND_METHOD *meth = RAND_get_rand_method(); diff --git a/src/lib/libcrypto/rand/randfile.c b/src/lib/libcrypto/rand/randfile.c index 6c0ec9a41c..d108353bbc 100644 --- a/src/lib/libcrypto/rand/randfile.c +++ b/src/lib/libcrypto/rand/randfile.c @@ -81,10 +81,25 @@ # include #endif +#ifdef _WIN32 +#define stat _stat +#define chmod _chmod +#define open _open +#define fdopen _fdopen +#endif + #undef BUFSIZE #define BUFSIZE 1024 #define RAND_DATA 1024 +#ifdef OPENSSL_SYS_VMS +/* This declaration is a nasty hack to get around vms' extension to fopen + * for passing in sharing options being disabled by our /STANDARD=ANSI89 */ +static FILE *(*const vms_fopen)(const char *, const char *, ...) = + (FILE *(*)(const char *, const char *, ...))fopen; +#define VMS_OPEN_ATTRS "shr=get,put,upd,del","ctx=bin,stm","rfm=stm","rat=none","mrs=0" +#endif + /* #define RFILE ".rnd" - defined in ../../e_os.h */ /* Note that these functions are intended for seed files only. @@ -106,7 +121,11 @@ int RAND_load_file(const char *file, long bytes) RAND_add(&sb,sizeof(sb),0.0); if (bytes == 0) return(ret); +#ifdef OPENSSL_SYS_VMS + in=vms_fopen(file,"rb",VMS_OPEN_ATTRS); +#else in=fopen(file,"rb"); +#endif if (in == NULL) goto err; #if defined(S_IFBLK) && defined(S_IFCHR) if (sb.st_mode & (S_IFBLK | S_IFCHR)) { @@ -167,7 +186,7 @@ int RAND_write_file(const char *file) #endif } -#if defined(O_CREAT) && !defined(OPENSSL_SYS_WIN32) +#if defined(O_CREAT) && !defined(OPENSSL_SYS_WIN32) && !defined(OPENSSL_SYS_VMS) { /* For some reason Win32 can't write to files created this way */ @@ -178,8 +197,34 @@ int RAND_write_file(const char *file) out = fdopen(fd, "wb"); } #endif + +#ifdef OPENSSL_SYS_VMS + /* VMS NOTE: Prior versions of this routine created a _new_ + * version of the rand file for each call into this routine, then + * deleted all existing versions named ;-1, and finally renamed + * the current version as ';1'. Under concurrent usage, this + * resulted in an RMS race condition in rename() which could + * orphan files (see vms message help for RMS$_REENT). With the + * fopen() calls below, openssl/VMS now shares the top-level + * version of the rand file. Note that there may still be + * conditions where the top-level rand file is locked. If so, this + * code will then create a new version of the rand file. Without + * the delete and rename code, this can result in ascending file + * versions that stop at version 32767, and this routine will then + * return an error. The remedy for this is to recode the calling + * application to avoid concurrent use of the rand file, or + * synchronize usage at the application level. Also consider + * whether or not you NEED a persistent rand file in a concurrent + * use situation. + */ + + out = vms_fopen(file,"rb+",VMS_OPEN_ATTRS); + if (out == NULL) + out = vms_fopen(file,"wb",VMS_OPEN_ATTRS); +#else if (out == NULL) out = fopen(file,"wb"); +#endif if (out == NULL) goto err; #ifndef NO_CHMOD @@ -201,25 +246,6 @@ int RAND_write_file(const char *file) ret+=i; if (n <= 0) break; } -#ifdef OPENSSL_SYS_VMS - /* Try to delete older versions of the file, until there aren't - any */ - { - char *tmpf; - - tmpf = OPENSSL_malloc(strlen(file) + 4); /* to add ";-1" and a nul */ - if (tmpf) - { - strcpy(tmpf, file); - strcat(tmpf, ";-1"); - while(delete(tmpf) == 0) - ; - rename(file,";1"); /* Make sure it's version 1, or we - will reach the limit (32767) at - some point... */ - } - } -#endif /* OPENSSL_SYS_VMS */ fclose(out); OPENSSL_cleanse(buf,BUFSIZE); diff --git a/src/lib/libcrypto/rc2/rc2.h b/src/lib/libcrypto/rc2/rc2.h index 34c8362317..e542ec94ff 100644 --- a/src/lib/libcrypto/rc2/rc2.h +++ b/src/lib/libcrypto/rc2/rc2.h @@ -79,7 +79,9 @@ typedef struct rc2_key_st RC2_INT data[64]; } RC2_KEY; - +#ifdef OPENSSL_FIPS +void private_RC2_set_key(RC2_KEY *key, int len, const unsigned char *data,int bits); +#endif void RC2_set_key(RC2_KEY *key, int len, const unsigned char *data,int bits); void RC2_ecb_encrypt(const unsigned char *in,unsigned char *out,RC2_KEY *key, int enc); diff --git a/src/lib/libcrypto/rc2/rc2_skey.c b/src/lib/libcrypto/rc2/rc2_skey.c index 4953642056..4e000e5b99 100644 --- a/src/lib/libcrypto/rc2/rc2_skey.c +++ b/src/lib/libcrypto/rc2/rc2_skey.c @@ -57,6 +57,11 @@ */ #include +#include +#ifdef OPENSSL_FIPS +#include +#endif + #include "rc2_locl.h" static unsigned char key_table[256]={ @@ -94,7 +99,19 @@ static unsigned char key_table[256]={ * BSAFE uses the 'retarded' version. What I previously shipped is * the same as specifying 1024 for the 'bits' parameter. Bsafe uses * a version where the bits parameter is the same as len*8 */ + +#ifdef OPENSSL_FIPS void RC2_set_key(RC2_KEY *key, int len, const unsigned char *data, int bits) + { + if (FIPS_mode()) + FIPS_BAD_ABORT(RC2) + private_RC2_set_key(key, len, data, bits); + } +void private_RC2_set_key(RC2_KEY *key, int len, const unsigned char *data, + int bits) +#else +void RC2_set_key(RC2_KEY *key, int len, const unsigned char *data, int bits) +#endif { int i,j; unsigned char *k; diff --git a/src/lib/libcrypto/rc4/asm/rc4-x86_64.pl b/src/lib/libcrypto/rc4/asm/rc4-x86_64.pl index 2d47320485..00c6fa28aa 100755 --- a/src/lib/libcrypto/rc4/asm/rc4-x86_64.pl +++ b/src/lib/libcrypto/rc4/asm/rc4-x86_64.pl @@ -359,6 +359,8 @@ ___ $code =~ s/#([bwd])/$1/gm; +$code =~ s/RC4_set_key/private_RC4_set_key/g if ($ENV{FIPSCANLIB} ne ""); + print $code; close STDOUT; diff --git a/src/lib/libcrypto/rc4/rc4.h b/src/lib/libcrypto/rc4/rc4.h index 7aec04fe93..2d8620d33b 100644 --- a/src/lib/libcrypto/rc4/rc4.h +++ b/src/lib/libcrypto/rc4/rc4.h @@ -76,6 +76,9 @@ typedef struct rc4_key_st const char *RC4_options(void); +#ifdef OPENSSL_FIPS +void private_RC4_set_key(RC4_KEY *key, int len, const unsigned char *data); +#endif void RC4_set_key(RC4_KEY *key, int len, const unsigned char *data); void RC4(RC4_KEY *key, unsigned long len, const unsigned char *indata, unsigned char *outdata); diff --git a/src/lib/libcrypto/rc4/rc4_skey.c b/src/lib/libcrypto/rc4/rc4_skey.c index 46b77ec321..4478d1a4b3 100644 --- a/src/lib/libcrypto/rc4/rc4_skey.c +++ b/src/lib/libcrypto/rc4/rc4_skey.c @@ -59,6 +59,11 @@ #include #include "rc4_locl.h" #include +#include +#ifdef OPENSSL_FIPS +#include +#endif + const char RC4_version[]="RC4" OPENSSL_VERSION_PTEXT; @@ -85,7 +90,11 @@ const char *RC4_options(void) * Date: Wed, 14 Sep 1994 06:35:31 GMT */ +#ifdef OPENSSL_FIPS +void private_RC4_set_key(RC4_KEY *key, int len, const unsigned char *data) +#else void RC4_set_key(RC4_KEY *key, int len, const unsigned char *data) +#endif { register RC4_INT tmp; register int id1,id2; @@ -127,7 +136,12 @@ void RC4_set_key(RC4_KEY *key, int len, const unsigned char *data) * * */ - if (OPENSSL_ia32cap_P & (1<<20)) { +#ifdef OPENSSL_FIPS + unsigned long *ia32cap_ptr = OPENSSL_ia32cap_loc(); + if (ia32cap_ptr && (*ia32cap_ptr & (1<<28))) { +#else + if (OPENSSL_ia32cap_P & (1<<28)) { +#endif unsigned char *cp=(unsigned char *)d; for (i=0;i<256;i++) cp[i]=i; diff --git a/src/lib/libcrypto/ripemd/ripemd.h b/src/lib/libcrypto/ripemd/ripemd.h index 033a5965b5..3b6d04386d 100644 --- a/src/lib/libcrypto/ripemd/ripemd.h +++ b/src/lib/libcrypto/ripemd/ripemd.h @@ -90,7 +90,9 @@ typedef struct RIPEMD160state_st RIPEMD160_LONG data[RIPEMD160_LBLOCK]; unsigned int num; } RIPEMD160_CTX; - +#ifdef OPENSSL_FIPS +int private_RIPEMD160_Init(RIPEMD160_CTX *c); +#endif int RIPEMD160_Init(RIPEMD160_CTX *c); int RIPEMD160_Update(RIPEMD160_CTX *c, const void *data, size_t len); int RIPEMD160_Final(unsigned char *md, RIPEMD160_CTX *c); diff --git a/src/lib/libcrypto/ripemd/rmd_dgst.c b/src/lib/libcrypto/ripemd/rmd_dgst.c index 61626284b8..ead11d075a 100644 --- a/src/lib/libcrypto/ripemd/rmd_dgst.c +++ b/src/lib/libcrypto/ripemd/rmd_dgst.c @@ -59,6 +59,11 @@ #include #include "rmd_locl.h" #include +#include +#ifdef OPENSSL_FIPS +#include +#endif + const char RMD160_version[]="RIPE-MD160" OPENSSL_VERSION_PTEXT; @@ -69,7 +74,7 @@ const char RMD160_version[]="RIPE-MD160" OPENSSL_VERSION_PTEXT; void ripemd160_block(RIPEMD160_CTX *c, unsigned long *p,size_t num); # endif -int RIPEMD160_Init(RIPEMD160_CTX *c) +FIPS_NON_FIPS_MD_Init(RIPEMD160) { c->A=RIPEMD160_A; c->B=RIPEMD160_B; diff --git a/src/lib/libcrypto/ripemd/rmd_locl.h b/src/lib/libcrypto/ripemd/rmd_locl.h index f14b346e66..ce12a8000e 100644 --- a/src/lib/libcrypto/ripemd/rmd_locl.h +++ b/src/lib/libcrypto/ripemd/rmd_locl.h @@ -72,7 +72,7 @@ */ #ifdef RMD160_ASM # if defined(__i386) || defined(__i386__) || defined(_M_IX86) || defined(__INTEL__) -# define ripemd160_block_data_order ripemd160_block_asm_data_order +# define ripemd160_block_host_order ripemd160_block_asm_data_order # endif #endif diff --git a/src/lib/libcrypto/rsa/rsa.h b/src/lib/libcrypto/rsa/rsa.h index 6b5e4f8a9a..5bb932ae15 100644 --- a/src/lib/libcrypto/rsa/rsa.h +++ b/src/lib/libcrypto/rsa/rsa.h @@ -74,6 +74,25 @@ #error RSA is disabled. #endif +/* If this flag is set the RSA method is FIPS compliant and can be used + * in FIPS mode. This is set in the validated module method. If an + * application sets this flag in its own methods it is its reposibility + * to ensure the result is compliant. + */ + +#define RSA_FLAG_FIPS_METHOD 0x0400 + +/* If this flag is set the operations normally disabled in FIPS mode are + * permitted it is then the applications responsibility to ensure that the + * usage is compliant. + */ + +#define RSA_FLAG_NON_FIPS_ALLOW 0x0400 + +#ifdef OPENSSL_FIPS +#define FIPS_RSA_SIZE_T int +#endif + #ifdef __cplusplus extern "C" { #endif @@ -163,6 +182,8 @@ struct rsa_st # define OPENSSL_RSA_MAX_MODULUS_BITS 16384 #endif +#define OPENSSL_RSA_FIPS_MIN_MODULUS_BITS 1024 + #ifndef OPENSSL_RSA_SMALL_MODULUS_BITS # define OPENSSL_RSA_SMALL_MODULUS_BITS 3072 #endif @@ -240,6 +261,11 @@ RSA * RSA_generate_key(int bits, unsigned long e,void /* New version */ int RSA_generate_key_ex(RSA *rsa, int bits, BIGNUM *e, BN_GENCB *cb); +int RSA_X931_derive_ex(RSA *rsa, BIGNUM *p1, BIGNUM *p2, BIGNUM *q1, BIGNUM *q2, + const BIGNUM *Xp1, const BIGNUM *Xp2, const BIGNUM *Xp, + const BIGNUM *Xq1, const BIGNUM *Xq2, const BIGNUM *Xq, + const BIGNUM *e, BN_GENCB *cb); +int RSA_X931_generate_key_ex(RSA *rsa, int bits, const BIGNUM *e, BN_GENCB *cb); int RSA_check_key(const RSA *); /* next 4 return -1 on error */ @@ -257,6 +283,11 @@ int RSA_up_ref(RSA *r); int RSA_flags(const RSA *r); +#ifdef OPENSSL_FIPS +RSA *FIPS_rsa_new(void); +void FIPS_rsa_free(RSA *r); +#endif + void RSA_set_default_method(const RSA_METHOD *meth); const RSA_METHOD *RSA_get_default_method(void); const RSA_METHOD *RSA_get_method(const RSA *rsa); @@ -281,6 +312,7 @@ int RSA_print_fp(FILE *fp, const RSA *r,int offset); int RSA_print(BIO *bp, const RSA *r,int offset); #endif +#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); @@ -294,6 +326,7 @@ int i2d_Netscape_RSA(const RSA *a, unsigned char **pp, 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 */ @@ -368,6 +401,8 @@ void ERR_load_RSA_strings(void); /* Error codes for the RSA functions. */ /* Function codes. */ +#define RSA_F_FIPS_RSA_SIGN 140 +#define RSA_F_FIPS_RSA_VERIFY 141 #define RSA_F_MEMORY_LOCK 100 #define RSA_F_RSA_BUILTIN_KEYGEN 129 #define RSA_F_RSA_CHECK_KEY 123 @@ -399,7 +434,11 @@ void ERR_load_RSA_strings(void); #define RSA_F_RSA_PADDING_CHECK_X931 128 #define RSA_F_RSA_PRINT 115 #define RSA_F_RSA_PRINT_FP 116 +#define RSA_F_RSA_PRIVATE_ENCRYPT 137 +#define RSA_F_RSA_PUBLIC_DECRYPT 138 #define RSA_F_RSA_SETUP_BLINDING 136 +#define RSA_F_RSA_SET_DEFAULT_METHOD 139 +#define RSA_F_RSA_SET_METHOD 142 #define RSA_F_RSA_SIGN 117 #define RSA_F_RSA_SIGN_ASN1_OCTET_STRING 118 #define RSA_F_RSA_VERIFY 119 @@ -433,10 +472,12 @@ void ERR_load_RSA_strings(void); #define RSA_R_KEY_SIZE_TOO_SMALL 120 #define RSA_R_LAST_OCTET_INVALID 134 #define RSA_R_MODULUS_TOO_LARGE 105 +#define RSA_R_NON_FIPS_METHOD 141 #define RSA_R_NO_PUBLIC_EXPONENT 140 #define RSA_R_NULL_BEFORE_BLOCK_MISSING 113 #define RSA_R_N_DOES_NOT_EQUAL_P_Q 127 #define RSA_R_OAEP_DECODING_ERROR 121 +#define RSA_R_OPERATION_NOT_ALLOWED_IN_FIPS_MODE 142 #define RSA_R_PADDING_CHECK_FAILED 114 #define RSA_R_P_NOT_PRIME 128 #define RSA_R_Q_NOT_PRIME 129 diff --git a/src/lib/libcrypto/rsa/rsa_asn1.c b/src/lib/libcrypto/rsa/rsa_asn1.c index bbbf26d50e..6e8a803e81 100644 --- a/src/lib/libcrypto/rsa/rsa_asn1.c +++ b/src/lib/libcrypto/rsa/rsa_asn1.c @@ -1,5 +1,5 @@ /* 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. */ /* ==================================================================== diff --git a/src/lib/libcrypto/rsa/rsa_eay.c b/src/lib/libcrypto/rsa/rsa_eay.c index ffadaab9a4..0ac6418449 100644 --- a/src/lib/libcrypto/rsa/rsa_eay.c +++ b/src/lib/libcrypto/rsa/rsa_eay.c @@ -115,7 +115,7 @@ #include #include -#ifndef RSA_NULL +#if !defined(RSA_NULL) && !defined(OPENSSL_FIPS) static int RSA_eay_public_encrypt(int flen, const unsigned char *from, unsigned char *to, RSA *rsa,int padding); @@ -150,16 +150,6 @@ const RSA_METHOD *RSA_PKCS1_SSLeay(void) return(&rsa_pkcs1_eay_meth); } -/* Usage example; - * MONT_HELPER(rsa->_method_mod_p, bn_ctx, rsa->p, rsa->flags & RSA_FLAG_CACHE_PRIVATE, goto err); - */ -#define MONT_HELPER(method_mod, ctx, m, pre_cond, err_instr) \ - if ((pre_cond) && ((method_mod) == NULL) && \ - !BN_MONT_CTX_set_locked(&(method_mod), \ - CRYPTO_LOCK_RSA, \ - (m), (ctx))) \ - err_instr - static int RSA_eay_public_encrypt(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding) { @@ -233,7 +223,9 @@ static int RSA_eay_public_encrypt(int flen, const unsigned char *from, goto err; } - MONT_HELPER(rsa->_method_mod_n, ctx, rsa->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; @@ -438,7 +430,9 @@ static int RSA_eay_private_encrypt(int flen, const unsigned char *from, else d= rsa->d; - MONT_HELPER(rsa->_method_mod_n, ctx, rsa->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,d,rsa->n,ctx, rsa->_method_mod_n)) goto err; @@ -559,7 +553,9 @@ static int RSA_eay_private_decrypt(int flen, const unsigned char *from, else d = rsa->d; - MONT_HELPER(rsa->_method_mod_n, ctx, rsa->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,d,rsa->n,ctx, rsa->_method_mod_n)) goto err; @@ -669,7 +665,9 @@ static int RSA_eay_public_decrypt(int flen, const unsigned char *from, goto err; } - MONT_HELPER(rsa->_method_mod_n, ctx, rsa->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; @@ -747,11 +745,18 @@ static int RSA_eay_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx) q = rsa->q; } - MONT_HELPER(rsa->_method_mod_p, ctx, p, rsa->flags & RSA_FLAG_CACHE_PRIVATE, goto err); - MONT_HELPER(rsa->_method_mod_q, ctx, q, rsa->flags & RSA_FLAG_CACHE_PRIVATE, goto err); + 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; + } } - MONT_HELPER(rsa->_method_mod_n, ctx, rsa->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; /* compute I mod q */ if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME)) diff --git a/src/lib/libcrypto/rsa/rsa_err.c b/src/lib/libcrypto/rsa/rsa_err.c index fe3ba1b44b..501f5ea389 100644 --- a/src/lib/libcrypto/rsa/rsa_err.c +++ b/src/lib/libcrypto/rsa/rsa_err.c @@ -1,6 +1,6 @@ /* crypto/rsa/rsa_err.c */ /* ==================================================================== - * Copyright (c) 1999-2005 The OpenSSL Project. All rights reserved. + * Copyright (c) 1999-2007 The OpenSSL Project. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -70,6 +70,8 @@ static ERR_STRING_DATA RSA_str_functs[]= { +{ERR_FUNC(RSA_F_FIPS_RSA_SIGN), "FIPS_RSA_SIGN"}, +{ERR_FUNC(RSA_F_FIPS_RSA_VERIFY), "FIPS_RSA_VERIFY"}, {ERR_FUNC(RSA_F_MEMORY_LOCK), "MEMORY_LOCK"}, {ERR_FUNC(RSA_F_RSA_BUILTIN_KEYGEN), "RSA_BUILTIN_KEYGEN"}, {ERR_FUNC(RSA_F_RSA_CHECK_KEY), "RSA_check_key"}, @@ -101,7 +103,11 @@ static ERR_STRING_DATA RSA_str_functs[]= {ERR_FUNC(RSA_F_RSA_PADDING_CHECK_X931), "RSA_padding_check_X931"}, {ERR_FUNC(RSA_F_RSA_PRINT), "RSA_print"}, {ERR_FUNC(RSA_F_RSA_PRINT_FP), "RSA_print_fp"}, +{ERR_FUNC(RSA_F_RSA_PRIVATE_ENCRYPT), "RSA_private_encrypt"}, +{ERR_FUNC(RSA_F_RSA_PUBLIC_DECRYPT), "RSA_public_decrypt"}, {ERR_FUNC(RSA_F_RSA_SETUP_BLINDING), "RSA_setup_blinding"}, +{ERR_FUNC(RSA_F_RSA_SET_DEFAULT_METHOD), "RSA_set_default_method"}, +{ERR_FUNC(RSA_F_RSA_SET_METHOD), "RSA_set_method"}, {ERR_FUNC(RSA_F_RSA_SIGN), "RSA_sign"}, {ERR_FUNC(RSA_F_RSA_SIGN_ASN1_OCTET_STRING), "RSA_sign_ASN1_OCTET_STRING"}, {ERR_FUNC(RSA_F_RSA_VERIFY), "RSA_verify"}, @@ -138,10 +144,12 @@ static ERR_STRING_DATA RSA_str_reasons[]= {ERR_REASON(RSA_R_KEY_SIZE_TOO_SMALL) ,"key size too small"}, {ERR_REASON(RSA_R_LAST_OCTET_INVALID) ,"last octet invalid"}, {ERR_REASON(RSA_R_MODULUS_TOO_LARGE) ,"modulus too large"}, +{ERR_REASON(RSA_R_NON_FIPS_METHOD) ,"non fips method"}, {ERR_REASON(RSA_R_NO_PUBLIC_EXPONENT) ,"no public exponent"}, {ERR_REASON(RSA_R_NULL_BEFORE_BLOCK_MISSING),"null before block missing"}, {ERR_REASON(RSA_R_N_DOES_NOT_EQUAL_P_Q) ,"n does not equal p q"}, {ERR_REASON(RSA_R_OAEP_DECODING_ERROR) ,"oaep decoding error"}, +{ERR_REASON(RSA_R_OPERATION_NOT_ALLOWED_IN_FIPS_MODE),"operation not allowed in fips mode"}, {ERR_REASON(RSA_R_PADDING_CHECK_FAILED) ,"padding check failed"}, {ERR_REASON(RSA_R_P_NOT_PRIME) ,"p not prime"}, {ERR_REASON(RSA_R_Q_NOT_PRIME) ,"q not prime"}, diff --git a/src/lib/libcrypto/rsa/rsa_gen.c b/src/lib/libcrypto/rsa/rsa_gen.c index 767f7ab682..41278f83c6 100644 --- a/src/lib/libcrypto/rsa/rsa_gen.c +++ b/src/lib/libcrypto/rsa/rsa_gen.c @@ -68,6 +68,8 @@ #include #include +#ifndef OPENSSL_FIPS + static int rsa_builtin_keygen(RSA *rsa, int bits, BIGNUM *e_value, BN_GENCB *cb); /* NB: this wrapper would normally be placed in rsa_lib.c and the static @@ -217,3 +219,4 @@ err: return ok; } +#endif diff --git a/src/lib/libcrypto/rsa/rsa_lib.c b/src/lib/libcrypto/rsa/rsa_lib.c index 104aa4c1f2..5714841f4c 100644 --- a/src/lib/libcrypto/rsa/rsa_lib.c +++ b/src/lib/libcrypto/rsa/rsa_lib.c @@ -67,215 +67,6 @@ #include #endif -const char RSA_version[]="RSA" OPENSSL_VERSION_PTEXT; - -static const RSA_METHOD *default_RSA_meth=NULL; - -RSA *RSA_new(void) - { - RSA *r=RSA_new_method(NULL); - - return r; - } - -void RSA_set_default_method(const RSA_METHOD *meth) - { - default_RSA_meth = meth; - } - -const RSA_METHOD *RSA_get_default_method(void) - { - if (default_RSA_meth == NULL) - { -#ifdef RSA_NULL - default_RSA_meth=RSA_null_method(); -#else -#if 0 /* was: #ifdef RSAref */ - default_RSA_meth=RSA_PKCS1_RSAref(); -#else - default_RSA_meth=RSA_PKCS1_SSLeay(); -#endif -#endif - } - - return default_RSA_meth; - } - -const RSA_METHOD *RSA_get_method(const RSA *rsa) - { - return rsa->meth; - } - -int RSA_set_method(RSA *rsa, const RSA_METHOD *meth) - { - /* NB: The caller is specifically setting a method, so it's not up to us - * to deal with which ENGINE it comes from. */ - const RSA_METHOD *mtmp; - mtmp = rsa->meth; - if (mtmp->finish) mtmp->finish(rsa); -#ifndef OPENSSL_NO_ENGINE - if (rsa->engine) - { - ENGINE_finish(rsa->engine); - rsa->engine = NULL; - } -#endif - rsa->meth = meth; - if (meth->init) meth->init(rsa); - return 1; - } - -RSA *RSA_new_method(ENGINE *engine) - { - RSA *ret; - - ret=(RSA *)OPENSSL_malloc(sizeof(RSA)); - if (ret == NULL) - { - RSAerr(RSA_F_RSA_NEW_METHOD,ERR_R_MALLOC_FAILURE); - return NULL; - } - - ret->meth = RSA_get_default_method(); -#ifndef OPENSSL_NO_ENGINE - if (engine) - { - if (!ENGINE_init(engine)) - { - RSAerr(RSA_F_RSA_NEW_METHOD, ERR_R_ENGINE_LIB); - OPENSSL_free(ret); - return NULL; - } - ret->engine = engine; - } - else - ret->engine = ENGINE_get_default_RSA(); - if(ret->engine) - { - ret->meth = ENGINE_get_RSA(ret->engine); - if(!ret->meth) - { - RSAerr(RSA_F_RSA_NEW_METHOD, - ERR_R_ENGINE_LIB); - ENGINE_finish(ret->engine); - OPENSSL_free(ret); - return NULL; - } - } -#endif - - ret->pad=0; - ret->version=0; - ret->n=NULL; - ret->e=NULL; - ret->d=NULL; - ret->p=NULL; - ret->q=NULL; - ret->dmp1=NULL; - ret->dmq1=NULL; - ret->iqmp=NULL; - ret->references=1; - ret->_method_mod_n=NULL; - 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 ((ret->meth->init != NULL) && !ret->meth->init(ret)) - { -#ifndef OPENSSL_NO_ENGINE - if (ret->engine) - ENGINE_finish(ret->engine); -#endif - CRYPTO_free_ex_data(CRYPTO_EX_INDEX_RSA, ret, &ret->ex_data); - OPENSSL_free(ret); - ret=NULL; - } - return(ret); - } - -void RSA_free(RSA *r) - { - int i; - - if (r == NULL) return; - - i=CRYPTO_add(&r->references,-1,CRYPTO_LOCK_RSA); -#ifdef REF_PRINT - REF_PRINT("RSA",r); -#endif - if (i > 0) return; -#ifdef REF_CHECK - if (i < 0) - { - fprintf(stderr,"RSA_free, bad reference count\n"); - abort(); - } -#endif - - if (r->meth->finish) - r->meth->finish(r); -#ifndef OPENSSL_NO_ENGINE - if (r->engine) - ENGINE_finish(r->engine); -#endif - - CRYPTO_free_ex_data(CRYPTO_EX_INDEX_RSA, r, &r->ex_data); - - if (r->n != NULL) BN_clear_free(r->n); - if (r->e != NULL) BN_clear_free(r->e); - if (r->d != NULL) BN_clear_free(r->d); - if (r->p != NULL) BN_clear_free(r->p); - if (r->q != NULL) BN_clear_free(r->q); - if (r->dmp1 != NULL) BN_clear_free(r->dmp1); - if (r->dmq1 != NULL) BN_clear_free(r->dmq1); - if (r->iqmp != NULL) BN_clear_free(r->iqmp); - if (r->blinding != NULL) BN_BLINDING_free(r->blinding); - if (r->mt_blinding != NULL) BN_BLINDING_free(r->mt_blinding); - if (r->bignum_data != NULL) OPENSSL_free_locked(r->bignum_data); - OPENSSL_free(r); - } - -int RSA_up_ref(RSA *r) - { - int i = CRYPTO_add(&r->references, 1, CRYPTO_LOCK_RSA); -#ifdef REF_PRINT - REF_PRINT("RSA",r); -#endif -#ifdef REF_CHECK - if (i < 2) - { - fprintf(stderr, "RSA_up_ref, bad reference count\n"); - abort(); - } -#endif - return ((i > 1) ? 1 : 0); - } - -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) - { - return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_RSA, argl, argp, - new_func, dup_func, free_func); - } - -int RSA_set_ex_data(RSA *r, int idx, void *arg) - { - return(CRYPTO_set_ex_data(&r->ex_data,idx,arg)); - } - -void *RSA_get_ex_data(const RSA *r, int idx) - { - return(CRYPTO_get_ex_data(&r->ex_data,idx)); - } - -int RSA_size(const RSA *r) - { - return(BN_num_bytes(r->n)); - } - int RSA_public_encrypt(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding) { @@ -285,6 +76,13 @@ int RSA_public_encrypt(int flen, const unsigned char *from, unsigned char *to, int RSA_private_encrypt(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding) { +#ifdef OPENSSL_FIPS + if(FIPS_mode() && !(rsa->flags & RSA_FLAG_NON_FIPS_ALLOW)) + { + RSAerr(RSA_F_RSA_PRIVATE_ENCRYPT, RSA_R_OPERATION_NOT_ALLOWED_IN_FIPS_MODE); + return 0; + } +#endif return(rsa->meth->rsa_priv_enc(flen, from, to, rsa, padding)); } @@ -297,12 +95,19 @@ int RSA_private_decrypt(int flen, const unsigned char *from, unsigned char *to, int RSA_public_decrypt(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding) { +#ifdef OPENSSL_FIPS + if(FIPS_mode() && !(rsa->flags & RSA_FLAG_NON_FIPS_ALLOW)) + { + RSAerr(RSA_F_RSA_PUBLIC_DECRYPT, RSA_R_OPERATION_NOT_ALLOWED_IN_FIPS_MODE); + return 0; + } +#endif return(rsa->meth->rsa_pub_dec(flen, from, to, rsa, padding)); } -int RSA_flags(const RSA *r) +int RSA_size(const RSA *r) { - return((r == NULL)?0:r->meth->flags); + return(BN_num_bytes(r->n)); } void RSA_blinding_off(RSA *rsa) @@ -427,48 +232,3 @@ err: return ret; } - -int RSA_memory_lock(RSA *r) - { - int i,j,k,off; - char *p; - BIGNUM *bn,**t[6],*b; - BN_ULONG *ul; - - if (r->d == NULL) return(1); - t[0]= &r->d; - t[1]= &r->p; - t[2]= &r->q; - t[3]= &r->dmp1; - t[4]= &r->dmq1; - t[5]= &r->iqmp; - k=sizeof(BIGNUM)*6; - off=k/sizeof(BN_ULONG)+1; - j=1; - for (i=0; i<6; i++) - j+= (*t[i])->top; - if ((p=OPENSSL_malloc_locked((off+j)*sizeof(BN_ULONG))) == NULL) - { - RSAerr(RSA_F_RSA_MEMORY_LOCK,ERR_R_MALLOC_FAILURE); - return(0); - } - bn=(BIGNUM *)p; - ul=(BN_ULONG *)&(p[off]); - for (i=0; i<6; i++) - { - b= *(t[i]); - *(t[i])= &(bn[i]); - memcpy((char *)&(bn[i]),(char *)b,sizeof(BIGNUM)); - bn[i].flags=BN_FLG_STATIC_DATA; - bn[i].d=ul; - memcpy((char *)ul,b->d,sizeof(BN_ULONG)*b->top); - ul+=b->top; - BN_clear_free(b); - } - - /* I should fix this so it can still be done */ - r->flags&= ~(RSA_FLAG_CACHE_PRIVATE|RSA_FLAG_CACHE_PUBLIC); - - r->bignum_data=p; - return(1); - } diff --git a/src/lib/libcrypto/rsa/rsa_oaep.c b/src/lib/libcrypto/rsa/rsa_oaep.c index 3652677a99..4d30c9d2d3 100644 --- a/src/lib/libcrypto/rsa/rsa_oaep.c +++ b/src/lib/libcrypto/rsa/rsa_oaep.c @@ -187,7 +187,7 @@ int PKCS1_MGF1(unsigned char *mask, long len, int mdlen; EVP_MD_CTX_init(&c); - mdlen = EVP_MD_size(dgst); + mdlen = M_EVP_MD_size(dgst); for (i = 0; outlen < len; i++) { cnt[0] = (unsigned char)((i >> 24) & 255); diff --git a/src/lib/libcrypto/rsa/rsa_pss.c b/src/lib/libcrypto/rsa/rsa_pss.c index e19d18c5b9..9b993aca49 100644 --- a/src/lib/libcrypto/rsa/rsa_pss.c +++ b/src/lib/libcrypto/rsa/rsa_pss.c @@ -1,5 +1,5 @@ /* rsa_pss.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 2005. */ /* ==================================================================== @@ -81,7 +81,7 @@ int RSA_verify_PKCS1_PSS(RSA *rsa, const unsigned char *mHash, EVP_MD_CTX ctx; unsigned char H_[EVP_MAX_MD_SIZE]; - hLen = EVP_MD_size(Hash); + hLen = M_EVP_MD_size(Hash); /* * Negative sLen has special meanings: * -1 sLen == hLen @@ -176,7 +176,7 @@ int RSA_padding_add_PKCS1_PSS(RSA *rsa, unsigned char *EM, unsigned char *H, *salt = NULL, *p; EVP_MD_CTX ctx; - hLen = EVP_MD_size(Hash); + hLen = M_EVP_MD_size(Hash); /* * Negative sLen has special meanings: * -1 sLen == hLen diff --git a/src/lib/libcrypto/rsa/rsa_sign.c b/src/lib/libcrypto/rsa/rsa_sign.c index 71aabeea1b..5488c06f6d 100644 --- a/src/lib/libcrypto/rsa/rsa_sign.c +++ b/src/lib/libcrypto/rsa/rsa_sign.c @@ -90,6 +90,14 @@ int RSA_sign(int type, const unsigned char *m, unsigned int m_len, i = SSL_SIG_LENGTH; s = m; } else { + /* NB: in FIPS mode block anything that isn't a TLS signature */ +#ifdef OPENSSL_FIPS + if(FIPS_mode() && !(rsa->flags & RSA_FLAG_NON_FIPS_ALLOW)) + { + RSAerr(RSA_F_RSA_SIGN, RSA_R_OPERATION_NOT_ALLOWED_IN_FIPS_MODE); + return 0; + } +#endif sig.algor= &algor; sig.algor->algorithm=OBJ_nid2obj(type); if (sig.algor->algorithm == NULL) @@ -167,10 +175,22 @@ int RSA_verify(int dtype, const unsigned char *m, unsigned int m_len, RSAerr(RSA_F_RSA_VERIFY,ERR_R_MALLOC_FAILURE); goto err; } - if((dtype == NID_md5_sha1) && (m_len != SSL_SIG_LENGTH) ) { + if(dtype == NID_md5_sha1) + { + if (m_len != SSL_SIG_LENGTH) + { RSAerr(RSA_F_RSA_VERIFY,RSA_R_INVALID_MESSAGE_LENGTH); goto err; - } + } + } + /* NB: in FIPS mode block anything that isn't a TLS signature */ +#ifdef OPENSSL_FIPS + else if(FIPS_mode() && !(rsa->flags & RSA_FLAG_NON_FIPS_ALLOW)) + { + RSAerr(RSA_F_RSA_VERIFY, RSA_R_OPERATION_NOT_ALLOWED_IN_FIPS_MODE); + return 0; + } +#endif i=RSA_public_decrypt((int)siglen,sigbuf,s,rsa,RSA_PKCS1_PADDING); if (i <= 0) goto err; diff --git a/src/lib/libcrypto/rsa/rsa_ssl.c b/src/lib/libcrypto/rsa/rsa_ssl.c index ea72629494..cfeff15bc9 100644 --- a/src/lib/libcrypto/rsa/rsa_ssl.c +++ b/src/lib/libcrypto/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/src/lib/libcrypto/rsa/rsa_x931.c b/src/lib/libcrypto/rsa/rsa_x931.c index e918654176..21548e37ed 100644 --- a/src/lib/libcrypto/rsa/rsa_x931.c +++ b/src/lib/libcrypto/rsa/rsa_x931.c @@ -1,5 +1,5 @@ /* rsa_x931.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 2005. */ /* ==================================================================== diff --git a/src/lib/libcrypto/sha/asm/sha1-586.pl b/src/lib/libcrypto/sha/asm/sha1-586.pl index 0b4dab2bd5..a787dd37da 100644 --- a/src/lib/libcrypto/sha/asm/sha1-586.pl +++ b/src/lib/libcrypto/sha/asm/sha1-586.pl @@ -149,7 +149,7 @@ sub BODY_40_59 &add($f,$e); # f+=ROTATE(a,5) } -&function_begin("sha1_block_data_order",16); +&function_begin("sha1_block_data_order"); &mov($tmp1,&wparam(0)); # SHA_CTX *c &mov($T,&wparam(1)); # const void *input &mov($A,&wparam(2)); # size_t num diff --git a/src/lib/libcrypto/sha/sha.h b/src/lib/libcrypto/sha/sha.h index eed44d7f94..47a2c29f66 100644 --- a/src/lib/libcrypto/sha/sha.h +++ b/src/lib/libcrypto/sha/sha.h @@ -106,6 +106,9 @@ typedef struct SHAstate_st } SHA_CTX; #ifndef OPENSSL_NO_SHA0 +#ifdef OPENSSL_FIPS +int private_SHA_Init(SHA_CTX *c); +#endif int SHA_Init(SHA_CTX *c); int SHA_Update(SHA_CTX *c, const void *data, size_t len); int SHA_Final(unsigned char *md, SHA_CTX *c); diff --git a/src/lib/libcrypto/sha/sha1_one.c b/src/lib/libcrypto/sha/sha1_one.c index 7c65b60276..4831174198 100644 --- a/src/lib/libcrypto/sha/sha1_one.c +++ b/src/lib/libcrypto/sha/sha1_one.c @@ -61,7 +61,7 @@ #include #include -#ifndef OPENSSL_NO_SHA1 +#if !defined(OPENSSL_NO_SHA1) unsigned char *SHA1(const unsigned char *d, size_t n, unsigned char *md) { SHA_CTX c; diff --git a/src/lib/libcrypto/sha/sha1dgst.c b/src/lib/libcrypto/sha/sha1dgst.c index 50d1925cde..d31f0781a0 100644 --- a/src/lib/libcrypto/sha/sha1dgst.c +++ b/src/lib/libcrypto/sha/sha1dgst.c @@ -63,6 +63,10 @@ #define SHA_1 #include +#ifdef OPENSSL_FIPS +#include +#endif + const char SHA1_version[]="SHA1" OPENSSL_VERSION_PTEXT; diff --git a/src/lib/libcrypto/sha/sha256.c b/src/lib/libcrypto/sha/sha256.c index 867f90cc97..3256a83e98 100644 --- a/src/lib/libcrypto/sha/sha256.c +++ b/src/lib/libcrypto/sha/sha256.c @@ -12,12 +12,19 @@ #include #include +#ifdef OPENSSL_FIPS +#include +#endif + #include const char SHA256_version[]="SHA-256" OPENSSL_VERSION_PTEXT; int SHA224_Init (SHA256_CTX *c) { +#ifdef OPENSSL_FIPS + FIPS_selftest_check(); +#endif c->h[0]=0xc1059ed8UL; c->h[1]=0x367cd507UL; c->h[2]=0x3070dd17UL; c->h[3]=0xf70e5939UL; c->h[4]=0xffc00b31UL; c->h[5]=0x68581511UL; @@ -29,6 +36,9 @@ int SHA224_Init (SHA256_CTX *c) int SHA256_Init (SHA256_CTX *c) { +#ifdef OPENSSL_FIPS + FIPS_selftest_check(); +#endif c->h[0]=0x6a09e667UL; c->h[1]=0xbb67ae85UL; c->h[2]=0x3c6ef372UL; c->h[3]=0xa54ff53aUL; c->h[4]=0x510e527fUL; c->h[5]=0x9b05688cUL; diff --git a/src/lib/libcrypto/sha/sha512.c b/src/lib/libcrypto/sha/sha512.c index 987fc07c99..f5ed468b85 100644 --- a/src/lib/libcrypto/sha/sha512.c +++ b/src/lib/libcrypto/sha/sha512.c @@ -5,6 +5,10 @@ * ==================================================================== */ #include +#ifdef OPENSSL_FIPS +#include +#endif + #if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_SHA512) /* * IMPLEMENTATION NOTES. @@ -61,6 +65,9 @@ const char SHA512_version[]="SHA-512" OPENSSL_VERSION_PTEXT; int SHA384_Init (SHA512_CTX *c) { +#ifdef OPENSSL_FIPS + FIPS_selftest_check(); +#endif c->h[0]=U64(0xcbbb9d5dc1059ed8); c->h[1]=U64(0x629a292a367cd507); c->h[2]=U64(0x9159015a3070dd17); @@ -76,6 +83,9 @@ int SHA384_Init (SHA512_CTX *c) int SHA512_Init (SHA512_CTX *c) { +#ifdef OPENSSL_FIPS + FIPS_selftest_check(); +#endif c->h[0]=U64(0x6a09e667f3bcc908); c->h[1]=U64(0xbb67ae8584caa73b); c->h[2]=U64(0x3c6ef372fe94f82b); @@ -327,7 +337,7 @@ static const SHA_LONG64 K512[80] = { ((SHA_LONG64)hi)<<32|lo; }) # else # define PULL64(x) ({ const unsigned int *p=(const unsigned int *)(&(x));\ - unsigned int hi=p[0],lo=p[1]; \ + unsigned int hi=p[0],lo=p[1]; \ asm ("bswapl %0; bswapl %1;" \ : "=r"(lo),"=r"(hi) \ : "0"(lo),"1"(hi)); \ diff --git a/src/lib/libcrypto/sha/sha_locl.h b/src/lib/libcrypto/sha/sha_locl.h index e37e5726e3..da46ddfe79 100644 --- a/src/lib/libcrypto/sha/sha_locl.h +++ b/src/lib/libcrypto/sha/sha_locl.h @@ -122,8 +122,15 @@ void sha1_block_data_order (SHA_CTX *c, const void *p,size_t num); #define INIT_DATA_h3 0x10325476UL #define INIT_DATA_h4 0xc3d2e1f0UL +#if defined(SHA_0) && defined(OPENSSL_FIPS) +FIPS_NON_FIPS_MD_Init(SHA) +#else int HASH_INIT (SHA_CTX *c) +#endif { +#if defined(SHA_1) && defined(OPENSSL_FIPS) + FIPS_selftest_check(); +#endif c->h0=INIT_DATA_h0; c->h1=INIT_DATA_h1; c->h2=INIT_DATA_h2; diff --git a/src/lib/libcrypto/stack/safestack.h b/src/lib/libcrypto/stack/safestack.h index 78cc485e6d..40b17902e0 100644 --- a/src/lib/libcrypto/stack/safestack.h +++ b/src/lib/libcrypto/stack/safestack.h @@ -986,6 +986,50 @@ STACK_OF(type) \ #define sk_MIME_HEADER_sort(st) SKM_sk_sort(MIME_HEADER, (st)) #define sk_MIME_HEADER_is_sorted(st) SKM_sk_is_sorted(MIME_HEADER, (st)) +#define sk_MIME_HEADER_new(st) SKM_sk_new(MIME_HEADER, (st)) +#define sk_MIME_HEADER_new_null() SKM_sk_new_null(MIME_HEADER) +#define sk_MIME_HEADER_free(st) SKM_sk_free(MIME_HEADER, (st)) +#define sk_MIME_HEADER_num(st) SKM_sk_num(MIME_HEADER, (st)) +#define sk_MIME_HEADER_value(st, i) SKM_sk_value(MIME_HEADER, (st), (i)) +#define sk_MIME_HEADER_set(st, i, val) SKM_sk_set(MIME_HEADER, (st), (i), (val)) +#define sk_MIME_HEADER_zero(st) SKM_sk_zero(MIME_HEADER, (st)) +#define sk_MIME_HEADER_push(st, val) SKM_sk_push(MIME_HEADER, (st), (val)) +#define sk_MIME_HEADER_unshift(st, val) SKM_sk_unshift(MIME_HEADER, (st), (val)) +#define sk_MIME_HEADER_find(st, val) SKM_sk_find(MIME_HEADER, (st), (val)) +#define sk_MIME_HEADER_find_ex(st, val) SKM_sk_find_ex(MIME_HEADER, (st), (val)) +#define sk_MIME_HEADER_delete(st, i) SKM_sk_delete(MIME_HEADER, (st), (i)) +#define sk_MIME_HEADER_delete_ptr(st, ptr) SKM_sk_delete_ptr(MIME_HEADER, (st), (ptr)) +#define sk_MIME_HEADER_insert(st, val, i) SKM_sk_insert(MIME_HEADER, (st), (val), (i)) +#define sk_MIME_HEADER_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(MIME_HEADER, (st), (cmp)) +#define sk_MIME_HEADER_dup(st) SKM_sk_dup(MIME_HEADER, st) +#define sk_MIME_HEADER_pop_free(st, free_func) SKM_sk_pop_free(MIME_HEADER, (st), (free_func)) +#define sk_MIME_HEADER_shift(st) SKM_sk_shift(MIME_HEADER, (st)) +#define sk_MIME_HEADER_pop(st) SKM_sk_pop(MIME_HEADER, (st)) +#define sk_MIME_HEADER_sort(st) SKM_sk_sort(MIME_HEADER, (st)) +#define sk_MIME_HEADER_is_sorted(st) SKM_sk_is_sorted(MIME_HEADER, (st)) + +#define sk_MIME_PARAM_new(st) SKM_sk_new(MIME_PARAM, (st)) +#define sk_MIME_PARAM_new_null() SKM_sk_new_null(MIME_PARAM) +#define sk_MIME_PARAM_free(st) SKM_sk_free(MIME_PARAM, (st)) +#define sk_MIME_PARAM_num(st) SKM_sk_num(MIME_PARAM, (st)) +#define sk_MIME_PARAM_value(st, i) SKM_sk_value(MIME_PARAM, (st), (i)) +#define sk_MIME_PARAM_set(st, i, val) SKM_sk_set(MIME_PARAM, (st), (i), (val)) +#define sk_MIME_PARAM_zero(st) SKM_sk_zero(MIME_PARAM, (st)) +#define sk_MIME_PARAM_push(st, val) SKM_sk_push(MIME_PARAM, (st), (val)) +#define sk_MIME_PARAM_unshift(st, val) SKM_sk_unshift(MIME_PARAM, (st), (val)) +#define sk_MIME_PARAM_find(st, val) SKM_sk_find(MIME_PARAM, (st), (val)) +#define sk_MIME_PARAM_find_ex(st, val) SKM_sk_find_ex(MIME_PARAM, (st), (val)) +#define sk_MIME_PARAM_delete(st, i) SKM_sk_delete(MIME_PARAM, (st), (i)) +#define sk_MIME_PARAM_delete_ptr(st, ptr) SKM_sk_delete_ptr(MIME_PARAM, (st), (ptr)) +#define sk_MIME_PARAM_insert(st, val, i) SKM_sk_insert(MIME_PARAM, (st), (val), (i)) +#define sk_MIME_PARAM_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(MIME_PARAM, (st), (cmp)) +#define sk_MIME_PARAM_dup(st) SKM_sk_dup(MIME_PARAM, st) +#define sk_MIME_PARAM_pop_free(st, free_func) SKM_sk_pop_free(MIME_PARAM, (st), (free_func)) +#define sk_MIME_PARAM_shift(st) SKM_sk_shift(MIME_PARAM, (st)) +#define sk_MIME_PARAM_pop(st) SKM_sk_pop(MIME_PARAM, (st)) +#define sk_MIME_PARAM_sort(st) SKM_sk_sort(MIME_PARAM, (st)) +#define sk_MIME_PARAM_is_sorted(st) SKM_sk_is_sorted(MIME_PARAM, (st)) + #define sk_MIME_PARAM_new(st) SKM_sk_new(MIME_PARAM, (st)) #define sk_MIME_PARAM_new_null() SKM_sk_new_null(MIME_PARAM) #define sk_MIME_PARAM_free(st) SKM_sk_free(MIME_PARAM, (st)) diff --git a/src/lib/libcrypto/ui/ui_openssl.c b/src/lib/libcrypto/ui/ui_openssl.c index 1f23a45a33..ef930bf247 100644 --- a/src/lib/libcrypto/ui/ui_openssl.c +++ b/src/lib/libcrypto/ui/ui_openssl.c @@ -677,6 +677,8 @@ static int noecho_fgets(char *buf, int size, FILE *tty) size--; #ifdef WIN16TTY i=_inchar(); +#elif defined(_WIN32) + i=_getch(); #else i=getch(); #endif diff --git a/src/lib/libcrypto/util/mkerr.pl b/src/lib/libcrypto/util/mkerr.pl index 53e14ab4df..554bebb159 100644 --- a/src/lib/libcrypto/util/mkerr.pl +++ b/src/lib/libcrypto/util/mkerr.pl @@ -44,7 +44,8 @@ while (@ARGV) { } if($recurse) { - @source = (, , ); + @source = ( , , , + , ); } else { @source = @ARGV; } diff --git a/src/lib/libcrypto/x509/by_dir.c b/src/lib/libcrypto/x509/by_dir.c index 37f9a48206..341e0ba6a4 100644 --- a/src/lib/libcrypto/x509/by_dir.c +++ b/src/lib/libcrypto/x509/by_dir.c @@ -74,6 +74,10 @@ #include #include +#ifdef _WIN32 +#define stat _stat +#endif + typedef struct lookup_dir_st { BUF_MEM *buffer; diff --git a/src/lib/libcrypto/x509/x509_att.c b/src/lib/libcrypto/x509/x509_att.c index 511b49d589..98460e8921 100644 --- a/src/lib/libcrypto/x509/x509_att.c +++ b/src/lib/libcrypto/x509/x509_att.c @@ -245,7 +245,7 @@ X509_ATTRIBUTE *X509_ATTRIBUTE_create_by_OBJ(X509_ATTRIBUTE **attr, goto err; if (!X509_ATTRIBUTE_set1_data(ret,atrtype,data,len)) goto err; - + if ((attr != NULL) && (*attr == NULL)) *attr=ret; return(ret); err: @@ -302,8 +302,15 @@ int X509_ATTRIBUTE_set1_data(X509_ATTRIBUTE *attr, int attrtype, const void *dat atype = attrtype; } if(!(attr->value.set = sk_ASN1_TYPE_new_null())) goto err; + attr->single = 0; + /* This is a bit naughty because the attribute should really have + * at least one value but some types use and zero length SET and + * require this. + */ + if (attrtype == 0) + return 1; if(!(ttmp = ASN1_TYPE_new())) goto err; - if (len == -1) + if ((len == -1) && !(attrtype & MBSTRING_FLAG)) { if (!ASN1_TYPE_set1(ttmp, attrtype, data)) goto err; @@ -311,7 +318,6 @@ int X509_ATTRIBUTE_set1_data(X509_ATTRIBUTE *attr, int attrtype, const void *dat else ASN1_TYPE_set(ttmp, atype, stmp); if(!sk_ASN1_TYPE_push(attr->value.set, ttmp)) goto err; - attr->single = 0; return 1; err: X509err(X509_F_X509_ATTRIBUTE_SET1_DATA, ERR_R_MALLOC_FAILURE); diff --git a/src/lib/libcrypto/x509/x509_cmp.c b/src/lib/libcrypto/x509/x509_cmp.c index 0d6bc653b2..e4c682fc44 100644 --- a/src/lib/libcrypto/x509/x509_cmp.c +++ b/src/lib/libcrypto/x509/x509_cmp.c @@ -322,10 +322,16 @@ unsigned long X509_NAME_hash(X509_NAME *x) { unsigned long ret=0; unsigned char md[16]; + EVP_MD_CTX md_ctx; /* Make sure X509_NAME structure contains valid cached encoding */ i2d_X509_NAME(x,NULL); - EVP_Digest(x->bytes->data, x->bytes->length, md, NULL, EVP_md5(), NULL); + EVP_MD_CTX_init(&md_ctx); + EVP_MD_CTX_set_flags(&md_ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW); + EVP_DigestInit_ex(&md_ctx, EVP_md5(), NULL); + EVP_DigestUpdate(&md_ctx, x->bytes->data, x->bytes->length); + EVP_DigestFinal_ex(&md_ctx,md,NULL); + EVP_MD_CTX_cleanup(&md_ctx); ret=( ((unsigned long)md[0] )|((unsigned long)md[1]<<8L)| ((unsigned long)md[2]<<16L)|((unsigned long)md[3]<<24L) diff --git a/src/lib/libcrypto/x509/x509_trs.c b/src/lib/libcrypto/x509/x509_trs.c index 9c84a59d52..ed18700585 100644 --- a/src/lib/libcrypto/x509/x509_trs.c +++ b/src/lib/libcrypto/x509/x509_trs.c @@ -1,5 +1,5 @@ /* x509_trs.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. */ /* ==================================================================== diff --git a/src/lib/libcrypto/x509/x509_vfy.c b/src/lib/libcrypto/x509/x509_vfy.c index 9a62ebcf67..336c40ddd7 100644 --- a/src/lib/libcrypto/x509/x509_vfy.c +++ b/src/lib/libcrypto/x509/x509_vfy.c @@ -394,7 +394,7 @@ static int check_chain_extensions(X509_STORE_CTX *ctx) #ifdef OPENSSL_NO_CHAIN_VERIFY return 1; #else - int i, ok=0, must_be_ca; + int i, ok=0, must_be_ca, plen = 0; X509 *x; int (*cb)(int xok,X509_STORE_CTX *xctx); int proxy_path_length = 0; @@ -495,9 +495,10 @@ static int check_chain_extensions(X509_STORE_CTX *ctx) if (!ok) goto end; } } - /* Check pathlen */ - if ((i > 1) && (x->ex_pathlen != -1) - && (i > (x->ex_pathlen + proxy_path_length + 1))) + /* Check pathlen if not self issued */ + if ((i > 1) && !(x->ex_flags & EXFLAG_SI) + && (x->ex_pathlen != -1) + && (plen > (x->ex_pathlen + proxy_path_length + 1))) { ctx->error = X509_V_ERR_PATH_LENGTH_EXCEEDED; ctx->error_depth = i; @@ -505,6 +506,9 @@ static int check_chain_extensions(X509_STORE_CTX *ctx) ok=cb(0,ctx); if (!ok) goto end; } + /* Increment path length if not self issued */ + if (!(x->ex_flags & EXFLAG_SI)) + plen++; /* If this certificate is a proxy certificate, the next certificate must be another proxy certificate or a EE certificate. If not, the next certificate must be a diff --git a/src/lib/libcrypto/x509/x509_vpm.c b/src/lib/libcrypto/x509/x509_vpm.c index e9db6d62a7..c92e65936f 100644 --- a/src/lib/libcrypto/x509/x509_vpm.c +++ b/src/lib/libcrypto/x509/x509_vpm.c @@ -1,5 +1,5 @@ /* x509_vpm.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 2004. */ /* ==================================================================== diff --git a/src/lib/libcrypto/x509/x509cset.c b/src/lib/libcrypto/x509/x509cset.c index 9d1646d5c8..7f4004b291 100644 --- a/src/lib/libcrypto/x509/x509cset.c +++ b/src/lib/libcrypto/x509/x509cset.c @@ -1,5 +1,5 @@ /* crypto/x509/x509cset.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 2001. */ /* ==================================================================== diff --git a/src/lib/libcrypto/x509/x509spki.c b/src/lib/libcrypto/x509/x509spki.c index ed868b838e..02a203d72c 100644 --- a/src/lib/libcrypto/x509/x509spki.c +++ b/src/lib/libcrypto/x509/x509spki.c @@ -1,5 +1,5 @@ /* x509spki.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. */ /* ==================================================================== diff --git a/src/lib/libcrypto/x509v3/ext_dat.h b/src/lib/libcrypto/x509v3/ext_dat.h index 5c063ac65d..3eaec46f8a 100644 --- a/src/lib/libcrypto/x509v3/ext_dat.h +++ b/src/lib/libcrypto/x509v3/ext_dat.h @@ -1,5 +1,5 @@ /* ext_dat.h */ -/* 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. */ /* ==================================================================== diff --git a/src/lib/libcrypto/x509v3/pcy_cache.c b/src/lib/libcrypto/x509v3/pcy_cache.c index c18beb89f5..1030931b71 100644 --- a/src/lib/libcrypto/x509v3/pcy_cache.c +++ b/src/lib/libcrypto/x509v3/pcy_cache.c @@ -1,5 +1,5 @@ /* pcy_cache.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 2004. */ /* ==================================================================== diff --git a/src/lib/libcrypto/x509v3/pcy_data.c b/src/lib/libcrypto/x509v3/pcy_data.c index 614d2b4935..fb392b901f 100644 --- a/src/lib/libcrypto/x509v3/pcy_data.c +++ b/src/lib/libcrypto/x509v3/pcy_data.c @@ -1,5 +1,5 @@ /* pcy_data.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 2004. */ /* ==================================================================== @@ -87,6 +87,12 @@ X509_POLICY_DATA *policy_data_new(POLICYINFO *policy, ASN1_OBJECT *id, int crit) X509_POLICY_DATA *ret; if (!policy && !id) return NULL; + if (id) + { + id = OBJ_dup(id); + if (!id) + return NULL; + } ret = OPENSSL_malloc(sizeof(X509_POLICY_DATA)); if (!ret) return NULL; @@ -94,6 +100,8 @@ X509_POLICY_DATA *policy_data_new(POLICYINFO *policy, ASN1_OBJECT *id, int crit) if (!ret->expected_policy_set) { OPENSSL_free(ret); + if (id) + ASN1_OBJECT_free(id); return NULL; } diff --git a/src/lib/libcrypto/x509v3/pcy_int.h b/src/lib/libcrypto/x509v3/pcy_int.h index ba62a209da..3780de4fcd 100644 --- a/src/lib/libcrypto/x509v3/pcy_int.h +++ b/src/lib/libcrypto/x509v3/pcy_int.h @@ -1,5 +1,5 @@ /* pcy_int.h */ -/* 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 2004. */ /* ==================================================================== diff --git a/src/lib/libcrypto/x509v3/pcy_lib.c b/src/lib/libcrypto/x509v3/pcy_lib.c index dae4840bc5..93bfd92703 100644 --- a/src/lib/libcrypto/x509v3/pcy_lib.c +++ b/src/lib/libcrypto/x509v3/pcy_lib.c @@ -1,5 +1,5 @@ /* pcy_lib.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 2004. */ /* ==================================================================== diff --git a/src/lib/libcrypto/x509v3/pcy_map.c b/src/lib/libcrypto/x509v3/pcy_map.c index 35221e8ba8..f28796e6d4 100644 --- a/src/lib/libcrypto/x509v3/pcy_map.c +++ b/src/lib/libcrypto/x509v3/pcy_map.c @@ -1,5 +1,5 @@ /* pcy_map.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 2004. */ /* ==================================================================== diff --git a/src/lib/libcrypto/x509v3/pcy_node.c b/src/lib/libcrypto/x509v3/pcy_node.c index dcc1554e29..6587cb05ab 100644 --- a/src/lib/libcrypto/x509v3/pcy_node.c +++ b/src/lib/libcrypto/x509v3/pcy_node.c @@ -1,5 +1,5 @@ /* pcy_node.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 2004. */ /* ==================================================================== diff --git a/src/lib/libcrypto/x509v3/pcy_tree.c b/src/lib/libcrypto/x509v3/pcy_tree.c index 4fda1d419a..6c87a7f506 100644 --- a/src/lib/libcrypto/x509v3/pcy_tree.c +++ b/src/lib/libcrypto/x509v3/pcy_tree.c @@ -1,5 +1,5 @@ /* pcy_tree.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 2004. */ /* ==================================================================== @@ -130,9 +130,9 @@ static int tree_init(X509_POLICY_TREE **ptree, STACK_OF(X509) *certs, ret = 2; if (explicit_policy > 0) { - explicit_policy--; - if (!(x->ex_flags & EXFLAG_SS) - && (cache->explicit_skip != -1) + if (!(x->ex_flags & EXFLAG_SI)) + explicit_policy--; + if ((cache->explicit_skip != -1) && (cache->explicit_skip < explicit_policy)) explicit_policy = cache->explicit_skip; } @@ -197,13 +197,14 @@ static int tree_init(X509_POLICY_TREE **ptree, STACK_OF(X509) *certs, /* Any matching allowed if certificate is self * issued and not the last in the chain. */ - if (!(x->ex_flags & EXFLAG_SS) || (i == 0)) + if (!(x->ex_flags & EXFLAG_SI) || (i == 0)) level->flags |= X509_V_FLAG_INHIBIT_ANY; } else { - any_skip--; - if ((cache->any_skip > 0) + if (!(x->ex_flags & EXFLAG_SI)) + any_skip--; + if ((cache->any_skip >= 0) && (cache->any_skip < any_skip)) any_skip = cache->any_skip; } @@ -213,7 +214,7 @@ static int tree_init(X509_POLICY_TREE **ptree, STACK_OF(X509) *certs, else { map_skip--; - if ((cache->map_skip > 0) + if ((cache->map_skip >= 0) && (cache->map_skip < map_skip)) map_skip = cache->map_skip; } @@ -310,7 +311,8 @@ static int tree_link_any(X509_POLICY_LEVEL *curr, if (data == NULL) return 0; - data->qualifier_set = curr->anyPolicy->data->qualifier_set; + /* Curr may not have anyPolicy */ + data->qualifier_set = cache->anyPolicy->qualifier_set; data->flags |= POLICY_DATA_FLAG_SHARED_QUALIFIERS; if (!level_add_node(curr, data, node, tree)) { diff --git a/src/lib/libcrypto/x509v3/v3_akey.c b/src/lib/libcrypto/x509v3/v3_akey.c index ac0548b775..c6b68ee221 100644 --- a/src/lib/libcrypto/x509v3/v3_akey.c +++ b/src/lib/libcrypto/x509v3/v3_akey.c @@ -1,5 +1,5 @@ /* v3_akey.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. */ /* ==================================================================== diff --git a/src/lib/libcrypto/x509v3/v3_akeya.c b/src/lib/libcrypto/x509v3/v3_akeya.c index 2aafa26ba7..2c50f7360e 100644 --- a/src/lib/libcrypto/x509v3/v3_akeya.c +++ b/src/lib/libcrypto/x509v3/v3_akeya.c @@ -1,5 +1,5 @@ /* v3_akey_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 1999. */ /* ==================================================================== diff --git a/src/lib/libcrypto/x509v3/v3_alt.c b/src/lib/libcrypto/x509v3/v3_alt.c index bb2f5bc54e..58b2952478 100644 --- a/src/lib/libcrypto/x509v3/v3_alt.c +++ b/src/lib/libcrypto/x509v3/v3_alt.c @@ -1,5 +1,5 @@ /* v3_alt.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. */ /* ==================================================================== @@ -527,7 +527,8 @@ GENERAL_NAME *v2i_GENERAL_NAME_ex(GENERAL_NAME *out, return gen; err: - GENERAL_NAME_free(gen); + if (!out) + GENERAL_NAME_free(gen); return NULL; } diff --git a/src/lib/libcrypto/x509v3/v3_bcons.c b/src/lib/libcrypto/x509v3/v3_bcons.c index 74b1233071..82aa488f75 100644 --- a/src/lib/libcrypto/x509v3/v3_bcons.c +++ b/src/lib/libcrypto/x509v3/v3_bcons.c @@ -1,5 +1,5 @@ /* v3_bcons.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. */ /* ==================================================================== diff --git a/src/lib/libcrypto/x509v3/v3_bitst.c b/src/lib/libcrypto/x509v3/v3_bitst.c index cf31f0816e..058d0d4dce 100644 --- a/src/lib/libcrypto/x509v3/v3_bitst.c +++ b/src/lib/libcrypto/x509v3/v3_bitst.c @@ -1,5 +1,5 @@ /* v3_bitst.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. */ /* ==================================================================== diff --git a/src/lib/libcrypto/x509v3/v3_conf.c b/src/lib/libcrypto/x509v3/v3_conf.c index 2b867305fb..11eb6b7fd5 100644 --- a/src/lib/libcrypto/x509v3/v3_conf.c +++ b/src/lib/libcrypto/x509v3/v3_conf.c @@ -1,5 +1,5 @@ /* v3_conf.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. */ /* ==================================================================== diff --git a/src/lib/libcrypto/x509v3/v3_cpols.c b/src/lib/libcrypto/x509v3/v3_cpols.c index a40f490aa9..95596055ab 100644 --- a/src/lib/libcrypto/x509v3/v3_cpols.c +++ b/src/lib/libcrypto/x509v3/v3_cpols.c @@ -1,5 +1,5 @@ /* v3_cpols.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. */ /* ==================================================================== diff --git a/src/lib/libcrypto/x509v3/v3_crld.c b/src/lib/libcrypto/x509v3/v3_crld.c index c6e3ebae7b..181a8977b1 100644 --- a/src/lib/libcrypto/x509v3/v3_crld.c +++ b/src/lib/libcrypto/x509v3/v3_crld.c @@ -1,5 +1,5 @@ /* v3_crld.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. */ /* ==================================================================== diff --git a/src/lib/libcrypto/x509v3/v3_enum.c b/src/lib/libcrypto/x509v3/v3_enum.c index a236cb22e1..36576eaa4d 100644 --- a/src/lib/libcrypto/x509v3/v3_enum.c +++ b/src/lib/libcrypto/x509v3/v3_enum.c @@ -1,5 +1,5 @@ /* v3_enum.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. */ /* ==================================================================== diff --git a/src/lib/libcrypto/x509v3/v3_extku.c b/src/lib/libcrypto/x509v3/v3_extku.c index a4efe0031e..c0d14500ed 100644 --- a/src/lib/libcrypto/x509v3/v3_extku.c +++ b/src/lib/libcrypto/x509v3/v3_extku.c @@ -1,5 +1,5 @@ /* v3_extku.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. */ /* ==================================================================== diff --git a/src/lib/libcrypto/x509v3/v3_genn.c b/src/lib/libcrypto/x509v3/v3_genn.c index 650b510980..84b4b1c881 100644 --- a/src/lib/libcrypto/x509v3/v3_genn.c +++ b/src/lib/libcrypto/x509v3/v3_genn.c @@ -1,5 +1,5 @@ /* v3_genn.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. */ /* ==================================================================== diff --git a/src/lib/libcrypto/x509v3/v3_ia5.c b/src/lib/libcrypto/x509v3/v3_ia5.c index b739ccd036..4ff12b52b5 100644 --- a/src/lib/libcrypto/x509v3/v3_ia5.c +++ b/src/lib/libcrypto/x509v3/v3_ia5.c @@ -1,5 +1,5 @@ /* v3_ia5.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. */ /* ==================================================================== diff --git a/src/lib/libcrypto/x509v3/v3_info.c b/src/lib/libcrypto/x509v3/v3_info.c index e0ef69de42..e1b8699f92 100644 --- a/src/lib/libcrypto/x509v3/v3_info.c +++ b/src/lib/libcrypto/x509v3/v3_info.c @@ -1,5 +1,5 @@ /* v3_info.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. */ /* ==================================================================== diff --git a/src/lib/libcrypto/x509v3/v3_int.c b/src/lib/libcrypto/x509v3/v3_int.c index 9a48dc1508..4bfd14cf46 100644 --- a/src/lib/libcrypto/x509v3/v3_int.c +++ b/src/lib/libcrypto/x509v3/v3_int.c @@ -1,5 +1,5 @@ /* v3_int.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. */ /* ==================================================================== diff --git a/src/lib/libcrypto/x509v3/v3_lib.c b/src/lib/libcrypto/x509v3/v3_lib.c index f3015ea610..df3a48f43e 100644 --- a/src/lib/libcrypto/x509v3/v3_lib.c +++ b/src/lib/libcrypto/x509v3/v3_lib.c @@ -1,5 +1,5 @@ /* v3_lib.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. */ /* ==================================================================== diff --git a/src/lib/libcrypto/x509v3/v3_ncons.c b/src/lib/libcrypto/x509v3/v3_ncons.c index 42e7f5a879..4e706be3e1 100644 --- a/src/lib/libcrypto/x509v3/v3_ncons.c +++ b/src/lib/libcrypto/x509v3/v3_ncons.c @@ -1,5 +1,5 @@ /* v3_ncons.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. */ /* ==================================================================== diff --git a/src/lib/libcrypto/x509v3/v3_ocsp.c b/src/lib/libcrypto/x509v3/v3_ocsp.c index 62aac06335..e426ea930c 100644 --- a/src/lib/libcrypto/x509v3/v3_ocsp.c +++ b/src/lib/libcrypto/x509v3/v3_ocsp.c @@ -1,5 +1,5 @@ /* v3_ocsp.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. */ /* ==================================================================== diff --git a/src/lib/libcrypto/x509v3/v3_pcons.c b/src/lib/libcrypto/x509v3/v3_pcons.c index 13248c2ada..86c0ff70e6 100644 --- a/src/lib/libcrypto/x509v3/v3_pcons.c +++ b/src/lib/libcrypto/x509v3/v3_pcons.c @@ -1,5 +1,5 @@ /* v3_pcons.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. */ /* ==================================================================== diff --git a/src/lib/libcrypto/x509v3/v3_pku.c b/src/lib/libcrypto/x509v3/v3_pku.c index 5c4626e89b..076f3ff48e 100644 --- a/src/lib/libcrypto/x509v3/v3_pku.c +++ b/src/lib/libcrypto/x509v3/v3_pku.c @@ -1,5 +1,5 @@ /* v3_pku.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. */ /* ==================================================================== diff --git a/src/lib/libcrypto/x509v3/v3_pmaps.c b/src/lib/libcrypto/x509v3/v3_pmaps.c index 626303264f..da03bbc35d 100644 --- a/src/lib/libcrypto/x509v3/v3_pmaps.c +++ b/src/lib/libcrypto/x509v3/v3_pmaps.c @@ -1,5 +1,5 @@ /* v3_pmaps.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. */ /* ==================================================================== diff --git a/src/lib/libcrypto/x509v3/v3_prn.c b/src/lib/libcrypto/x509v3/v3_prn.c index 20bd9bda19..c1bb17f105 100644 --- a/src/lib/libcrypto/x509v3/v3_prn.c +++ b/src/lib/libcrypto/x509v3/v3_prn.c @@ -1,5 +1,5 @@ /* v3_prn.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. */ /* ==================================================================== diff --git a/src/lib/libcrypto/x509v3/v3_purp.c b/src/lib/libcrypto/x509v3/v3_purp.c index b2f5cdfa05..e18751e01c 100644 --- a/src/lib/libcrypto/x509v3/v3_purp.c +++ b/src/lib/libcrypto/x509v3/v3_purp.c @@ -1,5 +1,5 @@ /* v3_purp.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 2001. */ /* ==================================================================== @@ -291,7 +291,9 @@ int X509_supported_extension(X509_EXTENSION *ex) NID_sbgp_ipAddrBlock, /* 290 */ NID_sbgp_autonomousSysNum, /* 291 */ #endif - NID_proxyCertInfo /* 661 */ + NID_policy_constraints, /* 401 */ + NID_proxyCertInfo, /* 661 */ + NID_inhibit_any_policy /* 748 */ }; int ex_nid; @@ -325,7 +327,7 @@ static void x509v3_cache_extensions(X509 *x) #endif /* Does subject name match issuer ? */ if(!X509_NAME_cmp(X509_get_subject_name(x), X509_get_issuer_name(x))) - x->ex_flags |= EXFLAG_SS; + x->ex_flags |= EXFLAG_SI; /* V1 should mean no extensions ... */ if(!X509_get_version(x)) x->ex_flags |= EXFLAG_V1; /* Handle basic constraints */ diff --git a/src/lib/libcrypto/x509v3/v3_skey.c b/src/lib/libcrypto/x509v3/v3_skey.c index da0a3558f6..202c9e4896 100644 --- a/src/lib/libcrypto/x509v3/v3_skey.c +++ b/src/lib/libcrypto/x509v3/v3_skey.c @@ -1,5 +1,5 @@ /* v3_skey.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. */ /* ==================================================================== diff --git a/src/lib/libcrypto/x509v3/v3_sxnet.c b/src/lib/libcrypto/x509v3/v3_sxnet.c index eaea9ea01b..2a6bf11b65 100644 --- a/src/lib/libcrypto/x509v3/v3_sxnet.c +++ b/src/lib/libcrypto/x509v3/v3_sxnet.c @@ -1,5 +1,5 @@ /* v3_sxnet.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. */ /* ==================================================================== diff --git a/src/lib/libcrypto/x509v3/v3_utl.c b/src/lib/libcrypto/x509v3/v3_utl.c index ac171ca940..a4236bbb6d 100644 --- a/src/lib/libcrypto/x509v3/v3_utl.c +++ b/src/lib/libcrypto/x509v3/v3_utl.c @@ -1,5 +1,5 @@ /* v3_utl.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. */ /* ==================================================================== @@ -736,17 +736,20 @@ static int ipv6_from_asc(unsigned char *v6, const char *in) /* Format result */ - /* Copy initial part */ - if (v6stat.zero_pos > 0) + if (v6stat.zero_pos >= 0) + { + /* Copy initial part */ memcpy(v6, v6stat.tmp, v6stat.zero_pos); - /* Zero middle */ - if (v6stat.total != 16) + /* Zero middle */ memset(v6 + v6stat.zero_pos, 0, 16 - v6stat.total); - /* Copy final part */ - if (v6stat.total != v6stat.zero_pos) - memcpy(v6 + v6stat.zero_pos + 16 - v6stat.total, - v6stat.tmp + v6stat.zero_pos, - v6stat.total - v6stat.zero_pos); + /* Copy final part */ + if (v6stat.total != v6stat.zero_pos) + memcpy(v6 + v6stat.zero_pos + 16 - v6stat.total, + v6stat.tmp + v6stat.zero_pos, + v6stat.total - v6stat.zero_pos); + } + else + memcpy(v6, v6stat.tmp, 16); return 1; } diff --git a/src/lib/libcrypto/x509v3/x509v3.h b/src/lib/libcrypto/x509v3/x509v3.h index db2b0482c1..9ef83da755 100644 --- a/src/lib/libcrypto/x509v3/x509v3.h +++ b/src/lib/libcrypto/x509v3/x509v3.h @@ -1,5 +1,5 @@ /* x509v3.h */ -/* 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. */ /* ==================================================================== @@ -363,6 +363,8 @@ DECLARE_ASN1_FUNCTIONS(PROXY_CERT_INFO_EXTENSION) #define EXFLAG_NSCERT 0x8 #define EXFLAG_CA 0x10 +/* Really self issued not necessarily self signed */ +#define EXFLAG_SI 0x20 #define EXFLAG_SS 0x20 #define EXFLAG_V1 0x40 #define EXFLAG_INVALID 0x80 @@ -370,7 +372,7 @@ DECLARE_ASN1_FUNCTIONS(PROXY_CERT_INFO_EXTENSION) #define EXFLAG_CRITICAL 0x200 #define EXFLAG_PROXY 0x400 -#define EXFLAG_INVALID_POLICY 0x400 +#define EXFLAG_INVALID_POLICY 0x800 #define KU_DIGITAL_SIGNATURE 0x0080 #define KU_NON_REPUDIATION 0x0040 diff --git a/src/lib/libssl/d1_clnt.c b/src/lib/libssl/d1_clnt.c index 5e59dc845a..49c6760d19 100644 --- a/src/lib/libssl/d1_clnt.c +++ b/src/lib/libssl/d1_clnt.c @@ -1095,8 +1095,7 @@ int dtls1_send_client_certificate(SSL *s) * ssl->rwstate=SSL_X509_LOOKUP; return(-1); * We then get retied later */ i=0; - if (s->ctx->client_cert_cb != NULL) - i=s->ctx->client_cert_cb(s,&(x509),&(pkey)); + i = ssl_do_client_cert_cb(s, &x509, &pkey); if (i < 0) { s->rwstate=SSL_X509_LOOKUP; diff --git a/src/lib/libssl/d1_enc.c b/src/lib/libssl/d1_enc.c index cbff7495c5..cf3332e4e4 100644 --- a/src/lib/libssl/d1_enc.c +++ b/src/lib/libssl/d1_enc.c @@ -115,12 +115,16 @@ #include #include "ssl_locl.h" +#ifndef OPENSSL_NO_COMP #include +#endif #include #include #include #include - +#ifdef KSSL_DEBUG +#include +#endif int dtls1_enc(SSL *s, int send) { @@ -202,10 +206,11 @@ int dtls1_enc(SSL *s, int send) { unsigned long ui; printf("EVP_Cipher(ds=%p,rec->data=%p,rec->input=%p,l=%ld) ==>\n", - ds,rec->data,rec->input,l); - printf("\tEVP_CIPHER_CTX: %d buf_len, %d key_len [%d %d], %d iv_len\n", + (void *)ds,rec->data,rec->input,l); + printf("\tEVP_CIPHER_CTX: %d buf_len, %d key_len [%ld %ld], %d iv_len\n", ds->buf_len, ds->cipher->key_len, - DES_KEY_SZ, DES_SCHEDULE_SZ, + (unsigned long)DES_KEY_SZ, + (unsigned long)DES_SCHEDULE_SZ, ds->cipher->iv_len); printf("\t\tIV: "); for (i=0; icipher->iv_len; i++) printf("%02X", ds->iv[i]); @@ -230,10 +235,10 @@ int dtls1_enc(SSL *s, int send) #ifdef KSSL_DEBUG { - unsigned long i; + unsigned long ki; printf("\trec->data="); - for (i=0; idata[i]); printf("\n"); + for (ki=0; kidata[ki]); printf("\n"); } #endif /* KSSL_DEBUG */ diff --git a/src/lib/libssl/d1_lib.c b/src/lib/libssl/d1_lib.c index fc088b4148..3568e97a87 100644 --- a/src/lib/libssl/d1_lib.c +++ b/src/lib/libssl/d1_lib.c @@ -106,6 +106,7 @@ int dtls1_new(SSL *s) pq_64bit_init(&(d1->bitmap.map)); pq_64bit_init(&(d1->bitmap.max_seq_num)); + d1->next_bitmap.length = d1->bitmap.length; pq_64bit_init(&(d1->next_bitmap.map)); pq_64bit_init(&(d1->next_bitmap.max_seq_num)); diff --git a/src/lib/libssl/d1_pkt.c b/src/lib/libssl/d1_pkt.c index 377696deac..eb56cf987b 100644 --- a/src/lib/libssl/d1_pkt.c +++ b/src/lib/libssl/d1_pkt.c @@ -597,6 +597,7 @@ again: /* check whether this is a repeat, or aged record */ if ( ! dtls1_record_replay_check(s, bitmap, &(rr->seq_num))) { + rr->length = 0; s->packet_length=0; /* dump this record */ goto again; /* get another record */ } @@ -811,6 +812,14 @@ start: * may be fragmented--don't always expect dest_maxlen bytes */ if ( rr->length < dest_maxlen) { +#ifdef DTLS1_AD_MISSING_HANDSHAKE_MESSAGE + /* + * for normal alerts rr->length is 2, while + * dest_maxlen is 7 if we were to handle this + * non-existing alert... + */ + FIX ME +#endif s->rstate=SSL_ST_READ_HEADER; rr->length = 0; goto start; @@ -1251,7 +1260,7 @@ int dtls1_write_bytes(SSL *s, int type, const void *buf_, int len) else s->s3->wnum += i; - return tot + i; + return i; } int do_dtls1_write(SSL *s, int type, const unsigned char *buf, unsigned int len, int create_empty_fragment) @@ -1576,7 +1585,7 @@ int dtls1_dispatch_alert(SSL *s) { int i,j; void (*cb)(const SSL *ssl,int type,int val)=NULL; - unsigned char buf[2 + 2 + 3]; /* alert level + alert desc + message seq +frag_off */ + unsigned char buf[DTLS1_AL_HEADER_LENGTH]; unsigned char *ptr = &buf[0]; s->s3->alert_dispatch=0; @@ -1585,6 +1594,7 @@ int dtls1_dispatch_alert(SSL *s) *ptr++ = s->s3->send_alert[0]; *ptr++ = s->s3->send_alert[1]; +#ifdef DTLS1_AD_MISSING_HANDSHAKE_MESSAGE if (s->s3->send_alert[1] == DTLS1_AD_MISSING_HANDSHAKE_MESSAGE) { s2n(s->d1->handshake_read_seq, ptr); @@ -1600,6 +1610,7 @@ int dtls1_dispatch_alert(SSL *s) #endif l2n3(s->d1->r_msg_hdr.frag_off, ptr); } +#endif i = do_dtls1_write(s, SSL3_RT_ALERT, &buf[0], sizeof(buf), 0); if (i <= 0) @@ -1609,8 +1620,11 @@ int dtls1_dispatch_alert(SSL *s) } else { - if ( s->s3->send_alert[0] == SSL3_AL_FATAL || - s->s3->send_alert[1] == DTLS1_AD_MISSING_HANDSHAKE_MESSAGE) + if (s->s3->send_alert[0] == SSL3_AL_FATAL +#ifdef DTLS1_AD_MISSING_HANDSHAKE_MESSAGE + || s->s3->send_alert[1] == DTLS1_AD_MISSING_HANDSHAKE_MESSAGE +#endif + ) (void)BIO_flush(s->wbio); if (s->msg_callback) diff --git a/src/lib/libssl/d1_srvr.c b/src/lib/libssl/d1_srvr.c index 927b01f3c4..0bbf8ae7f3 100644 --- a/src/lib/libssl/d1_srvr.c +++ b/src/lib/libssl/d1_srvr.c @@ -732,7 +732,7 @@ int dtls1_send_server_hello(SSL *s) d = dtls1_set_message_header(s, d, SSL3_MT_SERVER_HELLO, l, 0, l); - s->state=SSL3_ST_CW_CLNT_HELLO_B; + s->state=SSL3_ST_SW_SRVR_HELLO_B; /* number of bytes to write */ s->init_num=p-buf; s->init_off=0; @@ -741,7 +741,7 @@ int dtls1_send_server_hello(SSL *s) dtls1_buffer_message(s, 0); } - /* SSL3_ST_CW_CLNT_HELLO_B */ + /* SSL3_ST_SW_SRVR_HELLO_B */ return(dtls1_do_write(s,SSL3_RT_HANDSHAKE)); } @@ -765,7 +765,7 @@ int dtls1_send_server_done(SSL *s) dtls1_buffer_message(s, 0); } - /* SSL3_ST_CW_CLNT_HELLO_B */ + /* SSL3_ST_SW_SRVR_DONE_B */ return(dtls1_do_write(s,SSL3_RT_HANDSHAKE)); } diff --git a/src/lib/libssl/dtls1.h b/src/lib/libssl/dtls1.h index a663cf85f2..f159d37110 100644 --- a/src/lib/libssl/dtls1.h +++ b/src/lib/libssl/dtls1.h @@ -70,7 +70,10 @@ extern "C" { #define DTLS1_VERSION 0xFEFF #define DTLS1_BAD_VER 0x0100 +#if 0 +/* this alert description is not specified anywhere... */ #define DTLS1_AD_MISSING_HANDSHAKE_MESSAGE 110 +#endif /* lengths of messages */ #define DTLS1_COOKIE_LENGTH 32 @@ -84,7 +87,11 @@ extern "C" { #define DTLS1_CCS_HEADER_LENGTH 1 +#ifdef DTLS1_AD_MISSING_HANDSHAKE_MESSAGE #define DTLS1_AL_HEADER_LENGTH 7 +#else +#define DTLS1_AL_HEADER_LENGTH 2 +#endif typedef struct dtls1_bitmap_st diff --git a/src/lib/libssl/s23_clnt.c b/src/lib/libssl/s23_clnt.c index c45a8e0a04..bc918170e1 100644 --- a/src/lib/libssl/s23_clnt.c +++ b/src/lib/libssl/s23_clnt.c @@ -257,6 +257,14 @@ static int ssl23_client_hello(SSL *s) version_major = TLS1_VERSION_MAJOR; version_minor = TLS1_VERSION_MINOR; } +#ifdef OPENSSL_FIPS + else if(FIPS_mode()) + { + SSLerr(SSL_F_SSL23_CLIENT_HELLO, + SSL_R_ONLY_TLS_ALLOWED_IN_FIPS_MODE); + return -1; + } +#endif else if (version == SSL3_VERSION) { version_major = SSL3_VERSION_MAJOR; @@ -536,6 +544,14 @@ static int ssl23_get_server_hello(SSL *s) if ((p[2] == SSL3_VERSION_MINOR) && !(s->options & SSL_OP_NO_SSLv3)) { +#ifdef OPENSSL_FIPS + if(FIPS_mode()) + { + SSLerr(SSL_F_SSL23_GET_SERVER_HELLO, + SSL_R_ONLY_TLS_ALLOWED_IN_FIPS_MODE); + goto err; + } +#endif s->version=SSL3_VERSION; s->method=SSLv3_client_method(); } diff --git a/src/lib/libssl/s23_srvr.c b/src/lib/libssl/s23_srvr.c index 6637bb9549..ba06e7ae2e 100644 --- a/src/lib/libssl/s23_srvr.c +++ b/src/lib/libssl/s23_srvr.c @@ -386,6 +386,15 @@ int ssl23_get_client_hello(SSL *s) } } +#ifdef OPENSSL_FIPS + if (FIPS_mode() && (s->version < TLS1_VERSION)) + { + SSLerr(SSL_F_SSL23_GET_CLIENT_HELLO, + SSL_R_ONLY_TLS_ALLOWED_IN_FIPS_MODE); + goto err; + } +#endif + if (s->state == SSL23_ST_SR_CLNT_HELLO_B) { /* we have SSLv3/TLSv1 in an SSLv2 header diff --git a/src/lib/libssl/s3_clnt.c b/src/lib/libssl/s3_clnt.c index f6864cdc50..5fd3520caf 100644 --- a/src/lib/libssl/s3_clnt.c +++ b/src/lib/libssl/s3_clnt.c @@ -130,10 +130,17 @@ #include #include #include +#ifdef OPENSSL_FIPS +#include +#endif + #ifndef OPENSSL_NO_DH #include #endif #include +#ifndef OPENSSL_NO_ENGINE +#include +#endif static SSL_METHOD *ssl3_get_client_method(int ver); static int ca_dn_cmp(const X509_NAME * const *a,const X509_NAME * const *b); @@ -965,7 +972,7 @@ int ssl3_get_server_certificate(SSL *s) } i=ssl_verify_cert_chain(s,sk); - if ((s->verify_mode != SSL_VERIFY_NONE) && (!i) + if ((s->verify_mode != SSL_VERIFY_NONE) && (i <= 0) #ifndef OPENSSL_NO_KRB5 && (s->s3->tmp.new_cipher->algorithms & (SSL_MKEY_MASK|SSL_AUTH_MASK)) != (SSL_aKRB5|SSL_kKRB5) @@ -999,7 +1006,7 @@ int ssl3_get_server_certificate(SSL *s) == (SSL_aKRB5|SSL_kKRB5))? 0: 1; #ifdef KSSL_DEBUG - printf("pkey,x = %p, %p\n", pkey,x); + printf("pkey,x = %p, %p\n", (void *)pkey,(void *)x); printf("ssl_cert_type(x,pkey) = %d\n", ssl_cert_type(x,pkey)); printf("cipher, alg, nc = %s, %lx, %d\n", s->s3->tmp.new_cipher->name, s->s3->tmp.new_cipher->algorithms, need_cert); @@ -1415,6 +1422,8 @@ int ssl3_get_key_exchange(SSL *s) q=md_buf; for (num=2; num > 0; num--) { + EVP_MD_CTX_set_flags(&md_ctx, + EVP_MD_CTX_FLAG_NON_FIPS_ALLOW); EVP_DigestInit_ex(&md_ctx,(num == 2) ?s->ctx->md5:s->ctx->sha1, NULL); EVP_DigestUpdate(&md_ctx,&(s->s3->client_random[0]),SSL3_RANDOM_SIZE); @@ -1450,7 +1459,7 @@ int ssl3_get_key_exchange(SSL *s) EVP_VerifyUpdate(&md_ctx,&(s->s3->client_random[0]),SSL3_RANDOM_SIZE); EVP_VerifyUpdate(&md_ctx,&(s->s3->server_random[0]),SSL3_RANDOM_SIZE); EVP_VerifyUpdate(&md_ctx,param,param_len); - if (!EVP_VerifyFinal(&md_ctx,p,(int)n,pkey)) + if (EVP_VerifyFinal(&md_ctx,p,(int)n,pkey) <= 0) { /* bad signature */ al=SSL_AD_DECRYPT_ERROR; @@ -1468,7 +1477,7 @@ int ssl3_get_key_exchange(SSL *s) EVP_VerifyUpdate(&md_ctx,&(s->s3->client_random[0]),SSL3_RANDOM_SIZE); EVP_VerifyUpdate(&md_ctx,&(s->s3->server_random[0]),SSL3_RANDOM_SIZE); EVP_VerifyUpdate(&md_ctx,param,param_len); - if (!EVP_VerifyFinal(&md_ctx,p,(int)n,pkey)) + if (EVP_VerifyFinal(&md_ctx,p,(int)n,pkey) <= 0) { /* bad signature */ al=SSL_AD_DECRYPT_ERROR; @@ -1768,7 +1777,7 @@ int ssl3_get_cert_status(SSL *s) goto f_err; } n2l3(p, resplen); - if (resplen + 4 != n) + if (resplen + 4 != (unsigned long)n) { al = SSL_AD_DECODE_ERROR; SSLerr(SSL_F_SSL3_GET_CERT_STATUS,SSL_R_LENGTH_MISMATCH); @@ -2061,12 +2070,12 @@ int ssl3_send_client_key_exchange(SSL *s) { DH *dh_srvr,*dh_clnt; - if (s->session->sess_cert == NULL) - { - ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_UNEXPECTED_MESSAGE); - SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,SSL_R_UNEXPECTED_MESSAGE); - goto err; - } + if (s->session->sess_cert == NULL) + { + ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_UNEXPECTED_MESSAGE); + SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,SSL_R_UNEXPECTED_MESSAGE); + goto err; + } if (s->session->sess_cert->peer_dh_tmp != NULL) dh_srvr=s->session->sess_cert->peer_dh_tmp; @@ -2448,8 +2457,7 @@ int ssl3_send_client_certificate(SSL *s) * ssl->rwstate=SSL_X509_LOOKUP; return(-1); * We then get retied later */ i=0; - if (s->ctx->client_cert_cb != NULL) - i=s->ctx->client_cert_cb(s,&(x509),&(pkey)); + i = ssl_do_client_cert_cb(s, &x509, &pkey); if (i < 0) { s->rwstate=SSL_X509_LOOKUP; @@ -2716,3 +2724,21 @@ static int ssl3_check_finished(SSL *s) return 1; } #endif + +int ssl_do_client_cert_cb(SSL *s, X509 **px509, EVP_PKEY **ppkey) + { + int i = 0; +#ifndef OPENSSL_NO_ENGINE + if (s->ctx->client_cert_engine) + { + i = ENGINE_load_ssl_client_cert(s->ctx->client_cert_engine, s, + SSL_get_client_CA_list(s), + px509, ppkey, NULL, NULL, NULL); + if (i != 0) + return i; + } +#endif + if (s->ctx->client_cert_cb) + i = s->ctx->client_cert_cb(s,px509,ppkey); + return i; + } diff --git a/src/lib/libssl/s3_lib.c b/src/lib/libssl/s3_lib.c index bdbcd44f27..8916a0b1b3 100644 --- a/src/lib/libssl/s3_lib.c +++ b/src/lib/libssl/s3_lib.c @@ -158,7 +158,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[]={ SSL3_TXT_RSA_NULL_SHA, SSL3_CK_RSA_NULL_SHA, SSL_kRSA|SSL_aRSA|SSL_eNULL |SSL_SHA1|SSL_SSLV3, - SSL_NOT_EXP|SSL_STRONG_NONE, + SSL_NOT_EXP|SSL_STRONG_NONE|SSL_FIPS, 0, 0, 0, @@ -264,7 +264,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[]={ SSL3_TXT_RSA_DES_192_CBC3_SHA, SSL3_CK_RSA_DES_192_CBC3_SHA, SSL_kRSA|SSL_aRSA|SSL_3DES |SSL_SHA1|SSL_SSLV3, - SSL_NOT_EXP|SSL_HIGH, + SSL_NOT_EXP|SSL_HIGH|SSL_FIPS, 0, 168, 168, @@ -304,7 +304,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[]={ SSL3_TXT_DH_DSS_DES_192_CBC3_SHA, SSL3_CK_DH_DSS_DES_192_CBC3_SHA, SSL_kDHd |SSL_aDH|SSL_3DES |SSL_SHA1|SSL_SSLV3, - SSL_NOT_EXP|SSL_HIGH, + SSL_NOT_EXP|SSL_HIGH|SSL_FIPS, 0, 168, 168, @@ -343,7 +343,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[]={ SSL3_TXT_DH_RSA_DES_192_CBC3_SHA, SSL3_CK_DH_RSA_DES_192_CBC3_SHA, SSL_kDHr |SSL_aDH|SSL_3DES |SSL_SHA1|SSL_SSLV3, - SSL_NOT_EXP|SSL_HIGH, + SSL_NOT_EXP|SSL_HIGH|SSL_FIPS, 0, 168, 168, @@ -384,7 +384,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[]={ SSL3_TXT_EDH_DSS_DES_192_CBC3_SHA, SSL3_CK_EDH_DSS_DES_192_CBC3_SHA, SSL_kEDH|SSL_aDSS|SSL_3DES |SSL_SHA1|SSL_SSLV3, - SSL_NOT_EXP|SSL_HIGH, + SSL_NOT_EXP|SSL_HIGH|SSL_FIPS, 0, 168, 168, @@ -423,7 +423,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[]={ SSL3_TXT_EDH_RSA_DES_192_CBC3_SHA, SSL3_CK_EDH_RSA_DES_192_CBC3_SHA, SSL_kEDH|SSL_aRSA|SSL_3DES |SSL_SHA1|SSL_SSLV3, - SSL_NOT_EXP|SSL_HIGH, + SSL_NOT_EXP|SSL_HIGH|SSL_FIPS, 0, 168, 168, @@ -488,7 +488,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[]={ SSL3_TXT_ADH_DES_192_CBC_SHA, SSL3_CK_ADH_DES_192_CBC_SHA, SSL_kEDH |SSL_aNULL|SSL_3DES |SSL_SHA1|SSL_SSLV3, - SSL_NOT_EXP|SSL_HIGH, + SSL_NOT_EXP|SSL_HIGH|SSL_FIPS, 0, 168, 168, @@ -563,7 +563,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[]={ SSL3_TXT_KRB5_DES_192_CBC3_SHA, SSL3_CK_KRB5_DES_192_CBC3_SHA, SSL_kKRB5|SSL_aKRB5| SSL_3DES|SSL_SHA1 |SSL_SSLV3, - SSL_NOT_EXP|SSL_HIGH, + SSL_NOT_EXP|SSL_HIGH|SSL_FIPS, 0, 168, 168, @@ -747,7 +747,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[]={ TLS1_TXT_RSA_WITH_AES_128_SHA, TLS1_CK_RSA_WITH_AES_128_SHA, SSL_kRSA|SSL_aRSA|SSL_AES|SSL_SHA |SSL_TLSV1, - SSL_NOT_EXP|SSL_HIGH, + SSL_NOT_EXP|SSL_HIGH|SSL_FIPS, 0, 128, 128, @@ -760,7 +760,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[]={ TLS1_TXT_DH_DSS_WITH_AES_128_SHA, TLS1_CK_DH_DSS_WITH_AES_128_SHA, SSL_kDHd|SSL_aDH|SSL_AES|SSL_SHA|SSL_TLSV1, - SSL_NOT_EXP|SSL_HIGH, + SSL_NOT_EXP|SSL_HIGH|SSL_FIPS, 0, 128, 128, @@ -773,7 +773,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[]={ TLS1_TXT_DH_RSA_WITH_AES_128_SHA, TLS1_CK_DH_RSA_WITH_AES_128_SHA, SSL_kDHr|SSL_aDH|SSL_AES|SSL_SHA|SSL_TLSV1, - SSL_NOT_EXP|SSL_HIGH, + SSL_NOT_EXP|SSL_HIGH|SSL_FIPS, 0, 128, 128, @@ -786,7 +786,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[]={ TLS1_TXT_DHE_DSS_WITH_AES_128_SHA, TLS1_CK_DHE_DSS_WITH_AES_128_SHA, SSL_kEDH|SSL_aDSS|SSL_AES|SSL_SHA|SSL_TLSV1, - SSL_NOT_EXP|SSL_HIGH, + SSL_NOT_EXP|SSL_HIGH|SSL_FIPS, 0, 128, 128, @@ -799,7 +799,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[]={ TLS1_TXT_DHE_RSA_WITH_AES_128_SHA, TLS1_CK_DHE_RSA_WITH_AES_128_SHA, SSL_kEDH|SSL_aRSA|SSL_AES|SSL_SHA|SSL_TLSV1, - SSL_NOT_EXP|SSL_HIGH, + SSL_NOT_EXP|SSL_HIGH|SSL_FIPS, 0, 128, 128, @@ -812,7 +812,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[]={ TLS1_TXT_ADH_WITH_AES_128_SHA, TLS1_CK_ADH_WITH_AES_128_SHA, SSL_kEDH|SSL_aNULL|SSL_AES|SSL_SHA|SSL_TLSV1, - SSL_NOT_EXP|SSL_HIGH, + SSL_NOT_EXP|SSL_HIGH|SSL_FIPS, 0, 128, 128, @@ -826,7 +826,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[]={ TLS1_TXT_RSA_WITH_AES_256_SHA, TLS1_CK_RSA_WITH_AES_256_SHA, SSL_kRSA|SSL_aRSA|SSL_AES|SSL_SHA |SSL_TLSV1, - SSL_NOT_EXP|SSL_HIGH, + SSL_NOT_EXP|SSL_HIGH|SSL_FIPS, 0, 256, 256, @@ -839,7 +839,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[]={ TLS1_TXT_DH_DSS_WITH_AES_256_SHA, TLS1_CK_DH_DSS_WITH_AES_256_SHA, SSL_kDHd|SSL_aDH|SSL_AES|SSL_SHA|SSL_TLSV1, - SSL_NOT_EXP|SSL_HIGH, + SSL_NOT_EXP|SSL_HIGH|SSL_FIPS, 0, 256, 256, @@ -852,7 +852,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[]={ TLS1_TXT_DH_RSA_WITH_AES_256_SHA, TLS1_CK_DH_RSA_WITH_AES_256_SHA, SSL_kDHr|SSL_aDH|SSL_AES|SSL_SHA|SSL_TLSV1, - SSL_NOT_EXP|SSL_HIGH, + SSL_NOT_EXP|SSL_HIGH|SSL_FIPS, 0, 256, 256, @@ -865,7 +865,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[]={ TLS1_TXT_DHE_DSS_WITH_AES_256_SHA, TLS1_CK_DHE_DSS_WITH_AES_256_SHA, SSL_kEDH|SSL_aDSS|SSL_AES|SSL_SHA|SSL_TLSV1, - SSL_NOT_EXP|SSL_HIGH, + SSL_NOT_EXP|SSL_HIGH|SSL_FIPS, 0, 256, 256, @@ -878,7 +878,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[]={ TLS1_TXT_DHE_RSA_WITH_AES_256_SHA, TLS1_CK_DHE_RSA_WITH_AES_256_SHA, SSL_kEDH|SSL_aRSA|SSL_AES|SSL_SHA|SSL_TLSV1, - SSL_NOT_EXP|SSL_HIGH, + SSL_NOT_EXP|SSL_HIGH|SSL_FIPS, 0, 256, 256, @@ -891,7 +891,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[]={ TLS1_TXT_ADH_WITH_AES_256_SHA, TLS1_CK_ADH_WITH_AES_256_SHA, SSL_kEDH|SSL_aNULL|SSL_AES|SSL_SHA|SSL_TLSV1, - SSL_NOT_EXP|SSL_HIGH, + SSL_NOT_EXP|SSL_HIGH|SSL_FIPS, 0, 256, 256, diff --git a/src/lib/libssl/s3_pkt.c b/src/lib/libssl/s3_pkt.c index 44c7c143fe..9476dcddf6 100644 --- a/src/lib/libssl/s3_pkt.c +++ b/src/lib/libssl/s3_pkt.c @@ -753,8 +753,15 @@ int ssl3_write_pending(SSL *s, int type, const unsigned char *buf, s->rwstate=SSL_NOTHING; return(s->s3->wpend_ret); } - else if (i <= 0) + else if (i <= 0) { + if (s->version == DTLS1_VERSION || + s->version == DTLS1_BAD_VER) { + /* For DTLS, just drop it. That's kind of the whole + point in using a datagram service */ + s->s3->wbuf.left = 0; + } return(i); + } s->s3->wbuf.offset+=i; s->s3->wbuf.left-=i; } @@ -1225,6 +1232,13 @@ int ssl3_do_change_cipher_spec(SSL *s) if (s->s3->tmp.key_block == NULL) { + if (s->session == NULL) + { + /* might happen if dtls1_read_bytes() calls this */ + SSLerr(SSL_F_SSL3_DO_CHANGE_CIPHER_SPEC,SSL_R_CCS_RECEIVED_EARLY); + return (0); + } + s->session->cipher=s->s3->tmp.new_cipher; if (!s->method->ssl3_enc->setup_key_block(s)) return(0); } diff --git a/src/lib/libssl/s3_srvr.c b/src/lib/libssl/s3_srvr.c index 903522ab59..80b45eb86f 100644 --- a/src/lib/libssl/s3_srvr.c +++ b/src/lib/libssl/s3_srvr.c @@ -902,22 +902,28 @@ int ssl3_get_client_hello(SSL *s) break; } } - if (j == 0) - { - if ((s->options & SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG) && (sk_SSL_CIPHER_num(ciphers) == 1)) - { - /* Very bad for multi-threading.... */ - s->session->cipher=sk_SSL_CIPHER_value(ciphers, 0); - } - else + if (j == 0 && (s->options & SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG) && (sk_SSL_CIPHER_num(ciphers) == 1)) + { + /* Special case as client bug workaround: the previously used cipher may + * not be in the current list, the client instead might be trying to + * continue using a cipher that before wasn't chosen due to server + * preferences. We'll have to reject the connection if the cipher is not + * enabled, though. */ + c = sk_SSL_CIPHER_value(ciphers, 0); + if (sk_SSL_CIPHER_find(SSL_get_ciphers(s), c) >= 0) { - /* we need to have the cipher in the cipher - * list if we are asked to reuse it */ - al=SSL_AD_ILLEGAL_PARAMETER; - SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_REQUIRED_CIPHER_MISSING); - goto f_err; + s->session->cipher = c; + j = 1; } } + if (j == 0) + { + /* we need to have the cipher in the cipher + * list if we are asked to reuse it */ + al=SSL_AD_ILLEGAL_PARAMETER; + SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_REQUIRED_CIPHER_MISSING); + goto f_err; + } } /* compression */ @@ -1172,13 +1178,13 @@ int ssl3_send_server_hello(SSL *s) *(d++)=SSL3_MT_SERVER_HELLO; l2n3(l,d); - s->state=SSL3_ST_CW_CLNT_HELLO_B; + s->state=SSL3_ST_SW_SRVR_HELLO_B; /* number of bytes to write */ s->init_num=p-buf; s->init_off=0; } - /* SSL3_ST_CW_CLNT_HELLO_B */ + /* SSL3_ST_SW_SRVR_HELLO_B */ return(ssl3_do_write(s,SSL3_RT_HANDSHAKE)); } @@ -1202,7 +1208,7 @@ int ssl3_send_server_done(SSL *s) s->init_off=0; } - /* SSL3_ST_CW_CLNT_HELLO_B */ + /* SSL3_ST_SW_SRVR_DONE_B */ return(ssl3_do_write(s,SSL3_RT_HANDSHAKE)); } @@ -1540,6 +1546,8 @@ int ssl3_send_server_key_exchange(SSL *s) j=0; for (num=2; num > 0; num--) { + EVP_MD_CTX_set_flags(&md_ctx, + EVP_MD_CTX_FLAG_NON_FIPS_ALLOW); EVP_DigestInit_ex(&md_ctx,(num == 2) ?s->ctx->md5:s->ctx->sha1, NULL); EVP_DigestUpdate(&md_ctx,&(s->s3->client_random[0]),SSL3_RANDOM_SIZE); @@ -2558,7 +2566,7 @@ int ssl3_get_client_certificate(SSL *s) else { i=ssl_verify_cert_chain(s,sk); - if (!i) + if (i <= 0) { al=ssl_verify_alarm_type(s->verify_result); SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE,SSL_R_NO_CERTIFICATE_RETURNED); diff --git a/src/lib/libssl/ssl.h b/src/lib/libssl/ssl.h index 6df921f3c1..ff8a128d3c 100644 --- a/src/lib/libssl/ssl.h +++ b/src/lib/libssl/ssl.h @@ -252,6 +252,7 @@ extern "C" { #define SSL_TXT_LOW "LOW" #define SSL_TXT_MEDIUM "MEDIUM" #define SSL_TXT_HIGH "HIGH" +#define SSL_TXT_FIPS "FIPS" #define SSL_TXT_kFZA "kFZA" #define SSL_TXT_aFZA "aFZA" #define SSL_TXT_eFZA "eFZA" @@ -361,9 +362,6 @@ typedef struct ssl_cipher_st DECLARE_STACK_OF(SSL_CIPHER) -typedef struct ssl_st SSL; -typedef struct ssl_ctx_st SSL_CTX; - /* Used to hold functions for SSLv2 or SSLv3/TLSv1 functions */ typedef struct ssl_method_st { @@ -760,6 +758,12 @@ struct ssl_ctx_st int quiet_shutdown; +#ifndef OPENSSL_ENGINE + /* Engine to pass requests for client certs to + */ + ENGINE *client_cert_engine; +#endif + #ifndef OPENSSL_NO_TLSEXT /* TLS extensions servername callback */ int (*tlsext_servername_callback)(SSL*, int *, void *); @@ -829,6 +833,9 @@ void SSL_CTX_set_info_callback(SSL_CTX *ctx, void (*cb)(const SSL *ssl,int type, void (*SSL_CTX_get_info_callback(SSL_CTX *ctx))(const SSL *ssl,int type,int val); void SSL_CTX_set_client_cert_cb(SSL_CTX *ctx, int (*client_cert_cb)(SSL *ssl, X509 **x509, EVP_PKEY **pkey)); int (*SSL_CTX_get_client_cert_cb(SSL_CTX *ctx))(SSL *ssl, X509 **x509, EVP_PKEY **pkey); +#ifndef OPENSSL_NO_ENGINE +int SSL_CTX_set_client_cert_engine(SSL_CTX *ctx, ENGINE *e); +#endif void SSL_CTX_set_cookie_generate_cb(SSL_CTX *ctx, int (*app_gen_cookie_cb)(SSL *ssl, unsigned char *cookie, unsigned int *cookie_len)); void SSL_CTX_set_cookie_verify_cb(SSL_CTX *ctx, int (*app_verify_cookie_cb)(SSL *ssl, unsigned char *cookie, unsigned int cookie_len)); @@ -1702,6 +1709,7 @@ void ERR_load_SSL_strings(void); #define SSL_F_SSL3_CONNECT 132 #define SSL_F_SSL3_CTRL 213 #define SSL_F_SSL3_CTX_CTRL 133 +#define SSL_F_SSL3_DO_CHANGE_CIPHER_SPEC 279 #define SSL_F_SSL3_ENC 134 #define SSL_F_SSL3_GENERATE_KEY_BLOCK 238 #define SSL_F_SSL3_GET_CERTIFICATE_REQUEST 135 @@ -1755,6 +1763,7 @@ void ERR_load_SSL_strings(void); #define SSL_F_SSL_CTX_CHECK_PRIVATE_KEY 168 #define SSL_F_SSL_CTX_NEW 169 #define SSL_F_SSL_CTX_SET_CIPHER_LIST 269 +#define SSL_F_SSL_CTX_SET_CLIENT_CERT_ENGINE 278 #define SSL_F_SSL_CTX_SET_PURPOSE 226 #define SSL_F_SSL_CTX_SET_SESSION_ID_CONTEXT 219 #define SSL_F_SSL_CTX_SET_SSL_VERSION 170 @@ -1935,6 +1944,7 @@ void ERR_load_SSL_strings(void); #define SSL_R_NO_CIPHERS_SPECIFIED 183 #define SSL_R_NO_CIPHER_LIST 184 #define SSL_R_NO_CIPHER_MATCH 185 +#define SSL_R_NO_CLIENT_CERT_METHOD 317 #define SSL_R_NO_CLIENT_CERT_RECEIVED 186 #define SSL_R_NO_COMPRESSION_SPECIFIED 187 #define SSL_R_NO_METHOD_SPECIFIED 188 diff --git a/src/lib/libssl/ssl_asn1.c b/src/lib/libssl/ssl_asn1.c index 6e14f4d834..0f9a3489dd 100644 --- a/src/lib/libssl/ssl_asn1.c +++ b/src/lib/libssl/ssl_asn1.c @@ -353,7 +353,7 @@ SSL_SESSION *d2i_SSL_SESSION(SSL_SESSION **a, const unsigned char **pp, memcpy(ret->session_id,os.data,os.length); M_ASN1_D2I_get_x(ASN1_OCTET_STRING,osp,d2i_ASN1_OCTET_STRING); - if (ret->master_key_length > SSL_MAX_MASTER_KEY_LENGTH) + if (os.length > SSL_MAX_MASTER_KEY_LENGTH) ret->master_key_length=SSL_MAX_MASTER_KEY_LENGTH; else ret->master_key_length=os.length; diff --git a/src/lib/libssl/ssl_ciph.c b/src/lib/libssl/ssl_ciph.c index 725f7f3c1f..0c2aa249b4 100644 --- a/src/lib/libssl/ssl_ciph.c +++ b/src/lib/libssl/ssl_ciph.c @@ -115,7 +115,10 @@ */ #include #include +#ifndef OPENSSL_NO_COMP #include +#endif + #include "ssl_locl.h" #define SSL_ENC_DES_IDX 0 @@ -222,6 +225,7 @@ static const SSL_CIPHER cipher_aliases[]={ {0,SSL_TXT_LOW, 0, 0, SSL_LOW, 0,0,0,0,SSL_STRONG_MASK}, {0,SSL_TXT_MEDIUM,0, 0,SSL_MEDIUM, 0,0,0,0,SSL_STRONG_MASK}, {0,SSL_TXT_HIGH, 0, 0, SSL_HIGH, 0,0,0,0,SSL_STRONG_MASK}, + {0,SSL_TXT_FIPS, 0, 0, SSL_FIPS, 0,0,0,0,SSL_FIPS|SSL_STRONG_NONE}, }; void ssl_load_ciphers(void) @@ -515,7 +519,12 @@ static void ssl_cipher_collect_ciphers(const SSL_METHOD *ssl_method, c = ssl_method->get_cipher(i); #define IS_MASKED(c) ((c)->algorithms & (((c)->alg_bits == 256) ? m256 : mask)) /* drop those that use any of that is not available */ +#ifdef OPENSSL_FIPS + if ((c != NULL) && c->valid && !IS_MASKED(c) + && (!FIPS_mode() || (c->algo_strength & SSL_FIPS))) +#else if ((c != NULL) && c->valid && !IS_MASKED(c)) +#endif { co_list[co_list_num].cipher = c; co_list[co_list_num].next = NULL; @@ -1054,7 +1063,11 @@ STACK_OF(SSL_CIPHER) *ssl_create_cipher_list(const SSL_METHOD *ssl_method, */ for (curr = head; curr != NULL; curr = curr->next) { +#ifdef OPENSSL_FIPS + if (curr->active && (!FIPS_mode() || curr->cipher->algo_strength & SSL_FIPS)) +#else if (curr->active) +#endif { sk_SSL_CIPHER_push(cipherstack, curr->cipher); #ifdef CIPHER_DEBUG diff --git a/src/lib/libssl/ssl_err.c b/src/lib/libssl/ssl_err.c index 50779c1632..24a994fe01 100644 --- a/src/lib/libssl/ssl_err.c +++ b/src/lib/libssl/ssl_err.c @@ -1,6 +1,6 @@ /* ssl/ssl_err.c */ /* ==================================================================== - * Copyright (c) 1999-2007 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 @@ -138,6 +138,7 @@ static ERR_STRING_DATA SSL_str_functs[]= {ERR_FUNC(SSL_F_SSL3_CONNECT), "SSL3_CONNECT"}, {ERR_FUNC(SSL_F_SSL3_CTRL), "SSL3_CTRL"}, {ERR_FUNC(SSL_F_SSL3_CTX_CTRL), "SSL3_CTX_CTRL"}, +{ERR_FUNC(SSL_F_SSL3_DO_CHANGE_CIPHER_SPEC), "SSL3_DO_CHANGE_CIPHER_SPEC"}, {ERR_FUNC(SSL_F_SSL3_ENC), "SSL3_ENC"}, {ERR_FUNC(SSL_F_SSL3_GENERATE_KEY_BLOCK), "SSL3_GENERATE_KEY_BLOCK"}, {ERR_FUNC(SSL_F_SSL3_GET_CERTIFICATE_REQUEST), "SSL3_GET_CERTIFICATE_REQUEST"}, @@ -191,6 +192,7 @@ static ERR_STRING_DATA SSL_str_functs[]= {ERR_FUNC(SSL_F_SSL_CTX_CHECK_PRIVATE_KEY), "SSL_CTX_check_private_key"}, {ERR_FUNC(SSL_F_SSL_CTX_NEW), "SSL_CTX_new"}, {ERR_FUNC(SSL_F_SSL_CTX_SET_CIPHER_LIST), "SSL_CTX_set_cipher_list"}, +{ERR_FUNC(SSL_F_SSL_CTX_SET_CLIENT_CERT_ENGINE), "SSL_CTX_set_client_cert_engine"}, {ERR_FUNC(SSL_F_SSL_CTX_SET_PURPOSE), "SSL_CTX_set_purpose"}, {ERR_FUNC(SSL_F_SSL_CTX_SET_SESSION_ID_CONTEXT), "SSL_CTX_set_session_id_context"}, {ERR_FUNC(SSL_F_SSL_CTX_SET_SSL_VERSION), "SSL_CTX_set_ssl_version"}, @@ -374,6 +376,7 @@ static ERR_STRING_DATA SSL_str_reasons[]= {ERR_REASON(SSL_R_NO_CIPHERS_SPECIFIED) ,"no ciphers specified"}, {ERR_REASON(SSL_R_NO_CIPHER_LIST) ,"no cipher list"}, {ERR_REASON(SSL_R_NO_CIPHER_MATCH) ,"no cipher match"}, +{ERR_REASON(SSL_R_NO_CLIENT_CERT_METHOD) ,"no client cert method"}, {ERR_REASON(SSL_R_NO_CLIENT_CERT_RECEIVED),"no client cert received"}, {ERR_REASON(SSL_R_NO_COMPRESSION_SPECIFIED),"no compression specified"}, {ERR_REASON(SSL_R_NO_METHOD_SPECIFIED) ,"no method specified"}, diff --git a/src/lib/libssl/ssl_lib.c b/src/lib/libssl/ssl_lib.c index 065411aea8..68eee77e6f 100644 --- a/src/lib/libssl/ssl_lib.c +++ b/src/lib/libssl/ssl_lib.c @@ -130,6 +130,9 @@ #ifndef OPENSSL_NO_DH #include #endif +#ifndef OPENSSL_NO_ENGINE +#include +#endif const char *SSL_version_str=OPENSSL_VERSION_TEXT; @@ -1393,6 +1396,14 @@ SSL_CTX *SSL_CTX_new(SSL_METHOD *meth) return(NULL); } +#ifdef OPENSSL_FIPS + if (FIPS_mode() && (meth->version < TLS1_VERSION)) + { + SSLerr(SSL_F_SSL_CTX_NEW, SSL_R_ONLY_TLS_ALLOWED_IN_FIPS_MODE); + return NULL; + } +#endif + if (SSL_get_ex_data_X509_STORE_CTX_idx() < 0) { SSLerr(SSL_F_SSL_CTX_NEW,SSL_R_X509_VERIFICATION_SETUP_PROBLEMS); @@ -1511,6 +1522,27 @@ SSL_CTX *SSL_CTX_new(SSL_METHOD *meth) ret->tlsext_status_cb = 0; ret->tlsext_status_arg = NULL; +#endif + +#ifndef OPENSSL_NO_ENGINE + ret->client_cert_engine = NULL; +#ifdef OPENSSL_SSL_CLIENT_ENGINE_AUTO +#define eng_strx(x) #x +#define eng_str(x) eng_strx(x) + /* Use specific client engine automatically... ignore errors */ + { + ENGINE *eng; + eng = ENGINE_by_id(eng_str(OPENSSL_SSL_CLIENT_ENGINE_AUTO)); + if (!eng) + { + ERR_clear_error(); + ENGINE_load_builtin_engines(); + eng = ENGINE_by_id(eng_str(OPENSSL_SSL_CLIENT_ENGINE_AUTO)); + } + if (!eng || !SSL_CTX_set_client_cert_engine(ret, eng)) + ERR_clear_error(); + } +#endif #endif return(ret); @@ -1582,6 +1614,10 @@ void SSL_CTX_free(SSL_CTX *a) sk_SSL_COMP_pop_free(a->comp_methods,SSL_COMP_free); #else a->comp_methods = NULL; +#endif +#ifndef OPENSSL_NO_ENGINE + if (a->client_cert_engine) + ENGINE_finish(a->client_cert_engine); #endif OPENSSL_free(a); } diff --git a/src/lib/libssl/ssl_locl.h b/src/lib/libssl/ssl_locl.h index de94c0d0c7..ed4ddbbae6 100644 --- a/src/lib/libssl/ssl_locl.h +++ b/src/lib/libssl/ssl_locl.h @@ -124,7 +124,9 @@ #include "e_os.h" #include +#ifndef OPENSSL_NO_COMP #include +#endif #include #include #ifndef OPENSSL_NO_RSA @@ -330,8 +332,9 @@ #define SSL_LOW 0x00000020L #define SSL_MEDIUM 0x00000040L #define SSL_HIGH 0x00000080L +#define SSL_FIPS 0x00000100L -/* we have used 000000ff - 24 bits left to go */ +/* we have used 000001ff - 23 bits left to go */ /* * Macros to check the export status and cipher strength for export ciphers. @@ -499,6 +502,7 @@ typedef struct ssl3_enc_method int (*alert_value)(int); } SSL3_ENC_METHOD; +#ifndef OPENSSL_NO_COMP /* Used for holding the relevant compression methods loaded into SSL_CTX */ typedef struct ssl3_comp_st { @@ -506,6 +510,7 @@ typedef struct ssl3_comp_st char *name; /* Text name used for the compression type */ COMP_METHOD *method; /* The method :-) */ } SSL3_COMP; +#endif extern SSL3_ENC_METHOD ssl3_undef_enc_method; OPENSSL_EXTERN SSL_CIPHER ssl2_ciphers[]; @@ -874,6 +879,7 @@ int ssl3_get_new_session_ticket(SSL *s); int ssl3_get_cert_status(SSL *s); int ssl3_get_server_done(SSL *s); int ssl3_send_client_verify(SSL *s); +int ssl_do_client_cert_cb(SSL *s, X509 **px509, EVP_PKEY **ppkey); int ssl3_send_client_certificate(SSL *s); int ssl3_send_client_key_exchange(SSL *s); int ssl3_get_key_exchange(SSL *s); diff --git a/src/lib/libssl/ssl_sess.c b/src/lib/libssl/ssl_sess.c index ee88be2b88..8391d62212 100644 --- a/src/lib/libssl/ssl_sess.c +++ b/src/lib/libssl/ssl_sess.c @@ -59,6 +59,9 @@ #include #include #include +#ifndef OPENSSL_NO_ENGINE +#include +#endif #include "ssl_locl.h" static void SSL_SESSION_list_remove(SSL_CTX *ctx, SSL_SESSION *s); @@ -870,6 +873,25 @@ int (*SSL_CTX_get_client_cert_cb(SSL_CTX *ctx))(SSL * ssl, X509 ** x509 , EVP_PK return ctx->client_cert_cb; } +#ifndef OPENSSL_NO_ENGINE +int SSL_CTX_set_client_cert_engine(SSL_CTX *ctx, ENGINE *e) + { + if (!ENGINE_init(e)) + { + SSLerr(SSL_F_SSL_CTX_SET_CLIENT_CERT_ENGINE, ERR_R_ENGINE_LIB); + return 0; + } + if(!ENGINE_get_ssl_client_cert_function(e)) + { + SSLerr(SSL_F_SSL_CTX_SET_CLIENT_CERT_ENGINE, SSL_R_NO_CLIENT_CERT_METHOD); + ENGINE_finish(e); + return 0; + } + ctx->client_cert_engine = e; + return 1; + } +#endif + void SSL_CTX_set_cookie_generate_cb(SSL_CTX *ctx, int (*cb)(SSL *ssl, unsigned char *cookie, unsigned int *cookie_len)) { diff --git a/src/lib/libssl/t1_enc.c b/src/lib/libssl/t1_enc.c index ed5a4a7255..7cb3e29a41 100644 --- a/src/lib/libssl/t1_enc.c +++ b/src/lib/libssl/t1_enc.c @@ -111,10 +111,15 @@ #include #include "ssl_locl.h" +#ifndef OPENSSL_NO_COMP #include +#endif #include #include #include +#ifdef KSSL_DEBUG +#include +#endif static void tls1_P_hash(const EVP_MD *md, const unsigned char *sec, int sec_len, unsigned char *seed, int seed_len, @@ -131,6 +136,8 @@ static void tls1_P_hash(const EVP_MD *md, const unsigned char *sec, HMAC_CTX_init(&ctx); HMAC_CTX_init(&ctx_tmp); + HMAC_CTX_set_flags(&ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW); + HMAC_CTX_set_flags(&ctx_tmp, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW); HMAC_Init_ex(&ctx,sec,sec_len,md, NULL); HMAC_Init_ex(&ctx_tmp,sec,sec_len,md, NULL); HMAC_Update(&ctx,seed,seed_len); @@ -249,15 +256,15 @@ int tls1_change_cipher_state(SSL *s, int which) #ifdef KSSL_DEBUG printf("tls1_change_cipher_state(which= %d) w/\n", which); printf("\talg= %ld, comp= %p\n", s->s3->tmp.new_cipher->algorithms, - comp); - printf("\tevp_cipher == %p ==? &d_cbc_ede_cipher3\n", c); + (void *)comp); + printf("\tevp_cipher == %p ==? &d_cbc_ede_cipher3\n", (void *)c); printf("\tevp_cipher: nid, blksz= %d, %d, keylen=%d, ivlen=%d\n", c->nid,c->block_size,c->key_len,c->iv_len); printf("\tkey_block: len= %d, data= ", s->s3->tmp.key_block_length); { - int i; - for (i=0; is3->tmp.key_block_length; i++) - printf("%02x", key_block[i]); printf("\n"); + int ki; + for (ki=0; kis3->tmp.key_block_length; ki++) + printf("%02x", key_block[ki]); printf("\n"); } #endif /* KSSL_DEBUG */ @@ -413,11 +420,13 @@ printf("which = %04X\nmac key=",which); s->session->key_arg_length=0; #ifdef KSSL_DEBUG { - int i; + int ki; printf("EVP_CipherInit_ex(dd,c,key=,iv=,which)\n"); - printf("\tkey= "); for (i=0; ikey_len; i++) printf("%02x", key[i]); + printf("\tkey= "); + for (ki=0; kikey_len; ki++) printf("%02x", key[ki]); printf("\n"); - printf("\t iv= "); for (i=0; iiv_len; i++) printf("%02x", iv[i]); + printf("\t iv= "); + for (ki=0; kiiv_len; ki++) printf("%02x", iv[ki]); printf("\n"); } #endif /* KSSL_DEBUG */ @@ -590,10 +599,11 @@ int tls1_enc(SSL *s, int send) { unsigned long ui; printf("EVP_Cipher(ds=%p,rec->data=%p,rec->input=%p,l=%ld) ==>\n", - ds,rec->data,rec->input,l); - printf("\tEVP_CIPHER_CTX: %d buf_len, %d key_len [%d %d], %d iv_len\n", + (void *)ds,rec->data,rec->input,l); + printf("\tEVP_CIPHER_CTX: %d buf_len, %d key_len [%ld %ld], %d iv_len\n", ds->buf_len, ds->cipher->key_len, - DES_KEY_SZ, DES_SCHEDULE_SZ, + (unsigned long)DES_KEY_SZ, + (unsigned long)DES_SCHEDULE_SZ, ds->cipher->iv_len); printf("\t\tIV: "); for (i=0; icipher->iv_len; i++) printf("%02X", ds->iv[i]); @@ -618,10 +628,10 @@ int tls1_enc(SSL *s, int send) #ifdef KSSL_DEBUG { - unsigned long i; + unsigned long ki; printf("\trec->data="); - for (i=0; idata[i]); printf("\n"); + for (ki=0; kidata[ki]); printf("\n"); } #endif /* KSSL_DEBUG */ @@ -805,7 +815,7 @@ int tls1_generate_master_secret(SSL *s, unsigned char *out, unsigned char *p, unsigned char buff[SSL_MAX_MASTER_KEY_LENGTH]; #ifdef KSSL_DEBUG - printf ("tls1_generate_master_secret(%p,%p, %p, %d)\n", s,out, p,len); + printf ("tls1_generate_master_secret(%p,%p, %p, %d)\n", (void *)s,out, p,len); #endif /* KSSL_DEBUG */ /* Setup the stuff to munge */ @@ -852,8 +862,10 @@ int tls1_alert_code(int code) case SSL_AD_INTERNAL_ERROR: return(TLS1_AD_INTERNAL_ERROR); case SSL_AD_USER_CANCELLED: return(TLS1_AD_USER_CANCELLED); case SSL_AD_NO_RENEGOTIATION: return(TLS1_AD_NO_RENEGOTIATION); +#ifdef DTLS1_AD_MISSING_HANDSHAKE_MESSAGE case DTLS1_AD_MISSING_HANDSHAKE_MESSAGE: return (DTLS1_AD_MISSING_HANDSHAKE_MESSAGE); +#endif default: return(-1); } } diff --git a/src/lib/libssl/t1_lib.c b/src/lib/libssl/t1_lib.c index 35f04afa4a..9ce726996d 100644 --- a/src/lib/libssl/t1_lib.c +++ b/src/lib/libssl/t1_lib.c @@ -734,6 +734,13 @@ int tls1_process_ticket(SSL *s, unsigned char *session_id, int len, /* Point after session ID in client hello */ const unsigned char *p = session_id + len; unsigned short i; + + /* If tickets disabled behave as if no ticket present + * to permit stateful resumption. + */ + if (SSL_get_options(s) & SSL_OP_NO_TICKET) + return 1; + if ((s->version <= SSL3_VERSION) || !limit) return 1; if (p >= limit) @@ -761,12 +768,7 @@ int tls1_process_ticket(SSL *s, unsigned char *session_id, int len, return 1; if (type == TLSEXT_TYPE_session_ticket) { - /* If tickets disabled indicate cache miss which will - * trigger a full handshake - */ - if (SSL_get_options(s) & SSL_OP_NO_TICKET) - return 0; - /* If zero length not client will accept a ticket + /* If zero length note client will accept a ticket * and indicate cache miss to trigger full handshake */ if (size == 0) diff --git a/src/lib/libssl/test/CAss.cnf b/src/lib/libssl/test/CAss.cnf index 20f8f05e3d..546e660626 100644 --- a/src/lib/libssl/test/CAss.cnf +++ b/src/lib/libssl/test/CAss.cnf @@ -7,7 +7,7 @@ RANDFILE = ./.rnd #################################################################### [ req ] -default_bits = 512 +default_bits = 1024 default_keyfile = keySS.pem distinguished_name = req_distinguished_name encrypt_rsa_key = no diff --git a/src/lib/libssl/test/Uss.cnf b/src/lib/libssl/test/Uss.cnf index 0c0ebb5f67..98b2e054b7 100644 --- a/src/lib/libssl/test/Uss.cnf +++ b/src/lib/libssl/test/Uss.cnf @@ -7,7 +7,7 @@ RANDFILE = ./.rnd #################################################################### [ req ] -default_bits = 512 +default_bits = 1024 default_keyfile = keySS.pem distinguished_name = req_distinguished_name encrypt_rsa_key = no -- cgit v1.2.3-55-g6feb