summaryrefslogtreecommitdiff
path: root/src/lib/libcrypto
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/libcrypto')
-rw-r--r--src/lib/libcrypto/aes/aes.h28
-rw-r--r--src/lib/libcrypto/aes/aes_cbc.c82
-rw-r--r--src/lib/libcrypto/aes/aes_cfb.c160
-rw-r--r--src/lib/libcrypto/aes/aes_core.c209
-rw-r--r--src/lib/libcrypto/aes/aes_ctr.c90
-rw-r--r--src/lib/libcrypto/aes/aes_ige.c12
-rw-r--r--src/lib/libcrypto/aes/aes_ofb.c94
-rw-r--r--src/lib/libcrypto/aes/asm/aes-586.pl2401
-rw-r--r--src/lib/libcrypto/aes/asm/aes-armv4.pl1
-rw-r--r--src/lib/libcrypto/aes/asm/aes-ppc.pl269
-rw-r--r--src/lib/libcrypto/aes/asm/aes-s390x.pl6
-rwxr-xr-xsrc/lib/libcrypto/aes/asm/aes-x86_64.pl2012
-rw-r--r--src/lib/libcrypto/asn1/a_bitstr.c23
-rw-r--r--src/lib/libcrypto/asn1/a_dup.c2
-rw-r--r--src/lib/libcrypto/asn1/a_int.c10
-rw-r--r--src/lib/libcrypto/asn1/a_mbstr.c2
-rw-r--r--src/lib/libcrypto/asn1/a_object.c35
-rw-r--r--src/lib/libcrypto/asn1/a_octet.c4
-rw-r--r--src/lib/libcrypto/asn1/a_set.c45
-rw-r--r--src/lib/libcrypto/asn1/a_sign.c78
-rw-r--r--src/lib/libcrypto/asn1/a_strnid.c18
-rw-r--r--src/lib/libcrypto/asn1/a_time.c40
-rw-r--r--src/lib/libcrypto/asn1/a_type.c53
-rw-r--r--src/lib/libcrypto/asn1/a_verify.c31
-rw-r--r--src/lib/libcrypto/asn1/ameth_lib.c4
-rw-r--r--src/lib/libcrypto/asn1/asn1.h247
-rw-r--r--src/lib/libcrypto/asn1/asn1_err.c22
-rw-r--r--src/lib/libcrypto/asn1/asn1_gen.c42
-rw-r--r--src/lib/libcrypto/asn1/asn1_lib.c36
-rw-r--r--src/lib/libcrypto/asn1/asn1_mac.h7
-rw-r--r--src/lib/libcrypto/asn1/asn1_par.c17
-rw-r--r--src/lib/libcrypto/asn1/asn1t.h71
-rw-r--r--src/lib/libcrypto/asn1/asn_mime.c88
-rw-r--r--src/lib/libcrypto/asn1/asn_pack.c8
-rw-r--r--src/lib/libcrypto/asn1/charmap.h2
-rw-r--r--src/lib/libcrypto/asn1/d2i_pr.c97
-rw-r--r--src/lib/libcrypto/asn1/d2i_pu.c10
-rw-r--r--src/lib/libcrypto/asn1/i2d_pr.c39
-rw-r--r--src/lib/libcrypto/asn1/nsseq.c5
-rw-r--r--src/lib/libcrypto/asn1/p5_pbe.c105
-rw-r--r--src/lib/libcrypto/asn1/p5_pbev2.c54
-rw-r--r--src/lib/libcrypto/asn1/p8_pkey.c75
-rw-r--r--src/lib/libcrypto/asn1/t_pkey.c729
-rw-r--r--src/lib/libcrypto/asn1/t_req.c28
-rw-r--r--src/lib/libcrypto/asn1/t_spki.c31
-rw-r--r--src/lib/libcrypto/asn1/t_x509.c64
-rw-r--r--src/lib/libcrypto/asn1/tasn_dec.c24
-rw-r--r--src/lib/libcrypto/asn1/tasn_enc.c11
-rw-r--r--src/lib/libcrypto/asn1/tasn_fre.c8
-rw-r--r--src/lib/libcrypto/asn1/tasn_new.c23
-rw-r--r--src/lib/libcrypto/asn1/tasn_prn.c625
-rw-r--r--src/lib/libcrypto/asn1/tasn_typ.c11
-rw-r--r--src/lib/libcrypto/asn1/x_crl.c391
-rw-r--r--src/lib/libcrypto/asn1/x_long.c10
-rw-r--r--src/lib/libcrypto/asn1/x_name.c298
-rw-r--r--src/lib/libcrypto/asn1/x_pubkey.c304
-rw-r--r--src/lib/libcrypto/asn1/x_req.c3
-rw-r--r--src/lib/libcrypto/asn1/x_x509.c20
-rw-r--r--src/lib/libcrypto/bf/asm/bf-586.pl3
-rw-r--r--src/lib/libcrypto/bf/bf_skey.c7
-rw-r--r--src/lib/libcrypto/bf/blowfish.h6
-rw-r--r--src/lib/libcrypto/bio/b_print.c4
-rw-r--r--src/lib/libcrypto/bio/b_sock.c242
-rw-r--r--src/lib/libcrypto/bio/bio.h64
-rw-r--r--src/lib/libcrypto/bio/bio_cb.c24
-rw-r--r--src/lib/libcrypto/bio/bio_err.c2
-rw-r--r--src/lib/libcrypto/bio/bio_lib.c4
-rw-r--r--src/lib/libcrypto/bio/bss_acpt.c8
-rw-r--r--src/lib/libcrypto/bio/bss_dgram.c380
-rw-r--r--src/lib/libcrypto/bio/bss_fd.c27
-rw-r--r--src/lib/libcrypto/bio/bss_file.c65
-rw-r--r--src/lib/libcrypto/bio/bss_log.c55
-rw-r--r--src/lib/libcrypto/bio/bss_mem.c18
-rw-r--r--src/lib/libcrypto/bio/bss_sock.c13
-rw-r--r--src/lib/libcrypto/bn/asm/alpha-mont.pl8
-rw-r--r--src/lib/libcrypto/bn/asm/armv4-mont.pl1
-rw-r--r--src/lib/libcrypto/bn/asm/bn-586.pl203
-rw-r--r--src/lib/libcrypto/bn/asm/co-586.pl3
-rw-r--r--src/lib/libcrypto/bn/asm/ppc.pl233
-rw-r--r--src/lib/libcrypto/bn/asm/sparcv8plus.S15
-rw-r--r--src/lib/libcrypto/bn/asm/x86_64-gcc.c29
-rwxr-xr-xsrc/lib/libcrypto/bn/asm/x86_64-mont.pl136
-rw-r--r--src/lib/libcrypto/bn/bn.h181
-rw-r--r--src/lib/libcrypto/bn/bn_asm.c322
-rw-r--r--src/lib/libcrypto/bn/bn_blind.c17
-rw-r--r--src/lib/libcrypto/bn/bn_ctx.c6
-rw-r--r--src/lib/libcrypto/bn/bn_div.c15
-rw-r--r--src/lib/libcrypto/bn/bn_exp.c3
-rw-r--r--src/lib/libcrypto/bn/bn_gf2m.c145
-rw-r--r--src/lib/libcrypto/bn/bn_lcl.h3
-rw-r--r--src/lib/libcrypto/bn/bn_lib.c29
-rw-r--r--src/lib/libcrypto/bn/bn_mont.c269
-rw-r--r--src/lib/libcrypto/bn/bn_mul.c10
-rw-r--r--src/lib/libcrypto/bn/bn_print.c21
-rw-r--r--src/lib/libcrypto/buffer/buf_err.c2
-rw-r--r--src/lib/libcrypto/buffer/buffer.c89
-rw-r--r--src/lib/libcrypto/buffer/buffer.h9
-rw-r--r--src/lib/libcrypto/camellia/asm/cmll-x86.pl2
-rw-r--r--src/lib/libcrypto/camellia/asm/cmll-x86_64.pl4
-rw-r--r--src/lib/libcrypto/camellia/camellia.c2024
-rw-r--r--src/lib/libcrypto/camellia/camellia.h36
-rw-r--r--src/lib/libcrypto/camellia/cmll_cbc.c227
-rw-r--r--src/lib/libcrypto/camellia/cmll_cfb.c110
-rw-r--r--src/lib/libcrypto/camellia/cmll_ctr.c85
-rw-r--r--src/lib/libcrypto/camellia/cmll_locl.h102
-rw-r--r--src/lib/libcrypto/camellia/cmll_misc.c60
-rw-r--r--src/lib/libcrypto/camellia/cmll_ofb.c28
-rw-r--r--src/lib/libcrypto/cast/asm/cast-586.pl3
-rw-r--r--src/lib/libcrypto/cast/c_cfb64.c3
-rw-r--r--src/lib/libcrypto/cast/c_ecb.c3
-rw-r--r--src/lib/libcrypto/cast/c_enc.c13
-rw-r--r--src/lib/libcrypto/cast/c_ofb64.c3
-rw-r--r--src/lib/libcrypto/cast/c_skey.c7
-rw-r--r--src/lib/libcrypto/cast/cast.h18
-rw-r--r--src/lib/libcrypto/cms/cms.h10
-rw-r--r--src/lib/libcrypto/cms/cms_asn1.c46
-rw-r--r--src/lib/libcrypto/cms/cms_env.c85
-rw-r--r--src/lib/libcrypto/cms/cms_err.c4
-rw-r--r--src/lib/libcrypto/cms/cms_ess.c6
-rw-r--r--src/lib/libcrypto/cms/cms_io.c79
-rw-r--r--src/lib/libcrypto/cms/cms_lcl.h1
-rw-r--r--src/lib/libcrypto/cms/cms_lib.c32
-rw-r--r--src/lib/libcrypto/cms/cms_sd.c126
-rw-r--r--src/lib/libcrypto/cms/cms_smime.c22
-rw-r--r--src/lib/libcrypto/comp/c_zlib.c18
-rw-r--r--src/lib/libcrypto/comp/comp_err.c2
-rw-r--r--src/lib/libcrypto/conf/README47
-rw-r--r--src/lib/libcrypto/conf/conf.h35
-rw-r--r--src/lib/libcrypto/conf/conf_api.c134
-rw-r--r--src/lib/libcrypto/conf/conf_def.c11
-rw-r--r--src/lib/libcrypto/conf/conf_err.c4
-rw-r--r--src/lib/libcrypto/conf/conf_lib.c30
-rw-r--r--src/lib/libcrypto/conf/conf_mall.c2
-rw-r--r--src/lib/libcrypto/conf/conf_mod.c8
-rw-r--r--src/lib/libcrypto/cpt_err.c2
-rw-r--r--src/lib/libcrypto/cryptlib.c508
-rw-r--r--src/lib/libcrypto/crypto.h104
-rw-r--r--src/lib/libcrypto/des/asm/crypt586.pl5
-rw-r--r--src/lib/libcrypto/des/asm/des-586.pl274
-rw-r--r--src/lib/libcrypto/des/asm/des_enc.m46
-rw-r--r--src/lib/libcrypto/des/des_enc.c21
-rw-r--r--src/lib/libcrypto/des/des_locl.h6
-rw-r--r--src/lib/libcrypto/des/ecb_enc.c48
-rw-r--r--src/lib/libcrypto/des/enc_read.c12
-rw-r--r--src/lib/libcrypto/des/enc_writ.c4
-rw-r--r--src/lib/libcrypto/des/fcrypt_b.c4
-rw-r--r--src/lib/libcrypto/des/set_key.c13
-rw-r--r--src/lib/libcrypto/des/xcbc_enc.c2
-rw-r--r--src/lib/libcrypto/dh/dh.h41
-rw-r--r--src/lib/libcrypto/dh/dh_ameth.c500
-rw-r--r--src/lib/libcrypto/dh/dh_asn1.c10
-rw-r--r--src/lib/libcrypto/dh/dh_check.c8
-rw-r--r--src/lib/libcrypto/dh/dh_err.c21
-rw-r--r--src/lib/libcrypto/dh/dh_gen.c4
-rw-r--r--src/lib/libcrypto/dh/dh_key.c4
-rw-r--r--src/lib/libcrypto/dh/dh_pmeth.c254
-rw-r--r--src/lib/libcrypto/dh/dh_prn.c80
-rw-r--r--src/lib/libcrypto/doc/DSA_get_ex_new_index.pod2
-rw-r--r--src/lib/libcrypto/doc/EVP_DigestInit.pod23
-rw-r--r--src/lib/libcrypto/doc/EVP_DigestSignInit.pod87
-rw-r--r--src/lib/libcrypto/doc/EVP_DigestVerifyInit.pod82
-rw-r--r--src/lib/libcrypto/doc/EVP_PKEY_CTX_ctrl.pod128
-rw-r--r--src/lib/libcrypto/doc/EVP_PKEY_CTX_new.pod52
-rw-r--r--src/lib/libcrypto/doc/EVP_PKEY_cmp.pod61
-rw-r--r--src/lib/libcrypto/doc/EVP_PKEY_decrypt.pod93
-rw-r--r--src/lib/libcrypto/doc/EVP_PKEY_derive.pod93
-rw-r--r--src/lib/libcrypto/doc/EVP_PKEY_encrypt.pod93
-rw-r--r--src/lib/libcrypto/doc/EVP_PKEY_get_default_digest.pod41
-rw-r--r--src/lib/libcrypto/doc/EVP_PKEY_keygen.pod161
-rw-r--r--src/lib/libcrypto/doc/EVP_PKEY_print_private.pod53
-rw-r--r--src/lib/libcrypto/doc/EVP_PKEY_sign.pod96
-rw-r--r--src/lib/libcrypto/doc/EVP_PKEY_verify.pod91
-rw-r--r--src/lib/libcrypto/doc/EVP_SignInit.pod9
-rw-r--r--src/lib/libcrypto/doc/EVP_VerifyInit.pod9
-rw-r--r--src/lib/libcrypto/doc/OBJ_nid2obj.pod2
-rw-r--r--src/lib/libcrypto/doc/PEM_write_bio_CMS_stream.pod41
-rw-r--r--src/lib/libcrypto/doc/PEM_write_bio_PKCS7_stream.pod41
-rw-r--r--src/lib/libcrypto/doc/PKCS12_parse.pod31
-rw-r--r--src/lib/libcrypto/doc/PKCS7_decrypt.pod4
-rw-r--r--src/lib/libcrypto/doc/PKCS7_encrypt.pod61
-rw-r--r--src/lib/libcrypto/doc/PKCS7_sign.pod115
-rw-r--r--src/lib/libcrypto/doc/PKCS7_sign_add_signer.pod87
-rw-r--r--src/lib/libcrypto/doc/PKCS7_verify.pod6
-rw-r--r--src/lib/libcrypto/doc/SMIME_read_CMS.pod70
-rw-r--r--src/lib/libcrypto/doc/SMIME_read_PKCS7.pod4
-rw-r--r--src/lib/libcrypto/doc/SMIME_write_CMS.pod64
-rw-r--r--src/lib/libcrypto/doc/SMIME_write_PKCS7.pod24
-rw-r--r--src/lib/libcrypto/doc/X509_NAME_ENTRY_get_object.pod16
-rw-r--r--src/lib/libcrypto/doc/X509_NAME_add_entry_by_txt.pod12
-rw-r--r--src/lib/libcrypto/doc/X509_NAME_get_index_by_NID.pod14
-rw-r--r--src/lib/libcrypto/doc/X509_STORE_CTX_get_error.pod303
-rw-r--r--src/lib/libcrypto/doc/X509_STORE_CTX_get_ex_new_index.pod41
-rw-r--r--src/lib/libcrypto/doc/X509_STORE_CTX_new.pod122
-rw-r--r--src/lib/libcrypto/doc/X509_STORE_CTX_set_verify_cb.pod161
-rw-r--r--src/lib/libcrypto/doc/X509_STORE_set_verify_cb_func.pod54
-rw-r--r--src/lib/libcrypto/doc/X509_VERIFY_PARAM_set_flags.pod171
-rw-r--r--src/lib/libcrypto/doc/X509_new.pod2
-rw-r--r--src/lib/libcrypto/doc/X509_verify_cert.pod53
-rw-r--r--src/lib/libcrypto/doc/d2i_RSAPublicKey.pod8
-rw-r--r--src/lib/libcrypto/doc/d2i_X509.pod12
-rw-r--r--src/lib/libcrypto/doc/d2i_X509_CRL.pod4
-rw-r--r--src/lib/libcrypto/doc/d2i_X509_REQ.pod4
-rw-r--r--src/lib/libcrypto/doc/evp.pod22
-rw-r--r--src/lib/libcrypto/doc/i2d_CMS_bio_stream.pod44
-rw-r--r--src/lib/libcrypto/doc/i2d_PKCS7_bio_stream.pod44
-rw-r--r--src/lib/libcrypto/dsa/dsa.h69
-rw-r--r--src/lib/libcrypto/dsa/dsa_ameth.c657
-rw-r--r--src/lib/libcrypto/dsa/dsa_asn1.c96
-rw-r--r--src/lib/libcrypto/dsa/dsa_err.c26
-rw-r--r--src/lib/libcrypto/dsa/dsa_gen.c124
-rw-r--r--src/lib/libcrypto/dsa/dsa_key.c4
-rw-r--r--src/lib/libcrypto/dsa/dsa_lib.c49
-rw-r--r--src/lib/libcrypto/dsa/dsa_locl.h59
-rw-r--r--src/lib/libcrypto/dsa/dsa_ossl.c48
-rw-r--r--src/lib/libcrypto/dsa/dsa_pmeth.c315
-rw-r--r--src/lib/libcrypto/dsa/dsa_prn.c121
-rw-r--r--src/lib/libcrypto/dsa/dsa_sign.c35
-rw-r--r--src/lib/libcrypto/dsa/dsa_vrf.c37
-rw-r--r--src/lib/libcrypto/dso/dso.h43
-rw-r--r--src/lib/libcrypto/dso/dso_dlfcn.c157
-rw-r--r--src/lib/libcrypto/dso/dso_err.c14
-rw-r--r--src/lib/libcrypto/dso/dso_lib.c35
-rw-r--r--src/lib/libcrypto/dso/dso_null.c4
-rw-r--r--src/lib/libcrypto/dso/dso_openssl.c2
-rw-r--r--src/lib/libcrypto/ec/ec.h814
-rw-r--r--src/lib/libcrypto/ec/ec2_mult.c33
-rw-r--r--src/lib/libcrypto/ec/ec2_smpl.c114
-rw-r--r--src/lib/libcrypto/ec/ec_ameth.c659
-rw-r--r--src/lib/libcrypto/ec/ec_curve.c2593
-rw-r--r--src/lib/libcrypto/ec/ec_err.c21
-rw-r--r--src/lib/libcrypto/ec/ec_lcl.h13
-rw-r--r--src/lib/libcrypto/ec/ec_lib.c4
-rw-r--r--src/lib/libcrypto/ec/ec_mult.c22
-rw-r--r--src/lib/libcrypto/ec/ec_pmeth.c340
-rw-r--r--src/lib/libcrypto/ec/eck_prn.c391
-rw-r--r--src/lib/libcrypto/ec/ecp_nist.c26
-rw-r--r--src/lib/libcrypto/ecdh/ech_err.c4
-rw-r--r--src/lib/libcrypto/ecdsa/ecdsa.h193
-rw-r--r--src/lib/libcrypto/ecdsa/ecs_err.c2
-rw-r--r--src/lib/libcrypto/ecdsa/ecs_ossl.c54
-rw-r--r--src/lib/libcrypto/ecdsa/ecs_sign.c2
-rw-r--r--src/lib/libcrypto/engine/eng_all.c19
-rw-r--r--src/lib/libcrypto/engine/eng_cnf.c17
-rw-r--r--src/lib/libcrypto/engine/eng_ctrl.c8
-rw-r--r--src/lib/libcrypto/engine/eng_dyn.c14
-rw-r--r--src/lib/libcrypto/engine/eng_err.c6
-rw-r--r--src/lib/libcrypto/engine/eng_fat.c14
-rw-r--r--src/lib/libcrypto/engine/eng_int.h12
-rw-r--r--src/lib/libcrypto/engine/eng_lib.c3
-rw-r--r--src/lib/libcrypto/engine/eng_list.c2
-rw-r--r--src/lib/libcrypto/engine/eng_openssl.c2
-rw-r--r--src/lib/libcrypto/engine/eng_table.c72
-rw-r--r--src/lib/libcrypto/engine/engine.h55
-rw-r--r--src/lib/libcrypto/engine/tb_asnmth.c246
-rw-r--r--src/lib/libcrypto/engine/tb_pkmeth.c167
-rw-r--r--src/lib/libcrypto/err/err.c789
-rw-r--r--src/lib/libcrypto/err/err.h77
-rw-r--r--src/lib/libcrypto/err/err_all.c13
-rw-r--r--src/lib/libcrypto/err/err_prn.c77
-rw-r--r--src/lib/libcrypto/err/openssl.ec9
-rw-r--r--src/lib/libcrypto/evp/bio_b64.c77
-rw-r--r--src/lib/libcrypto/evp/bio_enc.c6
-rw-r--r--src/lib/libcrypto/evp/bio_md.c16
-rw-r--r--src/lib/libcrypto/evp/c_all.c2
-rw-r--r--src/lib/libcrypto/evp/digest.c211
-rw-r--r--src/lib/libcrypto/evp/e_aes.c35
-rw-r--r--src/lib/libcrypto/evp/e_camellia.c2
-rw-r--r--src/lib/libcrypto/evp/e_des.c91
-rw-r--r--src/lib/libcrypto/evp/e_des3.c95
-rw-r--r--src/lib/libcrypto/evp/e_idea.c2
-rw-r--r--src/lib/libcrypto/evp/e_null.c8
-rw-r--r--src/lib/libcrypto/evp/e_rc2.c5
-rw-r--r--src/lib/libcrypto/evp/e_rc4.c5
-rw-r--r--src/lib/libcrypto/evp/e_xcbc_d.c19
-rw-r--r--src/lib/libcrypto/evp/encode.c4
-rw-r--r--src/lib/libcrypto/evp/evp.h535
-rw-r--r--src/lib/libcrypto/evp/evp_enc.c267
-rw-r--r--src/lib/libcrypto/evp/evp_err.c60
-rw-r--r--src/lib/libcrypto/evp/evp_key.c9
-rw-r--r--src/lib/libcrypto/evp/evp_lib.c44
-rw-r--r--src/lib/libcrypto/evp/evp_locl.h155
-rw-r--r--src/lib/libcrypto/evp/evp_pbe.c266
-rw-r--r--src/lib/libcrypto/evp/evp_pkey.c646
-rw-r--r--src/lib/libcrypto/evp/m_dss.c2
-rw-r--r--src/lib/libcrypto/evp/m_dss1.c5
-rw-r--r--src/lib/libcrypto/evp/m_ecdsa.c2
-rw-r--r--src/lib/libcrypto/evp/m_md4.c1
-rw-r--r--src/lib/libcrypto/evp/m_md5.c1
-rw-r--r--src/lib/libcrypto/evp/m_sha1.c17
-rw-r--r--src/lib/libcrypto/evp/m_sigver.c200
-rw-r--r--src/lib/libcrypto/evp/m_wp.c42
-rw-r--r--src/lib/libcrypto/evp/names.c87
-rw-r--r--src/lib/libcrypto/evp/p5_crpt.c39
-rw-r--r--src/lib/libcrypto/evp/p5_crpt2.c86
-rw-r--r--src/lib/libcrypto/evp/p_dec.c4
-rw-r--r--src/lib/libcrypto/evp/p_enc.c4
-rw-r--r--src/lib/libcrypto/evp/p_lib.c394
-rw-r--r--src/lib/libcrypto/evp/p_open.c2
-rw-r--r--src/lib/libcrypto/evp/p_seal.c2
-rw-r--r--src/lib/libcrypto/evp/p_sign.c47
-rw-r--r--src/lib/libcrypto/evp/p_verify.c44
-rw-r--r--src/lib/libcrypto/evp/pmeth_fn.c368
-rw-r--r--src/lib/libcrypto/evp/pmeth_gn.c220
-rw-r--r--src/lib/libcrypto/evp/pmeth_lib.c538
-rw-r--r--src/lib/libcrypto/ex_data.c42
-rw-r--r--src/lib/libcrypto/hmac/hm_ameth.c167
-rw-r--r--src/lib/libcrypto/hmac/hm_pmeth.c265
-rw-r--r--src/lib/libcrypto/hmac/hmac.c90
-rw-r--r--src/lib/libcrypto/hmac/hmac.h9
-rw-r--r--src/lib/libcrypto/ia64cpuid.S46
-rw-r--r--src/lib/libcrypto/idea/idea.h5
-rw-r--r--src/lib/libcrypto/lhash/lh_stats.c12
-rw-r--r--src/lib/libcrypto/lhash/lhash.c41
-rw-r--r--src/lib/libcrypto/lhash/lhash.h131
-rw-r--r--src/lib/libcrypto/md32_common.h12
-rw-r--r--src/lib/libcrypto/md4/md4.h5
-rw-r--r--src/lib/libcrypto/md4/md4_dgst.c11
-rw-r--r--src/lib/libcrypto/md5/asm/md5-586.pl3
-rw-r--r--src/lib/libcrypto/md5/asm/md5-ia64.S992
-rwxr-xr-xsrc/lib/libcrypto/md5/asm/md5-x86_64.pl156
-rw-r--r--src/lib/libcrypto/md5/md5.h5
-rw-r--r--src/lib/libcrypto/md5/md5_dgst.c11
-rw-r--r--src/lib/libcrypto/md5/md5_locl.h2
-rw-r--r--src/lib/libcrypto/mem_dbg.c257
-rw-r--r--src/lib/libcrypto/modes/cbc128.c206
-rw-r--r--src/lib/libcrypto/modes/cfb128.c249
-rw-r--r--src/lib/libcrypto/modes/ctr128.c184
-rw-r--r--src/lib/libcrypto/modes/cts128.c259
-rw-r--r--src/lib/libcrypto/modes/modes.h59
-rw-r--r--src/lib/libcrypto/modes/ofb128.c128
-rw-r--r--src/lib/libcrypto/o_str.c4
-rw-r--r--src/lib/libcrypto/o_time.c153
-rw-r--r--src/lib/libcrypto/o_time.h1
-rw-r--r--src/lib/libcrypto/objects/o_names.c47
-rw-r--r--src/lib/libcrypto/objects/obj_dat.c180
-rw-r--r--src/lib/libcrypto/objects/obj_dat.pl20
-rw-r--r--src/lib/libcrypto/objects/obj_err.c2
-rw-r--r--src/lib/libcrypto/objects/obj_lib.c35
-rw-r--r--src/lib/libcrypto/objects/obj_mac.num34
-rw-r--r--src/lib/libcrypto/objects/obj_xref.c231
-rw-r--r--src/lib/libcrypto/objects/obj_xref.h75
-rw-r--r--src/lib/libcrypto/objects/obj_xref.txt42
-rw-r--r--src/lib/libcrypto/objects/objects.h97
-rw-r--r--src/lib/libcrypto/objects/objects.pl3
-rw-r--r--src/lib/libcrypto/objects/objects.txt44
-rw-r--r--src/lib/libcrypto/objects/objxref.pl107
-rw-r--r--src/lib/libcrypto/ocsp/ocsp.h22
-rw-r--r--src/lib/libcrypto/ocsp/ocsp_cl.c1
-rw-r--r--src/lib/libcrypto/ocsp/ocsp_err.c3
-rw-r--r--src/lib/libcrypto/ocsp/ocsp_ext.c47
-rw-r--r--src/lib/libcrypto/ocsp/ocsp_ht.c56
-rw-r--r--src/lib/libcrypto/ocsp/ocsp_lib.c3
-rw-r--r--src/lib/libcrypto/ocsp/ocsp_prn.c23
-rw-r--r--src/lib/libcrypto/ocsp/ocsp_vfy.c4
-rw-r--r--src/lib/libcrypto/opensslv.h10
-rw-r--r--src/lib/libcrypto/ossl_typ.h21
-rw-r--r--src/lib/libcrypto/pem/pem.h255
-rw-r--r--src/lib/libcrypto/pem/pem_all.c194
-rw-r--r--src/lib/libcrypto/pem/pem_err.c28
-rw-r--r--src/lib/libcrypto/pem/pem_info.c40
-rw-r--r--src/lib/libcrypto/pem/pem_lib.c100
-rw-r--r--src/lib/libcrypto/pem/pem_pkey.c109
-rw-r--r--src/lib/libcrypto/pem/pem_seal.c2
-rw-r--r--src/lib/libcrypto/pem/pem_x509.c1
-rw-r--r--src/lib/libcrypto/pem/pem_xaux.c1
-rw-r--r--src/lib/libcrypto/pem/pvkfmt.c942
-rwxr-xr-xsrc/lib/libcrypto/perlasm/ppc-xlate.pl152
-rwxr-xr-xsrc/lib/libcrypto/perlasm/x86_64-xlate.pl625
-rw-r--r--src/lib/libcrypto/perlasm/x86asm.pl317
-rw-r--r--src/lib/libcrypto/perlasm/x86gas.pl247
-rw-r--r--src/lib/libcrypto/pkcs12/p12_add.c20
-rw-r--r--src/lib/libcrypto/pkcs12/p12_attr.c2
-rw-r--r--src/lib/libcrypto/pkcs12/p12_crpt.c20
-rw-r--r--src/lib/libcrypto/pkcs12/p12_crt.c11
-rw-r--r--src/lib/libcrypto/pkcs12/p12_key.c7
-rw-r--r--src/lib/libcrypto/pkcs12/p12_kiss.c163
-rw-r--r--src/lib/libcrypto/pkcs12/p12_mutl.c8
-rw-r--r--src/lib/libcrypto/pkcs12/p12_npas.c17
-rw-r--r--src/lib/libcrypto/pkcs12/p12_utl.c4
-rw-r--r--src/lib/libcrypto/pkcs12/pk12err.c2
-rw-r--r--src/lib/libcrypto/pkcs12/pkcs12.h6
-rw-r--r--src/lib/libcrypto/pkcs7/bio_pk7.c69
-rw-r--r--src/lib/libcrypto/pkcs7/pk7_asn1.c43
-rw-r--r--src/lib/libcrypto/pkcs7/pk7_attr.c66
-rw-r--r--src/lib/libcrypto/pkcs7/pk7_doit.c486
-rw-r--r--src/lib/libcrypto/pkcs7/pk7_lib.c192
-rw-r--r--src/lib/libcrypto/pkcs7/pk7_mime.c669
-rw-r--r--src/lib/libcrypto/pkcs7/pk7_smime.c263
-rw-r--r--src/lib/libcrypto/pkcs7/pkcs7.h59
-rw-r--r--src/lib/libcrypto/pkcs7/pkcs7err.c22
-rwxr-xr-xsrc/lib/libcrypto/ppccpuid.pl2
-rw-r--r--src/lib/libcrypto/rand/rand.h29
-rw-r--r--src/lib/libcrypto/rand/rand_err.c20
-rw-r--r--src/lib/libcrypto/rand/rand_lib.c71
-rw-r--r--src/lib/libcrypto/rand/randfile.c33
-rw-r--r--src/lib/libcrypto/rc2/rc2.h4
-rw-r--r--src/lib/libcrypto/rc2/rc2_skey.c19
-rw-r--r--src/lib/libcrypto/rc4/asm/rc4-586.pl448
-rw-r--r--src/lib/libcrypto/rc4/asm/rc4-ia64.pl755
-rw-r--r--src/lib/libcrypto/rc4/asm/rc4-s390x.pl205
-rwxr-xr-xsrc/lib/libcrypto/rc4/asm/rc4-x86_64.pl176
-rw-r--r--src/lib/libcrypto/rc4/rc4.h7
-rw-r--r--src/lib/libcrypto/rc4/rc4_enc.c16
-rw-r--r--src/lib/libcrypto/rc4/rc4_skey.c21
-rw-r--r--src/lib/libcrypto/ripemd/asm/rmd-586.pl3
-rw-r--r--src/lib/libcrypto/ripemd/ripemd.h6
-rw-r--r--src/lib/libcrypto/ripemd/rmd_dgst.c11
-rw-r--r--src/lib/libcrypto/ripemd/rmd_locl.h2
-rw-r--r--src/lib/libcrypto/rsa/rsa.h89
-rw-r--r--src/lib/libcrypto/rsa/rsa_ameth.c349
-rw-r--r--src/lib/libcrypto/rsa/rsa_asn1.c16
-rw-r--r--src/lib/libcrypto/rsa/rsa_eay.c6
-rw-r--r--src/lib/libcrypto/rsa/rsa_err.c29
-rw-r--r--src/lib/libcrypto/rsa/rsa_gen.c3
-rw-r--r--src/lib/libcrypto/rsa/rsa_lib.c283
-rw-r--r--src/lib/libcrypto/rsa/rsa_locl.h4
-rw-r--r--src/lib/libcrypto/rsa/rsa_oaep.c35
-rw-r--r--src/lib/libcrypto/rsa/rsa_pmeth.c587
-rw-r--r--src/lib/libcrypto/rsa/rsa_prn.c93
-rw-r--r--src/lib/libcrypto/rsa/rsa_pss.c16
-rw-r--r--src/lib/libcrypto/rsa/rsa_sign.c88
-rw-r--r--src/lib/libcrypto/s390xcap.c37
-rw-r--r--src/lib/libcrypto/s390xcpuid.S16
-rw-r--r--src/lib/libcrypto/sha/asm/sha1-586.pl1
-rw-r--r--src/lib/libcrypto/sha/asm/sha1-armv4-large.pl234
-rwxr-xr-xsrc/lib/libcrypto/sha/asm/sha1-ppc.pl319
-rw-r--r--src/lib/libcrypto/sha/asm/sha1-s390x.pl226
-rw-r--r--src/lib/libcrypto/sha/asm/sha1-sparcv9.pl283
-rw-r--r--src/lib/libcrypto/sha/asm/sha1-sparcv9a.pl600
-rw-r--r--src/lib/libcrypto/sha/asm/sha1-thumb.pl259
-rwxr-xr-xsrc/lib/libcrypto/sha/asm/sha1-x86_64.pl125
-rw-r--r--src/lib/libcrypto/sha/asm/sha256-586.pl251
-rw-r--r--src/lib/libcrypto/sha/asm/sha256-armv4.pl181
-rw-r--r--src/lib/libcrypto/sha/asm/sha512-586.pl644
-rw-r--r--src/lib/libcrypto/sha/asm/sha512-armv4.pl399
-rwxr-xr-xsrc/lib/libcrypto/sha/asm/sha512-ppc.pl462
-rw-r--r--src/lib/libcrypto/sha/asm/sha512-s390x.pl301
-rw-r--r--src/lib/libcrypto/sha/asm/sha512-sparcv9.pl593
-rwxr-xr-xsrc/lib/libcrypto/sha/asm/sha512-x86_64.pl140
-rw-r--r--src/lib/libcrypto/sha/sha.h5
-rw-r--r--src/lib/libcrypto/sha/sha1_one.c2
-rw-r--r--src/lib/libcrypto/sha/sha1dgst.c4
-rw-r--r--src/lib/libcrypto/sha/sha256.c32
-rw-r--r--src/lib/libcrypto/sha/sha512.c184
-rw-r--r--src/lib/libcrypto/sha/sha_locl.h11
-rw-r--r--src/lib/libcrypto/sparccpuid.S119
-rw-r--r--src/lib/libcrypto/stack/safestack.h1008
-rw-r--r--src/lib/libcrypto/stack/stack.c85
-rw-r--r--src/lib/libcrypto/stack/stack.h49
-rw-r--r--src/lib/libcrypto/ts/ts.h861
-rw-r--r--src/lib/libcrypto/ts/ts_asn1.c322
-rw-r--r--src/lib/libcrypto/ts/ts_conf.c507
-rw-r--r--src/lib/libcrypto/ts/ts_err.c179
-rw-r--r--src/lib/libcrypto/ts/ts_lib.c145
-rw-r--r--src/lib/libcrypto/ts/ts_req_print.c102
-rw-r--r--src/lib/libcrypto/ts/ts_req_utils.c234
-rw-r--r--src/lib/libcrypto/ts/ts_rsp_print.c287
-rw-r--r--src/lib/libcrypto/ts/ts_rsp_sign.c1020
-rw-r--r--src/lib/libcrypto/ts/ts_rsp_utils.c409
-rw-r--r--src/lib/libcrypto/ts/ts_rsp_verify.c725
-rw-r--r--src/lib/libcrypto/ts/ts_verify_ctx.c160
-rw-r--r--src/lib/libcrypto/txt_db/txt_db.c76
-rw-r--r--src/lib/libcrypto/txt_db/txt_db.h19
-rw-r--r--src/lib/libcrypto/ui/ui.h4
-rw-r--r--src/lib/libcrypto/ui/ui_err.c2
-rw-r--r--src/lib/libcrypto/ui/ui_lib.c19
-rw-r--r--src/lib/libcrypto/ui/ui_openssl.c17
-rw-r--r--src/lib/libcrypto/util/mkerr.pl113
-rw-r--r--src/lib/libcrypto/util/mkstack.pl74
-rw-r--r--src/lib/libcrypto/whrlpool/asm/wp-mmx.pl493
-rw-r--r--src/lib/libcrypto/whrlpool/asm/wp-x86_64.pl589
-rw-r--r--src/lib/libcrypto/whrlpool/whrlpool.h38
-rw-r--r--src/lib/libcrypto/whrlpool/wp_block.c655
-rw-r--r--src/lib/libcrypto/whrlpool/wp_dgst.c264
-rw-r--r--src/lib/libcrypto/whrlpool/wp_locl.h3
-rw-r--r--src/lib/libcrypto/x509/by_dir.c226
-rw-r--r--src/lib/libcrypto/x509/by_file.c2
-rw-r--r--src/lib/libcrypto/x509/x509.h258
-rw-r--r--src/lib/libcrypto/x509/x509_cmp.c237
-rw-r--r--src/lib/libcrypto/x509/x509_err.c5
-rw-r--r--src/lib/libcrypto/x509/x509_lu.c215
-rw-r--r--src/lib/libcrypto/x509/x509_obj.c2
-rw-r--r--src/lib/libcrypto/x509/x509_req.c24
-rw-r--r--src/lib/libcrypto/x509/x509_set.c4
-rw-r--r--src/lib/libcrypto/x509/x509_trs.c3
-rw-r--r--src/lib/libcrypto/x509/x509_txt.c24
-rw-r--r--src/lib/libcrypto/x509/x509_vfy.c951
-rw-r--r--src/lib/libcrypto/x509/x509_vfy.h38
-rw-r--r--src/lib/libcrypto/x509/x509_vpm.c28
-rw-r--r--src/lib/libcrypto/x509/x509cset.c4
-rw-r--r--src/lib/libcrypto/x509/x509name.c2
-rw-r--r--src/lib/libcrypto/x509/x509type.c4
-rw-r--r--src/lib/libcrypto/x509/x_all.c7
-rw-r--r--src/lib/libcrypto/x509v3/ext_dat.h13
-rw-r--r--src/lib/libcrypto/x509v3/pcy_cache.c1
-rw-r--r--src/lib/libcrypto/x509v3/pcy_data.c12
-rw-r--r--src/lib/libcrypto/x509v3/pcy_int.h25
-rw-r--r--src/lib/libcrypto/x509v3/pcy_map.c56
-rw-r--r--src/lib/libcrypto/x509v3/pcy_node.c43
-rw-r--r--src/lib/libcrypto/x509v3/pcy_tree.c235
-rw-r--r--src/lib/libcrypto/x509v3/v3_alt.c136
-rw-r--r--src/lib/libcrypto/x509v3/v3_conf.c51
-rw-r--r--src/lib/libcrypto/x509v3/v3_cpols.c5
-rw-r--r--src/lib/libcrypto/x509v3/v3_crld.c552
-rw-r--r--src/lib/libcrypto/x509v3/v3_enum.c19
-rw-r--r--src/lib/libcrypto/x509v3/v3_extku.c16
-rw-r--r--src/lib/libcrypto/x509v3/v3_genn.c153
-rw-r--r--src/lib/libcrypto/x509v3/v3_lib.c24
-rw-r--r--src/lib/libcrypto/x509v3/v3_ncons.c312
-rw-r--r--src/lib/libcrypto/x509v3/v3_ocsp.c62
-rw-r--r--src/lib/libcrypto/x509v3/v3_pci.c32
-rw-r--r--src/lib/libcrypto/x509v3/v3_pcons.c20
-rw-r--r--src/lib/libcrypto/x509v3/v3_pmaps.c18
-rw-r--r--src/lib/libcrypto/x509v3/v3_prn.c2
-rw-r--r--src/lib/libcrypto/x509v3/v3_purp.c194
-rw-r--r--src/lib/libcrypto/x509v3/v3_utl.c45
-rw-r--r--src/lib/libcrypto/x509v3/v3err.c13
-rw-r--r--src/lib/libcrypto/x509v3/x509v3.h173
-rw-r--r--src/lib/libcrypto/x86_64cpuid.pl257
-rw-r--r--src/lib/libcrypto/x86cpuid.pl109
520 files changed, 50508 insertions, 14675 deletions
diff --git a/src/lib/libcrypto/aes/aes.h b/src/lib/libcrypto/aes/aes.h
index 450f2b4051..d2c99730fe 100644
--- a/src/lib/libcrypto/aes/aes.h
+++ b/src/lib/libcrypto/aes/aes.h
@@ -58,6 +58,8 @@
58#error AES is disabled. 58#error AES is disabled.
59#endif 59#endif
60 60
61#include <stddef.h>
62
61#define AES_ENCRYPT 1 63#define AES_ENCRYPT 1
62#define AES_DECRYPT 0 64#define AES_DECRYPT 0
63 65
@@ -66,10 +68,6 @@
66#define AES_MAXNR 14 68#define AES_MAXNR 14
67#define AES_BLOCK_SIZE 16 69#define AES_BLOCK_SIZE 16
68 70
69#ifdef OPENSSL_FIPS
70#define FIPS_AES_SIZE_T int
71#endif
72
73#ifdef __cplusplus 71#ifdef __cplusplus
74extern "C" { 72extern "C" {
75#endif 73#endif
@@ -100,37 +98,32 @@ void AES_decrypt(const unsigned char *in, unsigned char *out,
100void AES_ecb_encrypt(const unsigned char *in, unsigned char *out, 98void AES_ecb_encrypt(const unsigned char *in, unsigned char *out,
101 const AES_KEY *key, const int enc); 99 const AES_KEY *key, const int enc);
102void AES_cbc_encrypt(const unsigned char *in, unsigned char *out, 100void AES_cbc_encrypt(const unsigned char *in, unsigned char *out,
103 const unsigned long length, const AES_KEY *key, 101 size_t length, const AES_KEY *key,
104 unsigned char *ivec, const int enc); 102 unsigned char *ivec, const int enc);
105void AES_cfb128_encrypt(const unsigned char *in, unsigned char *out, 103void AES_cfb128_encrypt(const unsigned char *in, unsigned char *out,
106 const unsigned long length, const AES_KEY *key, 104 size_t length, const AES_KEY *key,
107 unsigned char *ivec, int *num, const int enc); 105 unsigned char *ivec, int *num, const int enc);
108void AES_cfb1_encrypt(const unsigned char *in, unsigned char *out, 106void AES_cfb1_encrypt(const unsigned char *in, unsigned char *out,
109 const unsigned long length, const AES_KEY *key, 107 size_t length, const AES_KEY *key,
110 unsigned char *ivec, int *num, const int enc); 108 unsigned char *ivec, int *num, const int enc);
111void AES_cfb8_encrypt(const unsigned char *in, unsigned char *out, 109void AES_cfb8_encrypt(const unsigned char *in, unsigned char *out,
112 const unsigned long length, const AES_KEY *key, 110 size_t length, const AES_KEY *key,
113 unsigned char *ivec, int *num, const int enc); 111 unsigned char *ivec, int *num, const int enc);
114void AES_cfbr_encrypt_block(const unsigned char *in,unsigned char *out,
115 const int nbits,const AES_KEY *key,
116 unsigned char *ivec,const int enc);
117void AES_ofb128_encrypt(const unsigned char *in, unsigned char *out, 112void AES_ofb128_encrypt(const unsigned char *in, unsigned char *out,
118 const unsigned long length, const AES_KEY *key, 113 size_t length, const AES_KEY *key,
119 unsigned char *ivec, int *num); 114 unsigned char *ivec, int *num);
120void AES_ctr128_encrypt(const unsigned char *in, unsigned char *out, 115void AES_ctr128_encrypt(const unsigned char *in, unsigned char *out,
121 const unsigned long length, const AES_KEY *key, 116 size_t length, const AES_KEY *key,
122 unsigned char ivec[AES_BLOCK_SIZE], 117 unsigned char ivec[AES_BLOCK_SIZE],
123 unsigned char ecount_buf[AES_BLOCK_SIZE], 118 unsigned char ecount_buf[AES_BLOCK_SIZE],
124 unsigned int *num); 119 unsigned int *num);
125
126/* For IGE, see also http://www.links.org/files/openssl-ige.pdf */
127/* NB: the IV is _two_ blocks long */ 120/* NB: the IV is _two_ blocks long */
128void AES_ige_encrypt(const unsigned char *in, unsigned char *out, 121void AES_ige_encrypt(const unsigned char *in, unsigned char *out,
129 const unsigned long length, const AES_KEY *key, 122 size_t length, const AES_KEY *key,
130 unsigned char *ivec, const int enc); 123 unsigned char *ivec, const int enc);
131/* NB: the IV is _four_ blocks long */ 124/* NB: the IV is _four_ blocks long */
132void AES_bi_ige_encrypt(const unsigned char *in, unsigned char *out, 125void AES_bi_ige_encrypt(const unsigned char *in, unsigned char *out,
133 const unsigned long length, const AES_KEY *key, 126 size_t length, const AES_KEY *key,
134 const AES_KEY *key2, const unsigned char *ivec, 127 const AES_KEY *key2, const unsigned char *ivec,
135 const int enc); 128 const int enc);
136 129
@@ -141,6 +134,7 @@ int AES_unwrap_key(AES_KEY *key, const unsigned char *iv,
141 unsigned char *out, 134 unsigned char *out,
142 const unsigned char *in, unsigned int inlen); 135 const unsigned char *in, unsigned int inlen);
143 136
137
144#ifdef __cplusplus 138#ifdef __cplusplus
145} 139}
146#endif 140#endif
diff --git a/src/lib/libcrypto/aes/aes_cbc.c b/src/lib/libcrypto/aes/aes_cbc.c
index 373864cd4b..227f75625d 100644
--- a/src/lib/libcrypto/aes/aes_cbc.c
+++ b/src/lib/libcrypto/aes/aes_cbc.c
@@ -49,85 +49,15 @@
49 * 49 *
50 */ 50 */
51 51
52#ifndef AES_DEBUG
53# ifndef NDEBUG
54# define NDEBUG
55# endif
56#endif
57#include <assert.h>
58
59#include <openssl/aes.h> 52#include <openssl/aes.h>
60#include "aes_locl.h" 53#include <openssl/modes.h>
61 54
62#if !defined(OPENSSL_FIPS_AES_ASM)
63void AES_cbc_encrypt(const unsigned char *in, unsigned char *out, 55void AES_cbc_encrypt(const unsigned char *in, unsigned char *out,
64 const unsigned long length, const AES_KEY *key, 56 size_t len, const AES_KEY *key,
65 unsigned char *ivec, const int enc) { 57 unsigned char *ivec, const int enc) {
66 58
67 unsigned long n; 59 if (enc)
68 unsigned long len = length; 60 CRYPTO_cbc128_encrypt(in,out,len,key,ivec,(block128_f)AES_encrypt);
69 unsigned char tmp[AES_BLOCK_SIZE]; 61 else
70 const unsigned char *iv = ivec; 62 CRYPTO_cbc128_decrypt(in,out,len,key,ivec,(block128_f)AES_decrypt);
71
72 assert(in && out && key && ivec);
73 assert((AES_ENCRYPT == enc)||(AES_DECRYPT == enc));
74
75 if (AES_ENCRYPT == enc) {
76 while (len >= AES_BLOCK_SIZE) {
77 for(n=0; n < AES_BLOCK_SIZE; ++n)
78 out[n] = in[n] ^ iv[n];
79 AES_encrypt(out, out, key);
80 iv = out;
81 len -= AES_BLOCK_SIZE;
82 in += AES_BLOCK_SIZE;
83 out += AES_BLOCK_SIZE;
84 }
85 if (len) {
86 for(n=0; n < len; ++n)
87 out[n] = in[n] ^ iv[n];
88 for(n=len; n < AES_BLOCK_SIZE; ++n)
89 out[n] = iv[n];
90 AES_encrypt(out, out, key);
91 iv = out;
92 }
93 memcpy(ivec,iv,AES_BLOCK_SIZE);
94 } else if (in != out) {
95 while (len >= AES_BLOCK_SIZE) {
96 AES_decrypt(in, out, key);
97 for(n=0; n < AES_BLOCK_SIZE; ++n)
98 out[n] ^= iv[n];
99 iv = in;
100 len -= AES_BLOCK_SIZE;
101 in += AES_BLOCK_SIZE;
102 out += AES_BLOCK_SIZE;
103 }
104 if (len) {
105 AES_decrypt(in,tmp,key);
106 for(n=0; n < len; ++n)
107 out[n] = tmp[n] ^ iv[n];
108 iv = in;
109 }
110 memcpy(ivec,iv,AES_BLOCK_SIZE);
111 } else {
112 while (len >= AES_BLOCK_SIZE) {
113 memcpy(tmp, in, AES_BLOCK_SIZE);
114 AES_decrypt(in, out, key);
115 for(n=0; n < AES_BLOCK_SIZE; ++n)
116 out[n] ^= ivec[n];
117 memcpy(ivec, tmp, AES_BLOCK_SIZE);
118 len -= AES_BLOCK_SIZE;
119 in += AES_BLOCK_SIZE;
120 out += AES_BLOCK_SIZE;
121 }
122 if (len) {
123 memcpy(tmp, in, AES_BLOCK_SIZE);
124 AES_decrypt(tmp, out, key);
125 for(n=0; n < len; ++n)
126 out[n] ^= ivec[n];
127 for(n=len; n < AES_BLOCK_SIZE; ++n)
128 out[n] = tmp[n];
129 memcpy(ivec, tmp, AES_BLOCK_SIZE);
130 }
131 }
132} 63}
133#endif
diff --git a/src/lib/libcrypto/aes/aes_cfb.c b/src/lib/libcrypto/aes/aes_cfb.c
index 49f0411010..0c6d058ce7 100644
--- a/src/lib/libcrypto/aes/aes_cfb.c
+++ b/src/lib/libcrypto/aes/aes_cfb.c
@@ -1,6 +1,6 @@
1/* crypto/aes/aes_cfb.c -*- mode:C; c-file-style: "eay" -*- */ 1/* crypto/aes/aes_cfb.c -*- mode:C; c-file-style: "eay" -*- */
2/* ==================================================================== 2/* ====================================================================
3 * Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved. 3 * Copyright (c) 2002-2006 The OpenSSL Project. All rights reserved.
4 * 4 *
5 * Redistribution and use in source and binary forms, with or without 5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions 6 * modification, are permitted provided that the following conditions
@@ -48,73 +48,9 @@
48 * ==================================================================== 48 * ====================================================================
49 * 49 *
50 */ 50 */
51/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
52 * All rights reserved.
53 *
54 * This package is an SSL implementation written
55 * by Eric Young (eay@cryptsoft.com).
56 * The implementation was written so as to conform with Netscapes SSL.
57 *
58 * This library is free for commercial and non-commercial use as long as
59 * the following conditions are aheared to. The following conditions
60 * apply to all code found in this distribution, be it the RC4, RSA,
61 * lhash, DES, etc., code; not just the SSL code. The SSL documentation
62 * included with this distribution is covered by the same copyright terms
63 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
64 *
65 * Copyright remains Eric Young's, and as such any Copyright notices in
66 * the code are not to be removed.
67 * If this package is used in a product, Eric Young should be given attribution
68 * as the author of the parts of the library used.
69 * This can be in the form of a textual message at program startup or
70 * in documentation (online or textual) provided with the package.
71 *
72 * Redistribution and use in source and binary forms, with or without
73 * modification, are permitted provided that the following conditions
74 * are met:
75 * 1. Redistributions of source code must retain the copyright
76 * notice, this list of conditions and the following disclaimer.
77 * 2. Redistributions in binary form must reproduce the above copyright
78 * notice, this list of conditions and the following disclaimer in the
79 * documentation and/or other materials provided with the distribution.
80 * 3. All advertising materials mentioning features or use of this software
81 * must display the following acknowledgement:
82 * "This product includes cryptographic software written by
83 * Eric Young (eay@cryptsoft.com)"
84 * The word 'cryptographic' can be left out if the rouines from the library
85 * being used are not cryptographic related :-).
86 * 4. If you include any Windows specific code (or a derivative thereof) from
87 * the apps directory (application code) you must include an acknowledgement:
88 * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
89 *
90 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
91 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
92 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
93 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
94 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
95 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
96 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
97 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
98 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
99 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
100 * SUCH DAMAGE.
101 *
102 * The licence and distribution terms for any publically available version or
103 * derivative of this code cannot be changed. i.e. this code cannot simply be
104 * copied and put under another distribution licence
105 * [including the GNU Public Licence.]
106 */
107
108#ifndef AES_DEBUG
109# ifndef NDEBUG
110# define NDEBUG
111# endif
112#endif
113#include <assert.h>
114 51
115#include <openssl/aes.h> 52#include <openssl/aes.h>
116#include "aes_locl.h" 53#include <openssl/modes.h>
117#include "e_os.h"
118 54
119/* The input and output encrypted as though 128bit cfb mode is being 55/* The input and output encrypted as though 128bit cfb mode is being
120 * used. The extra state information to record how much of the 56 * used. The extra state information to record how much of the
@@ -122,104 +58,24 @@
122 */ 58 */
123 59
124void AES_cfb128_encrypt(const unsigned char *in, unsigned char *out, 60void AES_cfb128_encrypt(const unsigned char *in, unsigned char *out,
125 const unsigned long length, const AES_KEY *key, 61 size_t length, const AES_KEY *key,
126 unsigned char *ivec, int *num, const int enc) { 62 unsigned char *ivec, int *num, const int enc) {
127 63
128 unsigned int n; 64 CRYPTO_cfb128_encrypt(in,out,length,key,ivec,num,enc,(block128_f)AES_encrypt);
129 unsigned long l = length;
130 unsigned char c;
131
132 assert(in && out && key && ivec && num);
133
134 n = *num;
135
136 if (enc) {
137 while (l--) {
138 if (n == 0) {
139 AES_encrypt(ivec, ivec, key);
140 }
141 ivec[n] = *(out++) = *(in++) ^ ivec[n];
142 n = (n+1) % AES_BLOCK_SIZE;
143 }
144 } else {
145 while (l--) {
146 if (n == 0) {
147 AES_encrypt(ivec, ivec, key);
148 }
149 c = *(in);
150 *(out++) = *(in++) ^ ivec[n];
151 ivec[n] = c;
152 n = (n+1) % AES_BLOCK_SIZE;
153 }
154 }
155
156 *num=n;
157} 65}
158 66
159/* This expects a single block of size nbits for both in and out. Note that
160 it corrupts any extra bits in the last byte of out */
161void AES_cfbr_encrypt_block(const unsigned char *in,unsigned char *out,
162 const int nbits,const AES_KEY *key,
163 unsigned char *ivec,const int enc)
164 {
165 int n,rem,num;
166 unsigned char ovec[AES_BLOCK_SIZE*2];
167
168 if (nbits<=0 || nbits>128) return;
169
170 /* fill in the first half of the new IV with the current IV */
171 memcpy(ovec,ivec,AES_BLOCK_SIZE);
172 /* construct the new IV */
173 AES_encrypt(ivec,ivec,key);
174 num = (nbits+7)/8;
175 if (enc) /* encrypt the input */
176 for(n=0 ; n < num ; ++n)
177 out[n] = (ovec[AES_BLOCK_SIZE+n] = in[n] ^ ivec[n]);
178 else /* decrypt the input */
179 for(n=0 ; n < num ; ++n)
180 out[n] = (ovec[AES_BLOCK_SIZE+n] = in[n]) ^ ivec[n];
181 /* shift ovec left... */
182 rem = nbits%8;
183 num = nbits/8;
184 if(rem==0)
185 memcpy(ivec,ovec+num,AES_BLOCK_SIZE);
186 else
187 for(n=0 ; n < AES_BLOCK_SIZE ; ++n)
188 ivec[n] = ovec[n+num]<<rem | ovec[n+num+1]>>(8-rem);
189
190 /* it is not necessary to cleanse ovec, since the IV is not secret */
191 }
192
193/* N.B. This expects the input to be packed, MS bit first */ 67/* N.B. This expects the input to be packed, MS bit first */
194void AES_cfb1_encrypt(const unsigned char *in, unsigned char *out, 68void AES_cfb1_encrypt(const unsigned char *in, unsigned char *out,
195 const unsigned long length, const AES_KEY *key, 69 size_t length, const AES_KEY *key,
196 unsigned char *ivec, int *num, const int enc) 70 unsigned char *ivec, int *num, const int enc)
197 { 71 {
198 unsigned int n; 72 CRYPTO_cfb128_1_encrypt(in,out,length,key,ivec,num,enc,(block128_f)AES_encrypt);
199 unsigned char c[1],d[1];
200
201 assert(in && out && key && ivec && num);
202 assert(*num == 0);
203
204 memset(out,0,(length+7)/8);
205 for(n=0 ; n < length ; ++n)
206 {
207 c[0]=(in[n/8]&(1 << (7-n%8))) ? 0x80 : 0;
208 AES_cfbr_encrypt_block(c,d,1,key,ivec,enc);
209 out[n/8]=(out[n/8]&~(1 << (7-n%8)))|((d[0]&0x80) >> (n%8));
210 }
211 } 73 }
212 74
213void AES_cfb8_encrypt(const unsigned char *in, unsigned char *out, 75void AES_cfb8_encrypt(const unsigned char *in, unsigned char *out,
214 const unsigned long length, const AES_KEY *key, 76 size_t length, const AES_KEY *key,
215 unsigned char *ivec, int *num, const int enc) 77 unsigned char *ivec, int *num, const int enc)
216 { 78 {
217 unsigned int n; 79 CRYPTO_cfb128_8_encrypt(in,out,length,key,ivec,num,enc,(block128_f)AES_encrypt);
218
219 assert(in && out && key && ivec && num);
220 assert(*num == 0);
221
222 for(n=0 ; n < length ; ++n)
223 AES_cfbr_encrypt_block(&in[n],&out[n],8,key,ivec,enc);
224 } 80 }
225 81
diff --git a/src/lib/libcrypto/aes/aes_core.c b/src/lib/libcrypto/aes/aes_core.c
index cffdd4daec..a7ec54f4da 100644
--- a/src/lib/libcrypto/aes/aes_core.c
+++ b/src/lib/libcrypto/aes/aes_core.c
@@ -37,12 +37,9 @@
37 37
38#include <stdlib.h> 38#include <stdlib.h>
39#include <openssl/aes.h> 39#include <openssl/aes.h>
40#ifdef OPENSSL_FIPS
41#include <openssl/fips.h>
42#endif
43
44#include "aes_locl.h" 40#include "aes_locl.h"
45 41
42#ifndef AES_ASM
46/* 43/*
47Te0[x] = S [x].[02, 01, 01, 03]; 44Te0[x] = S [x].[02, 01, 01, 03];
48Te1[x] = S [x].[03, 02, 01, 01]; 45Te1[x] = S [x].[03, 02, 01, 01];
@@ -635,10 +632,6 @@ int AES_set_encrypt_key(const unsigned char *userKey, const int bits,
635 int i = 0; 632 int i = 0;
636 u32 temp; 633 u32 temp;
637 634
638#ifdef OPENSSL_FIPS
639 FIPS_selftest_check();
640#endif
641
642 if (!userKey || !key) 635 if (!userKey || !key)
643 return -1; 636 return -1;
644 if (bits != 128 && bits != 192 && bits != 256) 637 if (bits != 128 && bits != 192 && bits != 256)
@@ -781,7 +774,6 @@ int AES_set_decrypt_key(const unsigned char *userKey, const int bits,
781 return 0; 774 return 0;
782} 775}
783 776
784#ifndef AES_ASM
785/* 777/*
786 * Encrypt a single block 778 * Encrypt a single block
787 * in and out can overlap 779 * in and out can overlap
@@ -1164,4 +1156,203 @@ void AES_decrypt(const unsigned char *in, unsigned char *out,
1164 PUTU32(out + 12, s3); 1156 PUTU32(out + 12, s3);
1165} 1157}
1166 1158
1159#else /* AES_ASM */
1160
1161static const u8 Te4[256] = {
1162 0x63U, 0x7cU, 0x77U, 0x7bU, 0xf2U, 0x6bU, 0x6fU, 0xc5U,
1163 0x30U, 0x01U, 0x67U, 0x2bU, 0xfeU, 0xd7U, 0xabU, 0x76U,
1164 0xcaU, 0x82U, 0xc9U, 0x7dU, 0xfaU, 0x59U, 0x47U, 0xf0U,
1165 0xadU, 0xd4U, 0xa2U, 0xafU, 0x9cU, 0xa4U, 0x72U, 0xc0U,
1166 0xb7U, 0xfdU, 0x93U, 0x26U, 0x36U, 0x3fU, 0xf7U, 0xccU,
1167 0x34U, 0xa5U, 0xe5U, 0xf1U, 0x71U, 0xd8U, 0x31U, 0x15U,
1168 0x04U, 0xc7U, 0x23U, 0xc3U, 0x18U, 0x96U, 0x05U, 0x9aU,
1169 0x07U, 0x12U, 0x80U, 0xe2U, 0xebU, 0x27U, 0xb2U, 0x75U,
1170 0x09U, 0x83U, 0x2cU, 0x1aU, 0x1bU, 0x6eU, 0x5aU, 0xa0U,
1171 0x52U, 0x3bU, 0xd6U, 0xb3U, 0x29U, 0xe3U, 0x2fU, 0x84U,
1172 0x53U, 0xd1U, 0x00U, 0xedU, 0x20U, 0xfcU, 0xb1U, 0x5bU,
1173 0x6aU, 0xcbU, 0xbeU, 0x39U, 0x4aU, 0x4cU, 0x58U, 0xcfU,
1174 0xd0U, 0xefU, 0xaaU, 0xfbU, 0x43U, 0x4dU, 0x33U, 0x85U,
1175 0x45U, 0xf9U, 0x02U, 0x7fU, 0x50U, 0x3cU, 0x9fU, 0xa8U,
1176 0x51U, 0xa3U, 0x40U, 0x8fU, 0x92U, 0x9dU, 0x38U, 0xf5U,
1177 0xbcU, 0xb6U, 0xdaU, 0x21U, 0x10U, 0xffU, 0xf3U, 0xd2U,
1178 0xcdU, 0x0cU, 0x13U, 0xecU, 0x5fU, 0x97U, 0x44U, 0x17U,
1179 0xc4U, 0xa7U, 0x7eU, 0x3dU, 0x64U, 0x5dU, 0x19U, 0x73U,
1180 0x60U, 0x81U, 0x4fU, 0xdcU, 0x22U, 0x2aU, 0x90U, 0x88U,
1181 0x46U, 0xeeU, 0xb8U, 0x14U, 0xdeU, 0x5eU, 0x0bU, 0xdbU,
1182 0xe0U, 0x32U, 0x3aU, 0x0aU, 0x49U, 0x06U, 0x24U, 0x5cU,
1183 0xc2U, 0xd3U, 0xacU, 0x62U, 0x91U, 0x95U, 0xe4U, 0x79U,
1184 0xe7U, 0xc8U, 0x37U, 0x6dU, 0x8dU, 0xd5U, 0x4eU, 0xa9U,
1185 0x6cU, 0x56U, 0xf4U, 0xeaU, 0x65U, 0x7aU, 0xaeU, 0x08U,
1186 0xbaU, 0x78U, 0x25U, 0x2eU, 0x1cU, 0xa6U, 0xb4U, 0xc6U,
1187 0xe8U, 0xddU, 0x74U, 0x1fU, 0x4bU, 0xbdU, 0x8bU, 0x8aU,
1188 0x70U, 0x3eU, 0xb5U, 0x66U, 0x48U, 0x03U, 0xf6U, 0x0eU,
1189 0x61U, 0x35U, 0x57U, 0xb9U, 0x86U, 0xc1U, 0x1dU, 0x9eU,
1190 0xe1U, 0xf8U, 0x98U, 0x11U, 0x69U, 0xd9U, 0x8eU, 0x94U,
1191 0x9bU, 0x1eU, 0x87U, 0xe9U, 0xceU, 0x55U, 0x28U, 0xdfU,
1192 0x8cU, 0xa1U, 0x89U, 0x0dU, 0xbfU, 0xe6U, 0x42U, 0x68U,
1193 0x41U, 0x99U, 0x2dU, 0x0fU, 0xb0U, 0x54U, 0xbbU, 0x16U
1194};
1195static const u32 rcon[] = {
1196 0x01000000, 0x02000000, 0x04000000, 0x08000000,
1197 0x10000000, 0x20000000, 0x40000000, 0x80000000,
1198 0x1B000000, 0x36000000, /* for 128-bit blocks, Rijndael never uses more than 10 rcon values */
1199};
1200
1201/**
1202 * Expand the cipher key into the encryption key schedule.
1203 */
1204int AES_set_encrypt_key(const unsigned char *userKey, const int bits,
1205 AES_KEY *key) {
1206 u32 *rk;
1207 int i = 0;
1208 u32 temp;
1209
1210 if (!userKey || !key)
1211 return -1;
1212 if (bits != 128 && bits != 192 && bits != 256)
1213 return -2;
1214
1215 rk = key->rd_key;
1216
1217 if (bits==128)
1218 key->rounds = 10;
1219 else if (bits==192)
1220 key->rounds = 12;
1221 else
1222 key->rounds = 14;
1223
1224 rk[0] = GETU32(userKey );
1225 rk[1] = GETU32(userKey + 4);
1226 rk[2] = GETU32(userKey + 8);
1227 rk[3] = GETU32(userKey + 12);
1228 if (bits == 128) {
1229 while (1) {
1230 temp = rk[3];
1231 rk[4] = rk[0] ^
1232 (Te4[(temp >> 16) & 0xff] << 24) ^
1233 (Te4[(temp >> 8) & 0xff] << 16) ^
1234 (Te4[(temp ) & 0xff] << 8) ^
1235 (Te4[(temp >> 24) ]) ^
1236 rcon[i];
1237 rk[5] = rk[1] ^ rk[4];
1238 rk[6] = rk[2] ^ rk[5];
1239 rk[7] = rk[3] ^ rk[6];
1240 if (++i == 10) {
1241 return 0;
1242 }
1243 rk += 4;
1244 }
1245 }
1246 rk[4] = GETU32(userKey + 16);
1247 rk[5] = GETU32(userKey + 20);
1248 if (bits == 192) {
1249 while (1) {
1250 temp = rk[ 5];
1251 rk[ 6] = rk[ 0] ^
1252 (Te4[(temp >> 16) & 0xff] << 24) ^
1253 (Te4[(temp >> 8) & 0xff] << 16) ^
1254 (Te4[(temp ) & 0xff] << 8) ^
1255 (Te4[(temp >> 24) ]) ^
1256 rcon[i];
1257 rk[ 7] = rk[ 1] ^ rk[ 6];
1258 rk[ 8] = rk[ 2] ^ rk[ 7];
1259 rk[ 9] = rk[ 3] ^ rk[ 8];
1260 if (++i == 8) {
1261 return 0;
1262 }
1263 rk[10] = rk[ 4] ^ rk[ 9];
1264 rk[11] = rk[ 5] ^ rk[10];
1265 rk += 6;
1266 }
1267 }
1268 rk[6] = GETU32(userKey + 24);
1269 rk[7] = GETU32(userKey + 28);
1270 if (bits == 256) {
1271 while (1) {
1272 temp = rk[ 7];
1273 rk[ 8] = rk[ 0] ^
1274 (Te4[(temp >> 16) & 0xff] << 24) ^
1275 (Te4[(temp >> 8) & 0xff] << 16) ^
1276 (Te4[(temp ) & 0xff] << 8) ^
1277 (Te4[(temp >> 24) ]) ^
1278 rcon[i];
1279 rk[ 9] = rk[ 1] ^ rk[ 8];
1280 rk[10] = rk[ 2] ^ rk[ 9];
1281 rk[11] = rk[ 3] ^ rk[10];
1282 if (++i == 7) {
1283 return 0;
1284 }
1285 temp = rk[11];
1286 rk[12] = rk[ 4] ^
1287 (Te4[(temp >> 24) ] << 24) ^
1288 (Te4[(temp >> 16) & 0xff] << 16) ^
1289 (Te4[(temp >> 8) & 0xff] << 8) ^
1290 (Te4[(temp ) & 0xff]);
1291 rk[13] = rk[ 5] ^ rk[12];
1292 rk[14] = rk[ 6] ^ rk[13];
1293 rk[15] = rk[ 7] ^ rk[14];
1294
1295 rk += 8;
1296 }
1297 }
1298 return 0;
1299}
1300
1301/**
1302 * Expand the cipher key into the decryption key schedule.
1303 */
1304int AES_set_decrypt_key(const unsigned char *userKey, const int bits,
1305 AES_KEY *key) {
1306
1307 u32 *rk;
1308 int i, j, status;
1309 u32 temp;
1310
1311 /* first, start with an encryption schedule */
1312 status = AES_set_encrypt_key(userKey, bits, key);
1313 if (status < 0)
1314 return status;
1315
1316 rk = key->rd_key;
1317
1318 /* invert the order of the round keys: */
1319 for (i = 0, j = 4*(key->rounds); i < j; i += 4, j -= 4) {
1320 temp = rk[i ]; rk[i ] = rk[j ]; rk[j ] = temp;
1321 temp = rk[i + 1]; rk[i + 1] = rk[j + 1]; rk[j + 1] = temp;
1322 temp = rk[i + 2]; rk[i + 2] = rk[j + 2]; rk[j + 2] = temp;
1323 temp = rk[i + 3]; rk[i + 3] = rk[j + 3]; rk[j + 3] = temp;
1324 }
1325 /* apply the inverse MixColumn transform to all round keys but the first and the last: */
1326 for (i = 1; i < (key->rounds); i++) {
1327 rk += 4;
1328 for (j = 0; j < 4; j++) {
1329 u32 tp1, tp2, tp4, tp8, tp9, tpb, tpd, tpe, m;
1330
1331 tp1 = rk[j];
1332 m = tp1 & 0x80808080;
1333 tp2 = ((tp1 & 0x7f7f7f7f) << 1) ^
1334 ((m - (m >> 7)) & 0x1b1b1b1b);
1335 m = tp2 & 0x80808080;
1336 tp4 = ((tp2 & 0x7f7f7f7f) << 1) ^
1337 ((m - (m >> 7)) & 0x1b1b1b1b);
1338 m = tp4 & 0x80808080;
1339 tp8 = ((tp4 & 0x7f7f7f7f) << 1) ^
1340 ((m - (m >> 7)) & 0x1b1b1b1b);
1341 tp9 = tp8 ^ tp1;
1342 tpb = tp9 ^ tp2;
1343 tpd = tp9 ^ tp4;
1344 tpe = tp8 ^ tp4 ^ tp2;
1345#if defined(ROTATE)
1346 rk[j] = tpe ^ ROTATE(tpd,16) ^
1347 ROTATE(tp9,24) ^ ROTATE(tpb,8);
1348#else
1349 rk[j] = tpe ^ (tpd >> 16) ^ (tpd << 16) ^
1350 (tp9 >> 8) ^ (tp9 << 24) ^
1351 (tpb >> 24) ^ (tpb << 8);
1352#endif
1353 }
1354 }
1355 return 0;
1356}
1357
1167#endif /* AES_ASM */ 1358#endif /* AES_ASM */
diff --git a/src/lib/libcrypto/aes/aes_ctr.c b/src/lib/libcrypto/aes/aes_ctr.c
index f36982be1e..7c9d165d8a 100644
--- a/src/lib/libcrypto/aes/aes_ctr.c
+++ b/src/lib/libcrypto/aes/aes_ctr.c
@@ -49,91 +49,13 @@
49 * 49 *
50 */ 50 */
51 51
52#ifndef AES_DEBUG
53# ifndef NDEBUG
54# define NDEBUG
55# endif
56#endif
57#include <assert.h>
58
59#include <openssl/aes.h> 52#include <openssl/aes.h>
60#include "aes_locl.h" 53#include <openssl/modes.h>
61
62/* NOTE: the IV/counter CTR mode is big-endian. The rest of the AES code
63 * is endian-neutral. */
64
65/* increment counter (128-bit int) by 1 */
66static void AES_ctr128_inc(unsigned char *counter) {
67 unsigned long c;
68
69 /* Grab bottom dword of counter and increment */
70 c = GETU32(counter + 12);
71 c++; c &= 0xFFFFFFFF;
72 PUTU32(counter + 12, c);
73
74 /* if no overflow, we're done */
75 if (c)
76 return;
77
78 /* Grab 1st dword of counter and increment */
79 c = GETU32(counter + 8);
80 c++; c &= 0xFFFFFFFF;
81 PUTU32(counter + 8, c);
82
83 /* if no overflow, we're done */
84 if (c)
85 return;
86
87 /* Grab 2nd dword of counter and increment */
88 c = GETU32(counter + 4);
89 c++; c &= 0xFFFFFFFF;
90 PUTU32(counter + 4, c);
91
92 /* if no overflow, we're done */
93 if (c)
94 return;
95 54
96 /* Grab top dword of counter and increment */
97 c = GETU32(counter + 0);
98 c++; c &= 0xFFFFFFFF;
99 PUTU32(counter + 0, c);
100}
101
102/* The input encrypted as though 128bit counter mode is being
103 * used. The extra state information to record how much of the
104 * 128bit block we have used is contained in *num, and the
105 * encrypted counter is kept in ecount_buf. Both *num and
106 * ecount_buf must be initialised with zeros before the first
107 * call to AES_ctr128_encrypt().
108 *
109 * This algorithm assumes that the counter is in the x lower bits
110 * of the IV (ivec), and that the application has full control over
111 * overflow and the rest of the IV. This implementation takes NO
112 * responsability for checking that the counter doesn't overflow
113 * into the rest of the IV when incremented.
114 */
115void AES_ctr128_encrypt(const unsigned char *in, unsigned char *out, 55void AES_ctr128_encrypt(const unsigned char *in, unsigned char *out,
116 const unsigned long length, const AES_KEY *key, 56 size_t length, const AES_KEY *key,
117 unsigned char ivec[AES_BLOCK_SIZE], 57 unsigned char ivec[AES_BLOCK_SIZE],
118 unsigned char ecount_buf[AES_BLOCK_SIZE], 58 unsigned char ecount_buf[AES_BLOCK_SIZE],
119 unsigned int *num) { 59 unsigned int *num) {
120 60 CRYPTO_ctr128_encrypt(in,out,length,key,ivec,ecount_buf,num,(block128_f)AES_encrypt);
121 unsigned int n;
122 unsigned long l=length;
123
124 assert(in && out && key && counter && num);
125 assert(*num < AES_BLOCK_SIZE);
126
127 n = *num;
128
129 while (l--) {
130 if (n == 0) {
131 AES_encrypt(ivec, ecount_buf, key);
132 AES_ctr128_inc(ivec);
133 }
134 *(out++) = *(in++) ^ ecount_buf[n];
135 n = (n+1) % AES_BLOCK_SIZE;
136 }
137
138 *num=n;
139} 61}
diff --git a/src/lib/libcrypto/aes/aes_ige.c b/src/lib/libcrypto/aes/aes_ige.c
index 45d7096181..c161351e65 100644
--- a/src/lib/libcrypto/aes/aes_ige.c
+++ b/src/lib/libcrypto/aes/aes_ige.c
@@ -77,11 +77,11 @@ typedef struct {
77/* N.B. The IV for this mode is _twice_ the block size */ 77/* N.B. The IV for this mode is _twice_ the block size */
78 78
79void AES_ige_encrypt(const unsigned char *in, unsigned char *out, 79void AES_ige_encrypt(const unsigned char *in, unsigned char *out,
80 const unsigned long length, const AES_KEY *key, 80 size_t length, const AES_KEY *key,
81 unsigned char *ivec, const int enc) 81 unsigned char *ivec, const int enc)
82 { 82 {
83 unsigned long n; 83 size_t n;
84 unsigned long len; 84 size_t len = length;
85 85
86 OPENSSL_assert(in && out && key && ivec); 86 OPENSSL_assert(in && out && key && ivec);
87 OPENSSL_assert((AES_ENCRYPT == enc)||(AES_DECRYPT == enc)); 87 OPENSSL_assert((AES_ENCRYPT == enc)||(AES_DECRYPT == enc));
@@ -211,12 +211,12 @@ void AES_ige_encrypt(const unsigned char *in, unsigned char *out,
211/* N.B. The IV for this mode is _four times_ the block size */ 211/* N.B. The IV for this mode is _four times_ the block size */
212 212
213void AES_bi_ige_encrypt(const unsigned char *in, unsigned char *out, 213void AES_bi_ige_encrypt(const unsigned char *in, unsigned char *out,
214 const unsigned long length, const AES_KEY *key, 214 size_t length, const AES_KEY *key,
215 const AES_KEY *key2, const unsigned char *ivec, 215 const AES_KEY *key2, const unsigned char *ivec,
216 const int enc) 216 const int enc)
217 { 217 {
218 unsigned long n; 218 size_t n;
219 unsigned long len = length; 219 size_t len = length;
220 unsigned char tmp[AES_BLOCK_SIZE]; 220 unsigned char tmp[AES_BLOCK_SIZE];
221 unsigned char tmp2[AES_BLOCK_SIZE]; 221 unsigned char tmp2[AES_BLOCK_SIZE];
222 unsigned char tmp3[AES_BLOCK_SIZE]; 222 unsigned char tmp3[AES_BLOCK_SIZE];
diff --git a/src/lib/libcrypto/aes/aes_ofb.c b/src/lib/libcrypto/aes/aes_ofb.c
index f358bb39e2..50bf0b8325 100644
--- a/src/lib/libcrypto/aes/aes_ofb.c
+++ b/src/lib/libcrypto/aes/aes_ofb.c
@@ -1,6 +1,6 @@
1/* crypto/aes/aes_ofb.c -*- mode:C; c-file-style: "eay" -*- */ 1/* crypto/aes/aes_ofb.c -*- mode:C; c-file-style: "eay" -*- */
2/* ==================================================================== 2/* ====================================================================
3 * Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved. 3 * Copyright (c) 2002-2006 The OpenSSL Project. All rights reserved.
4 * 4 *
5 * Redistribution and use in source and binary forms, with or without 5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions 6 * modification, are permitted provided that the following conditions
@@ -48,95 +48,13 @@
48 * ==================================================================== 48 * ====================================================================
49 * 49 *
50 */ 50 */
51/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
52 * All rights reserved.
53 *
54 * This package is an SSL implementation written
55 * by Eric Young (eay@cryptsoft.com).
56 * The implementation was written so as to conform with Netscapes SSL.
57 *
58 * This library is free for commercial and non-commercial use as long as
59 * the following conditions are aheared to. The following conditions
60 * apply to all code found in this distribution, be it the RC4, RSA,
61 * lhash, DES, etc., code; not just the SSL code. The SSL documentation
62 * included with this distribution is covered by the same copyright terms
63 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
64 *
65 * Copyright remains Eric Young's, and as such any Copyright notices in
66 * the code are not to be removed.
67 * If this package is used in a product, Eric Young should be given attribution
68 * as the author of the parts of the library used.
69 * This can be in the form of a textual message at program startup or
70 * in documentation (online or textual) provided with the package.
71 *
72 * Redistribution and use in source and binary forms, with or without
73 * modification, are permitted provided that the following conditions
74 * are met:
75 * 1. Redistributions of source code must retain the copyright
76 * notice, this list of conditions and the following disclaimer.
77 * 2. Redistributions in binary form must reproduce the above copyright
78 * notice, this list of conditions and the following disclaimer in the
79 * documentation and/or other materials provided with the distribution.
80 * 3. All advertising materials mentioning features or use of this software
81 * must display the following acknowledgement:
82 * "This product includes cryptographic software written by
83 * Eric Young (eay@cryptsoft.com)"
84 * The word 'cryptographic' can be left out if the rouines from the library
85 * being used are not cryptographic related :-).
86 * 4. If you include any Windows specific code (or a derivative thereof) from
87 * the apps directory (application code) you must include an acknowledgement:
88 * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
89 *
90 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
91 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
92 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
93 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
94 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
95 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
96 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
97 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
98 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
99 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
100 * SUCH DAMAGE.
101 *
102 * The licence and distribution terms for any publically available version or
103 * derivative of this code cannot be changed. i.e. this code cannot simply be
104 * copied and put under another distribution licence
105 * [including the GNU Public Licence.]
106 */
107
108#ifndef AES_DEBUG
109# ifndef NDEBUG
110# define NDEBUG
111# endif
112#endif
113#include <assert.h>
114 51
115#include <openssl/aes.h> 52#include <openssl/aes.h>
116#include "aes_locl.h" 53#include <openssl/modes.h>
117 54
118/* The input and output encrypted as though 128bit ofb mode is being
119 * used. The extra state information to record how much of the
120 * 128bit block we have used is contained in *num;
121 */
122void AES_ofb128_encrypt(const unsigned char *in, unsigned char *out, 55void AES_ofb128_encrypt(const unsigned char *in, unsigned char *out,
123 const unsigned long length, const AES_KEY *key, 56 size_t length, const AES_KEY *key,
124 unsigned char *ivec, int *num) { 57 unsigned char *ivec, int *num)
125 58{
126 unsigned int n; 59 CRYPTO_ofb128_encrypt(in,out,length,key,ivec,num,(block128_f)AES_encrypt);
127 unsigned long l=length;
128
129 assert(in && out && key && ivec && num);
130
131 n = *num;
132
133 while (l--) {
134 if (n == 0) {
135 AES_encrypt(ivec, ivec, key);
136 }
137 *(out++) = *(in++) ^ ivec[n];
138 n = (n+1) % AES_BLOCK_SIZE;
139 }
140
141 *num=n;
142} 60}
diff --git a/src/lib/libcrypto/aes/asm/aes-586.pl b/src/lib/libcrypto/aes/asm/aes-586.pl
index 3bc46a968e..aab40e6f1c 100644
--- a/src/lib/libcrypto/aes/asm/aes-586.pl
+++ b/src/lib/libcrypto/aes/asm/aes-586.pl
@@ -2,11 +2,12 @@
2# 2#
3# ==================================================================== 3# ====================================================================
4# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL 4# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
5# project. Rights for redistribution and usage in source and binary 5# project. The module is, however, dual licensed under OpenSSL and
6# forms are granted according to the OpenSSL license. 6# CRYPTOGAMS licenses depending on where you obtain it. For further
7# details see http://www.openssl.org/~appro/cryptogams/.
7# ==================================================================== 8# ====================================================================
8# 9#
9# Version 3.6. 10# Version 4.3.
10# 11#
11# You might fail to appreciate this module performance from the first 12# You might fail to appreciate this module performance from the first
12# try. If compared to "vanilla" linux-ia32-icc target, i.e. considered 13# try. If compared to "vanilla" linux-ia32-icc target, i.e. considered
@@ -81,11 +82,117 @@
81# AMD K8 20 19 82# AMD K8 20 19
82# PIII 25 23 83# PIII 25 23
83# Pentium 81 78 84# Pentium 81 78
84 85#
85push(@INC,"perlasm","../../perlasm"); 86# Version 3.7 reimplements outer rounds as "compact." Meaning that
87# first and last rounds reference compact 256 bytes S-box. This means
88# that first round consumes a lot more CPU cycles and that encrypt
89# and decrypt performance becomes asymmetric. Encrypt performance
90# drops by 10-12%, while decrypt - by 20-25%:-( 256 bytes S-box is
91# aggressively pre-fetched.
92#
93# Version 4.0 effectively rolls back to 3.6 and instead implements
94# additional set of functions, _[x86|sse]_AES_[en|de]crypt_compact,
95# which use exclusively 256 byte S-box. These functions are to be
96# called in modes not concealing plain text, such as ECB, or when
97# we're asked to process smaller amount of data [or unconditionally
98# on hyper-threading CPU]. Currently it's called unconditionally from
99# AES_[en|de]crypt, which affects all modes, but CBC. CBC routine
100# still needs to be modified to switch between slower and faster
101# mode when appropriate... But in either case benchmark landscape
102# changes dramatically and below numbers are CPU cycles per processed
103# byte for 128-bit key.
104#
105# ECB encrypt ECB decrypt CBC large chunk
106# P4 56[60] 84[100] 23
107# AMD K8 48[44] 70[79] 18
108# PIII 41[50] 61[91] 24
109# Core 2 32[38] 45[70] 18.5
110# Pentium 120 160 77
111#
112# Version 4.1 switches to compact S-box even in key schedule setup.
113#
114# Version 4.2 prefetches compact S-box in every SSE round or in other
115# words every cache-line is *guaranteed* to be accessed within ~50
116# cycles window. Why just SSE? Because it's needed on hyper-threading
117# CPU! Which is also why it's prefetched with 64 byte stride. Best
118# part is that it has no negative effect on performance:-)
119#
120# Version 4.3 implements switch between compact and non-compact block
121# functions in AES_cbc_encrypt depending on how much data was asked
122# to be processed in one stroke.
123#
124######################################################################
125# Timing attacks are classified in two classes: synchronous when
126# attacker consciously initiates cryptographic operation and collects
127# timing data of various character afterwards, and asynchronous when
128# malicious code is executed on same CPU simultaneously with AES,
129# instruments itself and performs statistical analysis of this data.
130#
131# As far as synchronous attacks go the root to the AES timing
132# vulnerability is twofold. Firstly, of 256 S-box elements at most 160
133# are referred to in single 128-bit block operation. Well, in C
134# implementation with 4 distinct tables it's actually as little as 40
135# references per 256 elements table, but anyway... Secondly, even
136# though S-box elements are clustered into smaller amount of cache-
137# lines, smaller than 160 and even 40, it turned out that for certain
138# plain-text pattern[s] or simply put chosen plain-text and given key
139# few cache-lines remain unaccessed during block operation. Now, if
140# attacker can figure out this access pattern, he can deduct the key
141# [or at least part of it]. The natural way to mitigate this kind of
142# attacks is to minimize the amount of cache-lines in S-box and/or
143# prefetch them to ensure that every one is accessed for more uniform
144# timing. But note that *if* plain-text was concealed in such way that
145# input to block function is distributed *uniformly*, then attack
146# wouldn't apply. Now note that some encryption modes, most notably
147# CBC, do mask the plain-text in this exact way [secure cipher output
148# is distributed uniformly]. Yes, one still might find input that
149# would reveal the information about given key, but if amount of
150# candidate inputs to be tried is larger than amount of possible key
151# combinations then attack becomes infeasible. This is why revised
152# AES_cbc_encrypt "dares" to switch to larger S-box when larger chunk
153# of data is to be processed in one stroke. The current size limit of
154# 512 bytes is chosen to provide same [diminishigly low] probability
155# for cache-line to remain untouched in large chunk operation with
156# large S-box as for single block operation with compact S-box and
157# surely needs more careful consideration...
158#
159# As for asynchronous attacks. There are two flavours: attacker code
160# being interleaved with AES on hyper-threading CPU at *instruction*
161# level, and two processes time sharing single core. As for latter.
162# Two vectors. 1. Given that attacker process has higher priority,
163# yield execution to process performing AES just before timer fires
164# off the scheduler, immediately regain control of CPU and analyze the
165# cache state. For this attack to be efficient attacker would have to
166# effectively slow down the operation by several *orders* of magnitute,
167# by ratio of time slice to duration of handful of AES rounds, which
168# unlikely to remain unnoticed. Not to mention that this also means
169# that he would spend correspondigly more time to collect enough
170# statistical data to mount the attack. It's probably appropriate to
171# say that if adeversary reckons that this attack is beneficial and
172# risks to be noticed, you probably have larger problems having him
173# mere opportunity. In other words suggested code design expects you
174# to preclude/mitigate this attack by overall system security design.
175# 2. Attacker manages to make his code interrupt driven. In order for
176# this kind of attack to be feasible, interrupt rate has to be high
177# enough, again comparable to duration of handful of AES rounds. But
178# is there interrupt source of such rate? Hardly, not even 1Gbps NIC
179# generates interrupts at such raging rate...
180#
181# And now back to the former, hyper-threading CPU or more specifically
182# Intel P4. Recall that asynchronous attack implies that malicious
183# code instruments itself. And naturally instrumentation granularity
184# has be noticeably lower than duration of codepath accessing S-box.
185# Given that all cache-lines are accessed during that time that is.
186# Current implementation accesses *all* cache-lines within ~50 cycles
187# window, which is actually *less* than RDTSC latency on Intel P4!
188
189$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
190push(@INC,"${dir}","${dir}../../perlasm");
86require "x86asm.pl"; 191require "x86asm.pl";
87 192
88&asm_init($ARGV[0],"aes-586.pl",$ARGV[$#ARGV] eq "386"); 193&asm_init($ARGV[0],"aes-586.pl",$x86only = $ARGV[$#ARGV] eq "386");
194&static_label("AES_Te");
195&static_label("AES_Td");
89 196
90$s0="eax"; 197$s0="eax";
91$s1="ebx"; 198$s1="ebx";
@@ -93,21 +200,36 @@ $s2="ecx";
93$s3="edx"; 200$s3="edx";
94$key="edi"; 201$key="edi";
95$acc="esi"; 202$acc="esi";
203$tbl="ebp";
204
205# stack frame layout in _[x86|sse]_AES_* routines, frame is allocated
206# by caller
207$__ra=&DWP(0,"esp"); # return address
208$__s0=&DWP(4,"esp"); # s0 backing store
209$__s1=&DWP(8,"esp"); # s1 backing store
210$__s2=&DWP(12,"esp"); # s2 backing store
211$__s3=&DWP(16,"esp"); # s3 backing store
212$__key=&DWP(20,"esp"); # pointer to key schedule
213$__end=&DWP(24,"esp"); # pointer to end of key schedule
214$__tbl=&DWP(28,"esp"); # %ebp backing store
215
216# stack frame layout in AES_[en|crypt] routines, which differs from
217# above by 4 and overlaps by %ebp backing store
218$_tbl=&DWP(24,"esp");
219$_esp=&DWP(28,"esp");
96 220
97$compromise=0; # $compromise=128 abstains from copying key 221sub _data_word() { my $i; while(defined($i=shift)) { &data_word($i,$i); } }
98 # schedule to stack when encrypting inputs 222
99 # shorter than 128 bytes at the cost of 223$speed_limit=512; # chunks smaller than $speed_limit are
100 # risksing aliasing with S-boxes. In return 224 # processed with compact routine in CBC mode
101 # you get way better, up to +70%, small block
102 # performance.
103$small_footprint=1; # $small_footprint=1 code is ~5% slower [on 225$small_footprint=1; # $small_footprint=1 code is ~5% slower [on
104 # recent µ-archs], but ~5 times smaller! 226 # recent µ-archs], but ~5 times smaller!
105 # I favor compact code to minimize cache 227 # I favor compact code to minimize cache
106 # contention and in hope to "collect" 5% back 228 # contention and in hope to "collect" 5% back
107 # in real-life applications... 229 # in real-life applications...
230
108$vertical_spin=0; # shift "verticaly" defaults to 0, because of 231$vertical_spin=0; # shift "verticaly" defaults to 0, because of
109 # its proof-of-concept status... 232 # its proof-of-concept status...
110
111# Note that there is no decvert(), as well as last encryption round is 233# Note that there is no decvert(), as well as last encryption round is
112# performed with "horizontal" shifts. This is because this "vertical" 234# performed with "horizontal" shifts. This is because this "vertical"
113# implementation [one which groups shifts on a given $s[i] to form a 235# implementation [one which groups shifts on a given $s[i] to form a
@@ -170,17 +292,484 @@ sub encvert()
170 &movz ($v0,&HB($v1)); 292 &movz ($v0,&HB($v1));
171 &and ($v1,0xFF); 293 &and ($v1,0xFF);
172 &xor ($s[3],&DWP(2,$te,$v1,8)); # s1>>16 294 &xor ($s[3],&DWP(2,$te,$v1,8)); # s1>>16
173 &mov ($key,&DWP(12,"esp")); # reincarnate v1 as key 295 &mov ($key,$__key); # reincarnate v1 as key
174 &xor ($s[2],&DWP(1,$te,$v0,8)); # s1>>24 296 &xor ($s[2],&DWP(1,$te,$v0,8)); # s1>>24
175} 297}
176 298
299# Another experimental routine, which features "horizontal spin," but
300# eliminates one reference to stack. Strangely enough runs slower...
301sub enchoriz()
302{ my $v0 = $key, $v1 = $acc;
303
304 &movz ($v0,&LB($s0)); # 3, 2, 1, 0*
305 &rotr ($s2,8); # 8,11,10, 9
306 &mov ($v1,&DWP(0,$te,$v0,8)); # 0
307 &movz ($v0,&HB($s1)); # 7, 6, 5*, 4
308 &rotr ($s3,16); # 13,12,15,14
309 &xor ($v1,&DWP(3,$te,$v0,8)); # 5
310 &movz ($v0,&HB($s2)); # 8,11,10*, 9
311 &rotr ($s0,16); # 1, 0, 3, 2
312 &xor ($v1,&DWP(2,$te,$v0,8)); # 10
313 &movz ($v0,&HB($s3)); # 13,12,15*,14
314 &xor ($v1,&DWP(1,$te,$v0,8)); # 15, t[0] collected
315 &mov ($__s0,$v1); # t[0] saved
316
317 &movz ($v0,&LB($s1)); # 7, 6, 5, 4*
318 &shr ($s1,16); # -, -, 7, 6
319 &mov ($v1,&DWP(0,$te,$v0,8)); # 4
320 &movz ($v0,&LB($s3)); # 13,12,15,14*
321 &xor ($v1,&DWP(2,$te,$v0,8)); # 14
322 &movz ($v0,&HB($s0)); # 1, 0, 3*, 2
323 &and ($s3,0xffff0000); # 13,12, -, -
324 &xor ($v1,&DWP(1,$te,$v0,8)); # 3
325 &movz ($v0,&LB($s2)); # 8,11,10, 9*
326 &or ($s3,$s1); # 13,12, 7, 6
327 &xor ($v1,&DWP(3,$te,$v0,8)); # 9, t[1] collected
328 &mov ($s1,$v1); # s[1]=t[1]
329
330 &movz ($v0,&LB($s0)); # 1, 0, 3, 2*
331 &shr ($s2,16); # -, -, 8,11
332 &mov ($v1,&DWP(2,$te,$v0,8)); # 2
333 &movz ($v0,&HB($s3)); # 13,12, 7*, 6
334 &xor ($v1,&DWP(1,$te,$v0,8)); # 7
335 &movz ($v0,&HB($s2)); # -, -, 8*,11
336 &xor ($v1,&DWP(0,$te,$v0,8)); # 8
337 &mov ($v0,$s3);
338 &shr ($v0,24); # 13
339 &xor ($v1,&DWP(3,$te,$v0,8)); # 13, t[2] collected
340
341 &movz ($v0,&LB($s2)); # -, -, 8,11*
342 &shr ($s0,24); # 1*
343 &mov ($s2,&DWP(1,$te,$v0,8)); # 11
344 &xor ($s2,&DWP(3,$te,$s0,8)); # 1
345 &mov ($s0,$__s0); # s[0]=t[0]
346 &movz ($v0,&LB($s3)); # 13,12, 7, 6*
347 &shr ($s3,16); # , ,13,12
348 &xor ($s2,&DWP(2,$te,$v0,8)); # 6
349 &mov ($key,$__key); # reincarnate v0 as key
350 &and ($s3,0xff); # , ,13,12*
351 &mov ($s3,&DWP(0,$te,$s3,8)); # 12
352 &xor ($s3,$s2); # s[2]=t[3] collected
353 &mov ($s2,$v1); # s[2]=t[2]
354}
355
356# More experimental code... SSE one... Even though this one eliminates
357# *all* references to stack, it's not faster...
358sub sse_encbody()
359{
360 &movz ($acc,&LB("eax")); # 0
361 &mov ("ecx",&DWP(0,$tbl,$acc,8)); # 0
362 &pshufw ("mm2","mm0",0x0d); # 7, 6, 3, 2
363 &movz ("edx",&HB("eax")); # 1
364 &mov ("edx",&DWP(3,$tbl,"edx",8)); # 1
365 &shr ("eax",16); # 5, 4
366
367 &movz ($acc,&LB("ebx")); # 10
368 &xor ("ecx",&DWP(2,$tbl,$acc,8)); # 10
369 &pshufw ("mm6","mm4",0x08); # 13,12, 9, 8
370 &movz ($acc,&HB("ebx")); # 11
371 &xor ("edx",&DWP(1,$tbl,$acc,8)); # 11
372 &shr ("ebx",16); # 15,14
373
374 &movz ($acc,&HB("eax")); # 5
375 &xor ("ecx",&DWP(3,$tbl,$acc,8)); # 5
376 &movq ("mm3",QWP(16,$key));
377 &movz ($acc,&HB("ebx")); # 15
378 &xor ("ecx",&DWP(1,$tbl,$acc,8)); # 15
379 &movd ("mm0","ecx"); # t[0] collected
380
381 &movz ($acc,&LB("eax")); # 4
382 &mov ("ecx",&DWP(0,$tbl,$acc,8)); # 4
383 &movd ("eax","mm2"); # 7, 6, 3, 2
384 &movz ($acc,&LB("ebx")); # 14
385 &xor ("ecx",&DWP(2,$tbl,$acc,8)); # 14
386 &movd ("ebx","mm6"); # 13,12, 9, 8
387
388 &movz ($acc,&HB("eax")); # 3
389 &xor ("ecx",&DWP(1,$tbl,$acc,8)); # 3
390 &movz ($acc,&HB("ebx")); # 9
391 &xor ("ecx",&DWP(3,$tbl,$acc,8)); # 9
392 &movd ("mm1","ecx"); # t[1] collected
393
394 &movz ($acc,&LB("eax")); # 2
395 &mov ("ecx",&DWP(2,$tbl,$acc,8)); # 2
396 &shr ("eax",16); # 7, 6
397 &punpckldq ("mm0","mm1"); # t[0,1] collected
398 &movz ($acc,&LB("ebx")); # 8
399 &xor ("ecx",&DWP(0,$tbl,$acc,8)); # 8
400 &shr ("ebx",16); # 13,12
401
402 &movz ($acc,&HB("eax")); # 7
403 &xor ("ecx",&DWP(1,$tbl,$acc,8)); # 7
404 &pxor ("mm0","mm3");
405 &movz ("eax",&LB("eax")); # 6
406 &xor ("edx",&DWP(2,$tbl,"eax",8)); # 6
407 &pshufw ("mm1","mm0",0x08); # 5, 4, 1, 0
408 &movz ($acc,&HB("ebx")); # 13
409 &xor ("ecx",&DWP(3,$tbl,$acc,8)); # 13
410 &xor ("ecx",&DWP(24,$key)); # t[2]
411 &movd ("mm4","ecx"); # t[2] collected
412 &movz ("ebx",&LB("ebx")); # 12
413 &xor ("edx",&DWP(0,$tbl,"ebx",8)); # 12
414 &shr ("ecx",16);
415 &movd ("eax","mm1"); # 5, 4, 1, 0
416 &mov ("ebx",&DWP(28,$key)); # t[3]
417 &xor ("ebx","edx");
418 &movd ("mm5","ebx"); # t[3] collected
419 &and ("ebx",0xffff0000);
420 &or ("ebx","ecx");
421
422 &punpckldq ("mm4","mm5"); # t[2,3] collected
423}
424
425######################################################################
426# "Compact" block function
427######################################################################
428
429sub enccompact()
430{ my $Fn = mov;
431 while ($#_>5) { pop(@_); $Fn=sub{}; }
432 my ($i,$te,@s)=@_;
433 my $tmp = $key;
434 my $out = $i==3?$s[0]:$acc;
435
436 # $Fn is used in first compact round and its purpose is to
437 # void restoration of some values from stack, so that after
438 # 4xenccompact with extra argument $key value is left there...
439 if ($i==3) { &$Fn ($key,$__key); }##%edx
440 else { &mov ($out,$s[0]); }
441 &and ($out,0xFF);
442 if ($i==1) { &shr ($s[0],16); }#%ebx[1]
443 if ($i==2) { &shr ($s[0],24); }#%ecx[2]
444 &movz ($out,&BP(-128,$te,$out,1));
445
446 if ($i==3) { $tmp=$s[1]; }##%eax
447 &movz ($tmp,&HB($s[1]));
448 &movz ($tmp,&BP(-128,$te,$tmp,1));
449 &shl ($tmp,8);
450 &xor ($out,$tmp);
451
452 if ($i==3) { $tmp=$s[2]; &mov ($s[1],$__s0); }##%ebx
453 else { &mov ($tmp,$s[2]);
454 &shr ($tmp,16); }
455 if ($i==2) { &and ($s[1],0xFF); }#%edx[2]
456 &and ($tmp,0xFF);
457 &movz ($tmp,&BP(-128,$te,$tmp,1));
458 &shl ($tmp,16);
459 &xor ($out,$tmp);
460
461 if ($i==3) { $tmp=$s[3]; &mov ($s[2],$__s1); }##%ecx
462 elsif($i==2){ &movz ($tmp,&HB($s[3])); }#%ebx[2]
463 else { &mov ($tmp,$s[3]);
464 &shr ($tmp,24); }
465 &movz ($tmp,&BP(-128,$te,$tmp,1));
466 &shl ($tmp,24);
467 &xor ($out,$tmp);
468 if ($i<2) { &mov (&DWP(4+4*$i,"esp"),$out); }
469 if ($i==3) { &mov ($s[3],$acc); }
470 &comment();
471}
472
473sub enctransform()
474{ my @s = ($s0,$s1,$s2,$s3);
475 my $i = shift;
476 my $tmp = $tbl;
477 my $r2 = $key ;
478
479 &mov ($acc,$s[$i]);
480 &and ($acc,0x80808080);
481 &mov ($tmp,$acc);
482 &shr ($tmp,7);
483 &lea ($r2,&DWP(0,$s[$i],$s[$i]));
484 &sub ($acc,$tmp);
485 &and ($r2,0xfefefefe);
486 &and ($acc,0x1b1b1b1b);
487 &mov ($tmp,$s[$i]);
488 &xor ($acc,$r2); # r2
489
490 &xor ($s[$i],$acc); # r0 ^ r2
491 &rotl ($s[$i],24);
492 &xor ($s[$i],$acc) # ROTATE(r2^r0,24) ^ r2
493 &rotr ($tmp,16);
494 &xor ($s[$i],$tmp);
495 &rotr ($tmp,8);
496 &xor ($s[$i],$tmp);
497}
498
499&function_begin_B("_x86_AES_encrypt_compact");
500 # note that caller is expected to allocate stack frame for me!
501 &mov ($__key,$key); # save key
502
503 &xor ($s0,&DWP(0,$key)); # xor with key
504 &xor ($s1,&DWP(4,$key));
505 &xor ($s2,&DWP(8,$key));
506 &xor ($s3,&DWP(12,$key));
507
508 &mov ($acc,&DWP(240,$key)); # load key->rounds
509 &lea ($acc,&DWP(-2,$acc,$acc));
510 &lea ($acc,&DWP(0,$key,$acc,8));
511 &mov ($__end,$acc); # end of key schedule
512
513 # prefetch Te4
514 &mov ($key,&DWP(0-128,$tbl));
515 &mov ($acc,&DWP(32-128,$tbl));
516 &mov ($key,&DWP(64-128,$tbl));
517 &mov ($acc,&DWP(96-128,$tbl));
518 &mov ($key,&DWP(128-128,$tbl));
519 &mov ($acc,&DWP(160-128,$tbl));
520 &mov ($key,&DWP(192-128,$tbl));
521 &mov ($acc,&DWP(224-128,$tbl));
522
523 &set_label("loop",16);
524
525 &enccompact(0,$tbl,$s0,$s1,$s2,$s3,1);
526 &enccompact(1,$tbl,$s1,$s2,$s3,$s0,1);
527 &enccompact(2,$tbl,$s2,$s3,$s0,$s1,1);
528 &enccompact(3,$tbl,$s3,$s0,$s1,$s2,1);
529 &enctransform(2);
530 &enctransform(3);
531 &enctransform(0);
532 &enctransform(1);
533 &mov ($key,$__key);
534 &mov ($tbl,$__tbl);
535 &add ($key,16); # advance rd_key
536 &xor ($s0,&DWP(0,$key));
537 &xor ($s1,&DWP(4,$key));
538 &xor ($s2,&DWP(8,$key));
539 &xor ($s3,&DWP(12,$key));
540
541 &cmp ($key,$__end);
542 &mov ($__key,$key);
543 &jb (&label("loop"));
544
545 &enccompact(0,$tbl,$s0,$s1,$s2,$s3);
546 &enccompact(1,$tbl,$s1,$s2,$s3,$s0);
547 &enccompact(2,$tbl,$s2,$s3,$s0,$s1);
548 &enccompact(3,$tbl,$s3,$s0,$s1,$s2);
549
550 &xor ($s0,&DWP(16,$key));
551 &xor ($s1,&DWP(20,$key));
552 &xor ($s2,&DWP(24,$key));
553 &xor ($s3,&DWP(28,$key));
554
555 &ret ();
556&function_end_B("_x86_AES_encrypt_compact");
557
558######################################################################
559# "Compact" SSE block function.
560######################################################################
561#
562# Performance is not actually extraordinary in comparison to pure
563# x86 code. In particular encrypt performance is virtually the same.
564# Decrypt performance on the other hand is 15-20% better on newer
565# µ-archs [but we're thankful for *any* improvement here], and ~50%
566# better on PIII:-) And additionally on the pros side this code
567# eliminates redundant references to stack and thus relieves/
568# minimizes the pressure on the memory bus.
569#
570# MMX register layout lsb
571# +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
572# | mm4 | mm0 |
573# +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
574# | s3 | s2 | s1 | s0 |
575# +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
576# |15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0|
577# +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
578#
579# Indexes translate as s[N/4]>>(8*(N%4)), e.g. 5 means s1>>8.
580# In this terms encryption and decryption "compact" permutation
581# matrices can be depicted as following:
582#
583# encryption lsb # decryption lsb
584# +----++----+----+----+----+ # +----++----+----+----+----+
585# | t0 || 15 | 10 | 5 | 0 | # | t0 || 7 | 10 | 13 | 0 |
586# +----++----+----+----+----+ # +----++----+----+----+----+
587# | t1 || 3 | 14 | 9 | 4 | # | t1 || 11 | 14 | 1 | 4 |
588# +----++----+----+----+----+ # +----++----+----+----+----+
589# | t2 || 7 | 2 | 13 | 8 | # | t2 || 15 | 2 | 5 | 8 |
590# +----++----+----+----+----+ # +----++----+----+----+----+
591# | t3 || 11 | 6 | 1 | 12 | # | t3 || 3 | 6 | 9 | 12 |
592# +----++----+----+----+----+ # +----++----+----+----+----+
593#
594######################################################################
595# Why not xmm registers? Short answer. It was actually tested and
596# was not any faster, but *contrary*, most notably on Intel CPUs.
597# Longer answer. Main advantage of using mm registers is that movd
598# latency is lower, especially on Intel P4. While arithmetic
599# instructions are twice as many, they can be scheduled every cycle
600# and not every second one when they are operating on xmm register,
601# so that "arithmetic throughput" remains virtually the same. And
602# finally the code can be executed even on elder SSE-only CPUs:-)
603
604sub sse_enccompact()
605{
606 &pshufw ("mm1","mm0",0x08); # 5, 4, 1, 0
607 &pshufw ("mm5","mm4",0x0d); # 15,14,11,10
608 &movd ("eax","mm1"); # 5, 4, 1, 0
609 &movd ("ebx","mm5"); # 15,14,11,10
610
611 &movz ($acc,&LB("eax")); # 0
612 &movz ("ecx",&BP(-128,$tbl,$acc,1)); # 0
613 &pshufw ("mm2","mm0",0x0d); # 7, 6, 3, 2
614 &movz ("edx",&HB("eax")); # 1
615 &movz ("edx",&BP(-128,$tbl,"edx",1)); # 1
616 &shl ("edx",8); # 1
617 &shr ("eax",16); # 5, 4
618
619 &movz ($acc,&LB("ebx")); # 10
620 &movz ($acc,&BP(-128,$tbl,$acc,1)); # 10
621 &shl ($acc,16); # 10
622 &or ("ecx",$acc); # 10
623 &pshufw ("mm6","mm4",0x08); # 13,12, 9, 8
624 &movz ($acc,&HB("ebx")); # 11
625 &movz ($acc,&BP(-128,$tbl,$acc,1)); # 11
626 &shl ($acc,24); # 11
627 &or ("edx",$acc); # 11
628 &shr ("ebx",16); # 15,14
629
630 &movz ($acc,&HB("eax")); # 5
631 &movz ($acc,&BP(-128,$tbl,$acc,1)); # 5
632 &shl ($acc,8); # 5
633 &or ("ecx",$acc); # 5
634 &movz ($acc,&HB("ebx")); # 15
635 &movz ($acc,&BP(-128,$tbl,$acc,1)); # 15
636 &shl ($acc,24); # 15
637 &or ("ecx",$acc); # 15
638 &movd ("mm0","ecx"); # t[0] collected
639
640 &movz ($acc,&LB("eax")); # 4
641 &movz ("ecx",&BP(-128,$tbl,$acc,1)); # 4
642 &movd ("eax","mm2"); # 7, 6, 3, 2
643 &movz ($acc,&LB("ebx")); # 14
644 &movz ($acc,&BP(-128,$tbl,$acc,1)); # 14
645 &shl ($acc,16); # 14
646 &or ("ecx",$acc); # 14
647
648 &movd ("ebx","mm6"); # 13,12, 9, 8
649 &movz ($acc,&HB("eax")); # 3
650 &movz ($acc,&BP(-128,$tbl,$acc,1)); # 3
651 &shl ($acc,24); # 3
652 &or ("ecx",$acc); # 3
653 &movz ($acc,&HB("ebx")); # 9
654 &movz ($acc,&BP(-128,$tbl,$acc,1)); # 9
655 &shl ($acc,8); # 9
656 &or ("ecx",$acc); # 9
657 &movd ("mm1","ecx"); # t[1] collected
658
659 &movz ($acc,&LB("ebx")); # 8
660 &movz ("ecx",&BP(-128,$tbl,$acc,1)); # 8
661 &shr ("ebx",16); # 13,12
662 &movz ($acc,&LB("eax")); # 2
663 &movz ($acc,&BP(-128,$tbl,$acc,1)); # 2
664 &shl ($acc,16); # 2
665 &or ("ecx",$acc); # 2
666 &shr ("eax",16); # 7, 6
667
668 &punpckldq ("mm0","mm1"); # t[0,1] collected
669
670 &movz ($acc,&HB("eax")); # 7
671 &movz ($acc,&BP(-128,$tbl,$acc,1)); # 7
672 &shl ($acc,24); # 7
673 &or ("ecx",$acc); # 7
674 &and ("eax",0xff); # 6
675 &movz ("eax",&BP(-128,$tbl,"eax",1)); # 6
676 &shl ("eax",16); # 6
677 &or ("edx","eax"); # 6
678 &movz ($acc,&HB("ebx")); # 13
679 &movz ($acc,&BP(-128,$tbl,$acc,1)); # 13
680 &shl ($acc,8); # 13
681 &or ("ecx",$acc); # 13
682 &movd ("mm4","ecx"); # t[2] collected
683 &and ("ebx",0xff); # 12
684 &movz ("ebx",&BP(-128,$tbl,"ebx",1)); # 12
685 &or ("edx","ebx"); # 12
686 &movd ("mm5","edx"); # t[3] collected
687
688 &punpckldq ("mm4","mm5"); # t[2,3] collected
689}
690
691 if (!$x86only) {
692&function_begin_B("_sse_AES_encrypt_compact");
693 &pxor ("mm0",&QWP(0,$key)); # 7, 6, 5, 4, 3, 2, 1, 0
694 &pxor ("mm4",&QWP(8,$key)); # 15,14,13,12,11,10, 9, 8
695
696 # note that caller is expected to allocate stack frame for me!
697 &mov ($acc,&DWP(240,$key)); # load key->rounds
698 &lea ($acc,&DWP(-2,$acc,$acc));
699 &lea ($acc,&DWP(0,$key,$acc,8));
700 &mov ($__end,$acc); # end of key schedule
701
702 &mov ($s0,0x1b1b1b1b); # magic constant
703 &mov (&DWP(8,"esp"),$s0);
704 &mov (&DWP(12,"esp"),$s0);
705
706 # prefetch Te4
707 &mov ($s0,&DWP(0-128,$tbl));
708 &mov ($s1,&DWP(32-128,$tbl));
709 &mov ($s2,&DWP(64-128,$tbl));
710 &mov ($s3,&DWP(96-128,$tbl));
711 &mov ($s0,&DWP(128-128,$tbl));
712 &mov ($s1,&DWP(160-128,$tbl));
713 &mov ($s2,&DWP(192-128,$tbl));
714 &mov ($s3,&DWP(224-128,$tbl));
715
716 &set_label("loop",16);
717 &sse_enccompact();
718 &add ($key,16);
719 &cmp ($key,$__end);
720 &ja (&label("out"));
721
722 &movq ("mm2",&QWP(8,"esp"));
723 &pxor ("mm3","mm3"); &pxor ("mm7","mm7");
724 &movq ("mm1","mm0"); &movq ("mm5","mm4"); # r0
725 &pcmpgtb("mm3","mm0"); &pcmpgtb("mm7","mm4");
726 &pand ("mm3","mm2"); &pand ("mm7","mm2");
727 &pshufw ("mm2","mm0",0xb1); &pshufw ("mm6","mm4",0xb1);# ROTATE(r0,16)
728 &paddb ("mm0","mm0"); &paddb ("mm4","mm4");
729 &pxor ("mm0","mm3"); &pxor ("mm4","mm7"); # = r2
730 &pshufw ("mm3","mm2",0xb1); &pshufw ("mm7","mm6",0xb1);# r0
731 &pxor ("mm1","mm0"); &pxor ("mm5","mm4"); # r0^r2
732 &pxor ("mm0","mm2"); &pxor ("mm4","mm6"); # ^= ROTATE(r0,16)
733
734 &movq ("mm2","mm3"); &movq ("mm6","mm7");
735 &pslld ("mm3",8); &pslld ("mm7",8);
736 &psrld ("mm2",24); &psrld ("mm6",24);
737 &pxor ("mm0","mm3"); &pxor ("mm4","mm7"); # ^= r0<<8
738 &pxor ("mm0","mm2"); &pxor ("mm4","mm6"); # ^= r0>>24
739
740 &movq ("mm3","mm1"); &movq ("mm7","mm5");
741 &movq ("mm2",&QWP(0,$key)); &movq ("mm6",&QWP(8,$key));
742 &psrld ("mm1",8); &psrld ("mm5",8);
743 &mov ($s0,&DWP(0-128,$tbl));
744 &pslld ("mm3",24); &pslld ("mm7",24);
745 &mov ($s1,&DWP(64-128,$tbl));
746 &pxor ("mm0","mm1"); &pxor ("mm4","mm5"); # ^= (r2^r0)<<8
747 &mov ($s2,&DWP(128-128,$tbl));
748 &pxor ("mm0","mm3"); &pxor ("mm4","mm7"); # ^= (r2^r0)>>24
749 &mov ($s3,&DWP(192-128,$tbl));
750
751 &pxor ("mm0","mm2"); &pxor ("mm4","mm6");
752 &jmp (&label("loop"));
753
754 &set_label("out",16);
755 &pxor ("mm0",&QWP(0,$key));
756 &pxor ("mm4",&QWP(8,$key));
757
758 &ret ();
759&function_end_B("_sse_AES_encrypt_compact");
760 }
761
762######################################################################
763# Vanilla block function.
764######################################################################
765
177sub encstep() 766sub encstep()
178{ my ($i,$te,@s) = @_; 767{ my ($i,$te,@s) = @_;
179 my $tmp = $key; 768 my $tmp = $key;
180 my $out = $i==3?$s[0]:$acc; 769 my $out = $i==3?$s[0]:$acc;
181 770
182 # lines marked with #%e?x[i] denote "reordered" instructions... 771 # lines marked with #%e?x[i] denote "reordered" instructions...
183 if ($i==3) { &mov ($key,&DWP(12,"esp")); }##%edx 772 if ($i==3) { &mov ($key,$__key); }##%edx
184 else { &mov ($out,$s[0]); 773 else { &mov ($out,$s[0]);
185 &and ($out,0xFF); } 774 &and ($out,0xFF); }
186 if ($i==1) { &shr ($s[0],16); }#%ebx[1] 775 if ($i==1) { &shr ($s[0],16); }#%ebx[1]
@@ -191,14 +780,14 @@ sub encstep()
191 &movz ($tmp,&HB($s[1])); 780 &movz ($tmp,&HB($s[1]));
192 &xor ($out,&DWP(3,$te,$tmp,8)); 781 &xor ($out,&DWP(3,$te,$tmp,8));
193 782
194 if ($i==3) { $tmp=$s[2]; &mov ($s[1],&DWP(4,"esp")); }##%ebx 783 if ($i==3) { $tmp=$s[2]; &mov ($s[1],$__s0); }##%ebx
195 else { &mov ($tmp,$s[2]); 784 else { &mov ($tmp,$s[2]);
196 &shr ($tmp,16); } 785 &shr ($tmp,16); }
197 if ($i==2) { &and ($s[1],0xFF); }#%edx[2] 786 if ($i==2) { &and ($s[1],0xFF); }#%edx[2]
198 &and ($tmp,0xFF); 787 &and ($tmp,0xFF);
199 &xor ($out,&DWP(2,$te,$tmp,8)); 788 &xor ($out,&DWP(2,$te,$tmp,8));
200 789
201 if ($i==3) { $tmp=$s[3]; &mov ($s[2],&DWP(8,"esp")); }##%ecx 790 if ($i==3) { $tmp=$s[3]; &mov ($s[2],$__s1); }##%ecx
202 elsif($i==2){ &movz ($tmp,&HB($s[3])); }#%ebx[2] 791 elsif($i==2){ &movz ($tmp,&HB($s[3])); }#%ebx[2]
203 else { &mov ($tmp,$s[3]); 792 else { &mov ($tmp,$s[3]);
204 &shr ($tmp,24) } 793 &shr ($tmp,24) }
@@ -213,7 +802,7 @@ sub enclast()
213 my $tmp = $key; 802 my $tmp = $key;
214 my $out = $i==3?$s[0]:$acc; 803 my $out = $i==3?$s[0]:$acc;
215 804
216 if ($i==3) { &mov ($key,&DWP(12,"esp")); }##%edx 805 if ($i==3) { &mov ($key,$__key); }##%edx
217 else { &mov ($out,$s[0]); } 806 else { &mov ($out,$s[0]); }
218 &and ($out,0xFF); 807 &and ($out,0xFF);
219 if ($i==1) { &shr ($s[0],16); }#%ebx[1] 808 if ($i==1) { &shr ($s[0],16); }#%ebx[1]
@@ -227,8 +816,8 @@ sub enclast()
227 &and ($tmp,0x0000ff00); 816 &and ($tmp,0x0000ff00);
228 &xor ($out,$tmp); 817 &xor ($out,$tmp);
229 818
230 if ($i==3) { $tmp=$s[2]; &mov ($s[1],&DWP(4,"esp")); }##%ebx 819 if ($i==3) { $tmp=$s[2]; &mov ($s[1],$__s0); }##%ebx
231 else { mov ($tmp,$s[2]); 820 else { &mov ($tmp,$s[2]);
232 &shr ($tmp,16); } 821 &shr ($tmp,16); }
233 if ($i==2) { &and ($s[1],0xFF); }#%edx[2] 822 if ($i==2) { &and ($s[1],0xFF); }#%edx[2]
234 &and ($tmp,0xFF); 823 &and ($tmp,0xFF);
@@ -236,7 +825,7 @@ sub enclast()
236 &and ($tmp,0x00ff0000); 825 &and ($tmp,0x00ff0000);
237 &xor ($out,$tmp); 826 &xor ($out,$tmp);
238 827
239 if ($i==3) { $tmp=$s[3]; &mov ($s[2],&DWP(8,"esp")); }##%ecx 828 if ($i==3) { $tmp=$s[3]; &mov ($s[2],$__s1); }##%ecx
240 elsif($i==2){ &movz ($tmp,&HB($s[3])); }#%ebx[2] 829 elsif($i==2){ &movz ($tmp,&HB($s[3])); }#%ebx[2]
241 else { &mov ($tmp,$s[3]); 830 else { &mov ($tmp,$s[3]);
242 &shr ($tmp,24); } 831 &shr ($tmp,24); }
@@ -247,9 +836,6 @@ sub enclast()
247 if ($i==3) { &mov ($s[3],$acc); } 836 if ($i==3) { &mov ($s[3],$acc); }
248} 837}
249 838
250sub _data_word() { my $i; while(defined($i=shift)) { &data_word($i,$i); } }
251
252&public_label("AES_Te");
253&function_begin_B("_x86_AES_encrypt"); 839&function_begin_B("_x86_AES_encrypt");
254 if ($vertical_spin) { 840 if ($vertical_spin) {
255 # I need high parts of volatile registers to be accessible... 841 # I need high parts of volatile registers to be accessible...
@@ -258,7 +844,7 @@ sub _data_word() { my $i; while(defined($i=shift)) { &data_word($i,$i); } }
258 } 844 }
259 845
260 # note that caller is expected to allocate stack frame for me! 846 # note that caller is expected to allocate stack frame for me!
261 &mov (&DWP(12,"esp"),$key); # save key 847 &mov ($__key,$key); # save key
262 848
263 &xor ($s0,&DWP(0,$key)); # xor with key 849 &xor ($s0,&DWP(0,$key)); # xor with key
264 &xor ($s1,&DWP(4,$key)); 850 &xor ($s1,&DWP(4,$key));
@@ -270,24 +856,24 @@ sub _data_word() { my $i; while(defined($i=shift)) { &data_word($i,$i); } }
270 if ($small_footprint) { 856 if ($small_footprint) {
271 &lea ($acc,&DWP(-2,$acc,$acc)); 857 &lea ($acc,&DWP(-2,$acc,$acc));
272 &lea ($acc,&DWP(0,$key,$acc,8)); 858 &lea ($acc,&DWP(0,$key,$acc,8));
273 &mov (&DWP(16,"esp"),$acc); # end of key schedule 859 &mov ($__end,$acc); # end of key schedule
274 &align (4); 860
275 &set_label("loop"); 861 &set_label("loop",16);
276 if ($vertical_spin) { 862 if ($vertical_spin) {
277 &encvert("ebp",$s0,$s1,$s2,$s3); 863 &encvert($tbl,$s0,$s1,$s2,$s3);
278 } else { 864 } else {
279 &encstep(0,"ebp",$s0,$s1,$s2,$s3); 865 &encstep(0,$tbl,$s0,$s1,$s2,$s3);
280 &encstep(1,"ebp",$s1,$s2,$s3,$s0); 866 &encstep(1,$tbl,$s1,$s2,$s3,$s0);
281 &encstep(2,"ebp",$s2,$s3,$s0,$s1); 867 &encstep(2,$tbl,$s2,$s3,$s0,$s1);
282 &encstep(3,"ebp",$s3,$s0,$s1,$s2); 868 &encstep(3,$tbl,$s3,$s0,$s1,$s2);
283 } 869 }
284 &add ($key,16); # advance rd_key 870 &add ($key,16); # advance rd_key
285 &xor ($s0,&DWP(0,$key)); 871 &xor ($s0,&DWP(0,$key));
286 &xor ($s1,&DWP(4,$key)); 872 &xor ($s1,&DWP(4,$key));
287 &xor ($s2,&DWP(8,$key)); 873 &xor ($s2,&DWP(8,$key));
288 &xor ($s3,&DWP(12,$key)); 874 &xor ($s3,&DWP(12,$key));
289 &cmp ($key,&DWP(16,"esp")); 875 &cmp ($key,$__end);
290 &mov (&DWP(12,"esp"),$key); 876 &mov ($__key,$key);
291 &jb (&label("loop")); 877 &jb (&label("loop"));
292 } 878 }
293 else { 879 else {
@@ -296,15 +882,15 @@ sub _data_word() { my $i; while(defined($i=shift)) { &data_word($i,$i); } }
296 &cmp ($acc,12); 882 &cmp ($acc,12);
297 &jle (&label("12rounds")); 883 &jle (&label("12rounds"));
298 884
299 &set_label("14rounds"); 885 &set_label("14rounds",4);
300 for ($i=1;$i<3;$i++) { 886 for ($i=1;$i<3;$i++) {
301 if ($vertical_spin) { 887 if ($vertical_spin) {
302 &encvert("ebp",$s0,$s1,$s2,$s3); 888 &encvert($tbl,$s0,$s1,$s2,$s3);
303 } else { 889 } else {
304 &encstep(0,"ebp",$s0,$s1,$s2,$s3); 890 &encstep(0,$tbl,$s0,$s1,$s2,$s3);
305 &encstep(1,"ebp",$s1,$s2,$s3,$s0); 891 &encstep(1,$tbl,$s1,$s2,$s3,$s0);
306 &encstep(2,"ebp",$s2,$s3,$s0,$s1); 892 &encstep(2,$tbl,$s2,$s3,$s0,$s1);
307 &encstep(3,"ebp",$s3,$s0,$s1,$s2); 893 &encstep(3,$tbl,$s3,$s0,$s1,$s2);
308 } 894 }
309 &xor ($s0,&DWP(16*$i+0,$key)); 895 &xor ($s0,&DWP(16*$i+0,$key));
310 &xor ($s1,&DWP(16*$i+4,$key)); 896 &xor ($s1,&DWP(16*$i+4,$key));
@@ -312,16 +898,16 @@ sub _data_word() { my $i; while(defined($i=shift)) { &data_word($i,$i); } }
312 &xor ($s3,&DWP(16*$i+12,$key)); 898 &xor ($s3,&DWP(16*$i+12,$key));
313 } 899 }
314 &add ($key,32); 900 &add ($key,32);
315 &mov (&DWP(12,"esp"),$key); # advance rd_key 901 &mov ($__key,$key); # advance rd_key
316 &set_label("12rounds"); 902 &set_label("12rounds",4);
317 for ($i=1;$i<3;$i++) { 903 for ($i=1;$i<3;$i++) {
318 if ($vertical_spin) { 904 if ($vertical_spin) {
319 &encvert("ebp",$s0,$s1,$s2,$s3); 905 &encvert($tbl,$s0,$s1,$s2,$s3);
320 } else { 906 } else {
321 &encstep(0,"ebp",$s0,$s1,$s2,$s3); 907 &encstep(0,$tbl,$s0,$s1,$s2,$s3);
322 &encstep(1,"ebp",$s1,$s2,$s3,$s0); 908 &encstep(1,$tbl,$s1,$s2,$s3,$s0);
323 &encstep(2,"ebp",$s2,$s3,$s0,$s1); 909 &encstep(2,$tbl,$s2,$s3,$s0,$s1);
324 &encstep(3,"ebp",$s3,$s0,$s1,$s2); 910 &encstep(3,$tbl,$s3,$s0,$s1,$s2);
325 } 911 }
326 &xor ($s0,&DWP(16*$i+0,$key)); 912 &xor ($s0,&DWP(16*$i+0,$key));
327 &xor ($s1,&DWP(16*$i+4,$key)); 913 &xor ($s1,&DWP(16*$i+4,$key));
@@ -329,16 +915,16 @@ sub _data_word() { my $i; while(defined($i=shift)) { &data_word($i,$i); } }
329 &xor ($s3,&DWP(16*$i+12,$key)); 915 &xor ($s3,&DWP(16*$i+12,$key));
330 } 916 }
331 &add ($key,32); 917 &add ($key,32);
332 &mov (&DWP(12,"esp"),$key); # advance rd_key 918 &mov ($__key,$key); # advance rd_key
333 &set_label("10rounds"); 919 &set_label("10rounds",4);
334 for ($i=1;$i<10;$i++) { 920 for ($i=1;$i<10;$i++) {
335 if ($vertical_spin) { 921 if ($vertical_spin) {
336 &encvert("ebp",$s0,$s1,$s2,$s3); 922 &encvert($tbl,$s0,$s1,$s2,$s3);
337 } else { 923 } else {
338 &encstep(0,"ebp",$s0,$s1,$s2,$s3); 924 &encstep(0,$tbl,$s0,$s1,$s2,$s3);
339 &encstep(1,"ebp",$s1,$s2,$s3,$s0); 925 &encstep(1,$tbl,$s1,$s2,$s3,$s0);
340 &encstep(2,"ebp",$s2,$s3,$s0,$s1); 926 &encstep(2,$tbl,$s2,$s3,$s0,$s1);
341 &encstep(3,"ebp",$s3,$s0,$s1,$s2); 927 &encstep(3,$tbl,$s3,$s0,$s1,$s2);
342 } 928 }
343 &xor ($s0,&DWP(16*$i+0,$key)); 929 &xor ($s0,&DWP(16*$i+0,$key));
344 &xor ($s1,&DWP(16*$i+4,$key)); 930 &xor ($s1,&DWP(16*$i+4,$key));
@@ -352,10 +938,10 @@ sub _data_word() { my $i; while(defined($i=shift)) { &data_word($i,$i); } }
352 &mov ($s1="ebx",$key="edi"); 938 &mov ($s1="ebx",$key="edi");
353 &mov ($s2="ecx",$acc="esi"); 939 &mov ($s2="ecx",$acc="esi");
354 } 940 }
355 &enclast(0,"ebp",$s0,$s1,$s2,$s3); 941 &enclast(0,$tbl,$s0,$s1,$s2,$s3);
356 &enclast(1,"ebp",$s1,$s2,$s3,$s0); 942 &enclast(1,$tbl,$s1,$s2,$s3,$s0);
357 &enclast(2,"ebp",$s2,$s3,$s0,$s1); 943 &enclast(2,$tbl,$s2,$s3,$s0,$s1);
358 &enclast(3,"ebp",$s3,$s0,$s1,$s2); 944 &enclast(3,$tbl,$s3,$s0,$s1,$s2);
359 945
360 &add ($key,$small_footprint?16:160); 946 &add ($key,$small_footprint?16:160);
361 &xor ($s0,&DWP(0,$key)); 947 &xor ($s0,&DWP(0,$key));
@@ -430,38 +1016,198 @@ sub _data_word() { my $i; while(defined($i=shift)) { &data_word($i,$i); } }
430 &_data_word(0xdabfbf65, 0x31e6e6d7, 0xc6424284, 0xb86868d0); 1016 &_data_word(0xdabfbf65, 0x31e6e6d7, 0xc6424284, 0xb86868d0);
431 &_data_word(0xc3414182, 0xb0999929, 0x772d2d5a, 0x110f0f1e); 1017 &_data_word(0xc3414182, 0xb0999929, 0x772d2d5a, 0x110f0f1e);
432 &_data_word(0xcbb0b07b, 0xfc5454a8, 0xd6bbbb6d, 0x3a16162c); 1018 &_data_word(0xcbb0b07b, 0xfc5454a8, 0xd6bbbb6d, 0x3a16162c);
1019
1020#Te4 # four copies of Te4 to choose from to avoid L1 aliasing
1021 &data_byte(0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5);
1022 &data_byte(0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76);
1023 &data_byte(0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0);
1024 &data_byte(0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0);
1025 &data_byte(0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc);
1026 &data_byte(0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15);
1027 &data_byte(0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a);
1028 &data_byte(0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75);
1029 &data_byte(0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0);
1030 &data_byte(0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84);
1031 &data_byte(0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b);
1032 &data_byte(0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf);
1033 &data_byte(0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85);
1034 &data_byte(0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8);
1035 &data_byte(0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5);
1036 &data_byte(0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2);
1037 &data_byte(0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17);
1038 &data_byte(0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73);
1039 &data_byte(0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88);
1040 &data_byte(0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb);
1041 &data_byte(0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c);
1042 &data_byte(0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79);
1043 &data_byte(0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9);
1044 &data_byte(0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08);
1045 &data_byte(0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6);
1046 &data_byte(0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a);
1047 &data_byte(0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e);
1048 &data_byte(0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e);
1049 &data_byte(0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94);
1050 &data_byte(0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf);
1051 &data_byte(0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68);
1052 &data_byte(0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16);
1053
1054 &data_byte(0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5);
1055 &data_byte(0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76);
1056 &data_byte(0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0);
1057 &data_byte(0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0);
1058 &data_byte(0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc);
1059 &data_byte(0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15);
1060 &data_byte(0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a);
1061 &data_byte(0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75);
1062 &data_byte(0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0);
1063 &data_byte(0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84);
1064 &data_byte(0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b);
1065 &data_byte(0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf);
1066 &data_byte(0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85);
1067 &data_byte(0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8);
1068 &data_byte(0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5);
1069 &data_byte(0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2);
1070 &data_byte(0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17);
1071 &data_byte(0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73);
1072 &data_byte(0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88);
1073 &data_byte(0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb);
1074 &data_byte(0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c);
1075 &data_byte(0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79);
1076 &data_byte(0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9);
1077 &data_byte(0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08);
1078 &data_byte(0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6);
1079 &data_byte(0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a);
1080 &data_byte(0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e);
1081 &data_byte(0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e);
1082 &data_byte(0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94);
1083 &data_byte(0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf);
1084 &data_byte(0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68);
1085 &data_byte(0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16);
1086
1087 &data_byte(0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5);
1088 &data_byte(0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76);
1089 &data_byte(0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0);
1090 &data_byte(0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0);
1091 &data_byte(0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc);
1092 &data_byte(0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15);
1093 &data_byte(0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a);
1094 &data_byte(0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75);
1095 &data_byte(0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0);
1096 &data_byte(0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84);
1097 &data_byte(0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b);
1098 &data_byte(0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf);
1099 &data_byte(0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85);
1100 &data_byte(0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8);
1101 &data_byte(0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5);
1102 &data_byte(0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2);
1103 &data_byte(0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17);
1104 &data_byte(0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73);
1105 &data_byte(0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88);
1106 &data_byte(0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb);
1107 &data_byte(0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c);
1108 &data_byte(0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79);
1109 &data_byte(0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9);
1110 &data_byte(0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08);
1111 &data_byte(0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6);
1112 &data_byte(0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a);
1113 &data_byte(0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e);
1114 &data_byte(0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e);
1115 &data_byte(0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94);
1116 &data_byte(0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf);
1117 &data_byte(0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68);
1118 &data_byte(0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16);
1119
1120 &data_byte(0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5);
1121 &data_byte(0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76);
1122 &data_byte(0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0);
1123 &data_byte(0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0);
1124 &data_byte(0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc);
1125 &data_byte(0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15);
1126 &data_byte(0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a);
1127 &data_byte(0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75);
1128 &data_byte(0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0);
1129 &data_byte(0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84);
1130 &data_byte(0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b);
1131 &data_byte(0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf);
1132 &data_byte(0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85);
1133 &data_byte(0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8);
1134 &data_byte(0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5);
1135 &data_byte(0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2);
1136 &data_byte(0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17);
1137 &data_byte(0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73);
1138 &data_byte(0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88);
1139 &data_byte(0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb);
1140 &data_byte(0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c);
1141 &data_byte(0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79);
1142 &data_byte(0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9);
1143 &data_byte(0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08);
1144 &data_byte(0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6);
1145 &data_byte(0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a);
1146 &data_byte(0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e);
1147 &data_byte(0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e);
1148 &data_byte(0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94);
1149 &data_byte(0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf);
1150 &data_byte(0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68);
1151 &data_byte(0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16);
433#rcon: 1152#rcon:
434 &data_word(0x00000001, 0x00000002, 0x00000004, 0x00000008); 1153 &data_word(0x00000001, 0x00000002, 0x00000004, 0x00000008);
435 &data_word(0x00000010, 0x00000020, 0x00000040, 0x00000080); 1154 &data_word(0x00000010, 0x00000020, 0x00000040, 0x00000080);
436 &data_word(0x0000001b, 0x00000036, 0, 0, 0, 0, 0, 0); 1155 &data_word(0x0000001b, 0x00000036, 0x00000000, 0x00000000);
1156 &data_word(0x00000000, 0x00000000, 0x00000000, 0x00000000);
437&function_end_B("_x86_AES_encrypt"); 1157&function_end_B("_x86_AES_encrypt");
438 1158
439# void AES_encrypt (const void *inp,void *out,const AES_KEY *key); 1159# void AES_encrypt (const void *inp,void *out,const AES_KEY *key);
440&public_label("AES_Te");
441&function_begin("AES_encrypt"); 1160&function_begin("AES_encrypt");
442 &mov ($acc,&wparam(0)); # load inp 1161 &mov ($acc,&wparam(0)); # load inp
443 &mov ($key,&wparam(2)); # load key 1162 &mov ($key,&wparam(2)); # load key
444 1163
445 &mov ($s0,"esp"); 1164 &mov ($s0,"esp");
446 &sub ("esp",24); 1165 &sub ("esp",36);
447 &and ("esp",-64); 1166 &and ("esp",-64); # align to cache-line
448 &add ("esp",4); 1167
449 &mov (&DWP(16,"esp"),$s0); 1168 # place stack frame just "above" the key schedule
1169 &lea ($s1,&DWP(-64-63,$key));
1170 &sub ($s1,"esp");
1171 &neg ($s1);
1172 &and ($s1,0x3C0); # modulo 1024, but aligned to cache-line
1173 &sub ("esp",$s1);
1174 &add ("esp",4); # 4 is reserved for caller's return address
1175 &mov ($_esp,$s0); # save stack pointer
450 1176
451 &call (&label("pic_point")); # make it PIC! 1177 &call (&label("pic_point")); # make it PIC!
452 &set_label("pic_point"); 1178 &set_label("pic_point");
453 &blindpop("ebp"); 1179 &blindpop($tbl);
454 &lea ("ebp",&DWP(&label("AES_Te")."-".&label("pic_point"),"ebp")); 1180 &picmeup($s0,"OPENSSL_ia32cap_P",$tbl,&label("pic_point")) if (!$x86only);
455 1181 &lea ($tbl,&DWP(&label("AES_Te")."-".&label("pic_point"),$tbl));
1182
1183 # pick Te4 copy which can't "overlap" with stack frame or key schedule
1184 &lea ($s1,&DWP(768-4,"esp"));
1185 &sub ($s1,$tbl);
1186 &and ($s1,0x300);
1187 &lea ($tbl,&DWP(2048+128,$tbl,$s1));
1188
1189 if (!$x86only) {
1190 &bt (&DWP(0,$s0),25); # check for SSE bit
1191 &jnc (&label("x86"));
1192
1193 &movq ("mm0",&QWP(0,$acc));
1194 &movq ("mm4",&QWP(8,$acc));
1195 &call ("_sse_AES_encrypt_compact");
1196 &mov ("esp",$_esp); # restore stack pointer
1197 &mov ($acc,&wparam(1)); # load out
1198 &movq (&QWP(0,$acc),"mm0"); # write output data
1199 &movq (&QWP(8,$acc),"mm4");
1200 &emms ();
1201 &function_end_A();
1202 }
1203 &set_label("x86",16);
1204 &mov ($_tbl,$tbl);
456 &mov ($s0,&DWP(0,$acc)); # load input data 1205 &mov ($s0,&DWP(0,$acc)); # load input data
457 &mov ($s1,&DWP(4,$acc)); 1206 &mov ($s1,&DWP(4,$acc));
458 &mov ($s2,&DWP(8,$acc)); 1207 &mov ($s2,&DWP(8,$acc));
459 &mov ($s3,&DWP(12,$acc)); 1208 &mov ($s3,&DWP(12,$acc));
460 1209 &call ("_x86_AES_encrypt_compact");
461 &call ("_x86_AES_encrypt"); 1210 &mov ("esp",$_esp); # restore stack pointer
462
463 &mov ("esp",&DWP(16,"esp"));
464
465 &mov ($acc,&wparam(1)); # load out 1211 &mov ($acc,&wparam(1)); # load out
466 &mov (&DWP(0,$acc),$s0); # write output data 1212 &mov (&DWP(0,$acc),$s0); # write output data
467 &mov (&DWP(4,$acc),$s1); 1213 &mov (&DWP(4,$acc),$s1);
@@ -469,7 +1215,370 @@ sub _data_word() { my $i; while(defined($i=shift)) { &data_word($i,$i); } }
469 &mov (&DWP(12,$acc),$s3); 1215 &mov (&DWP(12,$acc),$s3);
470&function_end("AES_encrypt"); 1216&function_end("AES_encrypt");
471 1217
472#------------------------------------------------------------------# 1218#--------------------------------------------------------------------#
1219
1220######################################################################
1221# "Compact" block function
1222######################################################################
1223
1224sub deccompact()
1225{ my $Fn = mov;
1226 while ($#_>5) { pop(@_); $Fn=sub{}; }
1227 my ($i,$td,@s)=@_;
1228 my $tmp = $key;
1229 my $out = $i==3?$s[0]:$acc;
1230
1231 # $Fn is used in first compact round and its purpose is to
1232 # void restoration of some values from stack, so that after
1233 # 4xdeccompact with extra argument $key, $s0 and $s1 values
1234 # are left there...
1235 if($i==3) { &$Fn ($key,$__key); }
1236 else { &mov ($out,$s[0]); }
1237 &and ($out,0xFF);
1238 &movz ($out,&BP(-128,$td,$out,1));
1239
1240 if ($i==3) { $tmp=$s[1]; }
1241 &movz ($tmp,&HB($s[1]));
1242 &movz ($tmp,&BP(-128,$td,$tmp,1));
1243 &shl ($tmp,8);
1244 &xor ($out,$tmp);
1245
1246 if ($i==3) { $tmp=$s[2]; &mov ($s[1],$acc); }
1247 else { mov ($tmp,$s[2]); }
1248 &shr ($tmp,16);
1249 &and ($tmp,0xFF);
1250 &movz ($tmp,&BP(-128,$td,$tmp,1));
1251 &shl ($tmp,16);
1252 &xor ($out,$tmp);
1253
1254 if ($i==3) { $tmp=$s[3]; &$Fn ($s[2],$__s1); }
1255 else { &mov ($tmp,$s[3]); }
1256 &shr ($tmp,24);
1257 &movz ($tmp,&BP(-128,$td,$tmp,1));
1258 &shl ($tmp,24);
1259 &xor ($out,$tmp);
1260 if ($i<2) { &mov (&DWP(4+4*$i,"esp"),$out); }
1261 if ($i==3) { &$Fn ($s[3],$__s0); }
1262}
1263
1264# must be called with 2,3,0,1 as argument sequence!!!
1265sub dectransform()
1266{ my @s = ($s0,$s1,$s2,$s3);
1267 my $i = shift;
1268 my $tmp = $key;
1269 my $tp2 = @s[($i+2)%4]; $tp2 = @s[2] if ($i==1);
1270 my $tp4 = @s[($i+3)%4]; $tp4 = @s[3] if ($i==1);
1271 my $tp8 = $tbl;
1272
1273 &mov ($acc,$s[$i]);
1274 &and ($acc,0x80808080);
1275 &mov ($tmp,$acc);
1276 &shr ($tmp,7);
1277 &lea ($tp2,&DWP(0,$s[$i],$s[$i]));
1278 &sub ($acc,$tmp);
1279 &and ($tp2,0xfefefefe);
1280 &and ($acc,0x1b1b1b1b);
1281 &xor ($acc,$tp2);
1282 &mov ($tp2,$acc);
1283
1284 &and ($acc,0x80808080);
1285 &mov ($tmp,$acc);
1286 &shr ($tmp,7);
1287 &lea ($tp4,&DWP(0,$tp2,$tp2));
1288 &sub ($acc,$tmp);
1289 &and ($tp4,0xfefefefe);
1290 &and ($acc,0x1b1b1b1b);
1291 &xor ($tp2,$s[$i]); # tp2^tp1
1292 &xor ($acc,$tp4);
1293 &mov ($tp4,$acc);
1294
1295 &and ($acc,0x80808080);
1296 &mov ($tmp,$acc);
1297 &shr ($tmp,7);
1298 &lea ($tp8,&DWP(0,$tp4,$tp4));
1299 &sub ($acc,$tmp);
1300 &and ($tp8,0xfefefefe);
1301 &and ($acc,0x1b1b1b1b);
1302 &xor ($tp4,$s[$i]); # tp4^tp1
1303 &rotl ($s[$i],8); # = ROTATE(tp1,8)
1304 &xor ($tp8,$acc);
1305
1306 &xor ($s[$i],$tp2);
1307 &xor ($tp2,$tp8);
1308 &rotl ($tp2,24);
1309 &xor ($s[$i],$tp4);
1310 &xor ($tp4,$tp8);
1311 &rotl ($tp4,16);
1312 &xor ($s[$i],$tp8); # ^= tp8^(tp4^tp1)^(tp2^tp1)
1313 &rotl ($tp8,8);
1314 &xor ($s[$i],$tp2); # ^= ROTATE(tp8^tp2^tp1,24)
1315 &xor ($s[$i],$tp4); # ^= ROTATE(tp8^tp4^tp1,16)
1316 &mov ($s[0],$__s0) if($i==2); #prefetch $s0
1317 &mov ($s[1],$__s1) if($i==3); #prefetch $s1
1318 &mov ($s[2],$__s2) if($i==1);
1319 &xor ($s[$i],$tp8); # ^= ROTATE(tp8,8)
1320
1321 &mov ($s[3],$__s3) if($i==1);
1322 &mov (&DWP(4+4*$i,"esp"),$s[$i]) if($i>=2);
1323}
1324
1325&function_begin_B("_x86_AES_decrypt_compact");
1326 # note that caller is expected to allocate stack frame for me!
1327 &mov ($__key,$key); # save key
1328
1329 &xor ($s0,&DWP(0,$key)); # xor with key
1330 &xor ($s1,&DWP(4,$key));
1331 &xor ($s2,&DWP(8,$key));
1332 &xor ($s3,&DWP(12,$key));
1333
1334 &mov ($acc,&DWP(240,$key)); # load key->rounds
1335
1336 &lea ($acc,&DWP(-2,$acc,$acc));
1337 &lea ($acc,&DWP(0,$key,$acc,8));
1338 &mov ($__end,$acc); # end of key schedule
1339
1340 # prefetch Td4
1341 &mov ($key,&DWP(0-128,$tbl));
1342 &mov ($acc,&DWP(32-128,$tbl));
1343 &mov ($key,&DWP(64-128,$tbl));
1344 &mov ($acc,&DWP(96-128,$tbl));
1345 &mov ($key,&DWP(128-128,$tbl));
1346 &mov ($acc,&DWP(160-128,$tbl));
1347 &mov ($key,&DWP(192-128,$tbl));
1348 &mov ($acc,&DWP(224-128,$tbl));
1349
1350 &set_label("loop",16);
1351
1352 &deccompact(0,$tbl,$s0,$s3,$s2,$s1,1);
1353 &deccompact(1,$tbl,$s1,$s0,$s3,$s2,1);
1354 &deccompact(2,$tbl,$s2,$s1,$s0,$s3,1);
1355 &deccompact(3,$tbl,$s3,$s2,$s1,$s0,1);
1356 &dectransform(2);
1357 &dectransform(3);
1358 &dectransform(0);
1359 &dectransform(1);
1360 &mov ($key,$__key);
1361 &mov ($tbl,$__tbl);
1362 &add ($key,16); # advance rd_key
1363 &xor ($s0,&DWP(0,$key));
1364 &xor ($s1,&DWP(4,$key));
1365 &xor ($s2,&DWP(8,$key));
1366 &xor ($s3,&DWP(12,$key));
1367
1368 &cmp ($key,$__end);
1369 &mov ($__key,$key);
1370 &jb (&label("loop"));
1371
1372 &deccompact(0,$tbl,$s0,$s3,$s2,$s1);
1373 &deccompact(1,$tbl,$s1,$s0,$s3,$s2);
1374 &deccompact(2,$tbl,$s2,$s1,$s0,$s3);
1375 &deccompact(3,$tbl,$s3,$s2,$s1,$s0);
1376
1377 &xor ($s0,&DWP(16,$key));
1378 &xor ($s1,&DWP(20,$key));
1379 &xor ($s2,&DWP(24,$key));
1380 &xor ($s3,&DWP(28,$key));
1381
1382 &ret ();
1383&function_end_B("_x86_AES_decrypt_compact");
1384
1385######################################################################
1386# "Compact" SSE block function.
1387######################################################################
1388
1389sub sse_deccompact()
1390{
1391 &pshufw ("mm1","mm0",0x0c); # 7, 6, 1, 0
1392 &movd ("eax","mm1"); # 7, 6, 1, 0
1393
1394 &pshufw ("mm5","mm4",0x09); # 13,12,11,10
1395 &movz ($acc,&LB("eax")); # 0
1396 &movz ("ecx",&BP(-128,$tbl,$acc,1)); # 0
1397 &movd ("ebx","mm5"); # 13,12,11,10
1398 &movz ("edx",&HB("eax")); # 1
1399 &movz ("edx",&BP(-128,$tbl,"edx",1)); # 1
1400 &shl ("edx",8); # 1
1401
1402 &pshufw ("mm2","mm0",0x06); # 3, 2, 5, 4
1403 &movz ($acc,&LB("ebx")); # 10
1404 &movz ($acc,&BP(-128,$tbl,$acc,1)); # 10
1405 &shl ($acc,16); # 10
1406 &or ("ecx",$acc); # 10
1407 &shr ("eax",16); # 7, 6
1408 &movz ($acc,&HB("ebx")); # 11
1409 &movz ($acc,&BP(-128,$tbl,$acc,1)); # 11
1410 &shl ($acc,24); # 11
1411 &or ("edx",$acc); # 11
1412 &shr ("ebx",16); # 13,12
1413
1414 &pshufw ("mm6","mm4",0x03); # 9, 8,15,14
1415 &movz ($acc,&HB("eax")); # 7
1416 &movz ($acc,&BP(-128,$tbl,$acc,1)); # 7
1417 &shl ($acc,24); # 7
1418 &or ("ecx",$acc); # 7
1419 &movz ($acc,&HB("ebx")); # 13
1420 &movz ($acc,&BP(-128,$tbl,$acc,1)); # 13
1421 &shl ($acc,8); # 13
1422 &or ("ecx",$acc); # 13
1423 &movd ("mm0","ecx"); # t[0] collected
1424
1425 &movz ($acc,&LB("eax")); # 6
1426 &movd ("eax","mm2"); # 3, 2, 5, 4
1427 &movz ("ecx",&BP(-128,$tbl,$acc,1)); # 6
1428 &shl ("ecx",16); # 6
1429 &movz ($acc,&LB("ebx")); # 12
1430 &movd ("ebx","mm6"); # 9, 8,15,14
1431 &movz ($acc,&BP(-128,$tbl,$acc,1)); # 12
1432 &or ("ecx",$acc); # 12
1433
1434 &movz ($acc,&LB("eax")); # 4
1435 &movz ($acc,&BP(-128,$tbl,$acc,1)); # 4
1436 &or ("edx",$acc); # 4
1437 &movz ($acc,&LB("ebx")); # 14
1438 &movz ($acc,&BP(-128,$tbl,$acc,1)); # 14
1439 &shl ($acc,16); # 14
1440 &or ("edx",$acc); # 14
1441 &movd ("mm1","edx"); # t[1] collected
1442
1443 &movz ($acc,&HB("eax")); # 5
1444 &movz ("edx",&BP(-128,$tbl,$acc,1)); # 5
1445 &shl ("edx",8); # 5
1446 &movz ($acc,&HB("ebx")); # 15
1447 &shr ("eax",16); # 3, 2
1448 &movz ($acc,&BP(-128,$tbl,$acc,1)); # 15
1449 &shl ($acc,24); # 15
1450 &or ("edx",$acc); # 15
1451 &shr ("ebx",16); # 9, 8
1452
1453 &punpckldq ("mm0","mm1"); # t[0,1] collected
1454
1455 &movz ($acc,&HB("ebx")); # 9
1456 &movz ($acc,&BP(-128,$tbl,$acc,1)); # 9
1457 &shl ($acc,8); # 9
1458 &or ("ecx",$acc); # 9
1459 &and ("ebx",0xff); # 8
1460 &movz ("ebx",&BP(-128,$tbl,"ebx",1)); # 8
1461 &or ("edx","ebx"); # 8
1462 &movz ($acc,&LB("eax")); # 2
1463 &movz ($acc,&BP(-128,$tbl,$acc,1)); # 2
1464 &shl ($acc,16); # 2
1465 &or ("edx",$acc); # 2
1466 &movd ("mm4","edx"); # t[2] collected
1467 &movz ("eax",&HB("eax")); # 3
1468 &movz ("eax",&BP(-128,$tbl,"eax",1)); # 3
1469 &shl ("eax",24); # 3
1470 &or ("ecx","eax"); # 3
1471 &movd ("mm5","ecx"); # t[3] collected
1472
1473 &punpckldq ("mm4","mm5"); # t[2,3] collected
1474}
1475
1476 if (!$x86only) {
1477&function_begin_B("_sse_AES_decrypt_compact");
1478 &pxor ("mm0",&QWP(0,$key)); # 7, 6, 5, 4, 3, 2, 1, 0
1479 &pxor ("mm4",&QWP(8,$key)); # 15,14,13,12,11,10, 9, 8
1480
1481 # note that caller is expected to allocate stack frame for me!
1482 &mov ($acc,&DWP(240,$key)); # load key->rounds
1483 &lea ($acc,&DWP(-2,$acc,$acc));
1484 &lea ($acc,&DWP(0,$key,$acc,8));
1485 &mov ($__end,$acc); # end of key schedule
1486
1487 &mov ($s0,0x1b1b1b1b); # magic constant
1488 &mov (&DWP(8,"esp"),$s0);
1489 &mov (&DWP(12,"esp"),$s0);
1490
1491 # prefetch Td4
1492 &mov ($s0,&DWP(0-128,$tbl));
1493 &mov ($s1,&DWP(32-128,$tbl));
1494 &mov ($s2,&DWP(64-128,$tbl));
1495 &mov ($s3,&DWP(96-128,$tbl));
1496 &mov ($s0,&DWP(128-128,$tbl));
1497 &mov ($s1,&DWP(160-128,$tbl));
1498 &mov ($s2,&DWP(192-128,$tbl));
1499 &mov ($s3,&DWP(224-128,$tbl));
1500
1501 &set_label("loop",16);
1502 &sse_deccompact();
1503 &add ($key,16);
1504 &cmp ($key,$__end);
1505 &ja (&label("out"));
1506
1507 # ROTATE(x^y,N) == ROTATE(x,N)^ROTATE(y,N)
1508 &movq ("mm3","mm0"); &movq ("mm7","mm4");
1509 &movq ("mm2","mm0",1); &movq ("mm6","mm4",1);
1510 &movq ("mm1","mm0"); &movq ("mm5","mm4");
1511 &pshufw ("mm0","mm0",0xb1); &pshufw ("mm4","mm4",0xb1);# = ROTATE(tp0,16)
1512 &pslld ("mm2",8); &pslld ("mm6",8);
1513 &psrld ("mm3",8); &psrld ("mm7",8);
1514 &pxor ("mm0","mm2"); &pxor ("mm4","mm6"); # ^= tp0<<8
1515 &pxor ("mm0","mm3"); &pxor ("mm4","mm7"); # ^= tp0>>8
1516 &pslld ("mm2",16); &pslld ("mm6",16);
1517 &psrld ("mm3",16); &psrld ("mm7",16);
1518 &pxor ("mm0","mm2"); &pxor ("mm4","mm6"); # ^= tp0<<24
1519 &pxor ("mm0","mm3"); &pxor ("mm4","mm7"); # ^= tp0>>24
1520
1521 &movq ("mm3",&QWP(8,"esp"));
1522 &pxor ("mm2","mm2"); &pxor ("mm6","mm6");
1523 &pcmpgtb("mm2","mm1"); &pcmpgtb("mm6","mm5");
1524 &pand ("mm2","mm3"); &pand ("mm6","mm3");
1525 &paddb ("mm1","mm1"); &paddb ("mm5","mm5");
1526 &pxor ("mm1","mm2"); &pxor ("mm5","mm6"); # tp2
1527 &movq ("mm3","mm1"); &movq ("mm7","mm5");
1528 &movq ("mm2","mm1"); &movq ("mm6","mm5");
1529 &pxor ("mm0","mm1"); &pxor ("mm4","mm5"); # ^= tp2
1530 &pslld ("mm3",24); &pslld ("mm7",24);
1531 &psrld ("mm2",8); &psrld ("mm6",8);
1532 &pxor ("mm0","mm3"); &pxor ("mm4","mm7"); # ^= tp2<<24
1533 &pxor ("mm0","mm2"); &pxor ("mm4","mm6"); # ^= tp2>>8
1534
1535 &movq ("mm2",&QWP(8,"esp"));
1536 &pxor ("mm3","mm3"); &pxor ("mm7","mm7");
1537 &pcmpgtb("mm3","mm1"); &pcmpgtb("mm7","mm5");
1538 &pand ("mm3","mm2"); &pand ("mm7","mm2");
1539 &paddb ("mm1","mm1"); &paddb ("mm5","mm5");
1540 &pxor ("mm1","mm3"); &pxor ("mm5","mm7"); # tp4
1541 &pshufw ("mm3","mm1",0xb1); &pshufw ("mm7","mm5",0xb1);
1542 &pxor ("mm0","mm1"); &pxor ("mm4","mm5"); # ^= tp4
1543 &pxor ("mm0","mm3"); &pxor ("mm4","mm7"); # ^= ROTATE(tp4,16)
1544
1545 &pxor ("mm3","mm3"); &pxor ("mm7","mm7");
1546 &pcmpgtb("mm3","mm1"); &pcmpgtb("mm7","mm5");
1547 &pand ("mm3","mm2"); &pand ("mm7","mm2");
1548 &paddb ("mm1","mm1"); &paddb ("mm5","mm5");
1549 &pxor ("mm1","mm3"); &pxor ("mm5","mm7"); # tp8
1550 &pxor ("mm0","mm1"); &pxor ("mm4","mm5"); # ^= tp8
1551 &movq ("mm3","mm1"); &movq ("mm7","mm5");
1552 &pshufw ("mm2","mm1",0xb1); &pshufw ("mm6","mm5",0xb1);
1553 &pxor ("mm0","mm2"); &pxor ("mm4","mm6"); # ^= ROTATE(tp8,16)
1554 &pslld ("mm1",8); &pslld ("mm5",8);
1555 &psrld ("mm3",8); &psrld ("mm7",8);
1556 &movq ("mm2",&QWP(0,$key)); &movq ("mm6",&QWP(8,$key));
1557 &pxor ("mm0","mm1"); &pxor ("mm4","mm5"); # ^= tp8<<8
1558 &pxor ("mm0","mm3"); &pxor ("mm4","mm7"); # ^= tp8>>8
1559 &mov ($s0,&DWP(0-128,$tbl));
1560 &pslld ("mm1",16); &pslld ("mm5",16);
1561 &mov ($s1,&DWP(64-128,$tbl));
1562 &psrld ("mm3",16); &psrld ("mm7",16);
1563 &mov ($s2,&DWP(128-128,$tbl));
1564 &pxor ("mm0","mm1"); &pxor ("mm4","mm5"); # ^= tp8<<24
1565 &mov ($s3,&DWP(192-128,$tbl));
1566 &pxor ("mm0","mm3"); &pxor ("mm4","mm7"); # ^= tp8>>24
1567
1568 &pxor ("mm0","mm2"); &pxor ("mm4","mm6");
1569 &jmp (&label("loop"));
1570
1571 &set_label("out",16);
1572 &pxor ("mm0",&QWP(0,$key));
1573 &pxor ("mm4",&QWP(8,$key));
1574
1575 &ret ();
1576&function_end_B("_sse_AES_decrypt_compact");
1577 }
1578
1579######################################################################
1580# Vanilla block function.
1581######################################################################
473 1582
474sub decstep() 1583sub decstep()
475{ my ($i,$td,@s) = @_; 1584{ my ($i,$td,@s) = @_;
@@ -480,7 +1589,7 @@ sub decstep()
480 # optimal... or rather that all attempts to reorder didn't 1589 # optimal... or rather that all attempts to reorder didn't
481 # result in better performance [which by the way is not a 1590 # result in better performance [which by the way is not a
482 # bit lower than ecryption]. 1591 # bit lower than ecryption].
483 if($i==3) { &mov ($key,&DWP(12,"esp")); } 1592 if($i==3) { &mov ($key,$__key); }
484 else { &mov ($out,$s[0]); } 1593 else { &mov ($out,$s[0]); }
485 &and ($out,0xFF); 1594 &and ($out,0xFF);
486 &mov ($out,&DWP(0,$td,$out,8)); 1595 &mov ($out,&DWP(0,$td,$out,8));
@@ -495,12 +1604,12 @@ sub decstep()
495 &and ($tmp,0xFF); 1604 &and ($tmp,0xFF);
496 &xor ($out,&DWP(2,$td,$tmp,8)); 1605 &xor ($out,&DWP(2,$td,$tmp,8));
497 1606
498 if ($i==3) { $tmp=$s[3]; &mov ($s[2],&DWP(8,"esp")); } 1607 if ($i==3) { $tmp=$s[3]; &mov ($s[2],$__s1); }
499 else { &mov ($tmp,$s[3]); } 1608 else { &mov ($tmp,$s[3]); }
500 &shr ($tmp,24); 1609 &shr ($tmp,24);
501 &xor ($out,&DWP(1,$td,$tmp,8)); 1610 &xor ($out,&DWP(1,$td,$tmp,8));
502 if ($i<2) { &mov (&DWP(4+4*$i,"esp"),$out); } 1611 if ($i<2) { &mov (&DWP(4+4*$i,"esp"),$out); }
503 if ($i==3) { &mov ($s[3],&DWP(4,"esp")); } 1612 if ($i==3) { &mov ($s[3],$__s0); }
504 &comment(); 1613 &comment();
505} 1614}
506 1615
@@ -509,14 +1618,24 @@ sub declast()
509 my $tmp = $key; 1618 my $tmp = $key;
510 my $out = $i==3?$s[0]:$acc; 1619 my $out = $i==3?$s[0]:$acc;
511 1620
512 if($i==3) { &mov ($key,&DWP(12,"esp")); } 1621 if($i==0) { &lea ($td,&DWP(2048+128,$td));
1622 &mov ($tmp,&DWP(0-128,$td));
1623 &mov ($acc,&DWP(32-128,$td));
1624 &mov ($tmp,&DWP(64-128,$td));
1625 &mov ($acc,&DWP(96-128,$td));
1626 &mov ($tmp,&DWP(128-128,$td));
1627 &mov ($acc,&DWP(160-128,$td));
1628 &mov ($tmp,&DWP(192-128,$td));
1629 &mov ($acc,&DWP(224-128,$td));
1630 &lea ($td,&DWP(-128,$td)); }
1631 if($i==3) { &mov ($key,$__key); }
513 else { &mov ($out,$s[0]); } 1632 else { &mov ($out,$s[0]); }
514 &and ($out,0xFF); 1633 &and ($out,0xFF);
515 &movz ($out,&BP(2048,$td,$out,1)); 1634 &movz ($out,&BP(0,$td,$out,1));
516 1635
517 if ($i==3) { $tmp=$s[1]; } 1636 if ($i==3) { $tmp=$s[1]; }
518 &movz ($tmp,&HB($s[1])); 1637 &movz ($tmp,&HB($s[1]));
519 &movz ($tmp,&BP(2048,$td,$tmp,1)); 1638 &movz ($tmp,&BP(0,$td,$tmp,1));
520 &shl ($tmp,8); 1639 &shl ($tmp,8);
521 &xor ($out,$tmp); 1640 &xor ($out,$tmp);
522 1641
@@ -524,24 +1643,24 @@ sub declast()
524 else { mov ($tmp,$s[2]); } 1643 else { mov ($tmp,$s[2]); }
525 &shr ($tmp,16); 1644 &shr ($tmp,16);
526 &and ($tmp,0xFF); 1645 &and ($tmp,0xFF);
527 &movz ($tmp,&BP(2048,$td,$tmp,1)); 1646 &movz ($tmp,&BP(0,$td,$tmp,1));
528 &shl ($tmp,16); 1647 &shl ($tmp,16);
529 &xor ($out,$tmp); 1648 &xor ($out,$tmp);
530 1649
531 if ($i==3) { $tmp=$s[3]; &mov ($s[2],&DWP(8,"esp")); } 1650 if ($i==3) { $tmp=$s[3]; &mov ($s[2],$__s1); }
532 else { &mov ($tmp,$s[3]); } 1651 else { &mov ($tmp,$s[3]); }
533 &shr ($tmp,24); 1652 &shr ($tmp,24);
534 &movz ($tmp,&BP(2048,$td,$tmp,1)); 1653 &movz ($tmp,&BP(0,$td,$tmp,1));
535 &shl ($tmp,24); 1654 &shl ($tmp,24);
536 &xor ($out,$tmp); 1655 &xor ($out,$tmp);
537 if ($i<2) { &mov (&DWP(4+4*$i,"esp"),$out); } 1656 if ($i<2) { &mov (&DWP(4+4*$i,"esp"),$out); }
538 if ($i==3) { &mov ($s[3],&DWP(4,"esp")); } 1657 if ($i==3) { &mov ($s[3],$__s0);
1658 &lea ($td,&DWP(-2048,$td)); }
539} 1659}
540 1660
541&public_label("AES_Td");
542&function_begin_B("_x86_AES_decrypt"); 1661&function_begin_B("_x86_AES_decrypt");
543 # note that caller is expected to allocate stack frame for me! 1662 # note that caller is expected to allocate stack frame for me!
544 &mov (&DWP(12,"esp"),$key); # save key 1663 &mov ($__key,$key); # save key
545 1664
546 &xor ($s0,&DWP(0,$key)); # xor with key 1665 &xor ($s0,&DWP(0,$key)); # xor with key
547 &xor ($s1,&DWP(4,$key)); 1666 &xor ($s1,&DWP(4,$key));
@@ -553,20 +1672,19 @@ sub declast()
553 if ($small_footprint) { 1672 if ($small_footprint) {
554 &lea ($acc,&DWP(-2,$acc,$acc)); 1673 &lea ($acc,&DWP(-2,$acc,$acc));
555 &lea ($acc,&DWP(0,$key,$acc,8)); 1674 &lea ($acc,&DWP(0,$key,$acc,8));
556 &mov (&DWP(16,"esp"),$acc); # end of key schedule 1675 &mov ($__end,$acc); # end of key schedule
557 &align (4); 1676 &set_label("loop",16);
558 &set_label("loop"); 1677 &decstep(0,$tbl,$s0,$s3,$s2,$s1);
559 &decstep(0,"ebp",$s0,$s3,$s2,$s1); 1678 &decstep(1,$tbl,$s1,$s0,$s3,$s2);
560 &decstep(1,"ebp",$s1,$s0,$s3,$s2); 1679 &decstep(2,$tbl,$s2,$s1,$s0,$s3);
561 &decstep(2,"ebp",$s2,$s1,$s0,$s3); 1680 &decstep(3,$tbl,$s3,$s2,$s1,$s0);
562 &decstep(3,"ebp",$s3,$s2,$s1,$s0);
563 &add ($key,16); # advance rd_key 1681 &add ($key,16); # advance rd_key
564 &xor ($s0,&DWP(0,$key)); 1682 &xor ($s0,&DWP(0,$key));
565 &xor ($s1,&DWP(4,$key)); 1683 &xor ($s1,&DWP(4,$key));
566 &xor ($s2,&DWP(8,$key)); 1684 &xor ($s2,&DWP(8,$key));
567 &xor ($s3,&DWP(12,$key)); 1685 &xor ($s3,&DWP(12,$key));
568 &cmp ($key,&DWP(16,"esp")); 1686 &cmp ($key,$__end);
569 &mov (&DWP(12,"esp"),$key); 1687 &mov ($__key,$key);
570 &jb (&label("loop")); 1688 &jb (&label("loop"));
571 } 1689 }
572 else { 1690 else {
@@ -575,38 +1693,38 @@ sub declast()
575 &cmp ($acc,12); 1693 &cmp ($acc,12);
576 &jle (&label("12rounds")); 1694 &jle (&label("12rounds"));
577 1695
578 &set_label("14rounds"); 1696 &set_label("14rounds",4);
579 for ($i=1;$i<3;$i++) { 1697 for ($i=1;$i<3;$i++) {
580 &decstep(0,"ebp",$s0,$s3,$s2,$s1); 1698 &decstep(0,$tbl,$s0,$s3,$s2,$s1);
581 &decstep(1,"ebp",$s1,$s0,$s3,$s2); 1699 &decstep(1,$tbl,$s1,$s0,$s3,$s2);
582 &decstep(2,"ebp",$s2,$s1,$s0,$s3); 1700 &decstep(2,$tbl,$s2,$s1,$s0,$s3);
583 &decstep(3,"ebp",$s3,$s2,$s1,$s0); 1701 &decstep(3,$tbl,$s3,$s2,$s1,$s0);
584 &xor ($s0,&DWP(16*$i+0,$key)); 1702 &xor ($s0,&DWP(16*$i+0,$key));
585 &xor ($s1,&DWP(16*$i+4,$key)); 1703 &xor ($s1,&DWP(16*$i+4,$key));
586 &xor ($s2,&DWP(16*$i+8,$key)); 1704 &xor ($s2,&DWP(16*$i+8,$key));
587 &xor ($s3,&DWP(16*$i+12,$key)); 1705 &xor ($s3,&DWP(16*$i+12,$key));
588 } 1706 }
589 &add ($key,32); 1707 &add ($key,32);
590 &mov (&DWP(12,"esp"),$key); # advance rd_key 1708 &mov ($__key,$key); # advance rd_key
591 &set_label("12rounds"); 1709 &set_label("12rounds",4);
592 for ($i=1;$i<3;$i++) { 1710 for ($i=1;$i<3;$i++) {
593 &decstep(0,"ebp",$s0,$s3,$s2,$s1); 1711 &decstep(0,$tbl,$s0,$s3,$s2,$s1);
594 &decstep(1,"ebp",$s1,$s0,$s3,$s2); 1712 &decstep(1,$tbl,$s1,$s0,$s3,$s2);
595 &decstep(2,"ebp",$s2,$s1,$s0,$s3); 1713 &decstep(2,$tbl,$s2,$s1,$s0,$s3);
596 &decstep(3,"ebp",$s3,$s2,$s1,$s0); 1714 &decstep(3,$tbl,$s3,$s2,$s1,$s0);
597 &xor ($s0,&DWP(16*$i+0,$key)); 1715 &xor ($s0,&DWP(16*$i+0,$key));
598 &xor ($s1,&DWP(16*$i+4,$key)); 1716 &xor ($s1,&DWP(16*$i+4,$key));
599 &xor ($s2,&DWP(16*$i+8,$key)); 1717 &xor ($s2,&DWP(16*$i+8,$key));
600 &xor ($s3,&DWP(16*$i+12,$key)); 1718 &xor ($s3,&DWP(16*$i+12,$key));
601 } 1719 }
602 &add ($key,32); 1720 &add ($key,32);
603 &mov (&DWP(12,"esp"),$key); # advance rd_key 1721 &mov ($__key,$key); # advance rd_key
604 &set_label("10rounds"); 1722 &set_label("10rounds",4);
605 for ($i=1;$i<10;$i++) { 1723 for ($i=1;$i<10;$i++) {
606 &decstep(0,"ebp",$s0,$s3,$s2,$s1); 1724 &decstep(0,$tbl,$s0,$s3,$s2,$s1);
607 &decstep(1,"ebp",$s1,$s0,$s3,$s2); 1725 &decstep(1,$tbl,$s1,$s0,$s3,$s2);
608 &decstep(2,"ebp",$s2,$s1,$s0,$s3); 1726 &decstep(2,$tbl,$s2,$s1,$s0,$s3);
609 &decstep(3,"ebp",$s3,$s2,$s1,$s0); 1727 &decstep(3,$tbl,$s3,$s2,$s1,$s0);
610 &xor ($s0,&DWP(16*$i+0,$key)); 1728 &xor ($s0,&DWP(16*$i+0,$key));
611 &xor ($s1,&DWP(16*$i+4,$key)); 1729 &xor ($s1,&DWP(16*$i+4,$key));
612 &xor ($s2,&DWP(16*$i+8,$key)); 1730 &xor ($s2,&DWP(16*$i+8,$key));
@@ -614,10 +1732,10 @@ sub declast()
614 } 1732 }
615 } 1733 }
616 1734
617 &declast(0,"ebp",$s0,$s3,$s2,$s1); 1735 &declast(0,$tbl,$s0,$s3,$s2,$s1);
618 &declast(1,"ebp",$s1,$s0,$s3,$s2); 1736 &declast(1,$tbl,$s1,$s0,$s3,$s2);
619 &declast(2,"ebp",$s2,$s1,$s0,$s3); 1737 &declast(2,$tbl,$s2,$s1,$s0,$s3);
620 &declast(3,"ebp",$s3,$s2,$s1,$s0); 1738 &declast(3,$tbl,$s3,$s2,$s1,$s0);
621 1739
622 &add ($key,$small_footprint?16:160); 1740 &add ($key,$small_footprint?16:160);
623 &xor ($s0,&DWP(0,$key)); 1741 &xor ($s0,&DWP(0,$key));
@@ -692,7 +1810,107 @@ sub declast()
692 &_data_word(0x72c31d16, 0x0c25e2bc, 0x8b493c28, 0x41950dff); 1810 &_data_word(0x72c31d16, 0x0c25e2bc, 0x8b493c28, 0x41950dff);
693 &_data_word(0x7101a839, 0xdeb30c08, 0x9ce4b4d8, 0x90c15664); 1811 &_data_word(0x7101a839, 0xdeb30c08, 0x9ce4b4d8, 0x90c15664);
694 &_data_word(0x6184cb7b, 0x70b632d5, 0x745c6c48, 0x4257b8d0); 1812 &_data_word(0x6184cb7b, 0x70b632d5, 0x745c6c48, 0x4257b8d0);
695#Td4: 1813
1814#Td4: # four copies of Td4 to choose from to avoid L1 aliasing
1815 &data_byte(0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38);
1816 &data_byte(0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb);
1817 &data_byte(0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87);
1818 &data_byte(0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb);
1819 &data_byte(0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d);
1820 &data_byte(0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e);
1821 &data_byte(0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2);
1822 &data_byte(0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25);
1823 &data_byte(0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16);
1824 &data_byte(0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92);
1825 &data_byte(0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda);
1826 &data_byte(0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84);
1827 &data_byte(0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a);
1828 &data_byte(0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06);
1829 &data_byte(0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02);
1830 &data_byte(0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b);
1831 &data_byte(0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea);
1832 &data_byte(0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73);
1833 &data_byte(0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85);
1834 &data_byte(0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e);
1835 &data_byte(0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89);
1836 &data_byte(0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b);
1837 &data_byte(0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20);
1838 &data_byte(0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4);
1839 &data_byte(0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31);
1840 &data_byte(0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f);
1841 &data_byte(0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d);
1842 &data_byte(0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef);
1843 &data_byte(0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0);
1844 &data_byte(0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61);
1845 &data_byte(0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26);
1846 &data_byte(0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d);
1847
1848 &data_byte(0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38);
1849 &data_byte(0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb);
1850 &data_byte(0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87);
1851 &data_byte(0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb);
1852 &data_byte(0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d);
1853 &data_byte(0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e);
1854 &data_byte(0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2);
1855 &data_byte(0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25);
1856 &data_byte(0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16);
1857 &data_byte(0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92);
1858 &data_byte(0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda);
1859 &data_byte(0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84);
1860 &data_byte(0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a);
1861 &data_byte(0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06);
1862 &data_byte(0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02);
1863 &data_byte(0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b);
1864 &data_byte(0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea);
1865 &data_byte(0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73);
1866 &data_byte(0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85);
1867 &data_byte(0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e);
1868 &data_byte(0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89);
1869 &data_byte(0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b);
1870 &data_byte(0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20);
1871 &data_byte(0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4);
1872 &data_byte(0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31);
1873 &data_byte(0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f);
1874 &data_byte(0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d);
1875 &data_byte(0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef);
1876 &data_byte(0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0);
1877 &data_byte(0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61);
1878 &data_byte(0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26);
1879 &data_byte(0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d);
1880
1881 &data_byte(0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38);
1882 &data_byte(0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb);
1883 &data_byte(0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87);
1884 &data_byte(0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb);
1885 &data_byte(0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d);
1886 &data_byte(0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e);
1887 &data_byte(0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2);
1888 &data_byte(0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25);
1889 &data_byte(0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16);
1890 &data_byte(0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92);
1891 &data_byte(0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda);
1892 &data_byte(0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84);
1893 &data_byte(0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a);
1894 &data_byte(0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06);
1895 &data_byte(0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02);
1896 &data_byte(0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b);
1897 &data_byte(0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea);
1898 &data_byte(0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73);
1899 &data_byte(0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85);
1900 &data_byte(0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e);
1901 &data_byte(0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89);
1902 &data_byte(0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b);
1903 &data_byte(0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20);
1904 &data_byte(0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4);
1905 &data_byte(0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31);
1906 &data_byte(0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f);
1907 &data_byte(0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d);
1908 &data_byte(0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef);
1909 &data_byte(0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0);
1910 &data_byte(0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61);
1911 &data_byte(0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26);
1912 &data_byte(0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d);
1913
696 &data_byte(0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38); 1914 &data_byte(0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38);
697 &data_byte(0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb); 1915 &data_byte(0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb);
698 &data_byte(0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87); 1916 &data_byte(0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87);
@@ -728,43 +1946,57 @@ sub declast()
728&function_end_B("_x86_AES_decrypt"); 1946&function_end_B("_x86_AES_decrypt");
729 1947
730# void AES_decrypt (const void *inp,void *out,const AES_KEY *key); 1948# void AES_decrypt (const void *inp,void *out,const AES_KEY *key);
731&public_label("AES_Td");
732&function_begin("AES_decrypt"); 1949&function_begin("AES_decrypt");
733 &mov ($acc,&wparam(0)); # load inp 1950 &mov ($acc,&wparam(0)); # load inp
734 &mov ($key,&wparam(2)); # load key 1951 &mov ($key,&wparam(2)); # load key
735 1952
736 &mov ($s0,"esp"); 1953 &mov ($s0,"esp");
737 &sub ("esp",24); 1954 &sub ("esp",36);
738 &and ("esp",-64); 1955 &and ("esp",-64); # align to cache-line
739 &add ("esp",4); 1956
740 &mov (&DWP(16,"esp"),$s0); 1957 # place stack frame just "above" the key schedule
1958 &lea ($s1,&DWP(-64-63,$key));
1959 &sub ($s1,"esp");
1960 &neg ($s1);
1961 &and ($s1,0x3C0); # modulo 1024, but aligned to cache-line
1962 &sub ("esp",$s1);
1963 &add ("esp",4); # 4 is reserved for caller's return address
1964 &mov ($_esp,$s0); # save stack pointer
741 1965
742 &call (&label("pic_point")); # make it PIC! 1966 &call (&label("pic_point")); # make it PIC!
743 &set_label("pic_point"); 1967 &set_label("pic_point");
744 &blindpop("ebp"); 1968 &blindpop($tbl);
745 &lea ("ebp",&DWP(&label("AES_Td")."-".&label("pic_point"),"ebp")); 1969 &picmeup($s0,"OPENSSL_ia32cap_P",$tbl,&label("pic_point")) if(!$x86only);
746 1970 &lea ($tbl,&DWP(&label("AES_Td")."-".&label("pic_point"),$tbl));
747 # prefetch Td4 1971
748 &lea ("ebp",&DWP(2048+128,"ebp")); 1972 # pick Td4 copy which can't "overlap" with stack frame or key schedule
749 &mov ($s0,&DWP(0-128,"ebp")); 1973 &lea ($s1,&DWP(768-4,"esp"));
750 &mov ($s1,&DWP(32-128,"ebp")); 1974 &sub ($s1,$tbl);
751 &mov ($s2,&DWP(64-128,"ebp")); 1975 &and ($s1,0x300);
752 &mov ($s3,&DWP(96-128,"ebp")); 1976 &lea ($tbl,&DWP(2048+128,$tbl,$s1));
753 &mov ($s0,&DWP(128-128,"ebp")); 1977
754 &mov ($s1,&DWP(160-128,"ebp")); 1978 if (!$x86only) {
755 &mov ($s2,&DWP(192-128,"ebp")); 1979 &bt (&DWP(0,$s0),25); # check for SSE bit
756 &mov ($s3,&DWP(224-128,"ebp")); 1980 &jnc (&label("x86"));
757 &lea ("ebp",&DWP(-2048-128,"ebp")); 1981
758 1982 &movq ("mm0",&QWP(0,$acc));
1983 &movq ("mm4",&QWP(8,$acc));
1984 &call ("_sse_AES_decrypt_compact");
1985 &mov ("esp",$_esp); # restore stack pointer
1986 &mov ($acc,&wparam(1)); # load out
1987 &movq (&QWP(0,$acc),"mm0"); # write output data
1988 &movq (&QWP(8,$acc),"mm4");
1989 &emms ();
1990 &function_end_A();
1991 }
1992 &set_label("x86",16);
1993 &mov ($_tbl,$tbl);
759 &mov ($s0,&DWP(0,$acc)); # load input data 1994 &mov ($s0,&DWP(0,$acc)); # load input data
760 &mov ($s1,&DWP(4,$acc)); 1995 &mov ($s1,&DWP(4,$acc));
761 &mov ($s2,&DWP(8,$acc)); 1996 &mov ($s2,&DWP(8,$acc));
762 &mov ($s3,&DWP(12,$acc)); 1997 &mov ($s3,&DWP(12,$acc));
763 1998 &call ("_x86_AES_decrypt_compact");
764 &call ("_x86_AES_decrypt"); 1999 &mov ("esp",$_esp); # restore stack pointer
765
766 &mov ("esp",&DWP(16,"esp"));
767
768 &mov ($acc,&wparam(1)); # load out 2000 &mov ($acc,&wparam(1)); # load out
769 &mov (&DWP(0,$acc),$s0); # write output data 2001 &mov (&DWP(0,$acc),$s0); # write output data
770 &mov (&DWP(4,$acc),$s1); 2002 &mov (&DWP(4,$acc),$s1);
@@ -777,126 +2009,136 @@ sub declast()
777# unsigned char *ivp,const int enc); 2009# unsigned char *ivp,const int enc);
778{ 2010{
779# stack frame layout 2011# stack frame layout
780# -4(%esp) 0(%esp) return address 2012# -4(%esp) # return address 0(%esp)
781# 0(%esp) 4(%esp) tmp1 2013# 0(%esp) # s0 backing store 4(%esp)
782# 4(%esp) 8(%esp) tmp2 2014# 4(%esp) # s1 backing store 8(%esp)
783# 8(%esp) 12(%esp) key 2015# 8(%esp) # s2 backing store 12(%esp)
784# 12(%esp) 16(%esp) end of key schedule 2016# 12(%esp) # s3 backing store 16(%esp)
785my $_esp=&DWP(16,"esp"); #saved %esp 2017# 16(%esp) # key backup 20(%esp)
786my $_inp=&DWP(20,"esp"); #copy of wparam(0) 2018# 20(%esp) # end of key schedule 24(%esp)
787my $_out=&DWP(24,"esp"); #copy of wparam(1) 2019# 24(%esp) # %ebp backup 28(%esp)
788my $_len=&DWP(28,"esp"); #copy of wparam(2) 2020# 28(%esp) # %esp backup
789my $_key=&DWP(32,"esp"); #copy of wparam(3) 2021my $_inp=&DWP(32,"esp"); # copy of wparam(0)
790my $_ivp=&DWP(36,"esp"); #copy of wparam(4) 2022my $_out=&DWP(36,"esp"); # copy of wparam(1)
791my $_tmp=&DWP(40,"esp"); #volatile variable 2023my $_len=&DWP(40,"esp"); # copy of wparam(2)
792my $ivec=&DWP(44,"esp"); #ivec[16] 2024my $_key=&DWP(44,"esp"); # copy of wparam(3)
793my $aes_key=&DWP(60,"esp"); #copy of aes_key 2025my $_ivp=&DWP(48,"esp"); # copy of wparam(4)
794my $mark=&DWP(60+240,"esp"); #copy of aes_key->rounds 2026my $_tmp=&DWP(52,"esp"); # volatile variable
795 2027#
796&public_label("AES_Te"); 2028my $ivec=&DWP(60,"esp"); # ivec[16]
797&public_label("AES_Td"); 2029my $aes_key=&DWP(76,"esp"); # copy of aes_key
2030my $mark=&DWP(76+240,"esp"); # copy of aes_key->rounds
2031
798&function_begin("AES_cbc_encrypt"); 2032&function_begin("AES_cbc_encrypt");
799 &mov ($s2 eq "ecx"? $s2 : "",&wparam(2)); # load len 2033 &mov ($s2 eq "ecx"? $s2 : "",&wparam(2)); # load len
800 &cmp ($s2,0); 2034 &cmp ($s2,0);
801 &je (&label("enc_out")); 2035 &je (&label("drop_out"));
802 2036
803 &call (&label("pic_point")); # make it PIC! 2037 &call (&label("pic_point")); # make it PIC!
804 &set_label("pic_point"); 2038 &set_label("pic_point");
805 &blindpop("ebp"); 2039 &blindpop($tbl);
806 2040 &picmeup($s0,"OPENSSL_ia32cap_P",$tbl,&label("pic_point")) if(!$x86only);
807 &pushf ();
808 &cld ();
809 2041
810 &cmp (&wparam(5),0); 2042 &cmp (&wparam(5),0);
811 &je (&label("DECRYPT")); 2043 &lea ($tbl,&DWP(&label("AES_Te")."-".&label("pic_point"),$tbl));
812 2044 &jne (&label("picked_te"));
813 &lea ("ebp",&DWP(&label("AES_Te")."-".&label("pic_point"),"ebp")); 2045 &lea ($tbl,&DWP(&label("AES_Td")."-".&label("AES_Te"),$tbl));
2046 &set_label("picked_te");
814 2047
815 # allocate aligned stack frame... 2048 # one can argue if this is required
816 &lea ($key,&DWP(-64-244,"esp")); 2049 &pushf ();
817 &and ($key,-64); 2050 &cld ();
818 2051
819 # ... and make sure it doesn't alias with AES_Te modulo 4096 2052 &cmp ($s2,$speed_limit);
820 &mov ($s0,"ebp"); 2053 &jb (&label("slow_way"));
821 &lea ($s1,&DWP(2048,"ebp")); 2054 &test ($s2,15);
822 &mov ($s3,$key); 2055 &jnz (&label("slow_way"));
2056 if (!$x86only) {
2057 &bt (&DWP(0,$s0),28); # check for hyper-threading bit
2058 &jc (&label("slow_way"));
2059 }
2060 # pre-allocate aligned stack frame...
2061 &lea ($acc,&DWP(-80-244,"esp"));
2062 &and ($acc,-64);
2063
2064 # ... and make sure it doesn't alias with $tbl modulo 4096
2065 &mov ($s0,$tbl);
2066 &lea ($s1,&DWP(2048+256,$tbl));
2067 &mov ($s3,$acc);
823 &and ($s0,0xfff); # s = %ebp&0xfff 2068 &and ($s0,0xfff); # s = %ebp&0xfff
824 &and ($s1,0xfff); # e = (%ebp+2048)&0xfff 2069 &and ($s1,0xfff); # e = (%ebp+2048+256)&0xfff
825 &and ($s3,0xfff); # p = %esp&0xfff 2070 &and ($s3,0xfff); # p = %esp&0xfff
826 2071
827 &cmp ($s3,$s1); # if (p>=e) %esp =- (p-e); 2072 &cmp ($s3,$s1); # if (p>=e) %esp =- (p-e);
828 &jb (&label("te_break_out")); 2073 &jb (&label("tbl_break_out"));
829 &sub ($s3,$s1); 2074 &sub ($s3,$s1);
830 &sub ($key,$s3); 2075 &sub ($acc,$s3);
831 &jmp (&label("te_ok")); 2076 &jmp (&label("tbl_ok"));
832 &set_label("te_break_out"); # else %esp -= (p-s)&0xfff + framesz; 2077 &set_label("tbl_break_out",4); # else %esp -= (p-s)&0xfff + framesz;
833 &sub ($s3,$s0); 2078 &sub ($s3,$s0);
834 &and ($s3,0xfff); 2079 &and ($s3,0xfff);
835 &add ($s3,64+256); 2080 &add ($s3,384);
836 &sub ($key,$s3); 2081 &sub ($acc,$s3);
837 &align (4); 2082 &set_label("tbl_ok",4);
838 &set_label("te_ok");
839
840 &mov ($s0,&wparam(0)); # load inp
841 &mov ($s1,&wparam(1)); # load out
842 &mov ($s3,&wparam(3)); # load key
843 &mov ($acc,&wparam(4)); # load ivp
844 2083
845 &exch ("esp",$key); 2084 &lea ($s3,&wparam(0)); # obtain pointer to parameter block
2085 &exch ("esp",$acc); # allocate stack frame
846 &add ("esp",4); # reserve for return address! 2086 &add ("esp",4); # reserve for return address!
847 &mov ($_esp,$key); # save %esp 2087 &mov ($_tbl,$tbl); # save %ebp
2088 &mov ($_esp,$acc); # save %esp
2089
2090 &mov ($s0,&DWP(0,$s3)); # load inp
2091 &mov ($s1,&DWP(4,$s3)); # load out
2092 #&mov ($s2,&DWP(8,$s3)); # load len
2093 &mov ($key,&DWP(12,$s3)); # load key
2094 &mov ($acc,&DWP(16,$s3)); # load ivp
2095 &mov ($s3,&DWP(20,$s3)); # load enc flag
848 2096
849 &mov ($_inp,$s0); # save copy of inp 2097 &mov ($_inp,$s0); # save copy of inp
850 &mov ($_out,$s1); # save copy of out 2098 &mov ($_out,$s1); # save copy of out
851 &mov ($_len,$s2); # save copy of len 2099 &mov ($_len,$s2); # save copy of len
852 &mov ($_key,$s3); # save copy of key 2100 &mov ($_key,$key); # save copy of key
853 &mov ($_ivp,$acc); # save copy of ivp 2101 &mov ($_ivp,$acc); # save copy of ivp
854 2102
855 &mov ($mark,0); # copy of aes_key->rounds = 0; 2103 &mov ($mark,0); # copy of aes_key->rounds = 0;
856 if ($compromise) {
857 &cmp ($s2,$compromise);
858 &jb (&label("skip_ecopy"));
859 }
860 # do we copy key schedule to stack? 2104 # do we copy key schedule to stack?
861 &mov ($s1 eq "ebx" ? $s1 : "",$s3); 2105 &mov ($s1 eq "ebx" ? $s1 : "",$key);
862 &mov ($s2 eq "ecx" ? $s2 : "",244/4); 2106 &mov ($s2 eq "ecx" ? $s2 : "",244/4);
863 &sub ($s1,"ebp"); 2107 &sub ($s1,$tbl);
864 &mov ("esi",$s3); 2108 &mov ("esi",$key);
865 &and ($s1,0xfff); 2109 &and ($s1,0xfff);
866 &lea ("edi",$aes_key); 2110 &lea ("edi",$aes_key);
867 &cmp ($s1,2048); 2111 &cmp ($s1,2048+256);
868 &jb (&label("do_ecopy")); 2112 &jb (&label("do_copy"));
869 &cmp ($s1,4096-244); 2113 &cmp ($s1,4096-244);
870 &jb (&label("skip_ecopy")); 2114 &jb (&label("skip_copy"));
871 &align (4); 2115 &set_label("do_copy",4);
872 &set_label("do_ecopy");
873 &mov ($_key,"edi"); 2116 &mov ($_key,"edi");
874 &data_word(0xA5F3F689); # rep movsd 2117 &data_word(0xA5F3F689); # rep movsd
875 &set_label("skip_ecopy"); 2118 &set_label("skip_copy");
876 2119
877 &mov ($acc,$s0);
878 &mov ($key,16); 2120 &mov ($key,16);
879 &align (4); 2121 &set_label("prefetch_tbl",4);
880 &set_label("prefetch_te"); 2122 &mov ($s0,&DWP(0,$tbl));
881 &mov ($s0,&DWP(0,"ebp")); 2123 &mov ($s1,&DWP(32,$tbl));
882 &mov ($s1,&DWP(32,"ebp")); 2124 &mov ($s2,&DWP(64,$tbl));
883 &mov ($s2,&DWP(64,"ebp")); 2125 &mov ($acc,&DWP(96,$tbl));
884 &mov ($s3,&DWP(96,"ebp")); 2126 &lea ($tbl,&DWP(128,$tbl));
885 &lea ("ebp",&DWP(128,"ebp")); 2127 &sub ($key,1);
886 &dec ($key); 2128 &jnz (&label("prefetch_tbl"));
887 &jnz (&label("prefetch_te")); 2129 &sub ($tbl,2048);
888 &sub ("ebp",2048); 2130
889 2131 &mov ($acc,$_inp);
890 &mov ($s2,$_len);
891 &mov ($key,$_ivp); 2132 &mov ($key,$_ivp);
892 &test ($s2,0xFFFFFFF0);
893 &jz (&label("enc_tail")); # short input...
894 2133
2134 &cmp ($s3,0);
2135 &je (&label("fast_decrypt"));
2136
2137#----------------------------- ENCRYPT -----------------------------#
895 &mov ($s0,&DWP(0,$key)); # load iv 2138 &mov ($s0,&DWP(0,$key)); # load iv
896 &mov ($s1,&DWP(4,$key)); 2139 &mov ($s1,&DWP(4,$key));
897 2140
898 &align (4); 2141 &set_label("fast_enc_loop",16);
899 &set_label("enc_loop");
900 &mov ($s2,&DWP(8,$key)); 2142 &mov ($s2,&DWP(8,$key));
901 &mov ($s3,&DWP(12,$key)); 2143 &mov ($s3,&DWP(12,$key));
902 2144
@@ -916,22 +2158,16 @@ my $mark=&DWP(60+240,"esp"); #copy of aes_key->rounds
916 &mov (&DWP(8,$key),$s2); 2158 &mov (&DWP(8,$key),$s2);
917 &mov (&DWP(12,$key),$s3); 2159 &mov (&DWP(12,$key),$s3);
918 2160
2161 &lea ($acc,&DWP(16,$acc)); # advance inp
919 &mov ($s2,$_len); # load len 2162 &mov ($s2,$_len); # load len
920
921 &lea ($acc,&DWP(16,$acc));
922 &mov ($_inp,$acc); # save inp 2163 &mov ($_inp,$acc); # save inp
923 2164 &lea ($s3,&DWP(16,$key)); # advance out
924 &lea ($s3,&DWP(16,$key));
925 &mov ($_out,$s3); # save out 2165 &mov ($_out,$s3); # save out
926 2166 &sub ($s2,16); # decrease len
927 &sub ($s2,16);
928 &test ($s2,0xFFFFFFF0);
929 &mov ($_len,$s2); # save len 2167 &mov ($_len,$s2); # save len
930 &jnz (&label("enc_loop")); 2168 &jnz (&label("fast_enc_loop"));
931 &test ($s2,15);
932 &jnz (&label("enc_tail"));
933 &mov ($acc,$_ivp); # load ivp 2169 &mov ($acc,$_ivp); # load ivp
934 &mov ($s2,&DWP(8,$key)); # restore last dwords 2170 &mov ($s2,&DWP(8,$key)); # restore last 2 dwords
935 &mov ($s3,&DWP(12,$key)); 2171 &mov ($s3,&DWP(12,$key));
936 &mov (&DWP(0,$acc),$s0); # save ivec 2172 &mov (&DWP(0,$acc),$s0); # save ivec
937 &mov (&DWP(4,$acc),$s1); 2173 &mov (&DWP(4,$acc),$s1);
@@ -949,125 +2185,20 @@ my $mark=&DWP(60+240,"esp"); #copy of aes_key->rounds
949 &set_label("skip_ezero") 2185 &set_label("skip_ezero")
950 &mov ("esp",$_esp); 2186 &mov ("esp",$_esp);
951 &popf (); 2187 &popf ();
952 &set_label("enc_out"); 2188 &set_label("drop_out");
953 &function_end_A(); 2189 &function_end_A();
954 &pushf (); # kludge, never executed 2190 &pushf (); # kludge, never executed
955 2191
956 &align (4);
957 &set_label("enc_tail");
958 &mov ($s0,$key eq "edi" ? $key : "");
959 &mov ($key,$_out); # load out
960 &push ($s0); # push ivp
961 &mov ($s1,16);
962 &sub ($s1,$s2);
963 &cmp ($key,$acc); # compare with inp
964 &je (&label("enc_in_place"));
965 &align (4);
966 &data_word(0xA4F3F689); # rep movsb # copy input
967 &jmp (&label("enc_skip_in_place"));
968 &set_label("enc_in_place");
969 &lea ($key,&DWP(0,$key,$s2));
970 &set_label("enc_skip_in_place");
971 &mov ($s2,$s1);
972 &xor ($s0,$s0);
973 &align (4);
974 &data_word(0xAAF3F689); # rep stosb # zero tail
975 &pop ($key); # pop ivp
976
977 &mov ($acc,$_out); # output as input
978 &mov ($s0,&DWP(0,$key));
979 &mov ($s1,&DWP(4,$key));
980 &mov ($_len,16); # len=16
981 &jmp (&label("enc_loop")); # one more spin...
982
983#----------------------------- DECRYPT -----------------------------# 2192#----------------------------- DECRYPT -----------------------------#
984&align (4); 2193&set_label("fast_decrypt",16);
985&set_label("DECRYPT");
986 &lea ("ebp",&DWP(&label("AES_Td")."-".&label("pic_point"),"ebp"));
987
988 # allocate aligned stack frame...
989 &lea ($key,&DWP(-64-244,"esp"));
990 &and ($key,-64);
991
992 # ... and make sure it doesn't alias with AES_Td modulo 4096
993 &mov ($s0,"ebp");
994 &lea ($s1,&DWP(2048+256,"ebp"));
995 &mov ($s3,$key);
996 &and ($s0,0xfff); # s = %ebp&0xfff
997 &and ($s1,0xfff); # e = (%ebp+2048+256)&0xfff
998 &and ($s3,0xfff); # p = %esp&0xfff
999
1000 &cmp ($s3,$s1); # if (p>=e) %esp =- (p-e);
1001 &jb (&label("td_break_out"));
1002 &sub ($s3,$s1);
1003 &sub ($key,$s3);
1004 &jmp (&label("td_ok"));
1005 &set_label("td_break_out"); # else %esp -= (p-s)&0xfff + framesz;
1006 &sub ($s3,$s0);
1007 &and ($s3,0xfff);
1008 &add ($s3,64+256);
1009 &sub ($key,$s3);
1010 &align (4);
1011 &set_label("td_ok");
1012
1013 &mov ($s0,&wparam(0)); # load inp
1014 &mov ($s1,&wparam(1)); # load out
1015 &mov ($s3,&wparam(3)); # load key
1016 &mov ($acc,&wparam(4)); # load ivp
1017
1018 &exch ("esp",$key);
1019 &add ("esp",4); # reserve for return address!
1020 &mov ($_esp,$key); # save %esp
1021
1022 &mov ($_inp,$s0); # save copy of inp
1023 &mov ($_out,$s1); # save copy of out
1024 &mov ($_len,$s2); # save copy of len
1025 &mov ($_key,$s3); # save copy of key
1026 &mov ($_ivp,$acc); # save copy of ivp
1027
1028 &mov ($mark,0); # copy of aes_key->rounds = 0;
1029 if ($compromise) {
1030 &cmp ($s2,$compromise);
1031 &jb (&label("skip_dcopy"));
1032 }
1033 # do we copy key schedule to stack?
1034 &mov ($s1 eq "ebx" ? $s1 : "",$s3);
1035 &mov ($s2 eq "ecx" ? $s2 : "",244/4);
1036 &sub ($s1,"ebp");
1037 &mov ("esi",$s3);
1038 &and ($s1,0xfff);
1039 &lea ("edi",$aes_key);
1040 &cmp ($s1,2048+256);
1041 &jb (&label("do_dcopy"));
1042 &cmp ($s1,4096-244);
1043 &jb (&label("skip_dcopy"));
1044 &align (4);
1045 &set_label("do_dcopy");
1046 &mov ($_key,"edi");
1047 &data_word(0xA5F3F689); # rep movsd
1048 &set_label("skip_dcopy");
1049
1050 &mov ($acc,$s0);
1051 &mov ($key,18);
1052 &align (4);
1053 &set_label("prefetch_td");
1054 &mov ($s0,&DWP(0,"ebp"));
1055 &mov ($s1,&DWP(32,"ebp"));
1056 &mov ($s2,&DWP(64,"ebp"));
1057 &mov ($s3,&DWP(96,"ebp"));
1058 &lea ("ebp",&DWP(128,"ebp"));
1059 &dec ($key);
1060 &jnz (&label("prefetch_td"));
1061 &sub ("ebp",2048+256);
1062 2194
1063 &cmp ($acc,$_out); 2195 &cmp ($acc,$_out);
1064 &je (&label("dec_in_place")); # in-place processing... 2196 &je (&label("fast_dec_in_place")); # in-place processing...
1065 2197
1066 &mov ($key,$_ivp); # load ivp
1067 &mov ($_tmp,$key); 2198 &mov ($_tmp,$key);
1068 2199
1069 &align (4); 2200 &align (4);
1070 &set_label("dec_loop"); 2201 &set_label("fast_dec_loop",16);
1071 &mov ($s0,&DWP(0,$acc)); # read input 2202 &mov ($s0,&DWP(0,$acc)); # read input
1072 &mov ($s1,&DWP(4,$acc)); 2203 &mov ($s1,&DWP(4,$acc));
1073 &mov ($s2,&DWP(8,$acc)); 2204 &mov ($s2,&DWP(8,$acc));
@@ -1083,27 +2214,24 @@ my $mark=&DWP(60+240,"esp"); #copy of aes_key->rounds
1083 &xor ($s2,&DWP(8,$key)); 2214 &xor ($s2,&DWP(8,$key));
1084 &xor ($s3,&DWP(12,$key)); 2215 &xor ($s3,&DWP(12,$key));
1085 2216
1086 &sub ($acc,16);
1087 &jc (&label("dec_partial"));
1088 &mov ($_len,$acc); # save len
1089 &mov ($acc,$_inp); # load inp
1090 &mov ($key,$_out); # load out 2217 &mov ($key,$_out); # load out
2218 &mov ($acc,$_inp); # load inp
1091 2219
1092 &mov (&DWP(0,$key),$s0); # write output 2220 &mov (&DWP(0,$key),$s0); # write output
1093 &mov (&DWP(4,$key),$s1); 2221 &mov (&DWP(4,$key),$s1);
1094 &mov (&DWP(8,$key),$s2); 2222 &mov (&DWP(8,$key),$s2);
1095 &mov (&DWP(12,$key),$s3); 2223 &mov (&DWP(12,$key),$s3);
1096 2224
2225 &mov ($s2,$_len); # load len
1097 &mov ($_tmp,$acc); # save ivp 2226 &mov ($_tmp,$acc); # save ivp
1098 &lea ($acc,&DWP(16,$acc)); 2227 &lea ($acc,&DWP(16,$acc)); # advance inp
1099 &mov ($_inp,$acc); # save inp 2228 &mov ($_inp,$acc); # save inp
1100 2229 &lea ($key,&DWP(16,$key)); # advance out
1101 &lea ($key,&DWP(16,$key));
1102 &mov ($_out,$key); # save out 2230 &mov ($_out,$key); # save out
1103 2231 &sub ($s2,16); # decrease len
1104 &jnz (&label("dec_loop")); 2232 &mov ($_len,$s2); # save len
2233 &jnz (&label("fast_dec_loop"));
1105 &mov ($key,$_tmp); # load temp ivp 2234 &mov ($key,$_tmp); # load temp ivp
1106 &set_label("dec_end");
1107 &mov ($acc,$_ivp); # load user ivp 2235 &mov ($acc,$_ivp); # load user ivp
1108 &mov ($s0,&DWP(0,$key)); # load iv 2236 &mov ($s0,&DWP(0,$key)); # load iv
1109 &mov ($s1,&DWP(4,$key)); 2237 &mov ($s1,&DWP(4,$key));
@@ -1113,31 +2241,16 @@ my $mark=&DWP(60+240,"esp"); #copy of aes_key->rounds
1113 &mov (&DWP(4,$acc),$s1); 2241 &mov (&DWP(4,$acc),$s1);
1114 &mov (&DWP(8,$acc),$s2); 2242 &mov (&DWP(8,$acc),$s2);
1115 &mov (&DWP(12,$acc),$s3); 2243 &mov (&DWP(12,$acc),$s3);
1116 &jmp (&label("dec_out")); 2244 &jmp (&label("fast_dec_out"));
1117 2245
1118 &align (4); 2246 &set_label("fast_dec_in_place",16);
1119 &set_label("dec_partial"); 2247 &set_label("fast_dec_in_place_loop");
1120 &lea ($key,$ivec);
1121 &mov (&DWP(0,$key),$s0); # dump output to stack
1122 &mov (&DWP(4,$key),$s1);
1123 &mov (&DWP(8,$key),$s2);
1124 &mov (&DWP(12,$key),$s3);
1125 &lea ($s2 eq "ecx" ? $s2 : "",&DWP(16,$acc));
1126 &mov ($acc eq "esi" ? $acc : "",$key);
1127 &mov ($key eq "edi" ? $key : "",$_out); # load out
1128 &data_word(0xA4F3F689); # rep movsb # copy output
1129 &mov ($key,$_inp); # use inp as temp ivp
1130 &jmp (&label("dec_end"));
1131
1132 &align (4);
1133 &set_label("dec_in_place");
1134 &set_label("dec_in_place_loop");
1135 &lea ($key,$ivec);
1136 &mov ($s0,&DWP(0,$acc)); # read input 2248 &mov ($s0,&DWP(0,$acc)); # read input
1137 &mov ($s1,&DWP(4,$acc)); 2249 &mov ($s1,&DWP(4,$acc));
1138 &mov ($s2,&DWP(8,$acc)); 2250 &mov ($s2,&DWP(8,$acc));
1139 &mov ($s3,&DWP(12,$acc)); 2251 &mov ($s3,&DWP(12,$acc));
1140 2252
2253 &lea ($key,$ivec);
1141 &mov (&DWP(0,$key),$s0); # copy to temp 2254 &mov (&DWP(0,$key),$s0); # copy to temp
1142 &mov (&DWP(4,$key),$s1); 2255 &mov (&DWP(4,$key),$s1);
1143 &mov (&DWP(8,$key),$s2); 2256 &mov (&DWP(8,$key),$s2);
@@ -1158,7 +2271,7 @@ my $mark=&DWP(60+240,"esp"); #copy of aes_key->rounds
1158 &mov (&DWP(8,$acc),$s2); 2271 &mov (&DWP(8,$acc),$s2);
1159 &mov (&DWP(12,$acc),$s3); 2272 &mov (&DWP(12,$acc),$s3);
1160 2273
1161 &lea ($acc,&DWP(16,$acc)); 2274 &lea ($acc,&DWP(16,$acc)); # advance out
1162 &mov ($_out,$acc); # save out 2275 &mov ($_out,$acc); # save out
1163 2276
1164 &lea ($acc,$ivec); 2277 &lea ($acc,$ivec);
@@ -1173,40 +2286,340 @@ my $mark=&DWP(60+240,"esp"); #copy of aes_key->rounds
1173 &mov (&DWP(12,$key),$s3); 2286 &mov (&DWP(12,$key),$s3);
1174 2287
1175 &mov ($acc,$_inp); # load inp 2288 &mov ($acc,$_inp); # load inp
2289 &mov ($s2,$_len); # load len
2290 &lea ($acc,&DWP(16,$acc)); # advance inp
2291 &mov ($_inp,$acc); # save inp
2292 &sub ($s2,16); # decrease len
2293 &mov ($_len,$s2); # save len
2294 &jnz (&label("fast_dec_in_place_loop"));
2295
2296 &set_label("fast_dec_out",4);
2297 &cmp ($mark,0); # was the key schedule copied?
2298 &mov ("edi",$_key);
2299 &je (&label("skip_dzero"));
2300 # zero copy of key schedule
2301 &mov ("ecx",240/4);
2302 &xor ("eax","eax");
2303 &align (4);
2304 &data_word(0xABF3F689); # rep stosd
2305 &set_label("skip_dzero")
2306 &mov ("esp",$_esp);
2307 &popf ();
2308 &function_end_A();
2309 &pushf (); # kludge, never executed
2310
2311#--------------------------- SLOW ROUTINE ---------------------------#
2312&set_label("slow_way",16);
2313
2314 &mov ($s0,&DWP(0,$s0)) if (!$x86only);# load OPENSSL_ia32cap
2315 &mov ($key,&wparam(3)); # load key
2316
2317 # pre-allocate aligned stack frame...
2318 &lea ($acc,&DWP(-80,"esp"));
2319 &and ($acc,-64);
2320
2321 # ... and make sure it doesn't alias with $key modulo 1024
2322 &lea ($s1,&DWP(-80-63,$key));
2323 &sub ($s1,$acc);
2324 &neg ($s1);
2325 &and ($s1,0x3C0); # modulo 1024, but aligned to cache-line
2326 &sub ($acc,$s1);
2327
2328 # pick S-box copy which can't overlap with stack frame or $key
2329 &lea ($s1,&DWP(768,$acc));
2330 &sub ($s1,$tbl);
2331 &and ($s1,0x300);
2332 &lea ($tbl,&DWP(2048+128,$tbl,$s1));
2333
2334 &lea ($s3,&wparam(0)); # pointer to parameter block
2335
2336 &exch ("esp",$acc);
2337 &add ("esp",4); # reserve for return address!
2338 &mov ($_tbl,$tbl); # save %ebp
2339 &mov ($_esp,$acc); # save %esp
2340 &mov ($_tmp,$s0); # save OPENSSL_ia32cap
2341
2342 &mov ($s0,&DWP(0,$s3)); # load inp
2343 &mov ($s1,&DWP(4,$s3)); # load out
2344 #&mov ($s2,&DWP(8,$s3)); # load len
2345 #&mov ($key,&DWP(12,$s3)); # load key
2346 &mov ($acc,&DWP(16,$s3)); # load ivp
2347 &mov ($s3,&DWP(20,$s3)); # load enc flag
2348
2349 &mov ($_inp,$s0); # save copy of inp
2350 &mov ($_out,$s1); # save copy of out
2351 &mov ($_len,$s2); # save copy of len
2352 &mov ($_key,$key); # save copy of key
2353 &mov ($_ivp,$acc); # save copy of ivp
2354
2355 &mov ($key,$acc);
2356 &mov ($acc,$s0);
2357
2358 &cmp ($s3,0);
2359 &je (&label("slow_decrypt"));
2360
2361#--------------------------- SLOW ENCRYPT ---------------------------#
2362 &cmp ($s2,16);
2363 &mov ($s3,$s1);
2364 &jb (&label("slow_enc_tail"));
2365
2366 if (!$x86only) {
2367 &bt ($_tmp,25); # check for SSE bit
2368 &jnc (&label("slow_enc_x86"));
1176 2369
1177 &lea ($acc,&DWP(16,$acc)); 2370 &movq ("mm0",&QWP(0,$key)); # load iv
2371 &movq ("mm4",&QWP(8,$key));
2372
2373 &set_label("slow_enc_loop_sse",16);
2374 &pxor ("mm0",&QWP(0,$acc)); # xor input data
2375 &pxor ("mm4",&QWP(8,$acc));
2376
2377 &mov ($key,$_key);
2378 &call ("_sse_AES_encrypt_compact");
2379
2380 &mov ($acc,$_inp); # load inp
2381 &mov ($key,$_out); # load out
2382 &mov ($s2,$_len); # load len
2383
2384 &movq (&QWP(0,$key),"mm0"); # save output data
2385 &movq (&QWP(8,$key),"mm4");
2386
2387 &lea ($acc,&DWP(16,$acc)); # advance inp
1178 &mov ($_inp,$acc); # save inp 2388 &mov ($_inp,$acc); # save inp
2389 &lea ($s3,&DWP(16,$key)); # advance out
2390 &mov ($_out,$s3); # save out
2391 &sub ($s2,16); # decrease len
2392 &cmp ($s2,16);
2393 &mov ($_len,$s2); # save len
2394 &jae (&label("slow_enc_loop_sse"));
2395 &test ($s2,15);
2396 &jnz (&label("slow_enc_tail"));
2397 &mov ($acc,$_ivp); # load ivp
2398 &movq (&QWP(0,$acc),"mm0"); # save ivec
2399 &movq (&QWP(8,$acc),"mm4");
2400 &emms ();
2401 &mov ("esp",$_esp);
2402 &popf ();
2403 &function_end_A();
2404 &pushf (); # kludge, never executed
2405 }
2406 &set_label("slow_enc_x86",16);
2407 &mov ($s0,&DWP(0,$key)); # load iv
2408 &mov ($s1,&DWP(4,$key));
2409
2410 &set_label("slow_enc_loop_x86",4);
2411 &mov ($s2,&DWP(8,$key));
2412 &mov ($s3,&DWP(12,$key));
2413
2414 &xor ($s0,&DWP(0,$acc)); # xor input data
2415 &xor ($s1,&DWP(4,$acc));
2416 &xor ($s2,&DWP(8,$acc));
2417 &xor ($s3,&DWP(12,$acc));
2418
2419 &mov ($key,$_key); # load key
2420 &call ("_x86_AES_encrypt_compact");
2421
2422 &mov ($acc,$_inp); # load inp
2423 &mov ($key,$_out); # load out
2424
2425 &mov (&DWP(0,$key),$s0); # save output data
2426 &mov (&DWP(4,$key),$s1);
2427 &mov (&DWP(8,$key),$s2);
2428 &mov (&DWP(12,$key),$s3);
1179 2429
1180 &mov ($s2,$_len); # load len 2430 &mov ($s2,$_len); # load len
1181 &sub ($s2,16); 2431 &lea ($acc,&DWP(16,$acc)); # advance inp
1182 &jc (&label("dec_in_place_partial")); 2432 &mov ($_inp,$acc); # save inp
2433 &lea ($s3,&DWP(16,$key)); # advance out
2434 &mov ($_out,$s3); # save out
2435 &sub ($s2,16); # decrease len
2436 &cmp ($s2,16);
1183 &mov ($_len,$s2); # save len 2437 &mov ($_len,$s2); # save len
1184 &jnz (&label("dec_in_place_loop")); 2438 &jae (&label("slow_enc_loop_x86"));
1185 &jmp (&label("dec_out")); 2439 &test ($s2,15);
1186 2440 &jnz (&label("slow_enc_tail"));
1187 &align (4); 2441 &mov ($acc,$_ivp); # load ivp
1188 &set_label("dec_in_place_partial"); 2442 &mov ($s2,&DWP(8,$key)); # restore last dwords
1189 # one can argue if this is actually required... 2443 &mov ($s3,&DWP(12,$key));
1190 &mov ($key eq "edi" ? $key : "",$_out); 2444 &mov (&DWP(0,$acc),$s0); # save ivec
1191 &lea ($acc eq "esi" ? $acc : "",$ivec); 2445 &mov (&DWP(4,$acc),$s1);
2446 &mov (&DWP(8,$acc),$s2);
2447 &mov (&DWP(12,$acc),$s3);
2448
2449 &mov ("esp",$_esp);
2450 &popf ();
2451 &function_end_A();
2452 &pushf (); # kludge, never executed
2453
2454 &set_label("slow_enc_tail",16);
2455 &emms () if (!$x86only);
2456 &mov ($key eq "edi"? $key:"",$s3); # load out to edi
2457 &mov ($s1,16);
2458 &sub ($s1,$s2);
2459 &cmp ($key,$acc eq "esi"? $acc:""); # compare with inp
2460 &je (&label("enc_in_place"));
2461 &align (4);
2462 &data_word(0xA4F3F689); # rep movsb # copy input
2463 &jmp (&label("enc_skip_in_place"));
2464 &set_label("enc_in_place");
1192 &lea ($key,&DWP(0,$key,$s2)); 2465 &lea ($key,&DWP(0,$key,$s2));
1193 &lea ($acc,&DWP(16,$acc,$s2)); 2466 &set_label("enc_skip_in_place");
1194 &neg ($s2 eq "ecx" ? $s2 : ""); 2467 &mov ($s2,$s1);
1195 &data_word(0xA4F3F689); # rep movsb # restore tail 2468 &xor ($s0,$s0);
1196 2469 &align (4);
1197 &align (4); 2470 &data_word(0xAAF3F689); # rep stosb # zero tail
1198 &set_label("dec_out"); 2471
1199 &cmp ($mark,0); # was the key schedule copied? 2472 &mov ($key,$_ivp); # restore ivp
1200 &mov ("edi",$_key); 2473 &mov ($acc,$s3); # output as input
1201 &je (&label("skip_dzero")); 2474 &mov ($s0,&DWP(0,$key));
1202 # zero copy of key schedule 2475 &mov ($s1,&DWP(4,$key));
1203 &mov ("ecx",240/4); 2476 &mov ($_len,16); # len=16
1204 &xor ("eax","eax"); 2477 &jmp (&label("slow_enc_loop_x86")); # one more spin...
1205 &align (4); 2478
1206 &data_word(0xABF3F689); # rep stosd 2479#--------------------------- SLOW DECRYPT ---------------------------#
1207 &set_label("skip_dzero") 2480&set_label("slow_decrypt",16);
1208 &mov ("esp",$_esp); 2481 if (!$x86only) {
1209 &popf (); 2482 &bt ($_tmp,25); # check for SSE bit
2483 &jnc (&label("slow_dec_loop_x86"));
2484
2485 &set_label("slow_dec_loop_sse",4);
2486 &movq ("mm0",&QWP(0,$acc)); # read input
2487 &movq ("mm4",&QWP(8,$acc));
2488
2489 &mov ($key,$_key);
2490 &call ("_sse_AES_decrypt_compact");
2491
2492 &mov ($acc,$_inp); # load inp
2493 &lea ($s0,$ivec);
2494 &mov ($s1,$_out); # load out
2495 &mov ($s2,$_len); # load len
2496 &mov ($key,$_ivp); # load ivp
2497
2498 &movq ("mm1",&QWP(0,$acc)); # re-read input
2499 &movq ("mm5",&QWP(8,$acc));
2500
2501 &pxor ("mm0",&QWP(0,$key)); # xor iv
2502 &pxor ("mm4",&QWP(8,$key));
2503
2504 &movq (&QWP(0,$key),"mm1"); # copy input to iv
2505 &movq (&QWP(8,$key),"mm5");
2506
2507 &sub ($s2,16); # decrease len
2508 &jc (&label("slow_dec_partial_sse"));
2509
2510 &movq (&QWP(0,$s1),"mm0"); # write output
2511 &movq (&QWP(8,$s1),"mm4");
2512
2513 &lea ($s1,&DWP(16,$s1)); # advance out
2514 &mov ($_out,$s1); # save out
2515 &lea ($acc,&DWP(16,$acc)); # advance inp
2516 &mov ($_inp,$acc); # save inp
2517 &mov ($_len,$s2); # save len
2518 &jnz (&label("slow_dec_loop_sse"));
2519 &emms ();
2520 &mov ("esp",$_esp);
2521 &popf ();
2522 &function_end_A();
2523 &pushf (); # kludge, never executed
2524
2525 &set_label("slow_dec_partial_sse",16);
2526 &movq (&QWP(0,$s0),"mm0"); # save output to temp
2527 &movq (&QWP(8,$s0),"mm4");
2528 &emms ();
2529
2530 &add ($s2 eq "ecx" ? "ecx":"",16);
2531 &mov ("edi",$s1); # out
2532 &mov ("esi",$s0); # temp
2533 &align (4);
2534 &data_word(0xA4F3F689); # rep movsb # copy partial output
2535
2536 &mov ("esp",$_esp);
2537 &popf ();
2538 &function_end_A();
2539 &pushf (); # kludge, never executed
2540 }
2541 &set_label("slow_dec_loop_x86",16);
2542 &mov ($s0,&DWP(0,$acc)); # read input
2543 &mov ($s1,&DWP(4,$acc));
2544 &mov ($s2,&DWP(8,$acc));
2545 &mov ($s3,&DWP(12,$acc));
2546
2547 &lea ($key,$ivec);
2548 &mov (&DWP(0,$key),$s0); # copy to temp
2549 &mov (&DWP(4,$key),$s1);
2550 &mov (&DWP(8,$key),$s2);
2551 &mov (&DWP(12,$key),$s3);
2552
2553 &mov ($key,$_key); # load key
2554 &call ("_x86_AES_decrypt_compact");
2555
2556 &mov ($key,$_ivp); # load ivp
2557 &mov ($acc,$_len); # load len
2558 &xor ($s0,&DWP(0,$key)); # xor iv
2559 &xor ($s1,&DWP(4,$key));
2560 &xor ($s2,&DWP(8,$key));
2561 &xor ($s3,&DWP(12,$key));
2562
2563 &sub ($acc,16);
2564 &jc (&label("slow_dec_partial_x86"));
2565
2566 &mov ($_len,$acc); # save len
2567 &mov ($acc,$_out); # load out
2568
2569 &mov (&DWP(0,$acc),$s0); # write output
2570 &mov (&DWP(4,$acc),$s1);
2571 &mov (&DWP(8,$acc),$s2);
2572 &mov (&DWP(12,$acc),$s3);
2573
2574 &lea ($acc,&DWP(16,$acc)); # advance out
2575 &mov ($_out,$acc); # save out
2576
2577 &lea ($acc,$ivec);
2578 &mov ($s0,&DWP(0,$acc)); # read temp
2579 &mov ($s1,&DWP(4,$acc));
2580 &mov ($s2,&DWP(8,$acc));
2581 &mov ($s3,&DWP(12,$acc));
2582
2583 &mov (&DWP(0,$key),$s0); # copy it to iv
2584 &mov (&DWP(4,$key),$s1);
2585 &mov (&DWP(8,$key),$s2);
2586 &mov (&DWP(12,$key),$s3);
2587
2588 &mov ($acc,$_inp); # load inp
2589 &lea ($acc,&DWP(16,$acc)); # advance inp
2590 &mov ($_inp,$acc); # save inp
2591 &jnz (&label("slow_dec_loop_x86"));
2592 &mov ("esp",$_esp);
2593 &popf ();
2594 &function_end_A();
2595 &pushf (); # kludge, never executed
2596
2597 &set_label("slow_dec_partial_x86",16);
2598 &lea ($acc,$ivec);
2599 &mov (&DWP(0,$acc),$s0); # save output to temp
2600 &mov (&DWP(4,$acc),$s1);
2601 &mov (&DWP(8,$acc),$s2);
2602 &mov (&DWP(12,$acc),$s3);
2603
2604 &mov ($acc,$_inp);
2605 &mov ($s0,&DWP(0,$acc)); # re-read input
2606 &mov ($s1,&DWP(4,$acc));
2607 &mov ($s2,&DWP(8,$acc));
2608 &mov ($s3,&DWP(12,$acc));
2609
2610 &mov (&DWP(0,$key),$s0); # copy it to iv
2611 &mov (&DWP(4,$key),$s1);
2612 &mov (&DWP(8,$key),$s2);
2613 &mov (&DWP(12,$key),$s3);
2614
2615 &mov ("ecx",$_len);
2616 &mov ("edi",$_out);
2617 &lea ("esi",$ivec);
2618 &align (4);
2619 &data_word(0xA4F3F689); # rep movsb # copy partial output
2620
2621 &mov ("esp",$_esp);
2622 &popf ();
1210&function_end("AES_cbc_encrypt"); 2623&function_end("AES_cbc_encrypt");
1211} 2624}
1212 2625
@@ -1215,35 +2628,31 @@ my $mark=&DWP(60+240,"esp"); #copy of aes_key->rounds
1215sub enckey() 2628sub enckey()
1216{ 2629{
1217 &movz ("esi",&LB("edx")); # rk[i]>>0 2630 &movz ("esi",&LB("edx")); # rk[i]>>0
1218 &mov ("ebx",&DWP(2,"ebp","esi",8)); 2631 &movz ("ebx",&BP(-128,$tbl,"esi",1));
1219 &movz ("esi",&HB("edx")); # rk[i]>>8 2632 &movz ("esi",&HB("edx")); # rk[i]>>8
1220 &and ("ebx",0xFF000000); 2633 &shl ("ebx",24);
1221 &xor ("eax","ebx"); 2634 &xor ("eax","ebx");
1222 2635
1223 &mov ("ebx",&DWP(2,"ebp","esi",8)); 2636 &movz ("ebx",&BP(-128,$tbl,"esi",1));
1224 &shr ("edx",16); 2637 &shr ("edx",16);
1225 &and ("ebx",0x000000FF);
1226 &movz ("esi",&LB("edx")); # rk[i]>>16 2638 &movz ("esi",&LB("edx")); # rk[i]>>16
1227 &xor ("eax","ebx"); 2639 &xor ("eax","ebx");
1228 2640
1229 &mov ("ebx",&DWP(0,"ebp","esi",8)); 2641 &movz ("ebx",&BP(-128,$tbl,"esi",1));
1230 &movz ("esi",&HB("edx")); # rk[i]>>24 2642 &movz ("esi",&HB("edx")); # rk[i]>>24
1231 &and ("ebx",0x0000FF00); 2643 &shl ("ebx",8);
1232 &xor ("eax","ebx"); 2644 &xor ("eax","ebx");
1233 2645
1234 &mov ("ebx",&DWP(0,"ebp","esi",8)); 2646 &movz ("ebx",&BP(-128,$tbl,"esi",1));
1235 &and ("ebx",0x00FF0000); 2647 &shl ("ebx",16);
1236 &xor ("eax","ebx"); 2648 &xor ("eax","ebx");
1237 2649
1238 &xor ("eax",&DWP(2048,"ebp","ecx",4)); # rcon 2650 &xor ("eax",&DWP(1024-128,$tbl,"ecx",4)); # rcon
1239} 2651}
1240 2652
1241# int AES_set_encrypt_key(const unsigned char *userKey, const int bits, 2653&function_begin("_x86_AES_set_encrypt_key");
1242# AES_KEY *key) 2654 &mov ("esi",&wparam(1)); # user supplied key
1243&public_label("AES_Te"); 2655 &mov ("edi",&wparam(3)); # private key schedule
1244&function_begin("AES_set_encrypt_key");
1245 &mov ("esi",&wparam(0)); # user supplied key
1246 &mov ("edi",&wparam(2)); # private key schedule
1247 2656
1248 &test ("esi",-1); 2657 &test ("esi",-1);
1249 &jz (&label("badpointer")); 2658 &jz (&label("badpointer"));
@@ -1252,10 +2661,21 @@ sub enckey()
1252 2661
1253 &call (&label("pic_point")); 2662 &call (&label("pic_point"));
1254 &set_label("pic_point"); 2663 &set_label("pic_point");
1255 &blindpop("ebp"); 2664 &blindpop($tbl);
1256 &lea ("ebp",&DWP(&label("AES_Te")."-".&label("pic_point"),"ebp")); 2665 &lea ($tbl,&DWP(&label("AES_Te")."-".&label("pic_point"),$tbl));
1257 2666 &lea ($tbl,&DWP(2048+128,$tbl));
1258 &mov ("ecx",&wparam(1)); # number of bits in key 2667
2668 # prefetch Te4
2669 &mov ("eax",&DWP(0-128,$tbl));
2670 &mov ("ebx",&DWP(32-128,$tbl));
2671 &mov ("ecx",&DWP(64-128,$tbl));
2672 &mov ("edx",&DWP(96-128,$tbl));
2673 &mov ("eax",&DWP(128-128,$tbl));
2674 &mov ("ebx",&DWP(160-128,$tbl));
2675 &mov ("ecx",&DWP(192-128,$tbl));
2676 &mov ("edx",&DWP(224-128,$tbl));
2677
2678 &mov ("ecx",&wparam(2)); # number of bits in key
1259 &cmp ("ecx",128); 2679 &cmp ("ecx",128);
1260 &je (&label("10rounds")); 2680 &je (&label("10rounds"));
1261 &cmp ("ecx",192); 2681 &cmp ("ecx",192);
@@ -1394,24 +2814,23 @@ sub enckey()
1394 &mov ("edx","eax"); 2814 &mov ("edx","eax");
1395 &mov ("eax",&DWP(16,"edi")); # rk[4] 2815 &mov ("eax",&DWP(16,"edi")); # rk[4]
1396 &movz ("esi",&LB("edx")); # rk[11]>>0 2816 &movz ("esi",&LB("edx")); # rk[11]>>0
1397 &mov ("ebx",&DWP(2,"ebp","esi",8)); 2817 &movz ("ebx",&BP(-128,$tbl,"esi",1));
1398 &movz ("esi",&HB("edx")); # rk[11]>>8 2818 &movz ("esi",&HB("edx")); # rk[11]>>8
1399 &and ("ebx",0x000000FF);
1400 &xor ("eax","ebx"); 2819 &xor ("eax","ebx");
1401 2820
1402 &mov ("ebx",&DWP(0,"ebp","esi",8)); 2821 &movz ("ebx",&BP(-128,$tbl,"esi",1));
1403 &shr ("edx",16); 2822 &shr ("edx",16);
1404 &and ("ebx",0x0000FF00); 2823 &shl ("ebx",8);
1405 &movz ("esi",&LB("edx")); # rk[11]>>16 2824 &movz ("esi",&LB("edx")); # rk[11]>>16
1406 &xor ("eax","ebx"); 2825 &xor ("eax","ebx");
1407 2826
1408 &mov ("ebx",&DWP(0,"ebp","esi",8)); 2827 &movz ("ebx",&BP(-128,$tbl,"esi",1));
1409 &movz ("esi",&HB("edx")); # rk[11]>>24 2828 &movz ("esi",&HB("edx")); # rk[11]>>24
1410 &and ("ebx",0x00FF0000); 2829 &shl ("ebx",16);
1411 &xor ("eax","ebx"); 2830 &xor ("eax","ebx");
1412 2831
1413 &mov ("ebx",&DWP(2,"ebp","esi",8)); 2832 &movz ("ebx",&BP(-128,$tbl,"esi",1));
1414 &and ("ebx",0xFF000000); 2833 &shl ("ebx",24);
1415 &xor ("eax","ebx"); 2834 &xor ("eax","ebx");
1416 2835
1417 &mov (&DWP(48,"edi"),"eax"); # rk[12] 2836 &mov (&DWP(48,"edi"),"eax"); # rk[12]
@@ -1433,43 +2852,74 @@ sub enckey()
1433 &set_label("badpointer"); 2852 &set_label("badpointer");
1434 &mov ("eax",-1); 2853 &mov ("eax",-1);
1435 &set_label("exit"); 2854 &set_label("exit");
1436&function_end("AES_set_encrypt_key"); 2855&function_end("_x86_AES_set_encrypt_key");
1437 2856
1438sub deckey() 2857# int AES_set_encrypt_key(const unsigned char *userKey, const int bits,
1439{ my ($i,$ptr,$te,$td) = @_; 2858# AES_KEY *key)
2859&function_begin_B("AES_set_encrypt_key");
2860 &call ("_x86_AES_set_encrypt_key");
2861 &ret ();
2862&function_end_B("AES_set_encrypt_key");
1440 2863
1441 &mov ("eax",&DWP($i,$ptr)); 2864sub deckey()
1442 &mov ("edx","eax"); 2865{ my ($i,$key,$tp1,$tp2,$tp4,$tp8) = @_;
1443 &movz ("ebx",&HB("eax")); 2866 my $tmp = $tbl;
1444 &shr ("edx",16); 2867
1445 &and ("eax",0xFF); 2868 &mov ($acc,$tp1);
1446 &movz ("eax",&BP(2,$te,"eax",8)); 2869 &and ($acc,0x80808080);
1447 &movz ("ebx",&BP(2,$te,"ebx",8)); 2870 &mov ($tmp,$acc);
1448 &mov ("eax",&DWP(0,$td,"eax",8)); 2871 &shr ($tmp,7);
1449 &xor ("eax",&DWP(3,$td,"ebx",8)); 2872 &lea ($tp2,&DWP(0,$tp1,$tp1));
1450 &movz ("ebx",&HB("edx")); 2873 &sub ($acc,$tmp);
1451 &and ("edx",0xFF); 2874 &and ($tp2,0xfefefefe);
1452 &movz ("edx",&BP(2,$te,"edx",8)); 2875 &and ($acc,0x1b1b1b1b);
1453 &movz ("ebx",&BP(2,$te,"ebx",8)); 2876 &xor ($acc,$tp2);
1454 &xor ("eax",&DWP(2,$td,"edx",8)); 2877 &mov ($tp2,$acc);
1455 &xor ("eax",&DWP(1,$td,"ebx",8)); 2878
1456 &mov (&DWP($i,$ptr),"eax"); 2879 &and ($acc,0x80808080);
2880 &mov ($tmp,$acc);
2881 &shr ($tmp,7);
2882 &lea ($tp4,&DWP(0,$tp2,$tp2));
2883 &sub ($acc,$tmp);
2884 &and ($tp4,0xfefefefe);
2885 &and ($acc,0x1b1b1b1b);
2886 &xor ($tp2,$tp1); # tp2^tp1
2887 &xor ($acc,$tp4);
2888 &mov ($tp4,$acc);
2889
2890 &and ($acc,0x80808080);
2891 &mov ($tmp,$acc);
2892 &shr ($tmp,7);
2893 &lea ($tp8,&DWP(0,$tp4,$tp4));
2894 &xor ($tp4,$tp1); # tp4^tp1
2895 &sub ($acc,$tmp);
2896 &and ($tp8,0xfefefefe);
2897 &and ($acc,0x1b1b1b1b);
2898 &rotl ($tp1,8); # = ROTATE(tp1,8)
2899 &xor ($tp8,$acc);
2900
2901 &mov ($tmp,&DWP(4*($i+1),$key)); # modulo-scheduled load
2902
2903 &xor ($tp1,$tp2);
2904 &xor ($tp2,$tp8);
2905 &xor ($tp1,$tp4);
2906 &rotl ($tp2,24);
2907 &xor ($tp4,$tp8);
2908 &xor ($tp1,$tp8); # ^= tp8^(tp4^tp1)^(tp2^tp1)
2909 &rotl ($tp4,16);
2910 &xor ($tp1,$tp2); # ^= ROTATE(tp8^tp2^tp1,24)
2911 &rotl ($tp8,8);
2912 &xor ($tp1,$tp4); # ^= ROTATE(tp8^tp4^tp1,16)
2913 &mov ($tp2,$tmp);
2914 &xor ($tp1,$tp8); # ^= ROTATE(tp8,8)
2915
2916 &mov (&DWP(4*$i,$key),$tp1);
1457} 2917}
1458 2918
1459# int AES_set_decrypt_key(const unsigned char *userKey, const int bits, 2919# int AES_set_decrypt_key(const unsigned char *userKey, const int bits,
1460# AES_KEY *key) 2920# AES_KEY *key)
1461&public_label("AES_Td");
1462&public_label("AES_Te");
1463&function_begin_B("AES_set_decrypt_key"); 2921&function_begin_B("AES_set_decrypt_key");
1464 &mov ("eax",&wparam(0)); 2922 &call ("_x86_AES_set_encrypt_key");
1465 &mov ("ecx",&wparam(1));
1466 &mov ("edx",&wparam(2));
1467 &sub ("esp",12);
1468 &mov (&DWP(0,"esp"),"eax");
1469 &mov (&DWP(4,"esp"),"ecx");
1470 &mov (&DWP(8,"esp"),"edx");
1471 &call ("AES_set_encrypt_key");
1472 &add ("esp",12);
1473 &cmp ("eax",0); 2923 &cmp ("eax",0);
1474 &je (&label("proceed")); 2924 &je (&label("proceed"));
1475 &ret (); 2925 &ret ();
@@ -1485,8 +2935,7 @@ sub deckey()
1485 &lea ("ecx",&DWP(0,"","ecx",4)); 2935 &lea ("ecx",&DWP(0,"","ecx",4));
1486 &lea ("edi",&DWP(0,"esi","ecx",4)); # pointer to last chunk 2936 &lea ("edi",&DWP(0,"esi","ecx",4)); # pointer to last chunk
1487 2937
1488 &align (4); 2938 &set_label("invert",4); # invert order of chunks
1489 &set_label("invert"); # invert order of chunks
1490 &mov ("eax",&DWP(0,"esi")); 2939 &mov ("eax",&DWP(0,"esi"));
1491 &mov ("ebx",&DWP(4,"esi")); 2940 &mov ("ebx",&DWP(4,"esi"));
1492 &mov ("ecx",&DWP(0,"edi")); 2941 &mov ("ecx",&DWP(0,"edi"));
@@ -1508,26 +2957,24 @@ sub deckey()
1508 &cmp ("esi","edi"); 2957 &cmp ("esi","edi");
1509 &jne (&label("invert")); 2958 &jne (&label("invert"));
1510 2959
1511 &call (&label("pic_point")); 2960 &mov ($key,&wparam(2));
1512 &set_label("pic_point"); 2961 &mov ($acc,&DWP(240,$key)); # pull number of rounds
1513 blindpop("ebp"); 2962 &lea ($acc,&DWP(-2,$acc,$acc));
1514 &lea ("edi",&DWP(&label("AES_Td")."-".&label("pic_point"),"ebp")); 2963 &lea ($acc,&DWP(0,$key,$acc,8));
1515 &lea ("ebp",&DWP(&label("AES_Te")."-".&label("pic_point"),"ebp")); 2964 &mov (&wparam(2),$acc);
1516 2965
1517 &mov ("esi",&wparam(2)); 2966 &mov ($s0,&DWP(16,$key)); # modulo-scheduled load
1518 &mov ("ecx",&DWP(240,"esi")); # pull number of rounds 2967 &set_label("permute",4); # permute the key schedule
1519 &dec ("ecx"); 2968 &add ($key,16);
1520 &align (4); 2969 &deckey (0,$key,$s0,$s1,$s2,$s3);
1521 &set_label("permute"); # permute the key schedule 2970 &deckey (1,$key,$s1,$s2,$s3,$s0);
1522 &add ("esi",16); 2971 &deckey (2,$key,$s2,$s3,$s0,$s1);
1523 &deckey (0,"esi","ebp","edi"); 2972 &deckey (3,$key,$s3,$s0,$s1,$s2);
1524 &deckey (4,"esi","ebp","edi"); 2973 &cmp ($key,&wparam(2));
1525 &deckey (8,"esi","ebp","edi"); 2974 &jb (&label("permute"));
1526 &deckey (12,"esi","ebp","edi");
1527 &dec ("ecx");
1528 &jnz (&label("permute"));
1529 2975
1530 &xor ("eax","eax"); # return success 2976 &xor ("eax","eax"); # return success
1531&function_end("AES_set_decrypt_key"); 2977&function_end("AES_set_decrypt_key");
2978&asciz("AES for x86, CRYPTOGAMS by <appro\@openssl.org>");
1532 2979
1533&asm_finish(); 2980&asm_finish();
diff --git a/src/lib/libcrypto/aes/asm/aes-armv4.pl b/src/lib/libcrypto/aes/asm/aes-armv4.pl
index 15742c1ec5..690244111a 100644
--- a/src/lib/libcrypto/aes/asm/aes-armv4.pl
+++ b/src/lib/libcrypto/aes/asm/aes-armv4.pl
@@ -1024,6 +1024,7 @@ _armv4_AES_decrypt:
1024 mov pc,lr @ return 1024 mov pc,lr @ return
1025.size _armv4_AES_decrypt,.-_armv4_AES_decrypt 1025.size _armv4_AES_decrypt,.-_armv4_AES_decrypt
1026.asciz "AES for ARMv4, CRYPTOGAMS by <appro\@openssl.org>" 1026.asciz "AES for ARMv4, CRYPTOGAMS by <appro\@openssl.org>"
1027.align 2
1027___ 1028___
1028 1029
1029$code =~ s/\bbx\s+lr\b/.word\t0xe12fff1e/gm; # make it possible to compile with -march=armv4 1030$code =~ s/\bbx\s+lr\b/.word\t0xe12fff1e/gm; # make it possible to compile with -march=armv4
diff --git a/src/lib/libcrypto/aes/asm/aes-ppc.pl b/src/lib/libcrypto/aes/asm/aes-ppc.pl
index ce427655ef..f82c5e1814 100644
--- a/src/lib/libcrypto/aes/asm/aes-ppc.pl
+++ b/src/lib/libcrypto/aes/asm/aes-ppc.pl
@@ -16,6 +16,19 @@
16# at 1/2 of ppc_AES_encrypt speed, while ppc_AES_decrypt_compact - 16# at 1/2 of ppc_AES_encrypt speed, while ppc_AES_decrypt_compact -
17# at 1/3 of ppc_AES_decrypt. 17# at 1/3 of ppc_AES_decrypt.
18 18
19# February 2010
20#
21# Rescheduling instructions to favour Power6 pipeline gives 10%
22# performance improvement on the platfrom in question (and marginal
23# improvement even on others). It should be noted that Power6 fails
24# to process byte in 18 cycles, only in 23, because it fails to issue
25# 4 load instructions in two cycles, only in 3. As result non-compact
26# block subroutines are 25% slower than one would expect. Compact
27# functions scale better, because they have pure computational part,
28# which scales perfectly with clock frequency. To be specific
29# ppc_AES_encrypt_compact operates at 42 cycles per byte, while
30# ppc_AES_decrypt_compact - at 55 (in 64-bit build).
31
19$flavour = shift; 32$flavour = shift;
20 33
21if ($flavour =~ /64/) { 34if ($flavour =~ /64/) {
@@ -376,7 +389,7 @@ $code.=<<___;
376 addi $sp,$sp,$FRAME 389 addi $sp,$sp,$FRAME
377 blr 390 blr
378 391
379.align 4 392.align 5
380Lppc_AES_encrypt: 393Lppc_AES_encrypt:
381 lwz $acc00,240($key) 394 lwz $acc00,240($key)
382 lwz $t0,0($key) 395 lwz $t0,0($key)
@@ -397,46 +410,46 @@ Lppc_AES_encrypt:
397Lenc_loop: 410Lenc_loop:
398 rlwinm $acc00,$s0,`32-24+3`,21,28 411 rlwinm $acc00,$s0,`32-24+3`,21,28
399 rlwinm $acc01,$s1,`32-24+3`,21,28 412 rlwinm $acc01,$s1,`32-24+3`,21,28
400 lwz $t0,0($key)
401 lwz $t1,4($key)
402 rlwinm $acc02,$s2,`32-24+3`,21,28 413 rlwinm $acc02,$s2,`32-24+3`,21,28
403 rlwinm $acc03,$s3,`32-24+3`,21,28 414 rlwinm $acc03,$s3,`32-24+3`,21,28
404 lwz $t2,8($key) 415 lwz $t0,0($key)
405 lwz $t3,12($key) 416 lwz $t1,4($key)
406 rlwinm $acc04,$s1,`32-16+3`,21,28 417 rlwinm $acc04,$s1,`32-16+3`,21,28
407 rlwinm $acc05,$s2,`32-16+3`,21,28 418 rlwinm $acc05,$s2,`32-16+3`,21,28
408 lwzx $acc00,$Tbl0,$acc00 419 lwz $t2,8($key)
409 lwzx $acc01,$Tbl0,$acc01 420 lwz $t3,12($key)
410 rlwinm $acc06,$s3,`32-16+3`,21,28 421 rlwinm $acc06,$s3,`32-16+3`,21,28
411 rlwinm $acc07,$s0,`32-16+3`,21,28 422 rlwinm $acc07,$s0,`32-16+3`,21,28
412 lwzx $acc02,$Tbl0,$acc02 423 lwzx $acc00,$Tbl0,$acc00
413 lwzx $acc03,$Tbl0,$acc03 424 lwzx $acc01,$Tbl0,$acc01
414 rlwinm $acc08,$s2,`32-8+3`,21,28 425 rlwinm $acc08,$s2,`32-8+3`,21,28
415 rlwinm $acc09,$s3,`32-8+3`,21,28 426 rlwinm $acc09,$s3,`32-8+3`,21,28
416 lwzx $acc04,$Tbl1,$acc04 427 lwzx $acc02,$Tbl0,$acc02
417 lwzx $acc05,$Tbl1,$acc05 428 lwzx $acc03,$Tbl0,$acc03
418 rlwinm $acc10,$s0,`32-8+3`,21,28 429 rlwinm $acc10,$s0,`32-8+3`,21,28
419 rlwinm $acc11,$s1,`32-8+3`,21,28 430 rlwinm $acc11,$s1,`32-8+3`,21,28
420 lwzx $acc06,$Tbl1,$acc06 431 lwzx $acc04,$Tbl1,$acc04
421 lwzx $acc07,$Tbl1,$acc07 432 lwzx $acc05,$Tbl1,$acc05
422 rlwinm $acc12,$s3,`0+3`,21,28 433 rlwinm $acc12,$s3,`0+3`,21,28
423 rlwinm $acc13,$s0,`0+3`,21,28 434 rlwinm $acc13,$s0,`0+3`,21,28
424 lwzx $acc08,$Tbl2,$acc08 435 lwzx $acc06,$Tbl1,$acc06
425 lwzx $acc09,$Tbl2,$acc09 436 lwzx $acc07,$Tbl1,$acc07
426 rlwinm $acc14,$s1,`0+3`,21,28 437 rlwinm $acc14,$s1,`0+3`,21,28
427 rlwinm $acc15,$s2,`0+3`,21,28 438 rlwinm $acc15,$s2,`0+3`,21,28
428 lwzx $acc10,$Tbl2,$acc10 439 lwzx $acc08,$Tbl2,$acc08
429 lwzx $acc11,$Tbl2,$acc11 440 lwzx $acc09,$Tbl2,$acc09
430 xor $t0,$t0,$acc00 441 xor $t0,$t0,$acc00
431 xor $t1,$t1,$acc01 442 xor $t1,$t1,$acc01
432 lwzx $acc12,$Tbl3,$acc12 443 lwzx $acc10,$Tbl2,$acc10
433 lwzx $acc13,$Tbl3,$acc13 444 lwzx $acc11,$Tbl2,$acc11
434 xor $t2,$t2,$acc02 445 xor $t2,$t2,$acc02
435 xor $t3,$t3,$acc03 446 xor $t3,$t3,$acc03
436 lwzx $acc14,$Tbl3,$acc14 447 lwzx $acc12,$Tbl3,$acc12
437 lwzx $acc15,$Tbl3,$acc15 448 lwzx $acc13,$Tbl3,$acc13
438 xor $t0,$t0,$acc04 449 xor $t0,$t0,$acc04
439 xor $t1,$t1,$acc05 450 xor $t1,$t1,$acc05
451 lwzx $acc14,$Tbl3,$acc14
452 lwzx $acc15,$Tbl3,$acc15
440 xor $t2,$t2,$acc06 453 xor $t2,$t2,$acc06
441 xor $t3,$t3,$acc07 454 xor $t3,$t3,$acc07
442 xor $t0,$t0,$acc08 455 xor $t0,$t0,$acc08
@@ -452,60 +465,60 @@ Lenc_loop:
452 465
453 addi $Tbl2,$Tbl0,2048 466 addi $Tbl2,$Tbl0,2048
454 nop 467 nop
455 lwz $acc08,`2048+0`($Tbl0) ! prefetch Te4
456 lwz $acc09,`2048+32`($Tbl0)
457 lwz $acc10,`2048+64`($Tbl0)
458 lwz $acc11,`2048+96`($Tbl0)
459 lwz $acc08,`2048+128`($Tbl0)
460 lwz $acc09,`2048+160`($Tbl0)
461 lwz $acc10,`2048+192`($Tbl0)
462 lwz $acc11,`2048+224`($Tbl0)
463 rlwinm $acc00,$s0,`32-24`,24,31
464 rlwinm $acc01,$s1,`32-24`,24,31
465 lwz $t0,0($key) 468 lwz $t0,0($key)
466 lwz $t1,4($key) 469 lwz $t1,4($key)
467 rlwinm $acc02,$s2,`32-24`,24,31 470 rlwinm $acc00,$s0,`32-24`,24,31
468 rlwinm $acc03,$s3,`32-24`,24,31 471 rlwinm $acc01,$s1,`32-24`,24,31
469 lwz $t2,8($key) 472 lwz $t2,8($key)
470 lwz $t3,12($key) 473 lwz $t3,12($key)
474 rlwinm $acc02,$s2,`32-24`,24,31
475 rlwinm $acc03,$s3,`32-24`,24,31
476 lwz $acc08,`2048+0`($Tbl0) ! prefetch Te4
477 lwz $acc09,`2048+32`($Tbl0)
471 rlwinm $acc04,$s1,`32-16`,24,31 478 rlwinm $acc04,$s1,`32-16`,24,31
472 rlwinm $acc05,$s2,`32-16`,24,31 479 rlwinm $acc05,$s2,`32-16`,24,31
473 lbzx $acc00,$Tbl2,$acc00 480 lwz $acc10,`2048+64`($Tbl0)
474 lbzx $acc01,$Tbl2,$acc01 481 lwz $acc11,`2048+96`($Tbl0)
475 rlwinm $acc06,$s3,`32-16`,24,31 482 rlwinm $acc06,$s3,`32-16`,24,31
476 rlwinm $acc07,$s0,`32-16`,24,31 483 rlwinm $acc07,$s0,`32-16`,24,31
477 lbzx $acc02,$Tbl2,$acc02 484 lwz $acc12,`2048+128`($Tbl0)
478 lbzx $acc03,$Tbl2,$acc03 485 lwz $acc13,`2048+160`($Tbl0)
479 rlwinm $acc08,$s2,`32-8`,24,31 486 rlwinm $acc08,$s2,`32-8`,24,31
480 rlwinm $acc09,$s3,`32-8`,24,31 487 rlwinm $acc09,$s3,`32-8`,24,31
481 lbzx $acc04,$Tbl2,$acc04 488 lwz $acc14,`2048+192`($Tbl0)
482 lbzx $acc05,$Tbl2,$acc05 489 lwz $acc15,`2048+224`($Tbl0)
483 rlwinm $acc10,$s0,`32-8`,24,31 490 rlwinm $acc10,$s0,`32-8`,24,31
484 rlwinm $acc11,$s1,`32-8`,24,31 491 rlwinm $acc11,$s1,`32-8`,24,31
485 lbzx $acc06,$Tbl2,$acc06 492 lbzx $acc00,$Tbl2,$acc00
486 lbzx $acc07,$Tbl2,$acc07 493 lbzx $acc01,$Tbl2,$acc01
487 rlwinm $acc12,$s3,`0`,24,31 494 rlwinm $acc12,$s3,`0`,24,31
488 rlwinm $acc13,$s0,`0`,24,31 495 rlwinm $acc13,$s0,`0`,24,31
489 lbzx $acc08,$Tbl2,$acc08 496 lbzx $acc02,$Tbl2,$acc02
490 lbzx $acc09,$Tbl2,$acc09 497 lbzx $acc03,$Tbl2,$acc03
491 rlwinm $acc14,$s1,`0`,24,31 498 rlwinm $acc14,$s1,`0`,24,31
492 rlwinm $acc15,$s2,`0`,24,31 499 rlwinm $acc15,$s2,`0`,24,31
493 lbzx $acc10,$Tbl2,$acc10 500 lbzx $acc04,$Tbl2,$acc04
494 lbzx $acc11,$Tbl2,$acc11 501 lbzx $acc05,$Tbl2,$acc05
495 rlwinm $s0,$acc00,24,0,7 502 rlwinm $s0,$acc00,24,0,7
496 rlwinm $s1,$acc01,24,0,7 503 rlwinm $s1,$acc01,24,0,7
497 lbzx $acc12,$Tbl2,$acc12 504 lbzx $acc06,$Tbl2,$acc06
498 lbzx $acc13,$Tbl2,$acc13 505 lbzx $acc07,$Tbl2,$acc07
499 rlwinm $s2,$acc02,24,0,7 506 rlwinm $s2,$acc02,24,0,7
500 rlwinm $s3,$acc03,24,0,7 507 rlwinm $s3,$acc03,24,0,7
501 lbzx $acc14,$Tbl2,$acc14 508 lbzx $acc08,$Tbl2,$acc08
502 lbzx $acc15,$Tbl2,$acc15 509 lbzx $acc09,$Tbl2,$acc09
503 rlwimi $s0,$acc04,16,8,15 510 rlwimi $s0,$acc04,16,8,15
504 rlwimi $s1,$acc05,16,8,15 511 rlwimi $s1,$acc05,16,8,15
512 lbzx $acc10,$Tbl2,$acc10
513 lbzx $acc11,$Tbl2,$acc11
505 rlwimi $s2,$acc06,16,8,15 514 rlwimi $s2,$acc06,16,8,15
506 rlwimi $s3,$acc07,16,8,15 515 rlwimi $s3,$acc07,16,8,15
516 lbzx $acc12,$Tbl2,$acc12
517 lbzx $acc13,$Tbl2,$acc13
507 rlwimi $s0,$acc08,8,16,23 518 rlwimi $s0,$acc08,8,16,23
508 rlwimi $s1,$acc09,8,16,23 519 rlwimi $s1,$acc09,8,16,23
520 lbzx $acc14,$Tbl2,$acc14
521 lbzx $acc15,$Tbl2,$acc15
509 rlwimi $s2,$acc10,8,16,23 522 rlwimi $s2,$acc10,8,16,23
510 rlwimi $s3,$acc11,8,16,23 523 rlwimi $s3,$acc11,8,16,23
511 or $s0,$s0,$acc12 524 or $s0,$s0,$acc12
@@ -542,40 +555,40 @@ Lenc_compact_loop:
542 rlwinm $acc01,$s1,`32-24`,24,31 555 rlwinm $acc01,$s1,`32-24`,24,31
543 rlwinm $acc02,$s2,`32-24`,24,31 556 rlwinm $acc02,$s2,`32-24`,24,31
544 rlwinm $acc03,$s3,`32-24`,24,31 557 rlwinm $acc03,$s3,`32-24`,24,31
545 lbzx $acc00,$Tbl1,$acc00
546 lbzx $acc01,$Tbl1,$acc01
547 rlwinm $acc04,$s1,`32-16`,24,31 558 rlwinm $acc04,$s1,`32-16`,24,31
548 rlwinm $acc05,$s2,`32-16`,24,31 559 rlwinm $acc05,$s2,`32-16`,24,31
549 lbzx $acc02,$Tbl1,$acc02
550 lbzx $acc03,$Tbl1,$acc03
551 rlwinm $acc06,$s3,`32-16`,24,31 560 rlwinm $acc06,$s3,`32-16`,24,31
552 rlwinm $acc07,$s0,`32-16`,24,31 561 rlwinm $acc07,$s0,`32-16`,24,31
553 lbzx $acc04,$Tbl1,$acc04 562 lbzx $acc00,$Tbl1,$acc00
554 lbzx $acc05,$Tbl1,$acc05 563 lbzx $acc01,$Tbl1,$acc01
555 rlwinm $acc08,$s2,`32-8`,24,31 564 rlwinm $acc08,$s2,`32-8`,24,31
556 rlwinm $acc09,$s3,`32-8`,24,31 565 rlwinm $acc09,$s3,`32-8`,24,31
557 lbzx $acc06,$Tbl1,$acc06 566 lbzx $acc02,$Tbl1,$acc02
558 lbzx $acc07,$Tbl1,$acc07 567 lbzx $acc03,$Tbl1,$acc03
559 rlwinm $acc10,$s0,`32-8`,24,31 568 rlwinm $acc10,$s0,`32-8`,24,31
560 rlwinm $acc11,$s1,`32-8`,24,31 569 rlwinm $acc11,$s1,`32-8`,24,31
561 lbzx $acc08,$Tbl1,$acc08 570 lbzx $acc04,$Tbl1,$acc04
562 lbzx $acc09,$Tbl1,$acc09 571 lbzx $acc05,$Tbl1,$acc05
563 rlwinm $acc12,$s3,`0`,24,31 572 rlwinm $acc12,$s3,`0`,24,31
564 rlwinm $acc13,$s0,`0`,24,31 573 rlwinm $acc13,$s0,`0`,24,31
565 lbzx $acc10,$Tbl1,$acc10 574 lbzx $acc06,$Tbl1,$acc06
566 lbzx $acc11,$Tbl1,$acc11 575 lbzx $acc07,$Tbl1,$acc07
567 rlwinm $acc14,$s1,`0`,24,31 576 rlwinm $acc14,$s1,`0`,24,31
568 rlwinm $acc15,$s2,`0`,24,31 577 rlwinm $acc15,$s2,`0`,24,31
569 lbzx $acc12,$Tbl1,$acc12 578 lbzx $acc08,$Tbl1,$acc08
570 lbzx $acc13,$Tbl1,$acc13 579 lbzx $acc09,$Tbl1,$acc09
571 rlwinm $s0,$acc00,24,0,7 580 rlwinm $s0,$acc00,24,0,7
572 rlwinm $s1,$acc01,24,0,7 581 rlwinm $s1,$acc01,24,0,7
573 lbzx $acc14,$Tbl1,$acc14 582 lbzx $acc10,$Tbl1,$acc10
574 lbzx $acc15,$Tbl1,$acc15 583 lbzx $acc11,$Tbl1,$acc11
575 rlwinm $s2,$acc02,24,0,7 584 rlwinm $s2,$acc02,24,0,7
576 rlwinm $s3,$acc03,24,0,7 585 rlwinm $s3,$acc03,24,0,7
586 lbzx $acc12,$Tbl1,$acc12
587 lbzx $acc13,$Tbl1,$acc13
577 rlwimi $s0,$acc04,16,8,15 588 rlwimi $s0,$acc04,16,8,15
578 rlwimi $s1,$acc05,16,8,15 589 rlwimi $s1,$acc05,16,8,15
590 lbzx $acc14,$Tbl1,$acc14
591 lbzx $acc15,$Tbl1,$acc15
579 rlwimi $s2,$acc06,16,8,15 592 rlwimi $s2,$acc06,16,8,15
580 rlwimi $s3,$acc07,16,8,15 593 rlwimi $s3,$acc07,16,8,15
581 rlwimi $s0,$acc08,8,16,23 594 rlwimi $s0,$acc08,8,16,23
@@ -725,7 +738,7 @@ Lenc_compact_done:
725 addi $sp,$sp,$FRAME 738 addi $sp,$sp,$FRAME
726 blr 739 blr
727 740
728.align 4 741.align 5
729Lppc_AES_decrypt: 742Lppc_AES_decrypt:
730 lwz $acc00,240($key) 743 lwz $acc00,240($key)
731 lwz $t0,0($key) 744 lwz $t0,0($key)
@@ -746,46 +759,46 @@ Lppc_AES_decrypt:
746Ldec_loop: 759Ldec_loop:
747 rlwinm $acc00,$s0,`32-24+3`,21,28 760 rlwinm $acc00,$s0,`32-24+3`,21,28
748 rlwinm $acc01,$s1,`32-24+3`,21,28 761 rlwinm $acc01,$s1,`32-24+3`,21,28
749 lwz $t0,0($key)
750 lwz $t1,4($key)
751 rlwinm $acc02,$s2,`32-24+3`,21,28 762 rlwinm $acc02,$s2,`32-24+3`,21,28
752 rlwinm $acc03,$s3,`32-24+3`,21,28 763 rlwinm $acc03,$s3,`32-24+3`,21,28
753 lwz $t2,8($key) 764 lwz $t0,0($key)
754 lwz $t3,12($key) 765 lwz $t1,4($key)
755 rlwinm $acc04,$s3,`32-16+3`,21,28 766 rlwinm $acc04,$s3,`32-16+3`,21,28
756 rlwinm $acc05,$s0,`32-16+3`,21,28 767 rlwinm $acc05,$s0,`32-16+3`,21,28
757 lwzx $acc00,$Tbl0,$acc00 768 lwz $t2,8($key)
758 lwzx $acc01,$Tbl0,$acc01 769 lwz $t3,12($key)
759 rlwinm $acc06,$s1,`32-16+3`,21,28 770 rlwinm $acc06,$s1,`32-16+3`,21,28
760 rlwinm $acc07,$s2,`32-16+3`,21,28 771 rlwinm $acc07,$s2,`32-16+3`,21,28
761 lwzx $acc02,$Tbl0,$acc02 772 lwzx $acc00,$Tbl0,$acc00
762 lwzx $acc03,$Tbl0,$acc03 773 lwzx $acc01,$Tbl0,$acc01
763 rlwinm $acc08,$s2,`32-8+3`,21,28 774 rlwinm $acc08,$s2,`32-8+3`,21,28
764 rlwinm $acc09,$s3,`32-8+3`,21,28 775 rlwinm $acc09,$s3,`32-8+3`,21,28
765 lwzx $acc04,$Tbl1,$acc04 776 lwzx $acc02,$Tbl0,$acc02
766 lwzx $acc05,$Tbl1,$acc05 777 lwzx $acc03,$Tbl0,$acc03
767 rlwinm $acc10,$s0,`32-8+3`,21,28 778 rlwinm $acc10,$s0,`32-8+3`,21,28
768 rlwinm $acc11,$s1,`32-8+3`,21,28 779 rlwinm $acc11,$s1,`32-8+3`,21,28
769 lwzx $acc06,$Tbl1,$acc06 780 lwzx $acc04,$Tbl1,$acc04
770 lwzx $acc07,$Tbl1,$acc07 781 lwzx $acc05,$Tbl1,$acc05
771 rlwinm $acc12,$s1,`0+3`,21,28 782 rlwinm $acc12,$s1,`0+3`,21,28
772 rlwinm $acc13,$s2,`0+3`,21,28 783 rlwinm $acc13,$s2,`0+3`,21,28
773 lwzx $acc08,$Tbl2,$acc08 784 lwzx $acc06,$Tbl1,$acc06
774 lwzx $acc09,$Tbl2,$acc09 785 lwzx $acc07,$Tbl1,$acc07
775 rlwinm $acc14,$s3,`0+3`,21,28 786 rlwinm $acc14,$s3,`0+3`,21,28
776 rlwinm $acc15,$s0,`0+3`,21,28 787 rlwinm $acc15,$s0,`0+3`,21,28
777 lwzx $acc10,$Tbl2,$acc10 788 lwzx $acc08,$Tbl2,$acc08
778 lwzx $acc11,$Tbl2,$acc11 789 lwzx $acc09,$Tbl2,$acc09
779 xor $t0,$t0,$acc00 790 xor $t0,$t0,$acc00
780 xor $t1,$t1,$acc01 791 xor $t1,$t1,$acc01
781 lwzx $acc12,$Tbl3,$acc12 792 lwzx $acc10,$Tbl2,$acc10
782 lwzx $acc13,$Tbl3,$acc13 793 lwzx $acc11,$Tbl2,$acc11
783 xor $t2,$t2,$acc02 794 xor $t2,$t2,$acc02
784 xor $t3,$t3,$acc03 795 xor $t3,$t3,$acc03
785 lwzx $acc14,$Tbl3,$acc14 796 lwzx $acc12,$Tbl3,$acc12
786 lwzx $acc15,$Tbl3,$acc15 797 lwzx $acc13,$Tbl3,$acc13
787 xor $t0,$t0,$acc04 798 xor $t0,$t0,$acc04
788 xor $t1,$t1,$acc05 799 xor $t1,$t1,$acc05
800 lwzx $acc14,$Tbl3,$acc14
801 lwzx $acc15,$Tbl3,$acc15
789 xor $t2,$t2,$acc06 802 xor $t2,$t2,$acc06
790 xor $t3,$t3,$acc07 803 xor $t3,$t3,$acc07
791 xor $t0,$t0,$acc08 804 xor $t0,$t0,$acc08
@@ -801,56 +814,56 @@ Ldec_loop:
801 814
802 addi $Tbl2,$Tbl0,2048 815 addi $Tbl2,$Tbl0,2048
803 nop 816 nop
804 lwz $acc08,`2048+0`($Tbl0) ! prefetch Td4
805 lwz $acc09,`2048+32`($Tbl0)
806 lwz $acc10,`2048+64`($Tbl0)
807 lwz $acc11,`2048+96`($Tbl0)
808 lwz $acc08,`2048+128`($Tbl0)
809 lwz $acc09,`2048+160`($Tbl0)
810 lwz $acc10,`2048+192`($Tbl0)
811 lwz $acc11,`2048+224`($Tbl0)
812 rlwinm $acc00,$s0,`32-24`,24,31
813 rlwinm $acc01,$s1,`32-24`,24,31
814 lwz $t0,0($key) 817 lwz $t0,0($key)
815 lwz $t1,4($key) 818 lwz $t1,4($key)
816 rlwinm $acc02,$s2,`32-24`,24,31 819 rlwinm $acc00,$s0,`32-24`,24,31
817 rlwinm $acc03,$s3,`32-24`,24,31 820 rlwinm $acc01,$s1,`32-24`,24,31
818 lwz $t2,8($key) 821 lwz $t2,8($key)
819 lwz $t3,12($key) 822 lwz $t3,12($key)
823 rlwinm $acc02,$s2,`32-24`,24,31
824 rlwinm $acc03,$s3,`32-24`,24,31
825 lwz $acc08,`2048+0`($Tbl0) ! prefetch Td4
826 lwz $acc09,`2048+32`($Tbl0)
820 rlwinm $acc04,$s3,`32-16`,24,31 827 rlwinm $acc04,$s3,`32-16`,24,31
821 rlwinm $acc05,$s0,`32-16`,24,31 828 rlwinm $acc05,$s0,`32-16`,24,31
829 lwz $acc10,`2048+64`($Tbl0)
830 lwz $acc11,`2048+96`($Tbl0)
822 lbzx $acc00,$Tbl2,$acc00 831 lbzx $acc00,$Tbl2,$acc00
823 lbzx $acc01,$Tbl2,$acc01 832 lbzx $acc01,$Tbl2,$acc01
833 lwz $acc12,`2048+128`($Tbl0)
834 lwz $acc13,`2048+160`($Tbl0)
824 rlwinm $acc06,$s1,`32-16`,24,31 835 rlwinm $acc06,$s1,`32-16`,24,31
825 rlwinm $acc07,$s2,`32-16`,24,31 836 rlwinm $acc07,$s2,`32-16`,24,31
826 lbzx $acc02,$Tbl2,$acc02 837 lwz $acc14,`2048+192`($Tbl0)
827 lbzx $acc03,$Tbl2,$acc03 838 lwz $acc15,`2048+224`($Tbl0)
828 rlwinm $acc08,$s2,`32-8`,24,31 839 rlwinm $acc08,$s2,`32-8`,24,31
829 rlwinm $acc09,$s3,`32-8`,24,31 840 rlwinm $acc09,$s3,`32-8`,24,31
830 lbzx $acc04,$Tbl2,$acc04 841 lbzx $acc02,$Tbl2,$acc02
831 lbzx $acc05,$Tbl2,$acc05 842 lbzx $acc03,$Tbl2,$acc03
832 rlwinm $acc10,$s0,`32-8`,24,31 843 rlwinm $acc10,$s0,`32-8`,24,31
833 rlwinm $acc11,$s1,`32-8`,24,31 844 rlwinm $acc11,$s1,`32-8`,24,31
834 lbzx $acc06,$Tbl2,$acc06 845 lbzx $acc04,$Tbl2,$acc04
835 lbzx $acc07,$Tbl2,$acc07 846 lbzx $acc05,$Tbl2,$acc05
836 rlwinm $acc12,$s1,`0`,24,31 847 rlwinm $acc12,$s1,`0`,24,31
837 rlwinm $acc13,$s2,`0`,24,31 848 rlwinm $acc13,$s2,`0`,24,31
838 lbzx $acc08,$Tbl2,$acc08 849 lbzx $acc06,$Tbl2,$acc06
839 lbzx $acc09,$Tbl2,$acc09 850 lbzx $acc07,$Tbl2,$acc07
840 rlwinm $acc14,$s3,`0`,24,31 851 rlwinm $acc14,$s3,`0`,24,31
841 rlwinm $acc15,$s0,`0`,24,31 852 rlwinm $acc15,$s0,`0`,24,31
842 lbzx $acc10,$Tbl2,$acc10 853 lbzx $acc08,$Tbl2,$acc08
843 lbzx $acc11,$Tbl2,$acc11 854 lbzx $acc09,$Tbl2,$acc09
844 rlwinm $s0,$acc00,24,0,7 855 rlwinm $s0,$acc00,24,0,7
845 rlwinm $s1,$acc01,24,0,7 856 rlwinm $s1,$acc01,24,0,7
846 lbzx $acc12,$Tbl2,$acc12 857 lbzx $acc10,$Tbl2,$acc10
847 lbzx $acc13,$Tbl2,$acc13 858 lbzx $acc11,$Tbl2,$acc11
848 rlwinm $s2,$acc02,24,0,7 859 rlwinm $s2,$acc02,24,0,7
849 rlwinm $s3,$acc03,24,0,7 860 rlwinm $s3,$acc03,24,0,7
850 lbzx $acc14,$Tbl2,$acc14 861 lbzx $acc12,$Tbl2,$acc12
851 lbzx $acc15,$Tbl2,$acc15 862 lbzx $acc13,$Tbl2,$acc13
852 rlwimi $s0,$acc04,16,8,15 863 rlwimi $s0,$acc04,16,8,15
853 rlwimi $s1,$acc05,16,8,15 864 rlwimi $s1,$acc05,16,8,15
865 lbzx $acc14,$Tbl2,$acc14
866 lbzx $acc15,$Tbl2,$acc15
854 rlwimi $s2,$acc06,16,8,15 867 rlwimi $s2,$acc06,16,8,15
855 rlwimi $s3,$acc07,16,8,15 868 rlwimi $s3,$acc07,16,8,15
856 rlwimi $s0,$acc08,8,16,23 869 rlwimi $s0,$acc08,8,16,23
@@ -897,40 +910,40 @@ Ldec_compact_loop:
897 rlwinm $acc01,$s1,`32-24`,24,31 910 rlwinm $acc01,$s1,`32-24`,24,31
898 rlwinm $acc02,$s2,`32-24`,24,31 911 rlwinm $acc02,$s2,`32-24`,24,31
899 rlwinm $acc03,$s3,`32-24`,24,31 912 rlwinm $acc03,$s3,`32-24`,24,31
900 lbzx $acc00,$Tbl1,$acc00
901 lbzx $acc01,$Tbl1,$acc01
902 rlwinm $acc04,$s3,`32-16`,24,31 913 rlwinm $acc04,$s3,`32-16`,24,31
903 rlwinm $acc05,$s0,`32-16`,24,31 914 rlwinm $acc05,$s0,`32-16`,24,31
904 lbzx $acc02,$Tbl1,$acc02
905 lbzx $acc03,$Tbl1,$acc03
906 rlwinm $acc06,$s1,`32-16`,24,31 915 rlwinm $acc06,$s1,`32-16`,24,31
907 rlwinm $acc07,$s2,`32-16`,24,31 916 rlwinm $acc07,$s2,`32-16`,24,31
908 lbzx $acc04,$Tbl1,$acc04 917 lbzx $acc00,$Tbl1,$acc00
909 lbzx $acc05,$Tbl1,$acc05 918 lbzx $acc01,$Tbl1,$acc01
910 rlwinm $acc08,$s2,`32-8`,24,31 919 rlwinm $acc08,$s2,`32-8`,24,31
911 rlwinm $acc09,$s3,`32-8`,24,31 920 rlwinm $acc09,$s3,`32-8`,24,31
912 lbzx $acc06,$Tbl1,$acc06 921 lbzx $acc02,$Tbl1,$acc02
913 lbzx $acc07,$Tbl1,$acc07 922 lbzx $acc03,$Tbl1,$acc03
914 rlwinm $acc10,$s0,`32-8`,24,31 923 rlwinm $acc10,$s0,`32-8`,24,31
915 rlwinm $acc11,$s1,`32-8`,24,31 924 rlwinm $acc11,$s1,`32-8`,24,31
916 lbzx $acc08,$Tbl1,$acc08 925 lbzx $acc04,$Tbl1,$acc04
917 lbzx $acc09,$Tbl1,$acc09 926 lbzx $acc05,$Tbl1,$acc05
918 rlwinm $acc12,$s1,`0`,24,31 927 rlwinm $acc12,$s1,`0`,24,31
919 rlwinm $acc13,$s2,`0`,24,31 928 rlwinm $acc13,$s2,`0`,24,31
920 lbzx $acc10,$Tbl1,$acc10 929 lbzx $acc06,$Tbl1,$acc06
921 lbzx $acc11,$Tbl1,$acc11 930 lbzx $acc07,$Tbl1,$acc07
922 rlwinm $acc14,$s3,`0`,24,31 931 rlwinm $acc14,$s3,`0`,24,31
923 rlwinm $acc15,$s0,`0`,24,31 932 rlwinm $acc15,$s0,`0`,24,31
924 lbzx $acc12,$Tbl1,$acc12 933 lbzx $acc08,$Tbl1,$acc08
925 lbzx $acc13,$Tbl1,$acc13 934 lbzx $acc09,$Tbl1,$acc09
926 rlwinm $s0,$acc00,24,0,7 935 rlwinm $s0,$acc00,24,0,7
927 rlwinm $s1,$acc01,24,0,7 936 rlwinm $s1,$acc01,24,0,7
928 lbzx $acc14,$Tbl1,$acc14 937 lbzx $acc10,$Tbl1,$acc10
929 lbzx $acc15,$Tbl1,$acc15 938 lbzx $acc11,$Tbl1,$acc11
930 rlwinm $s2,$acc02,24,0,7 939 rlwinm $s2,$acc02,24,0,7
931 rlwinm $s3,$acc03,24,0,7 940 rlwinm $s3,$acc03,24,0,7
941 lbzx $acc12,$Tbl1,$acc12
942 lbzx $acc13,$Tbl1,$acc13
932 rlwimi $s0,$acc04,16,8,15 943 rlwimi $s0,$acc04,16,8,15
933 rlwimi $s1,$acc05,16,8,15 944 rlwimi $s1,$acc05,16,8,15
945 lbzx $acc14,$Tbl1,$acc14
946 lbzx $acc15,$Tbl1,$acc15
934 rlwimi $s2,$acc06,16,8,15 947 rlwimi $s2,$acc06,16,8,15
935 rlwimi $s3,$acc07,16,8,15 948 rlwimi $s3,$acc07,16,8,15
936 rlwimi $s0,$acc08,8,16,23 949 rlwimi $s0,$acc08,8,16,23
diff --git a/src/lib/libcrypto/aes/asm/aes-s390x.pl b/src/lib/libcrypto/aes/asm/aes-s390x.pl
index 4b27afd92f..7e01889298 100644
--- a/src/lib/libcrypto/aes/asm/aes-s390x.pl
+++ b/src/lib/libcrypto/aes/asm/aes-s390x.pl
@@ -765,6 +765,11 @@ $code.=<<___ if (!$softonly);
765 srl %r5,6 765 srl %r5,6
766 ar %r5,%r0 766 ar %r5,%r0
767 767
768 larl %r1,OPENSSL_s390xcap_P
769 lg %r0,0(%r1)
770 tmhl %r0,0x4000 # check for message-security assist
771 jz .Lekey_internal
772
768 lghi %r0,0 # query capability vector 773 lghi %r0,0 # query capability vector
769 la %r1,16($sp) 774 la %r1,16($sp)
770 .long 0xb92f0042 # kmc %r4,%r2 775 .long 0xb92f0042 # kmc %r4,%r2
@@ -1323,6 +1328,7 @@ $code.=<<___;
13234: ex $len,0($s1) 13284: ex $len,0($s1)
1324 j .Lcbc_dec_exit 1329 j .Lcbc_dec_exit
1325.size AES_cbc_encrypt,.-AES_cbc_encrypt 1330.size AES_cbc_encrypt,.-AES_cbc_encrypt
1331.comm OPENSSL_s390xcap_P,8,8
1326___ 1332___
1327} 1333}
1328$code.=<<___; 1334$code.=<<___;
diff --git a/src/lib/libcrypto/aes/asm/aes-x86_64.pl b/src/lib/libcrypto/aes/asm/aes-x86_64.pl
index f616f1751f..a545e892ae 100755
--- a/src/lib/libcrypto/aes/asm/aes-x86_64.pl
+++ b/src/lib/libcrypto/aes/asm/aes-x86_64.pl
@@ -2,11 +2,12 @@
2# 2#
3# ==================================================================== 3# ====================================================================
4# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL 4# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
5# project. Rights for redistribution and usage in source and binary 5# project. The module is, however, dual licensed under OpenSSL and
6# forms are granted according to the OpenSSL license. 6# CRYPTOGAMS licenses depending on where you obtain it. For further
7# details see http://www.openssl.org/~appro/cryptogams/.
7# ==================================================================== 8# ====================================================================
8# 9#
9# Version 1.2. 10# Version 2.1.
10# 11#
11# aes-*-cbc benchmarks are improved by >70% [compared to gcc 3.3.2 on 12# aes-*-cbc benchmarks are improved by >70% [compared to gcc 3.3.2 on
12# Opteron 240 CPU] plus all the bells-n-whistles from 32-bit version 13# Opteron 240 CPU] plus all the bells-n-whistles from 32-bit version
@@ -17,17 +18,29 @@
17# 18#
18# Performance in number of cycles per processed byte for 128-bit key: 19# Performance in number of cycles per processed byte for 128-bit key:
19# 20#
20# ECB CBC encrypt 21# ECB encrypt ECB decrypt CBC large chunk
21# AMD64 13.7 13.0(*) 22# AMD64 33 41 13.0
22# EM64T 20.2 18.6(*) 23# EM64T 38 59 18.6(*)
24# Core 2 30 43 14.5(*)
23# 25#
24# (*) CBC benchmarks are better than ECB thanks to custom ABI used 26# (*) with hyper-threading off
25# by the private block encryption function. 27
28$flavour = shift;
29$output = shift;
30if ($flavour =~ /\./) { $output = $flavour; undef $flavour; }
31
32$win64=0; $win64=1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/);
33
34$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
35( $xlate="${dir}x86_64-xlate.pl" and -f $xlate ) or
36( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or
37die "can't locate x86_64-xlate.pl";
38
39open STDOUT,"| $^X $xlate $flavour $output";
26 40
27$verticalspin=1; # unlike 32-bit version $verticalspin performs 41$verticalspin=1; # unlike 32-bit version $verticalspin performs
28 # ~15% better on both AMD and Intel cores 42 # ~15% better on both AMD and Intel cores
29$output=shift; 43$speed_limit=512; # see aes-586.pl for details
30open STDOUT,"| $^X ../perlasm/x86_64-xlate.pl $output";
31 44
32$code=".text\n"; 45$code=".text\n";
33 46
@@ -35,9 +48,9 @@ $s0="%eax";
35$s1="%ebx"; 48$s1="%ebx";
36$s2="%ecx"; 49$s2="%ecx";
37$s3="%edx"; 50$s3="%edx";
38$acc0="%esi"; 51$acc0="%esi"; $mask80="%rsi";
39$acc1="%edi"; 52$acc1="%edi"; $maskfe="%rdi";
40$acc2="%ebp"; 53$acc2="%ebp"; $mask1b="%rbp";
41$inp="%r8"; 54$inp="%r8";
42$out="%r9"; 55$out="%r9";
43$t0="%r10d"; 56$t0="%r10d";
@@ -51,6 +64,8 @@ sub hi() { my $r=shift; $r =~ s/%[er]([a-d])x/%\1h/; $r; }
51sub lo() { my $r=shift; $r =~ s/%[er]([a-d])x/%\1l/; 64sub lo() { my $r=shift; $r =~ s/%[er]([a-d])x/%\1l/;
52 $r =~ s/%[er]([sd]i)/%\1l/; 65 $r =~ s/%[er]([sd]i)/%\1l/;
53 $r =~ s/%(r[0-9]+)[d]?/%\1b/; $r; } 66 $r =~ s/%(r[0-9]+)[d]?/%\1b/; $r; }
67sub LO() { my $r=shift; $r =~ s/%r([a-z]+)/%e\1/;
68 $r =~ s/%r([0-9]+)/%r\1d/; $r; }
54sub _data_word() 69sub _data_word()
55{ my $i; 70{ my $i;
56 while(defined($i=shift)) { $code.=sprintf".long\t0x%08x,0x%08x\n",$i,$i; } 71 while(defined($i=shift)) { $code.=sprintf".long\t0x%08x,0x%08x\n",$i,$i; }
@@ -138,22 +153,17 @@ $code.=<<___;
138 movzb `&lo("$s0")`,$acc0 153 movzb `&lo("$s0")`,$acc0
139 movzb `&lo("$s1")`,$acc1 154 movzb `&lo("$s1")`,$acc1
140 movzb `&lo("$s2")`,$acc2 155 movzb `&lo("$s2")`,$acc2
141 mov 2($sbox,$acc0,8),$t0 156 movzb 2($sbox,$acc0,8),$t0
142 mov 2($sbox,$acc1,8),$t1 157 movzb 2($sbox,$acc1,8),$t1
143 mov 2($sbox,$acc2,8),$t2 158 movzb 2($sbox,$acc2,8),$t2
144
145 and \$0x000000ff,$t0
146 and \$0x000000ff,$t1
147 and \$0x000000ff,$t2
148 159
149 movzb `&lo("$s3")`,$acc0 160 movzb `&lo("$s3")`,$acc0
150 movzb `&hi("$s1")`,$acc1 161 movzb `&hi("$s1")`,$acc1
151 movzb `&hi("$s2")`,$acc2 162 movzb `&hi("$s2")`,$acc2
152 mov 2($sbox,$acc0,8),$t3 163 movzb 2($sbox,$acc0,8),$t3
153 mov 0($sbox,$acc1,8),$acc1 #$t0 164 mov 0($sbox,$acc1,8),$acc1 #$t0
154 mov 0($sbox,$acc2,8),$acc2 #$t1 165 mov 0($sbox,$acc2,8),$acc2 #$t1
155 166
156 and \$0x000000ff,$t3
157 and \$0x0000ff00,$acc1 167 and \$0x0000ff00,$acc1
158 and \$0x0000ff00,$acc2 168 and \$0x0000ff00,$acc2
159 169
@@ -345,6 +355,234 @@ $code.=<<___;
345.size _x86_64_AES_encrypt,.-_x86_64_AES_encrypt 355.size _x86_64_AES_encrypt,.-_x86_64_AES_encrypt
346___ 356___
347 357
358# it's possible to implement this by shifting tN by 8, filling least
359# significant byte with byte load and finally bswap-ing at the end,
360# but such partial register load kills Core 2...
361sub enccompactvert()
362{ my ($t3,$t4,$t5)=("%r8d","%r9d","%r13d");
363
364$code.=<<___;
365 movzb `&lo("$s0")`,$t0
366 movzb `&lo("$s1")`,$t1
367 movzb `&lo("$s2")`,$t2
368 movzb ($sbox,$t0,1),$t0
369 movzb ($sbox,$t1,1),$t1
370 movzb ($sbox,$t2,1),$t2
371
372 movzb `&lo("$s3")`,$t3
373 movzb `&hi("$s1")`,$acc0
374 movzb `&hi("$s2")`,$acc1
375 movzb ($sbox,$t3,1),$t3
376 movzb ($sbox,$acc0,1),$t4 #$t0
377 movzb ($sbox,$acc1,1),$t5 #$t1
378
379 movzb `&hi("$s3")`,$acc2
380 movzb `&hi("$s0")`,$acc0
381 shr \$16,$s2
382 movzb ($sbox,$acc2,1),$acc2 #$t2
383 movzb ($sbox,$acc0,1),$acc0 #$t3
384 shr \$16,$s3
385
386 movzb `&lo("$s2")`,$acc1
387 shl \$8,$t4
388 shl \$8,$t5
389 movzb ($sbox,$acc1,1),$acc1 #$t0
390 xor $t4,$t0
391 xor $t5,$t1
392
393 movzb `&lo("$s3")`,$t4
394 shr \$16,$s0
395 shr \$16,$s1
396 movzb `&lo("$s0")`,$t5
397 shl \$8,$acc2
398 shl \$8,$acc0
399 movzb ($sbox,$t4,1),$t4 #$t1
400 movzb ($sbox,$t5,1),$t5 #$t2
401 xor $acc2,$t2
402 xor $acc0,$t3
403
404 movzb `&lo("$s1")`,$acc2
405 movzb `&hi("$s3")`,$acc0
406 shl \$16,$acc1
407 movzb ($sbox,$acc2,1),$acc2 #$t3
408 movzb ($sbox,$acc0,1),$acc0 #$t0
409 xor $acc1,$t0
410
411 movzb `&hi("$s0")`,$acc1
412 shr \$8,$s2
413 shr \$8,$s1
414 movzb ($sbox,$acc1,1),$acc1 #$t1
415 movzb ($sbox,$s2,1),$s3 #$t3
416 movzb ($sbox,$s1,1),$s2 #$t2
417 shl \$16,$t4
418 shl \$16,$t5
419 shl \$16,$acc2
420 xor $t4,$t1
421 xor $t5,$t2
422 xor $acc2,$t3
423
424 shl \$24,$acc0
425 shl \$24,$acc1
426 shl \$24,$s3
427 xor $acc0,$t0
428 shl \$24,$s2
429 xor $acc1,$t1
430 mov $t0,$s0
431 mov $t1,$s1
432 xor $t2,$s2
433 xor $t3,$s3
434___
435}
436
437sub enctransform_ref()
438{ my $sn = shift;
439 my ($acc,$r2,$tmp)=("%r8d","%r9d","%r13d");
440
441$code.=<<___;
442 mov $sn,$acc
443 and \$0x80808080,$acc
444 mov $acc,$tmp
445 shr \$7,$tmp
446 lea ($sn,$sn),$r2
447 sub $tmp,$acc
448 and \$0xfefefefe,$r2
449 and \$0x1b1b1b1b,$acc
450 mov $sn,$tmp
451 xor $acc,$r2
452
453 xor $r2,$sn
454 rol \$24,$sn
455 xor $r2,$sn
456 ror \$16,$tmp
457 xor $tmp,$sn
458 ror \$8,$tmp
459 xor $tmp,$sn
460___
461}
462
463# unlike decrypt case it does not pay off to parallelize enctransform
464sub enctransform()
465{ my ($t3,$r20,$r21)=($acc2,"%r8d","%r9d");
466
467$code.=<<___;
468 mov $s0,$acc0
469 mov $s1,$acc1
470 and \$0x80808080,$acc0
471 and \$0x80808080,$acc1
472 mov $acc0,$t0
473 mov $acc1,$t1
474 shr \$7,$t0
475 lea ($s0,$s0),$r20
476 shr \$7,$t1
477 lea ($s1,$s1),$r21
478 sub $t0,$acc0
479 sub $t1,$acc1
480 and \$0xfefefefe,$r20
481 and \$0xfefefefe,$r21
482 and \$0x1b1b1b1b,$acc0
483 and \$0x1b1b1b1b,$acc1
484 mov $s0,$t0
485 mov $s1,$t1
486 xor $acc0,$r20
487 xor $acc1,$r21
488
489 xor $r20,$s0
490 xor $r21,$s1
491 mov $s2,$acc0
492 mov $s3,$acc1
493 rol \$24,$s0
494 rol \$24,$s1
495 and \$0x80808080,$acc0
496 and \$0x80808080,$acc1
497 xor $r20,$s0
498 xor $r21,$s1
499 mov $acc0,$t2
500 mov $acc1,$t3
501 ror \$16,$t0
502 ror \$16,$t1
503 shr \$7,$t2
504 lea ($s2,$s2),$r20
505 xor $t0,$s0
506 xor $t1,$s1
507 shr \$7,$t3
508 lea ($s3,$s3),$r21
509 ror \$8,$t0
510 ror \$8,$t1
511 sub $t2,$acc0
512 sub $t3,$acc1
513 xor $t0,$s0
514 xor $t1,$s1
515
516 and \$0xfefefefe,$r20
517 and \$0xfefefefe,$r21
518 and \$0x1b1b1b1b,$acc0
519 and \$0x1b1b1b1b,$acc1
520 mov $s2,$t2
521 mov $s3,$t3
522 xor $acc0,$r20
523 xor $acc1,$r21
524
525 xor $r20,$s2
526 xor $r21,$s3
527 rol \$24,$s2
528 rol \$24,$s3
529 xor $r20,$s2
530 xor $r21,$s3
531 mov 0($sbox),$acc0 # prefetch Te4
532 ror \$16,$t2
533 ror \$16,$t3
534 mov 64($sbox),$acc1
535 xor $t2,$s2
536 xor $t3,$s3
537 mov 128($sbox),$r20
538 ror \$8,$t2
539 ror \$8,$t3
540 mov 192($sbox),$r21
541 xor $t2,$s2
542 xor $t3,$s3
543___
544}
545
546$code.=<<___;
547.type _x86_64_AES_encrypt_compact,\@abi-omnipotent
548.align 16
549_x86_64_AES_encrypt_compact:
550 lea 128($sbox),$inp # size optimization
551 mov 0-128($inp),$acc1 # prefetch Te4
552 mov 32-128($inp),$acc2
553 mov 64-128($inp),$t0
554 mov 96-128($inp),$t1
555 mov 128-128($inp),$acc1
556 mov 160-128($inp),$acc2
557 mov 192-128($inp),$t0
558 mov 224-128($inp),$t1
559 jmp .Lenc_loop_compact
560.align 16
561.Lenc_loop_compact:
562 xor 0($key),$s0 # xor with key
563 xor 4($key),$s1
564 xor 8($key),$s2
565 xor 12($key),$s3
566 lea 16($key),$key
567___
568 &enccompactvert();
569$code.=<<___;
570 cmp 16(%rsp),$key
571 je .Lenc_compact_done
572___
573 &enctransform();
574$code.=<<___;
575 jmp .Lenc_loop_compact
576.align 16
577.Lenc_compact_done:
578 xor 0($key),$s0
579 xor 4($key),$s1
580 xor 8($key),$s2
581 xor 12($key),$s3
582 .byte 0xf3,0xc3 # rep ret
583.size _x86_64_AES_encrypt_compact,.-_x86_64_AES_encrypt_compact
584___
585
348# void AES_encrypt (const void *inp,void *out,const AES_KEY *key); 586# void AES_encrypt (const void *inp,void *out,const AES_KEY *key);
349$code.=<<___; 587$code.=<<___;
350.globl AES_encrypt 588.globl AES_encrypt
@@ -358,31 +596,57 @@ AES_encrypt:
358 push %r14 596 push %r14
359 push %r15 597 push %r15
360 598
361 mov %rdx,$key 599 # allocate frame "above" key schedule
362 mov %rdi,$inp 600 mov %rsp,%r10
363 mov %rsi,$out 601 lea -63(%rdx),%rcx # %rdx is key argument
364 602 and \$-64,%rsp
365 .picmeup $sbox 603 sub %rsp,%rcx
366 lea AES_Te-.($sbox),$sbox 604 neg %rcx
367 605 and \$0x3c0,%rcx
368 mov 0($inp),$s0 606 sub %rcx,%rsp
369 mov 4($inp),$s1 607 sub \$32,%rsp
370 mov 8($inp),$s2
371 mov 12($inp),$s3
372 608
373 call _x86_64_AES_encrypt 609 mov %rsi,16(%rsp) # save out
610 mov %r10,24(%rsp) # save real stack pointer
611.Lenc_prologue:
374 612
375 mov $s0,0($out) 613 mov %rdx,$key
614 mov 240($key),$rnds # load rounds
615
616 mov 0(%rdi),$s0 # load input vector
617 mov 4(%rdi),$s1
618 mov 8(%rdi),$s2
619 mov 12(%rdi),$s3
620
621 shl \$4,$rnds
622 lea ($key,$rnds),%rbp
623 mov $key,(%rsp) # key schedule
624 mov %rbp,8(%rsp) # end of key schedule
625
626 # pick Te4 copy which can't "overlap" with stack frame or key schedule
627 lea .LAES_Te+2048(%rip),$sbox
628 lea 768(%rsp),%rbp
629 sub $sbox,%rbp
630 and \$0x300,%rbp
631 lea ($sbox,%rbp),$sbox
632
633 call _x86_64_AES_encrypt_compact
634
635 mov 16(%rsp),$out # restore out
636 mov 24(%rsp),%rsi # restore saved stack pointer
637 mov $s0,0($out) # write output vector
376 mov $s1,4($out) 638 mov $s1,4($out)
377 mov $s2,8($out) 639 mov $s2,8($out)
378 mov $s3,12($out) 640 mov $s3,12($out)
379 641
380 pop %r15 642 mov (%rsi),%r15
381 pop %r14 643 mov 8(%rsi),%r14
382 pop %r13 644 mov 16(%rsi),%r13
383 pop %r12 645 mov 24(%rsi),%r12
384 pop %rbp 646 mov 32(%rsi),%rbp
385 pop %rbx 647 mov 40(%rsi),%rbx
648 lea 48(%rsi),%rsp
649.Lenc_epilogue:
386 ret 650 ret
387.size AES_encrypt,.-AES_encrypt 651.size AES_encrypt,.-AES_encrypt
388___ 652___
@@ -453,19 +717,20 @@ sub declastvert()
453{ my $t3="%r8d"; # zaps $inp! 717{ my $t3="%r8d"; # zaps $inp!
454 718
455$code.=<<___; 719$code.=<<___;
720 lea 2048($sbox),$sbox # size optimization
456 movzb `&lo("$s0")`,$acc0 721 movzb `&lo("$s0")`,$acc0
457 movzb `&lo("$s1")`,$acc1 722 movzb `&lo("$s1")`,$acc1
458 movzb `&lo("$s2")`,$acc2 723 movzb `&lo("$s2")`,$acc2
459 movzb 2048($sbox,$acc0,1),$t0 724 movzb ($sbox,$acc0,1),$t0
460 movzb 2048($sbox,$acc1,1),$t1 725 movzb ($sbox,$acc1,1),$t1
461 movzb 2048($sbox,$acc2,1),$t2 726 movzb ($sbox,$acc2,1),$t2
462 727
463 movzb `&lo("$s3")`,$acc0 728 movzb `&lo("$s3")`,$acc0
464 movzb `&hi("$s3")`,$acc1 729 movzb `&hi("$s3")`,$acc1
465 movzb `&hi("$s0")`,$acc2 730 movzb `&hi("$s0")`,$acc2
466 movzb 2048($sbox,$acc0,1),$t3 731 movzb ($sbox,$acc0,1),$t3
467 movzb 2048($sbox,$acc1,1),$acc1 #$t0 732 movzb ($sbox,$acc1,1),$acc1 #$t0
468 movzb 2048($sbox,$acc2,1),$acc2 #$t1 733 movzb ($sbox,$acc2,1),$acc2 #$t1
469 734
470 shl \$8,$acc1 735 shl \$8,$acc1
471 shl \$8,$acc2 736 shl \$8,$acc2
@@ -477,8 +742,8 @@ $code.=<<___;
477 movzb `&hi("$s1")`,$acc0 742 movzb `&hi("$s1")`,$acc0
478 movzb `&hi("$s2")`,$acc1 743 movzb `&hi("$s2")`,$acc1
479 shr \$16,$s0 744 shr \$16,$s0
480 movzb 2048($sbox,$acc0,1),$acc0 #$t2 745 movzb ($sbox,$acc0,1),$acc0 #$t2
481 movzb 2048($sbox,$acc1,1),$acc1 #$t3 746 movzb ($sbox,$acc1,1),$acc1 #$t3
482 747
483 shl \$8,$acc0 748 shl \$8,$acc0
484 shl \$8,$acc1 749 shl \$8,$acc1
@@ -490,9 +755,9 @@ $code.=<<___;
490 movzb `&lo("$s2")`,$acc0 755 movzb `&lo("$s2")`,$acc0
491 movzb `&lo("$s3")`,$acc1 756 movzb `&lo("$s3")`,$acc1
492 movzb `&lo("$s0")`,$acc2 757 movzb `&lo("$s0")`,$acc2
493 movzb 2048($sbox,$acc0,1),$acc0 #$t0 758 movzb ($sbox,$acc0,1),$acc0 #$t0
494 movzb 2048($sbox,$acc1,1),$acc1 #$t1 759 movzb ($sbox,$acc1,1),$acc1 #$t1
495 movzb 2048($sbox,$acc2,1),$acc2 #$t2 760 movzb ($sbox,$acc2,1),$acc2 #$t2
496 761
497 shl \$16,$acc0 762 shl \$16,$acc0
498 shl \$16,$acc1 763 shl \$16,$acc1
@@ -505,9 +770,9 @@ $code.=<<___;
505 movzb `&lo("$s1")`,$acc0 770 movzb `&lo("$s1")`,$acc0
506 movzb `&hi("$s1")`,$acc1 771 movzb `&hi("$s1")`,$acc1
507 movzb `&hi("$s2")`,$acc2 772 movzb `&hi("$s2")`,$acc2
508 movzb 2048($sbox,$acc0,1),$acc0 #$t3 773 movzb ($sbox,$acc0,1),$acc0 #$t3
509 movzb 2048($sbox,$acc1,1),$acc1 #$t0 774 movzb ($sbox,$acc1,1),$acc1 #$t0
510 movzb 2048($sbox,$acc2,1),$acc2 #$t1 775 movzb ($sbox,$acc2,1),$acc2 #$t1
511 776
512 shl \$16,$acc0 777 shl \$16,$acc0
513 shl \$24,$acc1 778 shl \$24,$acc1
@@ -520,8 +785,8 @@ $code.=<<___;
520 movzb `&hi("$s3")`,$acc0 785 movzb `&hi("$s3")`,$acc0
521 movzb `&hi("$s0")`,$acc1 786 movzb `&hi("$s0")`,$acc1
522 mov 16+12($key),$s3 787 mov 16+12($key),$s3
523 movzb 2048($sbox,$acc0,1),$acc0 #$t2 788 movzb ($sbox,$acc0,1),$acc0 #$t2
524 movzb 2048($sbox,$acc1,1),$acc1 #$t3 789 movzb ($sbox,$acc1,1),$acc1 #$t3
525 mov 16+0($key),$s0 790 mov 16+0($key),$s0
526 791
527 shl \$24,$acc0 792 shl \$24,$acc0
@@ -532,6 +797,7 @@ $code.=<<___;
532 797
533 mov 16+4($key),$s1 798 mov 16+4($key),$s1
534 mov 16+8($key),$s2 799 mov 16+8($key),$s2
800 lea -2048($sbox),$sbox
535 xor $t0,$s0 801 xor $t0,$s0
536 xor $t1,$s1 802 xor $t1,$s1
537 xor $t2,$s2 803 xor $t2,$s2
@@ -659,6 +925,260 @@ $code.=<<___;
659.size _x86_64_AES_decrypt,.-_x86_64_AES_decrypt 925.size _x86_64_AES_decrypt,.-_x86_64_AES_decrypt
660___ 926___
661 927
928sub deccompactvert()
929{ my ($t3,$t4,$t5)=("%r8d","%r9d","%r13d");
930
931$code.=<<___;
932 movzb `&lo("$s0")`,$t0
933 movzb `&lo("$s1")`,$t1
934 movzb `&lo("$s2")`,$t2
935 movzb ($sbox,$t0,1),$t0
936 movzb ($sbox,$t1,1),$t1
937 movzb ($sbox,$t2,1),$t2
938
939 movzb `&lo("$s3")`,$t3
940 movzb `&hi("$s3")`,$acc0
941 movzb `&hi("$s0")`,$acc1
942 movzb ($sbox,$t3,1),$t3
943 movzb ($sbox,$acc0,1),$t4 #$t0
944 movzb ($sbox,$acc1,1),$t5 #$t1
945
946 movzb `&hi("$s1")`,$acc2
947 movzb `&hi("$s2")`,$acc0
948 shr \$16,$s2
949 movzb ($sbox,$acc2,1),$acc2 #$t2
950 movzb ($sbox,$acc0,1),$acc0 #$t3
951 shr \$16,$s3
952
953 movzb `&lo("$s2")`,$acc1
954 shl \$8,$t4
955 shl \$8,$t5
956 movzb ($sbox,$acc1,1),$acc1 #$t0
957 xor $t4,$t0
958 xor $t5,$t1
959
960 movzb `&lo("$s3")`,$t4
961 shr \$16,$s0
962 shr \$16,$s1
963 movzb `&lo("$s0")`,$t5
964 shl \$8,$acc2
965 shl \$8,$acc0
966 movzb ($sbox,$t4,1),$t4 #$t1
967 movzb ($sbox,$t5,1),$t5 #$t2
968 xor $acc2,$t2
969 xor $acc0,$t3
970
971 movzb `&lo("$s1")`,$acc2
972 movzb `&hi("$s1")`,$acc0
973 shl \$16,$acc1
974 movzb ($sbox,$acc2,1),$acc2 #$t3
975 movzb ($sbox,$acc0,1),$acc0 #$t0
976 xor $acc1,$t0
977
978 movzb `&hi("$s2")`,$acc1
979 shl \$16,$t4
980 shl \$16,$t5
981 movzb ($sbox,$acc1,1),$s1 #$t1
982 xor $t4,$t1
983 xor $t5,$t2
984
985 movzb `&hi("$s3")`,$acc1
986 shr \$8,$s0
987 shl \$16,$acc2
988 movzb ($sbox,$acc1,1),$s2 #$t2
989 movzb ($sbox,$s0,1),$s3 #$t3
990 xor $acc2,$t3
991
992 shl \$24,$acc0
993 shl \$24,$s1
994 shl \$24,$s2
995 xor $acc0,$t0
996 shl \$24,$s3
997 xor $t1,$s1
998 mov $t0,$s0
999 xor $t2,$s2
1000 xor $t3,$s3
1001___
1002}
1003
1004# parallelized version! input is pair of 64-bit values: %rax=s1.s0
1005# and %rcx=s3.s2, output is four 32-bit values in %eax=s0, %ebx=s1,
1006# %ecx=s2 and %edx=s3.
1007sub dectransform()
1008{ my ($tp10,$tp20,$tp40,$tp80,$acc0)=("%rax","%r8", "%r9", "%r10","%rbx");
1009 my ($tp18,$tp28,$tp48,$tp88,$acc8)=("%rcx","%r11","%r12","%r13","%rdx");
1010 my $prefetch = shift;
1011
1012$code.=<<___;
1013 mov $tp10,$acc0
1014 mov $tp18,$acc8
1015 and $mask80,$acc0
1016 and $mask80,$acc8
1017 mov $acc0,$tp40
1018 mov $acc8,$tp48
1019 shr \$7,$tp40
1020 lea ($tp10,$tp10),$tp20
1021 shr \$7,$tp48
1022 lea ($tp18,$tp18),$tp28
1023 sub $tp40,$acc0
1024 sub $tp48,$acc8
1025 and $maskfe,$tp20
1026 and $maskfe,$tp28
1027 and $mask1b,$acc0
1028 and $mask1b,$acc8
1029 xor $tp20,$acc0
1030 xor $tp28,$acc8
1031 mov $acc0,$tp20
1032 mov $acc8,$tp28
1033
1034 and $mask80,$acc0
1035 and $mask80,$acc8
1036 mov $acc0,$tp80
1037 mov $acc8,$tp88
1038 shr \$7,$tp80
1039 lea ($tp20,$tp20),$tp40
1040 shr \$7,$tp88
1041 lea ($tp28,$tp28),$tp48
1042 sub $tp80,$acc0
1043 sub $tp88,$acc8
1044 and $maskfe,$tp40
1045 and $maskfe,$tp48
1046 and $mask1b,$acc0
1047 and $mask1b,$acc8
1048 xor $tp40,$acc0
1049 xor $tp48,$acc8
1050 mov $acc0,$tp40
1051 mov $acc8,$tp48
1052
1053 and $mask80,$acc0
1054 and $mask80,$acc8
1055 mov $acc0,$tp80
1056 mov $acc8,$tp88
1057 shr \$7,$tp80
1058 xor $tp10,$tp20 # tp2^=tp1
1059 shr \$7,$tp88
1060 xor $tp18,$tp28 # tp2^=tp1
1061 sub $tp80,$acc0
1062 sub $tp88,$acc8
1063 lea ($tp40,$tp40),$tp80
1064 lea ($tp48,$tp48),$tp88
1065 xor $tp10,$tp40 # tp4^=tp1
1066 xor $tp18,$tp48 # tp4^=tp1
1067 and $maskfe,$tp80
1068 and $maskfe,$tp88
1069 and $mask1b,$acc0
1070 and $mask1b,$acc8
1071 xor $acc0,$tp80
1072 xor $acc8,$tp88
1073
1074 xor $tp80,$tp10 # tp1^=tp8
1075 xor $tp88,$tp18 # tp1^=tp8
1076 xor $tp80,$tp20 # tp2^tp1^=tp8
1077 xor $tp88,$tp28 # tp2^tp1^=tp8
1078 mov $tp10,$acc0
1079 mov $tp18,$acc8
1080 xor $tp80,$tp40 # tp4^tp1^=tp8
1081 xor $tp88,$tp48 # tp4^tp1^=tp8
1082 shr \$32,$acc0
1083 shr \$32,$acc8
1084 xor $tp20,$tp80 # tp8^=tp8^tp2^tp1=tp2^tp1
1085 xor $tp28,$tp88 # tp8^=tp8^tp2^tp1=tp2^tp1
1086 rol \$8,`&LO("$tp10")` # ROTATE(tp1^tp8,8)
1087 rol \$8,`&LO("$tp18")` # ROTATE(tp1^tp8,8)
1088 xor $tp40,$tp80 # tp2^tp1^=tp8^tp4^tp1=tp8^tp4^tp2
1089 xor $tp48,$tp88 # tp2^tp1^=tp8^tp4^tp1=tp8^tp4^tp2
1090
1091 rol \$8,`&LO("$acc0")` # ROTATE(tp1^tp8,8)
1092 rol \$8,`&LO("$acc8")` # ROTATE(tp1^tp8,8)
1093 xor `&LO("$tp80")`,`&LO("$tp10")`
1094 xor `&LO("$tp88")`,`&LO("$tp18")`
1095 shr \$32,$tp80
1096 shr \$32,$tp88
1097 xor `&LO("$tp80")`,`&LO("$acc0")`
1098 xor `&LO("$tp88")`,`&LO("$acc8")`
1099
1100 mov $tp20,$tp80
1101 mov $tp28,$tp88
1102 shr \$32,$tp80
1103 shr \$32,$tp88
1104 rol \$24,`&LO("$tp20")` # ROTATE(tp2^tp1^tp8,24)
1105 rol \$24,`&LO("$tp28")` # ROTATE(tp2^tp1^tp8,24)
1106 rol \$24,`&LO("$tp80")` # ROTATE(tp2^tp1^tp8,24)
1107 rol \$24,`&LO("$tp88")` # ROTATE(tp2^tp1^tp8,24)
1108 xor `&LO("$tp20")`,`&LO("$tp10")`
1109 xor `&LO("$tp28")`,`&LO("$tp18")`
1110 mov $tp40,$tp20
1111 mov $tp48,$tp28
1112 xor `&LO("$tp80")`,`&LO("$acc0")`
1113 xor `&LO("$tp88")`,`&LO("$acc8")`
1114
1115 `"mov 0($sbox),$mask80" if ($prefetch)`
1116 shr \$32,$tp20
1117 shr \$32,$tp28
1118 `"mov 64($sbox),$maskfe" if ($prefetch)`
1119 rol \$16,`&LO("$tp40")` # ROTATE(tp4^tp1^tp8,16)
1120 rol \$16,`&LO("$tp48")` # ROTATE(tp4^tp1^tp8,16)
1121 `"mov 128($sbox),$mask1b" if ($prefetch)`
1122 rol \$16,`&LO("$tp20")` # ROTATE(tp4^tp1^tp8,16)
1123 rol \$16,`&LO("$tp28")` # ROTATE(tp4^tp1^tp8,16)
1124 `"mov 192($sbox),$tp80" if ($prefetch)`
1125 xor `&LO("$tp40")`,`&LO("$tp10")`
1126 xor `&LO("$tp48")`,`&LO("$tp18")`
1127 `"mov 256($sbox),$tp88" if ($prefetch)`
1128 xor `&LO("$tp20")`,`&LO("$acc0")`
1129 xor `&LO("$tp28")`,`&LO("$acc8")`
1130___
1131}
1132
1133$code.=<<___;
1134.type _x86_64_AES_decrypt_compact,\@abi-omnipotent
1135.align 16
1136_x86_64_AES_decrypt_compact:
1137 lea 128($sbox),$inp # size optimization
1138 mov 0-128($inp),$acc1 # prefetch Td4
1139 mov 32-128($inp),$acc2
1140 mov 64-128($inp),$t0
1141 mov 96-128($inp),$t1
1142 mov 128-128($inp),$acc1
1143 mov 160-128($inp),$acc2
1144 mov 192-128($inp),$t0
1145 mov 224-128($inp),$t1
1146 jmp .Ldec_loop_compact
1147
1148.align 16
1149.Ldec_loop_compact:
1150 xor 0($key),$s0 # xor with key
1151 xor 4($key),$s1
1152 xor 8($key),$s2
1153 xor 12($key),$s3
1154 lea 16($key),$key
1155___
1156 &deccompactvert();
1157$code.=<<___;
1158 cmp 16(%rsp),$key
1159 je .Ldec_compact_done
1160
1161 mov 256+0($sbox),$mask80
1162 shl \$32,%rbx
1163 shl \$32,%rdx
1164 mov 256+8($sbox),$maskfe
1165 or %rbx,%rax
1166 or %rdx,%rcx
1167 mov 256+16($sbox),$mask1b
1168___
1169 &dectransform(1);
1170$code.=<<___;
1171 jmp .Ldec_loop_compact
1172.align 16
1173.Ldec_compact_done:
1174 xor 0($key),$s0
1175 xor 4($key),$s1
1176 xor 8($key),$s2
1177 xor 12($key),$s3
1178 .byte 0xf3,0xc3 # rep ret
1179.size _x86_64_AES_decrypt_compact,.-_x86_64_AES_decrypt_compact
1180___
1181
662# void AES_decrypt (const void *inp,void *out,const AES_KEY *key); 1182# void AES_decrypt (const void *inp,void *out,const AES_KEY *key);
663$code.=<<___; 1183$code.=<<___;
664.globl AES_decrypt 1184.globl AES_decrypt
@@ -672,43 +1192,59 @@ AES_decrypt:
672 push %r14 1192 push %r14
673 push %r15 1193 push %r15
674 1194
675 mov %rdx,$key 1195 # allocate frame "above" key schedule
676 mov %rdi,$inp 1196 mov %rsp,%r10
677 mov %rsi,$out 1197 lea -63(%rdx),%rcx # %rdx is key argument
1198 and \$-64,%rsp
1199 sub %rsp,%rcx
1200 neg %rcx
1201 and \$0x3c0,%rcx
1202 sub %rcx,%rsp
1203 sub \$32,%rsp
1204
1205 mov %rsi,16(%rsp) # save out
1206 mov %r10,24(%rsp) # save real stack pointer
1207.Ldec_prologue:
678 1208
679 .picmeup $sbox 1209 mov %rdx,$key
680 lea AES_Td-.($sbox),$sbox 1210 mov 240($key),$rnds # load rounds
681 1211
682 # prefetch Td4 1212 mov 0(%rdi),$s0 # load input vector
683 lea 2048+128($sbox),$sbox; 1213 mov 4(%rdi),$s1
684 mov 0-128($sbox),$s0 1214 mov 8(%rdi),$s2
685 mov 32-128($sbox),$s1 1215 mov 12(%rdi),$s3
686 mov 64-128($sbox),$s2 1216
687 mov 96-128($sbox),$s3 1217 shl \$4,$rnds
688 mov 128-128($sbox),$s0 1218 lea ($key,$rnds),%rbp
689 mov 160-128($sbox),$s1 1219 mov $key,(%rsp) # key schedule
690 mov 192-128($sbox),$s2 1220 mov %rbp,8(%rsp) # end of key schedule
691 mov 224-128($sbox),$s3 1221
692 lea -2048-128($sbox),$sbox; 1222 # pick Td4 copy which can't "overlap" with stack frame or key schedule
693 1223 lea .LAES_Td+2048(%rip),$sbox
694 mov 0($inp),$s0 1224 lea 768(%rsp),%rbp
695 mov 4($inp),$s1 1225 sub $sbox,%rbp
696 mov 8($inp),$s2 1226 and \$0x300,%rbp
697 mov 12($inp),$s3 1227 lea ($sbox,%rbp),$sbox
698 1228 shr \$3,%rbp # recall "magic" constants!
699 call _x86_64_AES_decrypt 1229 add %rbp,$sbox
700 1230
701 mov $s0,0($out) 1231 call _x86_64_AES_decrypt_compact
1232
1233 mov 16(%rsp),$out # restore out
1234 mov 24(%rsp),%rsi # restore saved stack pointer
1235 mov $s0,0($out) # write output vector
702 mov $s1,4($out) 1236 mov $s1,4($out)
703 mov $s2,8($out) 1237 mov $s2,8($out)
704 mov $s3,12($out) 1238 mov $s3,12($out)
705 1239
706 pop %r15 1240 mov (%rsi),%r15
707 pop %r14 1241 mov 8(%rsi),%r14
708 pop %r13 1242 mov 16(%rsi),%r13
709 pop %r12 1243 mov 24(%rsi),%r12
710 pop %rbp 1244 mov 32(%rsi),%rbp
711 pop %rbx 1245 mov 40(%rsi),%rbx
1246 lea 48(%rsi),%rsp
1247.Ldec_epilogue:
712 ret 1248 ret
713.size AES_decrypt,.-AES_decrypt 1249.size AES_decrypt,.-AES_decrypt
714___ 1250___
@@ -718,27 +1254,26 @@ sub enckey()
718{ 1254{
719$code.=<<___; 1255$code.=<<___;
720 movz %dl,%esi # rk[i]>>0 1256 movz %dl,%esi # rk[i]>>0
721 mov 2(%rbp,%rsi,8),%ebx 1257 movzb -128(%rbp,%rsi),%ebx
722 movz %dh,%esi # rk[i]>>8 1258 movz %dh,%esi # rk[i]>>8
723 and \$0xFF000000,%ebx 1259 shl \$24,%ebx
724 xor %ebx,%eax 1260 xor %ebx,%eax
725 1261
726 mov 2(%rbp,%rsi,8),%ebx 1262 movzb -128(%rbp,%rsi),%ebx
727 shr \$16,%edx 1263 shr \$16,%edx
728 and \$0x000000FF,%ebx
729 movz %dl,%esi # rk[i]>>16 1264 movz %dl,%esi # rk[i]>>16
730 xor %ebx,%eax 1265 xor %ebx,%eax
731 1266
732 mov 0(%rbp,%rsi,8),%ebx 1267 movzb -128(%rbp,%rsi),%ebx
733 movz %dh,%esi # rk[i]>>24 1268 movz %dh,%esi # rk[i]>>24
734 and \$0x0000FF00,%ebx 1269 shl \$8,%ebx
735 xor %ebx,%eax 1270 xor %ebx,%eax
736 1271
737 mov 0(%rbp,%rsi,8),%ebx 1272 movzb -128(%rbp,%rsi),%ebx
738 and \$0x00FF0000,%ebx 1273 shl \$16,%ebx
739 xor %ebx,%eax 1274 xor %ebx,%eax
740 1275
741 xor 2048(%rbp,%rcx,4),%eax # rcon 1276 xor 1024-128(%rbp,%rcx,4),%eax # rcon
742___ 1277___
743} 1278}
744 1279
@@ -751,7 +1286,29 @@ $code.=<<___;
751AES_set_encrypt_key: 1286AES_set_encrypt_key:
752 push %rbx 1287 push %rbx
753 push %rbp 1288 push %rbp
1289 push %r12 # redundant, but allows to share
1290 push %r13 # exception handler...
1291 push %r14
1292 push %r15
1293 sub \$8,%rsp
1294.Lenc_key_prologue:
1295
1296 call _x86_64_AES_set_encrypt_key
1297
1298 mov 8(%rsp),%r15
1299 mov 16(%rsp),%r14
1300 mov 24(%rsp),%r13
1301 mov 32(%rsp),%r12
1302 mov 40(%rsp),%rbp
1303 mov 48(%rsp),%rbx
1304 add \$56,%rsp
1305.Lenc_key_epilogue:
1306 ret
1307.size AES_set_encrypt_key,.-AES_set_encrypt_key
754 1308
1309.type _x86_64_AES_set_encrypt_key,\@abi-omnipotent
1310.align 16
1311_x86_64_AES_set_encrypt_key:
755 mov %esi,%ecx # %ecx=bits 1312 mov %esi,%ecx # %ecx=bits
756 mov %rdi,%rsi # %rsi=userKey 1313 mov %rdi,%rsi # %rsi=userKey
757 mov %rdx,%rdi # %rdi=key 1314 mov %rdx,%rdi # %rdi=key
@@ -761,8 +1318,18 @@ AES_set_encrypt_key:
761 test \$-1,%rdi 1318 test \$-1,%rdi
762 jz .Lbadpointer 1319 jz .Lbadpointer
763 1320
764 .picmeup %rbp 1321 lea .LAES_Te(%rip),%rbp
765 lea AES_Te-.(%rbp),%rbp 1322 lea 2048+128(%rbp),%rbp
1323
1324 # prefetch Te4
1325 mov 0-128(%rbp),%eax
1326 mov 32-128(%rbp),%ebx
1327 mov 64-128(%rbp),%r8d
1328 mov 96-128(%rbp),%edx
1329 mov 128-128(%rbp),%eax
1330 mov 160-128(%rbp),%ebx
1331 mov 192-128(%rbp),%r8d
1332 mov 224-128(%rbp),%edx
766 1333
767 cmp \$128,%ecx 1334 cmp \$128,%ecx
768 je .L10rounds 1335 je .L10rounds
@@ -774,15 +1341,12 @@ AES_set_encrypt_key:
774 jmp .Lexit 1341 jmp .Lexit
775 1342
776.L10rounds: 1343.L10rounds:
777 mov 0(%rsi),%eax # copy first 4 dwords 1344 mov 0(%rsi),%rax # copy first 4 dwords
778 mov 4(%rsi),%ebx 1345 mov 8(%rsi),%rdx
779 mov 8(%rsi),%ecx 1346 mov %rax,0(%rdi)
780 mov 12(%rsi),%edx 1347 mov %rdx,8(%rdi)
781 mov %eax,0(%rdi)
782 mov %ebx,4(%rdi)
783 mov %ecx,8(%rdi)
784 mov %edx,12(%rdi)
785 1348
1349 shr \$32,%rdx
786 xor %ecx,%ecx 1350 xor %ecx,%ecx
787 jmp .L10shortcut 1351 jmp .L10shortcut
788.align 4 1352.align 4
@@ -810,19 +1374,14 @@ $code.=<<___;
810 jmp .Lexit 1374 jmp .Lexit
811 1375
812.L12rounds: 1376.L12rounds:
813 mov 0(%rsi),%eax # copy first 6 dwords 1377 mov 0(%rsi),%rax # copy first 6 dwords
814 mov 4(%rsi),%ebx 1378 mov 8(%rsi),%rbx
815 mov 8(%rsi),%ecx 1379 mov 16(%rsi),%rdx
816 mov 12(%rsi),%edx 1380 mov %rax,0(%rdi)
817 mov %eax,0(%rdi) 1381 mov %rbx,8(%rdi)
818 mov %ebx,4(%rdi) 1382 mov %rdx,16(%rdi)
819 mov %ecx,8(%rdi) 1383
820 mov %edx,12(%rdi) 1384 shr \$32,%rdx
821 mov 16(%rsi),%ecx
822 mov 20(%rsi),%edx
823 mov %ecx,16(%rdi)
824 mov %edx,20(%rdi)
825
826 xor %ecx,%ecx 1385 xor %ecx,%ecx
827 jmp .L12shortcut 1386 jmp .L12shortcut
828.align 4 1387.align 4
@@ -858,30 +1417,23 @@ $code.=<<___;
858 jmp .Lexit 1417 jmp .Lexit
859 1418
860.L14rounds: 1419.L14rounds:
861 mov 0(%rsi),%eax # copy first 8 dwords 1420 mov 0(%rsi),%rax # copy first 8 dwords
862 mov 4(%rsi),%ebx 1421 mov 8(%rsi),%rbx
863 mov 8(%rsi),%ecx 1422 mov 16(%rsi),%rcx
864 mov 12(%rsi),%edx 1423 mov 24(%rsi),%rdx
865 mov %eax,0(%rdi) 1424 mov %rax,0(%rdi)
866 mov %ebx,4(%rdi) 1425 mov %rbx,8(%rdi)
867 mov %ecx,8(%rdi) 1426 mov %rcx,16(%rdi)
868 mov %edx,12(%rdi) 1427 mov %rdx,24(%rdi)
869 mov 16(%rsi),%eax 1428
870 mov 20(%rsi),%ebx 1429 shr \$32,%rdx
871 mov 24(%rsi),%ecx
872 mov 28(%rsi),%edx
873 mov %eax,16(%rdi)
874 mov %ebx,20(%rdi)
875 mov %ecx,24(%rdi)
876 mov %edx,28(%rdi)
877
878 xor %ecx,%ecx 1430 xor %ecx,%ecx
879 jmp .L14shortcut 1431 jmp .L14shortcut
880.align 4 1432.align 4
881.L14loop: 1433.L14loop:
1434 mov 0(%rdi),%eax # rk[0]
882 mov 28(%rdi),%edx # rk[4] 1435 mov 28(%rdi),%edx # rk[4]
883.L14shortcut: 1436.L14shortcut:
884 mov 0(%rdi),%eax # rk[0]
885___ 1437___
886 &enckey (); 1438 &enckey ();
887$code.=<<___; 1439$code.=<<___;
@@ -900,24 +1452,23 @@ $code.=<<___;
900 mov %eax,%edx 1452 mov %eax,%edx
901 mov 16(%rdi),%eax # rk[4] 1453 mov 16(%rdi),%eax # rk[4]
902 movz %dl,%esi # rk[11]>>0 1454 movz %dl,%esi # rk[11]>>0
903 mov 2(%rbp,%rsi,8),%ebx 1455 movzb -128(%rbp,%rsi),%ebx
904 movz %dh,%esi # rk[11]>>8 1456 movz %dh,%esi # rk[11]>>8
905 and \$0x000000FF,%ebx
906 xor %ebx,%eax 1457 xor %ebx,%eax
907 1458
908 mov 0(%rbp,%rsi,8),%ebx 1459 movzb -128(%rbp,%rsi),%ebx
909 shr \$16,%edx 1460 shr \$16,%edx
910 and \$0x0000FF00,%ebx 1461 shl \$8,%ebx
911 movz %dl,%esi # rk[11]>>16 1462 movz %dl,%esi # rk[11]>>16
912 xor %ebx,%eax 1463 xor %ebx,%eax
913 1464
914 mov 0(%rbp,%rsi,8),%ebx 1465 movzb -128(%rbp,%rsi),%ebx
915 movz %dh,%esi # rk[11]>>24 1466 movz %dh,%esi # rk[11]>>24
916 and \$0x00FF0000,%ebx 1467 shl \$16,%ebx
917 xor %ebx,%eax 1468 xor %ebx,%eax
918 1469
919 mov 2(%rbp,%rsi,8),%ebx 1470 movzb -128(%rbp,%rsi),%ebx
920 and \$0xFF000000,%ebx 1471 shl \$24,%ebx
921 xor %ebx,%eax 1472 xor %ebx,%eax
922 1473
923 mov %eax,48(%rdi) # rk[12] 1474 mov %eax,48(%rdi) # rk[12]
@@ -938,31 +1489,61 @@ $code.=<<___;
938.Lbadpointer: 1489.Lbadpointer:
939 mov \$-1,%rax 1490 mov \$-1,%rax
940.Lexit: 1491.Lexit:
941 pop %rbp 1492 .byte 0xf3,0xc3 # rep ret
942 pop %rbx 1493.size _x86_64_AES_set_encrypt_key,.-_x86_64_AES_set_encrypt_key
943 ret
944.size AES_set_encrypt_key,.-AES_set_encrypt_key
945___ 1494___
946 1495
947sub deckey() 1496sub deckey_ref()
948{ my ($i,$ptr,$te,$td) = @_; 1497{ my ($i,$ptr,$te,$td) = @_;
1498 my ($tp1,$tp2,$tp4,$tp8,$acc)=("%eax","%ebx","%edi","%edx","%r8d");
949$code.=<<___; 1499$code.=<<___;
950 mov $i($ptr),%eax 1500 mov $i($ptr),$tp1
951 mov %eax,%edx 1501 mov $tp1,$acc
952 movz %ah,%ebx 1502 and \$0x80808080,$acc
953 shr \$16,%edx 1503 mov $acc,$tp4
954 and \$0xFF,%eax 1504 shr \$7,$tp4
955 movzb 2($te,%rax,8),%rax 1505 lea 0($tp1,$tp1),$tp2
956 movzb 2($te,%rbx,8),%rbx 1506 sub $tp4,$acc
957 mov 0($td,%rax,8),%eax 1507 and \$0xfefefefe,$tp2
958 xor 3($td,%rbx,8),%eax 1508 and \$0x1b1b1b1b,$acc
959 movzb %dh,%ebx 1509 xor $tp2,$acc
960 and \$0xFF,%edx 1510 mov $acc,$tp2
961 movzb 2($te,%rdx,8),%rdx 1511
962 movzb 2($te,%rbx,8),%rbx 1512 and \$0x80808080,$acc
963 xor 2($td,%rdx,8),%eax 1513 mov $acc,$tp8
964 xor 1($td,%rbx,8),%eax 1514 shr \$7,$tp8
965 mov %eax,$i($ptr) 1515 lea 0($tp2,$tp2),$tp4
1516 sub $tp8,$acc
1517 and \$0xfefefefe,$tp4
1518 and \$0x1b1b1b1b,$acc
1519 xor $tp1,$tp2 # tp2^tp1
1520 xor $tp4,$acc
1521 mov $acc,$tp4
1522
1523 and \$0x80808080,$acc
1524 mov $acc,$tp8
1525 shr \$7,$tp8
1526 sub $tp8,$acc
1527 lea 0($tp4,$tp4),$tp8
1528 xor $tp1,$tp4 # tp4^tp1
1529 and \$0xfefefefe,$tp8
1530 and \$0x1b1b1b1b,$acc
1531 xor $acc,$tp8
1532
1533 xor $tp8,$tp1 # tp1^tp8
1534 rol \$8,$tp1 # ROTATE(tp1^tp8,8)
1535 xor $tp8,$tp2 # tp2^tp1^tp8
1536 xor $tp8,$tp4 # tp4^tp1^tp8
1537 xor $tp2,$tp8
1538 xor $tp4,$tp8 # tp8^(tp8^tp4^tp1)^(tp8^tp2^tp1)=tp8^tp4^tp2
1539
1540 xor $tp8,$tp1
1541 rol \$24,$tp2 # ROTATE(tp2^tp1^tp8,24)
1542 xor $tp2,$tp1
1543 rol \$16,$tp4 # ROTATE(tp4^tp1^tp8,16)
1544 xor $tp4,$tp1
1545
1546 mov $tp1,$i($ptr)
966___ 1547___
967} 1548}
968 1549
@@ -973,19 +1554,23 @@ $code.=<<___;
973.type AES_set_decrypt_key,\@function,3 1554.type AES_set_decrypt_key,\@function,3
974.align 16 1555.align 16
975AES_set_decrypt_key: 1556AES_set_decrypt_key:
976 push %rdx 1557 push %rbx
977 call AES_set_encrypt_key 1558 push %rbp
978 cmp \$0,%eax 1559 push %r12
979 je .Lproceed 1560 push %r13
980 lea 24(%rsp),%rsp 1561 push %r14
981 ret 1562 push %r15
982.Lproceed: 1563 push %rdx # save key schedule
1564.Ldec_key_prologue:
1565
1566 call _x86_64_AES_set_encrypt_key
983 mov (%rsp),%r8 # restore key schedule 1567 mov (%rsp),%r8 # restore key schedule
984 mov %rbx,(%rsp) 1568 cmp \$0,%eax
1569 jne .Labort
985 1570
986 mov 240(%r8),%ecx # pull number of rounds 1571 mov 240(%r8),%r14d # pull number of rounds
987 xor %rdi,%rdi 1572 xor %rdi,%rdi
988 lea (%rdi,%rcx,4),%rcx 1573 lea (%rdi,%r14d,4),%rcx
989 mov %r8,%rsi 1574 mov %r8,%rsi
990 lea (%r8,%rcx,4),%rdi # pointer to last chunk 1575 lea (%r8,%rcx,4),%rdi # pointer to last chunk
991.align 4 1576.align 4
@@ -1003,27 +1588,39 @@ AES_set_decrypt_key:
1003 cmp %rsi,%rdi 1588 cmp %rsi,%rdi
1004 jne .Linvert 1589 jne .Linvert
1005 1590
1006 .picmeup %r9 1591 lea .LAES_Te+2048+1024(%rip),%rax # rcon
1007 lea AES_Td-.(%r9),%rdi
1008 lea AES_Te-AES_Td(%rdi),%r9
1009 1592
1010 mov %r8,%rsi 1593 mov 40(%rax),$mask80
1011 mov 240(%r8),%ecx # pull number of rounds 1594 mov 48(%rax),$maskfe
1012 sub \$1,%ecx 1595 mov 56(%rax),$mask1b
1596
1597 mov %r8,$key
1598 sub \$1,%r14d
1013.align 4 1599.align 4
1014.Lpermute: 1600.Lpermute:
1015 lea 16(%rsi),%rsi 1601 lea 16($key),$key
1602 mov 0($key),%rax
1603 mov 8($key),%rcx
1016___ 1604___
1017 &deckey (0,"%rsi","%r9","%rdi"); 1605 &dectransform ();
1018 &deckey (4,"%rsi","%r9","%rdi");
1019 &deckey (8,"%rsi","%r9","%rdi");
1020 &deckey (12,"%rsi","%r9","%rdi");
1021$code.=<<___; 1606$code.=<<___;
1022 sub \$1,%ecx 1607 mov %eax,0($key)
1608 mov %ebx,4($key)
1609 mov %ecx,8($key)
1610 mov %edx,12($key)
1611 sub \$1,%r14d
1023 jnz .Lpermute 1612 jnz .Lpermute
1024 1613
1025 xor %rax,%rax 1614 xor %rax,%rax
1026 pop %rbx 1615.Labort:
1616 mov 8(%rsp),%r15
1617 mov 16(%rsp),%r14
1618 mov 24(%rsp),%r13
1619 mov 32(%rsp),%r12
1620 mov 40(%rsp),%rbp
1621 mov 48(%rsp),%rbx
1622 add \$56,%rsp
1623.Ldec_key_epilogue:
1027 ret 1624 ret
1028.size AES_set_decrypt_key,.-AES_set_decrypt_key 1625.size AES_set_decrypt_key,.-AES_set_decrypt_key
1029___ 1626___
@@ -1034,47 +1631,59 @@ ___
1034{ 1631{
1035# stack frame layout 1632# stack frame layout
1036# -8(%rsp) return address 1633# -8(%rsp) return address
1037my $_rsp="0(%rsp)"; # saved %rsp 1634my $keyp="0(%rsp)"; # one to pass as $key
1038my $_len="8(%rsp)"; # copy of 3rd parameter, length 1635my $keyend="8(%rsp)"; # &(keyp->rd_key[4*keyp->rounds])
1039my $_key="16(%rsp)"; # copy of 4th parameter, key 1636my $_rsp="16(%rsp)"; # saved %rsp
1040my $_ivp="24(%rsp)"; # copy of 5th parameter, ivp 1637my $_inp="24(%rsp)"; # copy of 1st parameter, inp
1041my $keyp="32(%rsp)"; # one to pass as $key 1638my $_out="32(%rsp)"; # copy of 2nd parameter, out
1042my $ivec="40(%rsp)"; # ivec[16] 1639my $_len="40(%rsp)"; # copy of 3rd parameter, length
1043my $aes_key="56(%rsp)"; # copy of aes_key 1640my $_key="48(%rsp)"; # copy of 4th parameter, key
1044my $mark="56+240(%rsp)"; # copy of aes_key->rounds 1641my $_ivp="56(%rsp)"; # copy of 5th parameter, ivp
1642my $ivec="64(%rsp)"; # ivec[16]
1643my $aes_key="80(%rsp)"; # copy of aes_key
1644my $mark="80+240(%rsp)"; # copy of aes_key->rounds
1045 1645
1046$code.=<<___; 1646$code.=<<___;
1047.globl AES_cbc_encrypt 1647.globl AES_cbc_encrypt
1048.type AES_cbc_encrypt,\@function,6 1648.type AES_cbc_encrypt,\@function,6
1049.align 16 1649.align 16
1650.extern OPENSSL_ia32cap_P
1050AES_cbc_encrypt: 1651AES_cbc_encrypt:
1051 cmp \$0,%rdx # check length 1652 cmp \$0,%rdx # check length
1052 je .Lcbc_just_ret 1653 je .Lcbc_epilogue
1654 pushfq
1053 push %rbx 1655 push %rbx
1054 push %rbp 1656 push %rbp
1055 push %r12 1657 push %r12
1056 push %r13 1658 push %r13
1057 push %r14 1659 push %r14
1058 push %r15 1660 push %r15
1059 pushfq 1661.Lcbc_prologue:
1662
1060 cld 1663 cld
1061 mov %r9d,%r9d # clear upper half of enc 1664 mov %r9d,%r9d # clear upper half of enc
1062 1665
1063 .picmeup $sbox 1666 lea .LAES_Te(%rip),$sbox
1064.Lcbc_pic_point:
1065
1066 cmp \$0,%r9 1667 cmp \$0,%r9
1067 je .LDECRYPT 1668 jne .Lcbc_picked_te
1068 1669 lea .LAES_Td(%rip),$sbox
1069 lea AES_Te-.Lcbc_pic_point($sbox),$sbox 1670.Lcbc_picked_te:
1671
1672 mov OPENSSL_ia32cap_P(%rip),%r10d
1673 cmp \$$speed_limit,%rdx
1674 jb .Lcbc_slow_prologue
1675 test \$15,%rdx
1676 jnz .Lcbc_slow_prologue
1677 bt \$28,%r10d
1678 jc .Lcbc_slow_prologue
1070 1679
1071 # allocate aligned stack frame... 1680 # allocate aligned stack frame...
1072 lea -64-248(%rsp),$key 1681 lea -88-248(%rsp),$key
1073 and \$-64,$key 1682 and \$-64,$key
1074 1683
1075 # ... and make it doesn't alias with AES_Te modulo 4096 1684 # ... and make sure it doesn't alias with AES_T[ed] modulo 4096
1076 mov $sbox,%r10 1685 mov $sbox,%r10
1077 lea 2048($sbox),%r11 1686 lea 2304($sbox),%r11
1078 mov $key,%r12 1687 mov $key,%r12
1079 and \$0xFFF,%r10 # s = $sbox&0xfff 1688 and \$0xFFF,%r10 # s = $sbox&0xfff
1080 and \$0xFFF,%r11 # e = ($sbox+2048)&0xfff 1689 and \$0xFFF,%r11 # e = ($sbox+2048)&0xfff
@@ -1094,22 +1703,27 @@ AES_cbc_encrypt:
1094.Lcbc_te_ok: 1703.Lcbc_te_ok:
1095 1704
1096 xchg %rsp,$key 1705 xchg %rsp,$key
1097 add \$8,%rsp # reserve for return address! 1706 #add \$8,%rsp # reserve for return address!
1098 mov $key,$_rsp # save %rsp 1707 mov $key,$_rsp # save %rsp
1708.Lcbc_fast_body:
1709 mov %rdi,$_inp # save copy of inp
1710 mov %rsi,$_out # save copy of out
1099 mov %rdx,$_len # save copy of len 1711 mov %rdx,$_len # save copy of len
1100 mov %rcx,$_key # save copy of key 1712 mov %rcx,$_key # save copy of key
1101 mov %r8,$_ivp # save copy of ivp 1713 mov %r8,$_ivp # save copy of ivp
1102 movl \$0,$mark # copy of aes_key->rounds = 0; 1714 movl \$0,$mark # copy of aes_key->rounds = 0;
1103 mov %r8,%rbp # rearrange input arguments 1715 mov %r8,%rbp # rearrange input arguments
1716 mov %r9,%rbx
1104 mov %rsi,$out 1717 mov %rsi,$out
1105 mov %rdi,$inp 1718 mov %rdi,$inp
1106 mov %rcx,$key 1719 mov %rcx,$key
1107 1720
1721 mov 240($key),%eax # key->rounds
1108 # do we copy key schedule to stack? 1722 # do we copy key schedule to stack?
1109 mov $key,%r10 1723 mov $key,%r10
1110 sub $sbox,%r10 1724 sub $sbox,%r10
1111 and \$0xfff,%r10 1725 and \$0xfff,%r10
1112 cmp \$2048,%r10 1726 cmp \$2304,%r10
1113 jb .Lcbc_do_ecopy 1727 jb .Lcbc_do_ecopy
1114 cmp \$4096-248,%r10 1728 cmp \$4096-248,%r10
1115 jb .Lcbc_skip_ecopy 1729 jb .Lcbc_skip_ecopy
@@ -1120,12 +1734,11 @@ AES_cbc_encrypt:
1120 lea $aes_key,$key 1734 lea $aes_key,$key
1121 mov \$240/8,%ecx 1735 mov \$240/8,%ecx
1122 .long 0x90A548F3 # rep movsq 1736 .long 0x90A548F3 # rep movsq
1123 mov (%rsi),%eax # copy aes_key->rounds 1737 mov %eax,(%rdi) # copy aes_key->rounds
1124 mov %eax,(%rdi)
1125.Lcbc_skip_ecopy: 1738.Lcbc_skip_ecopy:
1126 mov $key,$keyp # save key pointer 1739 mov $key,$keyp # save key pointer
1127 1740
1128 mov \$16,%ecx 1741 mov \$18,%ecx
1129.align 4 1742.align 4
1130.Lcbc_prefetch_te: 1743.Lcbc_prefetch_te:
1131 mov 0($sbox),%r10 1744 mov 0($sbox),%r10
@@ -1135,184 +1748,77 @@ AES_cbc_encrypt:
1135 lea 128($sbox),$sbox 1748 lea 128($sbox),$sbox
1136 sub \$1,%ecx 1749 sub \$1,%ecx
1137 jnz .Lcbc_prefetch_te 1750 jnz .Lcbc_prefetch_te
1138 sub \$2048,$sbox 1751 lea -2304($sbox),$sbox
1139 1752
1140 test \$-16,%rdx # check upon length 1753 cmp \$0,%rbx
1141 mov %rdx,%r10 1754 je .LFAST_DECRYPT
1755
1756#----------------------------- ENCRYPT -----------------------------#
1142 mov 0(%rbp),$s0 # load iv 1757 mov 0(%rbp),$s0 # load iv
1143 mov 4(%rbp),$s1 1758 mov 4(%rbp),$s1
1144 mov 8(%rbp),$s2 1759 mov 8(%rbp),$s2
1145 mov 12(%rbp),$s3 1760 mov 12(%rbp),$s3
1146 jz .Lcbc_enc_tail # short input...
1147 1761
1148.align 4 1762.align 4
1149.Lcbc_enc_loop: 1763.Lcbc_fast_enc_loop:
1150 xor 0($inp),$s0 1764 xor 0($inp),$s0
1151 xor 4($inp),$s1 1765 xor 4($inp),$s1
1152 xor 8($inp),$s2 1766 xor 8($inp),$s2
1153 xor 12($inp),$s3 1767 xor 12($inp),$s3
1154 mov $inp,$ivec # if ($verticalspin) save inp
1155
1156 mov $keyp,$key # restore key 1768 mov $keyp,$key # restore key
1769 mov $inp,$_inp # if ($verticalspin) save inp
1770
1157 call _x86_64_AES_encrypt 1771 call _x86_64_AES_encrypt
1158 1772
1159 mov $ivec,$inp # if ($verticalspin) restore inp 1773 mov $_inp,$inp # if ($verticalspin) restore inp
1774 mov $_len,%r10
1160 mov $s0,0($out) 1775 mov $s0,0($out)
1161 mov $s1,4($out) 1776 mov $s1,4($out)
1162 mov $s2,8($out) 1777 mov $s2,8($out)
1163 mov $s3,12($out) 1778 mov $s3,12($out)
1164 1779
1165 mov $_len,%r10
1166 lea 16($inp),$inp 1780 lea 16($inp),$inp
1167 lea 16($out),$out 1781 lea 16($out),$out
1168 sub \$16,%r10 1782 sub \$16,%r10
1169 test \$-16,%r10 1783 test \$-16,%r10
1170 mov %r10,$_len 1784 mov %r10,$_len
1171 jnz .Lcbc_enc_loop 1785 jnz .Lcbc_fast_enc_loop
1172 test \$15,%r10
1173 jnz .Lcbc_enc_tail
1174 mov $_ivp,%rbp # restore ivp 1786 mov $_ivp,%rbp # restore ivp
1175 mov $s0,0(%rbp) # save ivec 1787 mov $s0,0(%rbp) # save ivec
1176 mov $s1,4(%rbp) 1788 mov $s1,4(%rbp)
1177 mov $s2,8(%rbp) 1789 mov $s2,8(%rbp)
1178 mov $s3,12(%rbp) 1790 mov $s3,12(%rbp)
1179 1791
1180.align 4 1792 jmp .Lcbc_fast_cleanup
1181.Lcbc_cleanup: 1793
1182 cmpl \$0,$mark # was the key schedule copied?
1183 lea $aes_key,%rdi
1184 mov $_rsp,%rsp
1185 je .Lcbc_exit
1186 mov \$240/8,%ecx
1187 xor %rax,%rax
1188 .long 0x90AB48F3 # rep stosq
1189.Lcbc_exit:
1190 popfq
1191 pop %r15
1192 pop %r14
1193 pop %r13
1194 pop %r12
1195 pop %rbp
1196 pop %rbx
1197.Lcbc_just_ret:
1198 ret
1199.align 4
1200.Lcbc_enc_tail:
1201 mov %rax,%r11
1202 mov %rcx,%r12
1203 mov %r10,%rcx
1204 mov $inp,%rsi
1205 mov $out,%rdi
1206 .long 0xF689A4F3 # rep movsb
1207 mov \$16,%rcx # zero tail
1208 sub %r10,%rcx
1209 xor %rax,%rax
1210 .long 0xF689AAF3 # rep stosb
1211 mov $out,$inp # this is not a mistake!
1212 movq \$16,$_len # len=16
1213 mov %r11,%rax
1214 mov %r12,%rcx
1215 jmp .Lcbc_enc_loop # one more spin...
1216#----------------------------- DECRYPT -----------------------------# 1794#----------------------------- DECRYPT -----------------------------#
1217.align 16 1795.align 16
1218.LDECRYPT: 1796.LFAST_DECRYPT:
1219 lea AES_Td-.Lcbc_pic_point($sbox),$sbox
1220
1221 # allocate aligned stack frame...
1222 lea -64-248(%rsp),$key
1223 and \$-64,$key
1224
1225 # ... and make it doesn't alias with AES_Td modulo 4096
1226 mov $sbox,%r10
1227 lea 2304($sbox),%r11
1228 mov $key,%r12
1229 and \$0xFFF,%r10 # s = $sbox&0xfff
1230 and \$0xFFF,%r11 # e = ($sbox+2048+256)&0xfff
1231 and \$0xFFF,%r12 # p = %rsp&0xfff
1232
1233 cmp %r11,%r12 # if (p=>e) %rsp =- (p-e);
1234 jb .Lcbc_td_break_out
1235 sub %r11,%r12
1236 sub %r12,$key
1237 jmp .Lcbc_td_ok
1238.Lcbc_td_break_out: # else %rsp -= (p-s)&0xfff + framesz
1239 sub %r10,%r12
1240 and \$0xFFF,%r12
1241 add \$320,%r12
1242 sub %r12,$key
1243.align 4
1244.Lcbc_td_ok:
1245
1246 xchg %rsp,$key
1247 add \$8,%rsp # reserve for return address!
1248 mov $key,$_rsp # save %rsp
1249 mov %rdx,$_len # save copy of len
1250 mov %rcx,$_key # save copy of key
1251 mov %r8,$_ivp # save copy of ivp
1252 movl \$0,$mark # copy of aes_key->rounds = 0;
1253 mov %r8,%rbp # rearrange input arguments
1254 mov %rsi,$out
1255 mov %rdi,$inp
1256 mov %rcx,$key
1257
1258 # do we copy key schedule to stack?
1259 mov $key,%r10
1260 sub $sbox,%r10
1261 and \$0xfff,%r10
1262 cmp \$2304,%r10
1263 jb .Lcbc_do_dcopy
1264 cmp \$4096-248,%r10
1265 jb .Lcbc_skip_dcopy
1266.align 4
1267.Lcbc_do_dcopy:
1268 mov $key,%rsi
1269 lea $aes_key,%rdi
1270 lea $aes_key,$key
1271 mov \$240/8,%ecx
1272 .long 0x90A548F3 # rep movsq
1273 mov (%rsi),%eax # copy aes_key->rounds
1274 mov %eax,(%rdi)
1275.Lcbc_skip_dcopy:
1276 mov $key,$keyp # save key pointer
1277
1278 mov \$18,%ecx
1279.align 4
1280.Lcbc_prefetch_td:
1281 mov 0($sbox),%r10
1282 mov 32($sbox),%r11
1283 mov 64($sbox),%r12
1284 mov 96($sbox),%r13
1285 lea 128($sbox),$sbox
1286 sub \$1,%ecx
1287 jnz .Lcbc_prefetch_td
1288 sub \$2304,$sbox
1289
1290 cmp $inp,$out 1797 cmp $inp,$out
1291 je .Lcbc_dec_in_place 1798 je .Lcbc_fast_dec_in_place
1292 1799
1293 mov %rbp,$ivec 1800 mov %rbp,$ivec
1294.align 4 1801.align 4
1295.Lcbc_dec_loop: 1802.Lcbc_fast_dec_loop:
1296 mov 0($inp),$s0 # read input 1803 mov 0($inp),$s0 # read input
1297 mov 4($inp),$s1 1804 mov 4($inp),$s1
1298 mov 8($inp),$s2 1805 mov 8($inp),$s2
1299 mov 12($inp),$s3 1806 mov 12($inp),$s3
1300 mov $inp,8+$ivec # if ($verticalspin) save inp
1301
1302 mov $keyp,$key # restore key 1807 mov $keyp,$key # restore key
1808 mov $inp,$_inp # if ($verticalspin) save inp
1809
1303 call _x86_64_AES_decrypt 1810 call _x86_64_AES_decrypt
1304 1811
1305 mov $ivec,%rbp # load ivp 1812 mov $ivec,%rbp # load ivp
1306 mov 8+$ivec,$inp # if ($verticalspin) restore inp 1813 mov $_inp,$inp # if ($verticalspin) restore inp
1814 mov $_len,%r10 # load len
1307 xor 0(%rbp),$s0 # xor iv 1815 xor 0(%rbp),$s0 # xor iv
1308 xor 4(%rbp),$s1 1816 xor 4(%rbp),$s1
1309 xor 8(%rbp),$s2 1817 xor 8(%rbp),$s2
1310 xor 12(%rbp),$s3 1818 xor 12(%rbp),$s3
1311 mov $inp,%rbp # current input, next iv 1819 mov $inp,%rbp # current input, next iv
1312 1820
1313 mov $_len,%r10 # load len
1314 sub \$16,%r10 1821 sub \$16,%r10
1315 jc .Lcbc_dec_partial
1316 mov %r10,$_len # update len 1822 mov %r10,$_len # update len
1317 mov %rbp,$ivec # update ivp 1823 mov %rbp,$ivec # update ivp
1318 1824
@@ -1323,81 +1829,281 @@ AES_cbc_encrypt:
1323 1829
1324 lea 16($inp),$inp 1830 lea 16($inp),$inp
1325 lea 16($out),$out 1831 lea 16($out),$out
1326 jnz .Lcbc_dec_loop 1832 jnz .Lcbc_fast_dec_loop
1327.Lcbc_dec_end:
1328 mov $_ivp,%r12 # load user ivp 1833 mov $_ivp,%r12 # load user ivp
1329 mov 0(%rbp),%r10 # load iv 1834 mov 0(%rbp),%r10 # load iv
1330 mov 8(%rbp),%r11 1835 mov 8(%rbp),%r11
1331 mov %r10,0(%r12) # copy back to user 1836 mov %r10,0(%r12) # copy back to user
1332 mov %r11,8(%r12) 1837 mov %r11,8(%r12)
1333 jmp .Lcbc_cleanup 1838 jmp .Lcbc_fast_cleanup
1334
1335.align 4
1336.Lcbc_dec_partial:
1337 mov $s0,0+$ivec # dump output to stack
1338 mov $s1,4+$ivec
1339 mov $s2,8+$ivec
1340 mov $s3,12+$ivec
1341 mov $out,%rdi
1342 lea $ivec,%rsi
1343 mov \$16,%rcx
1344 add %r10,%rcx # number of bytes to copy
1345 .long 0xF689A4F3 # rep movsb
1346 jmp .Lcbc_dec_end
1347 1839
1348.align 16 1840.align 16
1349.Lcbc_dec_in_place: 1841.Lcbc_fast_dec_in_place:
1842 mov 0(%rbp),%r10 # copy iv to stack
1843 mov 8(%rbp),%r11
1844 mov %r10,0+$ivec
1845 mov %r11,8+$ivec
1846.align 4
1847.Lcbc_fast_dec_in_place_loop:
1350 mov 0($inp),$s0 # load input 1848 mov 0($inp),$s0 # load input
1351 mov 4($inp),$s1 1849 mov 4($inp),$s1
1352 mov 8($inp),$s2 1850 mov 8($inp),$s2
1353 mov 12($inp),$s3 1851 mov 12($inp),$s3
1852 mov $keyp,$key # restore key
1853 mov $inp,$_inp # if ($verticalspin) save inp
1354 1854
1355 mov $inp,$ivec # if ($verticalspin) save inp
1356 mov $keyp,$key
1357 call _x86_64_AES_decrypt 1855 call _x86_64_AES_decrypt
1358 1856
1359 mov $ivec,$inp # if ($verticalspin) restore inp 1857 mov $_inp,$inp # if ($verticalspin) restore inp
1360 mov $_ivp,%rbp 1858 mov $_len,%r10
1361 xor 0(%rbp),$s0 1859 xor 0+$ivec,$s0
1362 xor 4(%rbp),$s1 1860 xor 4+$ivec,$s1
1363 xor 8(%rbp),$s2 1861 xor 8+$ivec,$s2
1364 xor 12(%rbp),$s3 1862 xor 12+$ivec,$s3
1863
1864 mov 0($inp),%r11 # load input
1865 mov 8($inp),%r12
1866 sub \$16,%r10
1867 jz .Lcbc_fast_dec_in_place_done
1365 1868
1366 mov 0($inp),%r10 # copy input to iv 1869 mov %r11,0+$ivec # copy input to iv
1367 mov 8($inp),%r11 1870 mov %r12,8+$ivec
1368 mov %r10,0(%rbp)
1369 mov %r11,8(%rbp)
1370 1871
1371 mov $s0,0($out) # save output [zaps input] 1872 mov $s0,0($out) # save output [zaps input]
1372 mov $s1,4($out) 1873 mov $s1,4($out)
1373 mov $s2,8($out) 1874 mov $s2,8($out)
1374 mov $s3,12($out) 1875 mov $s3,12($out)
1375 1876
1376 mov $_len,%rcx
1377 lea 16($inp),$inp 1877 lea 16($inp),$inp
1378 lea 16($out),$out 1878 lea 16($out),$out
1379 sub \$16,%rcx 1879 mov %r10,$_len
1380 jc .Lcbc_dec_in_place_partial 1880 jmp .Lcbc_fast_dec_in_place_loop
1381 mov %rcx,$_len 1881.Lcbc_fast_dec_in_place_done:
1382 jnz .Lcbc_dec_in_place 1882 mov $_ivp,%rdi
1383 jmp .Lcbc_cleanup 1883 mov %r11,0(%rdi) # copy iv back to user
1884 mov %r12,8(%rdi)
1885
1886 mov $s0,0($out) # save output [zaps input]
1887 mov $s1,4($out)
1888 mov $s2,8($out)
1889 mov $s3,12($out)
1384 1890
1385.align 4 1891.align 4
1386.Lcbc_dec_in_place_partial: 1892.Lcbc_fast_cleanup:
1387 # one can argue if this is actually required 1893 cmpl \$0,$mark # was the key schedule copied?
1388 lea ($out,%rcx),%rdi 1894 lea $aes_key,%rdi
1389 lea (%rbp,%rcx),%rsi 1895 je .Lcbc_exit
1390 neg %rcx 1896 mov \$240/8,%ecx
1391 .long 0xF689A4F3 # rep movsb # restore tail 1897 xor %rax,%rax
1392 jmp .Lcbc_cleanup 1898 .long 0x90AB48F3 # rep stosq
1899
1900 jmp .Lcbc_exit
1901
1902#--------------------------- SLOW ROUTINE ---------------------------#
1903.align 16
1904.Lcbc_slow_prologue:
1905 # allocate aligned stack frame...
1906 lea -88(%rsp),%rbp
1907 and \$-64,%rbp
1908 # ... just "above" key schedule
1909 lea -88-63(%rcx),%r10
1910 sub %rbp,%r10
1911 neg %r10
1912 and \$0x3c0,%r10
1913 sub %r10,%rbp
1914
1915 xchg %rsp,%rbp
1916 #add \$8,%rsp # reserve for return address!
1917 mov %rbp,$_rsp # save %rsp
1918.Lcbc_slow_body:
1919 #mov %rdi,$_inp # save copy of inp
1920 #mov %rsi,$_out # save copy of out
1921 #mov %rdx,$_len # save copy of len
1922 #mov %rcx,$_key # save copy of key
1923 mov %r8,$_ivp # save copy of ivp
1924 mov %r8,%rbp # rearrange input arguments
1925 mov %r9,%rbx
1926 mov %rsi,$out
1927 mov %rdi,$inp
1928 mov %rcx,$key
1929 mov %rdx,%r10
1930
1931 mov 240($key),%eax
1932 mov $key,$keyp # save key pointer
1933 shl \$4,%eax
1934 lea ($key,%rax),%rax
1935 mov %rax,$keyend
1936
1937 # pick Te4 copy which can't "overlap" with stack frame or key scdedule
1938 lea 2048($sbox),$sbox
1939 lea 768-8(%rsp),%rax
1940 sub $sbox,%rax
1941 and \$0x300,%rax
1942 lea ($sbox,%rax),$sbox
1943
1944 cmp \$0,%rbx
1945 je .LSLOW_DECRYPT
1946
1947#--------------------------- SLOW ENCRYPT ---------------------------#
1948 test \$-16,%r10 # check upon length
1949 mov 0(%rbp),$s0 # load iv
1950 mov 4(%rbp),$s1
1951 mov 8(%rbp),$s2
1952 mov 12(%rbp),$s3
1953 jz .Lcbc_slow_enc_tail # short input...
1954
1955.align 4
1956.Lcbc_slow_enc_loop:
1957 xor 0($inp),$s0
1958 xor 4($inp),$s1
1959 xor 8($inp),$s2
1960 xor 12($inp),$s3
1961 mov $keyp,$key # restore key
1962 mov $inp,$_inp # save inp
1963 mov $out,$_out # save out
1964 mov %r10,$_len # save len
1965
1966 call _x86_64_AES_encrypt_compact
1967
1968 mov $_inp,$inp # restore inp
1969 mov $_out,$out # restore out
1970 mov $_len,%r10 # restore len
1971 mov $s0,0($out)
1972 mov $s1,4($out)
1973 mov $s2,8($out)
1974 mov $s3,12($out)
1975
1976 lea 16($inp),$inp
1977 lea 16($out),$out
1978 sub \$16,%r10
1979 test \$-16,%r10
1980 jnz .Lcbc_slow_enc_loop
1981 test \$15,%r10
1982 jnz .Lcbc_slow_enc_tail
1983 mov $_ivp,%rbp # restore ivp
1984 mov $s0,0(%rbp) # save ivec
1985 mov $s1,4(%rbp)
1986 mov $s2,8(%rbp)
1987 mov $s3,12(%rbp)
1988
1989 jmp .Lcbc_exit
1990
1991.align 4
1992.Lcbc_slow_enc_tail:
1993 mov %rax,%r11
1994 mov %rcx,%r12
1995 mov %r10,%rcx
1996 mov $inp,%rsi
1997 mov $out,%rdi
1998 .long 0x9066A4F3 # rep movsb
1999 mov \$16,%rcx # zero tail
2000 sub %r10,%rcx
2001 xor %rax,%rax
2002 .long 0x9066AAF3 # rep stosb
2003 mov $out,$inp # this is not a mistake!
2004 mov \$16,%r10 # len=16
2005 mov %r11,%rax
2006 mov %r12,%rcx
2007 jmp .Lcbc_slow_enc_loop # one more spin...
2008#--------------------------- SLOW DECRYPT ---------------------------#
2009.align 16
2010.LSLOW_DECRYPT:
2011 shr \$3,%rax
2012 add %rax,$sbox # recall "magic" constants!
2013
2014 mov 0(%rbp),%r11 # copy iv to stack
2015 mov 8(%rbp),%r12
2016 mov %r11,0+$ivec
2017 mov %r12,8+$ivec
2018
2019.align 4
2020.Lcbc_slow_dec_loop:
2021 mov 0($inp),$s0 # load input
2022 mov 4($inp),$s1
2023 mov 8($inp),$s2
2024 mov 12($inp),$s3
2025 mov $keyp,$key # restore key
2026 mov $inp,$_inp # save inp
2027 mov $out,$_out # save out
2028 mov %r10,$_len # save len
2029
2030 call _x86_64_AES_decrypt_compact
2031
2032 mov $_inp,$inp # restore inp
2033 mov $_out,$out # restore out
2034 mov $_len,%r10
2035 xor 0+$ivec,$s0
2036 xor 4+$ivec,$s1
2037 xor 8+$ivec,$s2
2038 xor 12+$ivec,$s3
2039
2040 mov 0($inp),%r11 # load input
2041 mov 8($inp),%r12
2042 sub \$16,%r10
2043 jc .Lcbc_slow_dec_partial
2044 jz .Lcbc_slow_dec_done
2045
2046 mov %r11,0+$ivec # copy input to iv
2047 mov %r12,8+$ivec
2048
2049 mov $s0,0($out) # save output [can zap input]
2050 mov $s1,4($out)
2051 mov $s2,8($out)
2052 mov $s3,12($out)
2053
2054 lea 16($inp),$inp
2055 lea 16($out),$out
2056 jmp .Lcbc_slow_dec_loop
2057.Lcbc_slow_dec_done:
2058 mov $_ivp,%rdi
2059 mov %r11,0(%rdi) # copy iv back to user
2060 mov %r12,8(%rdi)
2061
2062 mov $s0,0($out) # save output [can zap input]
2063 mov $s1,4($out)
2064 mov $s2,8($out)
2065 mov $s3,12($out)
2066
2067 jmp .Lcbc_exit
2068
2069.align 4
2070.Lcbc_slow_dec_partial:
2071 mov $_ivp,%rdi
2072 mov %r11,0(%rdi) # copy iv back to user
2073 mov %r12,8(%rdi)
2074
2075 mov $s0,0+$ivec # save output to stack
2076 mov $s1,4+$ivec
2077 mov $s2,8+$ivec
2078 mov $s3,12+$ivec
2079
2080 mov $out,%rdi
2081 lea $ivec,%rsi
2082 lea 16(%r10),%rcx
2083 .long 0x9066A4F3 # rep movsb
2084 jmp .Lcbc_exit
2085
2086.align 16
2087.Lcbc_exit:
2088 mov $_rsp,%rsi
2089 mov (%rsi),%r15
2090 mov 8(%rsi),%r14
2091 mov 16(%rsi),%r13
2092 mov 24(%rsi),%r12
2093 mov 32(%rsi),%rbp
2094 mov 40(%rsi),%rbx
2095 lea 48(%rsi),%rsp
2096.Lcbc_popfq:
2097 popfq
2098.Lcbc_epilogue:
2099 ret
1393.size AES_cbc_encrypt,.-AES_cbc_encrypt 2100.size AES_cbc_encrypt,.-AES_cbc_encrypt
1394___ 2101___
1395} 2102}
1396 2103
1397$code.=<<___; 2104$code.=<<___;
1398.globl AES_Te
1399.align 64 2105.align 64
1400AES_Te: 2106.LAES_Te:
1401___ 2107___
1402 &_data_word(0xa56363c6, 0x847c7cf8, 0x997777ee, 0x8d7b7bf6); 2108 &_data_word(0xa56363c6, 0x847c7cf8, 0x997777ee, 0x8d7b7bf6);
1403 &_data_word(0x0df2f2ff, 0xbd6b6bd6, 0xb16f6fde, 0x54c5c591); 2109 &_data_word(0x0df2f2ff, 0xbd6b6bd6, 0xb16f6fde, 0x54c5c591);
@@ -1463,16 +2169,149 @@ ___
1463 &_data_word(0xdabfbf65, 0x31e6e6d7, 0xc6424284, 0xb86868d0); 2169 &_data_word(0xdabfbf65, 0x31e6e6d7, 0xc6424284, 0xb86868d0);
1464 &_data_word(0xc3414182, 0xb0999929, 0x772d2d5a, 0x110f0f1e); 2170 &_data_word(0xc3414182, 0xb0999929, 0x772d2d5a, 0x110f0f1e);
1465 &_data_word(0xcbb0b07b, 0xfc5454a8, 0xd6bbbb6d, 0x3a16162c); 2171 &_data_word(0xcbb0b07b, 0xfc5454a8, 0xd6bbbb6d, 0x3a16162c);
2172
2173#Te4 # four copies of Te4 to choose from to avoid L1 aliasing
2174 &data_byte(0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5);
2175 &data_byte(0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76);
2176 &data_byte(0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0);
2177 &data_byte(0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0);
2178 &data_byte(0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc);
2179 &data_byte(0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15);
2180 &data_byte(0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a);
2181 &data_byte(0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75);
2182 &data_byte(0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0);
2183 &data_byte(0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84);
2184 &data_byte(0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b);
2185 &data_byte(0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf);
2186 &data_byte(0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85);
2187 &data_byte(0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8);
2188 &data_byte(0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5);
2189 &data_byte(0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2);
2190 &data_byte(0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17);
2191 &data_byte(0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73);
2192 &data_byte(0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88);
2193 &data_byte(0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb);
2194 &data_byte(0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c);
2195 &data_byte(0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79);
2196 &data_byte(0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9);
2197 &data_byte(0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08);
2198 &data_byte(0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6);
2199 &data_byte(0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a);
2200 &data_byte(0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e);
2201 &data_byte(0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e);
2202 &data_byte(0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94);
2203 &data_byte(0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf);
2204 &data_byte(0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68);
2205 &data_byte(0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16);
2206
2207 &data_byte(0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5);
2208 &data_byte(0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76);
2209 &data_byte(0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0);
2210 &data_byte(0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0);
2211 &data_byte(0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc);
2212 &data_byte(0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15);
2213 &data_byte(0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a);
2214 &data_byte(0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75);
2215 &data_byte(0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0);
2216 &data_byte(0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84);
2217 &data_byte(0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b);
2218 &data_byte(0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf);
2219 &data_byte(0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85);
2220 &data_byte(0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8);
2221 &data_byte(0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5);
2222 &data_byte(0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2);
2223 &data_byte(0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17);
2224 &data_byte(0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73);
2225 &data_byte(0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88);
2226 &data_byte(0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb);
2227 &data_byte(0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c);
2228 &data_byte(0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79);
2229 &data_byte(0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9);
2230 &data_byte(0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08);
2231 &data_byte(0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6);
2232 &data_byte(0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a);
2233 &data_byte(0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e);
2234 &data_byte(0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e);
2235 &data_byte(0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94);
2236 &data_byte(0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf);
2237 &data_byte(0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68);
2238 &data_byte(0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16);
2239
2240 &data_byte(0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5);
2241 &data_byte(0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76);
2242 &data_byte(0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0);
2243 &data_byte(0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0);
2244 &data_byte(0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc);
2245 &data_byte(0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15);
2246 &data_byte(0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a);
2247 &data_byte(0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75);
2248 &data_byte(0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0);
2249 &data_byte(0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84);
2250 &data_byte(0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b);
2251 &data_byte(0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf);
2252 &data_byte(0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85);
2253 &data_byte(0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8);
2254 &data_byte(0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5);
2255 &data_byte(0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2);
2256 &data_byte(0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17);
2257 &data_byte(0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73);
2258 &data_byte(0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88);
2259 &data_byte(0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb);
2260 &data_byte(0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c);
2261 &data_byte(0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79);
2262 &data_byte(0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9);
2263 &data_byte(0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08);
2264 &data_byte(0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6);
2265 &data_byte(0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a);
2266 &data_byte(0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e);
2267 &data_byte(0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e);
2268 &data_byte(0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94);
2269 &data_byte(0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf);
2270 &data_byte(0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68);
2271 &data_byte(0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16);
2272
2273 &data_byte(0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5);
2274 &data_byte(0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76);
2275 &data_byte(0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0);
2276 &data_byte(0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0);
2277 &data_byte(0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc);
2278 &data_byte(0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15);
2279 &data_byte(0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a);
2280 &data_byte(0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75);
2281 &data_byte(0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0);
2282 &data_byte(0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84);
2283 &data_byte(0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b);
2284 &data_byte(0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf);
2285 &data_byte(0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85);
2286 &data_byte(0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8);
2287 &data_byte(0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5);
2288 &data_byte(0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2);
2289 &data_byte(0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17);
2290 &data_byte(0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73);
2291 &data_byte(0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88);
2292 &data_byte(0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb);
2293 &data_byte(0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c);
2294 &data_byte(0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79);
2295 &data_byte(0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9);
2296 &data_byte(0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08);
2297 &data_byte(0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6);
2298 &data_byte(0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a);
2299 &data_byte(0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e);
2300 &data_byte(0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e);
2301 &data_byte(0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94);
2302 &data_byte(0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf);
2303 &data_byte(0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68);
2304 &data_byte(0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16);
1466#rcon: 2305#rcon:
1467$code.=<<___; 2306$code.=<<___;
1468 .long 0x00000001, 0x00000002, 0x00000004, 0x00000008 2307 .long 0x00000001, 0x00000002, 0x00000004, 0x00000008
1469 .long 0x00000010, 0x00000020, 0x00000040, 0x00000080 2308 .long 0x00000010, 0x00000020, 0x00000040, 0x00000080
1470 .long 0x0000001b, 0x00000036, 0, 0, 0, 0, 0, 0 2309 .long 0x0000001b, 0x00000036, 0x80808080, 0x80808080
2310 .long 0xfefefefe, 0xfefefefe, 0x1b1b1b1b, 0x1b1b1b1b
1471___ 2311___
1472$code.=<<___; 2312$code.=<<___;
1473.globl AES_Td
1474.align 64 2313.align 64
1475AES_Td: 2314.LAES_Td:
1476___ 2315___
1477 &_data_word(0x50a7f451, 0x5365417e, 0xc3a4171a, 0x965e273a); 2316 &_data_word(0x50a7f451, 0x5365417e, 0xc3a4171a, 0x965e273a);
1478 &_data_word(0xcb6bab3b, 0xf1459d1f, 0xab58faac, 0x9303e34b); 2317 &_data_word(0xcb6bab3b, 0xf1459d1f, 0xab58faac, 0x9303e34b);
@@ -1538,7 +2377,116 @@ ___
1538 &_data_word(0x72c31d16, 0x0c25e2bc, 0x8b493c28, 0x41950dff); 2377 &_data_word(0x72c31d16, 0x0c25e2bc, 0x8b493c28, 0x41950dff);
1539 &_data_word(0x7101a839, 0xdeb30c08, 0x9ce4b4d8, 0x90c15664); 2378 &_data_word(0x7101a839, 0xdeb30c08, 0x9ce4b4d8, 0x90c15664);
1540 &_data_word(0x6184cb7b, 0x70b632d5, 0x745c6c48, 0x4257b8d0); 2379 &_data_word(0x6184cb7b, 0x70b632d5, 0x745c6c48, 0x4257b8d0);
1541#Td4: 2380
2381#Td4: # four copies of Td4 to choose from to avoid L1 aliasing
2382 &data_byte(0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38);
2383 &data_byte(0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb);
2384 &data_byte(0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87);
2385 &data_byte(0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb);
2386 &data_byte(0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d);
2387 &data_byte(0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e);
2388 &data_byte(0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2);
2389 &data_byte(0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25);
2390 &data_byte(0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16);
2391 &data_byte(0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92);
2392 &data_byte(0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda);
2393 &data_byte(0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84);
2394 &data_byte(0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a);
2395 &data_byte(0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06);
2396 &data_byte(0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02);
2397 &data_byte(0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b);
2398 &data_byte(0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea);
2399 &data_byte(0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73);
2400 &data_byte(0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85);
2401 &data_byte(0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e);
2402 &data_byte(0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89);
2403 &data_byte(0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b);
2404 &data_byte(0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20);
2405 &data_byte(0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4);
2406 &data_byte(0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31);
2407 &data_byte(0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f);
2408 &data_byte(0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d);
2409 &data_byte(0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef);
2410 &data_byte(0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0);
2411 &data_byte(0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61);
2412 &data_byte(0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26);
2413 &data_byte(0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d);
2414$code.=<<___;
2415 .long 0x80808080, 0x80808080, 0xfefefefe, 0xfefefefe
2416 .long 0x1b1b1b1b, 0x1b1b1b1b, 0, 0
2417___
2418 &data_byte(0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38);
2419 &data_byte(0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb);
2420 &data_byte(0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87);
2421 &data_byte(0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb);
2422 &data_byte(0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d);
2423 &data_byte(0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e);
2424 &data_byte(0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2);
2425 &data_byte(0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25);
2426 &data_byte(0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16);
2427 &data_byte(0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92);
2428 &data_byte(0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda);
2429 &data_byte(0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84);
2430 &data_byte(0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a);
2431 &data_byte(0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06);
2432 &data_byte(0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02);
2433 &data_byte(0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b);
2434 &data_byte(0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea);
2435 &data_byte(0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73);
2436 &data_byte(0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85);
2437 &data_byte(0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e);
2438 &data_byte(0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89);
2439 &data_byte(0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b);
2440 &data_byte(0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20);
2441 &data_byte(0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4);
2442 &data_byte(0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31);
2443 &data_byte(0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f);
2444 &data_byte(0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d);
2445 &data_byte(0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef);
2446 &data_byte(0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0);
2447 &data_byte(0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61);
2448 &data_byte(0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26);
2449 &data_byte(0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d);
2450$code.=<<___;
2451 .long 0x80808080, 0x80808080, 0xfefefefe, 0xfefefefe
2452 .long 0x1b1b1b1b, 0x1b1b1b1b, 0, 0
2453___
2454 &data_byte(0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38);
2455 &data_byte(0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb);
2456 &data_byte(0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87);
2457 &data_byte(0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb);
2458 &data_byte(0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d);
2459 &data_byte(0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e);
2460 &data_byte(0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2);
2461 &data_byte(0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25);
2462 &data_byte(0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16);
2463 &data_byte(0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92);
2464 &data_byte(0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda);
2465 &data_byte(0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84);
2466 &data_byte(0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a);
2467 &data_byte(0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06);
2468 &data_byte(0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02);
2469 &data_byte(0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b);
2470 &data_byte(0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea);
2471 &data_byte(0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73);
2472 &data_byte(0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85);
2473 &data_byte(0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e);
2474 &data_byte(0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89);
2475 &data_byte(0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b);
2476 &data_byte(0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20);
2477 &data_byte(0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4);
2478 &data_byte(0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31);
2479 &data_byte(0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f);
2480 &data_byte(0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d);
2481 &data_byte(0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef);
2482 &data_byte(0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0);
2483 &data_byte(0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61);
2484 &data_byte(0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26);
2485 &data_byte(0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d);
2486$code.=<<___;
2487 .long 0x80808080, 0x80808080, 0xfefefefe, 0xfefefefe
2488 .long 0x1b1b1b1b, 0x1b1b1b1b, 0, 0
2489___
1542 &data_byte(0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38); 2490 &data_byte(0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38);
1543 &data_byte(0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb); 2491 &data_byte(0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb);
1544 &data_byte(0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87); 2492 &data_byte(0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87);
@@ -1571,6 +2519,288 @@ ___
1571 &data_byte(0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61); 2519 &data_byte(0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61);
1572 &data_byte(0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26); 2520 &data_byte(0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26);
1573 &data_byte(0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d); 2521 &data_byte(0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d);
2522$code.=<<___;
2523 .long 0x80808080, 0x80808080, 0xfefefefe, 0xfefefefe
2524 .long 0x1b1b1b1b, 0x1b1b1b1b, 0, 0
2525.asciz "AES for x86_64, CRYPTOGAMS by <appro\@openssl.org>"
2526.align 64
2527___
2528
2529# EXCEPTION_DISPOSITION handler (EXCEPTION_RECORD *rec,ULONG64 frame,
2530# CONTEXT *context,DISPATCHER_CONTEXT *disp)
2531if ($win64) {
2532$rec="%rcx";
2533$frame="%rdx";
2534$context="%r8";
2535$disp="%r9";
2536
2537$code.=<<___;
2538.extern __imp_RtlVirtualUnwind
2539.type block_se_handler,\@abi-omnipotent
2540.align 16
2541block_se_handler:
2542 push %rsi
2543 push %rdi
2544 push %rbx
2545 push %rbp
2546 push %r12
2547 push %r13
2548 push %r14
2549 push %r15
2550 pushfq
2551 sub \$64,%rsp
2552
2553 mov 120($context),%rax # pull context->Rax
2554 mov 248($context),%rbx # pull context->Rip
2555
2556 mov 8($disp),%rsi # disp->ImageBase
2557 mov 56($disp),%r11 # disp->HandlerData
2558
2559 mov 0(%r11),%r10d # HandlerData[0]
2560 lea (%rsi,%r10),%r10 # prologue label
2561 cmp %r10,%rbx # context->Rip<prologue label
2562 jb .Lin_block_prologue
2563
2564 mov 152($context),%rax # pull context->Rsp
2565
2566 mov 4(%r11),%r10d # HandlerData[1]
2567 lea (%rsi,%r10),%r10 # epilogue label
2568 cmp %r10,%rbx # context->Rip>=epilogue label
2569 jae .Lin_block_prologue
2570
2571 mov 24(%rax),%rax # pull saved real stack pointer
2572 lea 48(%rax),%rax # adjust...
2573
2574 mov -8(%rax),%rbx
2575 mov -16(%rax),%rbp
2576 mov -24(%rax),%r12
2577 mov -32(%rax),%r13
2578 mov -40(%rax),%r14
2579 mov -48(%rax),%r15
2580 mov %rbx,144($context) # restore context->Rbx
2581 mov %rbp,160($context) # restore context->Rbp
2582 mov %r12,216($context) # restore context->R12
2583 mov %r13,224($context) # restore context->R13
2584 mov %r14,232($context) # restore context->R14
2585 mov %r15,240($context) # restore context->R15
2586
2587.Lin_block_prologue:
2588 mov 8(%rax),%rdi
2589 mov 16(%rax),%rsi
2590 mov %rax,152($context) # restore context->Rsp
2591 mov %rsi,168($context) # restore context->Rsi
2592 mov %rdi,176($context) # restore context->Rdi
2593
2594 jmp .Lcommon_seh_exit
2595.size block_se_handler,.-block_se_handler
2596
2597.type key_se_handler,\@abi-omnipotent
2598.align 16
2599key_se_handler:
2600 push %rsi
2601 push %rdi
2602 push %rbx
2603 push %rbp
2604 push %r12
2605 push %r13
2606 push %r14
2607 push %r15
2608 pushfq
2609 sub \$64,%rsp
2610
2611 mov 120($context),%rax # pull context->Rax
2612 mov 248($context),%rbx # pull context->Rip
2613
2614 mov 8($disp),%rsi # disp->ImageBase
2615 mov 56($disp),%r11 # disp->HandlerData
2616
2617 mov 0(%r11),%r10d # HandlerData[0]
2618 lea (%rsi,%r10),%r10 # prologue label
2619 cmp %r10,%rbx # context->Rip<prologue label
2620 jb .Lin_key_prologue
2621
2622 mov 152($context),%rax # pull context->Rsp
2623
2624 mov 4(%r11),%r10d # HandlerData[1]
2625 lea (%rsi,%r10),%r10 # epilogue label
2626 cmp %r10,%rbx # context->Rip>=epilogue label
2627 jae .Lin_key_prologue
2628
2629 lea 56(%rax),%rax
2630
2631 mov -8(%rax),%rbx
2632 mov -16(%rax),%rbp
2633 mov -24(%rax),%r12
2634 mov -32(%rax),%r13
2635 mov -40(%rax),%r14
2636 mov -48(%rax),%r15
2637 mov %rbx,144($context) # restore context->Rbx
2638 mov %rbp,160($context) # restore context->Rbp
2639 mov %r12,216($context) # restore context->R12
2640 mov %r13,224($context) # restore context->R13
2641 mov %r14,232($context) # restore context->R14
2642 mov %r15,240($context) # restore context->R15
2643
2644.Lin_key_prologue:
2645 mov 8(%rax),%rdi
2646 mov 16(%rax),%rsi
2647 mov %rax,152($context) # restore context->Rsp
2648 mov %rsi,168($context) # restore context->Rsi
2649 mov %rdi,176($context) # restore context->Rdi
2650
2651 jmp .Lcommon_seh_exit
2652.size key_se_handler,.-key_se_handler
2653
2654.type cbc_se_handler,\@abi-omnipotent
2655.align 16
2656cbc_se_handler:
2657 push %rsi
2658 push %rdi
2659 push %rbx
2660 push %rbp
2661 push %r12
2662 push %r13
2663 push %r14
2664 push %r15
2665 pushfq
2666 sub \$64,%rsp
2667
2668 mov 120($context),%rax # pull context->Rax
2669 mov 248($context),%rbx # pull context->Rip
2670
2671 lea .Lcbc_prologue(%rip),%r10
2672 cmp %r10,%rbx # context->Rip<.Lcbc_prologue
2673 jb .Lin_cbc_prologue
2674
2675 lea .Lcbc_fast_body(%rip),%r10
2676 cmp %r10,%rbx # context->Rip<.Lcbc_fast_body
2677 jb .Lin_cbc_frame_setup
2678
2679 lea .Lcbc_slow_prologue(%rip),%r10
2680 cmp %r10,%rbx # context->Rip<.Lcbc_slow_prologue
2681 jb .Lin_cbc_body
2682
2683 lea .Lcbc_slow_body(%rip),%r10
2684 cmp %r10,%rbx # context->Rip<.Lcbc_slow_body
2685 jb .Lin_cbc_frame_setup
2686
2687.Lin_cbc_body:
2688 mov 152($context),%rax # pull context->Rsp
2689
2690 lea .Lcbc_epilogue(%rip),%r10
2691 cmp %r10,%rbx # context->Rip>=.Lcbc_epilogue
2692 jae .Lin_cbc_prologue
2693
2694 lea 8(%rax),%rax
2695
2696 lea .Lcbc_popfq(%rip),%r10
2697 cmp %r10,%rbx # context->Rip>=.Lcbc_popfq
2698 jae .Lin_cbc_prologue
2699
2700 mov `16-8`(%rax),%rax # biased $_rsp
2701 lea 56(%rax),%rax
2702
2703.Lin_cbc_frame_setup:
2704 mov -16(%rax),%rbx
2705 mov -24(%rax),%rbp
2706 mov -32(%rax),%r12
2707 mov -40(%rax),%r13
2708 mov -48(%rax),%r14
2709 mov -56(%rax),%r15
2710 mov %rbx,144($context) # restore context->Rbx
2711 mov %rbp,160($context) # restore context->Rbp
2712 mov %r12,216($context) # restore context->R12
2713 mov %r13,224($context) # restore context->R13
2714 mov %r14,232($context) # restore context->R14
2715 mov %r15,240($context) # restore context->R15
2716
2717.Lin_cbc_prologue:
2718 mov 8(%rax),%rdi
2719 mov 16(%rax),%rsi
2720 mov %rax,152($context) # restore context->Rsp
2721 mov %rsi,168($context) # restore context->Rsi
2722 mov %rdi,176($context) # restore context->Rdi
2723
2724.Lcommon_seh_exit:
2725
2726 mov 40($disp),%rdi # disp->ContextRecord
2727 mov $context,%rsi # context
2728 mov \$`1232/8`,%ecx # sizeof(CONTEXT)
2729 .long 0xa548f3fc # cld; rep movsq
2730
2731 mov $disp,%rsi
2732 xor %rcx,%rcx # arg1, UNW_FLAG_NHANDLER
2733 mov 8(%rsi),%rdx # arg2, disp->ImageBase
2734 mov 0(%rsi),%r8 # arg3, disp->ControlPc
2735 mov 16(%rsi),%r9 # arg4, disp->FunctionEntry
2736 mov 40(%rsi),%r10 # disp->ContextRecord
2737 lea 56(%rsi),%r11 # &disp->HandlerData
2738 lea 24(%rsi),%r12 # &disp->EstablisherFrame
2739 mov %r10,32(%rsp) # arg5
2740 mov %r11,40(%rsp) # arg6
2741 mov %r12,48(%rsp) # arg7
2742 mov %rcx,56(%rsp) # arg8, (NULL)
2743 call *__imp_RtlVirtualUnwind(%rip)
2744
2745 mov \$1,%eax # ExceptionContinueSearch
2746 add \$64,%rsp
2747 popfq
2748 pop %r15
2749 pop %r14
2750 pop %r13
2751 pop %r12
2752 pop %rbp
2753 pop %rbx
2754 pop %rdi
2755 pop %rsi
2756 ret
2757.size cbc_se_handler,.-cbc_se_handler
2758
2759.section .pdata
2760.align 4
2761 .rva .LSEH_begin_AES_encrypt
2762 .rva .LSEH_end_AES_encrypt
2763 .rva .LSEH_info_AES_encrypt
2764
2765 .rva .LSEH_begin_AES_decrypt
2766 .rva .LSEH_end_AES_decrypt
2767 .rva .LSEH_info_AES_decrypt
2768
2769 .rva .LSEH_begin_AES_set_encrypt_key
2770 .rva .LSEH_end_AES_set_encrypt_key
2771 .rva .LSEH_info_AES_set_encrypt_key
2772
2773 .rva .LSEH_begin_AES_set_decrypt_key
2774 .rva .LSEH_end_AES_set_decrypt_key
2775 .rva .LSEH_info_AES_set_decrypt_key
2776
2777 .rva .LSEH_begin_AES_cbc_encrypt
2778 .rva .LSEH_end_AES_cbc_encrypt
2779 .rva .LSEH_info_AES_cbc_encrypt
2780
2781.section .xdata
2782.align 8
2783.LSEH_info_AES_encrypt:
2784 .byte 9,0,0,0
2785 .rva block_se_handler
2786 .rva .Lenc_prologue,.Lenc_epilogue # HandlerData[]
2787.LSEH_info_AES_decrypt:
2788 .byte 9,0,0,0
2789 .rva block_se_handler
2790 .rva .Ldec_prologue,.Ldec_epilogue # HandlerData[]
2791.LSEH_info_AES_set_encrypt_key:
2792 .byte 9,0,0,0
2793 .rva key_se_handler
2794 .rva .Lenc_key_prologue,.Lenc_key_epilogue # HandlerData[]
2795.LSEH_info_AES_set_decrypt_key:
2796 .byte 9,0,0,0
2797 .rva key_se_handler
2798 .rva .Ldec_key_prologue,.Ldec_key_epilogue # HandlerData[]
2799.LSEH_info_AES_cbc_encrypt:
2800 .byte 9,0,0,0
2801 .rva cbc_se_handler
2802___
2803}
1574 2804
1575$code =~ s/\`([^\`]*)\`/eval($1)/gem; 2805$code =~ s/\`([^\`]*)\`/eval($1)/gem;
1576 2806
diff --git a/src/lib/libcrypto/asn1/a_bitstr.c b/src/lib/libcrypto/asn1/a_bitstr.c
index 0fb9ce0c2a..34179960b8 100644
--- a/src/lib/libcrypto/asn1/a_bitstr.c
+++ b/src/lib/libcrypto/asn1/a_bitstr.c
@@ -223,3 +223,26 @@ int ASN1_BIT_STRING_get_bit(ASN1_BIT_STRING *a, int n)
223 return((a->data[w]&v) != 0); 223 return((a->data[w]&v) != 0);
224 } 224 }
225 225
226/*
227 * Checks if the given bit string contains only bits specified by
228 * the flags vector. Returns 0 if there is at least one bit set in 'a'
229 * which is not specified in 'flags', 1 otherwise.
230 * 'len' is the length of 'flags'.
231 */
232int ASN1_BIT_STRING_check(ASN1_BIT_STRING *a,
233 unsigned char *flags, int flags_len)
234 {
235 int i, ok;
236 /* Check if there is one bit set at all. */
237 if (!a || !a->data) return 1;
238
239 /* Check each byte of the internal representation of the bit string. */
240 ok = 1;
241 for (i = 0; i < a->length && ok; ++i)
242 {
243 unsigned char mask = i < flags_len ? ~flags[i] : 0xff;
244 /* We are done if there is an unneeded bit set. */
245 ok = (a->data[i] & mask) == 0;
246 }
247 return ok;
248 }
diff --git a/src/lib/libcrypto/asn1/a_dup.c b/src/lib/libcrypto/asn1/a_dup.c
index 199d50f521..d98992548a 100644
--- a/src/lib/libcrypto/asn1/a_dup.c
+++ b/src/lib/libcrypto/asn1/a_dup.c
@@ -62,7 +62,7 @@
62 62
63#ifndef NO_OLD_ASN1 63#ifndef NO_OLD_ASN1
64 64
65void *ASN1_dup(i2d_of_void *i2d, d2i_of_void *d2i, char *x) 65void *ASN1_dup(i2d_of_void *i2d, d2i_of_void *d2i, void *x)
66 { 66 {
67 unsigned char *b,*p; 67 unsigned char *b,*p;
68 const unsigned char *p2; 68 const unsigned char *p2;
diff --git a/src/lib/libcrypto/asn1/a_int.c b/src/lib/libcrypto/asn1/a_int.c
index f8d198efb1..c6fd204ae3 100644
--- a/src/lib/libcrypto/asn1/a_int.c
+++ b/src/lib/libcrypto/asn1/a_int.c
@@ -61,10 +61,10 @@
61#include <openssl/asn1.h> 61#include <openssl/asn1.h>
62#include <openssl/bn.h> 62#include <openssl/bn.h>
63 63
64ASN1_INTEGER *ASN1_INTEGER_dup(ASN1_INTEGER *x) 64ASN1_INTEGER *ASN1_INTEGER_dup(const ASN1_INTEGER *x)
65{ return M_ASN1_INTEGER_dup(x);} 65{ return M_ASN1_INTEGER_dup(x);}
66 66
67int ASN1_INTEGER_cmp(ASN1_INTEGER *x, ASN1_INTEGER *y) 67int ASN1_INTEGER_cmp(const ASN1_INTEGER *x, const ASN1_INTEGER *y)
68 { 68 {
69 int neg, ret; 69 int neg, ret;
70 /* Compare signs */ 70 /* Compare signs */
@@ -373,7 +373,7 @@ int ASN1_INTEGER_set(ASN1_INTEGER *a, long v)
373 return(1); 373 return(1);
374 } 374 }
375 375
376long ASN1_INTEGER_get(ASN1_INTEGER *a) 376long ASN1_INTEGER_get(const ASN1_INTEGER *a)
377 { 377 {
378 int neg=0,i; 378 int neg=0,i;
379 long r=0; 379 long r=0;
@@ -402,7 +402,7 @@ long ASN1_INTEGER_get(ASN1_INTEGER *a)
402 return(r); 402 return(r);
403 } 403 }
404 404
405ASN1_INTEGER *BN_to_ASN1_INTEGER(BIGNUM *bn, ASN1_INTEGER *ai) 405ASN1_INTEGER *BN_to_ASN1_INTEGER(const BIGNUM *bn, ASN1_INTEGER *ai)
406 { 406 {
407 ASN1_INTEGER *ret; 407 ASN1_INTEGER *ret;
408 int len,j; 408 int len,j;
@@ -444,7 +444,7 @@ err:
444 return(NULL); 444 return(NULL);
445 } 445 }
446 446
447BIGNUM *ASN1_INTEGER_to_BN(ASN1_INTEGER *ai, BIGNUM *bn) 447BIGNUM *ASN1_INTEGER_to_BN(const ASN1_INTEGER *ai, BIGNUM *bn)
448 { 448 {
449 BIGNUM *ret; 449 BIGNUM *ret;
450 450
diff --git a/src/lib/libcrypto/asn1/a_mbstr.c b/src/lib/libcrypto/asn1/a_mbstr.c
index 1bcd046893..1538e0a4fc 100644
--- a/src/lib/libcrypto/asn1/a_mbstr.c
+++ b/src/lib/libcrypto/asn1/a_mbstr.c
@@ -93,7 +93,7 @@ int ASN1_mbstring_ncopy(ASN1_STRING **out, const unsigned char *in, int len,
93 int str_type; 93 int str_type;
94 int ret; 94 int ret;
95 char free_out; 95 char free_out;
96 int outform, outlen; 96 int outform, outlen = 0;
97 ASN1_STRING *dest; 97 ASN1_STRING *dest;
98 unsigned char *p; 98 unsigned char *p;
99 int nchar; 99 int nchar;
diff --git a/src/lib/libcrypto/asn1/a_object.c b/src/lib/libcrypto/asn1/a_object.c
index dc980421d0..e5fbe7cbb1 100644
--- a/src/lib/libcrypto/asn1/a_object.c
+++ b/src/lib/libcrypto/asn1/a_object.c
@@ -281,8 +281,6 @@ ASN1_OBJECT *d2i_ASN1_OBJECT(ASN1_OBJECT **a, const unsigned char **pp,
281 return ret; 281 return ret;
282err: 282err:
283 ASN1err(ASN1_F_D2I_ASN1_OBJECT,i); 283 ASN1err(ASN1_F_D2I_ASN1_OBJECT,i);
284 if ((ret != NULL) && ((a == NULL) || (*a != ret)))
285 ASN1_OBJECT_free(ret);
286 return(NULL); 284 return(NULL);
287} 285}
288ASN1_OBJECT *c2i_ASN1_OBJECT(ASN1_OBJECT **a, const unsigned char **pp, 286ASN1_OBJECT *c2i_ASN1_OBJECT(ASN1_OBJECT **a, const unsigned char **pp,
@@ -290,7 +288,19 @@ ASN1_OBJECT *c2i_ASN1_OBJECT(ASN1_OBJECT **a, const unsigned char **pp,
290 { 288 {
291 ASN1_OBJECT *ret=NULL; 289 ASN1_OBJECT *ret=NULL;
292 const unsigned char *p; 290 const unsigned char *p;
291 unsigned char *data;
293 int i; 292 int i;
293 /* Sanity check OID encoding: can't have leading 0x80 in
294 * subidentifiers, see: X.690 8.19.2
295 */
296 for (i = 0, p = *pp + 1; i < len - 1; i++, p++)
297 {
298 if (*p == 0x80 && (!i || !(p[-1] & 0x80)))
299 {
300 ASN1err(ASN1_F_C2I_ASN1_OBJECT,ASN1_R_INVALID_OBJECT_ENCODING);
301 return NULL;
302 }
303 }
294 304
295 /* only the ASN1_OBJECTs from the 'table' will have values 305 /* only the ASN1_OBJECTs from the 'table' will have values
296 * for ->sn or ->ln */ 306 * for ->sn or ->ln */
@@ -302,15 +312,22 @@ ASN1_OBJECT *c2i_ASN1_OBJECT(ASN1_OBJECT **a, const unsigned char **pp,
302 else ret=(*a); 312 else ret=(*a);
303 313
304 p= *pp; 314 p= *pp;
305 if ((ret->data == NULL) || (ret->length < len)) 315 /* detach data from object */
316 data = (unsigned char *)ret->data;
317 ret->data = NULL;
318 /* once detached we can change it */
319 if ((data == NULL) || (ret->length < len))
306 { 320 {
307 if (ret->data != NULL) OPENSSL_free(ret->data); 321 ret->length=0;
308 ret->data=(unsigned char *)OPENSSL_malloc(len ? (int)len : 1); 322 if (data != NULL) OPENSSL_free(data);
309 ret->flags|=ASN1_OBJECT_FLAG_DYNAMIC_DATA; 323 data=(unsigned char *)OPENSSL_malloc(len ? (int)len : 1);
310 if (ret->data == NULL) 324 if (data == NULL)
311 { i=ERR_R_MALLOC_FAILURE; goto err; } 325 { i=ERR_R_MALLOC_FAILURE; goto err; }
326 ret->flags|=ASN1_OBJECT_FLAG_DYNAMIC_DATA;
312 } 327 }
313 memcpy(ret->data,p,(int)len); 328 memcpy(data,p,(int)len);
329 /* reattach data to object, after which it remains const */
330 ret->data =data;
314 ret->length=(int)len; 331 ret->length=(int)len;
315 ret->sn=NULL; 332 ret->sn=NULL;
316 ret->ln=NULL; 333 ret->ln=NULL;
@@ -359,7 +376,7 @@ void ASN1_OBJECT_free(ASN1_OBJECT *a)
359 } 376 }
360 if (a->flags & ASN1_OBJECT_FLAG_DYNAMIC_DATA) 377 if (a->flags & ASN1_OBJECT_FLAG_DYNAMIC_DATA)
361 { 378 {
362 if (a->data != NULL) OPENSSL_free(a->data); 379 if (a->data != NULL) OPENSSL_free((void *)a->data);
363 a->data=NULL; 380 a->data=NULL;
364 a->length=0; 381 a->length=0;
365 } 382 }
diff --git a/src/lib/libcrypto/asn1/a_octet.c b/src/lib/libcrypto/asn1/a_octet.c
index 24fd0f8e5a..e8725e44f1 100644
--- a/src/lib/libcrypto/asn1/a_octet.c
+++ b/src/lib/libcrypto/asn1/a_octet.c
@@ -60,10 +60,10 @@
60#include "cryptlib.h" 60#include "cryptlib.h"
61#include <openssl/asn1.h> 61#include <openssl/asn1.h>
62 62
63ASN1_OCTET_STRING *ASN1_OCTET_STRING_dup(ASN1_OCTET_STRING *x) 63ASN1_OCTET_STRING *ASN1_OCTET_STRING_dup(const ASN1_OCTET_STRING *x)
64{ return M_ASN1_OCTET_STRING_dup(x); } 64{ return M_ASN1_OCTET_STRING_dup(x); }
65 65
66int ASN1_OCTET_STRING_cmp(ASN1_OCTET_STRING *a, ASN1_OCTET_STRING *b) 66int ASN1_OCTET_STRING_cmp(const ASN1_OCTET_STRING *a, const ASN1_OCTET_STRING *b)
67{ return M_ASN1_OCTET_STRING_cmp(a, b); } 67{ return M_ASN1_OCTET_STRING_cmp(a, b); }
68 68
69int ASN1_OCTET_STRING_set(ASN1_OCTET_STRING *x, const unsigned char *d, int len) 69int ASN1_OCTET_STRING_set(ASN1_OCTET_STRING *x, const unsigned char *d, int len)
diff --git a/src/lib/libcrypto/asn1/a_set.c b/src/lib/libcrypto/asn1/a_set.c
index 958558c204..d726c8d3a8 100644
--- a/src/lib/libcrypto/asn1/a_set.c
+++ b/src/lib/libcrypto/asn1/a_set.c
@@ -85,8 +85,9 @@ static int SetBlobCmp(const void *elem1, const void *elem2 )
85 } 85 }
86 86
87/* int is_set: if TRUE, then sort the contents (i.e. it isn't a SEQUENCE) */ 87/* int is_set: if TRUE, then sort the contents (i.e. it isn't a SEQUENCE) */
88int i2d_ASN1_SET(STACK *a, unsigned char **pp, i2d_of_void *i2d, int ex_tag, 88int i2d_ASN1_SET(STACK_OF(OPENSSL_BLOCK) *a, unsigned char **pp,
89 int ex_class, int is_set) 89 i2d_of_void *i2d, int ex_tag, int ex_class,
90 int is_set)
90 { 91 {
91 int ret=0,r; 92 int ret=0,r;
92 int i; 93 int i;
@@ -96,8 +97,8 @@ int i2d_ASN1_SET(STACK *a, unsigned char **pp, i2d_of_void *i2d, int ex_tag,
96 int totSize; 97 int totSize;
97 98
98 if (a == NULL) return(0); 99 if (a == NULL) return(0);
99 for (i=sk_num(a)-1; i>=0; i--) 100 for (i=sk_OPENSSL_BLOCK_num(a)-1; i>=0; i--)
100 ret+=i2d(sk_value(a,i),NULL); 101 ret+=i2d(sk_OPENSSL_BLOCK_value(a,i),NULL);
101 r=ASN1_object_size(1,ret,ex_tag); 102 r=ASN1_object_size(1,ret,ex_tag);
102 if (pp == NULL) return(r); 103 if (pp == NULL) return(r);
103 104
@@ -108,10 +109,10 @@ int i2d_ASN1_SET(STACK *a, unsigned char **pp, i2d_of_void *i2d, int ex_tag,
108 /* And then again by Ben */ 109 /* And then again by Ben */
109 /* And again by Steve */ 110 /* And again by Steve */
110 111
111 if(!is_set || (sk_num(a) < 2)) 112 if(!is_set || (sk_OPENSSL_BLOCK_num(a) < 2))
112 { 113 {
113 for (i=0; i<sk_num(a); i++) 114 for (i=0; i<sk_OPENSSL_BLOCK_num(a); i++)
114 i2d(sk_value(a,i),&p); 115 i2d(sk_OPENSSL_BLOCK_value(a,i),&p);
115 116
116 *pp=p; 117 *pp=p;
117 return(r); 118 return(r);
@@ -119,17 +120,17 @@ int i2d_ASN1_SET(STACK *a, unsigned char **pp, i2d_of_void *i2d, int ex_tag,
119 120
120 pStart = p; /* Catch the beg of Setblobs*/ 121 pStart = p; /* Catch the beg of Setblobs*/
121 /* In this array we will store the SET blobs */ 122 /* In this array we will store the SET blobs */
122 rgSetBlob = (MYBLOB *)OPENSSL_malloc(sk_num(a) * sizeof(MYBLOB)); 123 rgSetBlob = OPENSSL_malloc(sk_OPENSSL_BLOCK_num(a) * sizeof(MYBLOB));
123 if (rgSetBlob == NULL) 124 if (rgSetBlob == NULL)
124 { 125 {
125 ASN1err(ASN1_F_I2D_ASN1_SET,ERR_R_MALLOC_FAILURE); 126 ASN1err(ASN1_F_I2D_ASN1_SET,ERR_R_MALLOC_FAILURE);
126 return(0); 127 return(0);
127 } 128 }
128 129
129 for (i=0; i<sk_num(a); i++) 130 for (i=0; i<sk_OPENSSL_BLOCK_num(a); i++)
130 { 131 {
131 rgSetBlob[i].pbData = p; /* catch each set encode blob */ 132 rgSetBlob[i].pbData = p; /* catch each set encode blob */
132 i2d(sk_value(a,i),&p); 133 i2d(sk_OPENSSL_BLOCK_value(a,i),&p);
133 rgSetBlob[i].cbData = p - rgSetBlob[i].pbData; /* Length of this 134 rgSetBlob[i].cbData = p - rgSetBlob[i].pbData; /* Length of this
134SetBlob 135SetBlob
135*/ 136*/
@@ -139,7 +140,7 @@ SetBlob
139 140
140 /* Now we have to sort the blobs. I am using a simple algo. 141 /* Now we have to sort the blobs. I am using a simple algo.
141 *Sort ptrs *Copy to temp-mem *Copy from temp-mem to user-mem*/ 142 *Sort ptrs *Copy to temp-mem *Copy from temp-mem to user-mem*/
142 qsort( rgSetBlob, sk_num(a), sizeof(MYBLOB), SetBlobCmp); 143 qsort( rgSetBlob, sk_OPENSSL_BLOCK_num(a), sizeof(MYBLOB), SetBlobCmp);
143 if (!(pTempMem = OPENSSL_malloc(totSize))) 144 if (!(pTempMem = OPENSSL_malloc(totSize)))
144 { 145 {
145 ASN1err(ASN1_F_I2D_ASN1_SET,ERR_R_MALLOC_FAILURE); 146 ASN1err(ASN1_F_I2D_ASN1_SET,ERR_R_MALLOC_FAILURE);
@@ -148,7 +149,7 @@ SetBlob
148 149
149/* Copy to temp mem */ 150/* Copy to temp mem */
150 p = pTempMem; 151 p = pTempMem;
151 for(i=0; i<sk_num(a); ++i) 152 for(i=0; i<sk_OPENSSL_BLOCK_num(a); ++i)
152 { 153 {
153 memcpy(p, rgSetBlob[i].pbData, rgSetBlob[i].cbData); 154 memcpy(p, rgSetBlob[i].pbData, rgSetBlob[i].cbData);
154 p += rgSetBlob[i].cbData; 155 p += rgSetBlob[i].cbData;
@@ -162,16 +163,18 @@ SetBlob
162 return(r); 163 return(r);
163 } 164 }
164 165
165STACK *d2i_ASN1_SET(STACK **a, const unsigned char **pp, long length, 166STACK_OF(OPENSSL_BLOCK) *d2i_ASN1_SET(STACK_OF(OPENSSL_BLOCK) **a,
166 d2i_of_void *d2i, void (*free_func)(void *), int ex_tag, 167 const unsigned char **pp,
167 int ex_class) 168 long length, d2i_of_void *d2i,
169 void (*free_func)(OPENSSL_BLOCK), int ex_tag,
170 int ex_class)
168 { 171 {
169 ASN1_const_CTX c; 172 ASN1_const_CTX c;
170 STACK *ret=NULL; 173 STACK_OF(OPENSSL_BLOCK) *ret=NULL;
171 174
172 if ((a == NULL) || ((*a) == NULL)) 175 if ((a == NULL) || ((*a) == NULL))
173 { 176 {
174 if ((ret=sk_new_null()) == NULL) 177 if ((ret=sk_OPENSSL_BLOCK_new_null()) == NULL)
175 { 178 {
176 ASN1err(ASN1_F_D2I_ASN1_SET,ERR_R_MALLOC_FAILURE); 179 ASN1err(ASN1_F_D2I_ASN1_SET,ERR_R_MALLOC_FAILURE);
177 goto err; 180 goto err;
@@ -216,10 +219,10 @@ STACK *d2i_ASN1_SET(STACK **a, const unsigned char **pp, long length,
216 if ((s=d2i(NULL,&c.p,c.slen)) == NULL) 219 if ((s=d2i(NULL,&c.p,c.slen)) == NULL)
217 { 220 {
218 ASN1err(ASN1_F_D2I_ASN1_SET,ASN1_R_ERROR_PARSING_SET_ELEMENT); 221 ASN1err(ASN1_F_D2I_ASN1_SET,ASN1_R_ERROR_PARSING_SET_ELEMENT);
219 asn1_add_error(*pp,(int)(c.q- *pp)); 222 asn1_add_error(*pp,(int)(c.p- *pp));
220 goto err; 223 goto err;
221 } 224 }
222 if (!sk_push(ret,s)) goto err; 225 if (!sk_OPENSSL_BLOCK_push(ret,s)) goto err;
223 } 226 }
224 if (a != NULL) (*a)=ret; 227 if (a != NULL) (*a)=ret;
225 *pp=c.p; 228 *pp=c.p;
@@ -228,9 +231,9 @@ err:
228 if ((ret != NULL) && ((a == NULL) || (*a != ret))) 231 if ((ret != NULL) && ((a == NULL) || (*a != ret)))
229 { 232 {
230 if (free_func != NULL) 233 if (free_func != NULL)
231 sk_pop_free(ret,free_func); 234 sk_OPENSSL_BLOCK_pop_free(ret,free_func);
232 else 235 else
233 sk_free(ret); 236 sk_OPENSSL_BLOCK_free(ret);
234 } 237 }
235 return(NULL); 238 return(NULL);
236 } 239 }
diff --git a/src/lib/libcrypto/asn1/a_sign.c b/src/lib/libcrypto/asn1/a_sign.c
index 4dee45fbb8..ff63bfc7be 100644
--- a/src/lib/libcrypto/asn1/a_sign.c
+++ b/src/lib/libcrypto/asn1/a_sign.c
@@ -123,6 +123,7 @@
123#include <openssl/x509.h> 123#include <openssl/x509.h>
124#include <openssl/objects.h> 124#include <openssl/objects.h>
125#include <openssl/buffer.h> 125#include <openssl/buffer.h>
126#include "asn1_locl.h"
126 127
127#ifndef NO_ASN1_OLD 128#ifndef NO_ASN1_OLD
128 129
@@ -218,45 +219,47 @@ int ASN1_item_sign(const ASN1_ITEM *it, X509_ALGOR *algor1, X509_ALGOR *algor2,
218 { 219 {
219 EVP_MD_CTX ctx; 220 EVP_MD_CTX ctx;
220 unsigned char *buf_in=NULL,*buf_out=NULL; 221 unsigned char *buf_in=NULL,*buf_out=NULL;
221 int i,inl=0,outl=0,outll=0; 222 int inl=0,outl=0,outll=0;
222 X509_ALGOR *a; 223 int signid, paramtype;
223 224
224 EVP_MD_CTX_init(&ctx); 225 if (type == NULL)
225 for (i=0; i<2; i++)
226 { 226 {
227 if (i == 0) 227 int def_nid;
228 a=algor1; 228 if (EVP_PKEY_get_default_digest_nid(pkey, &def_nid) > 0)
229 else 229 type = EVP_get_digestbynid(def_nid);
230 a=algor2; 230 }
231 if (a == NULL) continue; 231
232 if (type->pkey_type == NID_dsaWithSHA1 || 232 if (type == NULL)
233 type->pkey_type == NID_ecdsa_with_SHA1) 233 {
234 { 234 ASN1err(ASN1_F_ASN1_ITEM_SIGN, ASN1_R_NO_DEFAULT_DIGEST);
235 /* special case: RFC 3279 tells us to omit 'parameters' 235 return 0;
236 * with id-dsa-with-sha1 and ecdsa-with-SHA1 */ 236 }
237 ASN1_TYPE_free(a->parameter); 237
238 a->parameter = NULL; 238 if (type->flags & EVP_MD_FLAG_PKEY_METHOD_SIGNATURE)
239 } 239 {
240 else if ((a->parameter == NULL) || 240 if (!pkey->ameth ||
241 (a->parameter->type != V_ASN1_NULL)) 241 !OBJ_find_sigid_by_algs(&signid, EVP_MD_nid(type),
242 { 242 pkey->ameth->pkey_id))
243 ASN1_TYPE_free(a->parameter);
244 if ((a->parameter=ASN1_TYPE_new()) == NULL) goto err;
245 a->parameter->type=V_ASN1_NULL;
246 }
247 ASN1_OBJECT_free(a->algorithm);
248 a->algorithm=OBJ_nid2obj(type->pkey_type);
249 if (a->algorithm == NULL)
250 {
251 ASN1err(ASN1_F_ASN1_ITEM_SIGN,ASN1_R_UNKNOWN_OBJECT_TYPE);
252 goto err;
253 }
254 if (a->algorithm->length == 0)
255 { 243 {
256 ASN1err(ASN1_F_ASN1_ITEM_SIGN,ASN1_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD); 244 ASN1err(ASN1_F_ASN1_ITEM_SIGN,
257 goto err; 245 ASN1_R_DIGEST_AND_KEY_TYPE_NOT_SUPPORTED);
246 return 0;
258 } 247 }
259 } 248 }
249 else
250 signid = type->pkey_type;
251
252 if (pkey->ameth->pkey_flags & ASN1_PKEY_SIGPARAM_NULL)
253 paramtype = V_ASN1_NULL;
254 else
255 paramtype = V_ASN1_UNDEF;
256
257 if (algor1)
258 X509_ALGOR_set0(algor1, OBJ_nid2obj(signid), paramtype, NULL);
259 if (algor2)
260 X509_ALGOR_set0(algor2, OBJ_nid2obj(signid), paramtype, NULL);
261
262 EVP_MD_CTX_init(&ctx);
260 inl=ASN1_item_i2d(asn,&buf_in, it); 263 inl=ASN1_item_i2d(asn,&buf_in, it);
261 outll=outl=EVP_PKEY_size(pkey); 264 outll=outl=EVP_PKEY_size(pkey);
262 buf_out=(unsigned char *)OPENSSL_malloc((unsigned int)outl); 265 buf_out=(unsigned char *)OPENSSL_malloc((unsigned int)outl);
@@ -267,12 +270,7 @@ int ASN1_item_sign(const ASN1_ITEM *it, X509_ALGOR *algor1, X509_ALGOR *algor2,
267 goto err; 270 goto err;
268 } 271 }
269 272
270 if (!EVP_SignInit_ex(&ctx,type, NULL)) 273 EVP_SignInit_ex(&ctx,type, NULL);
271 {
272 outl=0;
273 ASN1err(ASN1_F_ASN1_ITEM_SIGN,ERR_R_EVP_LIB);
274 goto err;
275 }
276 EVP_SignUpdate(&ctx,(unsigned char *)buf_in,inl); 274 EVP_SignUpdate(&ctx,(unsigned char *)buf_in,inl);
277 if (!EVP_SignFinal(&ctx,(unsigned char *)buf_out, 275 if (!EVP_SignFinal(&ctx,(unsigned char *)buf_out,
278 (unsigned int *)&outl,pkey)) 276 (unsigned int *)&outl,pkey))
diff --git a/src/lib/libcrypto/asn1/a_strnid.c b/src/lib/libcrypto/asn1/a_strnid.c
index fe515b52ba..753021a7a2 100644
--- a/src/lib/libcrypto/asn1/a_strnid.c
+++ b/src/lib/libcrypto/asn1/a_strnid.c
@@ -67,7 +67,6 @@ static STACK_OF(ASN1_STRING_TABLE) *stable = NULL;
67static void st_free(ASN1_STRING_TABLE *tbl); 67static void st_free(ASN1_STRING_TABLE *tbl);
68static int sk_table_cmp(const ASN1_STRING_TABLE * const *a, 68static int sk_table_cmp(const ASN1_STRING_TABLE * const *a,
69 const ASN1_STRING_TABLE * const *b); 69 const ASN1_STRING_TABLE * const *b);
70static int table_cmp(const void *a, const void *b);
71 70
72 71
73/* This is the global mask for the mbstring functions: this is use to 72/* This is the global mask for the mbstring functions: this is use to
@@ -158,7 +157,7 @@ ASN1_STRING *ASN1_STRING_set_by_NID(ASN1_STRING **out, const unsigned char *in,
158 157
159/* This table must be kept in NID order */ 158/* This table must be kept in NID order */
160 159
161static ASN1_STRING_TABLE tbl_standard[] = { 160static const ASN1_STRING_TABLE tbl_standard[] = {
162{NID_commonName, 1, ub_common_name, DIRSTRING_TYPE, 0}, 161{NID_commonName, 1, ub_common_name, DIRSTRING_TYPE, 0},
163{NID_countryName, 2, 2, B_ASN1_PRINTABLESTRING, STABLE_NO_MASK}, 162{NID_countryName, 2, 2, B_ASN1_PRINTABLESTRING, STABLE_NO_MASK},
164{NID_localityName, 1, ub_locality_name, DIRSTRING_TYPE, 0}, 163{NID_localityName, 1, ub_locality_name, DIRSTRING_TYPE, 0},
@@ -186,22 +185,23 @@ static int sk_table_cmp(const ASN1_STRING_TABLE * const *a,
186 return (*a)->nid - (*b)->nid; 185 return (*a)->nid - (*b)->nid;
187} 186}
188 187
189static int table_cmp(const void *a, const void *b) 188DECLARE_OBJ_BSEARCH_CMP_FN(ASN1_STRING_TABLE, ASN1_STRING_TABLE, table);
189
190static int table_cmp(const ASN1_STRING_TABLE *a, const ASN1_STRING_TABLE *b)
190{ 191{
191 const ASN1_STRING_TABLE *sa = a, *sb = b; 192 return a->nid - b->nid;
192 return sa->nid - sb->nid;
193} 193}
194 194
195IMPLEMENT_OBJ_BSEARCH_CMP_FN(ASN1_STRING_TABLE, ASN1_STRING_TABLE, table);
196
195ASN1_STRING_TABLE *ASN1_STRING_TABLE_get(int nid) 197ASN1_STRING_TABLE *ASN1_STRING_TABLE_get(int nid)
196{ 198{
197 int idx; 199 int idx;
198 ASN1_STRING_TABLE *ttmp; 200 ASN1_STRING_TABLE *ttmp;
199 ASN1_STRING_TABLE fnd; 201 ASN1_STRING_TABLE fnd;
200 fnd.nid = nid; 202 fnd.nid = nid;
201 ttmp = (ASN1_STRING_TABLE *) OBJ_bsearch((char *)&fnd, 203 ttmp = OBJ_bsearch_table(&fnd, tbl_standard,
202 (char *)tbl_standard, 204 sizeof(tbl_standard)/sizeof(ASN1_STRING_TABLE));
203 sizeof(tbl_standard)/sizeof(ASN1_STRING_TABLE),
204 sizeof(ASN1_STRING_TABLE), table_cmp);
205 if(ttmp) return ttmp; 205 if(ttmp) return ttmp;
206 if(!stable) return NULL; 206 if(!stable) return NULL;
207 idx = sk_ASN1_STRING_TABLE_find(stable, &fnd); 207 idx = sk_ASN1_STRING_TABLE_find(stable, &fnd);
diff --git a/src/lib/libcrypto/asn1/a_time.c b/src/lib/libcrypto/asn1/a_time.c
index 159681fbcb..e2eb9b243e 100644
--- a/src/lib/libcrypto/asn1/a_time.c
+++ b/src/lib/libcrypto/asn1/a_time.c
@@ -100,18 +100,29 @@ int i2d_ASN1_TIME(ASN1_TIME *a, unsigned char **pp)
100 100
101ASN1_TIME *ASN1_TIME_set(ASN1_TIME *s, time_t t) 101ASN1_TIME *ASN1_TIME_set(ASN1_TIME *s, time_t t)
102 { 102 {
103 return ASN1_TIME_adj(s, t, 0, 0);
104 }
105
106ASN1_TIME *ASN1_TIME_adj(ASN1_TIME *s, time_t t,
107 int offset_day, long offset_sec)
108 {
103 struct tm *ts; 109 struct tm *ts;
104 struct tm data; 110 struct tm data;
105 111
106 ts=OPENSSL_gmtime(&t,&data); 112 ts=OPENSSL_gmtime(&t,&data);
107 if (ts == NULL) 113 if (ts == NULL)
108 { 114 {
109 ASN1err(ASN1_F_ASN1_TIME_SET, ASN1_R_ERROR_GETTING_TIME); 115 ASN1err(ASN1_F_ASN1_TIME_ADJ, ASN1_R_ERROR_GETTING_TIME);
110 return NULL; 116 return NULL;
111 } 117 }
118 if (offset_day || offset_sec)
119 {
120 if (!OPENSSL_gmtime_adj(ts, offset_day, offset_sec))
121 return NULL;
122 }
112 if((ts->tm_year >= 50) && (ts->tm_year < 150)) 123 if((ts->tm_year >= 50) && (ts->tm_year < 150))
113 return ASN1_UTCTIME_set(s, t); 124 return ASN1_UTCTIME_adj(s, t, offset_day, offset_sec);
114 return ASN1_GENERALIZEDTIME_set(s,t); 125 return ASN1_GENERALIZEDTIME_adj(s, t, offset_day, offset_sec);
115 } 126 }
116 127
117int ASN1_TIME_check(ASN1_TIME *t) 128int ASN1_TIME_check(ASN1_TIME *t)
@@ -162,3 +173,26 @@ ASN1_GENERALIZEDTIME *ASN1_TIME_to_generalizedtime(ASN1_TIME *t, ASN1_GENERALIZE
162 173
163 return ret; 174 return ret;
164 } 175 }
176
177int ASN1_TIME_set_string(ASN1_TIME *s, const char *str)
178 {
179 ASN1_TIME t;
180
181 t.length = strlen(str);
182 t.data = (unsigned char *)str;
183 t.flags = 0;
184
185 t.type = V_ASN1_UTCTIME;
186
187 if (!ASN1_TIME_check(&t))
188 {
189 t.type = V_ASN1_GENERALIZEDTIME;
190 if (!ASN1_TIME_check(&t))
191 return 0;
192 }
193
194 if (s && !ASN1_STRING_copy((ASN1_STRING *)s, (ASN1_STRING *)&t))
195 return 0;
196
197 return 1;
198 }
diff --git a/src/lib/libcrypto/asn1/a_type.c b/src/lib/libcrypto/asn1/a_type.c
index 36beceacdb..a45d2f9d12 100644
--- a/src/lib/libcrypto/asn1/a_type.c
+++ b/src/lib/libcrypto/asn1/a_type.c
@@ -77,7 +77,10 @@ void ASN1_TYPE_set(ASN1_TYPE *a, int type, void *value)
77 ASN1_primitive_free((ASN1_VALUE **)tmp_a, NULL); 77 ASN1_primitive_free((ASN1_VALUE **)tmp_a, NULL);
78 } 78 }
79 a->type=type; 79 a->type=type;
80 a->value.ptr=value; 80 if (type == V_ASN1_BOOLEAN)
81 a->value.boolean = value ? 0xff : 0;
82 else
83 a->value.ptr=value;
81 } 84 }
82 85
83int ASN1_TYPE_set1(ASN1_TYPE *a, int type, const void *value) 86int ASN1_TYPE_set1(ASN1_TYPE *a, int type, const void *value)
@@ -98,7 +101,7 @@ int ASN1_TYPE_set1(ASN1_TYPE *a, int type, const void *value)
98 else 101 else
99 { 102 {
100 ASN1_STRING *sdup; 103 ASN1_STRING *sdup;
101 sdup = ASN1_STRING_dup((ASN1_STRING *)value); 104 sdup = ASN1_STRING_dup(value);
102 if (!sdup) 105 if (!sdup)
103 return 0; 106 return 0;
104 ASN1_TYPE_set(a, type, sdup); 107 ASN1_TYPE_set(a, type, sdup);
@@ -108,3 +111,49 @@ int ASN1_TYPE_set1(ASN1_TYPE *a, int type, const void *value)
108 111
109IMPLEMENT_STACK_OF(ASN1_TYPE) 112IMPLEMENT_STACK_OF(ASN1_TYPE)
110IMPLEMENT_ASN1_SET_OF(ASN1_TYPE) 113IMPLEMENT_ASN1_SET_OF(ASN1_TYPE)
114
115/* Returns 0 if they are equal, != 0 otherwise. */
116int ASN1_TYPE_cmp(ASN1_TYPE *a, ASN1_TYPE *b)
117 {
118 int result = -1;
119
120 if (!a || !b || a->type != b->type) return -1;
121
122 switch (a->type)
123 {
124 case V_ASN1_OBJECT:
125 result = OBJ_cmp(a->value.object, b->value.object);
126 break;
127 case V_ASN1_NULL:
128 result = 0; /* They do not have content. */
129 break;
130 case V_ASN1_INTEGER:
131 case V_ASN1_NEG_INTEGER:
132 case V_ASN1_ENUMERATED:
133 case V_ASN1_NEG_ENUMERATED:
134 case V_ASN1_BIT_STRING:
135 case V_ASN1_OCTET_STRING:
136 case V_ASN1_SEQUENCE:
137 case V_ASN1_SET:
138 case V_ASN1_NUMERICSTRING:
139 case V_ASN1_PRINTABLESTRING:
140 case V_ASN1_T61STRING:
141 case V_ASN1_VIDEOTEXSTRING:
142 case V_ASN1_IA5STRING:
143 case V_ASN1_UTCTIME:
144 case V_ASN1_GENERALIZEDTIME:
145 case V_ASN1_GRAPHICSTRING:
146 case V_ASN1_VISIBLESTRING:
147 case V_ASN1_GENERALSTRING:
148 case V_ASN1_UNIVERSALSTRING:
149 case V_ASN1_BMPSTRING:
150 case V_ASN1_UTF8STRING:
151 case V_ASN1_OTHER:
152 default:
153 result = ASN1_STRING_cmp((ASN1_STRING *) a->value.ptr,
154 (ASN1_STRING *) b->value.ptr);
155 break;
156 }
157
158 return result;
159 }
diff --git a/src/lib/libcrypto/asn1/a_verify.c b/src/lib/libcrypto/asn1/a_verify.c
index da3efaaf8d..cecdb13c70 100644
--- a/src/lib/libcrypto/asn1/a_verify.c
+++ b/src/lib/libcrypto/asn1/a_verify.c
@@ -60,6 +60,7 @@
60#include <time.h> 60#include <time.h>
61 61
62#include "cryptlib.h" 62#include "cryptlib.h"
63#include "asn1_locl.h"
63 64
64#ifndef NO_SYS_TYPES_H 65#ifndef NO_SYS_TYPES_H
65# include <sys/types.h> 66# include <sys/types.h>
@@ -100,12 +101,7 @@ int ASN1_verify(i2d_of_void *i2d, X509_ALGOR *a, ASN1_BIT_STRING *signature,
100 p=buf_in; 101 p=buf_in;
101 102
102 i2d(data,&p); 103 i2d(data,&p);
103 if (!EVP_VerifyInit_ex(&ctx,type, NULL)) 104 EVP_VerifyInit_ex(&ctx,type, NULL);
104 {
105 ASN1err(ASN1_F_ASN1_VERIFY,ERR_R_EVP_LIB);
106 ret=0;
107 goto err;
108 }
109 EVP_VerifyUpdate(&ctx,(unsigned char *)buf_in,inl); 105 EVP_VerifyUpdate(&ctx,(unsigned char *)buf_in,inl);
110 106
111 OPENSSL_cleanse(buf_in,(unsigned int)inl); 107 OPENSSL_cleanse(buf_in,(unsigned int)inl);
@@ -134,19 +130,34 @@ int ASN1_item_verify(const ASN1_ITEM *it, X509_ALGOR *a, ASN1_BIT_STRING *signat
134 void *asn, EVP_PKEY *pkey) 130 void *asn, EVP_PKEY *pkey)
135 { 131 {
136 EVP_MD_CTX ctx; 132 EVP_MD_CTX ctx;
137 const EVP_MD *type; 133 const EVP_MD *type = NULL;
138 unsigned char *buf_in=NULL; 134 unsigned char *buf_in=NULL;
139 int ret= -1,i,inl; 135 int ret= -1,inl;
136
137 int mdnid, pknid;
140 138
141 EVP_MD_CTX_init(&ctx); 139 EVP_MD_CTX_init(&ctx);
142 i=OBJ_obj2nid(a->algorithm); 140
143 type=EVP_get_digestbyname(OBJ_nid2sn(i)); 141 /* Convert signature OID into digest and public key OIDs */
142 if (!OBJ_find_sigid_algs(OBJ_obj2nid(a->algorithm), &mdnid, &pknid))
143 {
144 ASN1err(ASN1_F_ASN1_ITEM_VERIFY,ASN1_R_UNKNOWN_SIGNATURE_ALGORITHM);
145 goto err;
146 }
147 type=EVP_get_digestbynid(mdnid);
144 if (type == NULL) 148 if (type == NULL)
145 { 149 {
146 ASN1err(ASN1_F_ASN1_ITEM_VERIFY,ASN1_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM); 150 ASN1err(ASN1_F_ASN1_ITEM_VERIFY,ASN1_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM);
147 goto err; 151 goto err;
148 } 152 }
149 153
154 /* Check public key OID matches public key type */
155 if (EVP_PKEY_type(pknid) != pkey->ameth->pkey_id)
156 {
157 ASN1err(ASN1_F_ASN1_ITEM_VERIFY,ASN1_R_WRONG_PUBLIC_KEY_TYPE);
158 goto err;
159 }
160
150 if (!EVP_VerifyInit_ex(&ctx,type, NULL)) 161 if (!EVP_VerifyInit_ex(&ctx,type, NULL))
151 { 162 {
152 ASN1err(ASN1_F_ASN1_ITEM_VERIFY,ERR_R_EVP_LIB); 163 ASN1err(ASN1_F_ASN1_ITEM_VERIFY,ERR_R_EVP_LIB);
diff --git a/src/lib/libcrypto/asn1/ameth_lib.c b/src/lib/libcrypto/asn1/ameth_lib.c
index 18957c669e..9a8b6cc222 100644
--- a/src/lib/libcrypto/asn1/ameth_lib.c
+++ b/src/lib/libcrypto/asn1/ameth_lib.c
@@ -301,6 +301,8 @@ EVP_PKEY_ASN1_METHOD* EVP_PKEY_asn1_new(int id, int flags,
301 if (!ameth->info) 301 if (!ameth->info)
302 goto err; 302 goto err;
303 } 303 }
304 else
305 ameth->info = NULL;
304 306
305 if (pem_str) 307 if (pem_str)
306 { 308 {
@@ -308,6 +310,8 @@ EVP_PKEY_ASN1_METHOD* EVP_PKEY_asn1_new(int id, int flags,
308 if (!ameth->pem_str) 310 if (!ameth->pem_str)
309 goto err; 311 goto err;
310 } 312 }
313 else
314 ameth->pem_str = NULL;
311 315
312 ameth->pub_decode = 0; 316 ameth->pub_decode = 0;
313 ameth->pub_encode = 0; 317 ameth->pub_encode = 0;
diff --git a/src/lib/libcrypto/asn1/asn1.h b/src/lib/libcrypto/asn1/asn1.h
index e3385226d4..f7718b5a94 100644
--- a/src/lib/libcrypto/asn1/asn1.h
+++ b/src/lib/libcrypto/asn1/asn1.h
@@ -213,7 +213,7 @@ typedef struct asn1_object_st
213 const char *sn,*ln; 213 const char *sn,*ln;
214 int nid; 214 int nid;
215 int length; 215 int length;
216 unsigned char *data; 216 const unsigned char *data; /* data remains const after init */
217 int flags; /* Should we free this one */ 217 int flags; /* Should we free this one */
218 } ASN1_OBJECT; 218 } ASN1_OBJECT;
219 219
@@ -228,8 +228,12 @@ typedef struct asn1_object_st
228 * complete and is a place holder for content when it had all been 228 * complete and is a place holder for content when it had all been
229 * accessed. The flag will be reset when content has been written to it. 229 * accessed. The flag will be reset when content has been written to it.
230 */ 230 */
231#define ASN1_STRING_FLAG_CONT 0x020
232 231
232#define ASN1_STRING_FLAG_CONT 0x020
233/* This flag is used by ASN1 code to indicate an ASN1_STRING is an MSTRING
234 * type.
235 */
236#define ASN1_STRING_FLAG_MSTRING 0x040
233/* This is the base type that holds just about everything :-) */ 237/* This is the base type that holds just about everything :-) */
234typedef struct asn1_string_st 238typedef struct asn1_string_st
235 { 239 {
@@ -330,6 +334,13 @@ typedef struct ASN1_VALUE_st ASN1_VALUE;
330 type *name##_new(void); \ 334 type *name##_new(void); \
331 void name##_free(type *a); 335 void name##_free(type *a);
332 336
337#define DECLARE_ASN1_PRINT_FUNCTION(stname) \
338 DECLARE_ASN1_PRINT_FUNCTION_fname(stname, stname)
339
340#define DECLARE_ASN1_PRINT_FUNCTION_fname(stname, fname) \
341 int fname##_print_ctx(BIO *out, stname *x, int indent, \
342 const ASN1_PCTX *pctx);
343
333#define D2I_OF(type) type *(*)(type **,const unsigned char **,long) 344#define D2I_OF(type) type *(*)(type **,const unsigned char **,long)
334#define I2D_OF(type) int (*)(type *,unsigned char **) 345#define I2D_OF(type) int (*)(type *,unsigned char **)
335#define I2D_OF_const(type) int (*)(const type *,unsigned char **) 346#define I2D_OF_const(type) int (*)(const type *,unsigned char **)
@@ -534,28 +545,23 @@ typedef struct asn1_type_st
534 * contain the set or sequence bytes */ 545 * contain the set or sequence bytes */
535 ASN1_STRING * set; 546 ASN1_STRING * set;
536 ASN1_STRING * sequence; 547 ASN1_STRING * sequence;
537 ASN1_VALUE * asn1_value; 548 ASN1_VALUE * asn1_value;
538 } value; 549 } value;
539 } ASN1_TYPE; 550 } ASN1_TYPE;
540 551
541DECLARE_STACK_OF(ASN1_TYPE) 552DECLARE_STACK_OF(ASN1_TYPE)
542DECLARE_ASN1_SET_OF(ASN1_TYPE) 553DECLARE_ASN1_SET_OF(ASN1_TYPE)
543 554
544typedef struct asn1_method_st 555typedef STACK_OF(ASN1_TYPE) ASN1_SEQUENCE_ANY;
545 { 556
546 i2d_of_void *i2d; 557DECLARE_ASN1_ENCODE_FUNCTIONS_const(ASN1_SEQUENCE_ANY, ASN1_SEQUENCE_ANY)
547 d2i_of_void *d2i; 558DECLARE_ASN1_ENCODE_FUNCTIONS_const(ASN1_SEQUENCE_ANY, ASN1_SET_ANY)
548 void *(*create)(void); 559
549 void (*destroy)(void *); 560typedef struct NETSCAPE_X509_st
550 } ASN1_METHOD;
551
552/* This is used when parsing some Netscape objects */
553typedef struct asn1_header_st
554 { 561 {
555 ASN1_OCTET_STRING *header; 562 ASN1_OCTET_STRING *header;
556 void *data; 563 X509 *cert;
557 ASN1_METHOD *meth; 564 } NETSCAPE_X509;
558 } ASN1_HEADER;
559 565
560/* This is used to contain a list of bit names */ 566/* This is used to contain a list of bit names */
561typedef struct BIT_STRING_BITNAME_st { 567typedef struct BIT_STRING_BITNAME_st {
@@ -575,32 +581,34 @@ typedef struct BIT_STRING_BITNAME_st {
575 ASN1_STRING_type_new(V_ASN1_BIT_STRING) 581 ASN1_STRING_type_new(V_ASN1_BIT_STRING)
576#define M_ASN1_BIT_STRING_free(a) ASN1_STRING_free((ASN1_STRING *)a) 582#define M_ASN1_BIT_STRING_free(a) ASN1_STRING_free((ASN1_STRING *)a)
577#define M_ASN1_BIT_STRING_dup(a) (ASN1_BIT_STRING *)\ 583#define M_ASN1_BIT_STRING_dup(a) (ASN1_BIT_STRING *)\
578 ASN1_STRING_dup((ASN1_STRING *)a) 584 ASN1_STRING_dup((const ASN1_STRING *)a)
579#define M_ASN1_BIT_STRING_cmp(a,b) ASN1_STRING_cmp(\ 585#define M_ASN1_BIT_STRING_cmp(a,b) ASN1_STRING_cmp(\
580 (ASN1_STRING *)a,(ASN1_STRING *)b) 586 (const ASN1_STRING *)a,(const ASN1_STRING *)b)
581#define M_ASN1_BIT_STRING_set(a,b,c) ASN1_STRING_set((ASN1_STRING *)a,b,c) 587#define M_ASN1_BIT_STRING_set(a,b,c) ASN1_STRING_set((ASN1_STRING *)a,b,c)
582 588
583#define M_ASN1_INTEGER_new() (ASN1_INTEGER *)\ 589#define M_ASN1_INTEGER_new() (ASN1_INTEGER *)\
584 ASN1_STRING_type_new(V_ASN1_INTEGER) 590 ASN1_STRING_type_new(V_ASN1_INTEGER)
585#define M_ASN1_INTEGER_free(a) ASN1_STRING_free((ASN1_STRING *)a) 591#define M_ASN1_INTEGER_free(a) ASN1_STRING_free((ASN1_STRING *)a)
586#define M_ASN1_INTEGER_dup(a) (ASN1_INTEGER *)ASN1_STRING_dup((ASN1_STRING *)a) 592#define M_ASN1_INTEGER_dup(a) (ASN1_INTEGER *)\
593 ASN1_STRING_dup((const ASN1_STRING *)a)
587#define M_ASN1_INTEGER_cmp(a,b) ASN1_STRING_cmp(\ 594#define M_ASN1_INTEGER_cmp(a,b) ASN1_STRING_cmp(\
588 (ASN1_STRING *)a,(ASN1_STRING *)b) 595 (const ASN1_STRING *)a,(const ASN1_STRING *)b)
589 596
590#define M_ASN1_ENUMERATED_new() (ASN1_ENUMERATED *)\ 597#define M_ASN1_ENUMERATED_new() (ASN1_ENUMERATED *)\
591 ASN1_STRING_type_new(V_ASN1_ENUMERATED) 598 ASN1_STRING_type_new(V_ASN1_ENUMERATED)
592#define M_ASN1_ENUMERATED_free(a) ASN1_STRING_free((ASN1_STRING *)a) 599#define M_ASN1_ENUMERATED_free(a) ASN1_STRING_free((ASN1_STRING *)a)
593#define M_ASN1_ENUMERATED_dup(a) (ASN1_ENUMERATED *)ASN1_STRING_dup((ASN1_STRING *)a) 600#define M_ASN1_ENUMERATED_dup(a) (ASN1_ENUMERATED *)\
601 ASN1_STRING_dup((const ASN1_STRING *)a)
594#define M_ASN1_ENUMERATED_cmp(a,b) ASN1_STRING_cmp(\ 602#define M_ASN1_ENUMERATED_cmp(a,b) ASN1_STRING_cmp(\
595 (ASN1_STRING *)a,(ASN1_STRING *)b) 603 (const ASN1_STRING *)a,(const ASN1_STRING *)b)
596 604
597#define M_ASN1_OCTET_STRING_new() (ASN1_OCTET_STRING *)\ 605#define M_ASN1_OCTET_STRING_new() (ASN1_OCTET_STRING *)\
598 ASN1_STRING_type_new(V_ASN1_OCTET_STRING) 606 ASN1_STRING_type_new(V_ASN1_OCTET_STRING)
599#define M_ASN1_OCTET_STRING_free(a) ASN1_STRING_free((ASN1_STRING *)a) 607#define M_ASN1_OCTET_STRING_free(a) ASN1_STRING_free((ASN1_STRING *)a)
600#define M_ASN1_OCTET_STRING_dup(a) (ASN1_OCTET_STRING *)\ 608#define M_ASN1_OCTET_STRING_dup(a) (ASN1_OCTET_STRING *)\
601 ASN1_STRING_dup((ASN1_STRING *)a) 609 ASN1_STRING_dup((const ASN1_STRING *)a)
602#define M_ASN1_OCTET_STRING_cmp(a,b) ASN1_STRING_cmp(\ 610#define M_ASN1_OCTET_STRING_cmp(a,b) ASN1_STRING_cmp(\
603 (ASN1_STRING *)a,(ASN1_STRING *)b) 611 (const ASN1_STRING *)a,(const ASN1_STRING *)b)
604#define M_ASN1_OCTET_STRING_set(a,b,c) ASN1_STRING_set((ASN1_STRING *)a,b,c) 612#define M_ASN1_OCTET_STRING_set(a,b,c) ASN1_STRING_set((ASN1_STRING *)a,b,c)
605#define M_ASN1_OCTET_STRING_print(a,b) ASN1_STRING_print(a,(ASN1_STRING *)b) 613#define M_ASN1_OCTET_STRING_print(a,b) ASN1_STRING_print(a,(ASN1_STRING *)b)
606#define M_i2d_ASN1_OCTET_STRING(a,pp) \ 614#define M_i2d_ASN1_OCTET_STRING(a,pp) \
@@ -684,7 +692,7 @@ typedef struct BIT_STRING_BITNAME_st {
684 ASN1_STRING_type_new(V_ASN1_IA5STRING) 692 ASN1_STRING_type_new(V_ASN1_IA5STRING)
685#define M_ASN1_IA5STRING_free(a) ASN1_STRING_free((ASN1_STRING *)a) 693#define M_ASN1_IA5STRING_free(a) ASN1_STRING_free((ASN1_STRING *)a)
686#define M_ASN1_IA5STRING_dup(a) \ 694#define M_ASN1_IA5STRING_dup(a) \
687 (ASN1_IA5STRING *)ASN1_STRING_dup((ASN1_STRING *)a) 695 (ASN1_IA5STRING *)ASN1_STRING_dup((const ASN1_STRING *)a)
688#define M_i2d_ASN1_IA5STRING(a,pp) \ 696#define M_i2d_ASN1_IA5STRING(a,pp) \
689 i2d_ASN1_bytes((ASN1_STRING *)a,pp,V_ASN1_IA5STRING,\ 697 i2d_ASN1_bytes((ASN1_STRING *)a,pp,V_ASN1_IA5STRING,\
690 V_ASN1_UNIVERSAL) 698 V_ASN1_UNIVERSAL)
@@ -695,18 +703,20 @@ typedef struct BIT_STRING_BITNAME_st {
695#define M_ASN1_UTCTIME_new() (ASN1_UTCTIME *)\ 703#define M_ASN1_UTCTIME_new() (ASN1_UTCTIME *)\
696 ASN1_STRING_type_new(V_ASN1_UTCTIME) 704 ASN1_STRING_type_new(V_ASN1_UTCTIME)
697#define M_ASN1_UTCTIME_free(a) ASN1_STRING_free((ASN1_STRING *)a) 705#define M_ASN1_UTCTIME_free(a) ASN1_STRING_free((ASN1_STRING *)a)
698#define M_ASN1_UTCTIME_dup(a) (ASN1_UTCTIME *)ASN1_STRING_dup((ASN1_STRING *)a) 706#define M_ASN1_UTCTIME_dup(a) (ASN1_UTCTIME *)\
707 ASN1_STRING_dup((const ASN1_STRING *)a)
699 708
700#define M_ASN1_GENERALIZEDTIME_new() (ASN1_GENERALIZEDTIME *)\ 709#define M_ASN1_GENERALIZEDTIME_new() (ASN1_GENERALIZEDTIME *)\
701 ASN1_STRING_type_new(V_ASN1_GENERALIZEDTIME) 710 ASN1_STRING_type_new(V_ASN1_GENERALIZEDTIME)
702#define M_ASN1_GENERALIZEDTIME_free(a) ASN1_STRING_free((ASN1_STRING *)a) 711#define M_ASN1_GENERALIZEDTIME_free(a) ASN1_STRING_free((ASN1_STRING *)a)
703#define M_ASN1_GENERALIZEDTIME_dup(a) (ASN1_GENERALIZEDTIME *)ASN1_STRING_dup(\ 712#define M_ASN1_GENERALIZEDTIME_dup(a) (ASN1_GENERALIZEDTIME *)ASN1_STRING_dup(\
704 (ASN1_STRING *)a) 713 (const ASN1_STRING *)a)
705 714
706#define M_ASN1_TIME_new() (ASN1_TIME *)\ 715#define M_ASN1_TIME_new() (ASN1_TIME *)\
707 ASN1_STRING_type_new(V_ASN1_UTCTIME) 716 ASN1_STRING_type_new(V_ASN1_UTCTIME)
708#define M_ASN1_TIME_free(a) ASN1_STRING_free((ASN1_STRING *)a) 717#define M_ASN1_TIME_free(a) ASN1_STRING_free((ASN1_STRING *)a)
709#define M_ASN1_TIME_dup(a) (ASN1_TIME *)ASN1_STRING_dup((ASN1_STRING *)a) 718#define M_ASN1_TIME_dup(a) (ASN1_TIME *)\
719 ASN1_STRING_dup((const ASN1_STRING *)a)
710 720
711#define M_ASN1_GENERALSTRING_new() (ASN1_GENERALSTRING *)\ 721#define M_ASN1_GENERALSTRING_new() (ASN1_GENERALSTRING *)\
712 ASN1_STRING_type_new(V_ASN1_GENERALSTRING) 722 ASN1_STRING_type_new(V_ASN1_GENERALSTRING)
@@ -767,6 +777,7 @@ DECLARE_ASN1_FUNCTIONS_fname(ASN1_TYPE, ASN1_ANY, ASN1_TYPE)
767int ASN1_TYPE_get(ASN1_TYPE *a); 777int ASN1_TYPE_get(ASN1_TYPE *a);
768void ASN1_TYPE_set(ASN1_TYPE *a, int type, void *value); 778void ASN1_TYPE_set(ASN1_TYPE *a, int type, void *value);
769int ASN1_TYPE_set1(ASN1_TYPE *a, int type, const void *value); 779int ASN1_TYPE_set1(ASN1_TYPE *a, int type, const void *value);
780int ASN1_TYPE_cmp(ASN1_TYPE *a, ASN1_TYPE *b);
770 781
771ASN1_OBJECT * ASN1_OBJECT_new(void ); 782ASN1_OBJECT * ASN1_OBJECT_new(void );
772void ASN1_OBJECT_free(ASN1_OBJECT *a); 783void ASN1_OBJECT_free(ASN1_OBJECT *a);
@@ -783,14 +794,15 @@ DECLARE_ASN1_SET_OF(ASN1_OBJECT)
783 794
784ASN1_STRING * ASN1_STRING_new(void); 795ASN1_STRING * ASN1_STRING_new(void);
785void ASN1_STRING_free(ASN1_STRING *a); 796void ASN1_STRING_free(ASN1_STRING *a);
786ASN1_STRING * ASN1_STRING_dup(ASN1_STRING *a); 797int ASN1_STRING_copy(ASN1_STRING *dst, const ASN1_STRING *str);
798ASN1_STRING * ASN1_STRING_dup(const ASN1_STRING *a);
787ASN1_STRING * ASN1_STRING_type_new(int type ); 799ASN1_STRING * ASN1_STRING_type_new(int type );
788int ASN1_STRING_cmp(ASN1_STRING *a, ASN1_STRING *b); 800int ASN1_STRING_cmp(const ASN1_STRING *a, const ASN1_STRING *b);
789 /* Since this is used to store all sorts of things, via macros, for now, make 801 /* Since this is used to store all sorts of things, via macros, for now, make
790 its data void * */ 802 its data void * */
791int ASN1_STRING_set(ASN1_STRING *str, const void *data, int len); 803int ASN1_STRING_set(ASN1_STRING *str, const void *data, int len);
792void ASN1_STRING_set0(ASN1_STRING *str, void *data, int len); 804void ASN1_STRING_set0(ASN1_STRING *str, void *data, int len);
793int ASN1_STRING_length(ASN1_STRING *x); 805int ASN1_STRING_length(const ASN1_STRING *x);
794void ASN1_STRING_length_set(ASN1_STRING *x, int n); 806void ASN1_STRING_length_set(ASN1_STRING *x, int n);
795int ASN1_STRING_type(ASN1_STRING *x); 807int ASN1_STRING_type(ASN1_STRING *x);
796unsigned char * ASN1_STRING_data(ASN1_STRING *x); 808unsigned char * ASN1_STRING_data(ASN1_STRING *x);
@@ -803,6 +815,8 @@ int ASN1_BIT_STRING_set(ASN1_BIT_STRING *a, unsigned char *d,
803 int length ); 815 int length );
804int ASN1_BIT_STRING_set_bit(ASN1_BIT_STRING *a, int n, int value); 816int ASN1_BIT_STRING_set_bit(ASN1_BIT_STRING *a, int n, int value);
805int ASN1_BIT_STRING_get_bit(ASN1_BIT_STRING *a, int n); 817int ASN1_BIT_STRING_get_bit(ASN1_BIT_STRING *a, int n);
818int ASN1_BIT_STRING_check(ASN1_BIT_STRING *a,
819 unsigned char *flags, int flags_len);
806 820
807#ifndef OPENSSL_NO_BIO 821#ifndef OPENSSL_NO_BIO
808int ASN1_BIT_STRING_name_print(BIO *out, ASN1_BIT_STRING *bs, 822int ASN1_BIT_STRING_name_print(BIO *out, ASN1_BIT_STRING *bs,
@@ -821,13 +835,15 @@ ASN1_INTEGER *c2i_ASN1_INTEGER(ASN1_INTEGER **a,const unsigned char **pp,
821 long length); 835 long length);
822ASN1_INTEGER *d2i_ASN1_UINTEGER(ASN1_INTEGER **a,const unsigned char **pp, 836ASN1_INTEGER *d2i_ASN1_UINTEGER(ASN1_INTEGER **a,const unsigned char **pp,
823 long length); 837 long length);
824ASN1_INTEGER * ASN1_INTEGER_dup(ASN1_INTEGER *x); 838ASN1_INTEGER * ASN1_INTEGER_dup(const ASN1_INTEGER *x);
825int ASN1_INTEGER_cmp(ASN1_INTEGER *x, ASN1_INTEGER *y); 839int ASN1_INTEGER_cmp(const ASN1_INTEGER *x, const ASN1_INTEGER *y);
826 840
827DECLARE_ASN1_FUNCTIONS(ASN1_ENUMERATED) 841DECLARE_ASN1_FUNCTIONS(ASN1_ENUMERATED)
828 842
829int ASN1_UTCTIME_check(ASN1_UTCTIME *a); 843int ASN1_UTCTIME_check(ASN1_UTCTIME *a);
830ASN1_UTCTIME *ASN1_UTCTIME_set(ASN1_UTCTIME *s,time_t t); 844ASN1_UTCTIME *ASN1_UTCTIME_set(ASN1_UTCTIME *s,time_t t);
845ASN1_UTCTIME *ASN1_UTCTIME_adj(ASN1_UTCTIME *s, time_t t,
846 int offset_day, long offset_sec);
831int ASN1_UTCTIME_set_string(ASN1_UTCTIME *s, const char *str); 847int ASN1_UTCTIME_set_string(ASN1_UTCTIME *s, const char *str);
832int ASN1_UTCTIME_cmp_time_t(const ASN1_UTCTIME *s, time_t t); 848int ASN1_UTCTIME_cmp_time_t(const ASN1_UTCTIME *s, time_t t);
833#if 0 849#if 0
@@ -836,11 +852,13 @@ time_t ASN1_UTCTIME_get(const ASN1_UTCTIME *s);
836 852
837int ASN1_GENERALIZEDTIME_check(ASN1_GENERALIZEDTIME *a); 853int ASN1_GENERALIZEDTIME_check(ASN1_GENERALIZEDTIME *a);
838ASN1_GENERALIZEDTIME *ASN1_GENERALIZEDTIME_set(ASN1_GENERALIZEDTIME *s,time_t t); 854ASN1_GENERALIZEDTIME *ASN1_GENERALIZEDTIME_set(ASN1_GENERALIZEDTIME *s,time_t t);
855ASN1_GENERALIZEDTIME *ASN1_GENERALIZEDTIME_adj(ASN1_GENERALIZEDTIME *s,
856 time_t t, int offset_day, long offset_sec);
839int ASN1_GENERALIZEDTIME_set_string(ASN1_GENERALIZEDTIME *s, const char *str); 857int ASN1_GENERALIZEDTIME_set_string(ASN1_GENERALIZEDTIME *s, const char *str);
840 858
841DECLARE_ASN1_FUNCTIONS(ASN1_OCTET_STRING) 859DECLARE_ASN1_FUNCTIONS(ASN1_OCTET_STRING)
842ASN1_OCTET_STRING * ASN1_OCTET_STRING_dup(ASN1_OCTET_STRING *a); 860ASN1_OCTET_STRING * ASN1_OCTET_STRING_dup(const ASN1_OCTET_STRING *a);
843int ASN1_OCTET_STRING_cmp(ASN1_OCTET_STRING *a, ASN1_OCTET_STRING *b); 861int ASN1_OCTET_STRING_cmp(const ASN1_OCTET_STRING *a, const ASN1_OCTET_STRING *b);
844int ASN1_OCTET_STRING_set(ASN1_OCTET_STRING *str, const unsigned char *data, int len); 862int ASN1_OCTET_STRING_set(ASN1_OCTET_STRING *str, const unsigned char *data, int len);
845 863
846DECLARE_ASN1_FUNCTIONS(ASN1_VISIBLESTRING) 864DECLARE_ASN1_FUNCTIONS(ASN1_VISIBLESTRING)
@@ -867,14 +885,20 @@ DECLARE_ASN1_FUNCTIONS(ASN1_TIME)
867DECLARE_ASN1_ITEM(ASN1_OCTET_STRING_NDEF) 885DECLARE_ASN1_ITEM(ASN1_OCTET_STRING_NDEF)
868 886
869ASN1_TIME *ASN1_TIME_set(ASN1_TIME *s,time_t t); 887ASN1_TIME *ASN1_TIME_set(ASN1_TIME *s,time_t t);
888ASN1_TIME *ASN1_TIME_adj(ASN1_TIME *s,time_t t,
889 int offset_day, long offset_sec);
870int ASN1_TIME_check(ASN1_TIME *t); 890int ASN1_TIME_check(ASN1_TIME *t);
871ASN1_GENERALIZEDTIME *ASN1_TIME_to_generalizedtime(ASN1_TIME *t, ASN1_GENERALIZEDTIME **out); 891ASN1_GENERALIZEDTIME *ASN1_TIME_to_generalizedtime(ASN1_TIME *t, ASN1_GENERALIZEDTIME **out);
892int ASN1_TIME_set_string(ASN1_TIME *s, const char *str);
872 893
873int i2d_ASN1_SET(STACK *a, unsigned char **pp, 894int i2d_ASN1_SET(STACK_OF(OPENSSL_BLOCK) *a, unsigned char **pp,
874 i2d_of_void *i2d, int ex_tag, int ex_class, int is_set); 895 i2d_of_void *i2d, int ex_tag, int ex_class,
875STACK * d2i_ASN1_SET(STACK **a, const unsigned char **pp, long length, 896 int is_set);
876 d2i_of_void *d2i, void (*free_func)(void *), 897STACK_OF(OPENSSL_BLOCK) *d2i_ASN1_SET(STACK_OF(OPENSSL_BLOCK) **a,
877 int ex_tag, int ex_class); 898 const unsigned char **pp,
899 long length, d2i_of_void *d2i,
900 void (*free_func)(OPENSSL_BLOCK), int ex_tag,
901 int ex_class);
878 902
879#ifndef OPENSSL_NO_BIO 903#ifndef OPENSSL_NO_BIO
880int i2a_ASN1_INTEGER(BIO *bp, ASN1_INTEGER *a); 904int i2a_ASN1_INTEGER(BIO *bp, ASN1_INTEGER *a);
@@ -892,9 +916,9 @@ ASN1_OBJECT *ASN1_OBJECT_create(int nid, unsigned char *data,int len,
892 const char *sn, const char *ln); 916 const char *sn, const char *ln);
893 917
894int ASN1_INTEGER_set(ASN1_INTEGER *a, long v); 918int ASN1_INTEGER_set(ASN1_INTEGER *a, long v);
895long ASN1_INTEGER_get(ASN1_INTEGER *a); 919long ASN1_INTEGER_get(const ASN1_INTEGER *a);
896ASN1_INTEGER *BN_to_ASN1_INTEGER(BIGNUM *bn, ASN1_INTEGER *ai); 920ASN1_INTEGER *BN_to_ASN1_INTEGER(const BIGNUM *bn, ASN1_INTEGER *ai);
897BIGNUM *ASN1_INTEGER_to_BN(ASN1_INTEGER *ai,BIGNUM *bn); 921BIGNUM *ASN1_INTEGER_to_BN(const ASN1_INTEGER *ai,BIGNUM *bn);
898 922
899int ASN1_ENUMERATED_set(ASN1_ENUMERATED *a, long v); 923int ASN1_ENUMERATED_set(ASN1_ENUMERATED *a, long v);
900long ASN1_ENUMERATED_get(ASN1_ENUMERATED *a); 924long ASN1_ENUMERATED_get(ASN1_ENUMERATED *a);
@@ -928,7 +952,7 @@ int ASN1_put_eoc(unsigned char **pp);
928int ASN1_object_size(int constructed, int length, int tag); 952int ASN1_object_size(int constructed, int length, int tag);
929 953
930/* Used to implement other functions */ 954/* Used to implement other functions */
931void *ASN1_dup(i2d_of_void *i2d, d2i_of_void *d2i, char *x); 955void *ASN1_dup(i2d_of_void *i2d, d2i_of_void *d2i, void *x);
932 956
933#define ASN1_dup_of(type,i2d,d2i,x) \ 957#define ASN1_dup_of(type,i2d,d2i,x) \
934 ((type*)ASN1_dup(CHECKED_I2D_OF(type, i2d), \ 958 ((type*)ASN1_dup(CHECKED_I2D_OF(type, i2d), \
@@ -999,29 +1023,23 @@ int ASN1_i2d_bio(i2d_of_void *i2d,BIO *out, unsigned char *x);
999 CHECKED_PTR_OF(const type, x))) 1023 CHECKED_PTR_OF(const type, x)))
1000 1024
1001int ASN1_item_i2d_bio(const ASN1_ITEM *it, BIO *out, void *x); 1025int ASN1_item_i2d_bio(const ASN1_ITEM *it, BIO *out, void *x);
1002int ASN1_UTCTIME_print(BIO *fp,ASN1_UTCTIME *a); 1026int ASN1_UTCTIME_print(BIO *fp, const ASN1_UTCTIME *a);
1003int ASN1_GENERALIZEDTIME_print(BIO *fp,ASN1_GENERALIZEDTIME *a); 1027int ASN1_GENERALIZEDTIME_print(BIO *fp, const ASN1_GENERALIZEDTIME *a);
1004int ASN1_TIME_print(BIO *fp,ASN1_TIME *a); 1028int ASN1_TIME_print(BIO *fp, const ASN1_TIME *a);
1005int ASN1_STRING_print(BIO *bp,ASN1_STRING *v); 1029int ASN1_STRING_print(BIO *bp, const ASN1_STRING *v);
1006int ASN1_STRING_print_ex(BIO *out, ASN1_STRING *str, unsigned long flags); 1030int ASN1_STRING_print_ex(BIO *out, ASN1_STRING *str, unsigned long flags);
1031int ASN1_bn_print(BIO *bp, const char *number, const BIGNUM *num,
1032 unsigned char *buf, int off);
1007int ASN1_parse(BIO *bp,const unsigned char *pp,long len,int indent); 1033int ASN1_parse(BIO *bp,const unsigned char *pp,long len,int indent);
1008int ASN1_parse_dump(BIO *bp,const unsigned char *pp,long len,int indent,int dump); 1034int ASN1_parse_dump(BIO *bp,const unsigned char *pp,long len,int indent,int dump);
1009#endif 1035#endif
1010const char *ASN1_tag2str(int tag); 1036const char *ASN1_tag2str(int tag);
1011 1037
1012/* Used to load and write netscape format cert/key */ 1038/* Used to load and write netscape format cert */
1013int i2d_ASN1_HEADER(ASN1_HEADER *a,unsigned char **pp);
1014ASN1_HEADER *d2i_ASN1_HEADER(ASN1_HEADER **a,const unsigned char **pp, long length);
1015ASN1_HEADER *ASN1_HEADER_new(void );
1016void ASN1_HEADER_free(ASN1_HEADER *a);
1017 1039
1018int ASN1_UNIVERSALSTRING_to_string(ASN1_UNIVERSALSTRING *s); 1040DECLARE_ASN1_FUNCTIONS(NETSCAPE_X509)
1019 1041
1020/* Not used that much at this point, except for the first two */ 1042int ASN1_UNIVERSALSTRING_to_string(ASN1_UNIVERSALSTRING *s);
1021ASN1_METHOD *X509_asn1_meth(void);
1022ASN1_METHOD *RSAPrivateKey_asn1_meth(void);
1023ASN1_METHOD *ASN1_IA5STRING_asn1_meth(void);
1024ASN1_METHOD *ASN1_BIT_STRING_asn1_meth(void);
1025 1043
1026int ASN1_TYPE_set_octetstring(ASN1_TYPE *a, 1044int ASN1_TYPE_set_octetstring(ASN1_TYPE *a,
1027 unsigned char *data, int len); 1045 unsigned char *data, int len);
@@ -1032,9 +1050,9 @@ int ASN1_TYPE_set_int_octetstring(ASN1_TYPE *a, long num,
1032int ASN1_TYPE_get_int_octetstring(ASN1_TYPE *a,long *num, 1050int ASN1_TYPE_get_int_octetstring(ASN1_TYPE *a,long *num,
1033 unsigned char *data, int max_len); 1051 unsigned char *data, int max_len);
1034 1052
1035STACK *ASN1_seq_unpack(const unsigned char *buf, int len, 1053STACK_OF(OPENSSL_BLOCK) *ASN1_seq_unpack(const unsigned char *buf, int len,
1036 d2i_of_void *d2i, void (*free_func)(void *)); 1054 d2i_of_void *d2i, void (*free_func)(OPENSSL_BLOCK));
1037unsigned char *ASN1_seq_pack(STACK *safes, i2d_of_void *i2d, 1055unsigned char *ASN1_seq_pack(STACK_OF(OPENSSL_BLOCK) *safes, i2d_of_void *i2d,
1038 unsigned char **buf, int *len ); 1056 unsigned char **buf, int *len );
1039void *ASN1_unpack_string(ASN1_STRING *oct, d2i_of_void *d2i); 1057void *ASN1_unpack_string(ASN1_STRING *oct, d2i_of_void *d2i);
1040void *ASN1_item_unpack(ASN1_STRING *oct, const ASN1_ITEM *it); 1058void *ASN1_item_unpack(ASN1_STRING *oct, const ASN1_ITEM *it);
@@ -1077,15 +1095,58 @@ void ASN1_add_oid_module(void);
1077ASN1_TYPE *ASN1_generate_nconf(char *str, CONF *nconf); 1095ASN1_TYPE *ASN1_generate_nconf(char *str, CONF *nconf);
1078ASN1_TYPE *ASN1_generate_v3(char *str, X509V3_CTX *cnf); 1096ASN1_TYPE *ASN1_generate_v3(char *str, X509V3_CTX *cnf);
1079 1097
1080typedef int asn1_output_data_fn(BIO *out, BIO *data, ASN1_VALUE *val, int flags, 1098/* ASN1 Print flags */
1081 const ASN1_ITEM *it); 1099
1082 1100/* Indicate missing OPTIONAL fields */
1083int int_smime_write_ASN1(BIO *bio, ASN1_VALUE *val, BIO *data, int flags, 1101#define ASN1_PCTX_FLAGS_SHOW_ABSENT 0x001
1102/* Mark start and end of SEQUENCE */
1103#define ASN1_PCTX_FLAGS_SHOW_SEQUENCE 0x002
1104/* Mark start and end of SEQUENCE/SET OF */
1105#define ASN1_PCTX_FLAGS_SHOW_SSOF 0x004
1106/* Show the ASN1 type of primitives */
1107#define ASN1_PCTX_FLAGS_SHOW_TYPE 0x008
1108/* Don't show ASN1 type of ANY */
1109#define ASN1_PCTX_FLAGS_NO_ANY_TYPE 0x010
1110/* Don't show ASN1 type of MSTRINGs */
1111#define ASN1_PCTX_FLAGS_NO_MSTRING_TYPE 0x020
1112/* Don't show field names in SEQUENCE */
1113#define ASN1_PCTX_FLAGS_NO_FIELD_NAME 0x040
1114/* Show structure names of each SEQUENCE field */
1115#define ASN1_PCTX_FLAGS_SHOW_FIELD_STRUCT_NAME 0x080
1116/* Don't show structure name even at top level */
1117#define ASN1_PCTX_FLAGS_NO_STRUCT_NAME 0x100
1118
1119int ASN1_item_print(BIO *out, ASN1_VALUE *ifld, int indent,
1120 const ASN1_ITEM *it, const ASN1_PCTX *pctx);
1121ASN1_PCTX *ASN1_PCTX_new(void);
1122void ASN1_PCTX_free(ASN1_PCTX *p);
1123unsigned long ASN1_PCTX_get_flags(ASN1_PCTX *p);
1124void ASN1_PCTX_set_flags(ASN1_PCTX *p, unsigned long flags);
1125unsigned long ASN1_PCTX_get_nm_flags(ASN1_PCTX *p);
1126void ASN1_PCTX_set_nm_flags(ASN1_PCTX *p, unsigned long flags);
1127unsigned long ASN1_PCTX_get_cert_flags(ASN1_PCTX *p);
1128void ASN1_PCTX_set_cert_flags(ASN1_PCTX *p, unsigned long flags);
1129unsigned long ASN1_PCTX_get_oid_flags(ASN1_PCTX *p);
1130void ASN1_PCTX_set_oid_flags(ASN1_PCTX *p, unsigned long flags);
1131unsigned long ASN1_PCTX_get_str_flags(ASN1_PCTX *p);
1132void ASN1_PCTX_set_str_flags(ASN1_PCTX *p, unsigned long flags);
1133
1134BIO_METHOD *BIO_f_asn1(void);
1135
1136BIO *BIO_new_NDEF(BIO *out, ASN1_VALUE *val, const ASN1_ITEM *it);
1137
1138int i2d_ASN1_bio_stream(BIO *out, ASN1_VALUE *val, BIO *in, int flags,
1139 const ASN1_ITEM *it);
1140int PEM_write_bio_ASN1_stream(BIO *out, ASN1_VALUE *val, BIO *in, int flags,
1141 const char *hdr,
1142 const ASN1_ITEM *it);
1143int SMIME_write_ASN1(BIO *bio, ASN1_VALUE *val, BIO *data, int flags,
1084 int ctype_nid, int econt_nid, 1144 int ctype_nid, int econt_nid,
1085 STACK_OF(X509_ALGOR) *mdalgs, 1145 STACK_OF(X509_ALGOR) *mdalgs,
1086 asn1_output_data_fn *data_fn,
1087 const ASN1_ITEM *it); 1146 const ASN1_ITEM *it);
1088ASN1_VALUE *SMIME_read_ASN1(BIO *bio, BIO **bcont, const ASN1_ITEM *it); 1147ASN1_VALUE *SMIME_read_ASN1(BIO *bio, BIO **bcont, const ASN1_ITEM *it);
1148int SMIME_crlf_copy(BIO *in, BIO *out, int flags);
1149int SMIME_text(BIO *in, BIO *out);
1089 1150
1090/* BEGIN ERROR CODES */ 1151/* BEGIN ERROR CODES */
1091/* The following lines are auto generated by the script mkerr.pl. Any changes 1152/* The following lines are auto generated by the script mkerr.pl. Any changes
@@ -1116,6 +1177,7 @@ void ERR_load_ASN1_strings(void);
1116#define ASN1_F_ASN1_ENUMERATED_TO_BN 113 1177#define ASN1_F_ASN1_ENUMERATED_TO_BN 113
1117#define ASN1_F_ASN1_EX_C2I 204 1178#define ASN1_F_ASN1_EX_C2I 204
1118#define ASN1_F_ASN1_FIND_END 190 1179#define ASN1_F_ASN1_FIND_END 190
1180#define ASN1_F_ASN1_GENERALIZEDTIME_ADJ 216
1119#define ASN1_F_ASN1_GENERALIZEDTIME_SET 185 1181#define ASN1_F_ASN1_GENERALIZEDTIME_SET 185
1120#define ASN1_F_ASN1_GENERATE_V3 178 1182#define ASN1_F_ASN1_GENERATE_V3 178
1121#define ASN1_F_ASN1_GET_OBJECT 114 1183#define ASN1_F_ASN1_GET_OBJECT 114
@@ -1136,7 +1198,7 @@ void ERR_load_ASN1_strings(void);
1136#define ASN1_F_ASN1_ITEM_VERIFY 197 1198#define ASN1_F_ASN1_ITEM_VERIFY 197
1137#define ASN1_F_ASN1_MBSTRING_NCOPY 122 1199#define ASN1_F_ASN1_MBSTRING_NCOPY 122
1138#define ASN1_F_ASN1_OBJECT_NEW 123 1200#define ASN1_F_ASN1_OBJECT_NEW 123
1139#define ASN1_F_ASN1_OUTPUT_DATA 207 1201#define ASN1_F_ASN1_OUTPUT_DATA 214
1140#define ASN1_F_ASN1_PACK_STRING 124 1202#define ASN1_F_ASN1_PACK_STRING 124
1141#define ASN1_F_ASN1_PCTX_NEW 205 1203#define ASN1_F_ASN1_PCTX_NEW 205
1142#define ASN1_F_ASN1_PKCS5_PBE_SET 125 1204#define ASN1_F_ASN1_PKCS5_PBE_SET 125
@@ -1150,14 +1212,17 @@ void ERR_load_ASN1_strings(void);
1150#define ASN1_F_ASN1_TEMPLATE_EX_D2I 132 1212#define ASN1_F_ASN1_TEMPLATE_EX_D2I 132
1151#define ASN1_F_ASN1_TEMPLATE_NEW 133 1213#define ASN1_F_ASN1_TEMPLATE_NEW 133
1152#define ASN1_F_ASN1_TEMPLATE_NOEXP_D2I 131 1214#define ASN1_F_ASN1_TEMPLATE_NOEXP_D2I 131
1215#define ASN1_F_ASN1_TIME_ADJ 217
1153#define ASN1_F_ASN1_TIME_SET 175 1216#define ASN1_F_ASN1_TIME_SET 175
1154#define ASN1_F_ASN1_TYPE_GET_INT_OCTETSTRING 134 1217#define ASN1_F_ASN1_TYPE_GET_INT_OCTETSTRING 134
1155#define ASN1_F_ASN1_TYPE_GET_OCTETSTRING 135 1218#define ASN1_F_ASN1_TYPE_GET_OCTETSTRING 135
1156#define ASN1_F_ASN1_UNPACK_STRING 136 1219#define ASN1_F_ASN1_UNPACK_STRING 136
1220#define ASN1_F_ASN1_UTCTIME_ADJ 218
1157#define ASN1_F_ASN1_UTCTIME_SET 187 1221#define ASN1_F_ASN1_UTCTIME_SET 187
1158#define ASN1_F_ASN1_VERIFY 137 1222#define ASN1_F_ASN1_VERIFY 137
1159#define ASN1_F_B64_READ_ASN1 208 1223#define ASN1_F_B64_READ_ASN1 209
1160#define ASN1_F_B64_WRITE_ASN1 209 1224#define ASN1_F_B64_WRITE_ASN1 210
1225#define ASN1_F_BIO_NEW_NDEF 208
1161#define ASN1_F_BITSTR_CB 180 1226#define ASN1_F_BITSTR_CB 180
1162#define ASN1_F_BN_TO_ASN1_ENUMERATED 138 1227#define ASN1_F_BN_TO_ASN1_ENUMERATED 138
1163#define ASN1_F_BN_TO_ASN1_INTEGER 139 1228#define ASN1_F_BN_TO_ASN1_INTEGER 139
@@ -1176,6 +1241,7 @@ void ERR_load_ASN1_strings(void);
1176#define ASN1_F_D2I_ASN1_TYPE_BYTES 149 1241#define ASN1_F_D2I_ASN1_TYPE_BYTES 149
1177#define ASN1_F_D2I_ASN1_UINTEGER 150 1242#define ASN1_F_D2I_ASN1_UINTEGER 150
1178#define ASN1_F_D2I_ASN1_UTCTIME 151 1243#define ASN1_F_D2I_ASN1_UTCTIME 151
1244#define ASN1_F_D2I_AUTOPRIVATEKEY 207
1179#define ASN1_F_D2I_NETSCAPE_RSA 152 1245#define ASN1_F_D2I_NETSCAPE_RSA 152
1180#define ASN1_F_D2I_NETSCAPE_RSA_2 153 1246#define ASN1_F_D2I_NETSCAPE_RSA_2 153
1181#define ASN1_F_D2I_PRIVATEKEY 154 1247#define ASN1_F_D2I_PRIVATEKEY 154
@@ -1185,6 +1251,7 @@ void ERR_load_ASN1_strings(void);
1185#define ASN1_F_D2I_X509 156 1251#define ASN1_F_D2I_X509 156
1186#define ASN1_F_D2I_X509_CINF 157 1252#define ASN1_F_D2I_X509_CINF 157
1187#define ASN1_F_D2I_X509_PKEY 159 1253#define ASN1_F_D2I_X509_PKEY 159
1254#define ASN1_F_I2D_ASN1_BIO_STREAM 211
1188#define ASN1_F_I2D_ASN1_SET 188 1255#define ASN1_F_I2D_ASN1_SET 188
1189#define ASN1_F_I2D_ASN1_TIME 160 1256#define ASN1_F_I2D_ASN1_TIME 160
1190#define ASN1_F_I2D_DSA_PUBKEY 161 1257#define ASN1_F_I2D_DSA_PUBKEY 161
@@ -1196,10 +1263,11 @@ void ERR_load_ASN1_strings(void);
1196#define ASN1_F_LONG_C2I 166 1263#define ASN1_F_LONG_C2I 166
1197#define ASN1_F_OID_MODULE_INIT 174 1264#define ASN1_F_OID_MODULE_INIT 174
1198#define ASN1_F_PARSE_TAGGING 182 1265#define ASN1_F_PARSE_TAGGING 182
1199#define ASN1_F_PKCS5_PBE2_SET 167 1266#define ASN1_F_PKCS5_PBE2_SET_IV 167
1200#define ASN1_F_PKCS5_PBE_SET 202 1267#define ASN1_F_PKCS5_PBE_SET 202
1201#define ASN1_F_SMIME_READ_ASN1 210 1268#define ASN1_F_PKCS5_PBE_SET0_ALGOR 215
1202#define ASN1_F_SMIME_TEXT 211 1269#define ASN1_F_SMIME_READ_ASN1 212
1270#define ASN1_F_SMIME_TEXT 213
1203#define ASN1_F_X509_CINF_NEW 168 1271#define ASN1_F_X509_CINF_NEW 168
1204#define ASN1_F_X509_CRL_ADD0_REVOKED 169 1272#define ASN1_F_X509_CRL_ADD0_REVOKED 169
1205#define ASN1_F_X509_INFO_NEW 170 1273#define ASN1_F_X509_INFO_NEW 170
@@ -1211,14 +1279,14 @@ void ERR_load_ASN1_strings(void);
1211 1279
1212/* Reason codes. */ 1280/* Reason codes. */
1213#define ASN1_R_ADDING_OBJECT 171 1281#define ASN1_R_ADDING_OBJECT 171
1214#define ASN1_R_ASN1_PARSE_ERROR 198 1282#define ASN1_R_ASN1_PARSE_ERROR 203
1215#define ASN1_R_ASN1_SIG_PARSE_ERROR 199 1283#define ASN1_R_ASN1_SIG_PARSE_ERROR 204
1216#define ASN1_R_AUX_ERROR 100 1284#define ASN1_R_AUX_ERROR 100
1217#define ASN1_R_BAD_CLASS 101 1285#define ASN1_R_BAD_CLASS 101
1218#define ASN1_R_BAD_OBJECT_HEADER 102 1286#define ASN1_R_BAD_OBJECT_HEADER 102
1219#define ASN1_R_BAD_PASSWORD_READ 103 1287#define ASN1_R_BAD_PASSWORD_READ 103
1220#define ASN1_R_BAD_TAG 104 1288#define ASN1_R_BAD_TAG 104
1221#define ASN1_R_BMPSTRING_IS_WRONG_LENGTH 210 1289#define ASN1_R_BMPSTRING_IS_WRONG_LENGTH 214
1222#define ASN1_R_BN_LIB 105 1290#define ASN1_R_BN_LIB 105
1223#define ASN1_R_BOOLEAN_IS_WRONG_LENGTH 106 1291#define ASN1_R_BOOLEAN_IS_WRONG_LENGTH 106
1224#define ASN1_R_BUFFER_TOO_SMALL 107 1292#define ASN1_R_BUFFER_TOO_SMALL 107
@@ -1227,6 +1295,7 @@ void ERR_load_ASN1_strings(void);
1227#define ASN1_R_DECODE_ERROR 110 1295#define ASN1_R_DECODE_ERROR 110
1228#define ASN1_R_DECODING_ERROR 111 1296#define ASN1_R_DECODING_ERROR 111
1229#define ASN1_R_DEPTH_EXCEEDED 174 1297#define ASN1_R_DEPTH_EXCEEDED 174
1298#define ASN1_R_DIGEST_AND_KEY_TYPE_NOT_SUPPORTED 198
1230#define ASN1_R_ENCODE_ERROR 112 1299#define ASN1_R_ENCODE_ERROR 112
1231#define ASN1_R_ERROR_GETTING_TIME 173 1300#define ASN1_R_ERROR_GETTING_TIME 173
1232#define ASN1_R_ERROR_LOADING_SECTION 172 1301#define ASN1_R_ERROR_LOADING_SECTION 172
@@ -1260,9 +1329,10 @@ void ERR_load_ASN1_strings(void);
1260#define ASN1_R_INTEGER_TOO_LARGE_FOR_LONG 128 1329#define ASN1_R_INTEGER_TOO_LARGE_FOR_LONG 128
1261#define ASN1_R_INVALID_BMPSTRING_LENGTH 129 1330#define ASN1_R_INVALID_BMPSTRING_LENGTH 129
1262#define ASN1_R_INVALID_DIGIT 130 1331#define ASN1_R_INVALID_DIGIT 130
1263#define ASN1_R_INVALID_MIME_TYPE 200 1332#define ASN1_R_INVALID_MIME_TYPE 205
1264#define ASN1_R_INVALID_MODIFIER 186 1333#define ASN1_R_INVALID_MODIFIER 186
1265#define ASN1_R_INVALID_NUMBER 187 1334#define ASN1_R_INVALID_NUMBER 187
1335#define ASN1_R_INVALID_OBJECT_ENCODING 216
1266#define ASN1_R_INVALID_SEPARATOR 131 1336#define ASN1_R_INVALID_SEPARATOR 131
1267#define ASN1_R_INVALID_TIME_FORMAT 132 1337#define ASN1_R_INVALID_TIME_FORMAT 132
1268#define ASN1_R_INVALID_UNIVERSALSTRING_LENGTH 133 1338#define ASN1_R_INVALID_UNIVERSALSTRING_LENGTH 133
@@ -1270,9 +1340,9 @@ void ERR_load_ASN1_strings(void);
1270#define ASN1_R_IV_TOO_LARGE 135 1340#define ASN1_R_IV_TOO_LARGE 135
1271#define ASN1_R_LENGTH_ERROR 136 1341#define ASN1_R_LENGTH_ERROR 136
1272#define ASN1_R_LIST_ERROR 188 1342#define ASN1_R_LIST_ERROR 188
1273#define ASN1_R_MIME_NO_CONTENT_TYPE 201 1343#define ASN1_R_MIME_NO_CONTENT_TYPE 206
1274#define ASN1_R_MIME_PARSE_ERROR 202 1344#define ASN1_R_MIME_PARSE_ERROR 207
1275#define ASN1_R_MIME_SIG_PARSE_ERROR 203 1345#define ASN1_R_MIME_SIG_PARSE_ERROR 208
1276#define ASN1_R_MISSING_EOC 137 1346#define ASN1_R_MISSING_EOC 137
1277#define ASN1_R_MISSING_SECOND_NUMBER 138 1347#define ASN1_R_MISSING_SECOND_NUMBER 138
1278#define ASN1_R_MISSING_VALUE 189 1348#define ASN1_R_MISSING_VALUE 189
@@ -1282,11 +1352,12 @@ void ERR_load_ASN1_strings(void);
1282#define ASN1_R_NON_HEX_CHARACTERS 141 1352#define ASN1_R_NON_HEX_CHARACTERS 141
1283#define ASN1_R_NOT_ASCII_FORMAT 190 1353#define ASN1_R_NOT_ASCII_FORMAT 190
1284#define ASN1_R_NOT_ENOUGH_DATA 142 1354#define ASN1_R_NOT_ENOUGH_DATA 142
1285#define ASN1_R_NO_CONTENT_TYPE 204 1355#define ASN1_R_NO_CONTENT_TYPE 209
1356#define ASN1_R_NO_DEFAULT_DIGEST 201
1286#define ASN1_R_NO_MATCHING_CHOICE_TYPE 143 1357#define ASN1_R_NO_MATCHING_CHOICE_TYPE 143
1287#define ASN1_R_NO_MULTIPART_BODY_FAILURE 205 1358#define ASN1_R_NO_MULTIPART_BODY_FAILURE 210
1288#define ASN1_R_NO_MULTIPART_BOUNDARY 206 1359#define ASN1_R_NO_MULTIPART_BOUNDARY 211
1289#define ASN1_R_NO_SIG_CONTENT_TYPE 207 1360#define ASN1_R_NO_SIG_CONTENT_TYPE 212
1290#define ASN1_R_NULL_IS_WRONG_LENGTH 144 1361#define ASN1_R_NULL_IS_WRONG_LENGTH 144
1291#define ASN1_R_OBJECT_NOT_ASCII_FORMAT 191 1362#define ASN1_R_OBJECT_NOT_ASCII_FORMAT 191
1292#define ASN1_R_ODD_NUMBER_OF_CHARS 145 1363#define ASN1_R_ODD_NUMBER_OF_CHARS 145
@@ -1296,8 +1367,8 @@ void ERR_load_ASN1_strings(void);
1296#define ASN1_R_SEQUENCE_NOT_CONSTRUCTED 149 1367#define ASN1_R_SEQUENCE_NOT_CONSTRUCTED 149
1297#define ASN1_R_SEQUENCE_OR_SET_NEEDS_CONFIG 192 1368#define ASN1_R_SEQUENCE_OR_SET_NEEDS_CONFIG 192
1298#define ASN1_R_SHORT_LINE 150 1369#define ASN1_R_SHORT_LINE 150
1299#define ASN1_R_SIG_INVALID_MIME_TYPE 208 1370#define ASN1_R_SIG_INVALID_MIME_TYPE 213
1300#define ASN1_R_STREAMING_NOT_SUPPORTED 209 1371#define ASN1_R_STREAMING_NOT_SUPPORTED 202
1301#define ASN1_R_STRING_TOO_LONG 151 1372#define ASN1_R_STRING_TOO_LONG 151
1302#define ASN1_R_STRING_TOO_SHORT 152 1373#define ASN1_R_STRING_TOO_SHORT 152
1303#define ASN1_R_TAG_VALUE_TOO_HIGH 153 1374#define ASN1_R_TAG_VALUE_TOO_HIGH 153
@@ -1308,11 +1379,12 @@ void ERR_load_ASN1_strings(void);
1308#define ASN1_R_UNABLE_TO_DECODE_RSA_KEY 157 1379#define ASN1_R_UNABLE_TO_DECODE_RSA_KEY 157
1309#define ASN1_R_UNABLE_TO_DECODE_RSA_PRIVATE_KEY 158 1380#define ASN1_R_UNABLE_TO_DECODE_RSA_PRIVATE_KEY 158
1310#define ASN1_R_UNEXPECTED_EOC 159 1381#define ASN1_R_UNEXPECTED_EOC 159
1311#define ASN1_R_UNIVERSALSTRING_IS_WRONG_LENGTH 211 1382#define ASN1_R_UNIVERSALSTRING_IS_WRONG_LENGTH 215
1312#define ASN1_R_UNKNOWN_FORMAT 160 1383#define ASN1_R_UNKNOWN_FORMAT 160
1313#define ASN1_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM 161 1384#define ASN1_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM 161
1314#define ASN1_R_UNKNOWN_OBJECT_TYPE 162 1385#define ASN1_R_UNKNOWN_OBJECT_TYPE 162
1315#define ASN1_R_UNKNOWN_PUBLIC_KEY_TYPE 163 1386#define ASN1_R_UNKNOWN_PUBLIC_KEY_TYPE 163
1387#define ASN1_R_UNKNOWN_SIGNATURE_ALGORITHM 199
1316#define ASN1_R_UNKNOWN_TAG 194 1388#define ASN1_R_UNKNOWN_TAG 194
1317#define ASN1_R_UNKOWN_FORMAT 195 1389#define ASN1_R_UNKOWN_FORMAT 195
1318#define ASN1_R_UNSUPPORTED_ANY_DEFINED_BY_TYPE 164 1390#define ASN1_R_UNSUPPORTED_ANY_DEFINED_BY_TYPE 164
@@ -1320,6 +1392,7 @@ void ERR_load_ASN1_strings(void);
1320#define ASN1_R_UNSUPPORTED_ENCRYPTION_ALGORITHM 166 1392#define ASN1_R_UNSUPPORTED_ENCRYPTION_ALGORITHM 166
1321#define ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE 167 1393#define ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE 167
1322#define ASN1_R_UNSUPPORTED_TYPE 196 1394#define ASN1_R_UNSUPPORTED_TYPE 196
1395#define ASN1_R_WRONG_PUBLIC_KEY_TYPE 200
1323#define ASN1_R_WRONG_TAG 168 1396#define ASN1_R_WRONG_TAG 168
1324#define ASN1_R_WRONG_TYPE 169 1397#define ASN1_R_WRONG_TYPE 169
1325 1398
diff --git a/src/lib/libcrypto/asn1/asn1_err.c b/src/lib/libcrypto/asn1/asn1_err.c
index 5f5de98eed..6e04d08f31 100644
--- a/src/lib/libcrypto/asn1/asn1_err.c
+++ b/src/lib/libcrypto/asn1/asn1_err.c
@@ -1,6 +1,6 @@
1/* crypto/asn1/asn1_err.c */ 1/* crypto/asn1/asn1_err.c */
2/* ==================================================================== 2/* ====================================================================
3 * Copyright (c) 1999-2008 The OpenSSL Project. All rights reserved. 3 * Copyright (c) 1999-2009 The OpenSSL Project. All rights reserved.
4 * 4 *
5 * Redistribution and use in source and binary forms, with or without 5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions 6 * modification, are permitted provided that the following conditions
@@ -90,10 +90,11 @@ static ERR_STRING_DATA ASN1_str_functs[]=
90{ERR_FUNC(ASN1_F_ASN1_ENUMERATED_TO_BN), "ASN1_ENUMERATED_to_BN"}, 90{ERR_FUNC(ASN1_F_ASN1_ENUMERATED_TO_BN), "ASN1_ENUMERATED_to_BN"},
91{ERR_FUNC(ASN1_F_ASN1_EX_C2I), "ASN1_EX_C2I"}, 91{ERR_FUNC(ASN1_F_ASN1_EX_C2I), "ASN1_EX_C2I"},
92{ERR_FUNC(ASN1_F_ASN1_FIND_END), "ASN1_FIND_END"}, 92{ERR_FUNC(ASN1_F_ASN1_FIND_END), "ASN1_FIND_END"},
93{ERR_FUNC(ASN1_F_ASN1_GENERALIZEDTIME_ADJ), "ASN1_GENERALIZEDTIME_adj"},
93{ERR_FUNC(ASN1_F_ASN1_GENERALIZEDTIME_SET), "ASN1_GENERALIZEDTIME_set"}, 94{ERR_FUNC(ASN1_F_ASN1_GENERALIZEDTIME_SET), "ASN1_GENERALIZEDTIME_set"},
94{ERR_FUNC(ASN1_F_ASN1_GENERATE_V3), "ASN1_generate_v3"}, 95{ERR_FUNC(ASN1_F_ASN1_GENERATE_V3), "ASN1_generate_v3"},
95{ERR_FUNC(ASN1_F_ASN1_GET_OBJECT), "ASN1_get_object"}, 96{ERR_FUNC(ASN1_F_ASN1_GET_OBJECT), "ASN1_get_object"},
96{ERR_FUNC(ASN1_F_ASN1_HEADER_NEW), "ASN1_HEADER_new"}, 97{ERR_FUNC(ASN1_F_ASN1_HEADER_NEW), "ASN1_HEADER_NEW"},
97{ERR_FUNC(ASN1_F_ASN1_I2D_BIO), "ASN1_i2d_bio"}, 98{ERR_FUNC(ASN1_F_ASN1_I2D_BIO), "ASN1_i2d_bio"},
98{ERR_FUNC(ASN1_F_ASN1_I2D_FP), "ASN1_i2d_fp"}, 99{ERR_FUNC(ASN1_F_ASN1_I2D_FP), "ASN1_i2d_fp"},
99{ERR_FUNC(ASN1_F_ASN1_INTEGER_SET), "ASN1_INTEGER_set"}, 100{ERR_FUNC(ASN1_F_ASN1_INTEGER_SET), "ASN1_INTEGER_set"},
@@ -112,7 +113,7 @@ static ERR_STRING_DATA ASN1_str_functs[]=
112{ERR_FUNC(ASN1_F_ASN1_OBJECT_NEW), "ASN1_OBJECT_new"}, 113{ERR_FUNC(ASN1_F_ASN1_OBJECT_NEW), "ASN1_OBJECT_new"},
113{ERR_FUNC(ASN1_F_ASN1_OUTPUT_DATA), "ASN1_OUTPUT_DATA"}, 114{ERR_FUNC(ASN1_F_ASN1_OUTPUT_DATA), "ASN1_OUTPUT_DATA"},
114{ERR_FUNC(ASN1_F_ASN1_PACK_STRING), "ASN1_pack_string"}, 115{ERR_FUNC(ASN1_F_ASN1_PACK_STRING), "ASN1_pack_string"},
115{ERR_FUNC(ASN1_F_ASN1_PCTX_NEW), "ASN1_PCTX_NEW"}, 116{ERR_FUNC(ASN1_F_ASN1_PCTX_NEW), "ASN1_PCTX_new"},
116{ERR_FUNC(ASN1_F_ASN1_PKCS5_PBE_SET), "ASN1_PKCS5_PBE_SET"}, 117{ERR_FUNC(ASN1_F_ASN1_PKCS5_PBE_SET), "ASN1_PKCS5_PBE_SET"},
117{ERR_FUNC(ASN1_F_ASN1_SEQ_PACK), "ASN1_seq_pack"}, 118{ERR_FUNC(ASN1_F_ASN1_SEQ_PACK), "ASN1_seq_pack"},
118{ERR_FUNC(ASN1_F_ASN1_SEQ_UNPACK), "ASN1_seq_unpack"}, 119{ERR_FUNC(ASN1_F_ASN1_SEQ_UNPACK), "ASN1_seq_unpack"},
@@ -124,14 +125,17 @@ static ERR_STRING_DATA ASN1_str_functs[]=
124{ERR_FUNC(ASN1_F_ASN1_TEMPLATE_EX_D2I), "ASN1_TEMPLATE_EX_D2I"}, 125{ERR_FUNC(ASN1_F_ASN1_TEMPLATE_EX_D2I), "ASN1_TEMPLATE_EX_D2I"},
125{ERR_FUNC(ASN1_F_ASN1_TEMPLATE_NEW), "ASN1_TEMPLATE_NEW"}, 126{ERR_FUNC(ASN1_F_ASN1_TEMPLATE_NEW), "ASN1_TEMPLATE_NEW"},
126{ERR_FUNC(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I), "ASN1_TEMPLATE_NOEXP_D2I"}, 127{ERR_FUNC(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I), "ASN1_TEMPLATE_NOEXP_D2I"},
128{ERR_FUNC(ASN1_F_ASN1_TIME_ADJ), "ASN1_TIME_adj"},
127{ERR_FUNC(ASN1_F_ASN1_TIME_SET), "ASN1_TIME_set"}, 129{ERR_FUNC(ASN1_F_ASN1_TIME_SET), "ASN1_TIME_set"},
128{ERR_FUNC(ASN1_F_ASN1_TYPE_GET_INT_OCTETSTRING), "ASN1_TYPE_get_int_octetstring"}, 130{ERR_FUNC(ASN1_F_ASN1_TYPE_GET_INT_OCTETSTRING), "ASN1_TYPE_get_int_octetstring"},
129{ERR_FUNC(ASN1_F_ASN1_TYPE_GET_OCTETSTRING), "ASN1_TYPE_get_octetstring"}, 131{ERR_FUNC(ASN1_F_ASN1_TYPE_GET_OCTETSTRING), "ASN1_TYPE_get_octetstring"},
130{ERR_FUNC(ASN1_F_ASN1_UNPACK_STRING), "ASN1_unpack_string"}, 132{ERR_FUNC(ASN1_F_ASN1_UNPACK_STRING), "ASN1_unpack_string"},
133{ERR_FUNC(ASN1_F_ASN1_UTCTIME_ADJ), "ASN1_UTCTIME_adj"},
131{ERR_FUNC(ASN1_F_ASN1_UTCTIME_SET), "ASN1_UTCTIME_set"}, 134{ERR_FUNC(ASN1_F_ASN1_UTCTIME_SET), "ASN1_UTCTIME_set"},
132{ERR_FUNC(ASN1_F_ASN1_VERIFY), "ASN1_verify"}, 135{ERR_FUNC(ASN1_F_ASN1_VERIFY), "ASN1_verify"},
133{ERR_FUNC(ASN1_F_B64_READ_ASN1), "B64_READ_ASN1"}, 136{ERR_FUNC(ASN1_F_B64_READ_ASN1), "B64_READ_ASN1"},
134{ERR_FUNC(ASN1_F_B64_WRITE_ASN1), "B64_WRITE_ASN1"}, 137{ERR_FUNC(ASN1_F_B64_WRITE_ASN1), "B64_WRITE_ASN1"},
138{ERR_FUNC(ASN1_F_BIO_NEW_NDEF), "BIO_new_NDEF"},
135{ERR_FUNC(ASN1_F_BITSTR_CB), "BITSTR_CB"}, 139{ERR_FUNC(ASN1_F_BITSTR_CB), "BITSTR_CB"},
136{ERR_FUNC(ASN1_F_BN_TO_ASN1_ENUMERATED), "BN_to_ASN1_ENUMERATED"}, 140{ERR_FUNC(ASN1_F_BN_TO_ASN1_ENUMERATED), "BN_to_ASN1_ENUMERATED"},
137{ERR_FUNC(ASN1_F_BN_TO_ASN1_INTEGER), "BN_to_ASN1_INTEGER"}, 141{ERR_FUNC(ASN1_F_BN_TO_ASN1_INTEGER), "BN_to_ASN1_INTEGER"},
@@ -143,13 +147,14 @@ static ERR_STRING_DATA ASN1_str_functs[]=
143{ERR_FUNC(ASN1_F_D2I_ASN1_BOOLEAN), "d2i_ASN1_BOOLEAN"}, 147{ERR_FUNC(ASN1_F_D2I_ASN1_BOOLEAN), "d2i_ASN1_BOOLEAN"},
144{ERR_FUNC(ASN1_F_D2I_ASN1_BYTES), "d2i_ASN1_bytes"}, 148{ERR_FUNC(ASN1_F_D2I_ASN1_BYTES), "d2i_ASN1_bytes"},
145{ERR_FUNC(ASN1_F_D2I_ASN1_GENERALIZEDTIME), "D2I_ASN1_GENERALIZEDTIME"}, 149{ERR_FUNC(ASN1_F_D2I_ASN1_GENERALIZEDTIME), "D2I_ASN1_GENERALIZEDTIME"},
146{ERR_FUNC(ASN1_F_D2I_ASN1_HEADER), "d2i_ASN1_HEADER"}, 150{ERR_FUNC(ASN1_F_D2I_ASN1_HEADER), "D2I_ASN1_HEADER"},
147{ERR_FUNC(ASN1_F_D2I_ASN1_INTEGER), "D2I_ASN1_INTEGER"}, 151{ERR_FUNC(ASN1_F_D2I_ASN1_INTEGER), "D2I_ASN1_INTEGER"},
148{ERR_FUNC(ASN1_F_D2I_ASN1_OBJECT), "d2i_ASN1_OBJECT"}, 152{ERR_FUNC(ASN1_F_D2I_ASN1_OBJECT), "d2i_ASN1_OBJECT"},
149{ERR_FUNC(ASN1_F_D2I_ASN1_SET), "d2i_ASN1_SET"}, 153{ERR_FUNC(ASN1_F_D2I_ASN1_SET), "d2i_ASN1_SET"},
150{ERR_FUNC(ASN1_F_D2I_ASN1_TYPE_BYTES), "d2i_ASN1_type_bytes"}, 154{ERR_FUNC(ASN1_F_D2I_ASN1_TYPE_BYTES), "d2i_ASN1_type_bytes"},
151{ERR_FUNC(ASN1_F_D2I_ASN1_UINTEGER), "d2i_ASN1_UINTEGER"}, 155{ERR_FUNC(ASN1_F_D2I_ASN1_UINTEGER), "d2i_ASN1_UINTEGER"},
152{ERR_FUNC(ASN1_F_D2I_ASN1_UTCTIME), "D2I_ASN1_UTCTIME"}, 156{ERR_FUNC(ASN1_F_D2I_ASN1_UTCTIME), "D2I_ASN1_UTCTIME"},
157{ERR_FUNC(ASN1_F_D2I_AUTOPRIVATEKEY), "d2i_AutoPrivateKey"},
153{ERR_FUNC(ASN1_F_D2I_NETSCAPE_RSA), "d2i_Netscape_RSA"}, 158{ERR_FUNC(ASN1_F_D2I_NETSCAPE_RSA), "d2i_Netscape_RSA"},
154{ERR_FUNC(ASN1_F_D2I_NETSCAPE_RSA_2), "D2I_NETSCAPE_RSA_2"}, 159{ERR_FUNC(ASN1_F_D2I_NETSCAPE_RSA_2), "D2I_NETSCAPE_RSA_2"},
155{ERR_FUNC(ASN1_F_D2I_PRIVATEKEY), "d2i_PrivateKey"}, 160{ERR_FUNC(ASN1_F_D2I_PRIVATEKEY), "d2i_PrivateKey"},
@@ -159,6 +164,7 @@ static ERR_STRING_DATA ASN1_str_functs[]=
159{ERR_FUNC(ASN1_F_D2I_X509), "D2I_X509"}, 164{ERR_FUNC(ASN1_F_D2I_X509), "D2I_X509"},
160{ERR_FUNC(ASN1_F_D2I_X509_CINF), "D2I_X509_CINF"}, 165{ERR_FUNC(ASN1_F_D2I_X509_CINF), "D2I_X509_CINF"},
161{ERR_FUNC(ASN1_F_D2I_X509_PKEY), "d2i_X509_PKEY"}, 166{ERR_FUNC(ASN1_F_D2I_X509_PKEY), "d2i_X509_PKEY"},
167{ERR_FUNC(ASN1_F_I2D_ASN1_BIO_STREAM), "i2d_ASN1_bio_stream"},
162{ERR_FUNC(ASN1_F_I2D_ASN1_SET), "i2d_ASN1_SET"}, 168{ERR_FUNC(ASN1_F_I2D_ASN1_SET), "i2d_ASN1_SET"},
163{ERR_FUNC(ASN1_F_I2D_ASN1_TIME), "I2D_ASN1_TIME"}, 169{ERR_FUNC(ASN1_F_I2D_ASN1_TIME), "I2D_ASN1_TIME"},
164{ERR_FUNC(ASN1_F_I2D_DSA_PUBKEY), "i2d_DSA_PUBKEY"}, 170{ERR_FUNC(ASN1_F_I2D_DSA_PUBKEY), "i2d_DSA_PUBKEY"},
@@ -170,8 +176,9 @@ static ERR_STRING_DATA ASN1_str_functs[]=
170{ERR_FUNC(ASN1_F_LONG_C2I), "LONG_C2I"}, 176{ERR_FUNC(ASN1_F_LONG_C2I), "LONG_C2I"},
171{ERR_FUNC(ASN1_F_OID_MODULE_INIT), "OID_MODULE_INIT"}, 177{ERR_FUNC(ASN1_F_OID_MODULE_INIT), "OID_MODULE_INIT"},
172{ERR_FUNC(ASN1_F_PARSE_TAGGING), "PARSE_TAGGING"}, 178{ERR_FUNC(ASN1_F_PARSE_TAGGING), "PARSE_TAGGING"},
173{ERR_FUNC(ASN1_F_PKCS5_PBE2_SET), "PKCS5_pbe2_set"}, 179{ERR_FUNC(ASN1_F_PKCS5_PBE2_SET_IV), "PKCS5_pbe2_set_iv"},
174{ERR_FUNC(ASN1_F_PKCS5_PBE_SET), "PKCS5_pbe_set"}, 180{ERR_FUNC(ASN1_F_PKCS5_PBE_SET), "PKCS5_pbe_set"},
181{ERR_FUNC(ASN1_F_PKCS5_PBE_SET0_ALGOR), "PKCS5_pbe_set0_algor"},
175{ERR_FUNC(ASN1_F_SMIME_READ_ASN1), "SMIME_read_ASN1"}, 182{ERR_FUNC(ASN1_F_SMIME_READ_ASN1), "SMIME_read_ASN1"},
176{ERR_FUNC(ASN1_F_SMIME_TEXT), "SMIME_text"}, 183{ERR_FUNC(ASN1_F_SMIME_TEXT), "SMIME_text"},
177{ERR_FUNC(ASN1_F_X509_CINF_NEW), "X509_CINF_NEW"}, 184{ERR_FUNC(ASN1_F_X509_CINF_NEW), "X509_CINF_NEW"},
@@ -204,6 +211,7 @@ static ERR_STRING_DATA ASN1_str_reasons[]=
204{ERR_REASON(ASN1_R_DECODE_ERROR) ,"decode error"}, 211{ERR_REASON(ASN1_R_DECODE_ERROR) ,"decode error"},
205{ERR_REASON(ASN1_R_DECODING_ERROR) ,"decoding error"}, 212{ERR_REASON(ASN1_R_DECODING_ERROR) ,"decoding error"},
206{ERR_REASON(ASN1_R_DEPTH_EXCEEDED) ,"depth exceeded"}, 213{ERR_REASON(ASN1_R_DEPTH_EXCEEDED) ,"depth exceeded"},
214{ERR_REASON(ASN1_R_DIGEST_AND_KEY_TYPE_NOT_SUPPORTED),"digest and key type not supported"},
207{ERR_REASON(ASN1_R_ENCODE_ERROR) ,"encode error"}, 215{ERR_REASON(ASN1_R_ENCODE_ERROR) ,"encode error"},
208{ERR_REASON(ASN1_R_ERROR_GETTING_TIME) ,"error getting time"}, 216{ERR_REASON(ASN1_R_ERROR_GETTING_TIME) ,"error getting time"},
209{ERR_REASON(ASN1_R_ERROR_LOADING_SECTION),"error loading section"}, 217{ERR_REASON(ASN1_R_ERROR_LOADING_SECTION),"error loading section"},
@@ -240,6 +248,7 @@ static ERR_STRING_DATA ASN1_str_reasons[]=
240{ERR_REASON(ASN1_R_INVALID_MIME_TYPE) ,"invalid mime type"}, 248{ERR_REASON(ASN1_R_INVALID_MIME_TYPE) ,"invalid mime type"},
241{ERR_REASON(ASN1_R_INVALID_MODIFIER) ,"invalid modifier"}, 249{ERR_REASON(ASN1_R_INVALID_MODIFIER) ,"invalid modifier"},
242{ERR_REASON(ASN1_R_INVALID_NUMBER) ,"invalid number"}, 250{ERR_REASON(ASN1_R_INVALID_NUMBER) ,"invalid number"},
251{ERR_REASON(ASN1_R_INVALID_OBJECT_ENCODING),"invalid object encoding"},
243{ERR_REASON(ASN1_R_INVALID_SEPARATOR) ,"invalid separator"}, 252{ERR_REASON(ASN1_R_INVALID_SEPARATOR) ,"invalid separator"},
244{ERR_REASON(ASN1_R_INVALID_TIME_FORMAT) ,"invalid time format"}, 253{ERR_REASON(ASN1_R_INVALID_TIME_FORMAT) ,"invalid time format"},
245{ERR_REASON(ASN1_R_INVALID_UNIVERSALSTRING_LENGTH),"invalid universalstring length"}, 254{ERR_REASON(ASN1_R_INVALID_UNIVERSALSTRING_LENGTH),"invalid universalstring length"},
@@ -260,6 +269,7 @@ static ERR_STRING_DATA ASN1_str_reasons[]=
260{ERR_REASON(ASN1_R_NOT_ASCII_FORMAT) ,"not ascii format"}, 269{ERR_REASON(ASN1_R_NOT_ASCII_FORMAT) ,"not ascii format"},
261{ERR_REASON(ASN1_R_NOT_ENOUGH_DATA) ,"not enough data"}, 270{ERR_REASON(ASN1_R_NOT_ENOUGH_DATA) ,"not enough data"},
262{ERR_REASON(ASN1_R_NO_CONTENT_TYPE) ,"no content type"}, 271{ERR_REASON(ASN1_R_NO_CONTENT_TYPE) ,"no content type"},
272{ERR_REASON(ASN1_R_NO_DEFAULT_DIGEST) ,"no default digest"},
263{ERR_REASON(ASN1_R_NO_MATCHING_CHOICE_TYPE),"no matching choice type"}, 273{ERR_REASON(ASN1_R_NO_MATCHING_CHOICE_TYPE),"no matching choice type"},
264{ERR_REASON(ASN1_R_NO_MULTIPART_BODY_FAILURE),"no multipart body failure"}, 274{ERR_REASON(ASN1_R_NO_MULTIPART_BODY_FAILURE),"no multipart body failure"},
265{ERR_REASON(ASN1_R_NO_MULTIPART_BOUNDARY),"no multipart boundary"}, 275{ERR_REASON(ASN1_R_NO_MULTIPART_BOUNDARY),"no multipart boundary"},
@@ -290,6 +300,7 @@ static ERR_STRING_DATA ASN1_str_reasons[]=
290{ERR_REASON(ASN1_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM),"unknown message digest algorithm"}, 300{ERR_REASON(ASN1_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM),"unknown message digest algorithm"},
291{ERR_REASON(ASN1_R_UNKNOWN_OBJECT_TYPE) ,"unknown object type"}, 301{ERR_REASON(ASN1_R_UNKNOWN_OBJECT_TYPE) ,"unknown object type"},
292{ERR_REASON(ASN1_R_UNKNOWN_PUBLIC_KEY_TYPE),"unknown public key type"}, 302{ERR_REASON(ASN1_R_UNKNOWN_PUBLIC_KEY_TYPE),"unknown public key type"},
303{ERR_REASON(ASN1_R_UNKNOWN_SIGNATURE_ALGORITHM),"unknown signature algorithm"},
293{ERR_REASON(ASN1_R_UNKNOWN_TAG) ,"unknown tag"}, 304{ERR_REASON(ASN1_R_UNKNOWN_TAG) ,"unknown tag"},
294{ERR_REASON(ASN1_R_UNKOWN_FORMAT) ,"unkown format"}, 305{ERR_REASON(ASN1_R_UNKOWN_FORMAT) ,"unkown format"},
295{ERR_REASON(ASN1_R_UNSUPPORTED_ANY_DEFINED_BY_TYPE),"unsupported any defined by type"}, 306{ERR_REASON(ASN1_R_UNSUPPORTED_ANY_DEFINED_BY_TYPE),"unsupported any defined by type"},
@@ -297,6 +308,7 @@ static ERR_STRING_DATA ASN1_str_reasons[]=
297{ERR_REASON(ASN1_R_UNSUPPORTED_ENCRYPTION_ALGORITHM),"unsupported encryption algorithm"}, 308{ERR_REASON(ASN1_R_UNSUPPORTED_ENCRYPTION_ALGORITHM),"unsupported encryption algorithm"},
298{ERR_REASON(ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE),"unsupported public key type"}, 309{ERR_REASON(ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE),"unsupported public key type"},
299{ERR_REASON(ASN1_R_UNSUPPORTED_TYPE) ,"unsupported type"}, 310{ERR_REASON(ASN1_R_UNSUPPORTED_TYPE) ,"unsupported type"},
311{ERR_REASON(ASN1_R_WRONG_PUBLIC_KEY_TYPE),"wrong public key type"},
300{ERR_REASON(ASN1_R_WRONG_TAG) ,"wrong tag"}, 312{ERR_REASON(ASN1_R_WRONG_TAG) ,"wrong tag"},
301{ERR_REASON(ASN1_R_WRONG_TYPE) ,"wrong type"}, 313{ERR_REASON(ASN1_R_WRONG_TYPE) ,"wrong type"},
302{0,NULL} 314{0,NULL}
diff --git a/src/lib/libcrypto/asn1/asn1_gen.c b/src/lib/libcrypto/asn1/asn1_gen.c
index 2da38292c8..4fc241908f 100644
--- a/src/lib/libcrypto/asn1/asn1_gen.c
+++ b/src/lib/libcrypto/asn1/asn1_gen.c
@@ -227,6 +227,8 @@ ASN1_TYPE *ASN1_generate_v3(char *str, X509V3_CTX *cnf)
227 /* Allocate buffer for new encoding */ 227 /* Allocate buffer for new encoding */
228 228
229 new_der = OPENSSL_malloc(len); 229 new_der = OPENSSL_malloc(len);
230 if (!new_der)
231 goto err;
230 232
231 /* Generate tagged encoding */ 233 /* Generate tagged encoding */
232 234
@@ -245,8 +247,14 @@ ASN1_TYPE *ASN1_generate_v3(char *str, X509V3_CTX *cnf)
245 /* If IMPLICIT, output tag */ 247 /* If IMPLICIT, output tag */
246 248
247 if (asn1_tags.imp_tag != -1) 249 if (asn1_tags.imp_tag != -1)
250 {
251 if (asn1_tags.imp_class == V_ASN1_UNIVERSAL
252 && (asn1_tags.imp_tag == V_ASN1_SEQUENCE
253 || asn1_tags.imp_tag == V_ASN1_SET) )
254 hdr_constructed = V_ASN1_CONSTRUCTED;
248 ASN1_put_object(&p, hdr_constructed, hdr_len, 255 ASN1_put_object(&p, hdr_constructed, hdr_len,
249 asn1_tags.imp_tag, asn1_tags.imp_class); 256 asn1_tags.imp_tag, asn1_tags.imp_class);
257 }
250 258
251 /* Copy across original encoding */ 259 /* Copy across original encoding */
252 memcpy(p, cpy_start, cpy_len); 260 memcpy(p, cpy_start, cpy_len);
@@ -439,13 +447,15 @@ static int parse_tagging(const char *vstart, int vlen, int *ptag, int *pclass)
439 447
440static ASN1_TYPE *asn1_multi(int utype, const char *section, X509V3_CTX *cnf) 448static ASN1_TYPE *asn1_multi(int utype, const char *section, X509V3_CTX *cnf)
441 { 449 {
442 ASN1_TYPE *ret = NULL, *typ = NULL; 450 ASN1_TYPE *ret = NULL;
443 STACK_OF(ASN1_TYPE) *sk = NULL; 451 STACK_OF(ASN1_TYPE) *sk = NULL;
444 STACK_OF(CONF_VALUE) *sect = NULL; 452 STACK_OF(CONF_VALUE) *sect = NULL;
445 unsigned char *der = NULL, *p; 453 unsigned char *der = NULL;
446 int derlen; 454 int derlen;
447 int i, is_set; 455 int i;
448 sk = sk_ASN1_TYPE_new_null(); 456 sk = sk_ASN1_TYPE_new_null();
457 if (!sk)
458 goto bad;
449 if (section) 459 if (section)
450 { 460 {
451 if (!cnf) 461 if (!cnf)
@@ -455,28 +465,23 @@ static ASN1_TYPE *asn1_multi(int utype, const char *section, X509V3_CTX *cnf)
455 goto bad; 465 goto bad;
456 for (i = 0; i < sk_CONF_VALUE_num(sect); i++) 466 for (i = 0; i < sk_CONF_VALUE_num(sect); i++)
457 { 467 {
458 typ = ASN1_generate_v3(sk_CONF_VALUE_value(sect, i)->value, cnf); 468 ASN1_TYPE *typ = ASN1_generate_v3(sk_CONF_VALUE_value(sect, i)->value, cnf);
459 if (!typ) 469 if (!typ)
460 goto bad; 470 goto bad;
461 sk_ASN1_TYPE_push(sk, typ); 471 if (!sk_ASN1_TYPE_push(sk, typ))
462 typ = NULL; 472 goto bad;
463 } 473 }
464 } 474 }
465 475
466 /* Now we has a STACK of the components, convert to the correct form */ 476 /* Now we has a STACK of the components, convert to the correct form */
467 477
468 if (utype == V_ASN1_SET) 478 if (utype == V_ASN1_SET)
469 is_set = 1; 479 derlen = i2d_ASN1_SET_ANY(sk, &der);
470 else 480 else
471 is_set = 0; 481 derlen = i2d_ASN1_SEQUENCE_ANY(sk, &der);
472
473 482
474 derlen = i2d_ASN1_SET_OF_ASN1_TYPE(sk, NULL, i2d_ASN1_TYPE, utype, 483 if (derlen < 0)
475 V_ASN1_UNIVERSAL, is_set); 484 goto bad;
476 der = OPENSSL_malloc(derlen);
477 p = der;
478 i2d_ASN1_SET_OF_ASN1_TYPE(sk, &p, i2d_ASN1_TYPE, utype,
479 V_ASN1_UNIVERSAL, is_set);
480 485
481 if (!(ret = ASN1_TYPE_new())) 486 if (!(ret = ASN1_TYPE_new()))
482 goto bad; 487 goto bad;
@@ -498,8 +503,6 @@ static ASN1_TYPE *asn1_multi(int utype, const char *section, X509V3_CTX *cnf)
498 503
499 if (sk) 504 if (sk)
500 sk_ASN1_TYPE_pop_free(sk, ASN1_TYPE_free); 505 sk_ASN1_TYPE_pop_free(sk, ASN1_TYPE_free);
501 if (typ)
502 ASN1_TYPE_free(typ);
503 if (sect) 506 if (sect)
504 X509V3_section_free(cnf, sect); 507 X509V3_section_free(cnf, sect);
505 508
@@ -549,7 +552,7 @@ static int append_exp(tag_exp_arg *arg, int exp_tag, int exp_class, int exp_cons
549static int asn1_str2tag(const char *tagstr, int len) 552static int asn1_str2tag(const char *tagstr, int len)
550 { 553 {
551 unsigned int i; 554 unsigned int i;
552 static struct tag_name_st *tntmp, tnst [] = { 555 static const struct tag_name_st *tntmp, tnst [] = {
553 ASN1_GEN_STR("BOOL", V_ASN1_BOOLEAN), 556 ASN1_GEN_STR("BOOL", V_ASN1_BOOLEAN),
554 ASN1_GEN_STR("BOOLEAN", V_ASN1_BOOLEAN), 557 ASN1_GEN_STR("BOOLEAN", V_ASN1_BOOLEAN),
555 ASN1_GEN_STR("NULL", V_ASN1_NULL), 558 ASN1_GEN_STR("NULL", V_ASN1_NULL),
@@ -584,6 +587,8 @@ static int asn1_str2tag(const char *tagstr, int len)
584 ASN1_GEN_STR("TELETEXSTRING", V_ASN1_T61STRING), 587 ASN1_GEN_STR("TELETEXSTRING", V_ASN1_T61STRING),
585 ASN1_GEN_STR("GeneralString", V_ASN1_GENERALSTRING), 588 ASN1_GEN_STR("GeneralString", V_ASN1_GENERALSTRING),
586 ASN1_GEN_STR("GENSTR", V_ASN1_GENERALSTRING), 589 ASN1_GEN_STR("GENSTR", V_ASN1_GENERALSTRING),
590 ASN1_GEN_STR("NUMERIC", V_ASN1_NUMERICSTRING),
591 ASN1_GEN_STR("NUMERICSTRING", V_ASN1_NUMERICSTRING),
587 592
588 /* Special cases */ 593 /* Special cases */
589 ASN1_GEN_STR("SEQUENCE", V_ASN1_SEQUENCE), 594 ASN1_GEN_STR("SEQUENCE", V_ASN1_SEQUENCE),
@@ -729,6 +734,7 @@ static ASN1_TYPE *asn1_str2type(const char *str, int format, int utype)
729 case V_ASN1_VISIBLESTRING: 734 case V_ASN1_VISIBLESTRING:
730 case V_ASN1_UNIVERSALSTRING: 735 case V_ASN1_UNIVERSALSTRING:
731 case V_ASN1_GENERALSTRING: 736 case V_ASN1_GENERALSTRING:
737 case V_ASN1_NUMERICSTRING:
732 738
733 if (format == ASN1_GEN_FORMAT_ASCII) 739 if (format == ASN1_GEN_FORMAT_ASCII)
734 format = MBSTRING_ASC; 740 format = MBSTRING_ASC;
diff --git a/src/lib/libcrypto/asn1/asn1_lib.c b/src/lib/libcrypto/asn1/asn1_lib.c
index 5af559ef8d..1bcb44aee2 100644
--- a/src/lib/libcrypto/asn1/asn1_lib.c
+++ b/src/lib/libcrypto/asn1/asn1_lib.c
@@ -340,20 +340,31 @@ int asn1_GetSequence(ASN1_const_CTX *c, long *length)
340 return(1); 340 return(1);
341 } 341 }
342 342
343ASN1_STRING *ASN1_STRING_dup(ASN1_STRING *str) 343int ASN1_STRING_copy(ASN1_STRING *dst, const ASN1_STRING *str)
344 { 344 {
345 ASN1_STRING *ret; 345 if (str == NULL)
346 return 0;
347 dst->type = str->type;
348 if (!ASN1_STRING_set(dst,str->data,str->length))
349 return 0;
350 dst->flags = str->flags;
351 return 1;
352 }
346 353
347 if (str == NULL) return(NULL); 354ASN1_STRING *ASN1_STRING_dup(const ASN1_STRING *str)
348 if ((ret=ASN1_STRING_type_new(str->type)) == NULL) 355 {
349 return(NULL); 356 ASN1_STRING *ret;
350 if (!ASN1_STRING_set(ret,str->data,str->length)) 357 if (!str)
358 return NULL;
359 ret=ASN1_STRING_new();
360 if (!ret)
361 return NULL;
362 if (!ASN1_STRING_copy(ret,str))
351 { 363 {
352 ASN1_STRING_free(ret); 364 ASN1_STRING_free(ret);
353 return(NULL); 365 return NULL;
354 } 366 }
355 ret->flags = str->flags; 367 return ret;
356 return(ret);
357 } 368 }
358 369
359int ASN1_STRING_set(ASN1_STRING *str, const void *_data, int len) 370int ASN1_STRING_set(ASN1_STRING *str, const void *_data, int len)
@@ -427,11 +438,12 @@ ASN1_STRING *ASN1_STRING_type_new(int type)
427void ASN1_STRING_free(ASN1_STRING *a) 438void ASN1_STRING_free(ASN1_STRING *a)
428 { 439 {
429 if (a == NULL) return; 440 if (a == NULL) return;
430 if (a->data != NULL) OPENSSL_free(a->data); 441 if (a->data && !(a->flags & ASN1_STRING_FLAG_NDEF))
442 OPENSSL_free(a->data);
431 OPENSSL_free(a); 443 OPENSSL_free(a);
432 } 444 }
433 445
434int ASN1_STRING_cmp(ASN1_STRING *a, ASN1_STRING *b) 446int ASN1_STRING_cmp(const ASN1_STRING *a, const ASN1_STRING *b)
435 { 447 {
436 int i; 448 int i;
437 449
@@ -457,7 +469,7 @@ void asn1_add_error(const unsigned char *address, int offset)
457 ERR_add_error_data(4,"address=",buf1," offset=",buf2); 469 ERR_add_error_data(4,"address=",buf1," offset=",buf2);
458 } 470 }
459 471
460int ASN1_STRING_length(ASN1_STRING *x) 472int ASN1_STRING_length(const ASN1_STRING *x)
461{ return M_ASN1_STRING_length(x); } 473{ return M_ASN1_STRING_length(x); }
462 474
463void ASN1_STRING_length_set(ASN1_STRING *x, int len) 475void ASN1_STRING_length_set(ASN1_STRING *x, int len)
diff --git a/src/lib/libcrypto/asn1/asn1_mac.h b/src/lib/libcrypto/asn1/asn1_mac.h
index d958ca60d9..87bd0e9e1d 100644
--- a/src/lib/libcrypto/asn1/asn1_mac.h
+++ b/src/lib/libcrypto/asn1/asn1_mac.h
@@ -153,6 +153,13 @@ err:\
153 M_ASN1_D2I_get(b,func); \ 153 M_ASN1_D2I_get(b,func); \
154 } 154 }
155 155
156#define M_ASN1_D2I_get_int_opt(b,func,type) \
157 if ((c.slen != 0) && ((M_ASN1_next & (~V_ASN1_CONSTRUCTED)) \
158 == (V_ASN1_UNIVERSAL|(type)))) \
159 { \
160 M_ASN1_D2I_get_int(b,func); \
161 }
162
156#define M_ASN1_D2I_get_imp(b,func, type) \ 163#define M_ASN1_D2I_get_imp(b,func, type) \
157 M_ASN1_next=(_tmp& V_ASN1_CONSTRUCTED)|type; \ 164 M_ASN1_next=(_tmp& V_ASN1_CONSTRUCTED)|type; \
158 c.q=c.p; \ 165 c.q=c.p; \
diff --git a/src/lib/libcrypto/asn1/asn1_par.c b/src/lib/libcrypto/asn1/asn1_par.c
index 8657f73d66..aaca69aebd 100644
--- a/src/lib/libcrypto/asn1/asn1_par.c
+++ b/src/lib/libcrypto/asn1/asn1_par.c
@@ -70,9 +70,8 @@ static int asn1_print_info(BIO *bp, int tag, int xclass, int constructed,
70 int indent) 70 int indent)
71 { 71 {
72 static const char fmt[]="%-18s"; 72 static const char fmt[]="%-18s";
73 static const char fmt2[]="%2d %-15s";
74 char str[128]; 73 char str[128];
75 const char *p,*p2=NULL; 74 const char *p;
76 75
77 if (constructed & V_ASN1_CONSTRUCTED) 76 if (constructed & V_ASN1_CONSTRUCTED)
78 p="cons: "; 77 p="cons: ";
@@ -93,14 +92,8 @@ static int asn1_print_info(BIO *bp, int tag, int xclass, int constructed,
93 else 92 else
94 p = ASN1_tag2str(tag); 93 p = ASN1_tag2str(tag);
95 94
96 if (p2 != NULL) 95 if (BIO_printf(bp,fmt,p) <= 0)
97 { 96 goto err;
98 if (BIO_printf(bp,fmt2,tag,p2) <= 0) goto err;
99 }
100 else
101 {
102 if (BIO_printf(bp,fmt,p) <= 0) goto err;
103 }
104 return(1); 97 return(1);
105err: 98err:
106 return(0); 99 return(0);
@@ -246,7 +239,7 @@ static int asn1_parse2(BIO *bp, const unsigned char **pp, long length, int offse
246 ii=d2i_ASN1_BOOLEAN(NULL,&opp,len+hl); 239 ii=d2i_ASN1_BOOLEAN(NULL,&opp,len+hl);
247 if (ii < 0) 240 if (ii < 0)
248 { 241 {
249 if (BIO_write(bp,"Bad boolean\n",12)) 242 if (BIO_write(bp,"Bad boolean\n",12) <= 0)
250 goto end; 243 goto end;
251 } 244 }
252 BIO_printf(bp,":%d",ii); 245 BIO_printf(bp,":%d",ii);
@@ -424,7 +417,7 @@ end:
424 417
425const char *ASN1_tag2str(int tag) 418const char *ASN1_tag2str(int tag)
426{ 419{
427 static const char *tag2str[] = { 420 static const char * const tag2str[] = {
428 "EOC", "BOOLEAN", "INTEGER", "BIT STRING", "OCTET STRING", /* 0-4 */ 421 "EOC", "BOOLEAN", "INTEGER", "BIT STRING", "OCTET STRING", /* 0-4 */
429 "NULL", "OBJECT", "OBJECT DESCRIPTOR", "EXTERNAL", "REAL", /* 5-9 */ 422 "NULL", "OBJECT", "OBJECT DESCRIPTOR", "EXTERNAL", "REAL", /* 5-9 */
430 "ENUMERATED", "<ASN1 11>", "UTF8STRING", "<ASN1 13>", /* 10-13 */ 423 "ENUMERATED", "<ASN1 11>", "UTF8STRING", "<ASN1 13>", /* 10-13 */
diff --git a/src/lib/libcrypto/asn1/asn1t.h b/src/lib/libcrypto/asn1/asn1t.h
index ac14f9415b..d230e4bf70 100644
--- a/src/lib/libcrypto/asn1/asn1t.h
+++ b/src/lib/libcrypto/asn1/asn1t.h
@@ -3,7 +3,7 @@
3 * project 2000. 3 * project 2000.
4 */ 4 */
5/* ==================================================================== 5/* ====================================================================
6 * Copyright (c) 2000 The OpenSSL Project. All rights reserved. 6 * Copyright (c) 2000-2005 The OpenSSL Project. All rights reserved.
7 * 7 *
8 * Redistribution and use in source and binary forms, with or without 8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions 9 * modification, are permitted provided that the following conditions
@@ -218,6 +218,18 @@ extern "C" {
218 #stname \ 218 #stname \
219 ASN1_ITEM_end(tname) 219 ASN1_ITEM_end(tname)
220 220
221#define ASN1_NDEF_SEQUENCE_END_cb(stname, tname) \
222 ;\
223 ASN1_ITEM_start(tname) \
224 ASN1_ITYPE_NDEF_SEQUENCE,\
225 V_ASN1_SEQUENCE,\
226 tname##_seq_tt,\
227 sizeof(tname##_seq_tt) / sizeof(ASN1_TEMPLATE),\
228 &tname##_aux,\
229 sizeof(stname),\
230 #stname \
231 ASN1_ITEM_end(tname)
232
221 233
222/* This pair helps declare a CHOICE type. We can do: 234/* This pair helps declare a CHOICE type. We can do:
223 * 235 *
@@ -651,8 +663,13 @@ typedef int ASN1_ex_i2d(ASN1_VALUE **pval, unsigned char **out, const ASN1_ITEM
651typedef int ASN1_ex_new_func(ASN1_VALUE **pval, const ASN1_ITEM *it); 663typedef int ASN1_ex_new_func(ASN1_VALUE **pval, const ASN1_ITEM *it);
652typedef void ASN1_ex_free_func(ASN1_VALUE **pval, const ASN1_ITEM *it); 664typedef void ASN1_ex_free_func(ASN1_VALUE **pval, const ASN1_ITEM *it);
653 665
666typedef int ASN1_ex_print_func(BIO *out, ASN1_VALUE **pval,
667 int indent, const char *fname,
668 const ASN1_PCTX *pctx);
669
654typedef int ASN1_primitive_i2c(ASN1_VALUE **pval, unsigned char *cont, int *putype, const ASN1_ITEM *it); 670typedef int ASN1_primitive_i2c(ASN1_VALUE **pval, unsigned char *cont, int *putype, const ASN1_ITEM *it);
655typedef int ASN1_primitive_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len, int utype, char *free_cont, const ASN1_ITEM *it); 671typedef int ASN1_primitive_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len, int utype, char *free_cont, const ASN1_ITEM *it);
672typedef int ASN1_primitive_print(BIO *out, ASN1_VALUE **pval, const ASN1_ITEM *it, int indent, const ASN1_PCTX *pctx);
656 673
657typedef struct ASN1_COMPAT_FUNCS_st { 674typedef struct ASN1_COMPAT_FUNCS_st {
658 ASN1_new_func *asn1_new; 675 ASN1_new_func *asn1_new;
@@ -668,6 +685,7 @@ typedef struct ASN1_EXTERN_FUNCS_st {
668 ASN1_ex_free_func *asn1_ex_clear; 685 ASN1_ex_free_func *asn1_ex_clear;
669 ASN1_ex_d2i *asn1_ex_d2i; 686 ASN1_ex_d2i *asn1_ex_d2i;
670 ASN1_ex_i2d *asn1_ex_i2d; 687 ASN1_ex_i2d *asn1_ex_i2d;
688 ASN1_ex_print_func *asn1_ex_print;
671} ASN1_EXTERN_FUNCS; 689} ASN1_EXTERN_FUNCS;
672 690
673typedef struct ASN1_PRIMITIVE_FUNCS_st { 691typedef struct ASN1_PRIMITIVE_FUNCS_st {
@@ -678,6 +696,7 @@ typedef struct ASN1_PRIMITIVE_FUNCS_st {
678 ASN1_ex_free_func *prim_clear; 696 ASN1_ex_free_func *prim_clear;
679 ASN1_primitive_c2i *prim_c2i; 697 ASN1_primitive_c2i *prim_c2i;
680 ASN1_primitive_i2c *prim_i2c; 698 ASN1_primitive_i2c *prim_i2c;
699 ASN1_primitive_print *prim_print;
681} ASN1_PRIMITIVE_FUNCS; 700} ASN1_PRIMITIVE_FUNCS;
682 701
683/* This is the ASN1_AUX structure: it handles various 702/* This is the ASN1_AUX structure: it handles various
@@ -697,7 +716,8 @@ typedef struct ASN1_PRIMITIVE_FUNCS_st {
697 * then an external type is more appropriate. 716 * then an external type is more appropriate.
698 */ 717 */
699 718
700typedef int ASN1_aux_cb(int operation, ASN1_VALUE **in, const ASN1_ITEM *it); 719typedef int ASN1_aux_cb(int operation, ASN1_VALUE **in, const ASN1_ITEM *it,
720 void *exarg);
701 721
702typedef struct ASN1_AUX_st { 722typedef struct ASN1_AUX_st {
703 void *app_data; 723 void *app_data;
@@ -708,6 +728,23 @@ typedef struct ASN1_AUX_st {
708 int enc_offset; /* Offset of ASN1_ENCODING structure */ 728 int enc_offset; /* Offset of ASN1_ENCODING structure */
709} ASN1_AUX; 729} ASN1_AUX;
710 730
731/* For print related callbacks exarg points to this structure */
732typedef struct ASN1_PRINT_ARG_st {
733 BIO *out;
734 int indent;
735 const ASN1_PCTX *pctx;
736} ASN1_PRINT_ARG;
737
738/* For streaming related callbacks exarg points to this structure */
739typedef struct ASN1_STREAM_ARG_st {
740 /* BIO to stream through */
741 BIO *out;
742 /* BIO with filters appended */
743 BIO *ndef_bio;
744 /* Streaming I/O boundary */
745 unsigned char **boundary;
746} ASN1_STREAM_ARG;
747
711/* Flags in ASN1_AUX */ 748/* Flags in ASN1_AUX */
712 749
713/* Use a reference count */ 750/* Use a reference count */
@@ -727,6 +764,12 @@ typedef struct ASN1_AUX_st {
727#define ASN1_OP_D2I_POST 5 764#define ASN1_OP_D2I_POST 5
728#define ASN1_OP_I2D_PRE 6 765#define ASN1_OP_I2D_PRE 6
729#define ASN1_OP_I2D_POST 7 766#define ASN1_OP_I2D_POST 7
767#define ASN1_OP_PRINT_PRE 8
768#define ASN1_OP_PRINT_POST 9
769#define ASN1_OP_STREAM_PRE 10
770#define ASN1_OP_STREAM_POST 11
771#define ASN1_OP_DETACHED_PRE 12
772#define ASN1_OP_DETACHED_POST 13
730 773
731/* Macro to implement a primitive type */ 774/* Macro to implement a primitive type */
732#define IMPLEMENT_ASN1_TYPE(stname) IMPLEMENT_ASN1_TYPE_ex(stname, stname, 0) 775#define IMPLEMENT_ASN1_TYPE(stname) IMPLEMENT_ASN1_TYPE_ex(stname, stname, 0)
@@ -782,9 +825,22 @@ typedef struct ASN1_AUX_st {
782#define IMPLEMENT_ASN1_FUNCTIONS_ENCODE_name(stname, itname) \ 825#define IMPLEMENT_ASN1_FUNCTIONS_ENCODE_name(stname, itname) \
783 IMPLEMENT_ASN1_FUNCTIONS_ENCODE_fname(stname, itname, itname) 826 IMPLEMENT_ASN1_FUNCTIONS_ENCODE_fname(stname, itname, itname)
784 827
828#define IMPLEMENT_STATIC_ASN1_ALLOC_FUNCTIONS(stname) \
829 IMPLEMENT_ASN1_ALLOC_FUNCTIONS_pfname(static, stname, stname, stname)
830
785#define IMPLEMENT_ASN1_ALLOC_FUNCTIONS(stname) \ 831#define IMPLEMENT_ASN1_ALLOC_FUNCTIONS(stname) \
786 IMPLEMENT_ASN1_ALLOC_FUNCTIONS_fname(stname, stname, stname) 832 IMPLEMENT_ASN1_ALLOC_FUNCTIONS_fname(stname, stname, stname)
787 833
834#define IMPLEMENT_ASN1_ALLOC_FUNCTIONS_pfname(pre, stname, itname, fname) \
835 pre stname *fname##_new(void) \
836 { \
837 return (stname *)ASN1_item_new(ASN1_ITEM_rptr(itname)); \
838 } \
839 pre void fname##_free(stname *a) \
840 { \
841 ASN1_item_free((ASN1_VALUE *)a, ASN1_ITEM_rptr(itname)); \
842 }
843
788#define IMPLEMENT_ASN1_ALLOC_FUNCTIONS_fname(stname, itname, fname) \ 844#define IMPLEMENT_ASN1_ALLOC_FUNCTIONS_fname(stname, itname, fname) \
789 stname *fname##_new(void) \ 845 stname *fname##_new(void) \
790 { \ 846 { \
@@ -834,6 +890,17 @@ typedef struct ASN1_AUX_st {
834 return ASN1_item_dup(ASN1_ITEM_rptr(stname), x); \ 890 return ASN1_item_dup(ASN1_ITEM_rptr(stname), x); \
835 } 891 }
836 892
893#define IMPLEMENT_ASN1_PRINT_FUNCTION(stname) \
894 IMPLEMENT_ASN1_PRINT_FUNCTION_fname(stname, stname, stname)
895
896#define IMPLEMENT_ASN1_PRINT_FUNCTION_fname(stname, itname, fname) \
897 int fname##_print_ctx(BIO *out, stname *x, int indent, \
898 const ASN1_PCTX *pctx) \
899 { \
900 return ASN1_item_print(out, (ASN1_VALUE *)x, indent, \
901 ASN1_ITEM_rptr(itname), pctx); \
902 }
903
837#define IMPLEMENT_ASN1_FUNCTIONS_const(name) \ 904#define IMPLEMENT_ASN1_FUNCTIONS_const(name) \
838 IMPLEMENT_ASN1_FUNCTIONS_const_fname(name, name, name) 905 IMPLEMENT_ASN1_FUNCTIONS_const_fname(name, name, name)
839 906
diff --git a/src/lib/libcrypto/asn1/asn_mime.c b/src/lib/libcrypto/asn1/asn_mime.c
index d8d9e76cc0..c1d1b12291 100644
--- a/src/lib/libcrypto/asn1/asn_mime.c
+++ b/src/lib/libcrypto/asn1/asn_mime.c
@@ -59,6 +59,7 @@
59#include <openssl/x509.h> 59#include <openssl/x509.h>
60#include <openssl/asn1.h> 60#include <openssl/asn1.h>
61#include <openssl/asn1t.h> 61#include <openssl/asn1t.h>
62#include "asn1_locl.h"
62 63
63/* Generalised MIME like utilities for streaming ASN1. Although many 64/* Generalised MIME like utilities for streaming ASN1. Although many
64 * have a PKCS7/CMS like flavour others are more general purpose. 65 * have a PKCS7/CMS like flavour others are more general purpose.
@@ -86,6 +87,8 @@ STACK_OF(MIME_PARAM) *params; /* Zero or more parameters */
86DECLARE_STACK_OF(MIME_HEADER) 87DECLARE_STACK_OF(MIME_HEADER)
87IMPLEMENT_STACK_OF(MIME_HEADER) 88IMPLEMENT_STACK_OF(MIME_HEADER)
88 89
90static int asn1_output_data(BIO *out, BIO *data, ASN1_VALUE *val, int flags,
91 const ASN1_ITEM *it);
89static char * strip_ends(char *name); 92static char * strip_ends(char *name);
90static char * strip_start(char *name); 93static char * strip_start(char *name);
91static char * strip_end(char *name); 94static char * strip_end(char *name);
@@ -107,6 +110,39 @@ static void mime_hdr_free(MIME_HEADER *hdr);
107#define MAX_SMLEN 1024 110#define MAX_SMLEN 1024
108#define mime_debug(x) /* x */ 111#define mime_debug(x) /* x */
109 112
113/* Output an ASN1 structure in BER format streaming if necessary */
114
115int i2d_ASN1_bio_stream(BIO *out, ASN1_VALUE *val, BIO *in, int flags,
116 const ASN1_ITEM *it)
117 {
118 /* If streaming create stream BIO and copy all content through it */
119 if (flags & SMIME_STREAM)
120 {
121 BIO *bio, *tbio;
122 bio = BIO_new_NDEF(out, val, it);
123 if (!bio)
124 {
125 ASN1err(ASN1_F_I2D_ASN1_BIO_STREAM,ERR_R_MALLOC_FAILURE);
126 return 0;
127 }
128 SMIME_crlf_copy(in, bio, flags);
129 (void)BIO_flush(bio);
130 /* Free up successive BIOs until we hit the old output BIO */
131 do
132 {
133 tbio = BIO_pop(bio);
134 BIO_free(bio);
135 bio = tbio;
136 } while (bio != out);
137 }
138 /* else just write out ASN1 structure which will have all content
139 * stored internally
140 */
141 else
142 ASN1_item_i2d_bio(it, out, val);
143 return 1;
144 }
145
110/* Base 64 read and write of ASN1 structure */ 146/* Base 64 read and write of ASN1 structure */
111 147
112static int B64_write_ASN1(BIO *out, ASN1_VALUE *val, BIO *in, int flags, 148static int B64_write_ASN1(BIO *out, ASN1_VALUE *val, BIO *in, int flags,
@@ -123,13 +159,26 @@ static int B64_write_ASN1(BIO *out, ASN1_VALUE *val, BIO *in, int flags,
123 /* prepend the b64 BIO so all data is base64 encoded. 159 /* prepend the b64 BIO so all data is base64 encoded.
124 */ 160 */
125 out = BIO_push(b64, out); 161 out = BIO_push(b64, out);
126 r = ASN1_item_i2d_bio(it, out, val); 162 r = i2d_ASN1_bio_stream(out, val, in, flags, it);
127 (void)BIO_flush(out); 163 (void)BIO_flush(out);
128 BIO_pop(out); 164 BIO_pop(out);
129 BIO_free(b64); 165 BIO_free(b64);
130 return r; 166 return r;
131 } 167 }
132 168
169/* Streaming ASN1 PEM write */
170
171int PEM_write_bio_ASN1_stream(BIO *out, ASN1_VALUE *val, BIO *in, int flags,
172 const char *hdr,
173 const ASN1_ITEM *it)
174 {
175 int r;
176 BIO_printf(out, "-----BEGIN %s-----\n", hdr);
177 r = B64_write_ASN1(out, val, in, flags, it);
178 BIO_printf(out, "-----END %s-----\n", hdr);
179 return r;
180 }
181
133static ASN1_VALUE *b64_read_asn1(BIO *bio, const ASN1_ITEM *it) 182static ASN1_VALUE *b64_read_asn1(BIO *bio, const ASN1_ITEM *it)
134{ 183{
135 BIO *b64; 184 BIO *b64;
@@ -152,7 +201,8 @@ static ASN1_VALUE *b64_read_asn1(BIO *bio, const ASN1_ITEM *it)
152 201
153static int asn1_write_micalg(BIO *out, STACK_OF(X509_ALGOR) *mdalgs) 202static int asn1_write_micalg(BIO *out, STACK_OF(X509_ALGOR) *mdalgs)
154 { 203 {
155 int i, have_unknown = 0, write_comma, md_nid; 204 const EVP_MD *md;
205 int i, have_unknown = 0, write_comma, ret = 0, md_nid;
156 have_unknown = 0; 206 have_unknown = 0;
157 write_comma = 0; 207 write_comma = 0;
158 for (i = 0; i < sk_X509_ALGOR_num(mdalgs); i++) 208 for (i = 0; i < sk_X509_ALGOR_num(mdalgs); i++)
@@ -161,6 +211,21 @@ static int asn1_write_micalg(BIO *out, STACK_OF(X509_ALGOR) *mdalgs)
161 BIO_write(out, ",", 1); 211 BIO_write(out, ",", 1);
162 write_comma = 1; 212 write_comma = 1;
163 md_nid = OBJ_obj2nid(sk_X509_ALGOR_value(mdalgs, i)->algorithm); 213 md_nid = OBJ_obj2nid(sk_X509_ALGOR_value(mdalgs, i)->algorithm);
214 md = EVP_get_digestbynid(md_nid);
215 if (md && md->md_ctrl)
216 {
217 int rv;
218 char *micstr;
219 rv = md->md_ctrl(NULL, EVP_MD_CTRL_MICALG, 0, &micstr);
220 if (rv > 0)
221 {
222 BIO_puts(out, micstr);
223 OPENSSL_free(micstr);
224 continue;
225 }
226 if (rv != -2)
227 goto err;
228 }
164 switch(md_nid) 229 switch(md_nid)
165 { 230 {
166 case NID_sha1: 231 case NID_sha1:
@@ -183,6 +248,11 @@ static int asn1_write_micalg(BIO *out, STACK_OF(X509_ALGOR) *mdalgs)
183 BIO_puts(out, "sha-512"); 248 BIO_puts(out, "sha-512");
184 break; 249 break;
185 250
251 case NID_id_GostR3411_94:
252 BIO_puts(out, "gostr3411-94");
253 goto err;
254 break;
255
186 default: 256 default:
187 if (have_unknown) 257 if (have_unknown)
188 write_comma = 0; 258 write_comma = 0;
@@ -196,16 +266,18 @@ static int asn1_write_micalg(BIO *out, STACK_OF(X509_ALGOR) *mdalgs)
196 } 266 }
197 } 267 }
198 268
199 return 1; 269 ret = 1;
270 err:
271
272 return ret;
200 273
201 } 274 }
202 275
203/* SMIME sender */ 276/* SMIME sender */
204 277
205int int_smime_write_ASN1(BIO *bio, ASN1_VALUE *val, BIO *data, int flags, 278int SMIME_write_ASN1(BIO *bio, ASN1_VALUE *val, BIO *data, int flags,
206 int ctype_nid, int econt_nid, 279 int ctype_nid, int econt_nid,
207 STACK_OF(X509_ALGOR) *mdalgs, 280 STACK_OF(X509_ALGOR) *mdalgs,
208 asn1_output_data_fn *data_fn,
209 const ASN1_ITEM *it) 281 const ASN1_ITEM *it)
210{ 282{
211 char bound[33], c; 283 char bound[33], c;
@@ -243,7 +315,7 @@ int int_smime_write_ASN1(BIO *bio, ASN1_VALUE *val, BIO *data, int flags,
243 mime_eol, mime_eol); 315 mime_eol, mime_eol);
244 /* Now write out the first part */ 316 /* Now write out the first part */
245 BIO_printf(bio, "------%s%s", bound, mime_eol); 317 BIO_printf(bio, "------%s%s", bound, mime_eol);
246 if (!data_fn(bio, data, val, flags, it)) 318 if (!asn1_output_data(bio, data, val, flags, it))
247 return 0; 319 return 0;
248 BIO_printf(bio, "%s------%s%s", mime_eol, bound, mime_eol); 320 BIO_printf(bio, "%s------%s%s", mime_eol, bound, mime_eol);
249 321
@@ -296,8 +368,6 @@ int int_smime_write_ASN1(BIO *bio, ASN1_VALUE *val, BIO *data, int flags,
296 return 1; 368 return 1;
297} 369}
298 370
299#if 0
300
301/* Handle output of ASN1 data */ 371/* Handle output of ASN1 data */
302 372
303 373
@@ -350,8 +420,6 @@ static int asn1_output_data(BIO *out, BIO *data, ASN1_VALUE *val, int flags,
350 420
351 } 421 }
352 422
353#endif
354
355/* SMIME reader: handle multipart/signed and opaque signing. 423/* SMIME reader: handle multipart/signed and opaque signing.
356 * in multipart case the content is placed in a memory BIO 424 * in multipart case the content is placed in a memory BIO
357 * pointed to by "bcont". In opaque this is set to NULL 425 * pointed to by "bcont". In opaque this is set to NULL
diff --git a/src/lib/libcrypto/asn1/asn_pack.c b/src/lib/libcrypto/asn1/asn_pack.c
index f1a5a05632..ad738217d7 100644
--- a/src/lib/libcrypto/asn1/asn_pack.c
+++ b/src/lib/libcrypto/asn1/asn_pack.c
@@ -66,10 +66,10 @@
66 66
67/* Turn an ASN1 encoded SEQUENCE OF into a STACK of structures */ 67/* Turn an ASN1 encoded SEQUENCE OF into a STACK of structures */
68 68
69STACK *ASN1_seq_unpack(const unsigned char *buf, int len, 69STACK_OF(OPENSSL_BLOCK) *ASN1_seq_unpack(const unsigned char *buf, int len,
70 d2i_of_void *d2i,void (*free_func)(void *)) 70 d2i_of_void *d2i, void (*free_func)(OPENSSL_BLOCK))
71{ 71{
72 STACK *sk; 72 STACK_OF(OPENSSL_BLOCK) *sk;
73 const unsigned char *pbuf; 73 const unsigned char *pbuf;
74 pbuf = buf; 74 pbuf = buf;
75 if (!(sk = d2i_ASN1_SET(NULL, &pbuf, len, d2i, free_func, 75 if (!(sk = d2i_ASN1_SET(NULL, &pbuf, len, d2i, free_func,
@@ -82,7 +82,7 @@ STACK *ASN1_seq_unpack(const unsigned char *buf, int len,
82 * OPENSSL_malloc'ed buffer 82 * OPENSSL_malloc'ed buffer
83 */ 83 */
84 84
85unsigned char *ASN1_seq_pack(STACK *safes, i2d_of_void *i2d, 85unsigned char *ASN1_seq_pack(STACK_OF(OPENSSL_BLOCK) *safes, i2d_of_void *i2d,
86 unsigned char **buf, int *len) 86 unsigned char **buf, int *len)
87{ 87{
88 int safelen; 88 int safelen;
diff --git a/src/lib/libcrypto/asn1/charmap.h b/src/lib/libcrypto/asn1/charmap.h
index bd020a9562..b55e638725 100644
--- a/src/lib/libcrypto/asn1/charmap.h
+++ b/src/lib/libcrypto/asn1/charmap.h
@@ -2,7 +2,7 @@
2 * Mask of various character properties 2 * Mask of various character properties
3 */ 3 */
4 4
5static unsigned char char_type[] = { 5static const unsigned char char_type[] = {
6 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 6 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
7 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 7 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
8120, 0, 1,40, 0, 0, 0,16,16,16, 0,25,25,16,16,16, 8120, 0, 1,40, 0, 0, 0,16,16,16, 0,25,25,16,16,16,
diff --git a/src/lib/libcrypto/asn1/d2i_pr.c b/src/lib/libcrypto/asn1/d2i_pr.c
index 207ccda5ac..2828944777 100644
--- a/src/lib/libcrypto/asn1/d2i_pr.c
+++ b/src/lib/libcrypto/asn1/d2i_pr.c
@@ -61,16 +61,12 @@
61#include <openssl/bn.h> 61#include <openssl/bn.h>
62#include <openssl/evp.h> 62#include <openssl/evp.h>
63#include <openssl/objects.h> 63#include <openssl/objects.h>
64#include <openssl/asn1.h> 64#ifndef OPENSSL_NO_ENGINE
65#ifndef OPENSSL_NO_RSA 65#include <openssl/engine.h>
66#include <openssl/rsa.h>
67#endif
68#ifndef OPENSSL_NO_DSA
69#include <openssl/dsa.h>
70#endif
71#ifndef OPENSSL_NO_EC
72#include <openssl/ec.h>
73#endif 66#endif
67#include <openssl/x509.h>
68#include <openssl/asn1.h>
69#include "asn1_locl.h"
74 70
75EVP_PKEY *d2i_PrivateKey(int type, EVP_PKEY **a, const unsigned char **pp, 71EVP_PKEY *d2i_PrivateKey(int type, EVP_PKEY **a, const unsigned char **pp,
76 long length) 72 long length)
@@ -85,47 +81,43 @@ EVP_PKEY *d2i_PrivateKey(int type, EVP_PKEY **a, const unsigned char **pp,
85 return(NULL); 81 return(NULL);
86 } 82 }
87 } 83 }
88 else ret= *a; 84 else
89
90 ret->save_type=type;
91 ret->type=EVP_PKEY_type(type);
92 switch (ret->type)
93 { 85 {
94#ifndef OPENSSL_NO_RSA 86 ret= *a;
95 case EVP_PKEY_RSA: 87#ifndef OPENSSL_NO_ENGINE
96 if ((ret->pkey.rsa=d2i_RSAPrivateKey(NULL, 88 if (ret->engine)
97 (const unsigned char **)pp,length)) == NULL) /* TMP UGLY CAST */
98 { 89 {
99 ASN1err(ASN1_F_D2I_PRIVATEKEY,ERR_R_ASN1_LIB); 90 ENGINE_finish(ret->engine);
100 goto err; 91 ret->engine = NULL;
101 } 92 }
102 break;
103#endif 93#endif
104#ifndef OPENSSL_NO_DSA 94 }
105 case EVP_PKEY_DSA: 95
106 if ((ret->pkey.dsa=d2i_DSAPrivateKey(NULL, 96 if (!EVP_PKEY_set_type(ret, type))
107 (const unsigned char **)pp,length)) == NULL) /* TMP UGLY CAST */ 97 {
98 ASN1err(ASN1_F_D2I_PRIVATEKEY,ASN1_R_UNKNOWN_PUBLIC_KEY_TYPE);
99 goto err;
100 }
101
102 if (!ret->ameth->old_priv_decode ||
103 !ret->ameth->old_priv_decode(ret, pp, length))
104 {
105 if (ret->ameth->priv_decode)
108 { 106 {
109 ASN1err(ASN1_F_D2I_PRIVATEKEY,ERR_R_ASN1_LIB); 107 PKCS8_PRIV_KEY_INFO *p8=NULL;
110 goto err; 108 p8=d2i_PKCS8_PRIV_KEY_INFO(NULL,pp,length);
111 } 109 if (!p8) goto err;
112 break; 110 EVP_PKEY_free(ret);
113#endif 111 ret = EVP_PKCS82PKEY(p8);
114#ifndef OPENSSL_NO_EC 112 PKCS8_PRIV_KEY_INFO_free(p8);
115 case EVP_PKEY_EC: 113
116 if ((ret->pkey.ec = d2i_ECPrivateKey(NULL, 114 }
117 (const unsigned char **)pp, length)) == NULL) 115 else
118 { 116 {
119 ASN1err(ASN1_F_D2I_PRIVATEKEY, ERR_R_ASN1_LIB); 117 ASN1err(ASN1_F_D2I_PRIVATEKEY,ERR_R_ASN1_LIB);
120 goto err; 118 goto err;
121 } 119 }
122 break; 120 }
123#endif
124 default:
125 ASN1err(ASN1_F_D2I_PRIVATEKEY,ASN1_R_UNKNOWN_PUBLIC_KEY_TYPE);
126 goto err;
127 /* break; */
128 }
129 if (a != NULL) (*a)=ret; 121 if (a != NULL) (*a)=ret;
130 return(ret); 122 return(ret);
131err: 123err:
@@ -146,8 +138,7 @@ EVP_PKEY *d2i_AutoPrivateKey(EVP_PKEY **a, const unsigned char **pp,
146 * by analyzing it we can determine the passed structure: this 138 * by analyzing it we can determine the passed structure: this
147 * assumes the input is surrounded by an ASN1 SEQUENCE. 139 * assumes the input is surrounded by an ASN1 SEQUENCE.
148 */ 140 */
149 inkey = d2i_ASN1_SET_OF_ASN1_TYPE(NULL, &p, length, d2i_ASN1_TYPE, 141 inkey = d2i_ASN1_SEQUENCE_ANY(NULL, &p, length);
150 ASN1_TYPE_free, V_ASN1_SEQUENCE, V_ASN1_UNIVERSAL);
151 /* Since we only need to discern "traditional format" RSA and DSA 142 /* Since we only need to discern "traditional format" RSA and DSA
152 * keys we can just count the elements. 143 * keys we can just count the elements.
153 */ 144 */
@@ -155,6 +146,24 @@ EVP_PKEY *d2i_AutoPrivateKey(EVP_PKEY **a, const unsigned char **pp,
155 keytype = EVP_PKEY_DSA; 146 keytype = EVP_PKEY_DSA;
156 else if (sk_ASN1_TYPE_num(inkey) == 4) 147 else if (sk_ASN1_TYPE_num(inkey) == 4)
157 keytype = EVP_PKEY_EC; 148 keytype = EVP_PKEY_EC;
149 else if (sk_ASN1_TYPE_num(inkey) == 3)
150 { /* This seems to be PKCS8, not traditional format */
151 PKCS8_PRIV_KEY_INFO *p8 = d2i_PKCS8_PRIV_KEY_INFO(NULL,pp,length);
152 EVP_PKEY *ret;
153
154 sk_ASN1_TYPE_pop_free(inkey, ASN1_TYPE_free);
155 if (!p8)
156 {
157 ASN1err(ASN1_F_D2I_AUTOPRIVATEKEY,ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE);
158 return NULL;
159 }
160 ret = EVP_PKCS82PKEY(p8);
161 PKCS8_PRIV_KEY_INFO_free(p8);
162 if (a) {
163 *a = ret;
164 }
165 return ret;
166 }
158 else keytype = EVP_PKEY_RSA; 167 else keytype = EVP_PKEY_RSA;
159 sk_ASN1_TYPE_pop_free(inkey, ASN1_TYPE_free); 168 sk_ASN1_TYPE_pop_free(inkey, ASN1_TYPE_free);
160 return d2i_PrivateKey(keytype, a, pp, length); 169 return d2i_PrivateKey(keytype, a, pp, length);
diff --git a/src/lib/libcrypto/asn1/d2i_pu.c b/src/lib/libcrypto/asn1/d2i_pu.c
index 3694f51a8c..c8f39ceb03 100644
--- a/src/lib/libcrypto/asn1/d2i_pu.c
+++ b/src/lib/libcrypto/asn1/d2i_pu.c
@@ -87,9 +87,13 @@ EVP_PKEY *d2i_PublicKey(int type, EVP_PKEY **a, const unsigned char **pp,
87 } 87 }
88 else ret= *a; 88 else ret= *a;
89 89
90 ret->save_type=type; 90 if (!EVP_PKEY_set_type(ret, type))
91 ret->type=EVP_PKEY_type(type); 91 {
92 switch (ret->type) 92 ASN1err(ASN1_F_D2I_PUBLICKEY,ERR_R_EVP_LIB);
93 goto err;
94 }
95
96 switch (EVP_PKEY_id(ret))
93 { 97 {
94#ifndef OPENSSL_NO_RSA 98#ifndef OPENSSL_NO_RSA
95 case EVP_PKEY_RSA: 99 case EVP_PKEY_RSA:
diff --git a/src/lib/libcrypto/asn1/i2d_pr.c b/src/lib/libcrypto/asn1/i2d_pr.c
index 0be52c5b76..e398b62666 100644
--- a/src/lib/libcrypto/asn1/i2d_pr.c
+++ b/src/lib/libcrypto/asn1/i2d_pr.c
@@ -58,41 +58,22 @@
58 58
59#include <stdio.h> 59#include <stdio.h>
60#include "cryptlib.h" 60#include "cryptlib.h"
61#include <openssl/bn.h>
62#include <openssl/evp.h> 61#include <openssl/evp.h>
63#include <openssl/objects.h> 62#include <openssl/x509.h>
64#ifndef OPENSSL_NO_RSA 63#include "asn1_locl.h"
65#include <openssl/rsa.h>
66#endif
67#ifndef OPENSSL_NO_DSA
68#include <openssl/dsa.h>
69#endif
70#ifndef OPENSSL_NO_EC
71#include <openssl/ec.h>
72#endif
73 64
74int i2d_PrivateKey(EVP_PKEY *a, unsigned char **pp) 65int i2d_PrivateKey(EVP_PKEY *a, unsigned char **pp)
75 { 66 {
76#ifndef OPENSSL_NO_RSA 67 if (a->ameth && a->ameth->old_priv_encode)
77 if (a->type == EVP_PKEY_RSA)
78 { 68 {
79 return(i2d_RSAPrivateKey(a->pkey.rsa,pp)); 69 return a->ameth->old_priv_encode(a, pp);
80 } 70 }
81 else 71 if (a->ameth && a->ameth->priv_encode) {
82#endif 72 PKCS8_PRIV_KEY_INFO *p8 = EVP_PKEY2PKCS8(a);
83#ifndef OPENSSL_NO_DSA 73 int ret = i2d_PKCS8_PRIV_KEY_INFO(p8,pp);
84 if (a->type == EVP_PKEY_DSA) 74 PKCS8_PRIV_KEY_INFO_free(p8);
85 { 75 return ret;
86 return(i2d_DSAPrivateKey(a->pkey.dsa,pp)); 76 }
87 }
88#endif
89#ifndef OPENSSL_NO_EC
90 if (a->type == EVP_PKEY_EC)
91 {
92 return(i2d_ECPrivateKey(a->pkey.ec, pp));
93 }
94#endif
95
96 ASN1err(ASN1_F_I2D_PRIVATEKEY,ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE); 77 ASN1err(ASN1_F_I2D_PRIVATEKEY,ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE);
97 return(-1); 78 return(-1);
98 } 79 }
diff --git a/src/lib/libcrypto/asn1/nsseq.c b/src/lib/libcrypto/asn1/nsseq.c
index e551c57d59..b8c4202230 100644
--- a/src/lib/libcrypto/asn1/nsseq.c
+++ b/src/lib/libcrypto/asn1/nsseq.c
@@ -3,7 +3,7 @@
3 * project 1999. 3 * project 1999.
4 */ 4 */
5/* ==================================================================== 5/* ====================================================================
6 * Copyright (c) 1999 The OpenSSL Project. All rights reserved. 6 * Copyright (c) 1999-2005 The OpenSSL Project. All rights reserved.
7 * 7 *
8 * Redistribution and use in source and binary forms, with or without 8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions 9 * modification, are permitted provided that the following conditions
@@ -62,7 +62,8 @@
62#include <openssl/x509.h> 62#include <openssl/x509.h>
63#include <openssl/objects.h> 63#include <openssl/objects.h>
64 64
65static int nsseq_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it) 65static int nsseq_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
66 void *exarg)
66{ 67{
67 if(operation == ASN1_OP_NEW_POST) { 68 if(operation == ASN1_OP_NEW_POST) {
68 NETSCAPE_CERT_SEQUENCE *nsseq; 69 NETSCAPE_CERT_SEQUENCE *nsseq;
diff --git a/src/lib/libcrypto/asn1/p5_pbe.c b/src/lib/libcrypto/asn1/p5_pbe.c
index c4582f8041..94bc38b99f 100644
--- a/src/lib/libcrypto/asn1/p5_pbe.c
+++ b/src/lib/libcrypto/asn1/p5_pbe.c
@@ -71,61 +71,78 @@ ASN1_SEQUENCE(PBEPARAM) = {
71 71
72IMPLEMENT_ASN1_FUNCTIONS(PBEPARAM) 72IMPLEMENT_ASN1_FUNCTIONS(PBEPARAM)
73 73
74/* Return an algorithm identifier for a PKCS#5 PBE algorithm */
75 74
76X509_ALGOR *PKCS5_pbe_set(int alg, int iter, unsigned char *salt, 75/* Set an algorithm identifier for a PKCS#5 PBE algorithm */
77 int saltlen) 76
78{ 77int PKCS5_pbe_set0_algor(X509_ALGOR *algor, int alg, int iter,
78 const unsigned char *salt, int saltlen)
79 {
79 PBEPARAM *pbe=NULL; 80 PBEPARAM *pbe=NULL;
80 ASN1_OBJECT *al; 81 ASN1_STRING *pbe_str=NULL;
81 X509_ALGOR *algor; 82 unsigned char *sstr;
82 ASN1_TYPE *astype=NULL;
83 83
84 if (!(pbe = PBEPARAM_new ())) { 84 pbe = PBEPARAM_new();
85 ASN1err(ASN1_F_PKCS5_PBE_SET,ERR_R_MALLOC_FAILURE); 85 if (!pbe)
86 {
87 ASN1err(ASN1_F_PKCS5_PBE_SET0_ALGOR,ERR_R_MALLOC_FAILURE);
86 goto err; 88 goto err;
87 } 89 }
88 if(iter <= 0) iter = PKCS5_DEFAULT_ITER; 90 if(iter <= 0)
89 if (!ASN1_INTEGER_set(pbe->iter, iter)) { 91 iter = PKCS5_DEFAULT_ITER;
90 ASN1err(ASN1_F_PKCS5_PBE_SET,ERR_R_MALLOC_FAILURE); 92 if (!ASN1_INTEGER_set(pbe->iter, iter))
93 {
94 ASN1err(ASN1_F_PKCS5_PBE_SET0_ALGOR,ERR_R_MALLOC_FAILURE);
91 goto err; 95 goto err;
92 } 96 }
93 if (!saltlen) saltlen = PKCS5_SALT_LEN; 97 if (!saltlen)
94 if (!(pbe->salt->data = OPENSSL_malloc (saltlen))) { 98 saltlen = PKCS5_SALT_LEN;
95 ASN1err(ASN1_F_PKCS5_PBE_SET,ERR_R_MALLOC_FAILURE); 99 if (!ASN1_STRING_set(pbe->salt, NULL, saltlen))
100 {
101 ASN1err(ASN1_F_PKCS5_PBE_SET0_ALGOR,ERR_R_MALLOC_FAILURE);
96 goto err; 102 goto err;
97 } 103 }
98 pbe->salt->length = saltlen; 104 sstr = ASN1_STRING_data(pbe->salt);
99 if (salt) memcpy (pbe->salt->data, salt, saltlen); 105 if (salt)
100 else if (RAND_pseudo_bytes (pbe->salt->data, saltlen) < 0) 106 memcpy(sstr, salt, saltlen);
107 else if (RAND_pseudo_bytes(sstr, saltlen) < 0)
101 goto err; 108 goto err;
102 109
103 if (!(astype = ASN1_TYPE_new())) { 110 if(!ASN1_item_pack(pbe, ASN1_ITEM_rptr(PBEPARAM), &pbe_str))
104 ASN1err(ASN1_F_PKCS5_PBE_SET,ERR_R_MALLOC_FAILURE); 111 {
112 ASN1err(ASN1_F_PKCS5_PBE_SET0_ALGOR,ERR_R_MALLOC_FAILURE);
105 goto err; 113 goto err;
106 } 114 }
107 115
108 astype->type = V_ASN1_SEQUENCE; 116 PBEPARAM_free(pbe);
109 if(!ASN1_pack_string_of(PBEPARAM, pbe, i2d_PBEPARAM,
110 &astype->value.sequence)) {
111 ASN1err(ASN1_F_PKCS5_PBE_SET,ERR_R_MALLOC_FAILURE);
112 goto err;
113 }
114 PBEPARAM_free (pbe);
115 pbe = NULL; 117 pbe = NULL;
116
117 al = OBJ_nid2obj(alg); /* never need to free al */
118 if (!(algor = X509_ALGOR_new())) {
119 ASN1err(ASN1_F_PKCS5_PBE_SET,ERR_R_MALLOC_FAILURE);
120 goto err;
121 }
122 ASN1_OBJECT_free(algor->algorithm);
123 algor->algorithm = al;
124 algor->parameter = astype;
125 118
126 return (algor); 119 if (X509_ALGOR_set0(algor, OBJ_nid2obj(alg), V_ASN1_SEQUENCE, pbe_str))
120 return 1;
121
127err: 122err:
128 if (pbe != NULL) PBEPARAM_free(pbe); 123 if (pbe != NULL)
129 if (astype != NULL) ASN1_TYPE_free(astype); 124 PBEPARAM_free(pbe);
125 if (pbe_str != NULL)
126 ASN1_STRING_free(pbe_str);
127 return 0;
128 }
129
130/* Return an algorithm identifier for a PKCS#5 PBE algorithm */
131
132X509_ALGOR *PKCS5_pbe_set(int alg, int iter,
133 const unsigned char *salt, int saltlen)
134 {
135 X509_ALGOR *ret;
136 ret = X509_ALGOR_new();
137 if (!ret)
138 {
139 ASN1err(ASN1_F_PKCS5_PBE_SET,ERR_R_MALLOC_FAILURE);
140 return NULL;
141 }
142
143 if (PKCS5_pbe_set0_algor(ret, alg, iter, salt, saltlen))
144 return ret;
145
146 X509_ALGOR_free(ret);
130 return NULL; 147 return NULL;
131} 148 }
diff --git a/src/lib/libcrypto/asn1/p5_pbev2.c b/src/lib/libcrypto/asn1/p5_pbev2.c
index 2b0516afee..cb49b6651d 100644
--- a/src/lib/libcrypto/asn1/p5_pbev2.c
+++ b/src/lib/libcrypto/asn1/p5_pbev2.c
@@ -82,10 +82,13 @@ IMPLEMENT_ASN1_FUNCTIONS(PBKDF2PARAM)
82 82
83/* Return an algorithm identifier for a PKCS#5 v2.0 PBE algorithm: 83/* Return an algorithm identifier for a PKCS#5 v2.0 PBE algorithm:
84 * yes I know this is horrible! 84 * yes I know this is horrible!
85 *
86 * Extended version to allow application supplied PRF NID and IV.
85 */ 87 */
86 88
87X509_ALGOR *PKCS5_pbe2_set(const EVP_CIPHER *cipher, int iter, 89X509_ALGOR *PKCS5_pbe2_set_iv(const EVP_CIPHER *cipher, int iter,
88 unsigned char *salt, int saltlen) 90 unsigned char *salt, int saltlen,
91 unsigned char *aiv, int prf_nid)
89{ 92{
90 X509_ALGOR *scheme = NULL, *kalg = NULL, *ret = NULL; 93 X509_ALGOR *scheme = NULL, *kalg = NULL, *ret = NULL;
91 int alg_nid; 94 int alg_nid;
@@ -98,7 +101,7 @@ X509_ALGOR *PKCS5_pbe2_set(const EVP_CIPHER *cipher, int iter,
98 101
99 alg_nid = EVP_CIPHER_type(cipher); 102 alg_nid = EVP_CIPHER_type(cipher);
100 if(alg_nid == NID_undef) { 103 if(alg_nid == NID_undef) {
101 ASN1err(ASN1_F_PKCS5_PBE2_SET, 104 ASN1err(ASN1_F_PKCS5_PBE2_SET_IV,
102 ASN1_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER); 105 ASN1_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER);
103 goto err; 106 goto err;
104 } 107 }
@@ -113,20 +116,33 @@ X509_ALGOR *PKCS5_pbe2_set(const EVP_CIPHER *cipher, int iter,
113 if(!(scheme->parameter = ASN1_TYPE_new())) goto merr; 116 if(!(scheme->parameter = ASN1_TYPE_new())) goto merr;
114 117
115 /* Create random IV */ 118 /* Create random IV */
116 if (EVP_CIPHER_iv_length(cipher) && 119 if (EVP_CIPHER_iv_length(cipher))
117 RAND_pseudo_bytes(iv, EVP_CIPHER_iv_length(cipher)) < 0) 120 {
118 goto err; 121 if (aiv)
122 memcpy(iv, aiv, EVP_CIPHER_iv_length(cipher));
123 else if (RAND_pseudo_bytes(iv, EVP_CIPHER_iv_length(cipher)) < 0)
124 goto err;
125 }
119 126
120 EVP_CIPHER_CTX_init(&ctx); 127 EVP_CIPHER_CTX_init(&ctx);
121 128
122 /* Dummy cipherinit to just setup the IV */ 129 /* Dummy cipherinit to just setup the IV, and PRF */
123 EVP_CipherInit_ex(&ctx, cipher, NULL, NULL, iv, 0); 130 EVP_CipherInit_ex(&ctx, cipher, NULL, NULL, iv, 0);
124 if(EVP_CIPHER_param_to_asn1(&ctx, scheme->parameter) < 0) { 131 if(EVP_CIPHER_param_to_asn1(&ctx, scheme->parameter) < 0) {
125 ASN1err(ASN1_F_PKCS5_PBE2_SET, 132 ASN1err(ASN1_F_PKCS5_PBE2_SET_IV,
126 ASN1_R_ERROR_SETTING_CIPHER_PARAMS); 133 ASN1_R_ERROR_SETTING_CIPHER_PARAMS);
127 EVP_CIPHER_CTX_cleanup(&ctx); 134 EVP_CIPHER_CTX_cleanup(&ctx);
128 goto err; 135 goto err;
129 } 136 }
137 /* If prf NID unspecified see if cipher has a preference.
138 * An error is OK here: just means use default PRF.
139 */
140 if ((prf_nid == -1) &&
141 EVP_CIPHER_CTX_ctrl(&ctx, EVP_CTRL_PBE_PRF_NID, 0, &prf_nid) <= 0)
142 {
143 ERR_clear_error();
144 prf_nid = NID_hmacWithSHA1;
145 }
130 EVP_CIPHER_CTX_cleanup(&ctx); 146 EVP_CIPHER_CTX_cleanup(&ctx);
131 147
132 if(!(kdf = PBKDF2PARAM_new())) goto merr; 148 if(!(kdf = PBKDF2PARAM_new())) goto merr;
@@ -154,7 +170,15 @@ X509_ALGOR *PKCS5_pbe2_set(const EVP_CIPHER *cipher, int iter,
154 EVP_CIPHER_key_length(cipher))) goto merr; 170 EVP_CIPHER_key_length(cipher))) goto merr;
155 } 171 }
156 172
157 /* prf can stay NULL because we are using hmacWithSHA1 */ 173 /* prf can stay NULL if we are using hmacWithSHA1 */
174 if (prf_nid != NID_hmacWithSHA1)
175 {
176 kdf->prf = X509_ALGOR_new();
177 if (!kdf->prf)
178 goto merr;
179 X509_ALGOR_set0(kdf->prf, OBJ_nid2obj(prf_nid),
180 V_ASN1_NULL, NULL);
181 }
158 182
159 /* Now setup the PBE2PARAM keyfunc structure */ 183 /* Now setup the PBE2PARAM keyfunc structure */
160 184
@@ -164,7 +188,7 @@ X509_ALGOR *PKCS5_pbe2_set(const EVP_CIPHER *cipher, int iter,
164 188
165 if(!(pbe2->keyfunc->parameter = ASN1_TYPE_new())) goto merr; 189 if(!(pbe2->keyfunc->parameter = ASN1_TYPE_new())) goto merr;
166 190
167 if(!ASN1_pack_string_of(PBKDF2PARAM, kdf, i2d_PBKDF2PARAM, 191 if(!ASN1_item_pack(kdf, ASN1_ITEM_rptr(PBKDF2PARAM),
168 &pbe2->keyfunc->parameter->value.sequence)) goto merr; 192 &pbe2->keyfunc->parameter->value.sequence)) goto merr;
169 pbe2->keyfunc->parameter->type = V_ASN1_SEQUENCE; 193 pbe2->keyfunc->parameter->type = V_ASN1_SEQUENCE;
170 194
@@ -180,7 +204,7 @@ X509_ALGOR *PKCS5_pbe2_set(const EVP_CIPHER *cipher, int iter,
180 204
181 /* Encode PBE2PARAM into parameter */ 205 /* Encode PBE2PARAM into parameter */
182 206
183 if(!ASN1_pack_string_of(PBE2PARAM, pbe2, i2d_PBE2PARAM, 207 if(!ASN1_item_pack(pbe2, ASN1_ITEM_rptr(PBE2PARAM),
184 &ret->parameter->value.sequence)) goto merr; 208 &ret->parameter->value.sequence)) goto merr;
185 ret->parameter->type = V_ASN1_SEQUENCE; 209 ret->parameter->type = V_ASN1_SEQUENCE;
186 210
@@ -190,7 +214,7 @@ X509_ALGOR *PKCS5_pbe2_set(const EVP_CIPHER *cipher, int iter,
190 return ret; 214 return ret;
191 215
192 merr: 216 merr:
193 ASN1err(ASN1_F_PKCS5_PBE2_SET,ERR_R_MALLOC_FAILURE); 217 ASN1err(ASN1_F_PKCS5_PBE2_SET_IV,ERR_R_MALLOC_FAILURE);
194 218
195 err: 219 err:
196 PBE2PARAM_free(pbe2); 220 PBE2PARAM_free(pbe2);
@@ -203,3 +227,9 @@ X509_ALGOR *PKCS5_pbe2_set(const EVP_CIPHER *cipher, int iter,
203 return NULL; 227 return NULL;
204 228
205} 229}
230
231X509_ALGOR *PKCS5_pbe2_set(const EVP_CIPHER *cipher, int iter,
232 unsigned char *salt, int saltlen)
233 {
234 return PKCS5_pbe2_set_iv(cipher, iter, salt, saltlen, NULL, -1);
235 }
diff --git a/src/lib/libcrypto/asn1/p8_pkey.c b/src/lib/libcrypto/asn1/p8_pkey.c
index 0a1957556e..17b68d386d 100644
--- a/src/lib/libcrypto/asn1/p8_pkey.c
+++ b/src/lib/libcrypto/asn1/p8_pkey.c
@@ -3,7 +3,7 @@
3 * project 1999. 3 * project 1999.
4 */ 4 */
5/* ==================================================================== 5/* ====================================================================
6 * Copyright (c) 1999 The OpenSSL Project. All rights reserved. 6 * Copyright (c) 1999-2005 The OpenSSL Project. All rights reserved.
7 * 7 *
8 * Redistribution and use in source and binary forms, with or without 8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions 9 * modification, are permitted provided that the following conditions
@@ -62,7 +62,8 @@
62#include <openssl/x509.h> 62#include <openssl/x509.h>
63 63
64/* Minor tweak to operation: zero private key data */ 64/* Minor tweak to operation: zero private key data */
65static int pkey_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it) 65static int pkey_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
66 void *exarg)
66{ 67{
67 /* Since the structure must still be valid use ASN1_OP_FREE_PRE */ 68 /* Since the structure must still be valid use ASN1_OP_FREE_PRE */
68 if(operation == ASN1_OP_FREE_PRE) { 69 if(operation == ASN1_OP_FREE_PRE) {
@@ -82,3 +83,73 @@ ASN1_SEQUENCE_cb(PKCS8_PRIV_KEY_INFO, pkey_cb) = {
82} ASN1_SEQUENCE_END_cb(PKCS8_PRIV_KEY_INFO, PKCS8_PRIV_KEY_INFO) 83} ASN1_SEQUENCE_END_cb(PKCS8_PRIV_KEY_INFO, PKCS8_PRIV_KEY_INFO)
83 84
84IMPLEMENT_ASN1_FUNCTIONS(PKCS8_PRIV_KEY_INFO) 85IMPLEMENT_ASN1_FUNCTIONS(PKCS8_PRIV_KEY_INFO)
86
87int PKCS8_pkey_set0(PKCS8_PRIV_KEY_INFO *priv, ASN1_OBJECT *aobj,
88 int version,
89 int ptype, void *pval,
90 unsigned char *penc, int penclen)
91 {
92 unsigned char **ppenc = NULL;
93 if (version >= 0)
94 {
95 if (!ASN1_INTEGER_set(priv->version, version))
96 return 0;
97 }
98 if (penc)
99 {
100 int pmtype;
101 ASN1_OCTET_STRING *oct;
102 oct = ASN1_OCTET_STRING_new();
103 if (!oct)
104 return 0;
105 oct->data = penc;
106 ppenc = &oct->data;
107 oct->length = penclen;
108 if (priv->broken == PKCS8_NO_OCTET)
109 pmtype = V_ASN1_SEQUENCE;
110 else
111 pmtype = V_ASN1_OCTET_STRING;
112 ASN1_TYPE_set(priv->pkey, pmtype, oct);
113 }
114 if (!X509_ALGOR_set0(priv->pkeyalg, aobj, ptype, pval))
115 {
116 /* If call fails do not swallow 'enc' */
117 if (ppenc)
118 *ppenc = NULL;
119 return 0;
120 }
121 return 1;
122 }
123
124int PKCS8_pkey_get0(ASN1_OBJECT **ppkalg,
125 const unsigned char **pk, int *ppklen,
126 X509_ALGOR **pa,
127 PKCS8_PRIV_KEY_INFO *p8)
128 {
129 if (ppkalg)
130 *ppkalg = p8->pkeyalg->algorithm;
131 if(p8->pkey->type == V_ASN1_OCTET_STRING)
132 {
133 p8->broken = PKCS8_OK;
134 if (pk)
135 {
136 *pk = p8->pkey->value.octet_string->data;
137 *ppklen = p8->pkey->value.octet_string->length;
138 }
139 }
140 else if (p8->pkey->type == V_ASN1_SEQUENCE)
141 {
142 p8->broken = PKCS8_NO_OCTET;
143 if (pk)
144 {
145 *pk = p8->pkey->value.sequence->data;
146 *ppklen = p8->pkey->value.sequence->length;
147 }
148 }
149 else
150 return 0;
151 if (pa)
152 *pa = p8->pkeyalg;
153 return 1;
154 }
155
diff --git a/src/lib/libcrypto/asn1/t_pkey.c b/src/lib/libcrypto/asn1/t_pkey.c
index afb95d6712..9dd18f6579 100644
--- a/src/lib/libcrypto/asn1/t_pkey.c
+++ b/src/lib/libcrypto/asn1/t_pkey.c
@@ -55,520 +55,15 @@
55 * copied and put under another distribution licence 55 * copied and put under another distribution licence
56 * [including the GNU Public Licence.] 56 * [including the GNU Public Licence.]
57 */ 57 */
58/* ====================================================================
59 * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
60 * Binary polynomial ECC support in OpenSSL originally developed by
61 * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
62 */
63 58
64#include <stdio.h> 59#include <stdio.h>
65#include "cryptlib.h" 60#include "cryptlib.h"
66#include <openssl/objects.h> 61#include <openssl/objects.h>
67#include <openssl/buffer.h> 62#include <openssl/buffer.h>
68#include <openssl/bn.h> 63#include <openssl/bn.h>
69#ifndef OPENSSL_NO_RSA
70#include <openssl/rsa.h>
71#endif
72#ifndef OPENSSL_NO_DH
73#include <openssl/dh.h>
74#endif
75#ifndef OPENSSL_NO_DSA
76#include <openssl/dsa.h>
77#endif
78#ifndef OPENSSL_NO_EC
79#include <openssl/ec.h>
80#endif
81
82static int print(BIO *fp,const char *str, const BIGNUM *num,
83 unsigned char *buf,int off);
84#ifndef OPENSSL_NO_EC
85static int print_bin(BIO *fp, const char *str, const unsigned char *num,
86 size_t len, int off);
87#endif
88#ifndef OPENSSL_NO_RSA
89#ifndef OPENSSL_NO_FP_API
90int RSA_print_fp(FILE *fp, const RSA *x, int off)
91 {
92 BIO *b;
93 int ret;
94
95 if ((b=BIO_new(BIO_s_file())) == NULL)
96 {
97 RSAerr(RSA_F_RSA_PRINT_FP,ERR_R_BUF_LIB);
98 return(0);
99 }
100 BIO_set_fp(b,fp,BIO_NOCLOSE);
101 ret=RSA_print(b,x,off);
102 BIO_free(b);
103 return(ret);
104 }
105#endif
106
107int RSA_print(BIO *bp, const RSA *x, int off)
108 {
109 char str[128];
110 const char *s;
111 unsigned char *m=NULL;
112 int ret=0, mod_len = 0;
113 size_t buf_len=0, i;
114
115 if (x->n)
116 buf_len = (size_t)BN_num_bytes(x->n);
117 if (x->e)
118 if (buf_len < (i = (size_t)BN_num_bytes(x->e)))
119 buf_len = i;
120 if (x->d)
121 if (buf_len < (i = (size_t)BN_num_bytes(x->d)))
122 buf_len = i;
123 if (x->p)
124 if (buf_len < (i = (size_t)BN_num_bytes(x->p)))
125 buf_len = i;
126 if (x->q)
127 if (buf_len < (i = (size_t)BN_num_bytes(x->q)))
128 buf_len = i;
129 if (x->dmp1)
130 if (buf_len < (i = (size_t)BN_num_bytes(x->dmp1)))
131 buf_len = i;
132 if (x->dmq1)
133 if (buf_len < (i = (size_t)BN_num_bytes(x->dmq1)))
134 buf_len = i;
135 if (x->iqmp)
136 if (buf_len < (i = (size_t)BN_num_bytes(x->iqmp)))
137 buf_len = i;
138
139 m=(unsigned char *)OPENSSL_malloc(buf_len+10);
140 if (m == NULL)
141 {
142 RSAerr(RSA_F_RSA_PRINT,ERR_R_MALLOC_FAILURE);
143 goto err;
144 }
145
146 if (x->n != NULL)
147 mod_len = BN_num_bits(x->n);
148
149 if (x->d != NULL)
150 {
151 if(!BIO_indent(bp,off,128))
152 goto err;
153 if (BIO_printf(bp,"Private-Key: (%d bit)\n", mod_len)
154 <= 0) goto err;
155 }
156
157 if (x->d == NULL)
158 BIO_snprintf(str,sizeof str,"Modulus (%d bit):", mod_len);
159 else
160 BUF_strlcpy(str,"modulus:",sizeof str);
161 if (!print(bp,str,x->n,m,off)) goto err;
162 s=(x->d == NULL)?"Exponent:":"publicExponent:";
163 if ((x->e != NULL) && !print(bp,s,x->e,m,off))
164 goto err;
165 if ((x->d != NULL) && !print(bp,"privateExponent:",x->d,m,off))
166 goto err;
167 if ((x->p != NULL) && !print(bp,"prime1:",x->p,m,off))
168 goto err;
169 if ((x->q != NULL) && !print(bp,"prime2:",x->q,m,off))
170 goto err;
171 if ((x->dmp1 != NULL) && !print(bp,"exponent1:",x->dmp1,m,off))
172 goto err;
173 if ((x->dmq1 != NULL) && !print(bp,"exponent2:",x->dmq1,m,off))
174 goto err;
175 if ((x->iqmp != NULL) && !print(bp,"coefficient:",x->iqmp,m,off))
176 goto err;
177 ret=1;
178err:
179 if (m != NULL) OPENSSL_free(m);
180 return(ret);
181 }
182#endif /* OPENSSL_NO_RSA */
183
184#ifndef OPENSSL_NO_DSA
185#ifndef OPENSSL_NO_FP_API
186int DSA_print_fp(FILE *fp, const DSA *x, int off)
187 {
188 BIO *b;
189 int ret;
190
191 if ((b=BIO_new(BIO_s_file())) == NULL)
192 {
193 DSAerr(DSA_F_DSA_PRINT_FP,ERR_R_BUF_LIB);
194 return(0);
195 }
196 BIO_set_fp(b,fp,BIO_NOCLOSE);
197 ret=DSA_print(b,x,off);
198 BIO_free(b);
199 return(ret);
200 }
201#endif
202
203int DSA_print(BIO *bp, const DSA *x, int off)
204 {
205 unsigned char *m=NULL;
206 int ret=0;
207 size_t buf_len=0,i;
208
209 if (x->p)
210 buf_len = (size_t)BN_num_bytes(x->p);
211 else
212 {
213 DSAerr(DSA_F_DSA_PRINT,DSA_R_MISSING_PARAMETERS);
214 goto err;
215 }
216 if (x->q)
217 if (buf_len < (i = (size_t)BN_num_bytes(x->q)))
218 buf_len = i;
219 if (x->g)
220 if (buf_len < (i = (size_t)BN_num_bytes(x->g)))
221 buf_len = i;
222 if (x->priv_key)
223 if (buf_len < (i = (size_t)BN_num_bytes(x->priv_key)))
224 buf_len = i;
225 if (x->pub_key)
226 if (buf_len < (i = (size_t)BN_num_bytes(x->pub_key)))
227 buf_len = i;
228
229 m=(unsigned char *)OPENSSL_malloc(buf_len+10);
230 if (m == NULL)
231 {
232 DSAerr(DSA_F_DSA_PRINT,ERR_R_MALLOC_FAILURE);
233 goto err;
234 }
235
236 if (x->priv_key != NULL)
237 {
238 if(!BIO_indent(bp,off,128))
239 goto err;
240 if (BIO_printf(bp,"Private-Key: (%d bit)\n",BN_num_bits(x->p))
241 <= 0) goto err;
242 }
243
244 if ((x->priv_key != NULL) && !print(bp,"priv:",x->priv_key,m,off))
245 goto err;
246 if ((x->pub_key != NULL) && !print(bp,"pub: ",x->pub_key,m,off))
247 goto err;
248 if ((x->p != NULL) && !print(bp,"P: ",x->p,m,off)) goto err;
249 if ((x->q != NULL) && !print(bp,"Q: ",x->q,m,off)) goto err;
250 if ((x->g != NULL) && !print(bp,"G: ",x->g,m,off)) goto err;
251 ret=1;
252err:
253 if (m != NULL) OPENSSL_free(m);
254 return(ret);
255 }
256#endif /* !OPENSSL_NO_DSA */
257
258#ifndef OPENSSL_NO_EC
259#ifndef OPENSSL_NO_FP_API
260int ECPKParameters_print_fp(FILE *fp, const EC_GROUP *x, int off)
261 {
262 BIO *b;
263 int ret;
264
265 if ((b=BIO_new(BIO_s_file())) == NULL)
266 {
267 ECerr(EC_F_ECPKPARAMETERS_PRINT_FP,ERR_R_BUF_LIB);
268 return(0);
269 }
270 BIO_set_fp(b, fp, BIO_NOCLOSE);
271 ret = ECPKParameters_print(b, x, off);
272 BIO_free(b);
273 return(ret);
274 }
275
276int EC_KEY_print_fp(FILE *fp, const EC_KEY *x, int off)
277 {
278 BIO *b;
279 int ret;
280
281 if ((b=BIO_new(BIO_s_file())) == NULL)
282 {
283 ECerr(EC_F_EC_KEY_PRINT_FP, ERR_R_BIO_LIB);
284 return(0);
285 }
286 BIO_set_fp(b, fp, BIO_NOCLOSE);
287 ret = EC_KEY_print(b, x, off);
288 BIO_free(b);
289 return(ret);
290 }
291#endif
292
293int ECPKParameters_print(BIO *bp, const EC_GROUP *x, int off)
294 {
295 unsigned char *buffer=NULL;
296 size_t buf_len=0, i;
297 int ret=0, reason=ERR_R_BIO_LIB;
298 BN_CTX *ctx=NULL;
299 const EC_POINT *point=NULL;
300 BIGNUM *p=NULL, *a=NULL, *b=NULL, *gen=NULL,
301 *order=NULL, *cofactor=NULL;
302 const unsigned char *seed;
303 size_t seed_len=0;
304
305 static const char *gen_compressed = "Generator (compressed):";
306 static const char *gen_uncompressed = "Generator (uncompressed):";
307 static const char *gen_hybrid = "Generator (hybrid):";
308
309 if (!x)
310 {
311 reason = ERR_R_PASSED_NULL_PARAMETER;
312 goto err;
313 }
314
315 if (EC_GROUP_get_asn1_flag(x))
316 {
317 /* the curve parameter are given by an asn1 OID */
318 int nid;
319
320 if (!BIO_indent(bp, off, 128))
321 goto err;
322
323 nid = EC_GROUP_get_curve_name(x);
324 if (nid == 0)
325 goto err;
326
327 if (BIO_printf(bp, "ASN1 OID: %s", OBJ_nid2sn(nid)) <= 0)
328 goto err;
329 if (BIO_printf(bp, "\n") <= 0)
330 goto err;
331 }
332 else
333 {
334 /* explicit parameters */
335 int is_char_two = 0;
336 point_conversion_form_t form;
337 int tmp_nid = EC_METHOD_get_field_type(EC_GROUP_method_of(x));
338
339 if (tmp_nid == NID_X9_62_characteristic_two_field)
340 is_char_two = 1;
341
342 if ((p = BN_new()) == NULL || (a = BN_new()) == NULL ||
343 (b = BN_new()) == NULL || (order = BN_new()) == NULL ||
344 (cofactor = BN_new()) == NULL)
345 {
346 reason = ERR_R_MALLOC_FAILURE;
347 goto err;
348 }
349
350 if (is_char_two)
351 {
352 if (!EC_GROUP_get_curve_GF2m(x, p, a, b, ctx))
353 {
354 reason = ERR_R_EC_LIB;
355 goto err;
356 }
357 }
358 else /* prime field */
359 {
360 if (!EC_GROUP_get_curve_GFp(x, p, a, b, ctx))
361 {
362 reason = ERR_R_EC_LIB;
363 goto err;
364 }
365 }
366
367 if ((point = EC_GROUP_get0_generator(x)) == NULL)
368 {
369 reason = ERR_R_EC_LIB;
370 goto err;
371 }
372 if (!EC_GROUP_get_order(x, order, NULL) ||
373 !EC_GROUP_get_cofactor(x, cofactor, NULL))
374 {
375 reason = ERR_R_EC_LIB;
376 goto err;
377 }
378
379 form = EC_GROUP_get_point_conversion_form(x);
380
381 if ((gen = EC_POINT_point2bn(x, point,
382 form, NULL, ctx)) == NULL)
383 {
384 reason = ERR_R_EC_LIB;
385 goto err;
386 }
387
388 buf_len = (size_t)BN_num_bytes(p);
389 if (buf_len < (i = (size_t)BN_num_bytes(a)))
390 buf_len = i;
391 if (buf_len < (i = (size_t)BN_num_bytes(b)))
392 buf_len = i;
393 if (buf_len < (i = (size_t)BN_num_bytes(gen)))
394 buf_len = i;
395 if (buf_len < (i = (size_t)BN_num_bytes(order)))
396 buf_len = i;
397 if (buf_len < (i = (size_t)BN_num_bytes(cofactor)))
398 buf_len = i;
399
400 if ((seed = EC_GROUP_get0_seed(x)) != NULL)
401 seed_len = EC_GROUP_get_seed_len(x);
402
403 buf_len += 10;
404 if ((buffer = OPENSSL_malloc(buf_len)) == NULL)
405 {
406 reason = ERR_R_MALLOC_FAILURE;
407 goto err;
408 }
409
410 if (!BIO_indent(bp, off, 128))
411 goto err;
412
413 /* print the 'short name' of the field type */
414 if (BIO_printf(bp, "Field Type: %s\n", OBJ_nid2sn(tmp_nid))
415 <= 0)
416 goto err;
417
418 if (is_char_two)
419 {
420 /* print the 'short name' of the base type OID */
421 int basis_type = EC_GROUP_get_basis_type(x);
422 if (basis_type == 0)
423 goto err;
424
425 if (!BIO_indent(bp, off, 128))
426 goto err;
427
428 if (BIO_printf(bp, "Basis Type: %s\n",
429 OBJ_nid2sn(basis_type)) <= 0)
430 goto err;
431
432 /* print the polynomial */
433 if ((p != NULL) && !print(bp, "Polynomial:", p, buffer,
434 off))
435 goto err;
436 }
437 else
438 {
439 if ((p != NULL) && !print(bp, "Prime:", p, buffer,off))
440 goto err;
441 }
442 if ((a != NULL) && !print(bp, "A: ", a, buffer, off))
443 goto err;
444 if ((b != NULL) && !print(bp, "B: ", b, buffer, off))
445 goto err;
446 if (form == POINT_CONVERSION_COMPRESSED)
447 {
448 if ((gen != NULL) && !print(bp, gen_compressed, gen,
449 buffer, off))
450 goto err;
451 }
452 else if (form == POINT_CONVERSION_UNCOMPRESSED)
453 {
454 if ((gen != NULL) && !print(bp, gen_uncompressed, gen,
455 buffer, off))
456 goto err;
457 }
458 else /* form == POINT_CONVERSION_HYBRID */
459 {
460 if ((gen != NULL) && !print(bp, gen_hybrid, gen,
461 buffer, off))
462 goto err;
463 }
464 if ((order != NULL) && !print(bp, "Order: ", order,
465 buffer, off)) goto err;
466 if ((cofactor != NULL) && !print(bp, "Cofactor: ", cofactor,
467 buffer, off)) goto err;
468 if (seed && !print_bin(bp, "Seed:", seed, seed_len, off))
469 goto err;
470 }
471 ret=1;
472err:
473 if (!ret)
474 ECerr(EC_F_ECPKPARAMETERS_PRINT, reason);
475 if (p)
476 BN_free(p);
477 if (a)
478 BN_free(a);
479 if (b)
480 BN_free(b);
481 if (gen)
482 BN_free(gen);
483 if (order)
484 BN_free(order);
485 if (cofactor)
486 BN_free(cofactor);
487 if (ctx)
488 BN_CTX_free(ctx);
489 if (buffer != NULL)
490 OPENSSL_free(buffer);
491 return(ret);
492 }
493 64
494int EC_KEY_print(BIO *bp, const EC_KEY *x, int off) 65int ASN1_bn_print(BIO *bp, const char *number, const BIGNUM *num,
495 { 66 unsigned char *buf, int off)
496 unsigned char *buffer=NULL;
497 size_t buf_len=0, i;
498 int ret=0, reason=ERR_R_BIO_LIB;
499 BIGNUM *pub_key=NULL, *order=NULL;
500 BN_CTX *ctx=NULL;
501 const EC_GROUP *group;
502 const EC_POINT *public_key;
503 const BIGNUM *priv_key;
504
505 if (x == NULL || (group = EC_KEY_get0_group(x)) == NULL)
506 {
507 reason = ERR_R_PASSED_NULL_PARAMETER;
508 goto err;
509 }
510
511 public_key = EC_KEY_get0_public_key(x);
512 if ((pub_key = EC_POINT_point2bn(group, public_key,
513 EC_KEY_get_conv_form(x), NULL, ctx)) == NULL)
514 {
515 reason = ERR_R_EC_LIB;
516 goto err;
517 }
518
519 buf_len = (size_t)BN_num_bytes(pub_key);
520 priv_key = EC_KEY_get0_private_key(x);
521 if (priv_key != NULL)
522 {
523 if ((i = (size_t)BN_num_bytes(priv_key)) > buf_len)
524 buf_len = i;
525 }
526
527 buf_len += 10;
528 if ((buffer = OPENSSL_malloc(buf_len)) == NULL)
529 {
530 reason = ERR_R_MALLOC_FAILURE;
531 goto err;
532 }
533
534 if (priv_key != NULL)
535 {
536 if (!BIO_indent(bp, off, 128))
537 goto err;
538 if ((order = BN_new()) == NULL)
539 goto err;
540 if (!EC_GROUP_get_order(group, order, NULL))
541 goto err;
542 if (BIO_printf(bp, "Private-Key: (%d bit)\n",
543 BN_num_bits(order)) <= 0) goto err;
544 }
545
546 if ((priv_key != NULL) && !print(bp, "priv:", priv_key,
547 buffer, off))
548 goto err;
549 if ((pub_key != NULL) && !print(bp, "pub: ", pub_key,
550 buffer, off))
551 goto err;
552 if (!ECPKParameters_print(bp, group, off))
553 goto err;
554 ret=1;
555err:
556 if (!ret)
557 ECerr(EC_F_EC_KEY_PRINT, reason);
558 if (pub_key)
559 BN_free(pub_key);
560 if (order)
561 BN_free(order);
562 if (ctx)
563 BN_CTX_free(ctx);
564 if (buffer != NULL)
565 OPENSSL_free(buffer);
566 return(ret);
567 }
568#endif /* OPENSSL_NO_EC */
569
570static int print(BIO *bp, const char *number, const BIGNUM *num, unsigned char *buf,
571 int off)
572 { 67 {
573 int n,i; 68 int n,i;
574 const char *neg; 69 const char *neg;
@@ -617,223 +112,3 @@ static int print(BIO *bp, const char *number, const BIGNUM *num, unsigned char *
617 } 112 }
618 return(1); 113 return(1);
619 } 114 }
620
621#ifndef OPENSSL_NO_EC
622static int print_bin(BIO *fp, const char *name, const unsigned char *buf,
623 size_t len, int off)
624 {
625 size_t i;
626 char str[128];
627
628 if (buf == NULL)
629 return 1;
630 if (off)
631 {
632 if (off > 128)
633 off=128;
634 memset(str,' ',off);
635 if (BIO_write(fp, str, off) <= 0)
636 return 0;
637 }
638
639 if (BIO_printf(fp,"%s", name) <= 0)
640 return 0;
641
642 for (i=0; i<len; i++)
643 {
644 if ((i%15) == 0)
645 {
646 str[0]='\n';
647 memset(&(str[1]),' ',off+4);
648 if (BIO_write(fp, str, off+1+4) <= 0)
649 return 0;
650 }
651 if (BIO_printf(fp,"%02x%s",buf[i],((i+1) == len)?"":":") <= 0)
652 return 0;
653 }
654 if (BIO_write(fp,"\n",1) <= 0)
655 return 0;
656
657 return 1;
658 }
659#endif
660
661#ifndef OPENSSL_NO_DH
662#ifndef OPENSSL_NO_FP_API
663int DHparams_print_fp(FILE *fp, const DH *x)
664 {
665 BIO *b;
666 int ret;
667
668 if ((b=BIO_new(BIO_s_file())) == NULL)
669 {
670 DHerr(DH_F_DHPARAMS_PRINT_FP,ERR_R_BUF_LIB);
671 return(0);
672 }
673 BIO_set_fp(b,fp,BIO_NOCLOSE);
674 ret=DHparams_print(b, x);
675 BIO_free(b);
676 return(ret);
677 }
678#endif
679
680int DHparams_print(BIO *bp, const DH *x)
681 {
682 unsigned char *m=NULL;
683 int reason=ERR_R_BUF_LIB,ret=0;
684 size_t buf_len=0, i;
685
686 if (x->p)
687 buf_len = (size_t)BN_num_bytes(x->p);
688 else
689 {
690 reason = ERR_R_PASSED_NULL_PARAMETER;
691 goto err;
692 }
693 if (x->g)
694 if (buf_len < (i = (size_t)BN_num_bytes(x->g)))
695 buf_len = i;
696 m=(unsigned char *)OPENSSL_malloc(buf_len+10);
697 if (m == NULL)
698 {
699 reason=ERR_R_MALLOC_FAILURE;
700 goto err;
701 }
702
703 if (BIO_printf(bp,"Diffie-Hellman-Parameters: (%d bit)\n",
704 BN_num_bits(x->p)) <= 0)
705 goto err;
706 if (!print(bp,"prime:",x->p,m,4)) goto err;
707 if (!print(bp,"generator:",x->g,m,4)) goto err;
708 if (x->length != 0)
709 {
710 if (BIO_printf(bp," recommended-private-length: %d bits\n",
711 (int)x->length) <= 0) goto err;
712 }
713 ret=1;
714 if (0)
715 {
716err:
717 DHerr(DH_F_DHPARAMS_PRINT,reason);
718 }
719 if (m != NULL) OPENSSL_free(m);
720 return(ret);
721 }
722#endif
723
724#ifndef OPENSSL_NO_DSA
725#ifndef OPENSSL_NO_FP_API
726int DSAparams_print_fp(FILE *fp, const DSA *x)
727 {
728 BIO *b;
729 int ret;
730
731 if ((b=BIO_new(BIO_s_file())) == NULL)
732 {
733 DSAerr(DSA_F_DSAPARAMS_PRINT_FP,ERR_R_BUF_LIB);
734 return(0);
735 }
736 BIO_set_fp(b,fp,BIO_NOCLOSE);
737 ret=DSAparams_print(b, x);
738 BIO_free(b);
739 return(ret);
740 }
741#endif
742
743int DSAparams_print(BIO *bp, const DSA *x)
744 {
745 unsigned char *m=NULL;
746 int ret=0;
747 size_t buf_len=0,i;
748
749 if (x->p)
750 buf_len = (size_t)BN_num_bytes(x->p);
751 else
752 {
753 DSAerr(DSA_F_DSAPARAMS_PRINT,DSA_R_MISSING_PARAMETERS);
754 goto err;
755 }
756 if (x->q)
757 if (buf_len < (i = (size_t)BN_num_bytes(x->q)))
758 buf_len = i;
759 if (x->g)
760 if (buf_len < (i = (size_t)BN_num_bytes(x->g)))
761 buf_len = i;
762 m=(unsigned char *)OPENSSL_malloc(buf_len+10);
763 if (m == NULL)
764 {
765 DSAerr(DSA_F_DSAPARAMS_PRINT,ERR_R_MALLOC_FAILURE);
766 goto err;
767 }
768
769 if (BIO_printf(bp,"DSA-Parameters: (%d bit)\n",
770 BN_num_bits(x->p)) <= 0)
771 goto err;
772 if (!print(bp,"p:",x->p,m,4)) goto err;
773 if ((x->q != NULL) && !print(bp,"q:",x->q,m,4)) goto err;
774 if ((x->g != NULL) && !print(bp,"g:",x->g,m,4)) goto err;
775 ret=1;
776err:
777 if (m != NULL) OPENSSL_free(m);
778 return(ret);
779 }
780
781#endif /* !OPENSSL_NO_DSA */
782
783#ifndef OPENSSL_NO_EC
784#ifndef OPENSSL_NO_FP_API
785int ECParameters_print_fp(FILE *fp, const EC_KEY *x)
786 {
787 BIO *b;
788 int ret;
789
790 if ((b=BIO_new(BIO_s_file())) == NULL)
791 {
792 ECerr(EC_F_ECPARAMETERS_PRINT_FP, ERR_R_BIO_LIB);
793 return(0);
794 }
795 BIO_set_fp(b, fp, BIO_NOCLOSE);
796 ret = ECParameters_print(b, x);
797 BIO_free(b);
798 return(ret);
799 }
800#endif
801
802int ECParameters_print(BIO *bp, const EC_KEY *x)
803 {
804 int reason=ERR_R_EC_LIB, ret=0;
805 BIGNUM *order=NULL;
806 const EC_GROUP *group;
807
808 if (x == NULL || (group = EC_KEY_get0_group(x)) == NULL)
809 {
810 reason = ERR_R_PASSED_NULL_PARAMETER;;
811 goto err;
812 }
813
814 if ((order = BN_new()) == NULL)
815 {
816 reason = ERR_R_MALLOC_FAILURE;
817 goto err;
818 }
819
820 if (!EC_GROUP_get_order(group, order, NULL))
821 {
822 reason = ERR_R_EC_LIB;
823 goto err;
824 }
825
826 if (BIO_printf(bp, "ECDSA-Parameters: (%d bit)\n",
827 BN_num_bits(order)) <= 0)
828 goto err;
829 if (!ECPKParameters_print(bp, group, 4))
830 goto err;
831 ret=1;
832err:
833 if (order)
834 BN_free(order);
835 ECerr(EC_F_ECPARAMETERS_PRINT, reason);
836 return(ret);
837 }
838
839#endif
diff --git a/src/lib/libcrypto/asn1/t_req.c b/src/lib/libcrypto/asn1/t_req.c
index 5557e06584..ea1794e3e0 100644
--- a/src/lib/libcrypto/asn1/t_req.c
+++ b/src/lib/libcrypto/asn1/t_req.c
@@ -149,34 +149,10 @@ int X509_REQ_print_ex(BIO *bp, X509_REQ *x, unsigned long nmflags, unsigned long
149 ERR_print_errors(bp); 149 ERR_print_errors(bp);
150 } 150 }
151 else 151 else
152#ifndef OPENSSL_NO_RSA
153 if (pkey->type == EVP_PKEY_RSA)
154 {
155 BIO_printf(bp,"%12sRSA Public Key: (%d bit)\n","",
156 BN_num_bits(pkey->pkey.rsa->n));
157 RSA_print(bp,pkey->pkey.rsa,16);
158 }
159 else
160#endif
161#ifndef OPENSSL_NO_DSA
162 if (pkey->type == EVP_PKEY_DSA)
163 { 152 {
164 BIO_printf(bp,"%12sDSA Public Key:\n",""); 153 EVP_PKEY_print_public(bp, pkey, 16, NULL);
165 DSA_print(bp,pkey->pkey.dsa,16); 154 EVP_PKEY_free(pkey);
166 } 155 }
167 else
168#endif
169#ifndef OPENSSL_NO_EC
170 if (pkey->type == EVP_PKEY_EC)
171 {
172 BIO_printf(bp, "%12sEC Public Key: \n","");
173 EC_KEY_print(bp, pkey->pkey.ec, 16);
174 }
175 else
176#endif
177 BIO_printf(bp,"%12sUnknown Public Key:\n","");
178
179 EVP_PKEY_free(pkey);
180 } 156 }
181 157
182 if(!(cflag & X509_FLAG_NO_ATTRIBUTES)) 158 if(!(cflag & X509_FLAG_NO_ATTRIBUTES))
diff --git a/src/lib/libcrypto/asn1/t_spki.c b/src/lib/libcrypto/asn1/t_spki.c
index a73369b949..079c081a81 100644
--- a/src/lib/libcrypto/asn1/t_spki.c
+++ b/src/lib/libcrypto/asn1/t_spki.c
@@ -82,36 +82,11 @@ int NETSCAPE_SPKI_print(BIO *out, NETSCAPE_SPKI *spki)
82 (i == NID_undef)?"UNKNOWN":OBJ_nid2ln(i)); 82 (i == NID_undef)?"UNKNOWN":OBJ_nid2ln(i));
83 pkey = X509_PUBKEY_get(spki->spkac->pubkey); 83 pkey = X509_PUBKEY_get(spki->spkac->pubkey);
84 if(!pkey) BIO_printf(out, " Unable to load public key\n"); 84 if(!pkey) BIO_printf(out, " Unable to load public key\n");
85 else { 85 else
86#ifndef OPENSSL_NO_RSA
87 if (pkey->type == EVP_PKEY_RSA)
88 {
89 BIO_printf(out," RSA Public Key: (%d bit)\n",
90 BN_num_bits(pkey->pkey.rsa->n));
91 RSA_print(out,pkey->pkey.rsa,2);
92 }
93 else
94#endif
95#ifndef OPENSSL_NO_DSA
96 if (pkey->type == EVP_PKEY_DSA)
97 {
98 BIO_printf(out," DSA Public Key:\n");
99 DSA_print(out,pkey->pkey.dsa,2);
100 }
101 else
102#endif
103#ifndef OPENSSL_NO_EC
104 if (pkey->type == EVP_PKEY_EC)
105 { 86 {
106 BIO_printf(out, " EC Public Key:\n"); 87 EVP_PKEY_print_public(out, pkey, 4, NULL);
107 EC_KEY_print(out, pkey->pkey.ec,2);
108 }
109 else
110#endif
111
112 BIO_printf(out," Unknown Public Key:\n");
113 EVP_PKEY_free(pkey); 88 EVP_PKEY_free(pkey);
114 } 89 }
115 chal = spki->spkac->challenge; 90 chal = spki->spkac->challenge;
116 if(chal->length) 91 if(chal->length)
117 BIO_printf(out, " Challenge String: %s\n", chal->data); 92 BIO_printf(out, " Challenge String: %s\n", chal->data);
diff --git a/src/lib/libcrypto/asn1/t_x509.c b/src/lib/libcrypto/asn1/t_x509.c
index 8f746f9c05..e061f2ffad 100644
--- a/src/lib/libcrypto/asn1/t_x509.c
+++ b/src/lib/libcrypto/asn1/t_x509.c
@@ -111,7 +111,6 @@ int X509_print_ex(BIO *bp, X509 *x, unsigned long nmflags, unsigned long cflag)
111 ASN1_INTEGER *bs; 111 ASN1_INTEGER *bs;
112 EVP_PKEY *pkey=NULL; 112 EVP_PKEY *pkey=NULL;
113 const char *neg; 113 const char *neg;
114 ASN1_STRING *str=NULL;
115 114
116 if((nmflags & XN_FLAG_SEP_MASK) == XN_FLAG_SEP_MULTILINE) { 115 if((nmflags & XN_FLAG_SEP_MASK) == XN_FLAG_SEP_MULTILINE) {
117 mlch = '\n'; 116 mlch = '\n';
@@ -215,34 +214,10 @@ int X509_print_ex(BIO *bp, X509 *x, unsigned long nmflags, unsigned long cflag)
215 ERR_print_errors(bp); 214 ERR_print_errors(bp);
216 } 215 }
217 else 216 else
218#ifndef OPENSSL_NO_RSA
219 if (pkey->type == EVP_PKEY_RSA)
220 {
221 BIO_printf(bp,"%12sRSA Public Key: (%d bit)\n","",
222 BN_num_bits(pkey->pkey.rsa->n));
223 RSA_print(bp,pkey->pkey.rsa,16);
224 }
225 else
226#endif
227#ifndef OPENSSL_NO_DSA
228 if (pkey->type == EVP_PKEY_DSA)
229 {
230 BIO_printf(bp,"%12sDSA Public Key:\n","");
231 DSA_print(bp,pkey->pkey.dsa,16);
232 }
233 else
234#endif
235#ifndef OPENSSL_NO_EC
236 if (pkey->type == EVP_PKEY_EC)
237 { 217 {
238 BIO_printf(bp, "%12sEC Public Key:\n",""); 218 EVP_PKEY_print_public(bp, pkey, 16, NULL);
239 EC_KEY_print(bp, pkey->pkey.ec, 16); 219 EVP_PKEY_free(pkey);
240 } 220 }
241 else
242#endif
243 BIO_printf(bp,"%12sUnknown Public Key:\n","");
244
245 EVP_PKEY_free(pkey);
246 } 221 }
247 222
248 if (!(cflag & X509_FLAG_NO_EXTENSIONS)) 223 if (!(cflag & X509_FLAG_NO_EXTENSIONS))
@@ -259,7 +234,6 @@ int X509_print_ex(BIO *bp, X509 *x, unsigned long nmflags, unsigned long cflag)
259 } 234 }
260 ret=1; 235 ret=1;
261err: 236err:
262 if (str != NULL) ASN1_STRING_free(str);
263 if (m != NULL) OPENSSL_free(m); 237 if (m != NULL) OPENSSL_free(m);
264 return(ret); 238 return(ret);
265 } 239 }
@@ -329,14 +303,15 @@ int X509_signature_print(BIO *bp, X509_ALGOR *sigalg, ASN1_STRING *sig)
329 return 1; 303 return 1;
330} 304}
331 305
332int ASN1_STRING_print(BIO *bp, ASN1_STRING *v) 306int ASN1_STRING_print(BIO *bp, const ASN1_STRING *v)
333 { 307 {
334 int i,n; 308 int i,n;
335 char buf[80],*p; 309 char buf[80];
310 const char *p;
336 311
337 if (v == NULL) return(0); 312 if (v == NULL) return(0);
338 n=0; 313 n=0;
339 p=(char *)v->data; 314 p=(const char *)v->data;
340 for (i=0; i<v->length; i++) 315 for (i=0; i<v->length; i++)
341 { 316 {
342 if ((p[i] > '~') || ((p[i] < ' ') && 317 if ((p[i] > '~') || ((p[i] < ' ') &&
@@ -358,7 +333,7 @@ int ASN1_STRING_print(BIO *bp, ASN1_STRING *v)
358 return(1); 333 return(1);
359 } 334 }
360 335
361int ASN1_TIME_print(BIO *bp, ASN1_TIME *tm) 336int ASN1_TIME_print(BIO *bp, const ASN1_TIME *tm)
362{ 337{
363 if(tm->type == V_ASN1_UTCTIME) return ASN1_UTCTIME_print(bp, tm); 338 if(tm->type == V_ASN1_UTCTIME) return ASN1_UTCTIME_print(bp, tm);
364 if(tm->type == V_ASN1_GENERALIZEDTIME) 339 if(tm->type == V_ASN1_GENERALIZEDTIME)
@@ -373,12 +348,14 @@ static const char *mon[12]=
373 "Jul","Aug","Sep","Oct","Nov","Dec" 348 "Jul","Aug","Sep","Oct","Nov","Dec"
374 }; 349 };
375 350
376int ASN1_GENERALIZEDTIME_print(BIO *bp, ASN1_GENERALIZEDTIME *tm) 351int ASN1_GENERALIZEDTIME_print(BIO *bp, const ASN1_GENERALIZEDTIME *tm)
377 { 352 {
378 char *v; 353 char *v;
379 int gmt=0; 354 int gmt=0;
380 int i; 355 int i;
381 int y=0,M=0,d=0,h=0,m=0,s=0; 356 int y=0,M=0,d=0,h=0,m=0,s=0;
357 char *f = NULL;
358 int f_len = 0;
382 359
383 i=tm->length; 360 i=tm->length;
384 v=(char *)tm->data; 361 v=(char *)tm->data;
@@ -396,10 +373,21 @@ int ASN1_GENERALIZEDTIME_print(BIO *bp, ASN1_GENERALIZEDTIME *tm)
396 if (tm->length >= 14 && 373 if (tm->length >= 14 &&
397 (v[12] >= '0') && (v[12] <= '9') && 374 (v[12] >= '0') && (v[12] <= '9') &&
398 (v[13] >= '0') && (v[13] <= '9')) 375 (v[13] >= '0') && (v[13] <= '9'))
376 {
399 s= (v[12]-'0')*10+(v[13]-'0'); 377 s= (v[12]-'0')*10+(v[13]-'0');
378 /* Check for fractions of seconds. */
379 if (tm->length >= 15 && v[14] == '.')
380 {
381 int l = tm->length;
382 f = &v[14]; /* The decimal point. */
383 f_len = 1;
384 while (14 + f_len < l && f[f_len] >= '0' && f[f_len] <= '9')
385 ++f_len;
386 }
387 }
400 388
401 if (BIO_printf(bp,"%s %2d %02d:%02d:%02d %d%s", 389 if (BIO_printf(bp,"%s %2d %02d:%02d:%02d%.*s %d%s",
402 mon[M-1],d,h,m,s,y,(gmt)?" GMT":"") <= 0) 390 mon[M-1],d,h,m,s,f_len,f,y,(gmt)?" GMT":"") <= 0)
403 return(0); 391 return(0);
404 else 392 else
405 return(1); 393 return(1);
@@ -408,15 +396,15 @@ err:
408 return(0); 396 return(0);
409 } 397 }
410 398
411int ASN1_UTCTIME_print(BIO *bp, ASN1_UTCTIME *tm) 399int ASN1_UTCTIME_print(BIO *bp, const ASN1_UTCTIME *tm)
412 { 400 {
413 char *v; 401 const char *v;
414 int gmt=0; 402 int gmt=0;
415 int i; 403 int i;
416 int y=0,M=0,d=0,h=0,m=0,s=0; 404 int y=0,M=0,d=0,h=0,m=0,s=0;
417 405
418 i=tm->length; 406 i=tm->length;
419 v=(char *)tm->data; 407 v=(const char *)tm->data;
420 408
421 if (i < 10) goto err; 409 if (i < 10) goto err;
422 if (v[i-1] == 'Z') gmt=1; 410 if (v[i-1] == 'Z') gmt=1;
diff --git a/src/lib/libcrypto/asn1/tasn_dec.c b/src/lib/libcrypto/asn1/tasn_dec.c
index 48bc1c0d4d..3bee439968 100644
--- a/src/lib/libcrypto/asn1/tasn_dec.c
+++ b/src/lib/libcrypto/asn1/tasn_dec.c
@@ -114,6 +114,8 @@ unsigned long ASN1_tag2bit(int tag)
114/* Macro to initialize and invalidate the cache */ 114/* Macro to initialize and invalidate the cache */
115 115
116#define asn1_tlc_clear(c) if (c) (c)->valid = 0 116#define asn1_tlc_clear(c) if (c) (c)->valid = 0
117/* Version to avoid compiler warning about 'c' always non-NULL */
118#define asn1_tlc_clear_nc(c) (c)->valid = 0
117 119
118/* Decode an ASN1 item, this currently behaves just 120/* Decode an ASN1 item, this currently behaves just
119 * like a standard 'd2i' function. 'in' points to 121 * like a standard 'd2i' function. 'in' points to
@@ -130,7 +132,7 @@ ASN1_VALUE *ASN1_item_d2i(ASN1_VALUE **pval,
130 ASN1_VALUE *ptmpval = NULL; 132 ASN1_VALUE *ptmpval = NULL;
131 if (!pval) 133 if (!pval)
132 pval = &ptmpval; 134 pval = &ptmpval;
133 c.valid = 0; 135 asn1_tlc_clear_nc(&c);
134 if (ASN1_item_ex_d2i(pval, in, len, it, -1, 0, 0, &c) > 0) 136 if (ASN1_item_ex_d2i(pval, in, len, it, -1, 0, 0, &c) > 0)
135 return *pval; 137 return *pval;
136 return NULL; 138 return NULL;
@@ -140,7 +142,7 @@ int ASN1_template_d2i(ASN1_VALUE **pval,
140 const unsigned char **in, long len, const ASN1_TEMPLATE *tt) 142 const unsigned char **in, long len, const ASN1_TEMPLATE *tt)
141 { 143 {
142 ASN1_TLC c; 144 ASN1_TLC c;
143 c.valid = 0; 145 asn1_tlc_clear_nc(&c);
144 return asn1_template_ex_d2i(pval, in, len, tt, 0, &c); 146 return asn1_template_ex_d2i(pval, in, len, tt, 0, &c);
145 } 147 }
146 148
@@ -306,7 +308,7 @@ int ASN1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len,
306 308
307 309
308 case ASN1_ITYPE_CHOICE: 310 case ASN1_ITYPE_CHOICE:
309 if (asn1_cb && !asn1_cb(ASN1_OP_D2I_PRE, pval, it)) 311 if (asn1_cb && !asn1_cb(ASN1_OP_D2I_PRE, pval, it, NULL))
310 goto auxerr; 312 goto auxerr;
311 313
312 /* Allocate structure */ 314 /* Allocate structure */
@@ -356,7 +358,7 @@ int ASN1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len,
356 358
357 asn1_set_choice_selector(pval, i, it); 359 asn1_set_choice_selector(pval, i, it);
358 *in = p; 360 *in = p;
359 if (asn1_cb && !asn1_cb(ASN1_OP_D2I_POST, pval, it)) 361 if (asn1_cb && !asn1_cb(ASN1_OP_D2I_POST, pval, it, NULL))
360 goto auxerr; 362 goto auxerr;
361 return 1; 363 return 1;
362 364
@@ -403,7 +405,7 @@ int ASN1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len,
403 goto err; 405 goto err;
404 } 406 }
405 407
406 if (asn1_cb && !asn1_cb(ASN1_OP_D2I_PRE, pval, it)) 408 if (asn1_cb && !asn1_cb(ASN1_OP_D2I_PRE, pval, it, NULL))
407 goto auxerr; 409 goto auxerr;
408 410
409 /* Get each field entry */ 411 /* Get each field entry */
@@ -505,7 +507,7 @@ int ASN1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len,
505 if (!asn1_enc_save(pval, *in, p - *in, it)) 507 if (!asn1_enc_save(pval, *in, p - *in, it))
506 goto auxerr; 508 goto auxerr;
507 *in = p; 509 *in = p;
508 if (asn1_cb && !asn1_cb(ASN1_OP_D2I_POST, pval, it)) 510 if (asn1_cb && !asn1_cb(ASN1_OP_D2I_POST, pval, it, NULL))
509 goto auxerr; 511 goto auxerr;
510 return 1; 512 return 1;
511 513
@@ -665,11 +667,12 @@ static int asn1_template_noexp_d2i(ASN1_VALUE **val,
665 else 667 else
666 { 668 {
667 /* We've got a valid STACK: free up any items present */ 669 /* We've got a valid STACK: free up any items present */
668 STACK *sktmp = (STACK *)*val; 670 STACK_OF(ASN1_VALUE) *sktmp
671 = (STACK_OF(ASN1_VALUE) *)*val;
669 ASN1_VALUE *vtmp; 672 ASN1_VALUE *vtmp;
670 while(sk_num(sktmp) > 0) 673 while(sk_ASN1_VALUE_num(sktmp) > 0)
671 { 674 {
672 vtmp = (ASN1_VALUE *)sk_pop(sktmp); 675 vtmp = sk_ASN1_VALUE_pop(sktmp);
673 ASN1_item_ex_free(&vtmp, 676 ASN1_item_ex_free(&vtmp,
674 ASN1_ITEM_ptr(tt->item)); 677 ASN1_ITEM_ptr(tt->item));
675 } 678 }
@@ -710,7 +713,8 @@ static int asn1_template_noexp_d2i(ASN1_VALUE **val,
710 goto err; 713 goto err;
711 } 714 }
712 len -= p - q; 715 len -= p - q;
713 if (!sk_push((STACK *)*val, (char *)skfield)) 716 if (!sk_ASN1_VALUE_push((STACK_OF(ASN1_VALUE) *)*val,
717 skfield))
714 { 718 {
715 ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I, 719 ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I,
716 ERR_R_MALLOC_FAILURE); 720 ERR_R_MALLOC_FAILURE);
diff --git a/src/lib/libcrypto/asn1/tasn_enc.c b/src/lib/libcrypto/asn1/tasn_enc.c
index 2721f904a6..936ad1f767 100644
--- a/src/lib/libcrypto/asn1/tasn_enc.c
+++ b/src/lib/libcrypto/asn1/tasn_enc.c
@@ -158,7 +158,7 @@ int ASN1_item_ex_i2d(ASN1_VALUE **pval, unsigned char **out,
158 return asn1_i2d_ex_primitive(pval, out, it, -1, aclass); 158 return asn1_i2d_ex_primitive(pval, out, it, -1, aclass);
159 159
160 case ASN1_ITYPE_CHOICE: 160 case ASN1_ITYPE_CHOICE:
161 if (asn1_cb && !asn1_cb(ASN1_OP_I2D_PRE, pval, it)) 161 if (asn1_cb && !asn1_cb(ASN1_OP_I2D_PRE, pval, it, NULL))
162 return 0; 162 return 0;
163 i = asn1_get_choice_selector(pval, it); 163 i = asn1_get_choice_selector(pval, it);
164 if ((i >= 0) && (i < it->tcount)) 164 if ((i >= 0) && (i < it->tcount))
@@ -171,7 +171,7 @@ int ASN1_item_ex_i2d(ASN1_VALUE **pval, unsigned char **out,
171 -1, aclass); 171 -1, aclass);
172 } 172 }
173 /* Fixme: error condition if selector out of range */ 173 /* Fixme: error condition if selector out of range */
174 if (asn1_cb && !asn1_cb(ASN1_OP_I2D_POST, pval, it)) 174 if (asn1_cb && !asn1_cb(ASN1_OP_I2D_POST, pval, it, NULL))
175 return 0; 175 return 0;
176 break; 176 break;
177 177
@@ -216,7 +216,7 @@ int ASN1_item_ex_i2d(ASN1_VALUE **pval, unsigned char **out,
216 aclass = (aclass & ~ASN1_TFLG_TAG_CLASS) 216 aclass = (aclass & ~ASN1_TFLG_TAG_CLASS)
217 | V_ASN1_UNIVERSAL; 217 | V_ASN1_UNIVERSAL;
218 } 218 }
219 if (asn1_cb && !asn1_cb(ASN1_OP_I2D_PRE, pval, it)) 219 if (asn1_cb && !asn1_cb(ASN1_OP_I2D_PRE, pval, it, NULL))
220 return 0; 220 return 0;
221 /* First work out sequence content length */ 221 /* First work out sequence content length */
222 for (i = 0, tt = it->templates; i < it->tcount; tt++, i++) 222 for (i = 0, tt = it->templates; i < it->tcount; tt++, i++)
@@ -250,7 +250,7 @@ int ASN1_item_ex_i2d(ASN1_VALUE **pval, unsigned char **out,
250 } 250 }
251 if (ndef == 2) 251 if (ndef == 2)
252 ASN1_put_eoc(out); 252 ASN1_put_eoc(out);
253 if (asn1_cb && !asn1_cb(ASN1_OP_I2D_POST, pval, it)) 253 if (asn1_cb && !asn1_cb(ASN1_OP_I2D_POST, pval, it, NULL))
254 return 0; 254 return 0;
255 return seqlen; 255 return seqlen;
256 256
@@ -569,7 +569,8 @@ int asn1_ex_i2c(ASN1_VALUE **pval, unsigned char *cout, int *putype,
569 ASN1_STRING *strtmp; 569 ASN1_STRING *strtmp;
570 ASN1_OBJECT *otmp; 570 ASN1_OBJECT *otmp;
571 int utype; 571 int utype;
572 unsigned char *cont, c; 572 const unsigned char *cont;
573 unsigned char c;
573 int len; 574 int len;
574 const ASN1_PRIMITIVE_FUNCS *pf; 575 const ASN1_PRIMITIVE_FUNCS *pf;
575 pf = it->funcs; 576 pf = it->funcs;
diff --git a/src/lib/libcrypto/asn1/tasn_fre.c b/src/lib/libcrypto/asn1/tasn_fre.c
index d7c017fa1d..77d3092d31 100644
--- a/src/lib/libcrypto/asn1/tasn_fre.c
+++ b/src/lib/libcrypto/asn1/tasn_fre.c
@@ -110,7 +110,7 @@ static void asn1_item_combine_free(ASN1_VALUE **pval, const ASN1_ITEM *it, int c
110 case ASN1_ITYPE_CHOICE: 110 case ASN1_ITYPE_CHOICE:
111 if (asn1_cb) 111 if (asn1_cb)
112 { 112 {
113 i = asn1_cb(ASN1_OP_FREE_PRE, pval, it); 113 i = asn1_cb(ASN1_OP_FREE_PRE, pval, it, NULL);
114 if (i == 2) 114 if (i == 2)
115 return; 115 return;
116 } 116 }
@@ -123,7 +123,7 @@ static void asn1_item_combine_free(ASN1_VALUE **pval, const ASN1_ITEM *it, int c
123 ASN1_template_free(pchval, tt); 123 ASN1_template_free(pchval, tt);
124 } 124 }
125 if (asn1_cb) 125 if (asn1_cb)
126 asn1_cb(ASN1_OP_FREE_POST, pval, it); 126 asn1_cb(ASN1_OP_FREE_POST, pval, it, NULL);
127 if (!combine) 127 if (!combine)
128 { 128 {
129 OPENSSL_free(*pval); 129 OPENSSL_free(*pval);
@@ -149,7 +149,7 @@ static void asn1_item_combine_free(ASN1_VALUE **pval, const ASN1_ITEM *it, int c
149 return; 149 return;
150 if (asn1_cb) 150 if (asn1_cb)
151 { 151 {
152 i = asn1_cb(ASN1_OP_FREE_PRE, pval, it); 152 i = asn1_cb(ASN1_OP_FREE_PRE, pval, it, NULL);
153 if (i == 2) 153 if (i == 2)
154 return; 154 return;
155 } 155 }
@@ -170,7 +170,7 @@ static void asn1_item_combine_free(ASN1_VALUE **pval, const ASN1_ITEM *it, int c
170 ASN1_template_free(pseqval, seqtt); 170 ASN1_template_free(pseqval, seqtt);
171 } 171 }
172 if (asn1_cb) 172 if (asn1_cb)
173 asn1_cb(ASN1_OP_FREE_POST, pval, it); 173 asn1_cb(ASN1_OP_FREE_POST, pval, it, NULL);
174 if (!combine) 174 if (!combine)
175 { 175 {
176 OPENSSL_free(*pval); 176 OPENSSL_free(*pval);
diff --git a/src/lib/libcrypto/asn1/tasn_new.c b/src/lib/libcrypto/asn1/tasn_new.c
index 5c6a2ebd4d..0d9e78cc7c 100644
--- a/src/lib/libcrypto/asn1/tasn_new.c
+++ b/src/lib/libcrypto/asn1/tasn_new.c
@@ -68,7 +68,7 @@ static int asn1_item_ex_combine_new(ASN1_VALUE **pval, const ASN1_ITEM *it,
68 int combine); 68 int combine);
69static void asn1_item_clear(ASN1_VALUE **pval, const ASN1_ITEM *it); 69static void asn1_item_clear(ASN1_VALUE **pval, const ASN1_ITEM *it);
70static void asn1_template_clear(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt); 70static void asn1_template_clear(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt);
71void asn1_primitive_clear(ASN1_VALUE **pval, const ASN1_ITEM *it); 71static void asn1_primitive_clear(ASN1_VALUE **pval, const ASN1_ITEM *it);
72 72
73ASN1_VALUE *ASN1_item_new(const ASN1_ITEM *it) 73ASN1_VALUE *ASN1_item_new(const ASN1_ITEM *it)
74 { 74 {
@@ -146,7 +146,7 @@ static int asn1_item_ex_combine_new(ASN1_VALUE **pval, const ASN1_ITEM *it,
146 case ASN1_ITYPE_CHOICE: 146 case ASN1_ITYPE_CHOICE:
147 if (asn1_cb) 147 if (asn1_cb)
148 { 148 {
149 i = asn1_cb(ASN1_OP_NEW_PRE, pval, it); 149 i = asn1_cb(ASN1_OP_NEW_PRE, pval, it, NULL);
150 if (!i) 150 if (!i)
151 goto auxerr; 151 goto auxerr;
152 if (i==2) 152 if (i==2)
@@ -166,7 +166,7 @@ static int asn1_item_ex_combine_new(ASN1_VALUE **pval, const ASN1_ITEM *it,
166 memset(*pval, 0, it->size); 166 memset(*pval, 0, it->size);
167 } 167 }
168 asn1_set_choice_selector(pval, -1, it); 168 asn1_set_choice_selector(pval, -1, it);
169 if (asn1_cb && !asn1_cb(ASN1_OP_NEW_POST, pval, it)) 169 if (asn1_cb && !asn1_cb(ASN1_OP_NEW_POST, pval, it, NULL))
170 goto auxerr; 170 goto auxerr;
171 break; 171 break;
172 172
@@ -174,7 +174,7 @@ static int asn1_item_ex_combine_new(ASN1_VALUE **pval, const ASN1_ITEM *it,
174 case ASN1_ITYPE_SEQUENCE: 174 case ASN1_ITYPE_SEQUENCE:
175 if (asn1_cb) 175 if (asn1_cb)
176 { 176 {
177 i = asn1_cb(ASN1_OP_NEW_PRE, pval, it); 177 i = asn1_cb(ASN1_OP_NEW_PRE, pval, it, NULL);
178 if (!i) 178 if (!i)
179 goto auxerr; 179 goto auxerr;
180 if (i==2) 180 if (i==2)
@@ -201,7 +201,7 @@ static int asn1_item_ex_combine_new(ASN1_VALUE **pval, const ASN1_ITEM *it,
201 if (!ASN1_template_new(pseqval, tt)) 201 if (!ASN1_template_new(pseqval, tt))
202 goto memerr; 202 goto memerr;
203 } 203 }
204 if (asn1_cb && !asn1_cb(ASN1_OP_NEW_POST, pval, it)) 204 if (asn1_cb && !asn1_cb(ASN1_OP_NEW_POST, pval, it, NULL))
205 goto auxerr; 205 goto auxerr;
206 break; 206 break;
207 } 207 }
@@ -325,6 +325,7 @@ static void asn1_template_clear(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt)
325int ASN1_primitive_new(ASN1_VALUE **pval, const ASN1_ITEM *it) 325int ASN1_primitive_new(ASN1_VALUE **pval, const ASN1_ITEM *it)
326 { 326 {
327 ASN1_TYPE *typ; 327 ASN1_TYPE *typ;
328 ASN1_STRING *str;
328 int utype; 329 int utype;
329 330
330 if (it && it->funcs) 331 if (it && it->funcs)
@@ -345,10 +346,7 @@ int ASN1_primitive_new(ASN1_VALUE **pval, const ASN1_ITEM *it)
345 return 1; 346 return 1;
346 347
347 case V_ASN1_BOOLEAN: 348 case V_ASN1_BOOLEAN:
348 if (it) 349 *(ASN1_BOOLEAN *)pval = it->size;
349 *(ASN1_BOOLEAN *)pval = it->size;
350 else
351 *(ASN1_BOOLEAN *)pval = -1;
352 return 1; 350 return 1;
353 351
354 case V_ASN1_NULL: 352 case V_ASN1_NULL:
@@ -365,7 +363,10 @@ int ASN1_primitive_new(ASN1_VALUE **pval, const ASN1_ITEM *it)
365 break; 363 break;
366 364
367 default: 365 default:
368 *pval = (ASN1_VALUE *)ASN1_STRING_type_new(utype); 366 str = ASN1_STRING_type_new(utype);
367 if (it->itype == ASN1_ITYPE_MSTRING && str)
368 str->flags |= ASN1_STRING_FLAG_MSTRING;
369 *pval = (ASN1_VALUE *)str;
369 break; 370 break;
370 } 371 }
371 if (*pval) 372 if (*pval)
@@ -373,7 +374,7 @@ int ASN1_primitive_new(ASN1_VALUE **pval, const ASN1_ITEM *it)
373 return 0; 374 return 0;
374 } 375 }
375 376
376void asn1_primitive_clear(ASN1_VALUE **pval, const ASN1_ITEM *it) 377static void asn1_primitive_clear(ASN1_VALUE **pval, const ASN1_ITEM *it)
377 { 378 {
378 int utype; 379 int utype;
379 if (it && it->funcs) 380 if (it && it->funcs)
diff --git a/src/lib/libcrypto/asn1/tasn_prn.c b/src/lib/libcrypto/asn1/tasn_prn.c
index b9c96a6dbe..453698012d 100644
--- a/src/lib/libcrypto/asn1/tasn_prn.c
+++ b/src/lib/libcrypto/asn1/tasn_prn.c
@@ -3,7 +3,7 @@
3 * project 2000. 3 * project 2000.
4 */ 4 */
5/* ==================================================================== 5/* ====================================================================
6 * Copyright (c) 2000 The OpenSSL Project. All rights reserved. 6 * Copyright (c) 2000,2005 The OpenSSL Project. All rights reserved.
7 * 7 *
8 * Redistribution and use in source and binary forms, with or without 8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions 9 * modification, are permitted provided that the following conditions
@@ -58,141 +58,570 @@
58 58
59 59
60#include <stddef.h> 60#include <stddef.h>
61#include "cryptlib.h"
61#include <openssl/asn1.h> 62#include <openssl/asn1.h>
63#include <openssl/asn1t.h>
62#include <openssl/objects.h> 64#include <openssl/objects.h>
63#include <openssl/buffer.h> 65#include <openssl/buffer.h>
64#include <openssl/err.h> 66#include <openssl/err.h>
65#include <openssl/nasn.h> 67#include <openssl/x509v3.h>
68#include "asn1_locl.h"
66 69
67/* Print routines. Print out a whole structure from a template. 70/* Print routines.
68 */ 71 */
69 72
70static int asn1_item_print_nm(BIO *out, void *fld, int indent, const ASN1_ITEM *it, const char *name); 73/* ASN1_PCTX routines */
71 74
72int ASN1_item_print(BIO *out, void *fld, int indent, const ASN1_ITEM *it) 75ASN1_PCTX default_pctx =
73{ 76 {
74 return asn1_item_print_nm(out, fld, indent, it, it->sname); 77 ASN1_PCTX_FLAGS_SHOW_ABSENT, /* flags */
75} 78 0, /* nm_flags */
79 0, /* cert_flags */
80 0, /* oid_flags */
81 0 /* str_flags */
82 };
83
76 84
77static int asn1_item_print_nm(BIO *out, void *fld, int indent, const ASN1_ITEM *it, const char *name) 85ASN1_PCTX *ASN1_PCTX_new(void)
78{ 86 {
79 ASN1_STRING *str; 87 ASN1_PCTX *ret;
88 ret = OPENSSL_malloc(sizeof(ASN1_PCTX));
89 if (ret == NULL)
90 {
91 ASN1err(ASN1_F_ASN1_PCTX_NEW, ERR_R_MALLOC_FAILURE);
92 return NULL;
93 }
94 ret->flags = 0;
95 ret->nm_flags = 0;
96 ret->cert_flags = 0;
97 ret->oid_flags = 0;
98 ret->str_flags = 0;
99 return ret;
100 }
101
102void ASN1_PCTX_free(ASN1_PCTX *p)
103 {
104 OPENSSL_free(p);
105 }
106
107unsigned long ASN1_PCTX_get_flags(ASN1_PCTX *p)
108 {
109 return p->flags;
110 }
111
112void ASN1_PCTX_set_flags(ASN1_PCTX *p, unsigned long flags)
113 {
114 p->flags = flags;
115 }
116
117unsigned long ASN1_PCTX_get_nm_flags(ASN1_PCTX *p)
118 {
119 return p->nm_flags;
120 }
121
122void ASN1_PCTX_set_nm_flags(ASN1_PCTX *p, unsigned long flags)
123 {
124 p->nm_flags = flags;
125 }
126
127unsigned long ASN1_PCTX_get_cert_flags(ASN1_PCTX *p)
128 {
129 return p->cert_flags;
130 }
131
132void ASN1_PCTX_set_cert_flags(ASN1_PCTX *p, unsigned long flags)
133 {
134 p->cert_flags = flags;
135 }
136
137unsigned long ASN1_PCTX_get_oid_flags(ASN1_PCTX *p)
138 {
139 return p->oid_flags;
140 }
141
142void ASN1_PCTX_set_oid_flags(ASN1_PCTX *p, unsigned long flags)
143 {
144 p->oid_flags = flags;
145 }
146
147unsigned long ASN1_PCTX_get_str_flags(ASN1_PCTX *p)
148 {
149 return p->str_flags;
150 }
151
152void ASN1_PCTX_set_str_flags(ASN1_PCTX *p, unsigned long flags)
153 {
154 p->str_flags = flags;
155 }
156
157/* Main print routines */
158
159static int asn1_item_print_ctx(BIO *out, ASN1_VALUE **fld, int indent,
160 const ASN1_ITEM *it,
161 const char *fname, const char *sname,
162 int nohdr, const ASN1_PCTX *pctx);
163
164int asn1_template_print_ctx(BIO *out, ASN1_VALUE **fld, int indent,
165 const ASN1_TEMPLATE *tt, const ASN1_PCTX *pctx);
166
167static int asn1_primitive_print(BIO *out, ASN1_VALUE **fld,
168 const ASN1_ITEM *it, int indent,
169 const char *fname, const char *sname,
170 const ASN1_PCTX *pctx);
171
172static int asn1_print_fsname(BIO *out, int indent,
173 const char *fname, const char *sname,
174 const ASN1_PCTX *pctx);
175
176int ASN1_item_print(BIO *out, ASN1_VALUE *ifld, int indent,
177 const ASN1_ITEM *it, const ASN1_PCTX *pctx)
178 {
179 const char *sname;
180 if (pctx == NULL)
181 pctx = &default_pctx;
182 if (pctx->flags & ASN1_PCTX_FLAGS_NO_STRUCT_NAME)
183 sname = NULL;
184 else
185 sname = it->sname;
186 return asn1_item_print_ctx(out, &ifld, indent, it,
187 NULL, sname, 0, pctx);
188 }
189
190static int asn1_item_print_ctx(BIO *out, ASN1_VALUE **fld, int indent,
191 const ASN1_ITEM *it,
192 const char *fname, const char *sname,
193 int nohdr, const ASN1_PCTX *pctx)
194 {
80 const ASN1_TEMPLATE *tt; 195 const ASN1_TEMPLATE *tt;
81 void *tmpfld; 196 const ASN1_EXTERN_FUNCS *ef;
197 ASN1_VALUE **tmpfld;
198 const ASN1_AUX *aux = it->funcs;
199 ASN1_aux_cb *asn1_cb;
200 ASN1_PRINT_ARG parg;
82 int i; 201 int i;
83 if(!fld) { 202 if (aux && aux->asn1_cb)
84 BIO_printf(out, "%*s%s ABSENT\n", indent, "", name); 203 {
204 parg.out = out;
205 parg.indent = indent;
206 parg.pctx = pctx;
207 asn1_cb = aux->asn1_cb;
208 }
209 else asn1_cb = 0;
210
211 if(*fld == NULL)
212 {
213 if (pctx->flags & ASN1_PCTX_FLAGS_SHOW_ABSENT)
214 {
215 if (!nohdr && !asn1_print_fsname(out, indent,
216 fname, sname, pctx))
217 return 0;
218 if (BIO_puts(out, "<ABSENT>\n") <= 0)
219 return 0;
220 }
85 return 1; 221 return 1;
86 } 222 }
87 switch(it->itype) {
88 223
224 switch(it->itype)
225 {
89 case ASN1_ITYPE_PRIMITIVE: 226 case ASN1_ITYPE_PRIMITIVE:
90 if(it->templates) 227 if(it->templates)
91 return ASN1_template_print(out, fld, indent, it->templates); 228 {
92 return asn1_primitive_print(out, fld, it->utype, indent, name); 229 if (!asn1_template_print_ctx(out, fld, indent,
93 break; 230 it->templates, pctx))
94 231 return 0;
232 }
233 /* fall thru */
95 case ASN1_ITYPE_MSTRING: 234 case ASN1_ITYPE_MSTRING:
96 str = fld; 235 if (!asn1_primitive_print(out, fld, it,
97 return asn1_primitive_print(out, fld, str->type, indent, name); 236 indent, fname, sname,pctx))
237 return 0;
238 break;
98 239
99 case ASN1_ITYPE_EXTERN: 240 case ASN1_ITYPE_EXTERN:
100 BIO_printf(out, "%*s%s:EXTERNAL TYPE %s %s\n", indent, "", name, it->sname, fld ? "" : "ABSENT"); 241 if (!nohdr && !asn1_print_fsname(out, indent, fname, sname, pctx))
101 return 1; 242 return 0;
102 case ASN1_ITYPE_COMPAT: 243 /* Use new style print routine if possible */
103 BIO_printf(out, "%*s%s:COMPATIBLE TYPE %s %s\n", indent, "", name, it->sname, fld ? "" : "ABSENT"); 244 ef = it->funcs;
104 return 1; 245 if (ef && ef->asn1_ex_print)
105 246 {
247 i = ef->asn1_ex_print(out, fld, indent, "", pctx);
248 if (!i)
249 return 0;
250 if ((i == 2) && (BIO_puts(out, "\n") <= 0))
251 return 0;
252 return 1;
253 }
254 else if (sname &&
255 BIO_printf(out, ":EXTERNAL TYPE %s\n", sname) <= 0)
256 return 0;
257 break;
106 258
107 case ASN1_ITYPE_CHOICE: 259 case ASN1_ITYPE_CHOICE:
260#if 0
261 if (!nohdr && !asn1_print_fsname(out, indent, fname, sname, pctx))
262 return 0;
263#endif
108 /* CHOICE type, get selector */ 264 /* CHOICE type, get selector */
109 i = asn1_get_choice_selector(fld, it); 265 i = asn1_get_choice_selector(fld, it);
110 /* This should never happen... */ 266 /* This should never happen... */
111 if((i < 0) || (i >= it->tcount)) { 267 if((i < 0) || (i >= it->tcount))
112 BIO_printf(out, "%s selector [%d] out of range\n", it->sname, i); 268 {
269 if (BIO_printf(out,
270 "ERROR: selector [%d] invalid\n", i) <= 0)
271 return 0;
113 return 1; 272 return 1;
114 } 273 }
115 tt = it->templates + i; 274 tt = it->templates + i;
116 tmpfld = asn1_get_field(fld, tt); 275 tmpfld = asn1_get_field_ptr(fld, tt);
117 return ASN1_template_print(out, tmpfld, indent, tt); 276 if (!asn1_template_print_ctx(out, tmpfld, indent, tt, pctx))
277 return 0;
278 break;
118 279
119 case ASN1_ITYPE_SEQUENCE: 280 case ASN1_ITYPE_SEQUENCE:
120 BIO_printf(out, "%*s%s {\n", indent, "", name); 281 case ASN1_ITYPE_NDEF_SEQUENCE:
121 /* Get each field entry */ 282 if (!nohdr && !asn1_print_fsname(out, indent, fname, sname, pctx))
122 for(i = 0, tt = it->templates; i < it->tcount; i++, tt++) { 283 return 0;
123 tmpfld = asn1_get_field(fld, tt); 284 if (fname || sname)
124 ASN1_template_print(out, tmpfld, indent + 2, tt); 285 {
125 } 286 if (pctx->flags & ASN1_PCTX_FLAGS_SHOW_SEQUENCE)
126 BIO_printf(out, "%*s}\n", indent, ""); 287 {
127 return 1; 288 if (BIO_puts(out, " {\n") <= 0)
289 return 0;
290 }
291 else
292 {
293 if (BIO_puts(out, "\n") <= 0)
294 return 0;
295 }
296 }
297
298 if (asn1_cb)
299 {
300 i = asn1_cb(ASN1_OP_PRINT_PRE, fld, it, &parg);
301 if (i == 0)
302 return 0;
303 if (i == 2)
304 return 1;
305 }
306
307 /* Print each field entry */
308 for(i = 0, tt = it->templates; i < it->tcount; i++, tt++)
309 {
310 const ASN1_TEMPLATE *seqtt;
311 seqtt = asn1_do_adb(fld, tt, 1);
312 tmpfld = asn1_get_field_ptr(fld, seqtt);
313 if (!asn1_template_print_ctx(out, tmpfld,
314 indent + 2, seqtt, pctx))
315 return 0;
316 }
317 if (pctx->flags & ASN1_PCTX_FLAGS_SHOW_SEQUENCE)
318 {
319 if (BIO_printf(out, "%*s}\n", indent, "") < 0)
320 return 0;
321 }
322
323 if (asn1_cb)
324 {
325 i = asn1_cb(ASN1_OP_PRINT_POST, fld, it, &parg);
326 if (i == 0)
327 return 0;
328 }
329 break;
128 330
129 default: 331 default:
332 BIO_printf(out, "Unprocessed type %d\n", it->itype);
130 return 0; 333 return 0;
334 }
335
336 return 1;
131 } 337 }
132}
133 338
134int ASN1_template_print(BIO *out, void *fld, int indent, const ASN1_TEMPLATE *tt) 339int asn1_template_print_ctx(BIO *out, ASN1_VALUE **fld, int indent,
135{ 340 const ASN1_TEMPLATE *tt, const ASN1_PCTX *pctx)
341 {
136 int i, flags; 342 int i, flags;
137#if 0 343 const char *sname, *fname;
138 if(!fld) return 0;
139#endif
140 flags = tt->flags; 344 flags = tt->flags;
141 if(flags & ASN1_TFLG_SK_MASK) { 345 if(pctx->flags & ASN1_PCTX_FLAGS_SHOW_FIELD_STRUCT_NAME)
346 sname = ASN1_ITEM_ptr(tt->item)->sname;
347 else
348 sname = NULL;
349 if(pctx->flags & ASN1_PCTX_FLAGS_NO_FIELD_NAME)
350 fname = NULL;
351 else
352 fname = tt->field_name;
353 if(flags & ASN1_TFLG_SK_MASK)
354 {
142 char *tname; 355 char *tname;
143 void *skitem; 356 ASN1_VALUE *skitem;
357 STACK_OF(ASN1_VALUE) *stack;
358
144 /* SET OF, SEQUENCE OF */ 359 /* SET OF, SEQUENCE OF */
145 if(flags & ASN1_TFLG_SET_OF) tname = "SET"; 360 if (fname)
146 else tname = "SEQUENCE"; 361 {
147 if(fld) { 362 if(pctx->flags & ASN1_PCTX_FLAGS_SHOW_SSOF)
148 BIO_printf(out, "%*s%s OF %s {\n", indent, "", tname, tt->field_name); 363 {
149 for(i = 0; i < sk_num(fld); i++) { 364 if(flags & ASN1_TFLG_SET_OF)
150 skitem = sk_value(fld, i); 365 tname = "SET";
151 asn1_item_print_nm(out, skitem, indent + 2, tt->item, ""); 366 else
367 tname = "SEQUENCE";
368 if (BIO_printf(out, "%*s%s OF %s {\n",
369 indent, "", tname, tt->field_name) <= 0)
370 return 0;
371 }
372 else if (BIO_printf(out, "%*s%s:\n", indent, "",
373 fname) <= 0)
374 return 0;
375 }
376 stack = (STACK_OF(ASN1_VALUE) *)*fld;
377 for(i = 0; i < sk_ASN1_VALUE_num(stack); i++)
378 {
379 if ((i > 0) && (BIO_puts(out, "\n") <= 0))
380 return 0;
381
382 skitem = sk_ASN1_VALUE_value(stack, i);
383 if (!asn1_item_print_ctx(out, &skitem, indent + 2,
384 ASN1_ITEM_ptr(tt->item), NULL, NULL, 1, pctx))
385 return 0;
386 }
387 if (!i && BIO_printf(out, "%*s<EMPTY>\n", indent + 2, "") <= 0)
388 return 0;
389 if(pctx->flags & ASN1_PCTX_FLAGS_SHOW_SEQUENCE)
390 {
391 if (BIO_printf(out, "%*s}\n", indent, "") <= 0)
392 return 0;
152 } 393 }
153 BIO_printf(out, "%*s}\n", indent, "");
154 } else
155 BIO_printf(out, "%*s%s OF %s ABSENT\n", indent, "", tname, tt->field_name);
156 return 1; 394 return 1;
395 }
396 return asn1_item_print_ctx(out, fld, indent, ASN1_ITEM_ptr(tt->item),
397 fname, sname, 0, pctx);
157 } 398 }
158 return asn1_item_print_nm(out, fld, indent, tt->item, tt->field_name); 399
159} 400static int asn1_print_fsname(BIO *out, int indent,
160 401 const char *fname, const char *sname,
161static int asn1_primitive_print(BIO *out, void *fld, long utype, int indent, const char *name) 402 const ASN1_PCTX *pctx)
162{ 403 {
163 ASN1_STRING *str = fld; 404 static char spaces[] = " ";
164 if(fld) { 405 const int nspaces = sizeof(spaces) - 1;
165 if(utype == V_ASN1_BOOLEAN) { 406
166 int *bool = fld; 407#if 0
167if(*bool == -1) printf("BOOL MISSING\n"); 408 if (!sname && !fname)
168 BIO_printf(out, "%*s%s:%s", indent, "", "BOOLEAN", *bool ? "TRUE" : "FALSE"); 409 return 1;
169 } else if((utype == V_ASN1_INTEGER) 410#endif
170 || (utype == V_ASN1_ENUMERATED)) { 411
171 char *s, *nm; 412 while (indent > nspaces)
172 s = i2s_ASN1_INTEGER(NULL, fld); 413 {
173 if(utype == V_ASN1_INTEGER) nm = "INTEGER"; 414 if (BIO_write(out, spaces, nspaces) != nspaces)
174 else nm = "ENUMERATED"; 415 return 0;
175 BIO_printf(out, "%*s%s:%s", indent, "", nm, s); 416 indent -= nspaces;
176 OPENSSL_free(s); 417 }
177 } else if(utype == V_ASN1_NULL) { 418 if (BIO_write(out, spaces, indent) != indent)
178 BIO_printf(out, "%*s%s", indent, "", "NULL"); 419 return 0;
179 } else if(utype == V_ASN1_UTCTIME) { 420 if (pctx->flags & ASN1_PCTX_FLAGS_NO_STRUCT_NAME)
180 BIO_printf(out, "%*s%s:%s:", indent, "", name, "UTCTIME"); 421 sname = NULL;
181 ASN1_UTCTIME_print(out, str); 422 if (pctx->flags & ASN1_PCTX_FLAGS_NO_FIELD_NAME)
182 } else if(utype == V_ASN1_GENERALIZEDTIME) { 423 fname = NULL;
183 BIO_printf(out, "%*s%s:%s:", indent, "", name, "GENERALIZEDTIME"); 424 if (!sname && !fname)
184 ASN1_GENERALIZEDTIME_print(out, str); 425 return 1;
185 } else if(utype == V_ASN1_OBJECT) { 426 if (fname)
186 char objbuf[80], *ln; 427 {
187 ln = OBJ_nid2ln(OBJ_obj2nid(fld)); 428 if (BIO_puts(out, fname) <= 0)
188 if(!ln) ln = ""; 429 return 0;
189 OBJ_obj2txt(objbuf, sizeof objbuf, fld, 1);
190 BIO_printf(out, "%*s%s:%s (%s)", indent, "", "OBJECT", ln, objbuf);
191 } else {
192 BIO_printf(out, "%*s%s:", indent, "", name);
193 ASN1_STRING_print_ex(out, str, ASN1_STRFLGS_DUMP_UNKNOWN|ASN1_STRFLGS_SHOW_TYPE);
194 } 430 }
195 BIO_printf(out, "\n"); 431 if (sname)
196 } else BIO_printf(out, "%*s%s [ABSENT]\n", indent, "", name); 432 {
433 if (fname)
434 {
435 if (BIO_printf(out, " (%s)", sname) <= 0)
436 return 0;
437 }
438 else
439 {
440 if (BIO_puts(out, sname) <= 0)
441 return 0;
442 }
443 }
444 if (BIO_write(out, ": ", 2) != 2)
445 return 0;
197 return 1; 446 return 1;
198} 447 }
448
449static int asn1_print_boolean_ctx(BIO *out, const int bool,
450 const ASN1_PCTX *pctx)
451 {
452 const char *str;
453 switch (bool)
454 {
455 case -1:
456 str = "BOOL ABSENT";
457 break;
458
459 case 0:
460 str = "FALSE";
461 break;
462
463 default:
464 str = "TRUE";
465 break;
466
467 }
468
469 if (BIO_puts(out, str) <= 0)
470 return 0;
471 return 1;
472
473 }
474
475static int asn1_print_integer_ctx(BIO *out, ASN1_INTEGER *str,
476 const ASN1_PCTX *pctx)
477 {
478 char *s;
479 int ret = 1;
480 s = i2s_ASN1_INTEGER(NULL, str);
481 if (BIO_puts(out, s) <= 0)
482 ret = 0;
483 OPENSSL_free(s);
484 return ret;
485 }
486
487static int asn1_print_oid_ctx(BIO *out, const ASN1_OBJECT *oid,
488 const ASN1_PCTX *pctx)
489 {
490 char objbuf[80];
491 const char *ln;
492 ln = OBJ_nid2ln(OBJ_obj2nid(oid));
493 if(!ln)
494 ln = "";
495 OBJ_obj2txt(objbuf, sizeof objbuf, oid, 1);
496 if (BIO_printf(out, "%s (%s)", ln, objbuf) <= 0)
497 return 0;
498 return 1;
499 }
500
501static int asn1_print_obstring_ctx(BIO *out, ASN1_STRING *str, int indent,
502 const ASN1_PCTX *pctx)
503 {
504 if (str->type == V_ASN1_BIT_STRING)
505 {
506 if (BIO_printf(out, " (%ld unused bits)\n",
507 str->flags & 0x7) <= 0)
508 return 0;
509 }
510 else if (BIO_puts(out, "\n") <= 0)
511 return 0;
512 if ((str->length > 0)
513 && BIO_dump_indent(out, (char *)str->data, str->length,
514 indent + 2) <= 0)
515 return 0;
516 return 1;
517 }
518
519static int asn1_primitive_print(BIO *out, ASN1_VALUE **fld,
520 const ASN1_ITEM *it, int indent,
521 const char *fname, const char *sname,
522 const ASN1_PCTX *pctx)
523 {
524 long utype;
525 ASN1_STRING *str;
526 int ret = 1, needlf = 1;
527 const char *pname;
528 const ASN1_PRIMITIVE_FUNCS *pf;
529 pf = it->funcs;
530 if (!asn1_print_fsname(out, indent, fname, sname, pctx))
531 return 0;
532 if (pf && pf->prim_print)
533 return pf->prim_print(out, fld, it, indent, pctx);
534 str = (ASN1_STRING *)*fld;
535 if (it->itype == ASN1_ITYPE_MSTRING)
536 utype = str->type & ~V_ASN1_NEG;
537 else
538 utype = it->utype;
539 if (utype == V_ASN1_ANY)
540 {
541 ASN1_TYPE *atype = (ASN1_TYPE *)*fld;
542 utype = atype->type;
543 fld = &atype->value.asn1_value;
544 str = (ASN1_STRING *)*fld;
545 if (pctx->flags & ASN1_PCTX_FLAGS_NO_ANY_TYPE)
546 pname = NULL;
547 else
548 pname = ASN1_tag2str(utype);
549 }
550 else
551 {
552 if (pctx->flags & ASN1_PCTX_FLAGS_SHOW_TYPE)
553 pname = ASN1_tag2str(utype);
554 else
555 pname = NULL;
556 }
557
558 if (utype == V_ASN1_NULL)
559 {
560 if (BIO_puts(out, "NULL\n") <= 0)
561 return 0;
562 return 1;
563 }
564
565 if (pname)
566 {
567 if (BIO_puts(out, pname) <= 0)
568 return 0;
569 if (BIO_puts(out, ":") <= 0)
570 return 0;
571 }
572
573 switch (utype)
574 {
575 case V_ASN1_BOOLEAN:
576 {
577 int bool = *(int *)fld;
578 if (bool == -1)
579 bool = it->size;
580 ret = asn1_print_boolean_ctx(out, bool, pctx);
581 }
582 break;
583
584 case V_ASN1_INTEGER:
585 case V_ASN1_ENUMERATED:
586 ret = asn1_print_integer_ctx(out, str, pctx);
587 break;
588
589 case V_ASN1_UTCTIME:
590 ret = ASN1_UTCTIME_print(out, str);
591 break;
592
593 case V_ASN1_GENERALIZEDTIME:
594 ret = ASN1_GENERALIZEDTIME_print(out, str);
595 break;
596
597 case V_ASN1_OBJECT:
598 ret = asn1_print_oid_ctx(out, (const ASN1_OBJECT *)*fld, pctx);
599 break;
600
601 case V_ASN1_OCTET_STRING:
602 case V_ASN1_BIT_STRING:
603 ret = asn1_print_obstring_ctx(out, str, indent, pctx);
604 needlf = 0;
605 break;
606
607 case V_ASN1_SEQUENCE:
608 case V_ASN1_SET:
609 case V_ASN1_OTHER:
610 if (BIO_puts(out, "\n") <= 0)
611 return 0;
612 if (ASN1_parse_dump(out, str->data, str->length,
613 indent, 0) <= 0)
614 ret = 0;
615 needlf = 0;
616 break;
617
618 default:
619 ret = ASN1_STRING_print_ex(out, str, pctx->str_flags);
620
621 }
622 if (!ret)
623 return 0;
624 if (needlf && BIO_puts(out, "\n") <= 0)
625 return 0;
626 return 1;
627 }
diff --git a/src/lib/libcrypto/asn1/tasn_typ.c b/src/lib/libcrypto/asn1/tasn_typ.c
index 6252213d15..6fb1c372da 100644
--- a/src/lib/libcrypto/asn1/tasn_typ.c
+++ b/src/lib/libcrypto/asn1/tasn_typ.c
@@ -135,3 +135,14 @@ IMPLEMENT_ASN1_TYPE_ex(ASN1_FBOOLEAN, ASN1_BOOLEAN, 0)
135/* Special, OCTET STRING with indefinite length constructed support */ 135/* Special, OCTET STRING with indefinite length constructed support */
136 136
137IMPLEMENT_ASN1_TYPE_ex(ASN1_OCTET_STRING_NDEF, ASN1_OCTET_STRING, ASN1_TFLG_NDEF) 137IMPLEMENT_ASN1_TYPE_ex(ASN1_OCTET_STRING_NDEF, ASN1_OCTET_STRING, ASN1_TFLG_NDEF)
138
139ASN1_ITEM_TEMPLATE(ASN1_SEQUENCE_ANY) =
140 ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, ASN1_SEQUENCE_ANY, ASN1_ANY)
141ASN1_ITEM_TEMPLATE_END(ASN1_SEQUENCE_ANY)
142
143ASN1_ITEM_TEMPLATE(ASN1_SET_ANY) =
144 ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SET_OF, 0, ASN1_SET_ANY, ASN1_ANY)
145ASN1_ITEM_TEMPLATE_END(ASN1_SET_ANY)
146
147IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(ASN1_SEQUENCE_ANY, ASN1_SEQUENCE_ANY, ASN1_SEQUENCE_ANY)
148IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(ASN1_SEQUENCE_ANY, ASN1_SET_ANY, ASN1_SET_ANY)
diff --git a/src/lib/libcrypto/asn1/x_crl.c b/src/lib/libcrypto/asn1/x_crl.c
index 70d56a67f2..c51c690ba9 100644
--- a/src/lib/libcrypto/asn1/x_crl.c
+++ b/src/lib/libcrypto/asn1/x_crl.c
@@ -58,11 +58,14 @@
58 58
59#include <stdio.h> 59#include <stdio.h>
60#include "cryptlib.h" 60#include "cryptlib.h"
61#include "asn1_locl.h"
61#include <openssl/asn1t.h> 62#include <openssl/asn1t.h>
62#include <openssl/x509.h> 63#include <openssl/x509.h>
64#include <openssl/x509v3.h>
63 65
64static int X509_REVOKED_cmp(const X509_REVOKED * const *a, 66static int X509_REVOKED_cmp(const X509_REVOKED * const *a,
65 const X509_REVOKED * const *b); 67 const X509_REVOKED * const *b);
68static void setup_idp(X509_CRL *crl, ISSUING_DIST_POINT *idp);
66 69
67ASN1_SEQUENCE(X509_REVOKED) = { 70ASN1_SEQUENCE(X509_REVOKED) = {
68 ASN1_SIMPLE(X509_REVOKED,serialNumber, ASN1_INTEGER), 71 ASN1_SIMPLE(X509_REVOKED,serialNumber, ASN1_INTEGER),
@@ -70,11 +73,26 @@ ASN1_SEQUENCE(X509_REVOKED) = {
70 ASN1_SEQUENCE_OF_OPT(X509_REVOKED,extensions, X509_EXTENSION) 73 ASN1_SEQUENCE_OF_OPT(X509_REVOKED,extensions, X509_EXTENSION)
71} ASN1_SEQUENCE_END(X509_REVOKED) 74} ASN1_SEQUENCE_END(X509_REVOKED)
72 75
76static int def_crl_verify(X509_CRL *crl, EVP_PKEY *r);
77static int def_crl_lookup(X509_CRL *crl,
78 X509_REVOKED **ret, ASN1_INTEGER *serial, X509_NAME *issuer);
79
80static X509_CRL_METHOD int_crl_meth =
81 {
82 0,
83 0,0,
84 def_crl_lookup,
85 def_crl_verify
86 };
87
88static const X509_CRL_METHOD *default_crl_method = &int_crl_meth;
89
73/* The X509_CRL_INFO structure needs a bit of customisation. 90/* The X509_CRL_INFO structure needs a bit of customisation.
74 * Since we cache the original encoding the signature wont be affected by 91 * Since we cache the original encoding the signature wont be affected by
75 * reordering of the revoked field. 92 * reordering of the revoked field.
76 */ 93 */
77static int crl_inf_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it) 94static int crl_inf_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
95 void *exarg)
78{ 96{
79 X509_CRL_INFO *a = (X509_CRL_INFO *)*pval; 97 X509_CRL_INFO *a = (X509_CRL_INFO *)*pval;
80 98
@@ -101,7 +119,237 @@ ASN1_SEQUENCE_enc(X509_CRL_INFO, enc, crl_inf_cb) = {
101 ASN1_EXP_SEQUENCE_OF_OPT(X509_CRL_INFO, extensions, X509_EXTENSION, 0) 119 ASN1_EXP_SEQUENCE_OF_OPT(X509_CRL_INFO, extensions, X509_EXTENSION, 0)
102} ASN1_SEQUENCE_END_enc(X509_CRL_INFO, X509_CRL_INFO) 120} ASN1_SEQUENCE_END_enc(X509_CRL_INFO, X509_CRL_INFO)
103 121
104ASN1_SEQUENCE_ref(X509_CRL, 0, CRYPTO_LOCK_X509_CRL) = { 122/* Set CRL entry issuer according to CRL certificate issuer extension.
123 * Check for unhandled critical CRL entry extensions.
124 */
125
126static int crl_set_issuers(X509_CRL *crl)
127 {
128
129 int i, j;
130 GENERAL_NAMES *gens, *gtmp;
131 STACK_OF(X509_REVOKED) *revoked;
132
133 revoked = X509_CRL_get_REVOKED(crl);
134
135 gens = NULL;
136 for (i = 0; i < sk_X509_REVOKED_num(revoked); i++)
137 {
138 X509_REVOKED *rev = sk_X509_REVOKED_value(revoked, i);
139 STACK_OF(X509_EXTENSION) *exts;
140 ASN1_ENUMERATED *reason;
141 X509_EXTENSION *ext;
142 gtmp = X509_REVOKED_get_ext_d2i(rev,
143 NID_certificate_issuer,
144 &j, NULL);
145 if (!gtmp && (j != -1))
146 {
147 crl->flags |= EXFLAG_INVALID;
148 return 1;
149 }
150
151 if (gtmp)
152 {
153 gens = gtmp;
154 if (!crl->issuers)
155 {
156 crl->issuers = sk_GENERAL_NAMES_new_null();
157 if (!crl->issuers)
158 return 0;
159 }
160 if (!sk_GENERAL_NAMES_push(crl->issuers, gtmp))
161 return 0;
162 }
163 rev->issuer = gens;
164
165 reason = X509_REVOKED_get_ext_d2i(rev, NID_crl_reason,
166 &j, NULL);
167 if (!reason && (j != -1))
168 {
169 crl->flags |= EXFLAG_INVALID;
170 return 1;
171 }
172
173 if (reason)
174 {
175 rev->reason = ASN1_ENUMERATED_get(reason);
176 ASN1_ENUMERATED_free(reason);
177 }
178 else
179 rev->reason = CRL_REASON_NONE;
180
181 /* Check for critical CRL entry extensions */
182
183 exts = rev->extensions;
184
185 for (j = 0; j < sk_X509_EXTENSION_num(exts); j++)
186 {
187 ext = sk_X509_EXTENSION_value(exts, j);
188 if (ext->critical > 0)
189 {
190 if (OBJ_obj2nid(ext->object) ==
191 NID_certificate_issuer)
192 continue;
193 crl->flags |= EXFLAG_CRITICAL;
194 break;
195 }
196 }
197
198
199 }
200
201 return 1;
202
203 }
204
205/* The X509_CRL structure needs a bit of customisation. Cache some extensions
206 * and hash of the whole CRL.
207 */
208static int crl_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
209 void *exarg)
210 {
211 X509_CRL *crl = (X509_CRL *)*pval;
212 STACK_OF(X509_EXTENSION) *exts;
213 X509_EXTENSION *ext;
214 int idx;
215
216 switch(operation)
217 {
218 case ASN1_OP_NEW_POST:
219 crl->idp = NULL;
220 crl->akid = NULL;
221 crl->flags = 0;
222 crl->idp_flags = 0;
223 crl->idp_reasons = CRLDP_ALL_REASONS;
224 crl->meth = default_crl_method;
225 crl->meth_data = NULL;
226 crl->issuers = NULL;
227 crl->crl_number = NULL;
228 crl->base_crl_number = NULL;
229 break;
230
231 case ASN1_OP_D2I_POST:
232#ifndef OPENSSL_NO_SHA
233 X509_CRL_digest(crl, EVP_sha1(), crl->sha1_hash, NULL);
234#endif
235 crl->idp = X509_CRL_get_ext_d2i(crl,
236 NID_issuing_distribution_point, NULL, NULL);
237 if (crl->idp)
238 setup_idp(crl, crl->idp);
239
240 crl->akid = X509_CRL_get_ext_d2i(crl,
241 NID_authority_key_identifier, NULL, NULL);
242
243 crl->crl_number = X509_CRL_get_ext_d2i(crl,
244 NID_crl_number, NULL, NULL);
245
246 crl->base_crl_number = X509_CRL_get_ext_d2i(crl,
247 NID_delta_crl, NULL, NULL);
248 /* Delta CRLs must have CRL number */
249 if (crl->base_crl_number && !crl->crl_number)
250 crl->flags |= EXFLAG_INVALID;
251
252 /* See if we have any unhandled critical CRL extensions and
253 * indicate this in a flag. We only currently handle IDP so
254 * anything else critical sets the flag.
255 *
256 * This code accesses the X509_CRL structure directly:
257 * applications shouldn't do this.
258 */
259
260 exts = crl->crl->extensions;
261
262 for (idx = 0; idx < sk_X509_EXTENSION_num(exts); idx++)
263 {
264 int nid;
265 ext = sk_X509_EXTENSION_value(exts, idx);
266 nid = OBJ_obj2nid(ext->object);
267 if (nid == NID_freshest_crl)
268 crl->flags |= EXFLAG_FRESHEST;
269 if (ext->critical > 0)
270 {
271 /* We handle IDP and deltas */
272 if ((nid == NID_issuing_distribution_point)
273 || (nid == NID_delta_crl))
274 break;;
275 crl->flags |= EXFLAG_CRITICAL;
276 break;
277 }
278 }
279
280
281 if (!crl_set_issuers(crl))
282 return 0;
283
284 if (crl->meth->crl_init)
285 {
286 if (crl->meth->crl_init(crl) == 0)
287 return 0;
288 }
289 break;
290
291 case ASN1_OP_FREE_POST:
292 if (crl->meth->crl_free)
293 {
294 if (!crl->meth->crl_free(crl))
295 return 0;
296 }
297 if (crl->akid)
298 AUTHORITY_KEYID_free(crl->akid);
299 if (crl->idp)
300 ISSUING_DIST_POINT_free(crl->idp);
301 ASN1_INTEGER_free(crl->crl_number);
302 ASN1_INTEGER_free(crl->base_crl_number);
303 sk_GENERAL_NAMES_pop_free(crl->issuers, GENERAL_NAMES_free);
304 break;
305 }
306 return 1;
307 }
308
309/* Convert IDP into a more convenient form */
310
311static void setup_idp(X509_CRL *crl, ISSUING_DIST_POINT *idp)
312 {
313 int idp_only = 0;
314 /* Set various flags according to IDP */
315 crl->idp_flags |= IDP_PRESENT;
316 if (idp->onlyuser > 0)
317 {
318 idp_only++;
319 crl->idp_flags |= IDP_ONLYUSER;
320 }
321 if (idp->onlyCA > 0)
322 {
323 idp_only++;
324 crl->idp_flags |= IDP_ONLYCA;
325 }
326 if (idp->onlyattr > 0)
327 {
328 idp_only++;
329 crl->idp_flags |= IDP_ONLYATTR;
330 }
331
332 if (idp_only > 1)
333 crl->idp_flags |= IDP_INVALID;
334
335 if (idp->indirectCRL > 0)
336 crl->idp_flags |= IDP_INDIRECT;
337
338 if (idp->onlysomereasons)
339 {
340 crl->idp_flags |= IDP_REASONS;
341 if (idp->onlysomereasons->length > 0)
342 crl->idp_reasons = idp->onlysomereasons->data[0];
343 if (idp->onlysomereasons->length > 1)
344 crl->idp_reasons |=
345 (idp->onlysomereasons->data[1] << 8);
346 crl->idp_reasons &= CRLDP_ALL_REASONS;
347 }
348
349 DIST_POINT_set_dpname(idp->distpoint, X509_CRL_get_issuer(crl));
350 }
351
352ASN1_SEQUENCE_ref(X509_CRL, crl_cb, CRYPTO_LOCK_X509_CRL) = {
105 ASN1_SIMPLE(X509_CRL, crl, X509_CRL_INFO), 353 ASN1_SIMPLE(X509_CRL, crl, X509_CRL_INFO),
106 ASN1_SIMPLE(X509_CRL, sig_alg, X509_ALGOR), 354 ASN1_SIMPLE(X509_CRL, sig_alg, X509_ALGOR),
107 ASN1_SIMPLE(X509_CRL, signature, ASN1_BIT_STRING) 355 ASN1_SIMPLE(X509_CRL, signature, ASN1_BIT_STRING)
@@ -134,6 +382,145 @@ int X509_CRL_add0_revoked(X509_CRL *crl, X509_REVOKED *rev)
134 return 1; 382 return 1;
135} 383}
136 384
385int X509_CRL_verify(X509_CRL *crl, EVP_PKEY *r)
386 {
387 if (crl->meth->crl_verify)
388 return crl->meth->crl_verify(crl, r);
389 return 0;
390 }
391
392int X509_CRL_get0_by_serial(X509_CRL *crl,
393 X509_REVOKED **ret, ASN1_INTEGER *serial)
394 {
395 if (crl->meth->crl_lookup)
396 return crl->meth->crl_lookup(crl, ret, serial, NULL);
397 return 0;
398 }
399
400int X509_CRL_get0_by_cert(X509_CRL *crl, X509_REVOKED **ret, X509 *x)
401 {
402 if (crl->meth->crl_lookup)
403 return crl->meth->crl_lookup(crl, ret,
404 X509_get_serialNumber(x),
405 X509_get_issuer_name(x));
406 return 0;
407 }
408
409static int def_crl_verify(X509_CRL *crl, EVP_PKEY *r)
410 {
411 return(ASN1_item_verify(ASN1_ITEM_rptr(X509_CRL_INFO),
412 crl->sig_alg, crl->signature,crl->crl,r));
413 }
414
415static int crl_revoked_issuer_match(X509_CRL *crl, X509_NAME *nm,
416 X509_REVOKED *rev)
417 {
418 int i;
419
420 if (!rev->issuer)
421 {
422 if (!nm)
423 return 1;
424 if (!X509_NAME_cmp(nm, X509_CRL_get_issuer(crl)))
425 return 1;
426 return 0;
427 }
428
429 if (!nm)
430 nm = X509_CRL_get_issuer(crl);
431
432 for (i = 0; i < sk_GENERAL_NAME_num(rev->issuer); i++)
433 {
434 GENERAL_NAME *gen = sk_GENERAL_NAME_value(rev->issuer, i);
435 if (gen->type != GEN_DIRNAME)
436 continue;
437 if (!X509_NAME_cmp(nm, gen->d.directoryName))
438 return 1;
439 }
440 return 0;
441
442 }
443
444static int def_crl_lookup(X509_CRL *crl,
445 X509_REVOKED **ret, ASN1_INTEGER *serial, X509_NAME *issuer)
446 {
447 X509_REVOKED rtmp, *rev;
448 int idx;
449 rtmp.serialNumber = serial;
450 /* Sort revoked into serial number order if not already sorted.
451 * Do this under a lock to avoid race condition.
452 */
453 if (!sk_X509_REVOKED_is_sorted(crl->crl->revoked))
454 {
455 CRYPTO_w_lock(CRYPTO_LOCK_X509_CRL);
456 sk_X509_REVOKED_sort(crl->crl->revoked);
457 CRYPTO_w_unlock(CRYPTO_LOCK_X509_CRL);
458 }
459 idx = sk_X509_REVOKED_find(crl->crl->revoked, &rtmp);
460 if(idx < 0)
461 return 0;
462 /* Need to look for matching name */
463 for(;idx < sk_X509_REVOKED_num(crl->crl->revoked); idx++)
464 {
465 rev = sk_X509_REVOKED_value(crl->crl->revoked, idx);
466 if (ASN1_INTEGER_cmp(rev->serialNumber, serial))
467 return 0;
468 if (crl_revoked_issuer_match(crl, issuer, rev))
469 {
470 if (ret)
471 *ret = rev;
472 if (rev->reason == CRL_REASON_REMOVE_FROM_CRL)
473 return 2;
474 return 1;
475 }
476 }
477 return 0;
478 }
479
480void X509_CRL_set_default_method(const X509_CRL_METHOD *meth)
481 {
482 if (meth == NULL)
483 default_crl_method = &int_crl_meth;
484 else
485 default_crl_method = meth;
486 }
487
488X509_CRL_METHOD *X509_CRL_METHOD_new(
489 int (*crl_init)(X509_CRL *crl),
490 int (*crl_free)(X509_CRL *crl),
491 int (*crl_lookup)(X509_CRL *crl, X509_REVOKED **ret,
492 ASN1_INTEGER *ser, X509_NAME *issuer),
493 int (*crl_verify)(X509_CRL *crl, EVP_PKEY *pk))
494 {
495 X509_CRL_METHOD *m;
496 m = OPENSSL_malloc(sizeof(X509_CRL_METHOD));
497 if (!m)
498 return NULL;
499 m->crl_init = crl_init;
500 m->crl_free = crl_free;
501 m->crl_lookup = crl_lookup;
502 m->crl_verify = crl_verify;
503 m->flags = X509_CRL_METHOD_DYNAMIC;
504 return m;
505 }
506
507void X509_CRL_METHOD_free(X509_CRL_METHOD *m)
508 {
509 if (!(m->flags & X509_CRL_METHOD_DYNAMIC))
510 return;
511 OPENSSL_free(m);
512 }
513
514void X509_CRL_set_meth_data(X509_CRL *crl, void *dat)
515 {
516 crl->meth_data = dat;
517 }
518
519void *X509_CRL_get_meth_data(X509_CRL *crl)
520 {
521 return crl->meth_data;
522 }
523
137IMPLEMENT_STACK_OF(X509_REVOKED) 524IMPLEMENT_STACK_OF(X509_REVOKED)
138IMPLEMENT_ASN1_SET_OF(X509_REVOKED) 525IMPLEMENT_ASN1_SET_OF(X509_REVOKED)
139IMPLEMENT_STACK_OF(X509_CRL) 526IMPLEMENT_STACK_OF(X509_CRL)
diff --git a/src/lib/libcrypto/asn1/x_long.c b/src/lib/libcrypto/asn1/x_long.c
index bf35457c1f..75317418e1 100644
--- a/src/lib/libcrypto/asn1/x_long.c
+++ b/src/lib/libcrypto/asn1/x_long.c
@@ -71,6 +71,7 @@ static void long_free(ASN1_VALUE **pval, const ASN1_ITEM *it);
71 71
72static int long_i2c(ASN1_VALUE **pval, unsigned char *cont, int *putype, const ASN1_ITEM *it); 72static int long_i2c(ASN1_VALUE **pval, unsigned char *cont, int *putype, const ASN1_ITEM *it);
73static int long_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len, int utype, char *free_cont, const ASN1_ITEM *it); 73static int long_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len, int utype, char *free_cont, const ASN1_ITEM *it);
74static int long_print(BIO *out, ASN1_VALUE **pval, const ASN1_ITEM *it, int indent, const ASN1_PCTX *pctx);
74 75
75static ASN1_PRIMITIVE_FUNCS long_pf = { 76static ASN1_PRIMITIVE_FUNCS long_pf = {
76 NULL, 0, 77 NULL, 0,
@@ -78,7 +79,8 @@ static ASN1_PRIMITIVE_FUNCS long_pf = {
78 long_free, 79 long_free,
79 long_free, /* Clear should set to initial value */ 80 long_free, /* Clear should set to initial value */
80 long_c2i, 81 long_c2i,
81 long_i2c 82 long_i2c,
83 long_print
82}; 84};
83 85
84ASN1_ITEM_start(LONG) 86ASN1_ITEM_start(LONG)
@@ -169,3 +171,9 @@ static int long_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len,
169 memcpy(cp, &ltmp, sizeof(long)); 171 memcpy(cp, &ltmp, sizeof(long));
170 return 1; 172 return 1;
171} 173}
174
175static int long_print(BIO *out, ASN1_VALUE **pval, const ASN1_ITEM *it,
176 int indent, const ASN1_PCTX *pctx)
177 {
178 return BIO_printf(out, "%ld\n", *(long *)pval);
179 }
diff --git a/src/lib/libcrypto/asn1/x_name.c b/src/lib/libcrypto/asn1/x_name.c
index 04380abc3f..caa4409feb 100644
--- a/src/lib/libcrypto/asn1/x_name.c
+++ b/src/lib/libcrypto/asn1/x_name.c
@@ -57,18 +57,36 @@
57 */ 57 */
58 58
59#include <stdio.h> 59#include <stdio.h>
60#include <ctype.h>
60#include "cryptlib.h" 61#include "cryptlib.h"
61#include <openssl/asn1t.h> 62#include <openssl/asn1t.h>
62#include <openssl/x509.h> 63#include <openssl/x509.h>
64#include "asn1_locl.h"
63 65
64static int x509_name_ex_d2i(ASN1_VALUE **val, const unsigned char **in, long len, const ASN1_ITEM *it, 66typedef STACK_OF(X509_NAME_ENTRY) STACK_OF_X509_NAME_ENTRY;
65 int tag, int aclass, char opt, ASN1_TLC *ctx); 67DECLARE_STACK_OF(STACK_OF_X509_NAME_ENTRY)
66 68
67static int x509_name_ex_i2d(ASN1_VALUE **val, unsigned char **out, const ASN1_ITEM *it, int tag, int aclass); 69static int x509_name_ex_d2i(ASN1_VALUE **val,
70 const unsigned char **in, long len,
71 const ASN1_ITEM *it,
72 int tag, int aclass, char opt, ASN1_TLC *ctx);
73
74static int x509_name_ex_i2d(ASN1_VALUE **val, unsigned char **out,
75 const ASN1_ITEM *it, int tag, int aclass);
68static int x509_name_ex_new(ASN1_VALUE **val, const ASN1_ITEM *it); 76static int x509_name_ex_new(ASN1_VALUE **val, const ASN1_ITEM *it);
69static void x509_name_ex_free(ASN1_VALUE **val, const ASN1_ITEM *it); 77static void x509_name_ex_free(ASN1_VALUE **val, const ASN1_ITEM *it);
70 78
71static int x509_name_encode(X509_NAME *a); 79static int x509_name_encode(X509_NAME *a);
80static int x509_name_canon(X509_NAME *a);
81static int asn1_string_canon(ASN1_STRING *out, ASN1_STRING *in);
82static int i2d_name_canon(STACK_OF(STACK_OF_X509_NAME_ENTRY) *intname,
83 unsigned char **in);
84
85
86static int x509_name_ex_print(BIO *out, ASN1_VALUE **pval,
87 int indent,
88 const char *fname,
89 const ASN1_PCTX *pctx);
72 90
73ASN1_SEQUENCE(X509_NAME_ENTRY) = { 91ASN1_SEQUENCE(X509_NAME_ENTRY) = {
74 ASN1_SIMPLE(X509_NAME_ENTRY, object, ASN1_OBJECT), 92 ASN1_SIMPLE(X509_NAME_ENTRY, object, ASN1_OBJECT),
@@ -102,7 +120,8 @@ const ASN1_EXTERN_FUNCS x509_name_ff = {
102 x509_name_ex_free, 120 x509_name_ex_free,
103 0, /* Default clear behaviour is OK */ 121 0, /* Default clear behaviour is OK */
104 x509_name_ex_d2i, 122 x509_name_ex_d2i,
105 x509_name_ex_i2d 123 x509_name_ex_i2d,
124 x509_name_ex_print
106}; 125};
107 126
108IMPLEMENT_EXTERN_ASN1(X509_NAME, V_ASN1_SEQUENCE, x509_name_ff) 127IMPLEMENT_EXTERN_ASN1(X509_NAME, V_ASN1_SEQUENCE, x509_name_ff)
@@ -118,6 +137,8 @@ static int x509_name_ex_new(ASN1_VALUE **val, const ASN1_ITEM *it)
118 if ((ret->entries=sk_X509_NAME_ENTRY_new_null()) == NULL) 137 if ((ret->entries=sk_X509_NAME_ENTRY_new_null()) == NULL)
119 goto memerr; 138 goto memerr;
120 if((ret->bytes = BUF_MEM_new()) == NULL) goto memerr; 139 if((ret->bytes = BUF_MEM_new()) == NULL) goto memerr;
140 ret->canon_enc = NULL;
141 ret->canon_enclen = 0;
121 ret->modified=1; 142 ret->modified=1;
122 *val = (ASN1_VALUE *)ret; 143 *val = (ASN1_VALUE *)ret;
123 return 1; 144 return 1;
@@ -142,25 +163,19 @@ static void x509_name_ex_free(ASN1_VALUE **pval, const ASN1_ITEM *it)
142 163
143 BUF_MEM_free(a->bytes); 164 BUF_MEM_free(a->bytes);
144 sk_X509_NAME_ENTRY_pop_free(a->entries,X509_NAME_ENTRY_free); 165 sk_X509_NAME_ENTRY_pop_free(a->entries,X509_NAME_ENTRY_free);
166 if (a->canon_enc)
167 OPENSSL_free(a->canon_enc);
145 OPENSSL_free(a); 168 OPENSSL_free(a);
146 *pval = NULL; 169 *pval = NULL;
147} 170}
148 171
149/* Used with sk_pop_free() to free up the internal representation. 172static int x509_name_ex_d2i(ASN1_VALUE **val,
150 * NB: we only free the STACK and not its contents because it is 173 const unsigned char **in, long len, const ASN1_ITEM *it,
151 * already present in the X509_NAME structure. 174 int tag, int aclass, char opt, ASN1_TLC *ctx)
152 */
153
154static void sk_internal_free(void *a)
155{
156 sk_free(a);
157}
158
159static int x509_name_ex_d2i(ASN1_VALUE **val, const unsigned char **in, long len, const ASN1_ITEM *it,
160 int tag, int aclass, char opt, ASN1_TLC *ctx)
161{ 175{
162 const unsigned char *p = *in, *q; 176 const unsigned char *p = *in, *q;
163 union { STACK *s; ASN1_VALUE *a; } intname = {NULL}; 177 union { STACK_OF(STACK_OF_X509_NAME_ENTRY) *s;
178 ASN1_VALUE *a; } intname = {NULL};
164 union { X509_NAME *x; ASN1_VALUE *a; } nm = {NULL}; 179 union { X509_NAME *x; ASN1_VALUE *a; } nm = {NULL};
165 int i, j, ret; 180 int i, j, ret;
166 STACK_OF(X509_NAME_ENTRY) *entries; 181 STACK_OF(X509_NAME_ENTRY) *entries;
@@ -181,8 +196,8 @@ static int x509_name_ex_d2i(ASN1_VALUE **val, const unsigned char **in, long len
181 memcpy(nm.x->bytes->data, q, p - q); 196 memcpy(nm.x->bytes->data, q, p - q);
182 197
183 /* Convert internal representation to X509_NAME structure */ 198 /* Convert internal representation to X509_NAME structure */
184 for(i = 0; i < sk_num(intname.s); i++) { 199 for(i = 0; i < sk_STACK_OF_X509_NAME_ENTRY_num(intname.s); i++) {
185 entries = (STACK_OF(X509_NAME_ENTRY) *)sk_value(intname.s, i); 200 entries = sk_STACK_OF_X509_NAME_ENTRY_value(intname.s, i);
186 for(j = 0; j < sk_X509_NAME_ENTRY_num(entries); j++) { 201 for(j = 0; j < sk_X509_NAME_ENTRY_num(entries); j++) {
187 entry = sk_X509_NAME_ENTRY_value(entries, j); 202 entry = sk_X509_NAME_ENTRY_value(entries, j);
188 entry->set = i; 203 entry->set = i;
@@ -191,7 +206,10 @@ static int x509_name_ex_d2i(ASN1_VALUE **val, const unsigned char **in, long len
191 } 206 }
192 sk_X509_NAME_ENTRY_free(entries); 207 sk_X509_NAME_ENTRY_free(entries);
193 } 208 }
194 sk_free(intname.s); 209 sk_STACK_OF_X509_NAME_ENTRY_free(intname.s);
210 ret = x509_name_canon(nm.x);
211 if (!ret)
212 goto err;
195 nm.x->modified = 0; 213 nm.x->modified = 0;
196 *val = nm.a; 214 *val = nm.a;
197 *in = p; 215 *in = p;
@@ -206,8 +224,12 @@ static int x509_name_ex_i2d(ASN1_VALUE **val, unsigned char **out, const ASN1_IT
206 int ret; 224 int ret;
207 X509_NAME *a = (X509_NAME *)*val; 225 X509_NAME *a = (X509_NAME *)*val;
208 if(a->modified) { 226 if(a->modified) {
209 ret = x509_name_encode((X509_NAME *)a); 227 ret = x509_name_encode(a);
210 if(ret < 0) return ret; 228 if(ret < 0)
229 return ret;
230 ret = x509_name_canon(a);
231 if(ret < 0)
232 return ret;
211 } 233 }
212 ret = a->bytes->length; 234 ret = a->bytes->length;
213 if(out != NULL) { 235 if(out != NULL) {
@@ -217,22 +239,35 @@ static int x509_name_ex_i2d(ASN1_VALUE **val, unsigned char **out, const ASN1_IT
217 return ret; 239 return ret;
218} 240}
219 241
242static void local_sk_X509_NAME_ENTRY_free(STACK_OF(X509_NAME_ENTRY) *ne)
243 {
244 sk_X509_NAME_ENTRY_free(ne);
245 }
246
247static void local_sk_X509_NAME_ENTRY_pop_free(STACK_OF(X509_NAME_ENTRY) *ne)
248 {
249 sk_X509_NAME_ENTRY_pop_free(ne, X509_NAME_ENTRY_free);
250 }
251
220static int x509_name_encode(X509_NAME *a) 252static int x509_name_encode(X509_NAME *a)
221{ 253{
222 union { STACK *s; ASN1_VALUE *a; } intname = {NULL}; 254 union { STACK_OF(STACK_OF_X509_NAME_ENTRY) *s;
255 ASN1_VALUE *a; } intname = {NULL};
223 int len; 256 int len;
224 unsigned char *p; 257 unsigned char *p;
225 STACK_OF(X509_NAME_ENTRY) *entries = NULL; 258 STACK_OF(X509_NAME_ENTRY) *entries = NULL;
226 X509_NAME_ENTRY *entry; 259 X509_NAME_ENTRY *entry;
227 int i, set = -1; 260 int i, set = -1;
228 intname.s = sk_new_null(); 261 intname.s = sk_STACK_OF_X509_NAME_ENTRY_new_null();
229 if(!intname.s) goto memerr; 262 if(!intname.s) goto memerr;
230 for(i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) { 263 for(i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) {
231 entry = sk_X509_NAME_ENTRY_value(a->entries, i); 264 entry = sk_X509_NAME_ENTRY_value(a->entries, i);
232 if(entry->set != set) { 265 if(entry->set != set) {
233 entries = sk_X509_NAME_ENTRY_new_null(); 266 entries = sk_X509_NAME_ENTRY_new_null();
234 if(!entries) goto memerr; 267 if(!entries) goto memerr;
235 if(!sk_push(intname.s, (char *)entries)) goto memerr; 268 if(!sk_STACK_OF_X509_NAME_ENTRY_push(intname.s,
269 entries))
270 goto memerr;
236 set = entry->set; 271 set = entry->set;
237 } 272 }
238 if(!sk_X509_NAME_ENTRY_push(entries, entry)) goto memerr; 273 if(!sk_X509_NAME_ENTRY_push(entries, entry)) goto memerr;
@@ -243,15 +278,222 @@ static int x509_name_encode(X509_NAME *a)
243 p=(unsigned char *)a->bytes->data; 278 p=(unsigned char *)a->bytes->data;
244 ASN1_item_ex_i2d(&intname.a, 279 ASN1_item_ex_i2d(&intname.a,
245 &p, ASN1_ITEM_rptr(X509_NAME_INTERNAL), -1, -1); 280 &p, ASN1_ITEM_rptr(X509_NAME_INTERNAL), -1, -1);
246 sk_pop_free(intname.s, sk_internal_free); 281 sk_STACK_OF_X509_NAME_ENTRY_pop_free(intname.s,
282 local_sk_X509_NAME_ENTRY_free);
247 a->modified = 0; 283 a->modified = 0;
248 return len; 284 return len;
249 memerr: 285memerr:
250 sk_pop_free(intname.s, sk_internal_free); 286 sk_STACK_OF_X509_NAME_ENTRY_pop_free(intname.s,
287 local_sk_X509_NAME_ENTRY_free);
251 ASN1err(ASN1_F_X509_NAME_ENCODE, ERR_R_MALLOC_FAILURE); 288 ASN1err(ASN1_F_X509_NAME_ENCODE, ERR_R_MALLOC_FAILURE);
252 return -1; 289 return -1;
253} 290}
254 291
292static int x509_name_ex_print(BIO *out, ASN1_VALUE **pval,
293 int indent,
294 const char *fname,
295 const ASN1_PCTX *pctx)
296 {
297 if (X509_NAME_print_ex(out, (X509_NAME *)*pval,
298 indent, pctx->nm_flags) <= 0)
299 return 0;
300 return 2;
301 }
302
303/* This function generates the canonical encoding of the Name structure.
304 * In it all strings are converted to UTF8, leading, trailing and
305 * multiple spaces collapsed, converted to lower case and the leading
306 * SEQUENCE header removed.
307 *
308 * In future we could also normalize the UTF8 too.
309 *
310 * By doing this comparison of Name structures can be rapidly
311 * perfomed by just using memcmp() of the canonical encoding.
312 * By omitting the leading SEQUENCE name constraints of type
313 * dirName can also be checked with a simple memcmp().
314 */
315
316static int x509_name_canon(X509_NAME *a)
317 {
318 unsigned char *p;
319 STACK_OF(STACK_OF_X509_NAME_ENTRY) *intname = NULL;
320 STACK_OF(X509_NAME_ENTRY) *entries = NULL;
321 X509_NAME_ENTRY *entry, *tmpentry = NULL;
322 int i, set = -1, ret = 0;
323
324 if (a->canon_enc)
325 {
326 OPENSSL_free(a->canon_enc);
327 a->canon_enc = NULL;
328 }
329 /* Special case: empty X509_NAME => null encoding */
330 if (sk_X509_NAME_ENTRY_num(a->entries) == 0)
331 {
332 a->canon_enclen = 0;
333 return 1;
334 }
335 intname = sk_STACK_OF_X509_NAME_ENTRY_new_null();
336 if(!intname)
337 goto err;
338 for(i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++)
339 {
340 entry = sk_X509_NAME_ENTRY_value(a->entries, i);
341 if(entry->set != set)
342 {
343 entries = sk_X509_NAME_ENTRY_new_null();
344 if(!entries)
345 goto err;
346 if(!sk_STACK_OF_X509_NAME_ENTRY_push(intname, entries))
347 goto err;
348 set = entry->set;
349 }
350 tmpentry = X509_NAME_ENTRY_new();
351 tmpentry->object = OBJ_dup(entry->object);
352 if (!asn1_string_canon(tmpentry->value, entry->value))
353 goto err;
354 if(!sk_X509_NAME_ENTRY_push(entries, tmpentry))
355 goto err;
356 tmpentry = NULL;
357 }
358
359 /* Finally generate encoding */
360
361 a->canon_enclen = i2d_name_canon(intname, NULL);
362
363 p = OPENSSL_malloc(a->canon_enclen);
364
365 if (!p)
366 goto err;
367
368 a->canon_enc = p;
369
370 i2d_name_canon(intname, &p);
371
372 ret = 1;
373
374 err:
375
376 if (tmpentry)
377 X509_NAME_ENTRY_free(tmpentry);
378 if (intname)
379 sk_STACK_OF_X509_NAME_ENTRY_pop_free(intname,
380 local_sk_X509_NAME_ENTRY_pop_free);
381 return ret;
382 }
383
384/* Bitmap of all the types of string that will be canonicalized. */
385
386#define ASN1_MASK_CANON \
387 (B_ASN1_UTF8STRING | B_ASN1_BMPSTRING | B_ASN1_UNIVERSALSTRING \
388 | B_ASN1_PRINTABLESTRING | B_ASN1_T61STRING | B_ASN1_IA5STRING \
389 | B_ASN1_VISIBLESTRING)
390
391
392static int asn1_string_canon(ASN1_STRING *out, ASN1_STRING *in)
393 {
394 unsigned char *to, *from;
395 int len, i;
396
397 /* If type not in bitmask just copy string across */
398 if (!(ASN1_tag2bit(in->type) & ASN1_MASK_CANON))
399 {
400 out->type = in->type;
401 if (!ASN1_STRING_set(out, in->data, in->length))
402 return 0;
403 return 1;
404 }
405
406 out->type = V_ASN1_UTF8STRING;
407 out->length = ASN1_STRING_to_UTF8(&out->data, in);
408 if (out->length == -1)
409 return 0;
410
411 to = out->data;
412 from = to;
413
414 len = out->length;
415
416 /* Convert string in place to canonical form.
417 * Ultimately we may need to handle a wider range of characters
418 * but for now ignore anything with MSB set and rely on the
419 * isspace() and tolower() functions.
420 */
421
422 /* Ignore leading spaces */
423 while((len > 0) && !(*from & 0x80) && isspace(*from))
424 {
425 from++;
426 len--;
427 }
428
429 to = from + len - 1;
430
431 /* Ignore trailing spaces */
432 while ((len > 0) && !(*to & 0x80) && isspace(*to))
433 {
434 to--;
435 len--;
436 }
437
438 to = out->data;
439
440 i = 0;
441 while(i < len)
442 {
443 /* If MSB set just copy across */
444 if (*from & 0x80)
445 {
446 *to++ = *from++;
447 i++;
448 }
449 /* Collapse multiple spaces */
450 else if (isspace(*from))
451 {
452 /* Copy one space across */
453 *to++ = ' ';
454 /* Ignore subsequent spaces. Note: don't need to
455 * check len here because we know the last
456 * character is a non-space so we can't overflow.
457 */
458 do
459 {
460 from++;
461 i++;
462 }
463 while(!(*from & 0x80) && isspace(*from));
464 }
465 else
466 {
467 *to++ = tolower(*from++);
468 i++;
469 }
470 }
471
472 out->length = to - out->data;
473
474 return 1;
475
476 }
477
478static int i2d_name_canon(STACK_OF(STACK_OF_X509_NAME_ENTRY) *_intname,
479 unsigned char **in)
480 {
481 int i, len, ltmp;
482 ASN1_VALUE *v;
483 STACK_OF(ASN1_VALUE) *intname = (STACK_OF(ASN1_VALUE) *)_intname;
484
485 len = 0;
486 for (i = 0; i < sk_ASN1_VALUE_num(intname); i++)
487 {
488 v = sk_ASN1_VALUE_value(intname, i);
489 ltmp = ASN1_item_ex_i2d(&v, in,
490 ASN1_ITEM_rptr(X509_NAME_ENTRIES), -1, -1);
491 if (ltmp < 0)
492 return ltmp;
493 len += ltmp;
494 }
495 return len;
496 }
255 497
256int X509_NAME_set(X509_NAME **xn, X509_NAME *name) 498int X509_NAME_set(X509_NAME **xn, X509_NAME *name)
257 { 499 {
diff --git a/src/lib/libcrypto/asn1/x_pubkey.c b/src/lib/libcrypto/asn1/x_pubkey.c
index 91c2756116..d42b6a2c54 100644
--- a/src/lib/libcrypto/asn1/x_pubkey.c
+++ b/src/lib/libcrypto/asn1/x_pubkey.c
@@ -60,6 +60,7 @@
60#include "cryptlib.h" 60#include "cryptlib.h"
61#include <openssl/asn1t.h> 61#include <openssl/asn1t.h>
62#include <openssl/x509.h> 62#include <openssl/x509.h>
63#include "asn1_locl.h"
63#ifndef OPENSSL_NO_RSA 64#ifndef OPENSSL_NO_RSA
64#include <openssl/rsa.h> 65#include <openssl/rsa.h>
65#endif 66#endif
@@ -68,7 +69,8 @@
68#endif 69#endif
69 70
70/* Minor tweak to operation: free up EVP_PKEY */ 71/* Minor tweak to operation: free up EVP_PKEY */
71static int pubkey_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it) 72static int pubkey_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
73 void *exarg)
72 { 74 {
73 if (operation == ASN1_OP_FREE_POST) 75 if (operation == ASN1_OP_FREE_POST)
74 { 76 {
@@ -88,169 +90,42 @@ IMPLEMENT_ASN1_FUNCTIONS(X509_PUBKEY)
88int X509_PUBKEY_set(X509_PUBKEY **x, EVP_PKEY *pkey) 90int X509_PUBKEY_set(X509_PUBKEY **x, EVP_PKEY *pkey)
89 { 91 {
90 X509_PUBKEY *pk=NULL; 92 X509_PUBKEY *pk=NULL;
91 X509_ALGOR *a;
92 ASN1_OBJECT *o;
93 unsigned char *s,*p = NULL;
94 int i;
95 93
96 if (x == NULL) return(0); 94 if (x == NULL) return(0);
97 95
98 if ((pk=X509_PUBKEY_new()) == NULL) goto err; 96 if ((pk=X509_PUBKEY_new()) == NULL) goto error;
99 a=pk->algor;
100 97
101 /* set the algorithm id */ 98 if (pkey->ameth)
102 if ((o=OBJ_nid2obj(pkey->type)) == NULL) goto err;
103 ASN1_OBJECT_free(a->algorithm);
104 a->algorithm=o;
105
106 /* Set the parameter list */
107 if (!pkey->save_parameters || (pkey->type == EVP_PKEY_RSA))
108 { 99 {
109 if ((a->parameter == NULL) || 100 if (pkey->ameth->pub_encode)
110 (a->parameter->type != V_ASN1_NULL))
111 { 101 {
112 ASN1_TYPE_free(a->parameter); 102 if (!pkey->ameth->pub_encode(pk, pkey))
113 if (!(a->parameter=ASN1_TYPE_new()))
114 { 103 {
115 X509err(X509_F_X509_PUBKEY_SET,ERR_R_MALLOC_FAILURE); 104 X509err(X509_F_X509_PUBKEY_SET,
116 goto err; 105 X509_R_PUBLIC_KEY_ENCODE_ERROR);
106 goto error;
117 } 107 }
118 a->parameter->type=V_ASN1_NULL;
119 }
120 }
121#ifndef OPENSSL_NO_DSA
122 else if (pkey->type == EVP_PKEY_DSA)
123 {
124 unsigned char *pp;
125 DSA *dsa;
126
127 dsa=pkey->pkey.dsa;
128 dsa->write_params=0;
129 ASN1_TYPE_free(a->parameter);
130 if ((i=i2d_DSAparams(dsa,NULL)) <= 0)
131 goto err;
132 if (!(p=(unsigned char *)OPENSSL_malloc(i)))
133 {
134 X509err(X509_F_X509_PUBKEY_SET,ERR_R_MALLOC_FAILURE);
135 goto err;
136 }
137 pp=p;
138 i2d_DSAparams(dsa,&pp);
139 if (!(a->parameter=ASN1_TYPE_new()))
140 {
141 OPENSSL_free(p);
142 X509err(X509_F_X509_PUBKEY_SET,ERR_R_MALLOC_FAILURE);
143 goto err;
144 }
145 a->parameter->type=V_ASN1_SEQUENCE;
146 if (!(a->parameter->value.sequence=ASN1_STRING_new()))
147 {
148 OPENSSL_free(p);
149 X509err(X509_F_X509_PUBKEY_SET,ERR_R_MALLOC_FAILURE);
150 goto err;
151 } 108 }
152 if (!ASN1_STRING_set(a->parameter->value.sequence,p,i)) 109 else
153 { 110 {
154 OPENSSL_free(p); 111 X509err(X509_F_X509_PUBKEY_SET,
155 X509err(X509_F_X509_PUBKEY_SET,ERR_R_MALLOC_FAILURE); 112 X509_R_METHOD_NOT_SUPPORTED);
156 goto err; 113 goto error;
157 } 114 }
158 OPENSSL_free(p);
159 } 115 }
160#endif 116 else
161#ifndef OPENSSL_NO_EC
162 else if (pkey->type == EVP_PKEY_EC)
163 {
164 int nid=0;
165 unsigned char *pp;
166 EC_KEY *ec_key;
167 const EC_GROUP *group;
168
169 ec_key = pkey->pkey.ec;
170 ASN1_TYPE_free(a->parameter);
171
172 if ((a->parameter = ASN1_TYPE_new()) == NULL)
173 {
174 X509err(X509_F_X509_PUBKEY_SET, ERR_R_ASN1_LIB);
175 goto err;
176 }
177
178 group = EC_KEY_get0_group(ec_key);
179 if (EC_GROUP_get_asn1_flag(group)
180 && (nid = EC_GROUP_get_curve_name(group)))
181 {
182 /* just set the OID */
183 a->parameter->type = V_ASN1_OBJECT;
184 a->parameter->value.object = OBJ_nid2obj(nid);
185 }
186 else /* explicit parameters */
187 {
188 if ((i = i2d_ECParameters(ec_key, NULL)) == 0)
189 {
190 X509err(X509_F_X509_PUBKEY_SET, ERR_R_EC_LIB);
191 goto err;
192 }
193 if ((p = (unsigned char *) OPENSSL_malloc(i)) == NULL)
194 {
195 X509err(X509_F_X509_PUBKEY_SET, ERR_R_MALLOC_FAILURE);
196 goto err;
197 }
198 pp = p;
199 if (!i2d_ECParameters(ec_key, &pp))
200 {
201 X509err(X509_F_X509_PUBKEY_SET, ERR_R_EC_LIB);
202 OPENSSL_free(p);
203 goto err;
204 }
205 a->parameter->type = V_ASN1_SEQUENCE;
206 if ((a->parameter->value.sequence = ASN1_STRING_new()) == NULL)
207 {
208 X509err(X509_F_X509_PUBKEY_SET, ERR_R_ASN1_LIB);
209 OPENSSL_free(p);
210 goto err;
211 }
212 ASN1_STRING_set(a->parameter->value.sequence, p, i);
213 OPENSSL_free(p);
214 }
215 }
216#endif
217 else if (1)
218 { 117 {
219 X509err(X509_F_X509_PUBKEY_SET,X509_R_UNSUPPORTED_ALGORITHM); 118 X509err(X509_F_X509_PUBKEY_SET,X509_R_UNSUPPORTED_ALGORITHM);
220 goto err; 119 goto error;
221 } 120 }
222 121
223 if ((i=i2d_PublicKey(pkey,NULL)) <= 0) goto err;
224 if ((s=(unsigned char *)OPENSSL_malloc(i+1)) == NULL)
225 {
226 X509err(X509_F_X509_PUBKEY_SET,ERR_R_MALLOC_FAILURE);
227 goto err;
228 }
229 p=s;
230 i2d_PublicKey(pkey,&p);
231 if (!M_ASN1_BIT_STRING_set(pk->public_key,s,i))
232 {
233 X509err(X509_F_X509_PUBKEY_SET,ERR_R_MALLOC_FAILURE);
234 goto err;
235 }
236 /* Set number of unused bits to zero */
237 pk->public_key->flags&= ~(ASN1_STRING_FLAG_BITS_LEFT|0x07);
238 pk->public_key->flags|=ASN1_STRING_FLAG_BITS_LEFT;
239
240 OPENSSL_free(s);
241
242#if 0
243 CRYPTO_add(&pkey->references,1,CRYPTO_LOCK_EVP_PKEY);
244 pk->pkey=pkey;
245#endif
246
247 if (*x != NULL) 122 if (*x != NULL)
248 X509_PUBKEY_free(*x); 123 X509_PUBKEY_free(*x);
249 124
250 *x=pk; 125 *x=pk;
251 126
252 return 1; 127 return 1;
253err: 128error:
254 if (pk != NULL) X509_PUBKEY_free(pk); 129 if (pk != NULL) X509_PUBKEY_free(pk);
255 return 0; 130 return 0;
256 } 131 }
@@ -258,119 +133,50 @@ err:
258EVP_PKEY *X509_PUBKEY_get(X509_PUBKEY *key) 133EVP_PKEY *X509_PUBKEY_get(X509_PUBKEY *key)
259 { 134 {
260 EVP_PKEY *ret=NULL; 135 EVP_PKEY *ret=NULL;
261 long j;
262 int type;
263 const unsigned char *p;
264#if !defined(OPENSSL_NO_DSA) || !defined(OPENSSL_NO_ECDSA)
265 const unsigned char *cp;
266 X509_ALGOR *a;
267#endif
268 136
269 if (key == NULL) goto err; 137 if (key == NULL) goto error;
270 138
271 if (key->pkey != NULL) 139 if (key->pkey != NULL)
272 { 140 {
273 CRYPTO_add(&key->pkey->references, 1, CRYPTO_LOCK_EVP_PKEY); 141 CRYPTO_add(&key->pkey->references, 1, CRYPTO_LOCK_EVP_PKEY);
274 return(key->pkey); 142 return key->pkey;
275 } 143 }
276 144
277 if (key->public_key == NULL) goto err; 145 if (key->public_key == NULL) goto error;
278 146
279 type=OBJ_obj2nid(key->algor->algorithm);
280 if ((ret = EVP_PKEY_new()) == NULL) 147 if ((ret = EVP_PKEY_new()) == NULL)
281 { 148 {
282 X509err(X509_F_X509_PUBKEY_GET, ERR_R_MALLOC_FAILURE); 149 X509err(X509_F_X509_PUBKEY_GET, ERR_R_MALLOC_FAILURE);
283 goto err; 150 goto error;
284 } 151 }
285 ret->type = EVP_PKEY_type(type);
286
287 /* the parameters must be extracted before the public key (ECDSA!) */
288
289#if !defined(OPENSSL_NO_DSA) || !defined(OPENSSL_NO_ECDSA)
290 a=key->algor;
291#endif
292 152
293 if (0) 153 if (!EVP_PKEY_set_type(ret, OBJ_obj2nid(key->algor->algorithm)))
294 ;
295#ifndef OPENSSL_NO_DSA
296 else if (ret->type == EVP_PKEY_DSA)
297 { 154 {
298 if (a->parameter && (a->parameter->type == V_ASN1_SEQUENCE)) 155 X509err(X509_F_X509_PUBKEY_GET,X509_R_UNSUPPORTED_ALGORITHM);
299 { 156 goto error;
300 if ((ret->pkey.dsa = DSA_new()) == NULL)
301 {
302 X509err(X509_F_X509_PUBKEY_GET, ERR_R_MALLOC_FAILURE);
303 goto err;
304 }
305 ret->pkey.dsa->write_params=0;
306 cp=p=a->parameter->value.sequence->data;
307 j=a->parameter->value.sequence->length;
308 if (!d2i_DSAparams(&ret->pkey.dsa, &cp, (long)j))
309 goto err;
310 }
311 ret->save_parameters=1;
312 } 157 }
313#endif 158
314#ifndef OPENSSL_NO_EC 159 if (ret->ameth->pub_decode)
315 else if (ret->type == EVP_PKEY_EC)
316 { 160 {
317 if (a->parameter && (a->parameter->type == V_ASN1_SEQUENCE)) 161 if (!ret->ameth->pub_decode(ret, key))
318 { 162 {
319 /* type == V_ASN1_SEQUENCE => we have explicit parameters 163 X509err(X509_F_X509_PUBKEY_GET,
320 * (e.g. parameters in the X9_62_EC_PARAMETERS-structure ) 164 X509_R_PUBLIC_KEY_DECODE_ERROR);
321 */ 165 goto error;
322 if ((ret->pkey.ec= EC_KEY_new()) == NULL)
323 {
324 X509err(X509_F_X509_PUBKEY_GET,
325 ERR_R_MALLOC_FAILURE);
326 goto err;
327 }
328 cp = p = a->parameter->value.sequence->data;
329 j = a->parameter->value.sequence->length;
330 if (!d2i_ECParameters(&ret->pkey.ec, &cp, (long)j))
331 {
332 X509err(X509_F_X509_PUBKEY_GET, ERR_R_EC_LIB);
333 goto err;
334 }
335 }
336 else if (a->parameter && (a->parameter->type == V_ASN1_OBJECT))
337 {
338 /* type == V_ASN1_OBJECT => the parameters are given
339 * by an asn1 OID
340 */
341 EC_KEY *ec_key;
342 EC_GROUP *group;
343
344 if (ret->pkey.ec == NULL)
345 ret->pkey.ec = EC_KEY_new();
346 ec_key = ret->pkey.ec;
347 if (ec_key == NULL)
348 goto err;
349 group = EC_GROUP_new_by_curve_name(OBJ_obj2nid(a->parameter->value.object));
350 if (group == NULL)
351 goto err;
352 EC_GROUP_set_asn1_flag(group, OPENSSL_EC_NAMED_CURVE);
353 if (EC_KEY_set_group(ec_key, group) == 0)
354 goto err;
355 EC_GROUP_free(group);
356 } 166 }
357 /* the case implicitlyCA is currently not implemented */
358 ret->save_parameters = 1;
359 } 167 }
360#endif 168 else
361
362 p=key->public_key->data;
363 j=key->public_key->length;
364 if (!d2i_PublicKey(type, &ret, &p, (long)j))
365 { 169 {
366 X509err(X509_F_X509_PUBKEY_GET, X509_R_ERR_ASN1_LIB); 170 X509err(X509_F_X509_PUBKEY_GET, X509_R_METHOD_NOT_SUPPORTED);
367 goto err; 171 goto error;
368 } 172 }
369 173
370 key->pkey = ret; 174 key->pkey = ret;
371 CRYPTO_add(&ret->references, 1, CRYPTO_LOCK_EVP_PKEY); 175 CRYPTO_add(&ret->references, 1, CRYPTO_LOCK_EVP_PKEY);
372 return(ret); 176
373err: 177 return ret;
178
179 error:
374 if (ret != NULL) 180 if (ret != NULL)
375 EVP_PKEY_free(ret); 181 EVP_PKEY_free(ret);
376 return(NULL); 182 return(NULL);
@@ -529,3 +335,39 @@ int i2d_EC_PUBKEY(EC_KEY *a, unsigned char **pp)
529 return(ret); 335 return(ret);
530 } 336 }
531#endif 337#endif
338
339int X509_PUBKEY_set0_param(X509_PUBKEY *pub, ASN1_OBJECT *aobj,
340 int ptype, void *pval,
341 unsigned char *penc, int penclen)
342 {
343 if (!X509_ALGOR_set0(pub->algor, aobj, ptype, pval))
344 return 0;
345 if (penc)
346 {
347 if (pub->public_key->data)
348 OPENSSL_free(pub->public_key->data);
349 pub->public_key->data = penc;
350 pub->public_key->length = penclen;
351 /* Set number of unused bits to zero */
352 pub->public_key->flags&= ~(ASN1_STRING_FLAG_BITS_LEFT|0x07);
353 pub->public_key->flags|=ASN1_STRING_FLAG_BITS_LEFT;
354 }
355 return 1;
356 }
357
358int X509_PUBKEY_get0_param(ASN1_OBJECT **ppkalg,
359 const unsigned char **pk, int *ppklen,
360 X509_ALGOR **pa,
361 X509_PUBKEY *pub)
362 {
363 if (ppkalg)
364 *ppkalg = pub->algor->algorithm;
365 if (pk)
366 {
367 *pk = pub->public_key->data;
368 *ppklen = pub->public_key->length;
369 }
370 if (pa)
371 *pa = pub->algor;
372 return 1;
373 }
diff --git a/src/lib/libcrypto/asn1/x_req.c b/src/lib/libcrypto/asn1/x_req.c
index 59ca8ce329..d57555827c 100644
--- a/src/lib/libcrypto/asn1/x_req.c
+++ b/src/lib/libcrypto/asn1/x_req.c
@@ -79,7 +79,8 @@
79 * 79 *
80 */ 80 */
81 81
82static int rinf_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it) 82static int rinf_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
83 void *exarg)
83{ 84{
84 X509_REQ_INFO *rinf = (X509_REQ_INFO *)*pval; 85 X509_REQ_INFO *rinf = (X509_REQ_INFO *)*pval;
85 86
diff --git a/src/lib/libcrypto/asn1/x_x509.c b/src/lib/libcrypto/asn1/x_x509.c
index e118696625..dafd3cc921 100644
--- a/src/lib/libcrypto/asn1/x_x509.c
+++ b/src/lib/libcrypto/asn1/x_x509.c
@@ -81,7 +81,8 @@ IMPLEMENT_ASN1_FUNCTIONS(X509_CINF)
81 81
82extern void policy_cache_free(X509_POLICY_CACHE *cache); 82extern void policy_cache_free(X509_POLICY_CACHE *cache);
83 83
84static int x509_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it) 84static int x509_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
85 void *exarg)
85{ 86{
86 X509 *ret = (X509 *)*pval; 87 X509 *ret = (X509 *)*pval;
87 88
@@ -99,6 +100,7 @@ static int x509_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it)
99 ret->rfc3779_asid = NULL; 100 ret->rfc3779_asid = NULL;
100#endif 101#endif
101 ret->aux = NULL; 102 ret->aux = NULL;
103 ret->crldp = NULL;
102 CRYPTO_new_ex_data(CRYPTO_EX_INDEX_X509, ret, &ret->ex_data); 104 CRYPTO_new_ex_data(CRYPTO_EX_INDEX_X509, ret, &ret->ex_data);
103 break; 105 break;
104 106
@@ -112,7 +114,10 @@ static int x509_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it)
112 X509_CERT_AUX_free(ret->aux); 114 X509_CERT_AUX_free(ret->aux);
113 ASN1_OCTET_STRING_free(ret->skid); 115 ASN1_OCTET_STRING_free(ret->skid);
114 AUTHORITY_KEYID_free(ret->akid); 116 AUTHORITY_KEYID_free(ret->akid);
117 CRL_DIST_POINTS_free(ret->crldp);
115 policy_cache_free(ret->policy_cache); 118 policy_cache_free(ret->policy_cache);
119 GENERAL_NAMES_free(ret->altname);
120 NAME_CONSTRAINTS_free(ret->nc);
116#ifndef OPENSSL_NO_RFC3779 121#ifndef OPENSSL_NO_RFC3779
117 sk_IPAddressFamily_pop_free(ret->rfc3779_addr, IPAddressFamily_free); 122 sk_IPAddressFamily_pop_free(ret->rfc3779_addr, IPAddressFamily_free);
118 ASIdentifiers_free(ret->rfc3779_asid); 123 ASIdentifiers_free(ret->rfc3779_asid);
@@ -136,19 +141,6 @@ ASN1_SEQUENCE_ref(X509, x509_cb, CRYPTO_LOCK_X509) = {
136IMPLEMENT_ASN1_FUNCTIONS(X509) 141IMPLEMENT_ASN1_FUNCTIONS(X509)
137IMPLEMENT_ASN1_DUP_FUNCTION(X509) 142IMPLEMENT_ASN1_DUP_FUNCTION(X509)
138 143
139static ASN1_METHOD meth=
140 {
141 (I2D_OF(void)) i2d_X509,
142 (D2I_OF(void)) d2i_X509,
143 (void *(*)(void))X509_new,
144 (void (*)(void *)) X509_free
145 };
146
147ASN1_METHOD *X509_asn1_meth(void)
148 {
149 return(&meth);
150 }
151
152int X509_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func, 144int X509_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
153 CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func) 145 CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func)
154 { 146 {
diff --git a/src/lib/libcrypto/bf/asm/bf-586.pl b/src/lib/libcrypto/bf/asm/bf-586.pl
index b556642c94..b74cfbafd4 100644
--- a/src/lib/libcrypto/bf/asm/bf-586.pl
+++ b/src/lib/libcrypto/bf/asm/bf-586.pl
@@ -1,6 +1,7 @@
1#!/usr/local/bin/perl 1#!/usr/local/bin/perl
2 2
3push(@INC,"perlasm","../../perlasm"); 3$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
4push(@INC,"${dir}","${dir}../../perlasm");
4require "x86asm.pl"; 5require "x86asm.pl";
5require "cbc.pl"; 6require "cbc.pl";
6 7
diff --git a/src/lib/libcrypto/bf/bf_skey.c b/src/lib/libcrypto/bf/bf_skey.c
index 6ac2aeb279..3673cdee6e 100644
--- a/src/lib/libcrypto/bf/bf_skey.c
+++ b/src/lib/libcrypto/bf/bf_skey.c
@@ -59,15 +59,10 @@
59#include <stdio.h> 59#include <stdio.h>
60#include <string.h> 60#include <string.h>
61#include <openssl/blowfish.h> 61#include <openssl/blowfish.h>
62#include <openssl/crypto.h>
63#ifdef OPENSSL_FIPS
64#include <openssl/fips.h>
65#endif
66
67#include "bf_locl.h" 62#include "bf_locl.h"
68#include "bf_pi.h" 63#include "bf_pi.h"
69 64
70FIPS_NON_FIPS_VCIPHER_Init(BF) 65void BF_set_key(BF_KEY *key, int len, const unsigned char *data)
71 { 66 {
72 int i; 67 int i;
73 BF_LONG *p,ri,in[2]; 68 BF_LONG *p,ri,in[2];
diff --git a/src/lib/libcrypto/bf/blowfish.h b/src/lib/libcrypto/bf/blowfish.h
index d24ffccb65..b97e76f9a3 100644
--- a/src/lib/libcrypto/bf/blowfish.h
+++ b/src/lib/libcrypto/bf/blowfish.h
@@ -79,7 +79,7 @@ extern "C" {
79 * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 79 * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
80 */ 80 */
81 81
82#if defined(OPENSSL_SYS_WIN16) || defined(__LP32__) 82#if defined(__LP32__)
83#define BF_LONG unsigned long 83#define BF_LONG unsigned long
84#elif defined(OPENSSL_SYS_CRAY) || defined(__ILP64__) 84#elif defined(OPENSSL_SYS_CRAY) || defined(__ILP64__)
85#define BF_LONG unsigned long 85#define BF_LONG unsigned long
@@ -104,9 +104,7 @@ typedef struct bf_key_st
104 BF_LONG S[4*256]; 104 BF_LONG S[4*256];
105 } BF_KEY; 105 } BF_KEY;
106 106
107#ifdef OPENSSL_FIPS 107
108void private_BF_set_key(BF_KEY *key, int len, const unsigned char *data);
109#endif
110void BF_set_key(BF_KEY *key, int len, const unsigned char *data); 108void BF_set_key(BF_KEY *key, int len, const unsigned char *data);
111 109
112void BF_encrypt(BF_LONG *data,const BF_KEY *key); 110void BF_encrypt(BF_LONG *data,const BF_KEY *key);
diff --git a/src/lib/libcrypto/bio/b_print.c b/src/lib/libcrypto/bio/b_print.c
index 3a87b0ec0b..143a7cfefa 100644
--- a/src/lib/libcrypto/bio/b_print.c
+++ b/src/lib/libcrypto/bio/b_print.c
@@ -115,8 +115,8 @@
115#define LDOUBLE double 115#define LDOUBLE double
116#endif 116#endif
117 117
118#if HAVE_LONG_LONG 118#ifdef HAVE_LONG_LONG
119# if defined(OPENSSL_SYS_WIN32) && !defined(__GNUC__) 119# if defined(_WIN32) && !defined(__GNUC__)
120# define LLONG __int64 120# define LLONG __int64
121# else 121# else
122# define LLONG long long 122# define LLONG long long
diff --git a/src/lib/libcrypto/bio/b_sock.c b/src/lib/libcrypto/bio/b_sock.c
index ead477d8a2..12b0a53a81 100644
--- a/src/lib/libcrypto/bio/b_sock.c
+++ b/src/lib/libcrypto/bio/b_sock.c
@@ -72,11 +72,9 @@ NETDB_DEFINE_CONTEXT
72 72
73#ifndef OPENSSL_NO_SOCK 73#ifndef OPENSSL_NO_SOCK
74 74
75#ifdef OPENSSL_SYS_WIN16 75#include <openssl/dso.h>
76#define SOCKET_PROTOCOL 0 /* more microsoft stupidity */ 76
77#else
78#define SOCKET_PROTOCOL IPPROTO_TCP 77#define SOCKET_PROTOCOL IPPROTO_TCP
79#endif
80 78
81#ifdef SO_MAXCONN 79#ifdef SO_MAXCONN
82#define MAX_LISTEN SO_MAXCONN 80#define MAX_LISTEN SO_MAXCONN
@@ -90,6 +88,17 @@ NETDB_DEFINE_CONTEXT
90static int wsa_init_done=0; 88static int wsa_init_done=0;
91#endif 89#endif
92 90
91/*
92 * WSAAPI specifier is required to make indirect calls to run-time
93 * linked WinSock 2 functions used in this module, to be specific
94 * [get|free]addrinfo and getnameinfo. This is because WinSock uses
95 * uses non-C calling convention, __stdcall vs. __cdecl, on x86
96 * Windows. On non-WinSock platforms WSAAPI needs to be void.
97 */
98#ifndef WSAAPI
99#define WSAAPI
100#endif
101
93#if 0 102#if 0
94static unsigned long BIO_ghbn_hits=0L; 103static unsigned long BIO_ghbn_hits=0L;
95static unsigned long BIO_ghbn_miss=0L; 104static unsigned long BIO_ghbn_miss=0L;
@@ -226,6 +235,10 @@ int BIO_sock_error(int sock)
226 int j,i; 235 int j,i;
227 int size; 236 int size;
228 237
238#if defined(OPENSSL_SYS_BEOS_R5)
239 return 0;
240#endif
241
229 size=sizeof(int); 242 size=sizeof(int);
230 /* Note: under Windows the third parameter is of type (char *) 243 /* Note: under Windows the third parameter is of type (char *)
231 * whereas under other systems it is (void *) if you don't have 244 * whereas under other systems it is (void *) if you don't have
@@ -466,7 +479,12 @@ int BIO_sock_init(void)
466 479
467 wsa_init_done=1; 480 wsa_init_done=1;
468 memset(&wsa_state,0,sizeof(wsa_state)); 481 memset(&wsa_state,0,sizeof(wsa_state));
469 if (WSAStartup(0x0101,&wsa_state)!=0) 482 /* Not making wsa_state available to the rest of the
483 * code is formally wrong. But the structures we use
484 * are [beleived to be] invariable among Winsock DLLs,
485 * while API availability is [expected to be] probed
486 * at run-time with DSO_global_lookup. */
487 if (WSAStartup(0x0202,&wsa_state)!=0)
470 { 488 {
471 err=WSAGetLastError(); 489 err=WSAGetLastError();
472 SYSerr(SYS_F_WSASTARTUP,err); 490 SYSerr(SYS_F_WSASTARTUP,err);
@@ -510,8 +528,8 @@ void BIO_sock_cleanup(void)
510 if (wsa_init_done) 528 if (wsa_init_done)
511 { 529 {
512 wsa_init_done=0; 530 wsa_init_done=0;
513#ifndef OPENSSL_SYS_WINCE 531#if 0 /* this call is claimed to be non-present in Winsock2 */
514 WSACancelBlockingCall(); /* Winsock 1.1 specific */ 532 WSACancelBlockingCall();
515#endif 533#endif
516 WSACleanup(); 534 WSACleanup();
517 } 535 }
@@ -581,12 +599,18 @@ static int get_ip(const char *str, unsigned char ip[4])
581int BIO_get_accept_socket(char *host, int bind_mode) 599int BIO_get_accept_socket(char *host, int bind_mode)
582 { 600 {
583 int ret=0; 601 int ret=0;
584 struct sockaddr_in server,client; 602 union {
585 int s=INVALID_SOCKET,cs; 603 struct sockaddr sa;
604 struct sockaddr_in sa_in;
605#if OPENSSL_USE_IPV6
606 struct sockaddr_in6 sa_in6;
607#endif
608 } server,client;
609 int s=INVALID_SOCKET,cs,addrlen;
586 unsigned char ip[4]; 610 unsigned char ip[4];
587 unsigned short port; 611 unsigned short port;
588 char *str=NULL,*e; 612 char *str=NULL,*e;
589 const char *h,*p; 613 char *h,*p;
590 unsigned long l; 614 unsigned long l;
591 int err_num; 615 int err_num;
592 616
@@ -600,8 +624,7 @@ int BIO_get_accept_socket(char *host, int bind_mode)
600 { 624 {
601 if (*e == ':') 625 if (*e == ':')
602 { 626 {
603 p= &(e[1]); 627 p=e;
604 *e='\0';
605 } 628 }
606 else if (*e == '/') 629 else if (*e == '/')
607 { 630 {
@@ -609,21 +632,70 @@ int BIO_get_accept_socket(char *host, int bind_mode)
609 break; 632 break;
610 } 633 }
611 } 634 }
612 635 if (p) *p++='\0'; /* points at last ':', '::port' is special [see below] */
613 if (p == NULL) 636 else p=h,h=NULL;
637
638#ifdef EAI_FAMILY
639 do {
640 static union { void *p;
641 int (WSAAPI *f)(const char *,const char *,
642 const struct addrinfo *,
643 struct addrinfo **);
644 } p_getaddrinfo = {NULL};
645 static union { void *p;
646 void (WSAAPI *f)(struct addrinfo *);
647 } p_freeaddrinfo = {NULL};
648 struct addrinfo *res,hint;
649
650 if (p_getaddrinfo.p==NULL)
651 {
652 if ((p_getaddrinfo.p=DSO_global_lookup("getaddrinfo"))==NULL ||
653 (p_freeaddrinfo.p=DSO_global_lookup("freeaddrinfo"))==NULL)
654 p_getaddrinfo.p=(void*)-1;
655 }
656 if (p_getaddrinfo.p==(void *)-1) break;
657
658 /* '::port' enforces IPv6 wildcard listener. Some OSes,
659 * e.g. Solaris, default to IPv6 without any hint. Also
660 * note that commonly IPv6 wildchard socket can service
661 * IPv4 connections just as well... */
662 memset(&hint,0,sizeof(hint));
663 if (h)
614 { 664 {
615 p=h; 665 if (strchr(h,':'))
616 h="*"; 666 {
667 if (h[1]=='\0') h=NULL;
668#if OPENSSL_USE_IPV6
669 hint.ai_family = AF_INET6;
670#else
671 h=NULL;
672#endif
673 }
674 else if (h[0]=='*' && h[1]=='\0')
675 h=NULL;
617 } 676 }
618 677
678 if ((*p_getaddrinfo.f)(h,p,&hint,&res)) break;
679
680 addrlen = res->ai_addrlen<=sizeof(server) ?
681 res->ai_addrlen :
682 sizeof(server);
683 memcpy(&server, res->ai_addr, addrlen);
684
685 (*p_freeaddrinfo.f)(res);
686 goto again;
687 } while (0);
688#endif
689
619 if (!BIO_get_port(p,&port)) goto err; 690 if (!BIO_get_port(p,&port)) goto err;
620 691
621 memset((char *)&server,0,sizeof(server)); 692 memset((char *)&server,0,sizeof(server));
622 server.sin_family=AF_INET; 693 server.sa_in.sin_family=AF_INET;
623 server.sin_port=htons(port); 694 server.sa_in.sin_port=htons(port);
695 addrlen = sizeof(server.sa_in);
624 696
625 if (strcmp(h,"*") == 0) 697 if (h == NULL || strcmp(h,"*") == 0)
626 server.sin_addr.s_addr=INADDR_ANY; 698 server.sa_in.sin_addr.s_addr=INADDR_ANY;
627 else 699 else
628 { 700 {
629 if (!BIO_get_host_ip(h,&(ip[0]))) goto err; 701 if (!BIO_get_host_ip(h,&(ip[0]))) goto err;
@@ -632,11 +704,11 @@ int BIO_get_accept_socket(char *host, int bind_mode)
632 ((unsigned long)ip[1]<<16L)| 704 ((unsigned long)ip[1]<<16L)|
633 ((unsigned long)ip[2]<< 8L)| 705 ((unsigned long)ip[2]<< 8L)|
634 ((unsigned long)ip[3]); 706 ((unsigned long)ip[3]);
635 server.sin_addr.s_addr=htonl(l); 707 server.sa_in.sin_addr.s_addr=htonl(l);
636 } 708 }
637 709
638again: 710again:
639 s=socket(AF_INET,SOCK_STREAM,SOCKET_PROTOCOL); 711 s=socket(server.sa.sa_family,SOCK_STREAM,SOCKET_PROTOCOL);
640 if (s == INVALID_SOCKET) 712 if (s == INVALID_SOCKET)
641 { 713 {
642 SYSerr(SYS_F_SOCKET,get_last_socket_error()); 714 SYSerr(SYS_F_SOCKET,get_last_socket_error());
@@ -654,22 +726,42 @@ again:
654 bind_mode=BIO_BIND_NORMAL; 726 bind_mode=BIO_BIND_NORMAL;
655 } 727 }
656#endif 728#endif
657 if (bind(s,(struct sockaddr *)&server,sizeof(server)) == -1) 729 if (bind(s,&server.sa,addrlen) == -1)
658 { 730 {
659#ifdef SO_REUSEADDR 731#ifdef SO_REUSEADDR
660 err_num=get_last_socket_error(); 732 err_num=get_last_socket_error();
661 if ((bind_mode == BIO_BIND_REUSEADDR_IF_UNUSED) && 733 if ((bind_mode == BIO_BIND_REUSEADDR_IF_UNUSED) &&
734#ifdef OPENSSL_SYS_WINDOWS
735 /* Some versions of Windows define EADDRINUSE to
736 * a dummy value.
737 */
738 (err_num == WSAEADDRINUSE))
739#else
662 (err_num == EADDRINUSE)) 740 (err_num == EADDRINUSE))
741#endif
663 { 742 {
664 memcpy((char *)&client,(char *)&server,sizeof(server)); 743 client = server;
665 if (strcmp(h,"*") == 0) 744 if (h == NULL || strcmp(h,"*") == 0)
666 client.sin_addr.s_addr=htonl(0x7F000001); 745 {
667 cs=socket(AF_INET,SOCK_STREAM,SOCKET_PROTOCOL); 746#if OPENSSL_USE_IPV6
747 if (client.sa.sa_family == AF_INET6)
748 {
749 memset(&client.sa_in6.sin6_addr,0,sizeof(client.sa_in6.sin6_addr));
750 client.sa_in6.sin6_addr.s6_addr[15]=1;
751 }
752 else
753#endif
754 if (client.sa.sa_family == AF_INET)
755 {
756 client.sa_in.sin_addr.s_addr=htonl(0x7F000001);
757 }
758 else goto err;
759 }
760 cs=socket(client.sa.sa_family,SOCK_STREAM,SOCKET_PROTOCOL);
668 if (cs != INVALID_SOCKET) 761 if (cs != INVALID_SOCKET)
669 { 762 {
670 int ii; 763 int ii;
671 ii=connect(cs,(struct sockaddr *)&client, 764 ii=connect(cs,&client.sa,addrlen);
672 sizeof(client));
673 closesocket(cs); 765 closesocket(cs);
674 if (ii == INVALID_SOCKET) 766 if (ii == INVALID_SOCKET)
675 { 767 {
@@ -708,20 +800,52 @@ err:
708int BIO_accept(int sock, char **addr) 800int BIO_accept(int sock, char **addr)
709 { 801 {
710 int ret=INVALID_SOCKET; 802 int ret=INVALID_SOCKET;
711 static struct sockaddr_in from;
712 unsigned long l; 803 unsigned long l;
713 unsigned short port; 804 unsigned short port;
714 int len;
715 char *p; 805 char *p;
716 806
717 memset((char *)&from,0,sizeof(from)); 807 struct {
718 len=sizeof(from); 808 /*
719 /* Note: under VMS with SOCKETSHR the fourth parameter is currently 809 * As for following union. Trouble is that there are platforms
720 * of type (int *) whereas under other systems it is (void *) if 810 * that have socklen_t and there are platforms that don't, on
721 * you don't have a cast it will choke the compiler: if you do 811 * some platforms socklen_t is int and on some size_t. So what
722 * have a cast then you can either go for (int *) or (void *). 812 * one can do? One can cook #ifdef spaghetti, which is nothing
813 * but masochistic. Or one can do union between int and size_t.
814 * One naturally does it primarily for 64-bit platforms where
815 * sizeof(int) != sizeof(size_t). But would it work? Note that
816 * if size_t member is initialized to 0, then later int member
817 * assignment naturally does the job on little-endian platforms
818 * regardless accept's expectations! What about big-endians?
819 * If accept expects int*, then it works, and if size_t*, then
820 * length value would appear as unreasonably large. But this
821 * won't prevent it from filling in the address structure. The
822 * trouble of course would be if accept returns more data than
823 * actual buffer can accomodate and overwrite stack... That's
824 * where early OPENSSL_assert comes into picture. Besides, the
825 * only 64-bit big-endian platform found so far that expects
826 * size_t* is HP-UX, where stack grows towards higher address.
827 * <appro>
723 */ 828 */
724 ret=accept(sock,(struct sockaddr *)&from,(void *)&len); 829 union { size_t s; int i; } len;
830 union {
831 struct sockaddr sa;
832 struct sockaddr_in sa_in;
833#if OPENSSL_USE_IPV6
834 struct sockaddr_in6 sa_in6;
835#endif
836 } from;
837 } sa;
838
839 sa.len.s=0;
840 sa.len.i=sizeof(sa.from);
841 memset(&sa.from,0,sizeof(sa.from));
842 ret=accept(sock,&sa.from.sa,(void *)&sa.len);
843 if (sizeof(sa.len.i)!=sizeof(sa.len.s) && sa.len.i==0)
844 {
845 OPENSSL_assert(sa.len.s<=sizeof(sa.from));
846 sa.len.i = (int)sa.len.s;
847 /* use sa.len.i from this point */
848 }
725 if (ret == INVALID_SOCKET) 849 if (ret == INVALID_SOCKET)
726 { 850 {
727 if(BIO_sock_should_retry(ret)) return -2; 851 if(BIO_sock_should_retry(ret)) return -2;
@@ -732,8 +856,46 @@ int BIO_accept(int sock, char **addr)
732 856
733 if (addr == NULL) goto end; 857 if (addr == NULL) goto end;
734 858
735 l=ntohl(from.sin_addr.s_addr); 859#ifdef EAI_FAMILY
736 port=ntohs(from.sin_port); 860 do {
861 char h[NI_MAXHOST],s[NI_MAXSERV];
862 size_t nl;
863 static union { void *p;
864 int (WSAAPI *f)(const struct sockaddr *,size_t/*socklen_t*/,
865 char *,size_t,char *,size_t,int);
866 } p_getnameinfo = {NULL};
867 /* 2nd argument to getnameinfo is specified to
868 * be socklen_t. Unfortunately there is a number
869 * of environments where socklen_t is not defined.
870 * As it's passed by value, it's safe to pass it
871 * as size_t... <appro> */
872
873 if (p_getnameinfo.p==NULL)
874 {
875 if ((p_getnameinfo.p=DSO_global_lookup("getnameinfo"))==NULL)
876 p_getnameinfo.p=(void*)-1;
877 }
878 if (p_getnameinfo.p==(void *)-1) break;
879
880 if ((*p_getnameinfo.f)(&sa.from.sa,sa.len.i,h,sizeof(h),s,sizeof(s),
881 NI_NUMERICHOST|NI_NUMERICSERV)) break;
882 nl = strlen(h)+strlen(s)+2;
883 p = *addr;
884 if (p) { *p = '\0'; p = OPENSSL_realloc(p,nl); }
885 else { p = OPENSSL_malloc(nl); }
886 if (p==NULL)
887 {
888 BIOerr(BIO_F_BIO_ACCEPT,ERR_R_MALLOC_FAILURE);
889 goto end;
890 }
891 *addr = p;
892 BIO_snprintf(*addr,nl,"%s:%s",h,s);
893 goto end;
894 } while(0);
895#endif
896 if (sa.from.sa.sa_family != AF_INET) goto end;
897 l=ntohl(sa.from.sa_in.sin_addr.s_addr);
898 port=ntohs(sa.from.sa_in.sin_port);
737 if (*addr == NULL) 899 if (*addr == NULL)
738 { 900 {
739 if ((p=OPENSSL_malloc(24)) == NULL) 901 if ((p=OPENSSL_malloc(24)) == NULL)
diff --git a/src/lib/libcrypto/bio/bio.h b/src/lib/libcrypto/bio/bio.h
index cecb6a7207..152802fbdf 100644
--- a/src/lib/libcrypto/bio/bio.h
+++ b/src/lib/libcrypto/bio/bio.h
@@ -95,6 +95,7 @@ extern "C" {
95#define BIO_TYPE_BIO (19|0x0400) /* (half a) BIO pair */ 95#define BIO_TYPE_BIO (19|0x0400) /* (half a) BIO pair */
96#define BIO_TYPE_LINEBUFFER (20|0x0200) /* filter */ 96#define BIO_TYPE_LINEBUFFER (20|0x0200) /* filter */
97#define BIO_TYPE_DGRAM (21|0x0400|0x0100) 97#define BIO_TYPE_DGRAM (21|0x0400|0x0100)
98#define BIO_TYPE_ASN1 (22|0x0200) /* filter */
98#define BIO_TYPE_COMP (23|0x0200) /* filter */ 99#define BIO_TYPE_COMP (23|0x0200) /* filter */
99 100
100#define BIO_TYPE_DESCRIPTOR 0x0100 /* socket, fd, connect or accept */ 101#define BIO_TYPE_DESCRIPTOR 0x0100 /* socket, fd, connect or accept */
@@ -156,8 +157,11 @@ extern "C" {
156 * previous write 157 * previous write
157 * operation */ 158 * operation */
158 159
160#define BIO_CTRL_DGRAM_GET_PEER 46
159#define BIO_CTRL_DGRAM_SET_PEER 44 /* Destination for the data */ 161#define BIO_CTRL_DGRAM_SET_PEER 44 /* Destination for the data */
160 162
163#define BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT 45 /* Next DTLS handshake timeout to
164 * adjust socket timeouts */
161 165
162/* modifiers */ 166/* modifiers */
163#define BIO_FP_READ 0x02 167#define BIO_FP_READ 0x02
@@ -262,7 +266,6 @@ int BIO_method_type(const BIO *b);
262 266
263typedef void bio_info_cb(struct bio_st *, int, const char *, int, long, long); 267typedef void bio_info_cb(struct bio_st *, int, const char *, int, long, long);
264 268
265#ifndef OPENSSL_SYS_WIN16
266typedef struct bio_method_st 269typedef struct bio_method_st
267 { 270 {
268 int type; 271 int type;
@@ -276,21 +279,6 @@ typedef struct bio_method_st
276 int (*destroy)(BIO *); 279 int (*destroy)(BIO *);
277 long (*callback_ctrl)(BIO *, int, bio_info_cb *); 280 long (*callback_ctrl)(BIO *, int, bio_info_cb *);
278 } BIO_METHOD; 281 } BIO_METHOD;
279#else
280typedef struct bio_method_st
281 {
282 int type;
283 const char *name;
284 int (_far *bwrite)();
285 int (_far *bread)();
286 int (_far *bputs)();
287 int (_far *bgets)();
288 long (_far *ctrl)();
289 int (_far *create)();
290 int (_far *destroy)();
291 long (_far *callback_ctrl)();
292 } BIO_METHOD;
293#endif
294 282
295struct bio_st 283struct bio_st
296 { 284 {
@@ -331,6 +319,9 @@ typedef struct bio_f_buffer_ctx_struct
331 int obuf_off; /* write/read offset */ 319 int obuf_off; /* write/read offset */
332 } BIO_F_BUFFER_CTX; 320 } BIO_F_BUFFER_CTX;
333 321
322/* Prefix and suffix callback in ASN1 BIO */
323typedef int asn1_ps_func(BIO *b, unsigned char **pbuf, int *plen, void *parg);
324
334/* connect BIO stuff */ 325/* connect BIO stuff */
335#define BIO_CONN_S_BEFORE 1 326#define BIO_CONN_S_BEFORE 1
336#define BIO_CONN_S_GET_IP 2 327#define BIO_CONN_S_GET_IP 2
@@ -393,6 +384,13 @@ typedef struct bio_f_buffer_ctx_struct
393#define BIO_C_RESET_READ_REQUEST 147 384#define BIO_C_RESET_READ_REQUEST 147
394#define BIO_C_SET_MD_CTX 148 385#define BIO_C_SET_MD_CTX 148
395 386
387#define BIO_C_SET_PREFIX 149
388#define BIO_C_GET_PREFIX 150
389#define BIO_C_SET_SUFFIX 151
390#define BIO_C_GET_SUFFIX 152
391
392#define BIO_C_SET_EX_ARG 153
393#define BIO_C_GET_EX_ARG 154
396 394
397#define BIO_set_app_data(s,arg) BIO_set_ex_data(s,0,arg) 395#define BIO_set_app_data(s,arg) BIO_set_ex_data(s,0,arg)
398#define BIO_get_app_data(s) BIO_get_ex_data(s,0) 396#define BIO_get_app_data(s) BIO_get_ex_data(s,0)
@@ -405,7 +403,7 @@ typedef struct bio_f_buffer_ctx_struct
405#define BIO_get_conn_hostname(b) BIO_ptr_ctrl(b,BIO_C_GET_CONNECT,0) 403#define BIO_get_conn_hostname(b) BIO_ptr_ctrl(b,BIO_C_GET_CONNECT,0)
406#define BIO_get_conn_port(b) BIO_ptr_ctrl(b,BIO_C_GET_CONNECT,1) 404#define BIO_get_conn_port(b) BIO_ptr_ctrl(b,BIO_C_GET_CONNECT,1)
407#define BIO_get_conn_ip(b) BIO_ptr_ctrl(b,BIO_C_GET_CONNECT,2) 405#define BIO_get_conn_ip(b) BIO_ptr_ctrl(b,BIO_C_GET_CONNECT,2)
408#define BIO_get_conn_int_port(b) BIO_int_ctrl(b,BIO_C_GET_CONNECT,3) 406#define BIO_get_conn_int_port(b) BIO_int_ctrl(b,BIO_C_GET_CONNECT,3,0)
409 407
410 408
411#define BIO_set_nbio(b,n) BIO_ctrl(b,BIO_C_SET_NBIO,(n),NULL) 409#define BIO_set_nbio(b,n) BIO_ctrl(b,BIO_C_SET_NBIO,(n),NULL)
@@ -414,7 +412,7 @@ typedef struct bio_f_buffer_ctx_struct
414#define BIO_set_accept_port(b,name) BIO_ctrl(b,BIO_C_SET_ACCEPT,0,(char *)name) 412#define BIO_set_accept_port(b,name) BIO_ctrl(b,BIO_C_SET_ACCEPT,0,(char *)name)
415#define BIO_get_accept_port(b) BIO_ptr_ctrl(b,BIO_C_GET_ACCEPT,0) 413#define BIO_get_accept_port(b) BIO_ptr_ctrl(b,BIO_C_GET_ACCEPT,0)
416/* #define BIO_set_nbio(b,n) BIO_ctrl(b,BIO_C_SET_NBIO,(n),NULL) */ 414/* #define BIO_set_nbio(b,n) BIO_ctrl(b,BIO_C_SET_NBIO,(n),NULL) */
417#define BIO_set_nbio_accept(b,n) BIO_ctrl(b,BIO_C_SET_ACCEPT,1,(n)?"a":NULL) 415#define BIO_set_nbio_accept(b,n) BIO_ctrl(b,BIO_C_SET_ACCEPT,1,(n)?(void *)"a":NULL)
418#define BIO_set_accept_bios(b,bio) BIO_ctrl(b,BIO_C_SET_ACCEPT,2,(char *)bio) 416#define BIO_set_accept_bios(b,bio) BIO_ctrl(b,BIO_C_SET_ACCEPT,2,(char *)bio)
419 417
420#define BIO_BIND_NORMAL 0 418#define BIO_BIND_NORMAL 0
@@ -541,6 +539,8 @@ int BIO_ctrl_reset_read_request(BIO *b);
541 (int)BIO_ctrl(b, BIO_CTRL_DGRAM_GET_RECV_TIMER_EXP, 0, NULL) 539 (int)BIO_ctrl(b, BIO_CTRL_DGRAM_GET_RECV_TIMER_EXP, 0, NULL)
542#define BIO_dgram_send_timedout(b) \ 540#define BIO_dgram_send_timedout(b) \
543 (int)BIO_ctrl(b, BIO_CTRL_DGRAM_GET_SEND_TIMER_EXP, 0, NULL) 541 (int)BIO_ctrl(b, BIO_CTRL_DGRAM_GET_SEND_TIMER_EXP, 0, NULL)
542#define BIO_dgram_get_peer(b,peer) \
543 (int)BIO_ctrl(b, BIO_CTRL_DGRAM_GET_PEER, 0, (char *)peer)
544#define BIO_dgram_set_peer(b,peer) \ 544#define BIO_dgram_set_peer(b,peer) \
545 (int)BIO_ctrl(b, BIO_CTRL_DGRAM_SET_PEER, 0, (char *)peer) 545 (int)BIO_ctrl(b, BIO_CTRL_DGRAM_SET_PEER, 0, (char *)peer)
546 546
@@ -554,22 +554,21 @@ int BIO_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
554unsigned long BIO_number_read(BIO *bio); 554unsigned long BIO_number_read(BIO *bio);
555unsigned long BIO_number_written(BIO *bio); 555unsigned long BIO_number_written(BIO *bio);
556 556
557/* For BIO_f_asn1() */
558int BIO_asn1_set_prefix(BIO *b, asn1_ps_func *prefix,
559 asn1_ps_func *prefix_free);
560int BIO_asn1_get_prefix(BIO *b, asn1_ps_func **pprefix,
561 asn1_ps_func **pprefix_free);
562int BIO_asn1_set_suffix(BIO *b, asn1_ps_func *suffix,
563 asn1_ps_func *suffix_free);
564int BIO_asn1_get_suffix(BIO *b, asn1_ps_func **psuffix,
565 asn1_ps_func **psuffix_free);
566
557# ifndef OPENSSL_NO_FP_API 567# ifndef OPENSSL_NO_FP_API
558# if defined(OPENSSL_SYS_WIN16) && defined(_WINDLL)
559BIO_METHOD *BIO_s_file_internal(void);
560BIO *BIO_new_file_internal(char *filename, char *mode);
561BIO *BIO_new_fp_internal(FILE *stream, int close_flag);
562# define BIO_s_file BIO_s_file_internal
563# define BIO_new_file BIO_new_file_internal
564# define BIO_new_fp BIO_new_fp_internal
565# else /* FP_API */
566BIO_METHOD *BIO_s_file(void ); 568BIO_METHOD *BIO_s_file(void );
567BIO *BIO_new_file(const char *filename, const char *mode); 569BIO *BIO_new_file(const char *filename, const char *mode);
568BIO *BIO_new_fp(FILE *stream, int close_flag); 570BIO *BIO_new_fp(FILE *stream, int close_flag);
569# define BIO_s_file_internal BIO_s_file 571# define BIO_s_file_internal BIO_s_file
570# define BIO_new_file_internal BIO_new_file
571# define BIO_new_fp_internal BIO_s_file
572# endif /* FP_API */
573# endif 572# endif
574BIO * BIO_new(BIO_METHOD *type); 573BIO * BIO_new(BIO_METHOD *type);
575int BIO_set(BIO *a,BIO_METHOD *type); 574int BIO_set(BIO *a,BIO_METHOD *type);
@@ -598,13 +597,8 @@ int BIO_nread(BIO *bio, char **buf, int num);
598int BIO_nwrite0(BIO *bio, char **buf); 597int BIO_nwrite0(BIO *bio, char **buf);
599int BIO_nwrite(BIO *bio, char **buf, int num); 598int BIO_nwrite(BIO *bio, char **buf, int num);
600 599
601#ifndef OPENSSL_SYS_WIN16
602long BIO_debug_callback(BIO *bio,int cmd,const char *argp,int argi, 600long BIO_debug_callback(BIO *bio,int cmd,const char *argp,int argi,
603 long argl,long ret); 601 long argl,long ret);
604#else
605long _far _loadds BIO_debug_callback(BIO *bio,int cmd,const char *argp,int argi,
606 long argl,long ret);
607#endif
608 602
609BIO_METHOD *BIO_s_mem(void); 603BIO_METHOD *BIO_s_mem(void);
610BIO *BIO_new_mem_buf(void *buf, int len); 604BIO *BIO_new_mem_buf(void *buf, int len);
diff --git a/src/lib/libcrypto/bio/bio_cb.c b/src/lib/libcrypto/bio/bio_cb.c
index 6f4254a114..9bcbc321d9 100644
--- a/src/lib/libcrypto/bio/bio_cb.c
+++ b/src/lib/libcrypto/bio/bio_cb.c
@@ -85,28 +85,32 @@ long MS_CALLBACK BIO_debug_callback(BIO *bio, int cmd, const char *argp,
85 break; 85 break;
86 case BIO_CB_READ: 86 case BIO_CB_READ:
87 if (bio->method->type & BIO_TYPE_DESCRIPTOR) 87 if (bio->method->type & BIO_TYPE_DESCRIPTOR)
88 BIO_snprintf(p,p_maxlen,"read(%d,%d) - %s fd=%d\n", 88 BIO_snprintf(p,p_maxlen,"read(%d,%lu) - %s fd=%d\n",
89 bio->num,argi,bio->method->name,bio->num); 89 bio->num,(unsigned long)argi,
90 bio->method->name,bio->num);
90 else 91 else
91 BIO_snprintf(p,p_maxlen,"read(%d,%d) - %s\n", 92 BIO_snprintf(p,p_maxlen,"read(%d,%lu) - %s\n",
92 bio->num,argi,bio->method->name); 93 bio->num,(unsigned long)argi,
94 bio->method->name);
93 break; 95 break;
94 case BIO_CB_WRITE: 96 case BIO_CB_WRITE:
95 if (bio->method->type & BIO_TYPE_DESCRIPTOR) 97 if (bio->method->type & BIO_TYPE_DESCRIPTOR)
96 BIO_snprintf(p,p_maxlen,"write(%d,%d) - %s fd=%d\n", 98 BIO_snprintf(p,p_maxlen,"write(%d,%lu) - %s fd=%d\n",
97 bio->num,argi,bio->method->name,bio->num); 99 bio->num,(unsigned long)argi,
100 bio->method->name,bio->num);
98 else 101 else
99 BIO_snprintf(p,p_maxlen,"write(%d,%d) - %s\n", 102 BIO_snprintf(p,p_maxlen,"write(%d,%lu) - %s\n",
100 bio->num,argi,bio->method->name); 103 bio->num,(unsigned long)argi,
104 bio->method->name);
101 break; 105 break;
102 case BIO_CB_PUTS: 106 case BIO_CB_PUTS:
103 BIO_snprintf(p,p_maxlen,"puts() - %s\n",bio->method->name); 107 BIO_snprintf(p,p_maxlen,"puts() - %s\n",bio->method->name);
104 break; 108 break;
105 case BIO_CB_GETS: 109 case BIO_CB_GETS:
106 BIO_snprintf(p,p_maxlen,"gets(%d) - %s\n",argi,bio->method->name); 110 BIO_snprintf(p,p_maxlen,"gets(%lu) - %s\n",(unsigned long)argi,bio->method->name);
107 break; 111 break;
108 case BIO_CB_CTRL: 112 case BIO_CB_CTRL:
109 BIO_snprintf(p,p_maxlen,"ctrl(%d) - %s\n",argi,bio->method->name); 113 BIO_snprintf(p,p_maxlen,"ctrl(%lu) - %s\n",(unsigned long)argi,bio->method->name);
110 break; 114 break;
111 case BIO_CB_RETURN|BIO_CB_READ: 115 case BIO_CB_RETURN|BIO_CB_READ:
112 BIO_snprintf(p,p_maxlen,"read return %ld\n",ret); 116 BIO_snprintf(p,p_maxlen,"read return %ld\n",ret);
diff --git a/src/lib/libcrypto/bio/bio_err.c b/src/lib/libcrypto/bio/bio_err.c
index 6603f1c74d..a224edd5a0 100644
--- a/src/lib/libcrypto/bio/bio_err.c
+++ b/src/lib/libcrypto/bio/bio_err.c
@@ -1,6 +1,6 @@
1/* crypto/bio/bio_err.c */ 1/* crypto/bio/bio_err.c */
2/* ==================================================================== 2/* ====================================================================
3 * Copyright (c) 1999-2005 The OpenSSL Project. All rights reserved. 3 * Copyright (c) 1999-2006 The OpenSSL Project. All rights reserved.
4 * 4 *
5 * Redistribution and use in source and binary forms, with or without 5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions 6 * modification, are permitted provided that the following conditions
diff --git a/src/lib/libcrypto/bio/bio_lib.c b/src/lib/libcrypto/bio/bio_lib.c
index 3f52ae953c..77f4de9c32 100644
--- a/src/lib/libcrypto/bio/bio_lib.c
+++ b/src/lib/libcrypto/bio/bio_lib.c
@@ -429,7 +429,7 @@ BIO *BIO_push(BIO *b, BIO *bio)
429 if (bio != NULL) 429 if (bio != NULL)
430 bio->prev_bio=lb; 430 bio->prev_bio=lb;
431 /* called to do internal processing */ 431 /* called to do internal processing */
432 BIO_ctrl(b,BIO_CTRL_PUSH,0,NULL); 432 BIO_ctrl(b,BIO_CTRL_PUSH,0,lb);
433 return(b); 433 return(b);
434 } 434 }
435 435
@@ -441,7 +441,7 @@ BIO *BIO_pop(BIO *b)
441 if (b == NULL) return(NULL); 441 if (b == NULL) return(NULL);
442 ret=b->next_bio; 442 ret=b->next_bio;
443 443
444 BIO_ctrl(b,BIO_CTRL_POP,0,NULL); 444 BIO_ctrl(b,BIO_CTRL_POP,0,b);
445 445
446 if (b->prev_bio != NULL) 446 if (b->prev_bio != NULL)
447 b->prev_bio->next_bio=b->next_bio; 447 b->prev_bio->next_bio=b->next_bio;
diff --git a/src/lib/libcrypto/bio/bss_acpt.c b/src/lib/libcrypto/bio/bss_acpt.c
index d090b7272f..826f761143 100644
--- a/src/lib/libcrypto/bio/bss_acpt.c
+++ b/src/lib/libcrypto/bio/bss_acpt.c
@@ -100,8 +100,8 @@ static int acpt_new(BIO *h);
100static int acpt_free(BIO *data); 100static int acpt_free(BIO *data);
101static int acpt_state(BIO *b, BIO_ACCEPT *c); 101static int acpt_state(BIO *b, BIO_ACCEPT *c);
102static void acpt_close_socket(BIO *data); 102static void acpt_close_socket(BIO *data);
103BIO_ACCEPT *BIO_ACCEPT_new(void ); 103static BIO_ACCEPT *BIO_ACCEPT_new(void );
104void BIO_ACCEPT_free(BIO_ACCEPT *a); 104static void BIO_ACCEPT_free(BIO_ACCEPT *a);
105 105
106#define ACPT_S_BEFORE 1 106#define ACPT_S_BEFORE 1
107#define ACPT_S_GET_ACCEPT_SOCKET 2 107#define ACPT_S_GET_ACCEPT_SOCKET 2
@@ -141,7 +141,7 @@ static int acpt_new(BIO *bi)
141 return(1); 141 return(1);
142 } 142 }
143 143
144BIO_ACCEPT *BIO_ACCEPT_new(void) 144static BIO_ACCEPT *BIO_ACCEPT_new(void)
145 { 145 {
146 BIO_ACCEPT *ret; 146 BIO_ACCEPT *ret;
147 147
@@ -154,7 +154,7 @@ BIO_ACCEPT *BIO_ACCEPT_new(void)
154 return(ret); 154 return(ret);
155 } 155 }
156 156
157void BIO_ACCEPT_free(BIO_ACCEPT *a) 157static void BIO_ACCEPT_free(BIO_ACCEPT *a)
158 { 158 {
159 if(a == NULL) 159 if(a == NULL)
160 return; 160 return;
diff --git a/src/lib/libcrypto/bio/bss_dgram.c b/src/lib/libcrypto/bio/bss_dgram.c
index c3da6dc82f..eb7e365467 100644
--- a/src/lib/libcrypto/bio/bss_dgram.c
+++ b/src/lib/libcrypto/bio/bss_dgram.c
@@ -66,7 +66,13 @@
66 66
67#include <openssl/bio.h> 67#include <openssl/bio.h>
68 68
69#if defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_VMS)
70#include <sys/timeb.h>
71#endif
72
73#ifdef OPENSSL_SYS_LINUX
69#define IP_MTU 14 /* linux is lame */ 74#define IP_MTU 14 /* linux is lame */
75#endif
70 76
71#ifdef WATT32 77#ifdef WATT32
72#define sock_write SockWrite /* Watt-32 uses same names */ 78#define sock_write SockWrite /* Watt-32 uses same names */
@@ -84,6 +90,8 @@ static int dgram_clear(BIO *bio);
84 90
85static int BIO_dgram_should_retry(int s); 91static int BIO_dgram_should_retry(int s);
86 92
93static void get_current_time(struct timeval *t);
94
87static BIO_METHOD methods_dgramp= 95static BIO_METHOD methods_dgramp=
88 { 96 {
89 BIO_TYPE_DGRAM, 97 BIO_TYPE_DGRAM,
@@ -100,10 +108,18 @@ static BIO_METHOD methods_dgramp=
100 108
101typedef struct bio_dgram_data_st 109typedef struct bio_dgram_data_st
102 { 110 {
103 struct sockaddr peer; 111 union {
112 struct sockaddr sa;
113 struct sockaddr_in sa_in;
114#if OPENSSL_USE_IPV6
115 struct sockaddr_in6 sa_in6;
116#endif
117 } peer;
104 unsigned int connected; 118 unsigned int connected;
105 unsigned int _errno; 119 unsigned int _errno;
106 unsigned int mtu; 120 unsigned int mtu;
121 struct timeval next_timeout;
122 struct timeval socket_timeout;
107 } bio_dgram_data; 123 } bio_dgram_data;
108 124
109BIO_METHOD *BIO_s_datagram(void) 125BIO_METHOD *BIO_s_datagram(void)
@@ -165,31 +181,140 @@ static int dgram_clear(BIO *a)
165 } 181 }
166 return(1); 182 return(1);
167 } 183 }
168 184
185static void dgram_adjust_rcv_timeout(BIO *b)
186 {
187#if defined(SO_RCVTIMEO)
188 bio_dgram_data *data = (bio_dgram_data *)b->ptr;
189 int sz = sizeof(int);
190
191 /* Is a timer active? */
192 if (data->next_timeout.tv_sec > 0 || data->next_timeout.tv_usec > 0)
193 {
194 struct timeval timenow, timeleft;
195
196 /* Read current socket timeout */
197#ifdef OPENSSL_SYS_WINDOWS
198 int timeout;
199 if (getsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO,
200 (void*)&timeout, &sz) < 0)
201 { perror("getsockopt"); }
202 else
203 {
204 data->socket_timeout.tv_sec = timeout / 1000;
205 data->socket_timeout.tv_usec = (timeout % 1000) * 1000;
206 }
207#else
208 if ( getsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO,
209 &(data->socket_timeout), (void *)&sz) < 0)
210 { perror("getsockopt"); }
211#endif
212
213 /* Get current time */
214 get_current_time(&timenow);
215
216 /* Calculate time left until timer expires */
217 memcpy(&timeleft, &(data->next_timeout), sizeof(struct timeval));
218 timeleft.tv_sec -= timenow.tv_sec;
219 timeleft.tv_usec -= timenow.tv_usec;
220 if (timeleft.tv_usec < 0)
221 {
222 timeleft.tv_sec--;
223 timeleft.tv_usec += 1000000;
224 }
225
226 if (timeleft.tv_sec < 0)
227 {
228 timeleft.tv_sec = 0;
229 timeleft.tv_usec = 1;
230 }
231
232 /* Adjust socket timeout if next handhake message timer
233 * will expire earlier.
234 */
235 if ((data->socket_timeout.tv_sec == 0 && data->socket_timeout.tv_usec == 0) ||
236 (data->socket_timeout.tv_sec > timeleft.tv_sec) ||
237 (data->socket_timeout.tv_sec == timeleft.tv_sec &&
238 data->socket_timeout.tv_usec >= timeleft.tv_usec))
239 {
240#ifdef OPENSSL_SYS_WINDOWS
241 timeout = timeleft.tv_sec * 1000 + timeleft.tv_usec / 1000;
242 if (setsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO,
243 (void*)&timeout, sizeof(timeout)) < 0)
244 { perror("setsockopt"); }
245#else
246 if ( setsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO, &timeleft,
247 sizeof(struct timeval)) < 0)
248 { perror("setsockopt"); }
249#endif
250 }
251 }
252#endif
253 }
254
255static void dgram_reset_rcv_timeout(BIO *b)
256 {
257#if defined(SO_RCVTIMEO)
258 bio_dgram_data *data = (bio_dgram_data *)b->ptr;
259
260 /* Is a timer active? */
261 if (data->next_timeout.tv_sec > 0 || data->next_timeout.tv_usec > 0)
262 {
263#ifdef OPENSSL_SYS_WINDOWS
264 int timeout = data->socket_timeout.tv_sec * 1000 +
265 data->socket_timeout.tv_usec / 1000;
266 if (setsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO,
267 (void*)&timeout, sizeof(timeout)) < 0)
268 { perror("setsockopt"); }
269#else
270 if ( setsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO, &(data->socket_timeout),
271 sizeof(struct timeval)) < 0)
272 { perror("setsockopt"); }
273#endif
274 }
275#endif
276 }
277
169static int dgram_read(BIO *b, char *out, int outl) 278static int dgram_read(BIO *b, char *out, int outl)
170 { 279 {
171 int ret=0; 280 int ret=0;
172 bio_dgram_data *data = (bio_dgram_data *)b->ptr; 281 bio_dgram_data *data = (bio_dgram_data *)b->ptr;
173 282
174 struct sockaddr peer; 283 struct {
175 int peerlen = sizeof(peer); 284 /*
285 * See commentary in b_sock.c. <appro>
286 */
287 union { size_t s; int i; } len;
288 union {
289 struct sockaddr sa;
290 struct sockaddr_in sa_in;
291#if OPENSSL_USE_IPV6
292 struct sockaddr_in6 sa_in6;
293#endif
294 } peer;
295 } sa;
296
297 sa.len.s=0;
298 sa.len.i=sizeof(sa.peer);
176 299
177 if (out != NULL) 300 if (out != NULL)
178 { 301 {
179 clear_socket_error(); 302 clear_socket_error();
180 memset(&peer, 0x00, peerlen); 303 memset(&sa.peer, 0x00, sizeof(sa.peer));
181 /* Last arg in recvfrom is signed on some platforms and 304 dgram_adjust_rcv_timeout(b);
182 * unsigned on others. It is of type socklen_t on some 305 ret=recvfrom(b->num,out,outl,0,&sa.peer.sa,(void *)&sa.len);
183 * but this is not universal. Cast to (void *) to avoid 306 if (sizeof(sa.len.i)!=sizeof(sa.len.s) && sa.len.i==0)
184 * compiler warnings. 307 {
185 */ 308 OPENSSL_assert(sa.len.s<=sizeof(sa.peer));
186 ret=recvfrom(b->num,out,outl,0,&peer,(void *)&peerlen); 309 sa.len.i = (int)sa.len.s;
310 }
311 dgram_reset_rcv_timeout(b);
187 312
188 if ( ! data->connected && ret > 0) 313 if ( ! data->connected && ret >= 0)
189 BIO_ctrl(b, BIO_CTRL_DGRAM_CONNECT, 0, &peer); 314 BIO_ctrl(b, BIO_CTRL_DGRAM_SET_PEER, 0, &sa.peer);
190 315
191 BIO_clear_retry_flags(b); 316 BIO_clear_retry_flags(b);
192 if (ret <= 0) 317 if (ret < 0)
193 { 318 {
194 if (BIO_dgram_should_retry(ret)) 319 if (BIO_dgram_should_retry(ret))
195 { 320 {
@@ -207,19 +332,29 @@ static int dgram_write(BIO *b, const char *in, int inl)
207 bio_dgram_data *data = (bio_dgram_data *)b->ptr; 332 bio_dgram_data *data = (bio_dgram_data *)b->ptr;
208 clear_socket_error(); 333 clear_socket_error();
209 334
210 if ( data->connected ) 335 if ( data->connected )
211 ret=writesocket(b->num,in,inl); 336 ret=writesocket(b->num,in,inl);
212 else 337 else
338 {
339 int peerlen = sizeof(data->peer);
340
341 if (data->peer.sa.sa_family == AF_INET)
342 peerlen = sizeof(data->peer.sa_in);
343#if OPENSSL_USE_IVP6
344 else if (data->peer.sa.sa_family == AF_INET6)
345 peerlen = sizeof(data->peer.sa_in6);
346#endif
213#if defined(NETWARE_CLIB) && defined(NETWARE_BSDSOCK) 347#if defined(NETWARE_CLIB) && defined(NETWARE_BSDSOCK)
214 ret=sendto(b->num, (char *)in, inl, 0, &data->peer, sizeof(data->peer)); 348 ret=sendto(b->num, (char *)in, inl, 0, &data->peer.sa, peerlen);
215#else 349#else
216 ret=sendto(b->num, in, inl, 0, &data->peer, sizeof(data->peer)); 350 ret=sendto(b->num, in, inl, 0, &data->peer.sa, peerlen);
217#endif 351#endif
352 }
218 353
219 BIO_clear_retry_flags(b); 354 BIO_clear_retry_flags(b);
220 if (ret <= 0) 355 if (ret <= 0)
221 { 356 {
222 if (BIO_sock_should_retry(ret)) 357 if (BIO_dgram_should_retry(ret))
223 { 358 {
224 BIO_set_retry_write(b); 359 BIO_set_retry_write(b);
225 data->_errno = get_last_socket_error(); 360 data->_errno = get_last_socket_error();
@@ -240,8 +375,20 @@ static long dgram_ctrl(BIO *b, int cmd, long num, void *ptr)
240 int *ip; 375 int *ip;
241 struct sockaddr *to = NULL; 376 struct sockaddr *to = NULL;
242 bio_dgram_data *data = NULL; 377 bio_dgram_data *data = NULL;
378#if defined(IP_MTU_DISCOVER) || defined(IP_MTU)
243 long sockopt_val = 0; 379 long sockopt_val = 0;
244 unsigned int sockopt_len = 0; 380 unsigned int sockopt_len = 0;
381#endif
382#ifdef OPENSSL_SYS_LINUX
383 socklen_t addr_len;
384 union {
385 struct sockaddr sa;
386 struct sockaddr_in s4;
387#if OPENSSL_USE_IPV6
388 struct sockaddr_in6 s6;
389#endif
390 } addr;
391#endif
245 392
246 data = (bio_dgram_data *)b->ptr; 393 data = (bio_dgram_data *)b->ptr;
247 394
@@ -294,30 +441,110 @@ static long dgram_ctrl(BIO *b, int cmd, long num, void *ptr)
294 else 441 else
295 { 442 {
296#endif 443#endif
297 memcpy(&(data->peer),to, sizeof(struct sockaddr)); 444 switch (to->sa_family)
445 {
446 case AF_INET:
447 memcpy(&data->peer,to,sizeof(data->peer.sa_in));
448 break;
449#if OPENSSL_USE_IPV6
450 case AF_INET6:
451 memcpy(&data->peer,to,sizeof(data->peer.sa_in6));
452 break;
453#endif
454 default:
455 memcpy(&data->peer,to,sizeof(data->peer.sa));
456 break;
457 }
298#if 0 458#if 0
299 } 459 }
300#endif 460#endif
301 break; 461 break;
302 /* (Linux)kernel sets DF bit on outgoing IP packets */ 462 /* (Linux)kernel sets DF bit on outgoing IP packets */
303#ifdef IP_MTU_DISCOVER
304 case BIO_CTRL_DGRAM_MTU_DISCOVER: 463 case BIO_CTRL_DGRAM_MTU_DISCOVER:
305 sockopt_val = IP_PMTUDISC_DO; 464#ifdef OPENSSL_SYS_LINUX
306 if ((ret = setsockopt(b->num, IPPROTO_IP, IP_MTU_DISCOVER, 465 addr_len = (socklen_t)sizeof(addr);
307 &sockopt_val, sizeof(sockopt_val))) < 0) 466 memset((void *)&addr, 0, sizeof(addr));
308 perror("setsockopt"); 467 if (getsockname(b->num, &addr.sa, &addr_len) < 0)
468 {
469 ret = 0;
470 break;
471 }
472 sockopt_len = sizeof(sockopt_val);
473 switch (addr.sa.sa_family)
474 {
475 case AF_INET:
476 sockopt_val = IP_PMTUDISC_DO;
477 if ((ret = setsockopt(b->num, IPPROTO_IP, IP_MTU_DISCOVER,
478 &sockopt_val, sizeof(sockopt_val))) < 0)
479 perror("setsockopt");
480 break;
481#if OPENSSL_USE_IPV6 && defined(IPV6_MTU_DISCOVER)
482 case AF_INET6:
483 sockopt_val = IPV6_PMTUDISC_DO;
484 if ((ret = setsockopt(b->num, IPPROTO_IPV6, IPV6_MTU_DISCOVER,
485 &sockopt_val, sizeof(sockopt_val))) < 0)
486 perror("setsockopt");
487 break;
488#endif
489 default:
490 ret = -1;
491 break;
492 }
493 ret = -1;
494#else
309 break; 495 break;
310#endif 496#endif
311 case BIO_CTRL_DGRAM_QUERY_MTU: 497 case BIO_CTRL_DGRAM_QUERY_MTU:
312 sockopt_len = sizeof(sockopt_val); 498#ifdef OPENSSL_SYS_LINUX
313 if ((ret = getsockopt(b->num, IPPROTO_IP, IP_MTU, (void *)&sockopt_val, 499 addr_len = (socklen_t)sizeof(addr);
314 &sockopt_len)) < 0 || sockopt_val < 0) 500 memset((void *)&addr, 0, sizeof(addr));
315 { ret = 0; } 501 if (getsockname(b->num, &addr.sa, &addr_len) < 0)
316 else 502 {
503 ret = 0;
504 break;
505 }
506 sockopt_len = sizeof(sockopt_val);
507 switch (addr.sa.sa_family)
317 { 508 {
318 data->mtu = sockopt_val; 509 case AF_INET:
319 ret = data->mtu; 510 if ((ret = getsockopt(b->num, IPPROTO_IP, IP_MTU, (void *)&sockopt_val,
511 &sockopt_len)) < 0 || sockopt_val < 0)
512 {
513 ret = 0;
514 }
515 else
516 {
517 /* we assume that the transport protocol is UDP and no
518 * IP options are used.
519 */
520 data->mtu = sockopt_val - 8 - 20;
521 ret = data->mtu;
522 }
523 break;
524#if OPENSSL_USE_IPV6 && defined(IPV6_MTU)
525 case AF_INET6:
526 if ((ret = getsockopt(b->num, IPPROTO_IPV6, IPV6_MTU, (void *)&sockopt_val,
527 &sockopt_len)) < 0 || sockopt_val < 0)
528 {
529 ret = 0;
530 }
531 else
532 {
533 /* we assume that the transport protocol is UDP and no
534 * IPV6 options are used.
535 */
536 data->mtu = sockopt_val - 8 - 40;
537 ret = data->mtu;
538 }
539 break;
540#endif
541 default:
542 ret = 0;
543 break;
320 } 544 }
545#else
546 ret = 0;
547#endif
321 break; 548 break;
322 case BIO_CTRL_DGRAM_GET_MTU: 549 case BIO_CTRL_DGRAM_GET_MTU:
323 return data->mtu; 550 return data->mtu;
@@ -332,19 +559,66 @@ static long dgram_ctrl(BIO *b, int cmd, long num, void *ptr)
332 if ( to != NULL) 559 if ( to != NULL)
333 { 560 {
334 data->connected = 1; 561 data->connected = 1;
335 memcpy(&(data->peer),to, sizeof(struct sockaddr)); 562 switch (to->sa_family)
563 {
564 case AF_INET:
565 memcpy(&data->peer,to,sizeof(data->peer.sa_in));
566 break;
567#if OPENSSL_USE_IPV6
568 case AF_INET6:
569 memcpy(&data->peer,to,sizeof(data->peer.sa_in6));
570 break;
571#endif
572 default:
573 memcpy(&data->peer,to,sizeof(data->peer.sa));
574 break;
575 }
336 } 576 }
337 else 577 else
338 { 578 {
339 data->connected = 0; 579 data->connected = 0;
340 memset(&(data->peer), 0x00, sizeof(struct sockaddr)); 580 memset(&(data->peer), 0x00, sizeof(data->peer));
341 } 581 }
342 break; 582 break;
343 case BIO_CTRL_DGRAM_SET_PEER: 583 case BIO_CTRL_DGRAM_GET_PEER:
344 to = (struct sockaddr *) ptr; 584 switch (data->peer.sa.sa_family)
345 585 {
346 memcpy(&(data->peer), to, sizeof(struct sockaddr)); 586 case AF_INET:
347 break; 587 ret=sizeof(data->peer.sa_in);
588 break;
589#if OPENSSL_USE_IPV6
590 case AF_INET6:
591 ret=sizeof(data->peer.sa_in6);
592 break;
593#endif
594 default:
595 ret=sizeof(data->peer.sa);
596 break;
597 }
598 if (num==0 || num>ret)
599 num=ret;
600 memcpy(ptr,&data->peer,(ret=num));
601 break;
602 case BIO_CTRL_DGRAM_SET_PEER:
603 to = (struct sockaddr *) ptr;
604 switch (to->sa_family)
605 {
606 case AF_INET:
607 memcpy(&data->peer,to,sizeof(data->peer.sa_in));
608 break;
609#if OPENSSL_USE_IPV6
610 case AF_INET6:
611 memcpy(&data->peer,to,sizeof(data->peer.sa_in6));
612 break;
613#endif
614 default:
615 memcpy(&data->peer,to,sizeof(data->peer.sa));
616 break;
617 }
618 break;
619 case BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT:
620 memcpy(&(data->next_timeout), ptr, sizeof(struct timeval));
621 break;
348#if defined(SO_RCVTIMEO) 622#if defined(SO_RCVTIMEO)
349 case BIO_CTRL_DGRAM_SET_RECV_TIMEOUT: 623 case BIO_CTRL_DGRAM_SET_RECV_TIMEOUT:
350#ifdef OPENSSL_SYS_WINDOWS 624#ifdef OPENSSL_SYS_WINDOWS
@@ -507,10 +781,6 @@ int BIO_dgram_non_fatal_error(int err)
507# endif 781# endif
508#endif 782#endif
509 783
510#if defined(ENOTCONN)
511 case ENOTCONN:
512#endif
513
514#ifdef EINTR 784#ifdef EINTR
515 case EINTR: 785 case EINTR:
516#endif 786#endif
@@ -533,11 +803,6 @@ int BIO_dgram_non_fatal_error(int err)
533 case EALREADY: 803 case EALREADY:
534#endif 804#endif
535 805
536/* DF bit set, and packet larger than MTU */
537#ifdef EMSGSIZE
538 case EMSGSIZE:
539#endif
540
541 return(1); 806 return(1);
542 /* break; */ 807 /* break; */
543 default: 808 default:
@@ -546,3 +811,20 @@ int BIO_dgram_non_fatal_error(int err)
546 return(0); 811 return(0);
547 } 812 }
548#endif 813#endif
814
815static void get_current_time(struct timeval *t)
816 {
817#ifdef OPENSSL_SYS_WIN32
818 struct _timeb tb;
819 _ftime(&tb);
820 t->tv_sec = (long)tb.time;
821 t->tv_usec = (long)tb.millitm * 1000;
822#elif defined(OPENSSL_SYS_VMS)
823 struct timeb tb;
824 ftime(&tb);
825 t->tv_sec = (long)tb.time;
826 t->tv_usec = (long)tb.millitm * 1000;
827#else
828 gettimeofday(t, NULL);
829#endif
830 }
diff --git a/src/lib/libcrypto/bio/bss_fd.c b/src/lib/libcrypto/bio/bss_fd.c
index 4c229bf641..d1bf85aae1 100644
--- a/src/lib/libcrypto/bio/bss_fd.c
+++ b/src/lib/libcrypto/bio/bss_fd.c
@@ -60,6 +60,13 @@
60#include <errno.h> 60#include <errno.h>
61#define USE_SOCKETS 61#define USE_SOCKETS
62#include "cryptlib.h" 62#include "cryptlib.h"
63
64#if defined(OPENSSL_NO_POSIX_IO)
65/*
66 * One can argue that one should implement dummy placeholder for
67 * BIO_s_fd here...
68 */
69#else
63/* 70/*
64 * As for unconditional usage of "UPLINK" interface in this module. 71 * As for unconditional usage of "UPLINK" interface in this module.
65 * Trouble is that unlike Unix file descriptors [which are indexes 72 * Trouble is that unlike Unix file descriptors [which are indexes
@@ -77,6 +84,7 @@
77static int fd_write(BIO *h, const char *buf, int num); 84static int fd_write(BIO *h, const char *buf, int num);
78static int fd_read(BIO *h, char *buf, int size); 85static int fd_read(BIO *h, char *buf, int size);
79static int fd_puts(BIO *h, const char *str); 86static int fd_puts(BIO *h, const char *str);
87static int fd_gets(BIO *h, char *buf, int size);
80static long fd_ctrl(BIO *h, int cmd, long arg1, void *arg2); 88static long fd_ctrl(BIO *h, int cmd, long arg1, void *arg2);
81static int fd_new(BIO *h); 89static int fd_new(BIO *h);
82static int fd_free(BIO *data); 90static int fd_free(BIO *data);
@@ -88,7 +96,7 @@ static BIO_METHOD methods_fdp=
88 fd_write, 96 fd_write,
89 fd_read, 97 fd_read,
90 fd_puts, 98 fd_puts,
91 NULL, /* fd_gets, */ 99 fd_gets,
92 fd_ctrl, 100 fd_ctrl,
93 fd_new, 101 fd_new,
94 fd_free, 102 fd_free,
@@ -227,6 +235,22 @@ static int fd_puts(BIO *bp, const char *str)
227 return(ret); 235 return(ret);
228 } 236 }
229 237
238static int fd_gets(BIO *bp, char *buf, int size)
239 {
240 int ret=0;
241 char *ptr=buf;
242 char *end=buf+size-1;
243
244 while ( (ptr < end) && (fd_read(bp, ptr, 1) > 0) && (ptr[0] != '\n') )
245 ptr++;
246
247 ptr[0]='\0';
248
249 if (buf[0] != '\0')
250 ret=strlen(buf);
251 return(ret);
252 }
253
230int BIO_fd_should_retry(int i) 254int BIO_fd_should_retry(int i)
231 { 255 {
232 int err; 256 int err;
@@ -292,3 +316,4 @@ int BIO_fd_non_fatal_error(int err)
292 } 316 }
293 return(0); 317 return(0);
294 } 318 }
319#endif
diff --git a/src/lib/libcrypto/bio/bss_file.c b/src/lib/libcrypto/bio/bss_file.c
index 9ad46fa081..8bfa0bcd97 100644
--- a/src/lib/libcrypto/bio/bss_file.c
+++ b/src/lib/libcrypto/bio/bss_file.c
@@ -118,10 +118,47 @@ static BIO_METHOD methods_filep=
118 118
119BIO *BIO_new_file(const char *filename, const char *mode) 119BIO *BIO_new_file(const char *filename, const char *mode)
120 { 120 {
121 BIO *ret; 121 BIO *ret;
122 FILE *file; 122 FILE *file=NULL;
123
124#if defined(_WIN32) && defined(CP_UTF8)
125 int sz, len_0 = (int)strlen(filename)+1;
123 126
124 if ((file=fopen(filename,mode)) == NULL) 127 /*
128 * Basically there are three cases to cover: a) filename is
129 * pure ASCII string; b) actual UTF-8 encoded string and
130 * c) locale-ized string, i.e. one containing 8-bit
131 * characters that are meaningful in current system locale.
132 * If filename is pure ASCII or real UTF-8 encoded string,
133 * MultiByteToWideChar succeeds and _wfopen works. If
134 * filename is locale-ized string, chances are that
135 * MultiByteToWideChar fails reporting
136 * ERROR_NO_UNICODE_TRANSLATION, in which case we fall
137 * back to fopen...
138 */
139 if ((sz=MultiByteToWideChar(CP_UTF8,MB_ERR_INVALID_CHARS,
140 filename,len_0,NULL,0))>0)
141 {
142 WCHAR wmode[8];
143 WCHAR *wfilename = _alloca(sz*sizeof(WCHAR));
144
145 if (MultiByteToWideChar(CP_UTF8,MB_ERR_INVALID_CHARS,
146 filename,len_0,wfilename,sz) &&
147 MultiByteToWideChar(CP_UTF8,0,mode,strlen(mode)+1,
148 wmode,sizeof(wmode)/sizeof(wmode[0])) &&
149 (file=_wfopen(wfilename,wmode))==NULL && errno==ENOENT
150 ) /* UTF-8 decode succeeded, but no file, filename
151 * could still have been locale-ized... */
152 file = fopen(filename,mode);
153 }
154 else if (GetLastError()==ERROR_NO_UNICODE_TRANSLATION)
155 {
156 file = fopen(filename,mode);
157 }
158#else
159 file=fopen(filename,mode);
160#endif
161 if (file == NULL)
125 { 162 {
126 SYSerr(SYS_F_FOPEN,get_last_sys_error()); 163 SYSerr(SYS_F_FOPEN,get_last_sys_error());
127 ERR_add_error_data(5,"fopen('",filename,"','",mode,"')"); 164 ERR_add_error_data(5,"fopen('",filename,"','",mode,"')");
@@ -131,7 +168,7 @@ BIO *BIO_new_file(const char *filename, const char *mode)
131 BIOerr(BIO_F_BIO_NEW_FILE,ERR_R_SYS_LIB); 168 BIOerr(BIO_F_BIO_NEW_FILE,ERR_R_SYS_LIB);
132 return(NULL); 169 return(NULL);
133 } 170 }
134 if ((ret=BIO_new(BIO_s_file_internal())) == NULL) 171 if ((ret=BIO_new(BIO_s_file())) == NULL)
135 { 172 {
136 fclose(file); 173 fclose(file);
137 return(NULL); 174 return(NULL);
@@ -272,9 +309,9 @@ static long MS_CALLBACK file_ctrl(BIO *b, int cmd, long num, void *ptr)
272 BIO_clear_flags(b,BIO_FLAGS_UPLINK); 309 BIO_clear_flags(b,BIO_FLAGS_UPLINK);
273#endif 310#endif
274#endif 311#endif
275#ifdef UP_fsetmode 312#ifdef UP_fsetmod
276 if (b->flags&BIO_FLAGS_UPLINK) 313 if (b->flags&BIO_FLAGS_UPLINK)
277 UP_fsetmode(b->ptr,num&BIO_FP_TEXT?'t':'b'); 314 UP_fsetmod(b->ptr,(char)((num&BIO_FP_TEXT)?'t':'b'));
278 else 315 else
279#endif 316#endif
280 { 317 {
@@ -286,8 +323,7 @@ static long MS_CALLBACK file_ctrl(BIO *b, int cmd, long num, void *ptr)
286 _setmode(fd,_O_BINARY); 323 _setmode(fd,_O_BINARY);
287#elif defined(OPENSSL_SYS_NETWARE) && defined(NETWARE_CLIB) 324#elif defined(OPENSSL_SYS_NETWARE) && defined(NETWARE_CLIB)
288 int fd = fileno((FILE*)ptr); 325 int fd = fileno((FILE*)ptr);
289 /* Under CLib there are differences in file modes 326 /* Under CLib there are differences in file modes */
290 */
291 if (num & BIO_FP_TEXT) 327 if (num & BIO_FP_TEXT)
292 setmode(fd,O_TEXT); 328 setmode(fd,O_TEXT);
293 else 329 else
@@ -308,7 +344,7 @@ static long MS_CALLBACK file_ctrl(BIO *b, int cmd, long num, void *ptr)
308 else 344 else
309 _setmode(fd,_O_BINARY); 345 _setmode(fd,_O_BINARY);
310 } 346 }
311#elif defined(OPENSSL_SYS_OS2) 347#elif defined(OPENSSL_SYS_OS2) || defined(OPENSSL_SYS_WIN32_CYGWIN)
312 int fd = fileno((FILE*)ptr); 348 int fd = fileno((FILE*)ptr);
313 if (num & BIO_FP_TEXT) 349 if (num & BIO_FP_TEXT)
314 setmode(fd, O_TEXT); 350 setmode(fd, O_TEXT);
@@ -404,11 +440,18 @@ static int MS_CALLBACK file_gets(BIO *bp, char *buf, int size)
404 440
405 buf[0]='\0'; 441 buf[0]='\0';
406 if (bp->flags&BIO_FLAGS_UPLINK) 442 if (bp->flags&BIO_FLAGS_UPLINK)
407 UP_fgets(buf,size,bp->ptr); 443 {
444 if (!UP_fgets(buf,size,bp->ptr))
445 goto err;
446 }
408 else 447 else
409 fgets(buf,size,(FILE *)bp->ptr); 448 {
449 if (!fgets(buf,size,(FILE *)bp->ptr))
450 goto err;
451 }
410 if (buf[0] != '\0') 452 if (buf[0] != '\0')
411 ret=strlen(buf); 453 ret=strlen(buf);
454 err:
412 return(ret); 455 return(ret);
413 } 456 }
414 457
diff --git a/src/lib/libcrypto/bio/bss_log.c b/src/lib/libcrypto/bio/bss_log.c
index 6360dbc820..7ead044b37 100644
--- a/src/lib/libcrypto/bio/bss_log.c
+++ b/src/lib/libcrypto/bio/bss_log.c
@@ -70,7 +70,6 @@
70 70
71#if defined(OPENSSL_SYS_WINCE) 71#if defined(OPENSSL_SYS_WINCE)
72#elif defined(OPENSSL_SYS_WIN32) 72#elif defined(OPENSSL_SYS_WIN32)
73# include <process.h>
74#elif defined(OPENSSL_SYS_VMS) 73#elif defined(OPENSSL_SYS_VMS)
75# include <opcdef.h> 74# include <opcdef.h>
76# include <descrip.h> 75# include <descrip.h>
@@ -122,18 +121,6 @@ static int MS_CALLBACK slg_free(BIO *data);
122static void xopenlog(BIO* bp, char* name, int level); 121static void xopenlog(BIO* bp, char* name, int level);
123static void xsyslog(BIO* bp, int priority, const char* string); 122static void xsyslog(BIO* bp, int priority, const char* string);
124static void xcloselog(BIO* bp); 123static void xcloselog(BIO* bp);
125#ifdef OPENSSL_SYS_WIN32
126LONG (WINAPI *go_for_advapi)() = RegOpenKeyEx;
127HANDLE (WINAPI *register_event_source)() = NULL;
128BOOL (WINAPI *deregister_event_source)() = NULL;
129BOOL (WINAPI *report_event)() = NULL;
130#define DL_PROC(m,f) (GetProcAddress( m, f ))
131#ifdef UNICODE
132#define DL_PROC_X(m,f) DL_PROC( m, f "W" )
133#else
134#define DL_PROC_X(m,f) DL_PROC( m, f "A" )
135#endif
136#endif
137 124
138static BIO_METHOD methods_slg= 125static BIO_METHOD methods_slg=
139 { 126 {
@@ -175,7 +162,7 @@ static int MS_CALLBACK slg_write(BIO *b, const char *in, int inl)
175 char* buf; 162 char* buf;
176 char* pp; 163 char* pp;
177 int priority, i; 164 int priority, i;
178 static struct 165 static const struct
179 { 166 {
180 int strl; 167 int strl;
181 char str[10]; 168 char str[10];
@@ -249,35 +236,20 @@ static int MS_CALLBACK slg_puts(BIO *bp, const char *str)
249 236
250static void xopenlog(BIO* bp, char* name, int level) 237static void xopenlog(BIO* bp, char* name, int level)
251{ 238{
252 if ( !register_event_source ) 239 if (GetVersion() < 0x80000000)
253 { 240 bp->ptr = RegisterEventSourceA(NULL,name);
254 HANDLE advapi; 241 else
255 if ( !(advapi = GetModuleHandle("advapi32")) ) 242 bp->ptr = NULL;
256 return;
257 register_event_source = (HANDLE (WINAPI *)())DL_PROC_X(advapi,
258 "RegisterEventSource" );
259 deregister_event_source = (BOOL (WINAPI *)())DL_PROC(advapi,
260 "DeregisterEventSource");
261 report_event = (BOOL (WINAPI *)())DL_PROC_X(advapi,
262 "ReportEvent" );
263 if ( !(register_event_source && deregister_event_source &&
264 report_event) )
265 {
266 register_event_source = NULL;
267 deregister_event_source = NULL;
268 report_event = NULL;
269 return;
270 }
271 }
272 bp->ptr= (char *)register_event_source(NULL, name);
273} 243}
274 244
275static void xsyslog(BIO *bp, int priority, const char *string) 245static void xsyslog(BIO *bp, int priority, const char *string)
276{ 246{
277 LPCSTR lpszStrings[2]; 247 LPCSTR lpszStrings[2];
278 WORD evtype= EVENTLOG_ERROR_TYPE; 248 WORD evtype= EVENTLOG_ERROR_TYPE;
279 int pid = _getpid(); 249 char pidbuf[DECIMAL_SIZE(DWORD)+4];
280 char pidbuf[DECIMAL_SIZE(pid)+4]; 250
251 if (bp->ptr == NULL)
252 return;
281 253
282 switch (priority) 254 switch (priority)
283 { 255 {
@@ -301,19 +273,18 @@ static void xsyslog(BIO *bp, int priority, const char *string)
301 break; 273 break;
302 } 274 }
303 275
304 sprintf(pidbuf, "[%d] ", pid); 276 sprintf(pidbuf, "[%u] ", GetCurrentProcessId());
305 lpszStrings[0] = pidbuf; 277 lpszStrings[0] = pidbuf;
306 lpszStrings[1] = string; 278 lpszStrings[1] = string;
307 279
308 if(report_event && bp->ptr) 280 ReportEventA(bp->ptr, evtype, 0, 1024, NULL, 2, 0,
309 report_event(bp->ptr, evtype, 0, 1024, NULL, 2, 0,
310 lpszStrings, NULL); 281 lpszStrings, NULL);
311} 282}
312 283
313static void xcloselog(BIO* bp) 284static void xcloselog(BIO* bp)
314{ 285{
315 if(deregister_event_source && bp->ptr) 286 if(bp->ptr)
316 deregister_event_source((HANDLE)(bp->ptr)); 287 DeregisterEventSource((HANDLE)(bp->ptr));
317 bp->ptr= NULL; 288 bp->ptr= NULL;
318} 289}
319 290
diff --git a/src/lib/libcrypto/bio/bss_mem.c b/src/lib/libcrypto/bio/bss_mem.c
index e7ab9cb3a3..37d4194e4b 100644
--- a/src/lib/libcrypto/bio/bss_mem.c
+++ b/src/lib/libcrypto/bio/bss_mem.c
@@ -94,16 +94,18 @@ BIO *BIO_new_mem_buf(void *buf, int len)
94{ 94{
95 BIO *ret; 95 BIO *ret;
96 BUF_MEM *b; 96 BUF_MEM *b;
97 size_t sz;
98
97 if (!buf) { 99 if (!buf) {
98 BIOerr(BIO_F_BIO_NEW_MEM_BUF,BIO_R_NULL_PARAMETER); 100 BIOerr(BIO_F_BIO_NEW_MEM_BUF,BIO_R_NULL_PARAMETER);
99 return NULL; 101 return NULL;
100 } 102 }
101 if(len == -1) len = strlen(buf); 103 sz = (len<0) ? strlen(buf) : (size_t)len;
102 if(!(ret = BIO_new(BIO_s_mem())) ) return NULL; 104 if(!(ret = BIO_new(BIO_s_mem())) ) return NULL;
103 b = (BUF_MEM *)ret->ptr; 105 b = (BUF_MEM *)ret->ptr;
104 b->data = buf; 106 b->data = buf;
105 b->length = len; 107 b->length = sz;
106 b->max = len; 108 b->max = sz;
107 ret->flags |= BIO_FLAGS_MEM_RDONLY; 109 ret->flags |= BIO_FLAGS_MEM_RDONLY;
108 /* Since this is static data retrying wont help */ 110 /* Since this is static data retrying wont help */
109 ret->num = 0; 111 ret->num = 0;
@@ -144,22 +146,16 @@ static int mem_read(BIO *b, char *out, int outl)
144 { 146 {
145 int ret= -1; 147 int ret= -1;
146 BUF_MEM *bm; 148 BUF_MEM *bm;
147 int i;
148 char *from,*to;
149 149
150 bm=(BUF_MEM *)b->ptr; 150 bm=(BUF_MEM *)b->ptr;
151 BIO_clear_retry_flags(b); 151 BIO_clear_retry_flags(b);
152 ret=(outl > bm->length)?bm->length:outl; 152 ret=(outl >=0 && (size_t)outl > bm->length)?(int)bm->length:outl;
153 if ((out != NULL) && (ret > 0)) { 153 if ((out != NULL) && (ret > 0)) {
154 memcpy(out,bm->data,ret); 154 memcpy(out,bm->data,ret);
155 bm->length-=ret; 155 bm->length-=ret;
156 /* memmove(&(bm->data[0]),&(bm->data[ret]), bm->length); */
157 if(b->flags & BIO_FLAGS_MEM_RDONLY) bm->data += ret; 156 if(b->flags & BIO_FLAGS_MEM_RDONLY) bm->data += ret;
158 else { 157 else {
159 from=(char *)&(bm->data[ret]); 158 memmove(&(bm->data[0]),&(bm->data[ret]),bm->length);
160 to=(char *)&(bm->data[0]);
161 for (i=0; i<bm->length; i++)
162 to[i]=from[i];
163 } 159 }
164 } else if (bm->length == 0) 160 } else if (bm->length == 0)
165 { 161 {
diff --git a/src/lib/libcrypto/bio/bss_sock.c b/src/lib/libcrypto/bio/bss_sock.c
index 30c3ceab46..3df31938c1 100644
--- a/src/lib/libcrypto/bio/bss_sock.c
+++ b/src/lib/libcrypto/bio/bss_sock.c
@@ -172,15 +172,6 @@ static long sock_ctrl(BIO *b, int cmd, long num, void *ptr)
172 172
173 switch (cmd) 173 switch (cmd)
174 { 174 {
175 case BIO_CTRL_RESET:
176 num=0;
177 case BIO_C_FILE_SEEK:
178 ret=0;
179 break;
180 case BIO_C_FILE_TELL:
181 case BIO_CTRL_INFO:
182 ret=0;
183 break;
184 case BIO_C_SET_FD: 175 case BIO_C_SET_FD:
185 sock_free(b); 176 sock_free(b);
186 b->num= *((int *)ptr); 177 b->num= *((int *)ptr);
@@ -203,10 +194,6 @@ static long sock_ctrl(BIO *b, int cmd, long num, void *ptr)
203 case BIO_CTRL_SET_CLOSE: 194 case BIO_CTRL_SET_CLOSE:
204 b->shutdown=(int)num; 195 b->shutdown=(int)num;
205 break; 196 break;
206 case BIO_CTRL_PENDING:
207 case BIO_CTRL_WPENDING:
208 ret=0;
209 break;
210 case BIO_CTRL_DUP: 197 case BIO_CTRL_DUP:
211 case BIO_CTRL_FLUSH: 198 case BIO_CTRL_FLUSH:
212 ret=1; 199 ret=1;
diff --git a/src/lib/libcrypto/bn/asm/alpha-mont.pl b/src/lib/libcrypto/bn/asm/alpha-mont.pl
index 7a2cc3173b..f7e0ca1646 100644
--- a/src/lib/libcrypto/bn/asm/alpha-mont.pl
+++ b/src/lib/libcrypto/bn/asm/alpha-mont.pl
@@ -53,15 +53,15 @@ $code=<<___;
53.align 5 53.align 5
54.ent bn_mul_mont 54.ent bn_mul_mont
55bn_mul_mont: 55bn_mul_mont:
56 lda sp,-40(sp) 56 lda sp,-48(sp)
57 stq ra,0(sp) 57 stq ra,0(sp)
58 stq s3,8(sp) 58 stq s3,8(sp)
59 stq s4,16(sp) 59 stq s4,16(sp)
60 stq s5,24(sp) 60 stq s5,24(sp)
61 stq fp,32(sp) 61 stq fp,32(sp)
62 mov sp,fp 62 mov sp,fp
63 .mask 0x0400f000,-40 63 .mask 0x0400f000,-48
64 .frame fp,40,ra 64 .frame fp,48,ra
65 .prologue 0 65 .prologue 0
66 66
67 .align 4 67 .align 4
@@ -306,7 +306,7 @@ bn_mul_mont:
306 ldq s4,16(sp) 306 ldq s4,16(sp)
307 ldq s5,24(sp) 307 ldq s5,24(sp)
308 ldq fp,32(sp) 308 ldq fp,32(sp)
309 lda sp,40(sp) 309 lda sp,48(sp)
310 ret (ra) 310 ret (ra)
311.end bn_mul_mont 311.end bn_mul_mont
312.rdata 312.rdata
diff --git a/src/lib/libcrypto/bn/asm/armv4-mont.pl b/src/lib/libcrypto/bn/asm/armv4-mont.pl
index 05d5dc1a48..14e0d2d1dd 100644
--- a/src/lib/libcrypto/bn/asm/armv4-mont.pl
+++ b/src/lib/libcrypto/bn/asm/armv4-mont.pl
@@ -193,6 +193,7 @@ bn_mul_mont:
193 bx lr @ interoperable with Thumb ISA:-) 193 bx lr @ interoperable with Thumb ISA:-)
194.size bn_mul_mont,.-bn_mul_mont 194.size bn_mul_mont,.-bn_mul_mont
195.asciz "Montgomery multiplication for ARMv4, CRYPTOGAMS by <appro\@openssl.org>" 195.asciz "Montgomery multiplication for ARMv4, CRYPTOGAMS by <appro\@openssl.org>"
196.align 2
196___ 197___
197 198
198$code =~ s/\bbx\s+lr\b/.word\t0xe12fff1e/gm; # make it possible to compile with -march=armv4 199$code =~ s/\bbx\s+lr\b/.word\t0xe12fff1e/gm; # make it possible to compile with -march=armv4
diff --git a/src/lib/libcrypto/bn/asm/bn-586.pl b/src/lib/libcrypto/bn/asm/bn-586.pl
index 26c2685a72..332ef3e91d 100644
--- a/src/lib/libcrypto/bn/asm/bn-586.pl
+++ b/src/lib/libcrypto/bn/asm/bn-586.pl
@@ -1,6 +1,7 @@
1#!/usr/local/bin/perl 1#!/usr/local/bin/perl
2 2
3push(@INC,"perlasm","../../perlasm"); 3$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
4push(@INC,"${dir}","${dir}../../perlasm");
4require "x86asm.pl"; 5require "x86asm.pl";
5 6
6&asm_init($ARGV[0],$0); 7&asm_init($ARGV[0],$0);
@@ -24,38 +25,25 @@ sub bn_mul_add_words
24 { 25 {
25 local($name)=@_; 26 local($name)=@_;
26 27
27 &function_begin($name,$sse2?"EXTRN\t_OPENSSL_ia32cap_P:DWORD":""); 28 &function_begin_B($name,$sse2?"EXTRN\t_OPENSSL_ia32cap_P:DWORD":"");
28 29
29 &comment(""); 30 $r="eax";
30 $Low="eax"; 31 $a="edx";
31 $High="edx"; 32 $c="ecx";
32 $a="ebx";
33 $w="ebp";
34 $r="edi";
35 $c="esi";
36
37 &xor($c,$c); # clear carry
38 &mov($r,&wparam(0)); #
39
40 &mov("ecx",&wparam(2)); #
41 &mov($a,&wparam(1)); #
42
43 &and("ecx",0xfffffff8); # num / 8
44 &mov($w,&wparam(3)); #
45
46 &push("ecx"); # Up the stack for a tmp variable
47
48 &jz(&label("maw_finish"));
49 33
50 if ($sse2) { 34 if ($sse2) {
51 &picmeup("eax","OPENSSL_ia32cap_P"); 35 &picmeup("eax","OPENSSL_ia32cap_P");
52 &bt(&DWP(0,"eax"),26); 36 &bt(&DWP(0,"eax"),26);
53 &jnc(&label("maw_loop")); 37 &jnc(&label("maw_non_sse2"));
54 38
55 &movd("mm0",$w); # mm0 = w 39 &mov($r,&wparam(0));
40 &mov($a,&wparam(1));
41 &mov($c,&wparam(2));
42 &movd("mm0",&wparam(3)); # mm0 = w
56 &pxor("mm1","mm1"); # mm1 = carry_in 43 &pxor("mm1","mm1"); # mm1 = carry_in
57 44 &jmp(&label("maw_sse2_entry"));
58 &set_label("maw_sse2_loop",0); 45
46 &set_label("maw_sse2_unrolled",16);
59 &movd("mm3",&DWP(0,$r,"",0)); # mm3 = r[0] 47 &movd("mm3",&DWP(0,$r,"",0)); # mm3 = r[0]
60 &paddq("mm1","mm3"); # mm1 = carry_in + r[0] 48 &paddq("mm1","mm3"); # mm1 = carry_in + r[0]
61 &movd("mm2",&DWP(0,$a,"",0)); # mm2 = a[0] 49 &movd("mm2",&DWP(0,$a,"",0)); # mm2 = a[0]
@@ -112,42 +100,82 @@ sub bn_mul_add_words
112 &psrlq("mm1",32); # mm1 = carry6 100 &psrlq("mm1",32); # mm1 = carry6
113 &paddq("mm1","mm3"); # mm1 = carry6 + r[7] + w*a[7] 101 &paddq("mm1","mm3"); # mm1 = carry6 + r[7] + w*a[7]
114 &movd(&DWP(28,$r,"",0),"mm1"); 102 &movd(&DWP(28,$r,"",0),"mm1");
115 &add($r,32); 103 &lea($r,&DWP(32,$r));
116 &psrlq("mm1",32); # mm1 = carry_out 104 &psrlq("mm1",32); # mm1 = carry_out
117 105
118 &sub("ecx",8); 106 &sub($c,8);
107 &jz(&label("maw_sse2_exit"));
108 &set_label("maw_sse2_entry");
109 &test($c,0xfffffff8);
110 &jnz(&label("maw_sse2_unrolled"));
111
112 &set_label("maw_sse2_loop",4);
113 &movd("mm2",&DWP(0,$a)); # mm2 = a[i]
114 &movd("mm3",&DWP(0,$r)); # mm3 = r[i]
115 &pmuludq("mm2","mm0"); # a[i] *= w
116 &lea($a,&DWP(4,$a));
117 &paddq("mm1","mm3"); # carry += r[i]
118 &paddq("mm1","mm2"); # carry += a[i]*w
119 &movd(&DWP(0,$r),"mm1"); # r[i] = carry_low
120 &sub($c,1);
121 &psrlq("mm1",32); # carry = carry_high
122 &lea($r,&DWP(4,$r));
119 &jnz(&label("maw_sse2_loop")); 123 &jnz(&label("maw_sse2_loop"));
120 124 &set_label("maw_sse2_exit");
121 &movd($c,"mm1"); # c = carry_out 125 &movd("eax","mm1"); # c = carry_out
122 &emms(); 126 &emms();
127 &ret();
123 128
124 &jmp(&label("maw_finish")); 129 &set_label("maw_non_sse2",16);
125 } 130 }
126 131
127 &set_label("maw_loop",0); 132 # function_begin prologue
133 &push("ebp");
134 &push("ebx");
135 &push("esi");
136 &push("edi");
137
138 &comment("");
139 $Low="eax";
140 $High="edx";
141 $a="ebx";
142 $w="ebp";
143 $r="edi";
144 $c="esi";
145
146 &xor($c,$c); # clear carry
147 &mov($r,&wparam(0)); #
148
149 &mov("ecx",&wparam(2)); #
150 &mov($a,&wparam(1)); #
151
152 &and("ecx",0xfffffff8); # num / 8
153 &mov($w,&wparam(3)); #
128 154
129 &mov(&swtmp(0),"ecx"); # 155 &push("ecx"); # Up the stack for a tmp variable
156
157 &jz(&label("maw_finish"));
158
159 &set_label("maw_loop",16);
130 160
131 for ($i=0; $i<32; $i+=4) 161 for ($i=0; $i<32; $i+=4)
132 { 162 {
133 &comment("Round $i"); 163 &comment("Round $i");
134 164
135 &mov("eax",&DWP($i,$a,"",0)); # *a 165 &mov("eax",&DWP($i,$a)); # *a
136 &mul($w); # *a * w 166 &mul($w); # *a * w
137 &add("eax",$c); # L(t)+= *r 167 &add("eax",$c); # L(t)+= c
138 &mov($c,&DWP($i,$r,"",0)); # L(t)+= *r
139 &adc("edx",0); # H(t)+=carry 168 &adc("edx",0); # H(t)+=carry
140 &add("eax",$c); # L(t)+=c 169 &add("eax",&DWP($i,$r)); # L(t)+= *r
141 &adc("edx",0); # H(t)+=carry 170 &adc("edx",0); # H(t)+=carry
142 &mov(&DWP($i,$r,"",0),"eax"); # *r= L(t); 171 &mov(&DWP($i,$r),"eax"); # *r= L(t);
143 &mov($c,"edx"); # c= H(t); 172 &mov($c,"edx"); # c= H(t);
144 } 173 }
145 174
146 &comment(""); 175 &comment("");
147 &mov("ecx",&swtmp(0)); #
148 &add($a,32);
149 &add($r,32);
150 &sub("ecx",8); 176 &sub("ecx",8);
177 &lea($a,&DWP(32,$a));
178 &lea($r,&DWP(32,$r));
151 &jnz(&label("maw_loop")); 179 &jnz(&label("maw_loop"));
152 180
153 &set_label("maw_finish",0); 181 &set_label("maw_finish",0);
@@ -160,16 +188,15 @@ sub bn_mul_add_words
160 for ($i=0; $i<7; $i++) 188 for ($i=0; $i<7; $i++)
161 { 189 {
162 &comment("Tail Round $i"); 190 &comment("Tail Round $i");
163 &mov("eax",&DWP($i*4,$a,"",0));# *a 191 &mov("eax",&DWP($i*4,$a)); # *a
164 &mul($w); # *a * w 192 &mul($w); # *a * w
165 &add("eax",$c); # L(t)+=c 193 &add("eax",$c); # L(t)+=c
166 &mov($c,&DWP($i*4,$r,"",0)); # L(t)+= *r
167 &adc("edx",0); # H(t)+=carry 194 &adc("edx",0); # H(t)+=carry
168 &add("eax",$c); 195 &add("eax",&DWP($i*4,$r)); # L(t)+= *r
169 &adc("edx",0); # H(t)+=carry 196 &adc("edx",0); # H(t)+=carry
170 &dec("ecx") if ($i != 7-1); 197 &dec("ecx") if ($i != 7-1);
171 &mov(&DWP($i*4,$r,"",0),"eax"); # *r= L(t); 198 &mov(&DWP($i*4,$r),"eax"); # *r= L(t);
172 &mov($c,"edx"); # c= H(t); 199 &mov($c,"edx"); # c= H(t);
173 &jz(&label("maw_end")) if ($i != 7-1); 200 &jz(&label("maw_end")) if ($i != 7-1);
174 } 201 }
175 &set_label("maw_end",0); 202 &set_label("maw_end",0);
@@ -184,7 +211,45 @@ sub bn_mul_words
184 { 211 {
185 local($name)=@_; 212 local($name)=@_;
186 213
187 &function_begin($name,""); 214 &function_begin_B($name,$sse2?"EXTRN\t_OPENSSL_ia32cap_P:DWORD":"");
215
216 $r="eax";
217 $a="edx";
218 $c="ecx";
219
220 if ($sse2) {
221 &picmeup("eax","OPENSSL_ia32cap_P");
222 &bt(&DWP(0,"eax"),26);
223 &jnc(&label("mw_non_sse2"));
224
225 &mov($r,&wparam(0));
226 &mov($a,&wparam(1));
227 &mov($c,&wparam(2));
228 &movd("mm0",&wparam(3)); # mm0 = w
229 &pxor("mm1","mm1"); # mm1 = carry = 0
230
231 &set_label("mw_sse2_loop",16);
232 &movd("mm2",&DWP(0,$a)); # mm2 = a[i]
233 &pmuludq("mm2","mm0"); # a[i] *= w
234 &lea($a,&DWP(4,$a));
235 &paddq("mm1","mm2"); # carry += a[i]*w
236 &movd(&DWP(0,$r),"mm1"); # r[i] = carry_low
237 &sub($c,1);
238 &psrlq("mm1",32); # carry = carry_high
239 &lea($r,&DWP(4,$r));
240 &jnz(&label("mw_sse2_loop"));
241
242 &movd("eax","mm1"); # return carry
243 &emms();
244 &ret();
245 &set_label("mw_non_sse2",16);
246 }
247
248 # function_begin prologue
249 &push("ebp");
250 &push("ebx");
251 &push("esi");
252 &push("edi");
188 253
189 &comment(""); 254 &comment("");
190 $Low="eax"; 255 $Low="eax";
@@ -257,7 +322,40 @@ sub bn_sqr_words
257 { 322 {
258 local($name)=@_; 323 local($name)=@_;
259 324
260 &function_begin($name,""); 325 &function_begin_B($name,$sse2?"EXTRN\t_OPENSSL_ia32cap_P:DWORD":"");
326
327 $r="eax";
328 $a="edx";
329 $c="ecx";
330
331 if ($sse2) {
332 &picmeup("eax","OPENSSL_ia32cap_P");
333 &bt(&DWP(0,"eax"),26);
334 &jnc(&label("sqr_non_sse2"));
335
336 &mov($r,&wparam(0));
337 &mov($a,&wparam(1));
338 &mov($c,&wparam(2));
339
340 &set_label("sqr_sse2_loop",16);
341 &movd("mm0",&DWP(0,$a)); # mm0 = a[i]
342 &pmuludq("mm0","mm0"); # a[i] *= a[i]
343 &lea($a,&DWP(4,$a)); # a++
344 &movq(&QWP(0,$r),"mm0"); # r[i] = a[i]*a[i]
345 &sub($c,1);
346 &lea($r,&DWP(8,$r)); # r += 2
347 &jnz(&label("sqr_sse2_loop"));
348
349 &emms();
350 &ret();
351 &set_label("sqr_non_sse2",16);
352 }
353
354 # function_begin prologue
355 &push("ebp");
356 &push("ebx");
357 &push("esi");
358 &push("edi");
261 359
262 &comment(""); 360 &comment("");
263 $r="esi"; 361 $r="esi";
@@ -313,12 +411,13 @@ sub bn_div_words
313 { 411 {
314 local($name)=@_; 412 local($name)=@_;
315 413
316 &function_begin($name,""); 414 &function_begin_B($name,"");
317 &mov("edx",&wparam(0)); # 415 &mov("edx",&wparam(0)); #
318 &mov("eax",&wparam(1)); # 416 &mov("eax",&wparam(1)); #
319 &mov("ebx",&wparam(2)); # 417 &mov("ecx",&wparam(2)); #
320 &div("ebx"); 418 &div("ecx");
321 &function_end($name); 419 &ret();
420 &function_end_B($name);
322 } 421 }
323 422
324sub bn_add_words 423sub bn_add_words
diff --git a/src/lib/libcrypto/bn/asm/co-586.pl b/src/lib/libcrypto/bn/asm/co-586.pl
index 5d962cb957..57101a6bd7 100644
--- a/src/lib/libcrypto/bn/asm/co-586.pl
+++ b/src/lib/libcrypto/bn/asm/co-586.pl
@@ -1,6 +1,7 @@
1#!/usr/local/bin/perl 1#!/usr/local/bin/perl
2 2
3push(@INC,"perlasm","../../perlasm"); 3$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
4push(@INC,"${dir}","${dir}../../perlasm");
4require "x86asm.pl"; 5require "x86asm.pl";
5 6
6&asm_init($ARGV[0],$0); 7&asm_init($ARGV[0],$0);
diff --git a/src/lib/libcrypto/bn/asm/ppc.pl b/src/lib/libcrypto/bn/asm/ppc.pl
index 08e0053473..37c65d3511 100644
--- a/src/lib/libcrypto/bn/asm/ppc.pl
+++ b/src/lib/libcrypto/bn/asm/ppc.pl
@@ -100,9 +100,9 @@
100# me a note at schari@us.ibm.com 100# me a note at schari@us.ibm.com
101# 101#
102 102
103$opf = shift; 103$flavour = shift;
104 104
105if ($opf =~ /32\.s/) { 105if ($flavour =~ /32/) {
106 $BITS= 32; 106 $BITS= 32;
107 $BNSZ= $BITS/8; 107 $BNSZ= $BITS/8;
108 $ISA= "\"ppc\""; 108 $ISA= "\"ppc\"";
@@ -125,7 +125,7 @@ if ($opf =~ /32\.s/) {
125 $INSR= "insrwi"; # insert right 125 $INSR= "insrwi"; # insert right
126 $ROTL= "rotlwi"; # rotate left by immediate 126 $ROTL= "rotlwi"; # rotate left by immediate
127 $TR= "tw"; # conditional trap 127 $TR= "tw"; # conditional trap
128} elsif ($opf =~ /64\.s/) { 128} elsif ($flavour =~ /64/) {
129 $BITS= 64; 129 $BITS= 64;
130 $BNSZ= $BITS/8; 130 $BNSZ= $BITS/8;
131 $ISA= "\"ppc64\""; 131 $ISA= "\"ppc64\"";
@@ -149,93 +149,16 @@ if ($opf =~ /32\.s/) {
149 $INSR= "insrdi"; # insert right 149 $INSR= "insrdi"; # insert right
150 $ROTL= "rotldi"; # rotate left by immediate 150 $ROTL= "rotldi"; # rotate left by immediate
151 $TR= "td"; # conditional trap 151 $TR= "td"; # conditional trap
152} else { die "nonsense $opf"; } 152} else { die "nonsense $flavour"; }
153 153
154( defined shift || open STDOUT,">$opf" ) || die "can't open $opf: $!"; 154$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
155( $xlate="${dir}ppc-xlate.pl" and -f $xlate ) or
156( $xlate="${dir}../../perlasm/ppc-xlate.pl" and -f $xlate) or
157die "can't locate ppc-xlate.pl";
155 158
156# function entry points from the AIX code 159open STDOUT,"| $^X $xlate $flavour ".shift || die "can't call $xlate: $!";
157#
158# There are other, more elegant, ways to handle this. We (IBM) chose
159# this approach as it plays well with scripts we run to 'namespace'
160# OpenSSL .i.e. we add a prefix to all the public symbols so we can
161# co-exist in the same process with other implementations of OpenSSL.
162# 'cleverer' ways of doing these substitutions tend to hide data we
163# need to be obvious.
164#
165my @items = ("bn_sqr_comba4",
166 "bn_sqr_comba8",
167 "bn_mul_comba4",
168 "bn_mul_comba8",
169 "bn_sub_words",
170 "bn_add_words",
171 "bn_div_words",
172 "bn_sqr_words",
173 "bn_mul_words",
174 "bn_mul_add_words");
175 160
176if ($opf =~ /linux/) { do_linux(); } 161$data=<<EOF;
177elsif ($opf =~ /aix/) { do_aix(); }
178elsif ($opf =~ /osx/) { do_osx(); }
179else { do_bsd(); }
180
181sub do_linux {
182 $d=&data();
183
184 if ($BITS==64) {
185 foreach $t (@items) {
186 $d =~ s/\.$t:/\
187\t.section\t".opd","aw"\
188\t.align\t3\
189\t.globl\t$t\
190$t:\
191\t.quad\t.$t,.TOC.\@tocbase,0\
192\t.size\t$t,24\
193\t.previous\n\
194\t.type\t.$t,\@function\
195\t.globl\t.$t\
196.$t:/g;
197 }
198 }
199 else {
200 foreach $t (@items) {
201 $d=~s/\.$t/$t/g;
202 }
203 }
204 # hide internal labels to avoid pollution of name table...
205 $d=~s/Lppcasm_/.Lppcasm_/gm;
206 print $d;
207}
208
209sub do_aix {
210 # AIX assembler is smart enough to please the linker without
211 # making us do something special...
212 print &data();
213}
214
215# MacOSX 32 bit
216sub do_osx {
217 $d=&data();
218 # Change the bn symbol prefix from '.' to '_'
219 foreach $t (@items) {
220 $d=~s/\.$t/_$t/g;
221 }
222 # Change .machine to something OS X asm will accept
223 $d=~s/\.machine.*/.text/g;
224 $d=~s/\#/;/g; # change comment from '#' to ';'
225 print $d;
226}
227
228# BSD (Untested)
229sub do_bsd {
230 $d=&data();
231 foreach $t (@items) {
232 $d=~s/\.$t/_$t/g;
233 }
234 print $d;
235}
236
237sub data {
238 local($data)=<<EOF;
239#-------------------------------------------------------------------- 162#--------------------------------------------------------------------
240# 163#
241# 164#
@@ -297,33 +220,20 @@ sub data {
297# 220#
298# Defines to be used in the assembly code. 221# Defines to be used in the assembly code.
299# 222#
300.set r0,0 # we use it as storage for value of 0 223#.set r0,0 # we use it as storage for value of 0
301.set SP,1 # preserved 224#.set SP,1 # preserved
302.set RTOC,2 # preserved 225#.set RTOC,2 # preserved
303.set r3,3 # 1st argument/return value 226#.set r3,3 # 1st argument/return value
304.set r4,4 # 2nd argument/volatile register 227#.set r4,4 # 2nd argument/volatile register
305.set r5,5 # 3rd argument/volatile register 228#.set r5,5 # 3rd argument/volatile register
306.set r6,6 # ... 229#.set r6,6 # ...
307.set r7,7 230#.set r7,7
308.set r8,8 231#.set r8,8
309.set r9,9 232#.set r9,9
310.set r10,10 233#.set r10,10
311.set r11,11 234#.set r11,11
312.set r12,12 235#.set r12,12
313.set r13,13 # not used, nor any other "below" it... 236#.set r13,13 # not used, nor any other "below" it...
314
315.set BO_IF_NOT,4
316.set BO_IF,12
317.set BO_dCTR_NZERO,16
318.set BO_dCTR_ZERO,18
319.set BO_ALWAYS,20
320.set CR0_LT,0;
321.set CR0_GT,1;
322.set CR0_EQ,2
323.set CR1_FX,4;
324.set CR1_FEX,5;
325.set CR1_VX,6
326.set LR,8
327 237
328# Declare function names to be global 238# Declare function names to be global
329# NOTE: For gcc these names MUST be changed to remove 239# NOTE: For gcc these names MUST be changed to remove
@@ -344,7 +254,7 @@ sub data {
344 254
345# .text section 255# .text section
346 256
347 .machine $ISA 257 .machine "any"
348 258
349# 259#
350# NOTE: The following label name should be changed to 260# NOTE: The following label name should be changed to
@@ -478,7 +388,7 @@ sub data {
478 388
479 $ST r9,`6*$BNSZ`(r3) #r[6]=c1 389 $ST r9,`6*$BNSZ`(r3) #r[6]=c1
480 $ST r10,`7*$BNSZ`(r3) #r[7]=c2 390 $ST r10,`7*$BNSZ`(r3) #r[7]=c2
481 bclr BO_ALWAYS,CR0_LT 391 blr
482 .long 0x00000000 392 .long 0x00000000
483 393
484# 394#
@@ -903,7 +813,7 @@ sub data {
903 $ST r9, `15*$BNSZ`(r3) #r[15]=c1; 813 $ST r9, `15*$BNSZ`(r3) #r[15]=c1;
904 814
905 815
906 bclr BO_ALWAYS,CR0_LT 816 blr
907 817
908 .long 0x00000000 818 .long 0x00000000
909 819
@@ -1055,7 +965,7 @@ sub data {
1055 965
1056 $ST r10,`6*$BNSZ`(r3) #r[6]=c1 966 $ST r10,`6*$BNSZ`(r3) #r[6]=c1
1057 $ST r11,`7*$BNSZ`(r3) #r[7]=c2 967 $ST r11,`7*$BNSZ`(r3) #r[7]=c2
1058 bclr BO_ALWAYS,CR0_LT 968 blr
1059 .long 0x00000000 969 .long 0x00000000
1060 970
1061# 971#
@@ -1591,7 +1501,7 @@ sub data {
1591 adde r10,r10,r9 1501 adde r10,r10,r9
1592 $ST r12,`14*$BNSZ`(r3) #r[14]=c3; 1502 $ST r12,`14*$BNSZ`(r3) #r[14]=c3;
1593 $ST r10,`15*$BNSZ`(r3) #r[15]=c1; 1503 $ST r10,`15*$BNSZ`(r3) #r[15]=c1;
1594 bclr BO_ALWAYS,CR0_LT 1504 blr
1595 .long 0x00000000 1505 .long 0x00000000
1596 1506
1597# 1507#
@@ -1623,7 +1533,7 @@ sub data {
1623 subfc. r7,r0,r6 # If r6 is 0 then result is 0. 1533 subfc. r7,r0,r6 # If r6 is 0 then result is 0.
1624 # if r6 > 0 then result !=0 1534 # if r6 > 0 then result !=0
1625 # In either case carry bit is set. 1535 # In either case carry bit is set.
1626 bc BO_IF,CR0_EQ,Lppcasm_sub_adios 1536 beq Lppcasm_sub_adios
1627 addi r4,r4,-$BNSZ 1537 addi r4,r4,-$BNSZ
1628 addi r3,r3,-$BNSZ 1538 addi r3,r3,-$BNSZ
1629 addi r5,r5,-$BNSZ 1539 addi r5,r5,-$BNSZ
@@ -1635,11 +1545,11 @@ Lppcasm_sub_mainloop:
1635 # if carry = 1 this is r7-r8. Else it 1545 # if carry = 1 this is r7-r8. Else it
1636 # is r7-r8 -1 as we need. 1546 # is r7-r8 -1 as we need.
1637 $STU r6,$BNSZ(r3) 1547 $STU r6,$BNSZ(r3)
1638 bc BO_dCTR_NZERO,CR0_EQ,Lppcasm_sub_mainloop 1548 bdnz- Lppcasm_sub_mainloop
1639Lppcasm_sub_adios: 1549Lppcasm_sub_adios:
1640 subfze r3,r0 # if carry bit is set then r3 = 0 else -1 1550 subfze r3,r0 # if carry bit is set then r3 = 0 else -1
1641 andi. r3,r3,1 # keep only last bit. 1551 andi. r3,r3,1 # keep only last bit.
1642 bclr BO_ALWAYS,CR0_LT 1552 blr
1643 .long 0x00000000 1553 .long 0x00000000
1644 1554
1645 1555
@@ -1670,7 +1580,7 @@ Lppcasm_sub_adios:
1670# check for r6 = 0. Is this needed? 1580# check for r6 = 0. Is this needed?
1671# 1581#
1672 addic. r6,r6,0 #test r6 and clear carry bit. 1582 addic. r6,r6,0 #test r6 and clear carry bit.
1673 bc BO_IF,CR0_EQ,Lppcasm_add_adios 1583 beq Lppcasm_add_adios
1674 addi r4,r4,-$BNSZ 1584 addi r4,r4,-$BNSZ
1675 addi r3,r3,-$BNSZ 1585 addi r3,r3,-$BNSZ
1676 addi r5,r5,-$BNSZ 1586 addi r5,r5,-$BNSZ
@@ -1680,10 +1590,10 @@ Lppcasm_add_mainloop:
1680 $LDU r8,$BNSZ(r5) 1590 $LDU r8,$BNSZ(r5)
1681 adde r8,r7,r8 1591 adde r8,r7,r8
1682 $STU r8,$BNSZ(r3) 1592 $STU r8,$BNSZ(r3)
1683 bc BO_dCTR_NZERO,CR0_EQ,Lppcasm_add_mainloop 1593 bdnz- Lppcasm_add_mainloop
1684Lppcasm_add_adios: 1594Lppcasm_add_adios:
1685 addze r3,r0 #return carry bit. 1595 addze r3,r0 #return carry bit.
1686 bclr BO_ALWAYS,CR0_LT 1596 blr
1687 .long 0x00000000 1597 .long 0x00000000
1688 1598
1689# 1599#
@@ -1707,24 +1617,24 @@ Lppcasm_add_adios:
1707# r5 = d 1617# r5 = d
1708 1618
1709 $UCMPI 0,r5,0 # compare r5 and 0 1619 $UCMPI 0,r5,0 # compare r5 and 0
1710 bc BO_IF_NOT,CR0_EQ,Lppcasm_div1 # proceed if d!=0 1620 bne Lppcasm_div1 # proceed if d!=0
1711 li r3,-1 # d=0 return -1 1621 li r3,-1 # d=0 return -1
1712 bclr BO_ALWAYS,CR0_LT 1622 blr
1713Lppcasm_div1: 1623Lppcasm_div1:
1714 xor r0,r0,r0 #r0=0 1624 xor r0,r0,r0 #r0=0
1715 li r8,$BITS 1625 li r8,$BITS
1716 $CNTLZ. r7,r5 #r7 = num leading 0s in d. 1626 $CNTLZ. r7,r5 #r7 = num leading 0s in d.
1717 bc BO_IF,CR0_EQ,Lppcasm_div2 #proceed if no leading zeros 1627 beq Lppcasm_div2 #proceed if no leading zeros
1718 subf r8,r7,r8 #r8 = BN_num_bits_word(d) 1628 subf r8,r7,r8 #r8 = BN_num_bits_word(d)
1719 $SHR. r9,r3,r8 #are there any bits above r8'th? 1629 $SHR. r9,r3,r8 #are there any bits above r8'th?
1720 $TR 16,r9,r0 #if there're, signal to dump core... 1630 $TR 16,r9,r0 #if there're, signal to dump core...
1721Lppcasm_div2: 1631Lppcasm_div2:
1722 $UCMP 0,r3,r5 #h>=d? 1632 $UCMP 0,r3,r5 #h>=d?
1723 bc BO_IF,CR0_LT,Lppcasm_div3 #goto Lppcasm_div3 if not 1633 blt Lppcasm_div3 #goto Lppcasm_div3 if not
1724 subf r3,r5,r3 #h-=d ; 1634 subf r3,r5,r3 #h-=d ;
1725Lppcasm_div3: #r7 = BN_BITS2-i. so r7=i 1635Lppcasm_div3: #r7 = BN_BITS2-i. so r7=i
1726 cmpi 0,0,r7,0 # is (i == 0)? 1636 cmpi 0,0,r7,0 # is (i == 0)?
1727 bc BO_IF,CR0_EQ,Lppcasm_div4 1637 beq Lppcasm_div4
1728 $SHL r3,r3,r7 # h = (h<< i) 1638 $SHL r3,r3,r7 # h = (h<< i)
1729 $SHR r8,r4,r8 # r8 = (l >> BN_BITS2 -i) 1639 $SHR r8,r4,r8 # r8 = (l >> BN_BITS2 -i)
1730 $SHL r5,r5,r7 # d<<=i 1640 $SHL r5,r5,r7 # d<<=i
@@ -1741,7 +1651,7 @@ Lppcasm_divouterloop:
1741 $SHRI r11,r4,`$BITS/2` #r11= (l&BN_MASK2h)>>BN_BITS4 1651 $SHRI r11,r4,`$BITS/2` #r11= (l&BN_MASK2h)>>BN_BITS4
1742 # compute here for innerloop. 1652 # compute here for innerloop.
1743 $UCMP 0,r8,r9 # is (h>>BN_BITS4)==dh 1653 $UCMP 0,r8,r9 # is (h>>BN_BITS4)==dh
1744 bc BO_IF_NOT,CR0_EQ,Lppcasm_div5 # goto Lppcasm_div5 if not 1654 bne Lppcasm_div5 # goto Lppcasm_div5 if not
1745 1655
1746 li r8,-1 1656 li r8,-1
1747 $CLRU r8,r8,`$BITS/2` #q = BN_MASK2l 1657 $CLRU r8,r8,`$BITS/2` #q = BN_MASK2l
@@ -1762,9 +1672,9 @@ Lppcasm_divinnerloop:
1762 # the following 2 instructions do that 1672 # the following 2 instructions do that
1763 $SHLI r7,r10,`$BITS/2` # r7 = (t<<BN_BITS4) 1673 $SHLI r7,r10,`$BITS/2` # r7 = (t<<BN_BITS4)
1764 or r7,r7,r11 # r7|=((l&BN_MASK2h)>>BN_BITS4) 1674 or r7,r7,r11 # r7|=((l&BN_MASK2h)>>BN_BITS4)
1765 $UCMP 1,r6,r7 # compare (tl <= r7) 1675 $UCMP cr1,r6,r7 # compare (tl <= r7)
1766 bc BO_IF_NOT,CR0_EQ,Lppcasm_divinnerexit 1676 bne Lppcasm_divinnerexit
1767 bc BO_IF_NOT,CR1_FEX,Lppcasm_divinnerexit 1677 ble cr1,Lppcasm_divinnerexit
1768 addi r8,r8,-1 #q-- 1678 addi r8,r8,-1 #q--
1769 subf r12,r9,r12 #th -=dh 1679 subf r12,r9,r12 #th -=dh
1770 $CLRU r10,r5,`$BITS/2` #r10=dl. t is no longer needed in loop. 1680 $CLRU r10,r5,`$BITS/2` #r10=dl. t is no longer needed in loop.
@@ -1773,14 +1683,14 @@ Lppcasm_divinnerloop:
1773Lppcasm_divinnerexit: 1683Lppcasm_divinnerexit:
1774 $SHRI r10,r6,`$BITS/2` #t=(tl>>BN_BITS4) 1684 $SHRI r10,r6,`$BITS/2` #t=(tl>>BN_BITS4)
1775 $SHLI r11,r6,`$BITS/2` #tl=(tl<<BN_BITS4)&BN_MASK2h; 1685 $SHLI r11,r6,`$BITS/2` #tl=(tl<<BN_BITS4)&BN_MASK2h;
1776 $UCMP 1,r4,r11 # compare l and tl 1686 $UCMP cr1,r4,r11 # compare l and tl
1777 add r12,r12,r10 # th+=t 1687 add r12,r12,r10 # th+=t
1778 bc BO_IF_NOT,CR1_FX,Lppcasm_div7 # if (l>=tl) goto Lppcasm_div7 1688 bge cr1,Lppcasm_div7 # if (l>=tl) goto Lppcasm_div7
1779 addi r12,r12,1 # th++ 1689 addi r12,r12,1 # th++
1780Lppcasm_div7: 1690Lppcasm_div7:
1781 subf r11,r11,r4 #r11=l-tl 1691 subf r11,r11,r4 #r11=l-tl
1782 $UCMP 1,r3,r12 #compare h and th 1692 $UCMP cr1,r3,r12 #compare h and th
1783 bc BO_IF_NOT,CR1_FX,Lppcasm_div8 #if (h>=th) goto Lppcasm_div8 1693 bge cr1,Lppcasm_div8 #if (h>=th) goto Lppcasm_div8
1784 addi r8,r8,-1 # q-- 1694 addi r8,r8,-1 # q--
1785 add r3,r5,r3 # h+=d 1695 add r3,r5,r3 # h+=d
1786Lppcasm_div8: 1696Lppcasm_div8:
@@ -1791,12 +1701,12 @@ Lppcasm_div8:
1791 # the following 2 instructions will do this. 1701 # the following 2 instructions will do this.
1792 $INSR r11,r12,`$BITS/2`,`$BITS/2` # r11 is the value we want rotated $BITS/2. 1702 $INSR r11,r12,`$BITS/2`,`$BITS/2` # r11 is the value we want rotated $BITS/2.
1793 $ROTL r3,r11,`$BITS/2` # rotate by $BITS/2 and store in r3 1703 $ROTL r3,r11,`$BITS/2` # rotate by $BITS/2 and store in r3
1794 bc BO_dCTR_ZERO,CR0_EQ,Lppcasm_div9#if (count==0) break ; 1704 bdz Lppcasm_div9 #if (count==0) break ;
1795 $SHLI r0,r8,`$BITS/2` #ret =q<<BN_BITS4 1705 $SHLI r0,r8,`$BITS/2` #ret =q<<BN_BITS4
1796 b Lppcasm_divouterloop 1706 b Lppcasm_divouterloop
1797Lppcasm_div9: 1707Lppcasm_div9:
1798 or r3,r8,r0 1708 or r3,r8,r0
1799 bclr BO_ALWAYS,CR0_LT 1709 blr
1800 .long 0x00000000 1710 .long 0x00000000
1801 1711
1802# 1712#
@@ -1822,7 +1732,7 @@ Lppcasm_div9:
1822# No unrolling done here. Not performance critical. 1732# No unrolling done here. Not performance critical.
1823 1733
1824 addic. r5,r5,0 #test r5. 1734 addic. r5,r5,0 #test r5.
1825 bc BO_IF,CR0_EQ,Lppcasm_sqr_adios 1735 beq Lppcasm_sqr_adios
1826 addi r4,r4,-$BNSZ 1736 addi r4,r4,-$BNSZ
1827 addi r3,r3,-$BNSZ 1737 addi r3,r3,-$BNSZ
1828 mtctr r5 1738 mtctr r5
@@ -1833,9 +1743,9 @@ Lppcasm_sqr_mainloop:
1833 $UMULH r8,r6,r6 1743 $UMULH r8,r6,r6
1834 $STU r7,$BNSZ(r3) 1744 $STU r7,$BNSZ(r3)
1835 $STU r8,$BNSZ(r3) 1745 $STU r8,$BNSZ(r3)
1836 bc BO_dCTR_NZERO,CR0_EQ,Lppcasm_sqr_mainloop 1746 bdnz- Lppcasm_sqr_mainloop
1837Lppcasm_sqr_adios: 1747Lppcasm_sqr_adios:
1838 bclr BO_ALWAYS,CR0_LT 1748 blr
1839 .long 0x00000000 1749 .long 0x00000000
1840 1750
1841 1751
@@ -1858,7 +1768,7 @@ Lppcasm_sqr_adios:
1858 xor r0,r0,r0 1768 xor r0,r0,r0
1859 xor r12,r12,r12 # used for carry 1769 xor r12,r12,r12 # used for carry
1860 rlwinm. r7,r5,30,2,31 # num >> 2 1770 rlwinm. r7,r5,30,2,31 # num >> 2
1861 bc BO_IF,CR0_EQ,Lppcasm_mw_REM 1771 beq Lppcasm_mw_REM
1862 mtctr r7 1772 mtctr r7
1863Lppcasm_mw_LOOP: 1773Lppcasm_mw_LOOP:
1864 #mul(rp[0],ap[0],w,c1); 1774 #mul(rp[0],ap[0],w,c1);
@@ -1896,11 +1806,11 @@ Lppcasm_mw_LOOP:
1896 1806
1897 addi r3,r3,`4*$BNSZ` 1807 addi r3,r3,`4*$BNSZ`
1898 addi r4,r4,`4*$BNSZ` 1808 addi r4,r4,`4*$BNSZ`
1899 bc BO_dCTR_NZERO,CR0_EQ,Lppcasm_mw_LOOP 1809 bdnz- Lppcasm_mw_LOOP
1900 1810
1901Lppcasm_mw_REM: 1811Lppcasm_mw_REM:
1902 andi. r5,r5,0x3 1812 andi. r5,r5,0x3
1903 bc BO_IF,CR0_EQ,Lppcasm_mw_OVER 1813 beq Lppcasm_mw_OVER
1904 #mul(rp[0],ap[0],w,c1); 1814 #mul(rp[0],ap[0],w,c1);
1905 $LD r8,`0*$BNSZ`(r4) 1815 $LD r8,`0*$BNSZ`(r4)
1906 $UMULL r9,r6,r8 1816 $UMULL r9,r6,r8
@@ -1912,7 +1822,7 @@ Lppcasm_mw_REM:
1912 1822
1913 addi r5,r5,-1 1823 addi r5,r5,-1
1914 cmpli 0,0,r5,0 1824 cmpli 0,0,r5,0
1915 bc BO_IF,CR0_EQ,Lppcasm_mw_OVER 1825 beq Lppcasm_mw_OVER
1916 1826
1917 1827
1918 #mul(rp[1],ap[1],w,c1); 1828 #mul(rp[1],ap[1],w,c1);
@@ -1926,7 +1836,7 @@ Lppcasm_mw_REM:
1926 1836
1927 addi r5,r5,-1 1837 addi r5,r5,-1
1928 cmpli 0,0,r5,0 1838 cmpli 0,0,r5,0
1929 bc BO_IF,CR0_EQ,Lppcasm_mw_OVER 1839 beq Lppcasm_mw_OVER
1930 1840
1931 #mul_add(rp[2],ap[2],w,c1); 1841 #mul_add(rp[2],ap[2],w,c1);
1932 $LD r8,`2*$BNSZ`(r4) 1842 $LD r8,`2*$BNSZ`(r4)
@@ -1939,7 +1849,7 @@ Lppcasm_mw_REM:
1939 1849
1940Lppcasm_mw_OVER: 1850Lppcasm_mw_OVER:
1941 addi r3,r12,0 1851 addi r3,r12,0
1942 bclr BO_ALWAYS,CR0_LT 1852 blr
1943 .long 0x00000000 1853 .long 0x00000000
1944 1854
1945# 1855#
@@ -1964,7 +1874,7 @@ Lppcasm_mw_OVER:
1964 xor r0,r0,r0 #r0 = 0 1874 xor r0,r0,r0 #r0 = 0
1965 xor r12,r12,r12 #r12 = 0 . used for carry 1875 xor r12,r12,r12 #r12 = 0 . used for carry
1966 rlwinm. r7,r5,30,2,31 # num >> 2 1876 rlwinm. r7,r5,30,2,31 # num >> 2
1967 bc BO_IF,CR0_EQ,Lppcasm_maw_leftover # if (num < 4) go LPPCASM_maw_leftover 1877 beq Lppcasm_maw_leftover # if (num < 4) go LPPCASM_maw_leftover
1968 mtctr r7 1878 mtctr r7
1969Lppcasm_maw_mainloop: 1879Lppcasm_maw_mainloop:
1970 #mul_add(rp[0],ap[0],w,c1); 1880 #mul_add(rp[0],ap[0],w,c1);
@@ -2017,11 +1927,11 @@ Lppcasm_maw_mainloop:
2017 $ST r11,`3*$BNSZ`(r3) 1927 $ST r11,`3*$BNSZ`(r3)
2018 addi r3,r3,`4*$BNSZ` 1928 addi r3,r3,`4*$BNSZ`
2019 addi r4,r4,`4*$BNSZ` 1929 addi r4,r4,`4*$BNSZ`
2020 bc BO_dCTR_NZERO,CR0_EQ,Lppcasm_maw_mainloop 1930 bdnz- Lppcasm_maw_mainloop
2021 1931
2022Lppcasm_maw_leftover: 1932Lppcasm_maw_leftover:
2023 andi. r5,r5,0x3 1933 andi. r5,r5,0x3
2024 bc BO_IF,CR0_EQ,Lppcasm_maw_adios 1934 beq Lppcasm_maw_adios
2025 addi r3,r3,-$BNSZ 1935 addi r3,r3,-$BNSZ
2026 addi r4,r4,-$BNSZ 1936 addi r4,r4,-$BNSZ
2027 #mul_add(rp[0],ap[0],w,c1); 1937 #mul_add(rp[0],ap[0],w,c1);
@@ -2036,7 +1946,7 @@ Lppcasm_maw_leftover:
2036 addze r12,r10 1946 addze r12,r10
2037 $ST r9,0(r3) 1947 $ST r9,0(r3)
2038 1948
2039 bc BO_dCTR_ZERO,CR0_EQ,Lppcasm_maw_adios 1949 bdz Lppcasm_maw_adios
2040 #mul_add(rp[1],ap[1],w,c1); 1950 #mul_add(rp[1],ap[1],w,c1);
2041 $LDU r8,$BNSZ(r4) 1951 $LDU r8,$BNSZ(r4)
2042 $UMULL r9,r6,r8 1952 $UMULL r9,r6,r8
@@ -2048,7 +1958,7 @@ Lppcasm_maw_leftover:
2048 addze r12,r10 1958 addze r12,r10
2049 $ST r9,0(r3) 1959 $ST r9,0(r3)
2050 1960
2051 bc BO_dCTR_ZERO,CR0_EQ,Lppcasm_maw_adios 1961 bdz Lppcasm_maw_adios
2052 #mul_add(rp[2],ap[2],w,c1); 1962 #mul_add(rp[2],ap[2],w,c1);
2053 $LDU r8,$BNSZ(r4) 1963 $LDU r8,$BNSZ(r4)
2054 $UMULL r9,r6,r8 1964 $UMULL r9,r6,r8
@@ -2062,17 +1972,10 @@ Lppcasm_maw_leftover:
2062 1972
2063Lppcasm_maw_adios: 1973Lppcasm_maw_adios:
2064 addi r3,r12,0 1974 addi r3,r12,0
2065 bclr BO_ALWAYS,CR0_LT 1975 blr
2066 .long 0x00000000 1976 .long 0x00000000
2067 .align 4 1977 .align 4
2068EOF 1978EOF
2069 $data =~ s/\`([^\`]*)\`/eval $1/gem; 1979$data =~ s/\`([^\`]*)\`/eval $1/gem;
2070 1980print $data;
2071 # if some assembler chokes on some simplified mnemonic, 1981close STDOUT;
2072 # this is the spot to fix it up, e.g.:
2073 # GNU as doesn't seem to accept cmplw, 32-bit unsigned compare
2074 $data =~ s/^(\s*)cmplw(\s+)([^,]+),(.*)/$1cmpl$2$3,0,$4/gm;
2075 # assembler X doesn't accept li, load immediate value
2076 #$data =~ s/^(\s*)li(\s+)([^,]+),(.*)/$1addi$2$3,0,$4/gm;
2077 return($data);
2078}
diff --git a/src/lib/libcrypto/bn/asm/sparcv8plus.S b/src/lib/libcrypto/bn/asm/sparcv8plus.S
index 8c56e2e7e7..63de1860f2 100644
--- a/src/lib/libcrypto/bn/asm/sparcv8plus.S
+++ b/src/lib/libcrypto/bn/asm/sparcv8plus.S
@@ -144,6 +144,19 @@
144 * } 144 * }
145 */ 145 */
146 146
147#if defined(__SUNPRO_C) && defined(__sparcv9)
148 /* They've said -xarch=v9 at command line */
149 .register %g2,#scratch
150 .register %g3,#scratch
151# define FRAME_SIZE -192
152#elif defined(__GNUC__) && defined(__arch64__)
153 /* They've said -m64 at command line */
154 .register %g2,#scratch
155 .register %g3,#scratch
156# define FRAME_SIZE -192
157#else
158# define FRAME_SIZE -96
159#endif
147/* 160/*
148 * GNU assembler can't stand stuw:-( 161 * GNU assembler can't stand stuw:-(
149 */ 162 */
@@ -619,8 +632,6 @@ bn_sub_words:
619 * Andy. 632 * Andy.
620 */ 633 */
621 634
622#define FRAME_SIZE -96
623
624/* 635/*
625 * Here is register usage map for *all* routines below. 636 * Here is register usage map for *all* routines below.
626 */ 637 */
diff --git a/src/lib/libcrypto/bn/asm/x86_64-gcc.c b/src/lib/libcrypto/bn/asm/x86_64-gcc.c
index f13f52dd85..acb0b40118 100644
--- a/src/lib/libcrypto/bn/asm/x86_64-gcc.c
+++ b/src/lib/libcrypto/bn/asm/x86_64-gcc.c
@@ -1,4 +1,5 @@
1#ifdef __SUNPRO_C 1#include "../bn_lcl.h"
2#if !(defined(__GNUC__) && __GNUC__>=2)
2# include "../bn_asm.c" /* kind of dirty hack for Sun Studio */ 3# include "../bn_asm.c" /* kind of dirty hack for Sun Studio */
3#else 4#else
4/* 5/*
@@ -54,7 +55,15 @@
54 * machine. 55 * machine.
55 */ 56 */
56 57
58#ifdef _WIN64
59#define BN_ULONG unsigned long long
60#else
57#define BN_ULONG unsigned long 61#define BN_ULONG unsigned long
62#endif
63
64#undef mul
65#undef mul_add
66#undef sqr
58 67
59/* 68/*
60 * "m"(a), "+m"(r) is the way to favor DirectPath µ-code; 69 * "m"(a), "+m"(r) is the way to favor DirectPath µ-code;
@@ -97,7 +106,7 @@
97 : "a"(a) \ 106 : "a"(a) \
98 : "cc"); 107 : "cc");
99 108
100BN_ULONG bn_mul_add_words(BN_ULONG *rp, BN_ULONG *ap, int num, BN_ULONG w) 109BN_ULONG bn_mul_add_words(BN_ULONG *rp, const BN_ULONG *ap, int num, BN_ULONG w)
101 { 110 {
102 BN_ULONG c1=0; 111 BN_ULONG c1=0;
103 112
@@ -121,7 +130,7 @@ BN_ULONG bn_mul_add_words(BN_ULONG *rp, BN_ULONG *ap, int num, BN_ULONG w)
121 return(c1); 130 return(c1);
122 } 131 }
123 132
124BN_ULONG bn_mul_words(BN_ULONG *rp, BN_ULONG *ap, int num, BN_ULONG w) 133BN_ULONG bn_mul_words(BN_ULONG *rp, const BN_ULONG *ap, int num, BN_ULONG w)
125 { 134 {
126 BN_ULONG c1=0; 135 BN_ULONG c1=0;
127 136
@@ -144,7 +153,7 @@ BN_ULONG bn_mul_words(BN_ULONG *rp, BN_ULONG *ap, int num, BN_ULONG w)
144 return(c1); 153 return(c1);
145 } 154 }
146 155
147void bn_sqr_words(BN_ULONG *r, BN_ULONG *a, int n) 156void bn_sqr_words(BN_ULONG *r, const BN_ULONG *a, int n)
148 { 157 {
149 if (n <= 0) return; 158 if (n <= 0) return;
150 159
@@ -175,14 +184,14 @@ BN_ULONG bn_div_words(BN_ULONG h, BN_ULONG l, BN_ULONG d)
175 return ret; 184 return ret;
176} 185}
177 186
178BN_ULONG bn_add_words (BN_ULONG *rp, BN_ULONG *ap, BN_ULONG *bp,int n) 187BN_ULONG bn_add_words (BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp,int n)
179{ BN_ULONG ret=0,i=0; 188{ BN_ULONG ret=0,i=0;
180 189
181 if (n <= 0) return 0; 190 if (n <= 0) return 0;
182 191
183 asm ( 192 asm (
184 " subq %2,%2 \n" 193 " subq %2,%2 \n"
185 ".align 16 \n" 194 ".p2align 4 \n"
186 "1: movq (%4,%2,8),%0 \n" 195 "1: movq (%4,%2,8),%0 \n"
187 " adcq (%5,%2,8),%0 \n" 196 " adcq (%5,%2,8),%0 \n"
188 " movq %0,(%3,%2,8) \n" 197 " movq %0,(%3,%2,8) \n"
@@ -198,14 +207,14 @@ BN_ULONG bn_add_words (BN_ULONG *rp, BN_ULONG *ap, BN_ULONG *bp,int n)
198} 207}
199 208
200#ifndef SIMICS 209#ifndef SIMICS
201BN_ULONG bn_sub_words (BN_ULONG *rp, BN_ULONG *ap, BN_ULONG *bp,int n) 210BN_ULONG bn_sub_words (BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp,int n)
202{ BN_ULONG ret=0,i=0; 211{ BN_ULONG ret=0,i=0;
203 212
204 if (n <= 0) return 0; 213 if (n <= 0) return 0;
205 214
206 asm ( 215 asm (
207 " subq %2,%2 \n" 216 " subq %2,%2 \n"
208 ".align 16 \n" 217 ".p2align 4 \n"
209 "1: movq (%4,%2,8),%0 \n" 218 "1: movq (%4,%2,8),%0 \n"
210 " sbbq (%5,%2,8),%0 \n" 219 " sbbq (%5,%2,8),%0 \n"
211 " movq %0,(%3,%2,8) \n" 220 " movq %0,(%3,%2,8) \n"
@@ -485,7 +494,7 @@ void bn_mul_comba4(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b)
485 r[7]=c2; 494 r[7]=c2;
486 } 495 }
487 496
488void bn_sqr_comba8(BN_ULONG *r, BN_ULONG *a) 497void bn_sqr_comba8(BN_ULONG *r, const BN_ULONG *a)
489 { 498 {
490 BN_ULONG t1,t2; 499 BN_ULONG t1,t2;
491 BN_ULONG c1,c2,c3; 500 BN_ULONG c1,c2,c3;
@@ -561,7 +570,7 @@ void bn_sqr_comba8(BN_ULONG *r, BN_ULONG *a)
561 r[15]=c1; 570 r[15]=c1;
562 } 571 }
563 572
564void bn_sqr_comba4(BN_ULONG *r, BN_ULONG *a) 573void bn_sqr_comba4(BN_ULONG *r, const BN_ULONG *a)
565 { 574 {
566 BN_ULONG t1,t2; 575 BN_ULONG t1,t2;
567 BN_ULONG c1,c2,c3; 576 BN_ULONG c1,c2,c3;
diff --git a/src/lib/libcrypto/bn/asm/x86_64-mont.pl b/src/lib/libcrypto/bn/asm/x86_64-mont.pl
index c43b69592a..3b7a6f243f 100755
--- a/src/lib/libcrypto/bn/asm/x86_64-mont.pl
+++ b/src/lib/libcrypto/bn/asm/x86_64-mont.pl
@@ -15,14 +15,18 @@
15# respectful 50%. It remains to be seen if loop unrolling and 15# respectful 50%. It remains to be seen if loop unrolling and
16# dedicated squaring routine can provide further improvement... 16# dedicated squaring routine can provide further improvement...
17 17
18$output=shift; 18$flavour = shift;
19$output = shift;
20if ($flavour =~ /\./) { $output = $flavour; undef $flavour; }
21
22$win64=0; $win64=1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/);
19 23
20$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; 24$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
21( $xlate="${dir}x86_64-xlate.pl" and -f $xlate ) or 25( $xlate="${dir}x86_64-xlate.pl" and -f $xlate ) or
22( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or 26( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or
23die "can't locate x86_64-xlate.pl"; 27die "can't locate x86_64-xlate.pl";
24 28
25open STDOUT,"| $^X $xlate $output"; 29open STDOUT,"| $^X $xlate $flavour $output";
26 30
27# int bn_mul_mont( 31# int bn_mul_mont(
28$rp="%rdi"; # BN_ULONG *rp, 32$rp="%rdi"; # BN_ULONG *rp,
@@ -55,13 +59,14 @@ bn_mul_mont:
55 push %r15 59 push %r15
56 60
57 mov ${num}d,${num}d 61 mov ${num}d,${num}d
58 lea 2($num),%rax 62 lea 2($num),%r10
59 mov %rsp,%rbp 63 mov %rsp,%r11
60 neg %rax 64 neg %r10
61 lea (%rsp,%rax,8),%rsp # tp=alloca(8*(num+2)) 65 lea (%rsp,%r10,8),%rsp # tp=alloca(8*(num+2))
62 and \$-1024,%rsp # minimize TLB usage 66 and \$-1024,%rsp # minimize TLB usage
63 67
64 mov %rbp,8(%rsp,$num,8) # tp[num+1]=%rsp 68 mov %r11,8(%rsp,$num,8) # tp[num+1]=%rsp
69.Lprologue:
65 mov %rdx,$bp # $bp reassigned, remember? 70 mov %rdx,$bp # $bp reassigned, remember?
66 71
67 mov ($n0),$n0 # pull n0[0] value 72 mov ($n0),$n0 # pull n0[0] value
@@ -197,18 +202,129 @@ bn_mul_mont:
197 dec $j 202 dec $j
198 jge .Lcopy 203 jge .Lcopy
199 204
200 mov 8(%rsp,$num,8),%rsp # restore %rsp 205 mov 8(%rsp,$num,8),%rsi # restore %rsp
201 mov \$1,%rax 206 mov \$1,%rax
207 mov (%rsi),%r15
208 mov 8(%rsi),%r14
209 mov 16(%rsi),%r13
210 mov 24(%rsi),%r12
211 mov 32(%rsi),%rbp
212 mov 40(%rsi),%rbx
213 lea 48(%rsi),%rsp
214.Lepilogue:
215 ret
216.size bn_mul_mont,.-bn_mul_mont
217.asciz "Montgomery Multiplication for x86_64, CRYPTOGAMS by <appro\@openssl.org>"
218.align 16
219___
220
221# EXCEPTION_DISPOSITION handler (EXCEPTION_RECORD *rec,ULONG64 frame,
222# CONTEXT *context,DISPATCHER_CONTEXT *disp)
223if ($win64) {
224$rec="%rcx";
225$frame="%rdx";
226$context="%r8";
227$disp="%r9";
228
229$code.=<<___;
230.extern __imp_RtlVirtualUnwind
231.type se_handler,\@abi-omnipotent
232.align 16
233se_handler:
234 push %rsi
235 push %rdi
236 push %rbx
237 push %rbp
238 push %r12
239 push %r13
240 push %r14
241 push %r15
242 pushfq
243 sub \$64,%rsp
244
245 mov 120($context),%rax # pull context->Rax
246 mov 248($context),%rbx # pull context->Rip
247
248 lea .Lprologue(%rip),%r10
249 cmp %r10,%rbx # context->Rip<.Lprologue
250 jb .Lin_prologue
251
252 mov 152($context),%rax # pull context->Rsp
253
254 lea .Lepilogue(%rip),%r10
255 cmp %r10,%rbx # context->Rip>=.Lepilogue
256 jae .Lin_prologue
257
258 mov 192($context),%r10 # pull $num
259 mov 8(%rax,%r10,8),%rax # pull saved stack pointer
260 lea 48(%rax),%rax
261
262 mov -8(%rax),%rbx
263 mov -16(%rax),%rbp
264 mov -24(%rax),%r12
265 mov -32(%rax),%r13
266 mov -40(%rax),%r14
267 mov -48(%rax),%r15
268 mov %rbx,144($context) # restore context->Rbx
269 mov %rbp,160($context) # restore context->Rbp
270 mov %r12,216($context) # restore context->R12
271 mov %r13,224($context) # restore context->R13
272 mov %r14,232($context) # restore context->R14
273 mov %r15,240($context) # restore context->R15
274
275.Lin_prologue:
276 mov 8(%rax),%rdi
277 mov 16(%rax),%rsi
278 mov %rax,152($context) # restore context->Rsp
279 mov %rsi,168($context) # restore context->Rsi
280 mov %rdi,176($context) # restore context->Rdi
281
282 mov 40($disp),%rdi # disp->ContextRecord
283 mov $context,%rsi # context
284 mov \$154,%ecx # sizeof(CONTEXT)
285 .long 0xa548f3fc # cld; rep movsq
286
287 mov $disp,%rsi
288 xor %rcx,%rcx # arg1, UNW_FLAG_NHANDLER
289 mov 8(%rsi),%rdx # arg2, disp->ImageBase
290 mov 0(%rsi),%r8 # arg3, disp->ControlPc
291 mov 16(%rsi),%r9 # arg4, disp->FunctionEntry
292 mov 40(%rsi),%r10 # disp->ContextRecord
293 lea 56(%rsi),%r11 # &disp->HandlerData
294 lea 24(%rsi),%r12 # &disp->EstablisherFrame
295 mov %r10,32(%rsp) # arg5
296 mov %r11,40(%rsp) # arg6
297 mov %r12,48(%rsp) # arg7
298 mov %rcx,56(%rsp) # arg8, (NULL)
299 call *__imp_RtlVirtualUnwind(%rip)
300
301 mov \$1,%eax # ExceptionContinueSearch
302 add \$64,%rsp
303 popfq
202 pop %r15 304 pop %r15
203 pop %r14 305 pop %r14
204 pop %r13 306 pop %r13
205 pop %r12 307 pop %r12
206 pop %rbp 308 pop %rbp
207 pop %rbx 309 pop %rbx
310 pop %rdi
311 pop %rsi
208 ret 312 ret
209.size bn_mul_mont,.-bn_mul_mont 313.size se_handler,.-se_handler
210.asciz "Montgomery Multiplication for x86_64, CRYPTOGAMS by <appro\@openssl.org>" 314
315.section .pdata
316.align 4
317 .rva .LSEH_begin_bn_mul_mont
318 .rva .LSEH_end_bn_mul_mont
319 .rva .LSEH_info_bn_mul_mont
320
321.section .xdata
322.align 8
323.LSEH_info_bn_mul_mont:
324 .byte 9,0,0,0
325 .rva se_handler
211___ 326___
327}
212 328
213print $code; 329print $code;
214close STDOUT; 330close STDOUT;
diff --git a/src/lib/libcrypto/bn/bn.h b/src/lib/libcrypto/bn/bn.h
index f1719a5877..e484b7fc11 100644
--- a/src/lib/libcrypto/bn/bn.h
+++ b/src/lib/libcrypto/bn/bn.h
@@ -56,6 +56,59 @@
56 * [including the GNU Public Licence.] 56 * [including the GNU Public Licence.]
57 */ 57 */
58/* ==================================================================== 58/* ====================================================================
59 * Copyright (c) 1998-2006 The OpenSSL Project. All rights reserved.
60 *
61 * Redistribution and use in source and binary forms, with or without
62 * modification, are permitted provided that the following conditions
63 * are met:
64 *
65 * 1. Redistributions of source code must retain the above copyright
66 * notice, this list of conditions and the following disclaimer.
67 *
68 * 2. Redistributions in binary form must reproduce the above copyright
69 * notice, this list of conditions and the following disclaimer in
70 * the documentation and/or other materials provided with the
71 * distribution.
72 *
73 * 3. All advertising materials mentioning features or use of this
74 * software must display the following acknowledgment:
75 * "This product includes software developed by the OpenSSL Project
76 * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
77 *
78 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
79 * endorse or promote products derived from this software without
80 * prior written permission. For written permission, please contact
81 * openssl-core@openssl.org.
82 *
83 * 5. Products derived from this software may not be called "OpenSSL"
84 * nor may "OpenSSL" appear in their names without prior written
85 * permission of the OpenSSL Project.
86 *
87 * 6. Redistributions of any form whatsoever must retain the following
88 * acknowledgment:
89 * "This product includes software developed by the OpenSSL Project
90 * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
91 *
92 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
93 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
94 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
95 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
96 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
97 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
98 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
99 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
100 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
101 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
102 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
103 * OF THE POSSIBILITY OF SUCH DAMAGE.
104 * ====================================================================
105 *
106 * This product includes cryptographic software written by Eric Young
107 * (eay@cryptsoft.com). This product includes software written by Tim
108 * Hudson (tjh@cryptsoft.com).
109 *
110 */
111/* ====================================================================
59 * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. 112 * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
60 * 113 *
61 * Portions of the attached software ("Contribution") are developed by 114 * Portions of the attached software ("Contribution") are developed by
@@ -77,6 +130,7 @@
77#include <stdio.h> /* FILE */ 130#include <stdio.h> /* FILE */
78#endif 131#endif
79#include <openssl/ossl_typ.h> 132#include <openssl/ossl_typ.h>
133#include <openssl/crypto.h>
80 134
81#ifdef __cplusplus 135#ifdef __cplusplus
82extern "C" { 136extern "C" {
@@ -94,9 +148,11 @@ extern "C" {
94/* #define BN_DEBUG */ 148/* #define BN_DEBUG */
95/* #define BN_DEBUG_RAND */ 149/* #define BN_DEBUG_RAND */
96 150
151#ifndef OPENSSL_SMALL_FOOTPRINT
97#define BN_MUL_COMBA 152#define BN_MUL_COMBA
98#define BN_SQR_COMBA 153#define BN_SQR_COMBA
99#define BN_RECURSION 154#define BN_RECURSION
155#endif
100 156
101/* This next option uses the C libraries (2 word)/(1 word) function. 157/* This next option uses the C libraries (2 word)/(1 word) function.
102 * If it is not defined, I use my C version (which is slower). 158 * If it is not defined, I use my C version (which is slower).
@@ -137,6 +193,8 @@ extern "C" {
137#define BN_DEC_FMT1 "%lu" 193#define BN_DEC_FMT1 "%lu"
138#define BN_DEC_FMT2 "%019lu" 194#define BN_DEC_FMT2 "%019lu"
139#define BN_DEC_NUM 19 195#define BN_DEC_NUM 19
196#define BN_HEX_FMT1 "%lX"
197#define BN_HEX_FMT2 "%016lX"
140#endif 198#endif
141 199
142/* This is where the long long data type is 64 bits, but long is 32. 200/* This is where the long long data type is 64 bits, but long is 32.
@@ -162,83 +220,37 @@ extern "C" {
162#define BN_DEC_FMT1 "%llu" 220#define BN_DEC_FMT1 "%llu"
163#define BN_DEC_FMT2 "%019llu" 221#define BN_DEC_FMT2 "%019llu"
164#define BN_DEC_NUM 19 222#define BN_DEC_NUM 19
223#define BN_HEX_FMT1 "%llX"
224#define BN_HEX_FMT2 "%016llX"
165#endif 225#endif
166 226
167#ifdef THIRTY_TWO_BIT 227#ifdef THIRTY_TWO_BIT
168#ifdef BN_LLONG 228#ifdef BN_LLONG
169# if defined(OPENSSL_SYS_WIN32) && !defined(__GNUC__) 229# if defined(_WIN32) && !defined(__GNUC__)
170# define BN_ULLONG unsigned __int64 230# define BN_ULLONG unsigned __int64
231# define BN_MASK (0xffffffffffffffffI64)
171# else 232# else
172# define BN_ULLONG unsigned long long 233# define BN_ULLONG unsigned long long
234# define BN_MASK (0xffffffffffffffffLL)
173# endif 235# endif
174#endif 236#endif
175#define BN_ULONG unsigned long 237#define BN_ULONG unsigned int
176#define BN_LONG long 238#define BN_LONG int
177#define BN_BITS 64 239#define BN_BITS 64
178#define BN_BYTES 4 240#define BN_BYTES 4
179#define BN_BITS2 32 241#define BN_BITS2 32
180#define BN_BITS4 16 242#define BN_BITS4 16
181#ifdef OPENSSL_SYS_WIN32
182/* VC++ doesn't like the LL suffix */
183#define BN_MASK (0xffffffffffffffffL)
184#else
185#define BN_MASK (0xffffffffffffffffLL)
186#endif
187#define BN_MASK2 (0xffffffffL) 243#define BN_MASK2 (0xffffffffL)
188#define BN_MASK2l (0xffff) 244#define BN_MASK2l (0xffff)
189#define BN_MASK2h1 (0xffff8000L) 245#define BN_MASK2h1 (0xffff8000L)
190#define BN_MASK2h (0xffff0000L) 246#define BN_MASK2h (0xffff0000L)
191#define BN_TBIT (0x80000000L) 247#define BN_TBIT (0x80000000L)
192#define BN_DEC_CONV (1000000000L) 248#define BN_DEC_CONV (1000000000L)
193#define BN_DEC_FMT1 "%lu"
194#define BN_DEC_FMT2 "%09lu"
195#define BN_DEC_NUM 9
196#endif
197
198#ifdef SIXTEEN_BIT
199#ifndef BN_DIV2W
200#define BN_DIV2W
201#endif
202#define BN_ULLONG unsigned long
203#define BN_ULONG unsigned short
204#define BN_LONG short
205#define BN_BITS 32
206#define BN_BYTES 2
207#define BN_BITS2 16
208#define BN_BITS4 8
209#define BN_MASK (0xffffffff)
210#define BN_MASK2 (0xffff)
211#define BN_MASK2l (0xff)
212#define BN_MASK2h1 (0xff80)
213#define BN_MASK2h (0xff00)
214#define BN_TBIT (0x8000)
215#define BN_DEC_CONV (100000)
216#define BN_DEC_FMT1 "%u" 249#define BN_DEC_FMT1 "%u"
217#define BN_DEC_FMT2 "%05u" 250#define BN_DEC_FMT2 "%09u"
218#define BN_DEC_NUM 5 251#define BN_DEC_NUM 9
219#endif 252#define BN_HEX_FMT1 "%X"
220 253#define BN_HEX_FMT2 "%08X"
221#ifdef EIGHT_BIT
222#ifndef BN_DIV2W
223#define BN_DIV2W
224#endif
225#define BN_ULLONG unsigned short
226#define BN_ULONG unsigned char
227#define BN_LONG char
228#define BN_BITS 16
229#define BN_BYTES 1
230#define BN_BITS2 8
231#define BN_BITS4 4
232#define BN_MASK (0xffff)
233#define BN_MASK2 (0xff)
234#define BN_MASK2l (0xf)
235#define BN_MASK2h1 (0xf8)
236#define BN_MASK2h (0xf0)
237#define BN_TBIT (0x80)
238#define BN_DEC_CONV (100)
239#define BN_DEC_FMT1 "%u"
240#define BN_DEC_FMT2 "%02u"
241#define BN_DEC_NUM 2
242#endif 254#endif
243 255
244#define BN_DEFAULT_BITS 1280 256#define BN_DEFAULT_BITS 1280
@@ -303,12 +315,8 @@ struct bn_mont_ctx_st
303 BIGNUM N; /* The modulus */ 315 BIGNUM N; /* The modulus */
304 BIGNUM Ni; /* R*(1/R mod N) - N*Ni = 1 316 BIGNUM Ni; /* R*(1/R mod N) - N*Ni = 1
305 * (Ni is only stored for bignum algorithm) */ 317 * (Ni is only stored for bignum algorithm) */
306#if 0 318 BN_ULONG n0[2];/* least significant word(s) of Ni;
307 /* OpenSSL 0.9.9 preview: */ 319 (type changed with 0.9.9, was "BN_ULONG n0;" before) */
308 BN_ULONG n0[2];/* least significant word(s) of Ni */
309#else
310 BN_ULONG n0; /* least significant word of Ni */
311#endif
312 int flags; 320 int flags;
313 }; 321 };
314 322
@@ -504,6 +512,7 @@ char * BN_bn2hex(const BIGNUM *a);
504char * BN_bn2dec(const BIGNUM *a); 512char * BN_bn2dec(const BIGNUM *a);
505int BN_hex2bn(BIGNUM **a, const char *str); 513int BN_hex2bn(BIGNUM **a, const char *str);
506int BN_dec2bn(BIGNUM **a, const char *str); 514int BN_dec2bn(BIGNUM **a, const char *str);
515int BN_asc2bn(BIGNUM **a, const char *str);
507int BN_gcd(BIGNUM *r,const BIGNUM *a,const BIGNUM *b,BN_CTX *ctx); 516int BN_gcd(BIGNUM *r,const BIGNUM *a,const BIGNUM *b,BN_CTX *ctx);
508int BN_kronecker(const BIGNUM *a,const BIGNUM *b,BN_CTX *ctx); /* returns -2 for error */ 517int BN_kronecker(const BIGNUM *a,const BIGNUM *b,BN_CTX *ctx); /* returns -2 for error */
509BIGNUM *BN_mod_inverse(BIGNUM *ret, 518BIGNUM *BN_mod_inverse(BIGNUM *ret,
@@ -531,17 +540,6 @@ int BN_is_prime_ex(const BIGNUM *p,int nchecks, BN_CTX *ctx, BN_GENCB *cb);
531int BN_is_prime_fasttest_ex(const BIGNUM *p,int nchecks, BN_CTX *ctx, 540int BN_is_prime_fasttest_ex(const BIGNUM *p,int nchecks, BN_CTX *ctx,
532 int do_trial_division, BN_GENCB *cb); 541 int do_trial_division, BN_GENCB *cb);
533 542
534int BN_X931_generate_Xpq(BIGNUM *Xp, BIGNUM *Xq, int nbits, BN_CTX *ctx);
535
536int BN_X931_derive_prime_ex(BIGNUM *p, BIGNUM *p1, BIGNUM *p2,
537 const BIGNUM *Xp, const BIGNUM *Xp1, const BIGNUM *Xp2,
538 const BIGNUM *e, BN_CTX *ctx, BN_GENCB *cb);
539int BN_X931_generate_prime_ex(BIGNUM *p, BIGNUM *p1, BIGNUM *p2,
540 BIGNUM *Xp1, BIGNUM *Xp2,
541 const BIGNUM *Xp,
542 const BIGNUM *e, BN_CTX *ctx,
543 BN_GENCB *cb);
544
545BN_MONT_CTX *BN_MONT_CTX_new(void ); 543BN_MONT_CTX *BN_MONT_CTX_new(void );
546void BN_MONT_CTX_init(BN_MONT_CTX *ctx); 544void BN_MONT_CTX_init(BN_MONT_CTX *ctx);
547int BN_mod_mul_montgomery(BIGNUM *r,const BIGNUM *a,const BIGNUM *b, 545int BN_mod_mul_montgomery(BIGNUM *r,const BIGNUM *a,const BIGNUM *b,
@@ -560,19 +558,22 @@ BN_MONT_CTX *BN_MONT_CTX_set_locked(BN_MONT_CTX **pmont, int lock,
560#define BN_BLINDING_NO_UPDATE 0x00000001 558#define BN_BLINDING_NO_UPDATE 0x00000001
561#define BN_BLINDING_NO_RECREATE 0x00000002 559#define BN_BLINDING_NO_RECREATE 0x00000002
562 560
563BN_BLINDING *BN_BLINDING_new(const BIGNUM *A, const BIGNUM *Ai, /* const */ BIGNUM *mod); 561BN_BLINDING *BN_BLINDING_new(const BIGNUM *A, const BIGNUM *Ai, BIGNUM *mod);
564void BN_BLINDING_free(BN_BLINDING *b); 562void BN_BLINDING_free(BN_BLINDING *b);
565int BN_BLINDING_update(BN_BLINDING *b,BN_CTX *ctx); 563int BN_BLINDING_update(BN_BLINDING *b,BN_CTX *ctx);
566int BN_BLINDING_convert(BIGNUM *n, BN_BLINDING *b, BN_CTX *ctx); 564int BN_BLINDING_convert(BIGNUM *n, BN_BLINDING *b, BN_CTX *ctx);
567int BN_BLINDING_invert(BIGNUM *n, BN_BLINDING *b, BN_CTX *ctx); 565int BN_BLINDING_invert(BIGNUM *n, BN_BLINDING *b, BN_CTX *ctx);
568int BN_BLINDING_convert_ex(BIGNUM *n, BIGNUM *r, BN_BLINDING *b, BN_CTX *); 566int BN_BLINDING_convert_ex(BIGNUM *n, BIGNUM *r, BN_BLINDING *b, BN_CTX *);
569int BN_BLINDING_invert_ex(BIGNUM *n, const BIGNUM *r, BN_BLINDING *b, BN_CTX *); 567int BN_BLINDING_invert_ex(BIGNUM *n, const BIGNUM *r, BN_BLINDING *b, BN_CTX *);
568#ifndef OPENSSL_NO_DEPRECATED
570unsigned long BN_BLINDING_get_thread_id(const BN_BLINDING *); 569unsigned long BN_BLINDING_get_thread_id(const BN_BLINDING *);
571void BN_BLINDING_set_thread_id(BN_BLINDING *, unsigned long); 570void BN_BLINDING_set_thread_id(BN_BLINDING *, unsigned long);
571#endif
572CRYPTO_THREADID *BN_BLINDING_thread_id(BN_BLINDING *);
572unsigned long BN_BLINDING_get_flags(const BN_BLINDING *); 573unsigned long BN_BLINDING_get_flags(const BN_BLINDING *);
573void BN_BLINDING_set_flags(BN_BLINDING *, unsigned long); 574void BN_BLINDING_set_flags(BN_BLINDING *, unsigned long);
574BN_BLINDING *BN_BLINDING_create_param(BN_BLINDING *b, 575BN_BLINDING *BN_BLINDING_create_param(BN_BLINDING *b,
575 const BIGNUM *e, /* const */ BIGNUM *m, BN_CTX *ctx, 576 const BIGNUM *e, BIGNUM *m, BN_CTX *ctx,
576 int (*bn_mod_exp)(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, 577 int (*bn_mod_exp)(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
577 const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx), 578 const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx),
578 BN_MONT_CTX *m_ctx); 579 BN_MONT_CTX *m_ctx);
@@ -625,24 +626,24 @@ int BN_GF2m_mod_solve_quad(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
625 * t^p[0] + t^p[1] + ... + t^p[k] 626 * t^p[0] + t^p[1] + ... + t^p[k]
626 * where m = p[0] > p[1] > ... > p[k] = 0. 627 * where m = p[0] > p[1] > ... > p[k] = 0.
627 */ 628 */
628int BN_GF2m_mod_arr(BIGNUM *r, const BIGNUM *a, const unsigned int p[]); 629int BN_GF2m_mod_arr(BIGNUM *r, const BIGNUM *a, const int p[]);
629 /* r = a mod p */ 630 /* r = a mod p */
630int BN_GF2m_mod_mul_arr(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, 631int BN_GF2m_mod_mul_arr(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
631 const unsigned int p[], BN_CTX *ctx); /* r = (a * b) mod p */ 632 const int p[], BN_CTX *ctx); /* r = (a * b) mod p */
632int BN_GF2m_mod_sqr_arr(BIGNUM *r, const BIGNUM *a, const unsigned int p[], 633int BN_GF2m_mod_sqr_arr(BIGNUM *r, const BIGNUM *a, const int p[],
633 BN_CTX *ctx); /* r = (a * a) mod p */ 634 BN_CTX *ctx); /* r = (a * a) mod p */
634int BN_GF2m_mod_inv_arr(BIGNUM *r, const BIGNUM *b, const unsigned int p[], 635int BN_GF2m_mod_inv_arr(BIGNUM *r, const BIGNUM *b, const int p[],
635 BN_CTX *ctx); /* r = (1 / b) mod p */ 636 BN_CTX *ctx); /* r = (1 / b) mod p */
636int BN_GF2m_mod_div_arr(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, 637int BN_GF2m_mod_div_arr(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
637 const unsigned int p[], BN_CTX *ctx); /* r = (a / b) mod p */ 638 const int p[], BN_CTX *ctx); /* r = (a / b) mod p */
638int BN_GF2m_mod_exp_arr(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, 639int BN_GF2m_mod_exp_arr(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
639 const unsigned int p[], BN_CTX *ctx); /* r = (a ^ b) mod p */ 640 const int p[], BN_CTX *ctx); /* r = (a ^ b) mod p */
640int BN_GF2m_mod_sqrt_arr(BIGNUM *r, const BIGNUM *a, 641int BN_GF2m_mod_sqrt_arr(BIGNUM *r, const BIGNUM *a,
641 const unsigned int p[], BN_CTX *ctx); /* r = sqrt(a) mod p */ 642 const int p[], BN_CTX *ctx); /* r = sqrt(a) mod p */
642int BN_GF2m_mod_solve_quad_arr(BIGNUM *r, const BIGNUM *a, 643int BN_GF2m_mod_solve_quad_arr(BIGNUM *r, const BIGNUM *a,
643 const unsigned int p[], BN_CTX *ctx); /* r^2 + r = a mod p */ 644 const int p[], BN_CTX *ctx); /* r^2 + r = a mod p */
644int BN_GF2m_poly2arr(const BIGNUM *a, unsigned int p[], int max); 645int BN_GF2m_poly2arr(const BIGNUM *a, int p[], int max);
645int BN_GF2m_arr2poly(const unsigned int p[], BIGNUM *a); 646int BN_GF2m_arr2poly(const int p[], BIGNUM *a);
646 647
647/* faster mod functions for the 'NIST primes' 648/* faster mod functions for the 'NIST primes'
648 * 0 <= a < p^2 */ 649 * 0 <= a < p^2 */
@@ -751,10 +752,12 @@ int RAND_pseudo_bytes(unsigned char *buf,int num);
751#define bn_correct_top(a) \ 752#define bn_correct_top(a) \
752 { \ 753 { \
753 BN_ULONG *ftl; \ 754 BN_ULONG *ftl; \
754 if ((a)->top > 0) \ 755 int tmp_top = (a)->top; \
756 if (tmp_top > 0) \
755 { \ 757 { \
756 for (ftl= &((a)->d[(a)->top-1]); (a)->top > 0; (a)->top--) \ 758 for (ftl= &((a)->d[tmp_top-1]); tmp_top > 0; tmp_top--) \
757 if (*(ftl--)) break; \ 759 if (*(ftl--)) break; \
760 (a)->top = tmp_top; \
758 } \ 761 } \
759 bn_pollute(a); \ 762 bn_pollute(a); \
760 } 763 }
diff --git a/src/lib/libcrypto/bn/bn_asm.c b/src/lib/libcrypto/bn/bn_asm.c
index 99bc2de491..c43c91cc09 100644
--- a/src/lib/libcrypto/bn/bn_asm.c
+++ b/src/lib/libcrypto/bn/bn_asm.c
@@ -75,6 +75,7 @@ BN_ULONG bn_mul_add_words(BN_ULONG *rp, const BN_ULONG *ap, int num, BN_ULONG w)
75 assert(num >= 0); 75 assert(num >= 0);
76 if (num <= 0) return(c1); 76 if (num <= 0) return(c1);
77 77
78#ifndef OPENSSL_SMALL_FOOTPRINT
78 while (num&~3) 79 while (num&~3)
79 { 80 {
80 mul_add(rp[0],ap[0],w,c1); 81 mul_add(rp[0],ap[0],w,c1);
@@ -83,11 +84,11 @@ BN_ULONG bn_mul_add_words(BN_ULONG *rp, const BN_ULONG *ap, int num, BN_ULONG w)
83 mul_add(rp[3],ap[3],w,c1); 84 mul_add(rp[3],ap[3],w,c1);
84 ap+=4; rp+=4; num-=4; 85 ap+=4; rp+=4; num-=4;
85 } 86 }
86 if (num) 87#endif
88 while (num)
87 { 89 {
88 mul_add(rp[0],ap[0],w,c1); if (--num==0) return c1; 90 mul_add(rp[0],ap[0],w,c1);
89 mul_add(rp[1],ap[1],w,c1); if (--num==0) return c1; 91 ap++; rp++; num--;
90 mul_add(rp[2],ap[2],w,c1); return c1;
91 } 92 }
92 93
93 return(c1); 94 return(c1);
@@ -100,6 +101,7 @@ BN_ULONG bn_mul_words(BN_ULONG *rp, const BN_ULONG *ap, int num, BN_ULONG w)
100 assert(num >= 0); 101 assert(num >= 0);
101 if (num <= 0) return(c1); 102 if (num <= 0) return(c1);
102 103
104#ifndef OPENSSL_SMALL_FOOTPRINT
103 while (num&~3) 105 while (num&~3)
104 { 106 {
105 mul(rp[0],ap[0],w,c1); 107 mul(rp[0],ap[0],w,c1);
@@ -108,11 +110,11 @@ BN_ULONG bn_mul_words(BN_ULONG *rp, const BN_ULONG *ap, int num, BN_ULONG w)
108 mul(rp[3],ap[3],w,c1); 110 mul(rp[3],ap[3],w,c1);
109 ap+=4; rp+=4; num-=4; 111 ap+=4; rp+=4; num-=4;
110 } 112 }
111 if (num) 113#endif
114 while (num)
112 { 115 {
113 mul(rp[0],ap[0],w,c1); if (--num == 0) return c1; 116 mul(rp[0],ap[0],w,c1);
114 mul(rp[1],ap[1],w,c1); if (--num == 0) return c1; 117 ap++; rp++; num--;
115 mul(rp[2],ap[2],w,c1);
116 } 118 }
117 return(c1); 119 return(c1);
118 } 120 }
@@ -121,6 +123,8 @@ void bn_sqr_words(BN_ULONG *r, const BN_ULONG *a, int n)
121 { 123 {
122 assert(n >= 0); 124 assert(n >= 0);
123 if (n <= 0) return; 125 if (n <= 0) return;
126
127#ifndef OPENSSL_SMALL_FOOTPRINT
124 while (n&~3) 128 while (n&~3)
125 { 129 {
126 sqr(r[0],r[1],a[0]); 130 sqr(r[0],r[1],a[0]);
@@ -129,11 +133,11 @@ void bn_sqr_words(BN_ULONG *r, const BN_ULONG *a, int n)
129 sqr(r[6],r[7],a[3]); 133 sqr(r[6],r[7],a[3]);
130 a+=4; r+=8; n-=4; 134 a+=4; r+=8; n-=4;
131 } 135 }
132 if (n) 136#endif
137 while (n)
133 { 138 {
134 sqr(r[0],r[1],a[0]); if (--n == 0) return; 139 sqr(r[0],r[1],a[0]);
135 sqr(r[2],r[3],a[1]); if (--n == 0) return; 140 a++; r+=2; n--;
136 sqr(r[4],r[5],a[2]);
137 } 141 }
138 } 142 }
139 143
@@ -150,18 +154,20 @@ BN_ULONG bn_mul_add_words(BN_ULONG *rp, const BN_ULONG *ap, int num, BN_ULONG w)
150 bl=LBITS(w); 154 bl=LBITS(w);
151 bh=HBITS(w); 155 bh=HBITS(w);
152 156
153 for (;;) 157#ifndef OPENSSL_SMALL_FOOTPRINT
158 while (num&~3)
154 { 159 {
155 mul_add(rp[0],ap[0],bl,bh,c); 160 mul_add(rp[0],ap[0],bl,bh,c);
156 if (--num == 0) break;
157 mul_add(rp[1],ap[1],bl,bh,c); 161 mul_add(rp[1],ap[1],bl,bh,c);
158 if (--num == 0) break;
159 mul_add(rp[2],ap[2],bl,bh,c); 162 mul_add(rp[2],ap[2],bl,bh,c);
160 if (--num == 0) break;
161 mul_add(rp[3],ap[3],bl,bh,c); 163 mul_add(rp[3],ap[3],bl,bh,c);
162 if (--num == 0) break; 164 ap+=4; rp+=4; num-=4;
163 ap+=4; 165 }
164 rp+=4; 166#endif
167 while (num)
168 {
169 mul_add(rp[0],ap[0],bl,bh,c);
170 ap++; rp++; num--;
165 } 171 }
166 return(c); 172 return(c);
167 } 173 }
@@ -177,18 +183,20 @@ BN_ULONG bn_mul_words(BN_ULONG *rp, const BN_ULONG *ap, int num, BN_ULONG w)
177 bl=LBITS(w); 183 bl=LBITS(w);
178 bh=HBITS(w); 184 bh=HBITS(w);
179 185
180 for (;;) 186#ifndef OPENSSL_SMALL_FOOTPRINT
187 while (num&~3)
181 { 188 {
182 mul(rp[0],ap[0],bl,bh,carry); 189 mul(rp[0],ap[0],bl,bh,carry);
183 if (--num == 0) break;
184 mul(rp[1],ap[1],bl,bh,carry); 190 mul(rp[1],ap[1],bl,bh,carry);
185 if (--num == 0) break;
186 mul(rp[2],ap[2],bl,bh,carry); 191 mul(rp[2],ap[2],bl,bh,carry);
187 if (--num == 0) break;
188 mul(rp[3],ap[3],bl,bh,carry); 192 mul(rp[3],ap[3],bl,bh,carry);
189 if (--num == 0) break; 193 ap+=4; rp+=4; num-=4;
190 ap+=4; 194 }
191 rp+=4; 195#endif
196 while (num)
197 {
198 mul(rp[0],ap[0],bl,bh,carry);
199 ap++; rp++; num--;
192 } 200 }
193 return(carry); 201 return(carry);
194 } 202 }
@@ -197,22 +205,21 @@ void bn_sqr_words(BN_ULONG *r, const BN_ULONG *a, int n)
197 { 205 {
198 assert(n >= 0); 206 assert(n >= 0);
199 if (n <= 0) return; 207 if (n <= 0) return;
200 for (;;) 208
209#ifndef OPENSSL_SMALL_FOOTPRINT
210 while (n&~3)
201 { 211 {
202 sqr64(r[0],r[1],a[0]); 212 sqr64(r[0],r[1],a[0]);
203 if (--n == 0) break;
204
205 sqr64(r[2],r[3],a[1]); 213 sqr64(r[2],r[3],a[1]);
206 if (--n == 0) break;
207
208 sqr64(r[4],r[5],a[2]); 214 sqr64(r[4],r[5],a[2]);
209 if (--n == 0) break;
210
211 sqr64(r[6],r[7],a[3]); 215 sqr64(r[6],r[7],a[3]);
212 if (--n == 0) break; 216 a+=4; r+=8; n-=4;
213 217 }
214 a+=4; 218#endif
215 r+=8; 219 while (n)
220 {
221 sqr64(r[0],r[1],a[0]);
222 a++; r+=2; n--;
216 } 223 }
217 } 224 }
218 225
@@ -303,31 +310,30 @@ BN_ULONG bn_add_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b, int n)
303 assert(n >= 0); 310 assert(n >= 0);
304 if (n <= 0) return((BN_ULONG)0); 311 if (n <= 0) return((BN_ULONG)0);
305 312
306 for (;;) 313#ifndef OPENSSL_SMALL_FOOTPRINT
314 while (n&~3)
307 { 315 {
308 ll+=(BN_ULLONG)a[0]+b[0]; 316 ll+=(BN_ULLONG)a[0]+b[0];
309 r[0]=(BN_ULONG)ll&BN_MASK2; 317 r[0]=(BN_ULONG)ll&BN_MASK2;
310 ll>>=BN_BITS2; 318 ll>>=BN_BITS2;
311 if (--n <= 0) break;
312
313 ll+=(BN_ULLONG)a[1]+b[1]; 319 ll+=(BN_ULLONG)a[1]+b[1];
314 r[1]=(BN_ULONG)ll&BN_MASK2; 320 r[1]=(BN_ULONG)ll&BN_MASK2;
315 ll>>=BN_BITS2; 321 ll>>=BN_BITS2;
316 if (--n <= 0) break;
317
318 ll+=(BN_ULLONG)a[2]+b[2]; 322 ll+=(BN_ULLONG)a[2]+b[2];
319 r[2]=(BN_ULONG)ll&BN_MASK2; 323 r[2]=(BN_ULONG)ll&BN_MASK2;
320 ll>>=BN_BITS2; 324 ll>>=BN_BITS2;
321 if (--n <= 0) break;
322
323 ll+=(BN_ULLONG)a[3]+b[3]; 325 ll+=(BN_ULLONG)a[3]+b[3];
324 r[3]=(BN_ULONG)ll&BN_MASK2; 326 r[3]=(BN_ULONG)ll&BN_MASK2;
325 ll>>=BN_BITS2; 327 ll>>=BN_BITS2;
326 if (--n <= 0) break; 328 a+=4; b+=4; r+=4; n-=4;
327 329 }
328 a+=4; 330#endif
329 b+=4; 331 while (n)
330 r+=4; 332 {
333 ll+=(BN_ULLONG)a[0]+b[0];
334 r[0]=(BN_ULONG)ll&BN_MASK2;
335 ll>>=BN_BITS2;
336 a++; b++; r++; n--;
331 } 337 }
332 return((BN_ULONG)ll); 338 return((BN_ULONG)ll);
333 } 339 }
@@ -340,7 +346,8 @@ BN_ULONG bn_add_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b, int n)
340 if (n <= 0) return((BN_ULONG)0); 346 if (n <= 0) return((BN_ULONG)0);
341 347
342 c=0; 348 c=0;
343 for (;;) 349#ifndef OPENSSL_SMALL_FOOTPRINT
350 while (n&~3)
344 { 351 {
345 t=a[0]; 352 t=a[0];
346 t=(t+c)&BN_MASK2; 353 t=(t+c)&BN_MASK2;
@@ -348,35 +355,36 @@ BN_ULONG bn_add_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b, int n)
348 l=(t+b[0])&BN_MASK2; 355 l=(t+b[0])&BN_MASK2;
349 c+=(l < t); 356 c+=(l < t);
350 r[0]=l; 357 r[0]=l;
351 if (--n <= 0) break;
352
353 t=a[1]; 358 t=a[1];
354 t=(t+c)&BN_MASK2; 359 t=(t+c)&BN_MASK2;
355 c=(t < c); 360 c=(t < c);
356 l=(t+b[1])&BN_MASK2; 361 l=(t+b[1])&BN_MASK2;
357 c+=(l < t); 362 c+=(l < t);
358 r[1]=l; 363 r[1]=l;
359 if (--n <= 0) break;
360
361 t=a[2]; 364 t=a[2];
362 t=(t+c)&BN_MASK2; 365 t=(t+c)&BN_MASK2;
363 c=(t < c); 366 c=(t < c);
364 l=(t+b[2])&BN_MASK2; 367 l=(t+b[2])&BN_MASK2;
365 c+=(l < t); 368 c+=(l < t);
366 r[2]=l; 369 r[2]=l;
367 if (--n <= 0) break;
368
369 t=a[3]; 370 t=a[3];
370 t=(t+c)&BN_MASK2; 371 t=(t+c)&BN_MASK2;
371 c=(t < c); 372 c=(t < c);
372 l=(t+b[3])&BN_MASK2; 373 l=(t+b[3])&BN_MASK2;
373 c+=(l < t); 374 c+=(l < t);
374 r[3]=l; 375 r[3]=l;
375 if (--n <= 0) break; 376 a+=4; b+=4; r+=4; n-=4;
376 377 }
377 a+=4; 378#endif
378 b+=4; 379 while(n)
379 r+=4; 380 {
381 t=a[0];
382 t=(t+c)&BN_MASK2;
383 c=(t < c);
384 l=(t+b[0])&BN_MASK2;
385 c+=(l < t);
386 r[0]=l;
387 a++; b++; r++; n--;
380 } 388 }
381 return((BN_ULONG)c); 389 return((BN_ULONG)c);
382 } 390 }
@@ -390,36 +398,35 @@ BN_ULONG bn_sub_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b, int n)
390 assert(n >= 0); 398 assert(n >= 0);
391 if (n <= 0) return((BN_ULONG)0); 399 if (n <= 0) return((BN_ULONG)0);
392 400
393 for (;;) 401#ifndef OPENSSL_SMALL_FOOTPRINT
402 while (n&~3)
394 { 403 {
395 t1=a[0]; t2=b[0]; 404 t1=a[0]; t2=b[0];
396 r[0]=(t1-t2-c)&BN_MASK2; 405 r[0]=(t1-t2-c)&BN_MASK2;
397 if (t1 != t2) c=(t1 < t2); 406 if (t1 != t2) c=(t1 < t2);
398 if (--n <= 0) break;
399
400 t1=a[1]; t2=b[1]; 407 t1=a[1]; t2=b[1];
401 r[1]=(t1-t2-c)&BN_MASK2; 408 r[1]=(t1-t2-c)&BN_MASK2;
402 if (t1 != t2) c=(t1 < t2); 409 if (t1 != t2) c=(t1 < t2);
403 if (--n <= 0) break;
404
405 t1=a[2]; t2=b[2]; 410 t1=a[2]; t2=b[2];
406 r[2]=(t1-t2-c)&BN_MASK2; 411 r[2]=(t1-t2-c)&BN_MASK2;
407 if (t1 != t2) c=(t1 < t2); 412 if (t1 != t2) c=(t1 < t2);
408 if (--n <= 0) break;
409
410 t1=a[3]; t2=b[3]; 413 t1=a[3]; t2=b[3];
411 r[3]=(t1-t2-c)&BN_MASK2; 414 r[3]=(t1-t2-c)&BN_MASK2;
412 if (t1 != t2) c=(t1 < t2); 415 if (t1 != t2) c=(t1 < t2);
413 if (--n <= 0) break; 416 a+=4; b+=4; r+=4; n-=4;
414 417 }
415 a+=4; 418#endif
416 b+=4; 419 while (n)
417 r+=4; 420 {
421 t1=a[0]; t2=b[0];
422 r[0]=(t1-t2-c)&BN_MASK2;
423 if (t1 != t2) c=(t1 < t2);
424 a++; b++; r++; n--;
418 } 425 }
419 return(c); 426 return(c);
420 } 427 }
421 428
422#ifdef BN_MUL_COMBA 429#if defined(BN_MUL_COMBA) && !defined(OPENSSL_SMALL_FOOTPRINT)
423 430
424#undef bn_mul_comba8 431#undef bn_mul_comba8
425#undef bn_mul_comba4 432#undef bn_mul_comba4
@@ -820,18 +827,134 @@ void bn_sqr_comba4(BN_ULONG *r, const BN_ULONG *a)
820 r[6]=c1; 827 r[6]=c1;
821 r[7]=c2; 828 r[7]=c2;
822 } 829 }
830
831#ifdef OPENSSL_NO_ASM
832#ifdef OPENSSL_BN_ASM_MONT
833#include <alloca.h>
834/*
835 * This is essentially reference implementation, which may or may not
836 * result in performance improvement. E.g. on IA-32 this routine was
837 * observed to give 40% faster rsa1024 private key operations and 10%
838 * faster rsa4096 ones, while on AMD64 it improves rsa1024 sign only
839 * by 10% and *worsens* rsa4096 sign by 15%. Once again, it's a
840 * reference implementation, one to be used as starting point for
841 * platform-specific assembler. Mentioned numbers apply to compiler
842 * generated code compiled with and without -DOPENSSL_BN_ASM_MONT and
843 * can vary not only from platform to platform, but even for compiler
844 * versions. Assembler vs. assembler improvement coefficients can
845 * [and are known to] differ and are to be documented elsewhere.
846 */
847int bn_mul_mont(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, const BN_ULONG *np,const BN_ULONG *n0p, int num)
848 {
849 BN_ULONG c0,c1,ml,*tp,n0;
850#ifdef mul64
851 BN_ULONG mh;
852#endif
853 volatile BN_ULONG *vp;
854 int i=0,j;
855
856#if 0 /* template for platform-specific implementation */
857 if (ap==bp) return bn_sqr_mont(rp,ap,np,n0p,num);
858#endif
859 vp = tp = alloca((num+2)*sizeof(BN_ULONG));
860
861 n0 = *n0p;
862
863 c0 = 0;
864 ml = bp[0];
865#ifdef mul64
866 mh = HBITS(ml);
867 ml = LBITS(ml);
868 for (j=0;j<num;++j)
869 mul(tp[j],ap[j],ml,mh,c0);
870#else
871 for (j=0;j<num;++j)
872 mul(tp[j],ap[j],ml,c0);
873#endif
874
875 tp[num] = c0;
876 tp[num+1] = 0;
877 goto enter;
878
879 for(i=0;i<num;i++)
880 {
881 c0 = 0;
882 ml = bp[i];
883#ifdef mul64
884 mh = HBITS(ml);
885 ml = LBITS(ml);
886 for (j=0;j<num;++j)
887 mul_add(tp[j],ap[j],ml,mh,c0);
888#else
889 for (j=0;j<num;++j)
890 mul_add(tp[j],ap[j],ml,c0);
891#endif
892 c1 = (tp[num] + c0)&BN_MASK2;
893 tp[num] = c1;
894 tp[num+1] = (c1<c0?1:0);
895 enter:
896 c1 = tp[0];
897 ml = (c1*n0)&BN_MASK2;
898 c0 = 0;
899#ifdef mul64
900 mh = HBITS(ml);
901 ml = LBITS(ml);
902 mul_add(c1,np[0],ml,mh,c0);
903#else
904 mul_add(c1,ml,np[0],c0);
905#endif
906 for(j=1;j<num;j++)
907 {
908 c1 = tp[j];
909#ifdef mul64
910 mul_add(c1,np[j],ml,mh,c0);
911#else
912 mul_add(c1,ml,np[j],c0);
913#endif
914 tp[j-1] = c1&BN_MASK2;
915 }
916 c1 = (tp[num] + c0)&BN_MASK2;
917 tp[num-1] = c1;
918 tp[num] = tp[num+1] + (c1<c0?1:0);
919 }
920
921 if (tp[num]!=0 || tp[num-1]>=np[num-1])
922 {
923 c0 = bn_sub_words(rp,tp,np,num);
924 if (tp[num]!=0 || c0==0)
925 {
926 for(i=0;i<num+2;i++) vp[i] = 0;
927 return 1;
928 }
929 }
930 for(i=0;i<num;i++) rp[i] = tp[i], vp[i] = 0;
931 vp[num] = 0;
932 vp[num+1] = 0;
933 return 1;
934 }
935#else
936/*
937 * Return value of 0 indicates that multiplication/convolution was not
938 * performed to signal the caller to fall down to alternative/original
939 * code-path.
940 */
941int bn_mul_mont(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, const BN_ULONG *np,const BN_ULONG *n0, int num)
942{ return 0; }
943#endif /* OPENSSL_BN_ASM_MONT */
944#endif
945
823#else /* !BN_MUL_COMBA */ 946#else /* !BN_MUL_COMBA */
824 947
825/* hmm... is it faster just to do a multiply? */ 948/* hmm... is it faster just to do a multiply? */
826#undef bn_sqr_comba4 949#undef bn_sqr_comba4
827void bn_sqr_comba4(BN_ULONG *r, BN_ULONG *a) 950void bn_sqr_comba4(BN_ULONG *r, const BN_ULONG *a)
828 { 951 {
829 BN_ULONG t[8]; 952 BN_ULONG t[8];
830 bn_sqr_normal(r,a,4,t); 953 bn_sqr_normal(r,a,4,t);
831 } 954 }
832 955
833#undef bn_sqr_comba8 956#undef bn_sqr_comba8
834void bn_sqr_comba8(BN_ULONG *r, BN_ULONG *a) 957void bn_sqr_comba8(BN_ULONG *r, const BN_ULONG *a)
835 { 958 {
836 BN_ULONG t[16]; 959 BN_ULONG t[16];
837 bn_sqr_normal(r,a,8,t); 960 bn_sqr_normal(r,a,8,t);
@@ -857,4 +980,51 @@ void bn_mul_comba8(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b)
857 r[15]=bn_mul_add_words(&(r[7]),a,8,b[7]); 980 r[15]=bn_mul_add_words(&(r[7]),a,8,b[7]);
858 } 981 }
859 982
983#ifdef OPENSSL_NO_ASM
984#ifdef OPENSSL_BN_ASM_MONT
985#include <alloca.h>
986int bn_mul_mont(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, const BN_ULONG *np,const BN_ULONG *n0p, int num)
987 {
988 BN_ULONG c0,c1,*tp,n0=*n0p;
989 volatile BN_ULONG *vp;
990 int i=0,j;
991
992 vp = tp = alloca((num+2)*sizeof(BN_ULONG));
993
994 for(i=0;i<=num;i++) tp[i]=0;
995
996 for(i=0;i<num;i++)
997 {
998 c0 = bn_mul_add_words(tp,ap,num,bp[i]);
999 c1 = (tp[num] + c0)&BN_MASK2;
1000 tp[num] = c1;
1001 tp[num+1] = (c1<c0?1:0);
1002
1003 c0 = bn_mul_add_words(tp,np,num,tp[0]*n0);
1004 c1 = (tp[num] + c0)&BN_MASK2;
1005 tp[num] = c1;
1006 tp[num+1] += (c1<c0?1:0);
1007 for(j=0;j<=num;j++) tp[j]=tp[j+1];
1008 }
1009
1010 if (tp[num]!=0 || tp[num-1]>=np[num-1])
1011 {
1012 c0 = bn_sub_words(rp,tp,np,num);
1013 if (tp[num]!=0 || c0==0)
1014 {
1015 for(i=0;i<num+2;i++) vp[i] = 0;
1016 return 1;
1017 }
1018 }
1019 for(i=0;i<num;i++) rp[i] = tp[i], vp[i] = 0;
1020 vp[num] = 0;
1021 vp[num+1] = 0;
1022 return 1;
1023 }
1024#else
1025int bn_mul_mont(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, const BN_ULONG *np,const BN_ULONG *n0, int num)
1026{ return 0; }
1027#endif /* OPENSSL_BN_ASM_MONT */
1028#endif
1029
860#endif /* !BN_MUL_COMBA */ 1030#endif /* !BN_MUL_COMBA */
diff --git a/src/lib/libcrypto/bn/bn_blind.c b/src/lib/libcrypto/bn/bn_blind.c
index c11fb4ccc2..e060592fdc 100644
--- a/src/lib/libcrypto/bn/bn_blind.c
+++ b/src/lib/libcrypto/bn/bn_blind.c
@@ -1,6 +1,6 @@
1/* crypto/bn/bn_blind.c */ 1/* crypto/bn/bn_blind.c */
2/* ==================================================================== 2/* ====================================================================
3 * Copyright (c) 1998-2005 The OpenSSL Project. All rights reserved. 3 * Copyright (c) 1998-2006 The OpenSSL Project. All rights reserved.
4 * 4 *
5 * Redistribution and use in source and binary forms, with or without 5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions 6 * modification, are permitted provided that the following conditions
@@ -121,8 +121,11 @@ struct bn_blinding_st
121 BIGNUM *Ai; 121 BIGNUM *Ai;
122 BIGNUM *e; 122 BIGNUM *e;
123 BIGNUM *mod; /* just a reference */ 123 BIGNUM *mod; /* just a reference */
124#ifndef OPENSSL_NO_DEPRECATED
124 unsigned long thread_id; /* added in OpenSSL 0.9.6j and 0.9.7b; 125 unsigned long thread_id; /* added in OpenSSL 0.9.6j and 0.9.7b;
125 * used only by crypto/rsa/rsa_eay.c, rsa_lib.c */ 126 * used only by crypto/rsa/rsa_eay.c, rsa_lib.c */
127#endif
128 CRYPTO_THREADID tid;
126 unsigned int counter; 129 unsigned int counter;
127 unsigned long flags; 130 unsigned long flags;
128 BN_MONT_CTX *m_ctx; 131 BN_MONT_CTX *m_ctx;
@@ -131,7 +134,7 @@ struct bn_blinding_st
131 BN_MONT_CTX *m_ctx); 134 BN_MONT_CTX *m_ctx);
132 }; 135 };
133 136
134BN_BLINDING *BN_BLINDING_new(const BIGNUM *A, const BIGNUM *Ai, /* const */ BIGNUM *mod) 137BN_BLINDING *BN_BLINDING_new(const BIGNUM *A, const BIGNUM *Ai, BIGNUM *mod)
135 { 138 {
136 BN_BLINDING *ret=NULL; 139 BN_BLINDING *ret=NULL;
137 140
@@ -158,6 +161,7 @@ BN_BLINDING *BN_BLINDING_new(const BIGNUM *A, const BIGNUM *Ai, /* const */ BIGN
158 BN_set_flags(ret->mod, BN_FLG_CONSTTIME); 161 BN_set_flags(ret->mod, BN_FLG_CONSTTIME);
159 162
160 ret->counter = BN_BLINDING_COUNTER; 163 ret->counter = BN_BLINDING_COUNTER;
164 CRYPTO_THREADID_current(&ret->tid);
161 return(ret); 165 return(ret);
162err: 166err:
163 if (ret != NULL) BN_BLINDING_free(ret); 167 if (ret != NULL) BN_BLINDING_free(ret);
@@ -263,6 +267,7 @@ int BN_BLINDING_invert_ex(BIGNUM *n, const BIGNUM *r, BN_BLINDING *b, BN_CTX *ct
263 return(ret); 267 return(ret);
264 } 268 }
265 269
270#ifndef OPENSSL_NO_DEPRECATED
266unsigned long BN_BLINDING_get_thread_id(const BN_BLINDING *b) 271unsigned long BN_BLINDING_get_thread_id(const BN_BLINDING *b)
267 { 272 {
268 return b->thread_id; 273 return b->thread_id;
@@ -272,6 +277,12 @@ void BN_BLINDING_set_thread_id(BN_BLINDING *b, unsigned long n)
272 { 277 {
273 b->thread_id = n; 278 b->thread_id = n;
274 } 279 }
280#endif
281
282CRYPTO_THREADID *BN_BLINDING_thread_id(BN_BLINDING *b)
283 {
284 return &b->tid;
285 }
275 286
276unsigned long BN_BLINDING_get_flags(const BN_BLINDING *b) 287unsigned long BN_BLINDING_get_flags(const BN_BLINDING *b)
277 { 288 {
@@ -284,7 +295,7 @@ void BN_BLINDING_set_flags(BN_BLINDING *b, unsigned long flags)
284 } 295 }
285 296
286BN_BLINDING *BN_BLINDING_create_param(BN_BLINDING *b, 297BN_BLINDING *BN_BLINDING_create_param(BN_BLINDING *b,
287 const BIGNUM *e, /* const */ BIGNUM *m, BN_CTX *ctx, 298 const BIGNUM *e, BIGNUM *m, BN_CTX *ctx,
288 int (*bn_mod_exp)(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, 299 int (*bn_mod_exp)(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
289 const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx), 300 const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx),
290 BN_MONT_CTX *m_ctx) 301 BN_MONT_CTX *m_ctx)
diff --git a/src/lib/libcrypto/bn/bn_ctx.c b/src/lib/libcrypto/bn/bn_ctx.c
index b3452f1a91..3f2256f675 100644
--- a/src/lib/libcrypto/bn/bn_ctx.c
+++ b/src/lib/libcrypto/bn/bn_ctx.c
@@ -161,7 +161,7 @@ static void ctxdbg(BN_CTX *ctx)
161 fprintf(stderr,"(%08x): ", (unsigned int)ctx); 161 fprintf(stderr,"(%08x): ", (unsigned int)ctx);
162 while(bnidx < ctx->used) 162 while(bnidx < ctx->used)
163 { 163 {
164 fprintf(stderr,"%02x ", item->vals[bnidx++ % BN_CTX_POOL_SIZE].dmax); 164 fprintf(stderr,"%03x ", item->vals[bnidx++ % BN_CTX_POOL_SIZE].dmax);
165 if(!(bnidx % BN_CTX_POOL_SIZE)) 165 if(!(bnidx % BN_CTX_POOL_SIZE))
166 item = item->next; 166 item = item->next;
167 } 167 }
@@ -171,8 +171,8 @@ static void ctxdbg(BN_CTX *ctx)
171 while(fpidx < stack->depth) 171 while(fpidx < stack->depth)
172 { 172 {
173 while(bnidx++ < stack->indexes[fpidx]) 173 while(bnidx++ < stack->indexes[fpidx])
174 fprintf(stderr," "); 174 fprintf(stderr," ");
175 fprintf(stderr,"^^ "); 175 fprintf(stderr,"^^^ ");
176 bnidx++; 176 bnidx++;
177 fpidx++; 177 fpidx++;
178 } 178 }
diff --git a/src/lib/libcrypto/bn/bn_div.c b/src/lib/libcrypto/bn/bn_div.c
index 1e8e57626b..802a43d642 100644
--- a/src/lib/libcrypto/bn/bn_div.c
+++ b/src/lib/libcrypto/bn/bn_div.c
@@ -102,7 +102,7 @@ int BN_div(BIGNUM *dv, BIGNUM *rem, const BIGNUM *m, const BIGNUM *d,
102 /* The next 2 are needed so we can do a dv->d[0]|=1 later 102 /* The next 2 are needed so we can do a dv->d[0]|=1 later
103 * since BN_lshift1 will only work once there is a value :-) */ 103 * since BN_lshift1 will only work once there is a value :-) */
104 BN_zero(dv); 104 BN_zero(dv);
105 bn_wexpand(dv,1); 105 if(bn_wexpand(dv,1) == NULL) goto end;
106 dv->top=1; 106 dv->top=1;
107 107
108 if (!BN_lshift(D,D,nm-nd)) goto end; 108 if (!BN_lshift(D,D,nm-nd)) goto end;
@@ -229,7 +229,8 @@ int BN_div(BIGNUM *dv, BIGNUM *rm, const BIGNUM *num, const BIGNUM *divisor,
229 if (dv == NULL) 229 if (dv == NULL)
230 res=BN_CTX_get(ctx); 230 res=BN_CTX_get(ctx);
231 else res=dv; 231 else res=dv;
232 if (sdiv == NULL || res == NULL) goto err; 232 if (sdiv == NULL || res == NULL || tmp == NULL || snum == NULL)
233 goto err;
233 234
234 /* First we normalise the numbers */ 235 /* First we normalise the numbers */
235 norm_shift=BN_BITS2-((BN_num_bits(divisor))%BN_BITS2); 236 norm_shift=BN_BITS2-((BN_num_bits(divisor))%BN_BITS2);
@@ -336,7 +337,7 @@ X) -> 0x%08X\n",
336 t2 -= d1; 337 t2 -= d1;
337 } 338 }
338#else /* !BN_LLONG */ 339#else /* !BN_LLONG */
339 BN_ULONG t2l,t2h,ql,qh; 340 BN_ULONG t2l,t2h;
340 341
341 q=bn_div_words(n0,n1,d0); 342 q=bn_div_words(n0,n1,d0);
342#ifdef BN_DEBUG_LEVITTE 343#ifdef BN_DEBUG_LEVITTE
@@ -354,9 +355,12 @@ X) -> 0x%08X\n",
354 t2l = d1 * q; 355 t2l = d1 * q;
355 t2h = BN_UMULT_HIGH(d1,q); 356 t2h = BN_UMULT_HIGH(d1,q);
356#else 357#else
358 {
359 BN_ULONG ql, qh;
357 t2l=LBITS(d1); t2h=HBITS(d1); 360 t2l=LBITS(d1); t2h=HBITS(d1);
358 ql =LBITS(q); qh =HBITS(q); 361 ql =LBITS(q); qh =HBITS(q);
359 mul64(t2l,t2h,ql,qh); /* t2=(BN_ULLONG)d1*q; */ 362 mul64(t2l,t2h,ql,qh); /* t2=(BN_ULLONG)d1*q; */
363 }
360#endif 364#endif
361 365
362 for (;;) 366 for (;;)
@@ -560,7 +564,7 @@ X) -> 0x%08X\n",
560 t2 -= d1; 564 t2 -= d1;
561 } 565 }
562#else /* !BN_LLONG */ 566#else /* !BN_LLONG */
563 BN_ULONG t2l,t2h,ql,qh; 567 BN_ULONG t2l,t2h;
564 568
565 q=bn_div_words(n0,n1,d0); 569 q=bn_div_words(n0,n1,d0);
566#ifdef BN_DEBUG_LEVITTE 570#ifdef BN_DEBUG_LEVITTE
@@ -578,9 +582,12 @@ X) -> 0x%08X\n",
578 t2l = d1 * q; 582 t2l = d1 * q;
579 t2h = BN_UMULT_HIGH(d1,q); 583 t2h = BN_UMULT_HIGH(d1,q);
580#else 584#else
585 {
586 BN_ULONG ql, qh;
581 t2l=LBITS(d1); t2h=HBITS(d1); 587 t2l=LBITS(d1); t2h=HBITS(d1);
582 ql =LBITS(q); qh =HBITS(q); 588 ql =LBITS(q); qh =HBITS(q);
583 mul64(t2l,t2h,ql,qh); /* t2=(BN_ULLONG)d1*q; */ 589 mul64(t2l,t2h,ql,qh); /* t2=(BN_ULLONG)d1*q; */
590 }
584#endif 591#endif
585 592
586 for (;;) 593 for (;;)
diff --git a/src/lib/libcrypto/bn/bn_exp.c b/src/lib/libcrypto/bn/bn_exp.c
index 70a33f0d93..d9b6c737fc 100644
--- a/src/lib/libcrypto/bn/bn_exp.c
+++ b/src/lib/libcrypto/bn/bn_exp.c
@@ -134,7 +134,8 @@ int BN_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx)
134 rr = BN_CTX_get(ctx); 134 rr = BN_CTX_get(ctx);
135 else 135 else
136 rr = r; 136 rr = r;
137 if ((v = BN_CTX_get(ctx)) == NULL) goto err; 137 v = BN_CTX_get(ctx);
138 if (rr == NULL || v == NULL) goto err;
138 139
139 if (BN_copy(v,a) == NULL) goto err; 140 if (BN_copy(v,a) == NULL) goto err;
140 bits=BN_num_bits(p); 141 bits=BN_num_bits(p);
diff --git a/src/lib/libcrypto/bn/bn_gf2m.c b/src/lib/libcrypto/bn/bn_gf2m.c
index 306f029f27..527b0fa15b 100644
--- a/src/lib/libcrypto/bn/bn_gf2m.c
+++ b/src/lib/libcrypto/bn/bn_gf2m.c
@@ -121,74 +121,12 @@ static const BN_ULONG SQR_tb[16] =
121 SQR_tb[(w) >> 12 & 0xF] << 24 | SQR_tb[(w) >> 8 & 0xF] << 16 | \ 121 SQR_tb[(w) >> 12 & 0xF] << 24 | SQR_tb[(w) >> 8 & 0xF] << 16 | \
122 SQR_tb[(w) >> 4 & 0xF] << 8 | SQR_tb[(w) & 0xF] 122 SQR_tb[(w) >> 4 & 0xF] << 8 | SQR_tb[(w) & 0xF]
123#endif 123#endif
124#ifdef SIXTEEN_BIT
125#define SQR1(w) \
126 SQR_tb[(w) >> 12 & 0xF] << 8 | SQR_tb[(w) >> 8 & 0xF]
127#define SQR0(w) \
128 SQR_tb[(w) >> 4 & 0xF] << 8 | SQR_tb[(w) & 0xF]
129#endif
130#ifdef EIGHT_BIT
131#define SQR1(w) \
132 SQR_tb[(w) >> 4 & 0xF]
133#define SQR0(w) \
134 SQR_tb[(w) & 15]
135#endif
136 124
137/* Product of two polynomials a, b each with degree < BN_BITS2 - 1, 125/* Product of two polynomials a, b each with degree < BN_BITS2 - 1,
138 * result is a polynomial r with degree < 2 * BN_BITS - 1 126 * result is a polynomial r with degree < 2 * BN_BITS - 1
139 * The caller MUST ensure that the variables have the right amount 127 * The caller MUST ensure that the variables have the right amount
140 * of space allocated. 128 * of space allocated.
141 */ 129 */
142#ifdef EIGHT_BIT
143static void bn_GF2m_mul_1x1(BN_ULONG *r1, BN_ULONG *r0, const BN_ULONG a, const BN_ULONG b)
144 {
145 register BN_ULONG h, l, s;
146 BN_ULONG tab[4], top1b = a >> 7;
147 register BN_ULONG a1, a2;
148
149 a1 = a & (0x7F); a2 = a1 << 1;
150
151 tab[0] = 0; tab[1] = a1; tab[2] = a2; tab[3] = a1^a2;
152
153 s = tab[b & 0x3]; l = s;
154 s = tab[b >> 2 & 0x3]; l ^= s << 2; h = s >> 6;
155 s = tab[b >> 4 & 0x3]; l ^= s << 4; h ^= s >> 4;
156 s = tab[b >> 6 ]; l ^= s << 6; h ^= s >> 2;
157
158 /* compensate for the top bit of a */
159
160 if (top1b & 01) { l ^= b << 7; h ^= b >> 1; }
161
162 *r1 = h; *r0 = l;
163 }
164#endif
165#ifdef SIXTEEN_BIT
166static void bn_GF2m_mul_1x1(BN_ULONG *r1, BN_ULONG *r0, const BN_ULONG a, const BN_ULONG b)
167 {
168 register BN_ULONG h, l, s;
169 BN_ULONG tab[4], top1b = a >> 15;
170 register BN_ULONG a1, a2;
171
172 a1 = a & (0x7FFF); a2 = a1 << 1;
173
174 tab[0] = 0; tab[1] = a1; tab[2] = a2; tab[3] = a1^a2;
175
176 s = tab[b & 0x3]; l = s;
177 s = tab[b >> 2 & 0x3]; l ^= s << 2; h = s >> 14;
178 s = tab[b >> 4 & 0x3]; l ^= s << 4; h ^= s >> 12;
179 s = tab[b >> 6 & 0x3]; l ^= s << 6; h ^= s >> 10;
180 s = tab[b >> 8 & 0x3]; l ^= s << 8; h ^= s >> 8;
181 s = tab[b >>10 & 0x3]; l ^= s << 10; h ^= s >> 6;
182 s = tab[b >>12 & 0x3]; l ^= s << 12; h ^= s >> 4;
183 s = tab[b >>14 ]; l ^= s << 14; h ^= s >> 2;
184
185 /* compensate for the top bit of a */
186
187 if (top1b & 01) { l ^= b << 15; h ^= b >> 1; }
188
189 *r1 = h; *r0 = l;
190 }
191#endif
192#ifdef THIRTY_TWO_BIT 130#ifdef THIRTY_TWO_BIT
193static void bn_GF2m_mul_1x1(BN_ULONG *r1, BN_ULONG *r0, const BN_ULONG a, const BN_ULONG b) 131static void bn_GF2m_mul_1x1(BN_ULONG *r1, BN_ULONG *r0, const BN_ULONG a, const BN_ULONG b)
194 { 132 {
@@ -294,7 +232,8 @@ int BN_GF2m_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b)
294 if (a->top < b->top) { at = b; bt = a; } 232 if (a->top < b->top) { at = b; bt = a; }
295 else { at = a; bt = b; } 233 else { at = a; bt = b; }
296 234
297 bn_wexpand(r, at->top); 235 if(bn_wexpand(r, at->top) == NULL)
236 return 0;
298 237
299 for (i = 0; i < bt->top; i++) 238 for (i = 0; i < bt->top; i++)
300 { 239 {
@@ -320,7 +259,7 @@ int BN_GF2m_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b)
320 259
321 260
322/* Performs modular reduction of a and store result in r. r could be a. */ 261/* Performs modular reduction of a and store result in r. r could be a. */
323int BN_GF2m_mod_arr(BIGNUM *r, const BIGNUM *a, const unsigned int p[]) 262int BN_GF2m_mod_arr(BIGNUM *r, const BIGNUM *a, const int p[])
324 { 263 {
325 int j, k; 264 int j, k;
326 int n, dN, d0, d1; 265 int n, dN, d0, d1;
@@ -421,11 +360,11 @@ int BN_GF2m_mod_arr(BIGNUM *r, const BIGNUM *a, const unsigned int p[])
421int BN_GF2m_mod(BIGNUM *r, const BIGNUM *a, const BIGNUM *p) 360int BN_GF2m_mod(BIGNUM *r, const BIGNUM *a, const BIGNUM *p)
422 { 361 {
423 int ret = 0; 362 int ret = 0;
424 const int max = BN_num_bits(p); 363 const int max = BN_num_bits(p) + 1;
425 unsigned int *arr=NULL; 364 int *arr=NULL;
426 bn_check_top(a); 365 bn_check_top(a);
427 bn_check_top(p); 366 bn_check_top(p);
428 if ((arr = (unsigned int *)OPENSSL_malloc(sizeof(unsigned int) * max)) == NULL) goto err; 367 if ((arr = (int *)OPENSSL_malloc(sizeof(int) * max)) == NULL) goto err;
429 ret = BN_GF2m_poly2arr(p, arr, max); 368 ret = BN_GF2m_poly2arr(p, arr, max);
430 if (!ret || ret > max) 369 if (!ret || ret > max)
431 { 370 {
@@ -443,7 +382,7 @@ err:
443/* Compute the product of two polynomials a and b, reduce modulo p, and store 382/* Compute the product of two polynomials a and b, reduce modulo p, and store
444 * the result in r. r could be a or b; a could be b. 383 * the result in r. r could be a or b; a could be b.
445 */ 384 */
446int BN_GF2m_mod_mul_arr(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const unsigned int p[], BN_CTX *ctx) 385int BN_GF2m_mod_mul_arr(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const int p[], BN_CTX *ctx)
447 { 386 {
448 int zlen, i, j, k, ret = 0; 387 int zlen, i, j, k, ret = 0;
449 BIGNUM *s; 388 BIGNUM *s;
@@ -499,12 +438,12 @@ err:
499int BN_GF2m_mod_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *p, BN_CTX *ctx) 438int BN_GF2m_mod_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *p, BN_CTX *ctx)
500 { 439 {
501 int ret = 0; 440 int ret = 0;
502 const int max = BN_num_bits(p); 441 const int max = BN_num_bits(p) + 1;
503 unsigned int *arr=NULL; 442 int *arr=NULL;
504 bn_check_top(a); 443 bn_check_top(a);
505 bn_check_top(b); 444 bn_check_top(b);
506 bn_check_top(p); 445 bn_check_top(p);
507 if ((arr = (unsigned int *)OPENSSL_malloc(sizeof(unsigned int) * max)) == NULL) goto err; 446 if ((arr = (int *)OPENSSL_malloc(sizeof(int) * max)) == NULL) goto err;
508 ret = BN_GF2m_poly2arr(p, arr, max); 447 ret = BN_GF2m_poly2arr(p, arr, max);
509 if (!ret || ret > max) 448 if (!ret || ret > max)
510 { 449 {
@@ -520,7 +459,7 @@ err:
520 459
521 460
522/* Square a, reduce the result mod p, and store it in a. r could be a. */ 461/* Square a, reduce the result mod p, and store it in a. r could be a. */
523int BN_GF2m_mod_sqr_arr(BIGNUM *r, const BIGNUM *a, const unsigned int p[], BN_CTX *ctx) 462int BN_GF2m_mod_sqr_arr(BIGNUM *r, const BIGNUM *a, const int p[], BN_CTX *ctx)
524 { 463 {
525 int i, ret = 0; 464 int i, ret = 0;
526 BIGNUM *s; 465 BIGNUM *s;
@@ -555,12 +494,12 @@ err:
555int BN_GF2m_mod_sqr(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx) 494int BN_GF2m_mod_sqr(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx)
556 { 495 {
557 int ret = 0; 496 int ret = 0;
558 const int max = BN_num_bits(p); 497 const int max = BN_num_bits(p) + 1;
559 unsigned int *arr=NULL; 498 int *arr=NULL;
560 499
561 bn_check_top(a); 500 bn_check_top(a);
562 bn_check_top(p); 501 bn_check_top(p);
563 if ((arr = (unsigned int *)OPENSSL_malloc(sizeof(unsigned int) * max)) == NULL) goto err; 502 if ((arr = (int *)OPENSSL_malloc(sizeof(int) * max)) == NULL) goto err;
564 ret = BN_GF2m_poly2arr(p, arr, max); 503 ret = BN_GF2m_poly2arr(p, arr, max);
565 if (!ret || ret > max) 504 if (!ret || ret > max)
566 { 505 {
@@ -642,7 +581,7 @@ err:
642 * function is only provided for convenience; for best performance, use the 581 * function is only provided for convenience; for best performance, use the
643 * BN_GF2m_mod_inv function. 582 * BN_GF2m_mod_inv function.
644 */ 583 */
645int BN_GF2m_mod_inv_arr(BIGNUM *r, const BIGNUM *xx, const unsigned int p[], BN_CTX *ctx) 584int BN_GF2m_mod_inv_arr(BIGNUM *r, const BIGNUM *xx, const int p[], BN_CTX *ctx)
646 { 585 {
647 BIGNUM *field; 586 BIGNUM *field;
648 int ret = 0; 587 int ret = 0;
@@ -768,7 +707,7 @@ err:
768 * function is only provided for convenience; for best performance, use the 707 * function is only provided for convenience; for best performance, use the
769 * BN_GF2m_mod_div function. 708 * BN_GF2m_mod_div function.
770 */ 709 */
771int BN_GF2m_mod_div_arr(BIGNUM *r, const BIGNUM *yy, const BIGNUM *xx, const unsigned int p[], BN_CTX *ctx) 710int BN_GF2m_mod_div_arr(BIGNUM *r, const BIGNUM *yy, const BIGNUM *xx, const int p[], BN_CTX *ctx)
772 { 711 {
773 BIGNUM *field; 712 BIGNUM *field;
774 int ret = 0; 713 int ret = 0;
@@ -793,7 +732,7 @@ err:
793 * the result in r. r could be a. 732 * the result in r. r could be a.
794 * Uses simple square-and-multiply algorithm A.5.1 from IEEE P1363. 733 * Uses simple square-and-multiply algorithm A.5.1 from IEEE P1363.
795 */ 734 */
796int BN_GF2m_mod_exp_arr(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const unsigned int p[], BN_CTX *ctx) 735int BN_GF2m_mod_exp_arr(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const int p[], BN_CTX *ctx)
797 { 736 {
798 int ret = 0, i, n; 737 int ret = 0, i, n;
799 BIGNUM *u; 738 BIGNUM *u;
@@ -839,12 +778,12 @@ err:
839int BN_GF2m_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *p, BN_CTX *ctx) 778int BN_GF2m_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *p, BN_CTX *ctx)
840 { 779 {
841 int ret = 0; 780 int ret = 0;
842 const int max = BN_num_bits(p); 781 const int max = BN_num_bits(p) + 1;
843 unsigned int *arr=NULL; 782 int *arr=NULL;
844 bn_check_top(a); 783 bn_check_top(a);
845 bn_check_top(b); 784 bn_check_top(b);
846 bn_check_top(p); 785 bn_check_top(p);
847 if ((arr = (unsigned int *)OPENSSL_malloc(sizeof(unsigned int) * max)) == NULL) goto err; 786 if ((arr = (int *)OPENSSL_malloc(sizeof(int) * max)) == NULL) goto err;
848 ret = BN_GF2m_poly2arr(p, arr, max); 787 ret = BN_GF2m_poly2arr(p, arr, max);
849 if (!ret || ret > max) 788 if (!ret || ret > max)
850 { 789 {
@@ -862,7 +801,7 @@ err:
862 * the result in r. r could be a. 801 * the result in r. r could be a.
863 * Uses exponentiation as in algorithm A.4.1 from IEEE P1363. 802 * Uses exponentiation as in algorithm A.4.1 from IEEE P1363.
864 */ 803 */
865int BN_GF2m_mod_sqrt_arr(BIGNUM *r, const BIGNUM *a, const unsigned int p[], BN_CTX *ctx) 804int BN_GF2m_mod_sqrt_arr(BIGNUM *r, const BIGNUM *a, const int p[], BN_CTX *ctx)
866 { 805 {
867 int ret = 0; 806 int ret = 0;
868 BIGNUM *u; 807 BIGNUM *u;
@@ -898,11 +837,11 @@ err:
898int BN_GF2m_mod_sqrt(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx) 837int BN_GF2m_mod_sqrt(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx)
899 { 838 {
900 int ret = 0; 839 int ret = 0;
901 const int max = BN_num_bits(p); 840 const int max = BN_num_bits(p) + 1;
902 unsigned int *arr=NULL; 841 int *arr=NULL;
903 bn_check_top(a); 842 bn_check_top(a);
904 bn_check_top(p); 843 bn_check_top(p);
905 if ((arr = (unsigned int *)OPENSSL_malloc(sizeof(unsigned int) * max)) == NULL) goto err; 844 if ((arr = (int *)OPENSSL_malloc(sizeof(int) * max)) == NULL) goto err;
906 ret = BN_GF2m_poly2arr(p, arr, max); 845 ret = BN_GF2m_poly2arr(p, arr, max);
907 if (!ret || ret > max) 846 if (!ret || ret > max)
908 { 847 {
@@ -919,10 +858,9 @@ err:
919/* Find r such that r^2 + r = a mod p. r could be a. If no r exists returns 0. 858/* Find r such that r^2 + r = a mod p. r could be a. If no r exists returns 0.
920 * Uses algorithms A.4.7 and A.4.6 from IEEE P1363. 859 * Uses algorithms A.4.7 and A.4.6 from IEEE P1363.
921 */ 860 */
922int BN_GF2m_mod_solve_quad_arr(BIGNUM *r, const BIGNUM *a_, const unsigned int p[], BN_CTX *ctx) 861int BN_GF2m_mod_solve_quad_arr(BIGNUM *r, const BIGNUM *a_, const int p[], BN_CTX *ctx)
923 { 862 {
924 int ret = 0, count = 0; 863 int ret = 0, count = 0, j;
925 unsigned int j;
926 BIGNUM *a, *z, *rho, *w, *w2, *tmp; 864 BIGNUM *a, *z, *rho, *w, *w2, *tmp;
927 865
928 bn_check_top(a_); 866 bn_check_top(a_);
@@ -1017,11 +955,11 @@ err:
1017int BN_GF2m_mod_solve_quad(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx) 955int BN_GF2m_mod_solve_quad(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx)
1018 { 956 {
1019 int ret = 0; 957 int ret = 0;
1020 const int max = BN_num_bits(p); 958 const int max = BN_num_bits(p) + 1;
1021 unsigned int *arr=NULL; 959 int *arr=NULL;
1022 bn_check_top(a); 960 bn_check_top(a);
1023 bn_check_top(p); 961 bn_check_top(p);
1024 if ((arr = (unsigned int *)OPENSSL_malloc(sizeof(unsigned int) * 962 if ((arr = (int *)OPENSSL_malloc(sizeof(int) *
1025 max)) == NULL) goto err; 963 max)) == NULL) goto err;
1026 ret = BN_GF2m_poly2arr(p, arr, max); 964 ret = BN_GF2m_poly2arr(p, arr, max);
1027 if (!ret || ret > max) 965 if (!ret || ret > max)
@@ -1037,20 +975,17 @@ err:
1037 } 975 }
1038 976
1039/* Convert the bit-string representation of a polynomial 977/* Convert the bit-string representation of a polynomial
1040 * ( \sum_{i=0}^n a_i * x^i , where a_0 is *not* zero) into an array 978 * ( \sum_{i=0}^n a_i * x^i) into an array of integers corresponding
1041 * of integers corresponding to the bits with non-zero coefficient. 979 * to the bits with non-zero coefficient. Array is terminated with -1.
1042 * Up to max elements of the array will be filled. Return value is total 980 * Up to max elements of the array will be filled. Return value is total
1043 * number of coefficients that would be extracted if array was large enough. 981 * number of array elements that would be filled if array was large enough.
1044 */ 982 */
1045int BN_GF2m_poly2arr(const BIGNUM *a, unsigned int p[], int max) 983int BN_GF2m_poly2arr(const BIGNUM *a, int p[], int max)
1046 { 984 {
1047 int i, j, k = 0; 985 int i, j, k = 0;
1048 BN_ULONG mask; 986 BN_ULONG mask;
1049 987
1050 if (BN_is_zero(a) || !BN_is_bit_set(a, 0)) 988 if (BN_is_zero(a))
1051 /* a_0 == 0 => return error (the unsigned int array
1052 * must be terminated by 0)
1053 */
1054 return 0; 989 return 0;
1055 990
1056 for (i = a->top - 1; i >= 0; i--) 991 for (i = a->top - 1; i >= 0; i--)
@@ -1070,24 +1005,28 @@ int BN_GF2m_poly2arr(const BIGNUM *a, unsigned int p[], int max)
1070 } 1005 }
1071 } 1006 }
1072 1007
1008 if (k < max) {
1009 p[k] = -1;
1010 k++;
1011 }
1012
1073 return k; 1013 return k;
1074 } 1014 }
1075 1015
1076/* Convert the coefficient array representation of a polynomial to a 1016/* Convert the coefficient array representation of a polynomial to a
1077 * bit-string. The array must be terminated by 0. 1017 * bit-string. The array must be terminated by -1.
1078 */ 1018 */
1079int BN_GF2m_arr2poly(const unsigned int p[], BIGNUM *a) 1019int BN_GF2m_arr2poly(const int p[], BIGNUM *a)
1080 { 1020 {
1081 int i; 1021 int i;
1082 1022
1083 bn_check_top(a); 1023 bn_check_top(a);
1084 BN_zero(a); 1024 BN_zero(a);
1085 for (i = 0; p[i] != 0; i++) 1025 for (i = 0; p[i] != -1; i++)
1086 { 1026 {
1087 if (BN_set_bit(a, p[i]) == 0) 1027 if (BN_set_bit(a, p[i]) == 0)
1088 return 0; 1028 return 0;
1089 } 1029 }
1090 BN_set_bit(a, 0);
1091 bn_check_top(a); 1030 bn_check_top(a);
1092 1031
1093 return 1; 1032 return 1;
diff --git a/src/lib/libcrypto/bn/bn_lcl.h b/src/lib/libcrypto/bn/bn_lcl.h
index 27ac4397a1..8e5e98e3f2 100644
--- a/src/lib/libcrypto/bn/bn_lcl.h
+++ b/src/lib/libcrypto/bn/bn_lcl.h
@@ -255,7 +255,8 @@ extern "C" {
255 : "r"(a), "r"(b)); \ 255 : "r"(a), "r"(b)); \
256 ret; }) 256 ret; })
257# endif /* compiler */ 257# endif /* compiler */
258# elif defined(__x86_64) && defined(SIXTY_FOUR_BIT_LONG) 258# elif (defined(__x86_64) || defined(__x86_64__)) && \
259 (defined(SIXTY_FOUR_BIT_LONG) || defined(SIXTY_FOUR_BIT))
259# if defined(__GNUC__) 260# if defined(__GNUC__)
260# define BN_UMULT_HIGH(a,b) ({ \ 261# define BN_UMULT_HIGH(a,b) ({ \
261 register BN_ULONG ret,discard; \ 262 register BN_ULONG ret,discard; \
diff --git a/src/lib/libcrypto/bn/bn_lib.c b/src/lib/libcrypto/bn/bn_lib.c
index 32a8fbaf51..5470fbe6ef 100644
--- a/src/lib/libcrypto/bn/bn_lib.c
+++ b/src/lib/libcrypto/bn/bn_lib.c
@@ -133,15 +133,34 @@ int BN_get_params(int which)
133 133
134const BIGNUM *BN_value_one(void) 134const BIGNUM *BN_value_one(void)
135 { 135 {
136 static BN_ULONG data_one=1L; 136 static const BN_ULONG data_one=1L;
137 static BIGNUM const_one={&data_one,1,1,0,BN_FLG_STATIC_DATA}; 137 static const BIGNUM const_one={(BN_ULONG *)&data_one,1,1,0,BN_FLG_STATIC_DATA};
138 138
139 return(&const_one); 139 return(&const_one);
140 } 140 }
141 141
142char *BN_options(void)
143 {
144 static int init=0;
145 static char data[16];
146
147 if (!init)
148 {
149 init++;
150#ifdef BN_LLONG
151 BIO_snprintf(data,sizeof data,"bn(%d,%d)",
152 (int)sizeof(BN_ULLONG)*8,(int)sizeof(BN_ULONG)*8);
153#else
154 BIO_snprintf(data,sizeof data,"bn(%d,%d)",
155 (int)sizeof(BN_ULONG)*8,(int)sizeof(BN_ULONG)*8);
156#endif
157 }
158 return(data);
159 }
160
142int BN_num_bits_word(BN_ULONG l) 161int BN_num_bits_word(BN_ULONG l)
143 { 162 {
144 static const char bits[256]={ 163 static const unsigned char bits[256]={
145 0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4, 164 0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4,
146 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, 165 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
147 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, 166 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
@@ -216,7 +235,7 @@ int BN_num_bits_word(BN_ULONG l)
216 else 235 else
217#endif 236#endif
218 { 237 {
219#if defined(SIXTEEN_BIT) || defined(THIRTY_TWO_BIT) || defined(SIXTY_FOUR_BIT) || defined(SIXTY_FOUR_BIT_LONG) 238#if defined(THIRTY_TWO_BIT) || defined(SIXTY_FOUR_BIT) || defined(SIXTY_FOUR_BIT_LONG)
220 if (l & 0xff00L) 239 if (l & 0xff00L)
221 return(bits[(int)(l>>8)]+8); 240 return(bits[(int)(l>>8)]+8);
222 else 241 else
@@ -744,7 +763,7 @@ int BN_is_bit_set(const BIGNUM *a, int n)
744 i=n/BN_BITS2; 763 i=n/BN_BITS2;
745 j=n%BN_BITS2; 764 j=n%BN_BITS2;
746 if (a->top <= i) return 0; 765 if (a->top <= i) return 0;
747 return(((a->d[i])>>j)&((BN_ULONG)1)); 766 return (int)(((a->d[i])>>j)&((BN_ULONG)1));
748 } 767 }
749 768
750int BN_mask_bits(BIGNUM *a, int n) 769int BN_mask_bits(BIGNUM *a, int n)
diff --git a/src/lib/libcrypto/bn/bn_mont.c b/src/lib/libcrypto/bn/bn_mont.c
index 4799b152dd..7224637ab3 100644
--- a/src/lib/libcrypto/bn/bn_mont.c
+++ b/src/lib/libcrypto/bn/bn_mont.c
@@ -122,26 +122,10 @@
122 122
123#define MONT_WORD /* use the faster word-based algorithm */ 123#define MONT_WORD /* use the faster word-based algorithm */
124 124
125#if defined(MONT_WORD) && defined(OPENSSL_BN_ASM_MONT) && (BN_BITS2<=32) 125#ifdef MONT_WORD
126/* This condition means we have a specific non-default build:
127 * In the 0.9.8 branch, OPENSSL_BN_ASM_MONT is normally not set for any
128 * BN_BITS2<=32 platform; an explicit "enable-montasm" is required.
129 * I.e., if we are here, the user intentionally deviates from the
130 * normal stable build to get better Montgomery performance from
131 * the 0.9.9-dev backport.
132 *
133 * In this case only, we also enable BN_from_montgomery_word()
134 * (another non-stable feature from 0.9.9-dev).
135 */
136#define MONT_FROM_WORD___NON_DEFAULT_0_9_8_BUILD
137#endif
138
139#ifdef MONT_FROM_WORD___NON_DEFAULT_0_9_8_BUILD
140static int BN_from_montgomery_word(BIGNUM *ret, BIGNUM *r, BN_MONT_CTX *mont); 126static int BN_from_montgomery_word(BIGNUM *ret, BIGNUM *r, BN_MONT_CTX *mont);
141#endif 127#endif
142 128
143
144
145int BN_mod_mul_montgomery(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, 129int BN_mod_mul_montgomery(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
146 BN_MONT_CTX *mont, BN_CTX *ctx) 130 BN_MONT_CTX *mont, BN_CTX *ctx)
147 { 131 {
@@ -153,11 +137,7 @@ int BN_mod_mul_montgomery(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
153 if (num>1 && a->top==num && b->top==num) 137 if (num>1 && a->top==num && b->top==num)
154 { 138 {
155 if (bn_wexpand(r,num) == NULL) return(0); 139 if (bn_wexpand(r,num) == NULL) return(0);
156#if 0 /* for OpenSSL 0.9.9 mont->n0 */
157 if (bn_mul_mont(r->d,a->d,b->d,mont->N.d,mont->n0,num)) 140 if (bn_mul_mont(r->d,a->d,b->d,mont->N.d,mont->n0,num))
158#else
159 if (bn_mul_mont(r->d,a->d,b->d,mont->N.d,&mont->n0,num))
160#endif
161 { 141 {
162 r->neg = a->neg^b->neg; 142 r->neg = a->neg^b->neg;
163 r->top = num; 143 r->top = num;
@@ -181,7 +161,7 @@ int BN_mod_mul_montgomery(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
181 if (!BN_mul(tmp,a,b,ctx)) goto err; 161 if (!BN_mul(tmp,a,b,ctx)) goto err;
182 } 162 }
183 /* reduce from aRR to aR */ 163 /* reduce from aRR to aR */
184#ifdef MONT_FROM_WORD___NON_DEFAULT_0_9_8_BUILD 164#ifdef MONT_WORD
185 if (!BN_from_montgomery_word(r,tmp,mont)) goto err; 165 if (!BN_from_montgomery_word(r,tmp,mont)) goto err;
186#else 166#else
187 if (!BN_from_montgomery(r,tmp,mont,ctx)) goto err; 167 if (!BN_from_montgomery(r,tmp,mont,ctx)) goto err;
@@ -193,7 +173,7 @@ err:
193 return(ret); 173 return(ret);
194 } 174 }
195 175
196#ifdef MONT_FROM_WORD___NON_DEFAULT_0_9_8_BUILD 176#ifdef MONT_WORD
197static int BN_from_montgomery_word(BIGNUM *ret, BIGNUM *r, BN_MONT_CTX *mont) 177static int BN_from_montgomery_word(BIGNUM *ret, BIGNUM *r, BN_MONT_CTX *mont)
198 { 178 {
199 BIGNUM *n; 179 BIGNUM *n;
@@ -217,15 +197,15 @@ static int BN_from_montgomery_word(BIGNUM *ret, BIGNUM *r, BN_MONT_CTX *mont)
217 nrp= &(r->d[nl]); 197 nrp= &(r->d[nl]);
218 198
219 /* clear the top words of T */ 199 /* clear the top words of T */
200#if 1
220 for (i=r->top; i<max; i++) /* memset? XXX */ 201 for (i=r->top; i<max; i++) /* memset? XXX */
221 r->d[i]=0; 202 r->d[i]=0;
203#else
204 memset(&(r->d[r->top]),0,(max-r->top)*sizeof(BN_ULONG));
205#endif
222 206
223 r->top=max; 207 r->top=max;
224#if 0 /* for OpenSSL 0.9.9 mont->n0 */
225 n0=mont->n0[0]; 208 n0=mont->n0[0];
226#else
227 n0=mont->n0;
228#endif
229 209
230#ifdef BN_COUNT 210#ifdef BN_COUNT
231 fprintf(stderr,"word BN_from_montgomery_word %d * %d\n",nl,nl); 211 fprintf(stderr,"word BN_from_montgomery_word %d * %d\n",nl,nl);
@@ -270,6 +250,8 @@ static int BN_from_montgomery_word(BIGNUM *ret, BIGNUM *r, BN_MONT_CTX *mont)
270 } 250 }
271 al=r->top-ri; 251 al=r->top-ri;
272 252
253#define BRANCH_FREE 1
254#if BRANCH_FREE
273 if (bn_wexpand(ret,ri) == NULL) return(0); 255 if (bn_wexpand(ret,ri) == NULL) return(0);
274 x=0-(((al-ri)>>(sizeof(al)*8-1))&1); 256 x=0-(((al-ri)>>(sizeof(al)*8-1))&1);
275 ret->top=x=(ri&~x)|(al&x); /* min(ri,al) */ 257 ret->top=x=(ri&~x)|(al&x); /* min(ri,al) */
@@ -317,164 +299,8 @@ static int BN_from_montgomery_word(BIGNUM *ret, BIGNUM *r, BN_MONT_CTX *mont)
317 rp[i]=nrp[i], ap[i]=0; 299 rp[i]=nrp[i], ap[i]=0;
318 bn_correct_top(r); 300 bn_correct_top(r);
319 bn_correct_top(ret); 301 bn_correct_top(ret);
320 bn_check_top(ret);
321
322 return(1);
323 }
324
325int BN_from_montgomery(BIGNUM *ret, const BIGNUM *a, BN_MONT_CTX *mont,
326 BN_CTX *ctx)
327 {
328 int retn=0;
329 BIGNUM *t;
330
331 BN_CTX_start(ctx);
332 if ((t = BN_CTX_get(ctx)) && BN_copy(t,a))
333 retn = BN_from_montgomery_word(ret,t,mont);
334 BN_CTX_end(ctx);
335 return retn;
336 }
337
338#else /* !MONT_FROM_WORD___NON_DEFAULT_0_9_8_BUILD */
339
340int BN_from_montgomery(BIGNUM *ret, const BIGNUM *a, BN_MONT_CTX *mont,
341 BN_CTX *ctx)
342 {
343 int retn=0;
344
345#ifdef MONT_WORD
346 BIGNUM *n,*r;
347 BN_ULONG *ap,*np,*rp,n0,v,*nrp;
348 int al,nl,max,i,x,ri;
349
350 BN_CTX_start(ctx);
351 if ((r = BN_CTX_get(ctx)) == NULL) goto err;
352
353 if (!BN_copy(r,a)) goto err;
354 n= &(mont->N);
355
356 ap=a->d;
357 /* mont->ri is the size of mont->N in bits (rounded up
358 to the word size) */
359 al=ri=mont->ri/BN_BITS2;
360
361 nl=n->top;
362 if ((al == 0) || (nl == 0)) { r->top=0; return(1); }
363
364 max=(nl+al+1); /* allow for overflow (no?) XXX */
365 if (bn_wexpand(r,max) == NULL) goto err;
366
367 r->neg=a->neg^n->neg;
368 np=n->d;
369 rp=r->d;
370 nrp= &(r->d[nl]);
371
372 /* clear the top words of T */
373#if 1
374 for (i=r->top; i<max; i++) /* memset? XXX */
375 r->d[i]=0;
376#else 302#else
377 memset(&(r->d[r->top]),0,(max-r->top)*sizeof(BN_ULONG)); 303 if (bn_wexpand(ret,al) == NULL) return(0);
378#endif
379
380 r->top=max;
381 n0=mont->n0;
382
383#ifdef BN_COUNT
384 fprintf(stderr,"word BN_from_montgomery %d * %d\n",nl,nl);
385#endif
386 for (i=0; i<nl; i++)
387 {
388#ifdef __TANDEM
389 {
390 long long t1;
391 long long t2;
392 long long t3;
393 t1 = rp[0] * (n0 & 0177777);
394 t2 = 037777600000l;
395 t2 = n0 & t2;
396 t3 = rp[0] & 0177777;
397 t2 = (t3 * t2) & BN_MASK2;
398 t1 = t1 + t2;
399 v=bn_mul_add_words(rp,np,nl,(BN_ULONG) t1);
400 }
401#else
402 v=bn_mul_add_words(rp,np,nl,(rp[0]*n0)&BN_MASK2);
403#endif
404 nrp++;
405 rp++;
406 if (((nrp[-1]+=v)&BN_MASK2) >= v)
407 continue;
408 else
409 {
410 if (((++nrp[0])&BN_MASK2) != 0) continue;
411 if (((++nrp[1])&BN_MASK2) != 0) continue;
412 for (x=2; (((++nrp[x])&BN_MASK2) == 0); x++) ;
413 }
414 }
415 bn_correct_top(r);
416
417 /* mont->ri will be a multiple of the word size and below code
418 * is kind of BN_rshift(ret,r,mont->ri) equivalent */
419 if (r->top <= ri)
420 {
421 ret->top=0;
422 retn=1;
423 goto err;
424 }
425 al=r->top-ri;
426
427# define BRANCH_FREE 1
428# if BRANCH_FREE
429 if (bn_wexpand(ret,ri) == NULL) goto err;
430 x=0-(((al-ri)>>(sizeof(al)*8-1))&1);
431 ret->top=x=(ri&~x)|(al&x); /* min(ri,al) */
432 ret->neg=r->neg;
433
434 rp=ret->d;
435 ap=&(r->d[ri]);
436
437 {
438 size_t m1,m2;
439
440 v=bn_sub_words(rp,ap,np,ri);
441 /* this ----------------^^ works even in al<ri case
442 * thanks to zealous zeroing of top of the vector in the
443 * beginning. */
444
445 /* if (al==ri && !v) || al>ri) nrp=rp; else nrp=ap; */
446 /* in other words if subtraction result is real, then
447 * trick unconditional memcpy below to perform in-place
448 * "refresh" instead of actual copy. */
449 m1=0-(size_t)(((al-ri)>>(sizeof(al)*8-1))&1); /* al<ri */
450 m2=0-(size_t)(((ri-al)>>(sizeof(al)*8-1))&1); /* al>ri */
451 m1|=m2; /* (al!=ri) */
452 m1|=(0-(size_t)v); /* (al!=ri || v) */
453 m1&=~m2; /* (al!=ri || v) && !al>ri */
454 nrp=(BN_ULONG *)(((size_t)rp&~m1)|((size_t)ap&m1));
455 }
456
457 /* 'i<ri' is chosen to eliminate dependency on input data, even
458 * though it results in redundant copy in al<ri case. */
459 for (i=0,ri-=4; i<ri; i+=4)
460 {
461 BN_ULONG t1,t2,t3,t4;
462
463 t1=nrp[i+0];
464 t2=nrp[i+1];
465 t3=nrp[i+2]; ap[i+0]=0;
466 t4=nrp[i+3]; ap[i+1]=0;
467 rp[i+0]=t1; ap[i+2]=0;
468 rp[i+1]=t2; ap[i+3]=0;
469 rp[i+2]=t3;
470 rp[i+3]=t4;
471 }
472 for (ri+=4; i<ri; i++)
473 rp[i]=nrp[i], ap[i]=0;
474 bn_correct_top(r);
475 bn_correct_top(ret);
476# else
477 if (bn_wexpand(ret,al) == NULL) goto err;
478 ret->top=al; 304 ret->top=al;
479 ret->neg=r->neg; 305 ret->neg=r->neg;
480 306
@@ -497,8 +323,30 @@ int BN_from_montgomery(BIGNUM *ret, const BIGNUM *a, BN_MONT_CTX *mont,
497 al+=4; 323 al+=4;
498 for (; i<al; i++) 324 for (; i<al; i++)
499 rp[i]=ap[i]; 325 rp[i]=ap[i];
500# endif 326
501#else /* !MONT_WORD */ 327 if (BN_ucmp(ret, &(mont->N)) >= 0)
328 {
329 if (!BN_usub(ret,ret,&(mont->N))) return(0);
330 }
331#endif
332 bn_check_top(ret);
333
334 return(1);
335 }
336#endif /* MONT_WORD */
337
338int BN_from_montgomery(BIGNUM *ret, const BIGNUM *a, BN_MONT_CTX *mont,
339 BN_CTX *ctx)
340 {
341 int retn=0;
342#ifdef MONT_WORD
343 BIGNUM *t;
344
345 BN_CTX_start(ctx);
346 if ((t = BN_CTX_get(ctx)) && BN_copy(t,a))
347 retn = BN_from_montgomery_word(ret,t,mont);
348 BN_CTX_end(ctx);
349#else /* !MONT_WORD */
502 BIGNUM *t1,*t2; 350 BIGNUM *t1,*t2;
503 351
504 BN_CTX_start(ctx); 352 BN_CTX_start(ctx);
@@ -515,21 +363,18 @@ int BN_from_montgomery(BIGNUM *ret, const BIGNUM *a, BN_MONT_CTX *mont,
515 if (!BN_mul(t1,t2,&mont->N,ctx)) goto err; 363 if (!BN_mul(t1,t2,&mont->N,ctx)) goto err;
516 if (!BN_add(t2,a,t1)) goto err; 364 if (!BN_add(t2,a,t1)) goto err;
517 if (!BN_rshift(ret,t2,mont->ri)) goto err; 365 if (!BN_rshift(ret,t2,mont->ri)) goto err;
518#endif /* MONT_WORD */
519 366
520#if !defined(BRANCH_FREE) || BRANCH_FREE==0
521 if (BN_ucmp(ret, &(mont->N)) >= 0) 367 if (BN_ucmp(ret, &(mont->N)) >= 0)
522 { 368 {
523 if (!BN_usub(ret,ret,&(mont->N))) goto err; 369 if (!BN_usub(ret,ret,&(mont->N))) goto err;
524 } 370 }
525#endif
526 retn=1; 371 retn=1;
527 bn_check_top(ret); 372 bn_check_top(ret);
528 err: 373 err:
529 BN_CTX_end(ctx); 374 BN_CTX_end(ctx);
375#endif /* MONT_WORD */
530 return(retn); 376 return(retn);
531 } 377 }
532#endif /* MONT_FROM_WORD___NON_DEFAULT_0_9_8_BUILD */
533 378
534BN_MONT_CTX *BN_MONT_CTX_new(void) 379BN_MONT_CTX *BN_MONT_CTX_new(void)
535 { 380 {
@@ -549,11 +394,7 @@ void BN_MONT_CTX_init(BN_MONT_CTX *ctx)
549 BN_init(&(ctx->RR)); 394 BN_init(&(ctx->RR));
550 BN_init(&(ctx->N)); 395 BN_init(&(ctx->N));
551 BN_init(&(ctx->Ni)); 396 BN_init(&(ctx->Ni));
552#if 0 /* for OpenSSL 0.9.9 mont->n0 */
553 ctx->n0[0] = ctx->n0[1] = 0; 397 ctx->n0[0] = ctx->n0[1] = 0;
554#else
555 ctx->n0 = 0;
556#endif
557 ctx->flags=0; 398 ctx->flags=0;
558 } 399 }
559 400
@@ -585,26 +426,22 @@ int BN_MONT_CTX_set(BN_MONT_CTX *mont, const BIGNUM *mod, BN_CTX *ctx)
585 BIGNUM tmod; 426 BIGNUM tmod;
586 BN_ULONG buf[2]; 427 BN_ULONG buf[2];
587 428
588 mont->ri=(BN_num_bits(mod)+(BN_BITS2-1))/BN_BITS2*BN_BITS2;
589 BN_zero(R);
590#if 0 /* for OpenSSL 0.9.9 mont->n0, would be "#if defined(OPENSSL_BN_ASM_MONT) && (BN_BITS2<=32)",
591 only certain BN_BITS2<=32 platforms actually need this */
592 if (!(BN_set_bit(R,2*BN_BITS2))) goto err; /* R */
593#else
594 if (!(BN_set_bit(R,BN_BITS2))) goto err; /* R */
595#endif
596
597 buf[0]=mod->d[0]; /* tmod = N mod word size */
598 buf[1]=0;
599
600 BN_init(&tmod); 429 BN_init(&tmod);
601 tmod.d=buf; 430 tmod.d=buf;
602 tmod.top = buf[0] != 0 ? 1 : 0;
603 tmod.dmax=2; 431 tmod.dmax=2;
604 tmod.neg=0; 432 tmod.neg=0;
605 433
606#if 0 /* for OpenSSL 0.9.9 mont->n0, would be "#if defined(OPENSSL_BN_ASM_MONT) && (BN_BITS2<=32)"; 434 mont->ri=(BN_num_bits(mod)+(BN_BITS2-1))/BN_BITS2*BN_BITS2;
607 only certain BN_BITS2<=32 platforms actually need this */ 435
436#if defined(OPENSSL_BN_ASM_MONT) && (BN_BITS2<=32)
437 /* Only certain BN_BITS2<=32 platforms actually make use of
438 * n0[1], and we could use the #else case (with a shorter R
439 * value) for the others. However, currently only the assembler
440 * files do know which is which. */
441
442 BN_zero(R);
443 if (!(BN_set_bit(R,2*BN_BITS2))) goto err;
444
608 tmod.top=0; 445 tmod.top=0;
609 if ((buf[0] = mod->d[0])) tmod.top=1; 446 if ((buf[0] = mod->d[0])) tmod.top=1;
610 if ((buf[1] = mod->top>1 ? mod->d[1] : 0)) tmod.top=2; 447 if ((buf[1] = mod->top>1 ? mod->d[1] : 0)) tmod.top=2;
@@ -632,6 +469,12 @@ int BN_MONT_CTX_set(BN_MONT_CTX *mont, const BIGNUM *mod, BN_CTX *ctx)
632 mont->n0[0] = (Ri->top > 0) ? Ri->d[0] : 0; 469 mont->n0[0] = (Ri->top > 0) ? Ri->d[0] : 0;
633 mont->n0[1] = (Ri->top > 1) ? Ri->d[1] : 0; 470 mont->n0[1] = (Ri->top > 1) ? Ri->d[1] : 0;
634#else 471#else
472 BN_zero(R);
473 if (!(BN_set_bit(R,BN_BITS2))) goto err; /* R */
474
475 buf[0]=mod->d[0]; /* tmod = N mod word size */
476 buf[1]=0;
477 tmod.top = buf[0] != 0 ? 1 : 0;
635 /* Ri = R^-1 mod N*/ 478 /* Ri = R^-1 mod N*/
636 if ((BN_mod_inverse(Ri,R,&tmod,ctx)) == NULL) 479 if ((BN_mod_inverse(Ri,R,&tmod,ctx)) == NULL)
637 goto err; 480 goto err;
@@ -647,12 +490,8 @@ int BN_MONT_CTX_set(BN_MONT_CTX *mont, const BIGNUM *mod, BN_CTX *ctx)
647 if (!BN_div(Ri,NULL,Ri,&tmod,ctx)) goto err; 490 if (!BN_div(Ri,NULL,Ri,&tmod,ctx)) goto err;
648 /* Ni = (R*Ri-1)/N, 491 /* Ni = (R*Ri-1)/N,
649 * keep only least significant word: */ 492 * keep only least significant word: */
650# if 0 /* for OpenSSL 0.9.9 mont->n0 */
651 mont->n0[0] = (Ri->top > 0) ? Ri->d[0] : 0; 493 mont->n0[0] = (Ri->top > 0) ? Ri->d[0] : 0;
652 mont->n0[1] = 0; 494 mont->n0[1] = 0;
653# else
654 mont->n0 = (Ri->top > 0) ? Ri->d[0] : 0;
655# endif
656#endif 495#endif
657 } 496 }
658#else /* !MONT_WORD */ 497#else /* !MONT_WORD */
@@ -689,12 +528,8 @@ BN_MONT_CTX *BN_MONT_CTX_copy(BN_MONT_CTX *to, BN_MONT_CTX *from)
689 if (!BN_copy(&(to->N),&(from->N))) return NULL; 528 if (!BN_copy(&(to->N),&(from->N))) return NULL;
690 if (!BN_copy(&(to->Ni),&(from->Ni))) return NULL; 529 if (!BN_copy(&(to->Ni),&(from->Ni))) return NULL;
691 to->ri=from->ri; 530 to->ri=from->ri;
692#if 0 /* for OpenSSL 0.9.9 mont->n0 */
693 to->n0[0]=from->n0[0]; 531 to->n0[0]=from->n0[0];
694 to->n0[1]=from->n0[1]; 532 to->n0[1]=from->n0[1];
695#else
696 to->n0=from->n0;
697#endif
698 return(to); 533 return(to);
699 } 534 }
700 535
diff --git a/src/lib/libcrypto/bn/bn_mul.c b/src/lib/libcrypto/bn/bn_mul.c
index b848c8cc60..a0e9ec3b46 100644
--- a/src/lib/libcrypto/bn/bn_mul.c
+++ b/src/lib/libcrypto/bn/bn_mul.c
@@ -1028,17 +1028,19 @@ int BN_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
1028 assert(j <= al || j <= bl); 1028 assert(j <= al || j <= bl);
1029 k = j+j; 1029 k = j+j;
1030 t = BN_CTX_get(ctx); 1030 t = BN_CTX_get(ctx);
1031 if (t == NULL)
1032 goto err;
1031 if (al > j || bl > j) 1033 if (al > j || bl > j)
1032 { 1034 {
1033 bn_wexpand(t,k*4); 1035 if (bn_wexpand(t,k*4) == NULL) goto err;
1034 bn_wexpand(rr,k*4); 1036 if (bn_wexpand(rr,k*4) == NULL) goto err;
1035 bn_mul_part_recursive(rr->d,a->d,b->d, 1037 bn_mul_part_recursive(rr->d,a->d,b->d,
1036 j,al-j,bl-j,t->d); 1038 j,al-j,bl-j,t->d);
1037 } 1039 }
1038 else /* al <= j || bl <= j */ 1040 else /* al <= j || bl <= j */
1039 { 1041 {
1040 bn_wexpand(t,k*2); 1042 if (bn_wexpand(t,k*2) == NULL) goto err;
1041 bn_wexpand(rr,k*2); 1043 if (bn_wexpand(rr,k*2) == NULL) goto err;
1042 bn_mul_recursive(rr->d,a->d,b->d, 1044 bn_mul_recursive(rr->d,a->d,b->d,
1043 j,al-j,bl-j,t->d); 1045 j,al-j,bl-j,t->d);
1044 } 1046 }
diff --git a/src/lib/libcrypto/bn/bn_print.c b/src/lib/libcrypto/bn/bn_print.c
index 810dde34e1..bebb466d08 100644
--- a/src/lib/libcrypto/bn/bn_print.c
+++ b/src/lib/libcrypto/bn/bn_print.c
@@ -294,6 +294,27 @@ err:
294 return(0); 294 return(0);
295 } 295 }
296 296
297int BN_asc2bn(BIGNUM **bn, const char *a)
298 {
299 const char *p = a;
300 if (*p == '-')
301 p++;
302
303 if (p[0] == '0' && (p[1] == 'X' || p[1] == 'x'))
304 {
305 if (!BN_hex2bn(bn, p + 2))
306 return 0;
307 }
308 else
309 {
310 if (!BN_dec2bn(bn, p))
311 return 0;
312 }
313 if (*a == '-')
314 (*bn)->neg = 1;
315 return 1;
316 }
317
297#ifndef OPENSSL_NO_BIO 318#ifndef OPENSSL_NO_BIO
298#ifndef OPENSSL_NO_FP_API 319#ifndef OPENSSL_NO_FP_API
299int BN_print_fp(FILE *fp, const BIGNUM *a) 320int BN_print_fp(FILE *fp, const BIGNUM *a)
diff --git a/src/lib/libcrypto/buffer/buf_err.c b/src/lib/libcrypto/buffer/buf_err.c
index 3e25bbe879..8f1de6192b 100644
--- a/src/lib/libcrypto/buffer/buf_err.c
+++ b/src/lib/libcrypto/buffer/buf_err.c
@@ -1,6 +1,6 @@
1/* crypto/buffer/buf_err.c */ 1/* crypto/buffer/buf_err.c */
2/* ==================================================================== 2/* ====================================================================
3 * Copyright (c) 1999-2005 The OpenSSL Project. All rights reserved. 3 * Copyright (c) 1999-2006 The OpenSSL Project. All rights reserved.
4 * 4 *
5 * Redistribution and use in source and binary forms, with or without 5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions 6 * modification, are permitted provided that the following conditions
diff --git a/src/lib/libcrypto/buffer/buffer.c b/src/lib/libcrypto/buffer/buffer.c
index b3e947771d..620ea8d536 100644
--- a/src/lib/libcrypto/buffer/buffer.c
+++ b/src/lib/libcrypto/buffer/buffer.c
@@ -89,10 +89,10 @@ void BUF_MEM_free(BUF_MEM *a)
89 OPENSSL_free(a); 89 OPENSSL_free(a);
90 } 90 }
91 91
92int BUF_MEM_grow(BUF_MEM *str, int len) 92int BUF_MEM_grow(BUF_MEM *str, size_t len)
93 { 93 {
94 char *ret; 94 char *ret;
95 unsigned int n; 95 size_t n;
96 96
97 if (str->length >= len) 97 if (str->length >= len)
98 { 98 {
@@ -125,10 +125,10 @@ int BUF_MEM_grow(BUF_MEM *str, int len)
125 return(len); 125 return(len);
126 } 126 }
127 127
128int BUF_MEM_grow_clean(BUF_MEM *str, int len) 128int BUF_MEM_grow_clean(BUF_MEM *str, size_t len)
129 { 129 {
130 char *ret; 130 char *ret;
131 unsigned int n; 131 size_t n;
132 132
133 if (str->length >= len) 133 if (str->length >= len)
134 { 134 {
@@ -161,3 +161,84 @@ int BUF_MEM_grow_clean(BUF_MEM *str, int len)
161 } 161 }
162 return(len); 162 return(len);
163 } 163 }
164
165char *BUF_strdup(const char *str)
166 {
167 if (str == NULL) return(NULL);
168 return BUF_strndup(str, strlen(str));
169 }
170
171char *BUF_strndup(const char *str, size_t siz)
172 {
173 char *ret;
174
175 if (str == NULL) return(NULL);
176
177 ret=OPENSSL_malloc(siz+1);
178 if (ret == NULL)
179 {
180 BUFerr(BUF_F_BUF_STRNDUP,ERR_R_MALLOC_FAILURE);
181 return(NULL);
182 }
183 BUF_strlcpy(ret,str,siz+1);
184 return(ret);
185 }
186
187void *BUF_memdup(const void *data, size_t siz)
188 {
189 void *ret;
190
191 if (data == NULL) return(NULL);
192
193 ret=OPENSSL_malloc(siz);
194 if (ret == NULL)
195 {
196 BUFerr(BUF_F_BUF_MEMDUP,ERR_R_MALLOC_FAILURE);
197 return(NULL);
198 }
199 return memcpy(ret, data, siz);
200 }
201
202size_t BUF_strlcpy(char *dst, const char *src, size_t size)
203 {
204 size_t l = 0;
205 for(; size > 1 && *src; size--)
206 {
207 *dst++ = *src++;
208 l++;
209 }
210 if (size)
211 *dst = '\0';
212 return l + strlen(src);
213 }
214
215size_t BUF_strlcat(char *dst, const char *src, size_t size)
216 {
217 size_t l = 0;
218 for(; size > 0 && *dst; size--, dst++)
219 l++;
220 return l + BUF_strlcpy(dst, src, size);
221 }
222
223void BUF_reverse(unsigned char *out, unsigned char *in, size_t size)
224 {
225 size_t i;
226 if (in)
227 {
228 out += size - 1;
229 for (i = 0; i < size; i++)
230 *in++ = *out--;
231 }
232 else
233 {
234 unsigned char *q;
235 char c;
236 q = out + size - 1;
237 for (i = 0; i < size/2; i++)
238 {
239 c = *q;
240 *q-- = *out;
241 *out++ = c;
242 }
243 }
244 }
diff --git a/src/lib/libcrypto/buffer/buffer.h b/src/lib/libcrypto/buffer/buffer.h
index 1db9607450..178e418282 100644
--- a/src/lib/libcrypto/buffer/buffer.h
+++ b/src/lib/libcrypto/buffer/buffer.h
@@ -76,18 +76,19 @@ extern "C" {
76 76
77struct buf_mem_st 77struct buf_mem_st
78 { 78 {
79 int length; /* current number of bytes */ 79 size_t length; /* current number of bytes */
80 char *data; 80 char *data;
81 int max; /* size of buffer */ 81 size_t max; /* size of buffer */
82 }; 82 };
83 83
84BUF_MEM *BUF_MEM_new(void); 84BUF_MEM *BUF_MEM_new(void);
85void BUF_MEM_free(BUF_MEM *a); 85void BUF_MEM_free(BUF_MEM *a);
86int BUF_MEM_grow(BUF_MEM *str, int len); 86int BUF_MEM_grow(BUF_MEM *str, size_t len);
87int BUF_MEM_grow_clean(BUF_MEM *str, int len); 87int BUF_MEM_grow_clean(BUF_MEM *str, size_t len);
88char * BUF_strdup(const char *str); 88char * BUF_strdup(const char *str);
89char * BUF_strndup(const char *str, size_t siz); 89char * BUF_strndup(const char *str, size_t siz);
90void * BUF_memdup(const void *data, size_t siz); 90void * BUF_memdup(const void *data, size_t siz);
91void BUF_reverse(unsigned char *out, unsigned char *in, size_t siz);
91 92
92/* safe string functions */ 93/* safe string functions */
93size_t BUF_strlcpy(char *dst,const char *src,size_t siz); 94size_t BUF_strlcpy(char *dst,const char *src,size_t siz);
diff --git a/src/lib/libcrypto/camellia/asm/cmll-x86.pl b/src/lib/libcrypto/camellia/asm/cmll-x86.pl
index 0812815bfb..027302ac86 100644
--- a/src/lib/libcrypto/camellia/asm/cmll-x86.pl
+++ b/src/lib/libcrypto/camellia/asm/cmll-x86.pl
@@ -1133,6 +1133,6 @@ my ($s0,$s1,$s2,$s3) = @T;
1133&function_end("Camellia_cbc_encrypt"); 1133&function_end("Camellia_cbc_encrypt");
1134} 1134}
1135 1135
1136&asciz("Camellia for x86 by <appro@openssl.org>"); 1136&asciz("Camellia for x86 by <appro\@openssl.org>");
1137 1137
1138&asm_finish(); 1138&asm_finish();
diff --git a/src/lib/libcrypto/camellia/asm/cmll-x86_64.pl b/src/lib/libcrypto/camellia/asm/cmll-x86_64.pl
index c683646ca7..76955e4726 100644
--- a/src/lib/libcrypto/camellia/asm/cmll-x86_64.pl
+++ b/src/lib/libcrypto/camellia/asm/cmll-x86_64.pl
@@ -656,7 +656,7 @@ Camellia_cbc_encrypt:
656 mov %rsi,$out # out argument 656 mov %rsi,$out # out argument
657 mov %r8,%rbx # ivp argument 657 mov %r8,%rbx # ivp argument
658 mov %rcx,$key # key argument 658 mov %rcx,$key # key argument
659 mov 272(%rcx),$keyend # grandRounds 659 mov 272(%rcx),${keyend}d # grandRounds
660 660
661 mov %r8,$_ivp 661 mov %r8,$_ivp
662 mov %rbp,$_rsp 662 mov %rbp,$_rsp
@@ -859,7 +859,7 @@ Camellia_cbc_encrypt:
859 ret 859 ret
860.size Camellia_cbc_encrypt,.-Camellia_cbc_encrypt 860.size Camellia_cbc_encrypt,.-Camellia_cbc_encrypt
861 861
862.asciz "Camellia for x86_64 by <appro@openssl.org>" 862.asciz "Camellia for x86_64 by <appro\@openssl.org>"
863___ 863___
864} 864}
865 865
diff --git a/src/lib/libcrypto/camellia/camellia.c b/src/lib/libcrypto/camellia/camellia.c
index 491c26b39e..75fc8991c0 100644
--- a/src/lib/libcrypto/camellia/camellia.c
+++ b/src/lib/libcrypto/camellia/camellia.c
@@ -68,1557 +68,515 @@
68/* Algorithm Specification 68/* Algorithm Specification
69 http://info.isl.ntt.co.jp/crypt/eng/camellia/specifications.html 69 http://info.isl.ntt.co.jp/crypt/eng/camellia/specifications.html
70*/ 70*/
71 71
72 72/*
73#include <string.h> 73 * This release balances code size and performance. In particular key
74#include <stdlib.h> 74 * schedule setup is fully unrolled, because doing so *significantly*
75 * reduces amount of instructions per setup round and code increase is
76 * justifiable. In block functions on the other hand only inner loops
77 * are unrolled, as full unroll gives only nominal performance boost,
78 * while code size grows 4 or 7 times. Also, unlike previous versions
79 * this one "encourages" compiler to keep intermediate variables in
80 * registers, which should give better "all round" results, in other
81 * words reasonable performance even with not so modern compilers.
82 */
75 83
76#include "camellia.h" 84#include "camellia.h"
77#include "cmll_locl.h" 85#include "cmll_locl.h"
86#include <string.h>
87#include <stdlib.h>
78 88
79/* key constants */ 89/* 32-bit rotations */
80#define CAMELLIA_SIGMA1L (0xA09E667FL) 90#if !defined(PEDANTIC) && !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM)
81#define CAMELLIA_SIGMA1R (0x3BCC908BL) 91# if defined(_MSC_VER) && (defined(_M_IX86) || defined(_M_AMD64) || defined(_M_X64))
82#define CAMELLIA_SIGMA2L (0xB67AE858L) 92# define RightRotate(x, s) _lrotr(x, s)
83#define CAMELLIA_SIGMA2R (0x4CAA73B2L) 93# define LeftRotate(x, s) _lrotl(x, s)
84#define CAMELLIA_SIGMA3L (0xC6EF372FL) 94# if _MSC_VER >= 1400
85#define CAMELLIA_SIGMA3R (0xE94F82BEL) 95# define SWAP(x) _byteswap_ulong(x)
86#define CAMELLIA_SIGMA4L (0x54FF53A5L) 96# else
87#define CAMELLIA_SIGMA4R (0xF1D36F1CL) 97# define SWAP(x) (_lrotl(x, 8) & 0x00ff00ff | _lrotr(x, 8) & 0xff00ff00)
88#define CAMELLIA_SIGMA5L (0x10E527FAL) 98# endif
89#define CAMELLIA_SIGMA5R (0xDE682D1DL) 99# define GETU32(p) SWAP(*((u32 *)(p)))
90#define CAMELLIA_SIGMA6L (0xB05688C2L) 100# define PUTU32(p,v) (*((u32 *)(p)) = SWAP((v)))
91#define CAMELLIA_SIGMA6R (0xB3E6C1FDL) 101# elif defined(__GNUC__) && __GNUC__>=2
92 102# if defined(__i386) || defined(__x86_64)
103# define RightRotate(x,s) ({u32 ret; asm ("rorl %1,%0":"=r"(ret):"I"(s),"0"(x):"cc"); ret; })
104# define LeftRotate(x,s) ({u32 ret; asm ("roll %1,%0":"=r"(ret):"I"(s),"0"(x):"cc"); ret; })
105# if defined(B_ENDIAN) /* stratus.com does it */
106# define GETU32(p) (*(u32 *)(p))
107# define PUTU32(p,v) (*(u32 *)(p)=(v))
108# else
109# define GETU32(p) ({u32 r=*(const u32 *)(p); asm("bswapl %0":"=r"(r):"0"(r)); r; })
110# define PUTU32(p,v) ({u32 r=(v); asm("bswapl %0":"=r"(r):"0"(r)); *(u32 *)(p)=r; })
111# endif
112# elif defined(_ARCH_PPC) || defined(_ARCH_PPC64) || \
113 defined(__powerpc) || defined(__ppc__) || defined(__powerpc64__)
114# define LeftRotate(x,s) ({u32 ret; asm ("rlwinm %0,%1,%2,0,31":"=r"(ret):"r"(x),"I"(s)); ret; })
115# define RightRotate(x,s) LeftRotate(x,(32-s))
116# elif defined(__s390x__)
117# define LeftRotate(x,s) ({u32 ret; asm ("rll %0,%1,%2":"=r"(ret):"r"(x),"I"(s)); ret; })
118# define RightRotate(x,s) LeftRotate(x,(32-s))
119# define GETU32(p) (*(u32 *)(p))
120# define PUTU32(p,v) (*(u32 *)(p)=(v))
121# endif
122# endif
123#endif
124
125#if !defined(RightRotate) && !defined(LeftRotate)
126# define RightRotate(x, s) ( ((x) >> (s)) + ((x) << (32 - s)) )
127# define LeftRotate(x, s) ( ((x) << (s)) + ((x) >> (32 - s)) )
128#endif
129
130#if !defined(GETU32) && !defined(PUTU32)
131# define GETU32(p) (((u32)(p)[0] << 24) ^ ((u32)(p)[1] << 16) ^ ((u32)(p)[2] << 8) ^ ((u32)(p)[3]))
132# define PUTU32(p,v) ((p)[0] = (u8)((v) >> 24), (p)[1] = (u8)((v) >> 16), (p)[2] = (u8)((v) >> 8), (p)[3] = (u8)(v))
133#endif
134
135/* S-box data */
136#define SBOX1_1110 Camellia_SBOX[0]
137#define SBOX4_4404 Camellia_SBOX[1]
138#define SBOX2_0222 Camellia_SBOX[2]
139#define SBOX3_3033 Camellia_SBOX[3]
140static const u32 Camellia_SBOX[][256] = {
141{ 0x70707000, 0x82828200, 0x2c2c2c00, 0xececec00, 0xb3b3b300, 0x27272700,
142 0xc0c0c000, 0xe5e5e500, 0xe4e4e400, 0x85858500, 0x57575700, 0x35353500,
143 0xeaeaea00, 0x0c0c0c00, 0xaeaeae00, 0x41414100, 0x23232300, 0xefefef00,
144 0x6b6b6b00, 0x93939300, 0x45454500, 0x19191900, 0xa5a5a500, 0x21212100,
145 0xededed00, 0x0e0e0e00, 0x4f4f4f00, 0x4e4e4e00, 0x1d1d1d00, 0x65656500,
146 0x92929200, 0xbdbdbd00, 0x86868600, 0xb8b8b800, 0xafafaf00, 0x8f8f8f00,
147 0x7c7c7c00, 0xebebeb00, 0x1f1f1f00, 0xcecece00, 0x3e3e3e00, 0x30303000,
148 0xdcdcdc00, 0x5f5f5f00, 0x5e5e5e00, 0xc5c5c500, 0x0b0b0b00, 0x1a1a1a00,
149 0xa6a6a600, 0xe1e1e100, 0x39393900, 0xcacaca00, 0xd5d5d500, 0x47474700,
150 0x5d5d5d00, 0x3d3d3d00, 0xd9d9d900, 0x01010100, 0x5a5a5a00, 0xd6d6d600,
151 0x51515100, 0x56565600, 0x6c6c6c00, 0x4d4d4d00, 0x8b8b8b00, 0x0d0d0d00,
152 0x9a9a9a00, 0x66666600, 0xfbfbfb00, 0xcccccc00, 0xb0b0b000, 0x2d2d2d00,
153 0x74747400, 0x12121200, 0x2b2b2b00, 0x20202000, 0xf0f0f000, 0xb1b1b100,
154 0x84848400, 0x99999900, 0xdfdfdf00, 0x4c4c4c00, 0xcbcbcb00, 0xc2c2c200,
155 0x34343400, 0x7e7e7e00, 0x76767600, 0x05050500, 0x6d6d6d00, 0xb7b7b700,
156 0xa9a9a900, 0x31313100, 0xd1d1d100, 0x17171700, 0x04040400, 0xd7d7d700,
157 0x14141400, 0x58585800, 0x3a3a3a00, 0x61616100, 0xdedede00, 0x1b1b1b00,
158 0x11111100, 0x1c1c1c00, 0x32323200, 0x0f0f0f00, 0x9c9c9c00, 0x16161600,
159 0x53535300, 0x18181800, 0xf2f2f200, 0x22222200, 0xfefefe00, 0x44444400,
160 0xcfcfcf00, 0xb2b2b200, 0xc3c3c300, 0xb5b5b500, 0x7a7a7a00, 0x91919100,
161 0x24242400, 0x08080800, 0xe8e8e800, 0xa8a8a800, 0x60606000, 0xfcfcfc00,
162 0x69696900, 0x50505000, 0xaaaaaa00, 0xd0d0d000, 0xa0a0a000, 0x7d7d7d00,
163 0xa1a1a100, 0x89898900, 0x62626200, 0x97979700, 0x54545400, 0x5b5b5b00,
164 0x1e1e1e00, 0x95959500, 0xe0e0e000, 0xffffff00, 0x64646400, 0xd2d2d200,
165 0x10101000, 0xc4c4c400, 0x00000000, 0x48484800, 0xa3a3a300, 0xf7f7f700,
166 0x75757500, 0xdbdbdb00, 0x8a8a8a00, 0x03030300, 0xe6e6e600, 0xdadada00,
167 0x09090900, 0x3f3f3f00, 0xdddddd00, 0x94949400, 0x87878700, 0x5c5c5c00,
168 0x83838300, 0x02020200, 0xcdcdcd00, 0x4a4a4a00, 0x90909000, 0x33333300,
169 0x73737300, 0x67676700, 0xf6f6f600, 0xf3f3f300, 0x9d9d9d00, 0x7f7f7f00,
170 0xbfbfbf00, 0xe2e2e200, 0x52525200, 0x9b9b9b00, 0xd8d8d800, 0x26262600,
171 0xc8c8c800, 0x37373700, 0xc6c6c600, 0x3b3b3b00, 0x81818100, 0x96969600,
172 0x6f6f6f00, 0x4b4b4b00, 0x13131300, 0xbebebe00, 0x63636300, 0x2e2e2e00,
173 0xe9e9e900, 0x79797900, 0xa7a7a700, 0x8c8c8c00, 0x9f9f9f00, 0x6e6e6e00,
174 0xbcbcbc00, 0x8e8e8e00, 0x29292900, 0xf5f5f500, 0xf9f9f900, 0xb6b6b600,
175 0x2f2f2f00, 0xfdfdfd00, 0xb4b4b400, 0x59595900, 0x78787800, 0x98989800,
176 0x06060600, 0x6a6a6a00, 0xe7e7e700, 0x46464600, 0x71717100, 0xbababa00,
177 0xd4d4d400, 0x25252500, 0xababab00, 0x42424200, 0x88888800, 0xa2a2a200,
178 0x8d8d8d00, 0xfafafa00, 0x72727200, 0x07070700, 0xb9b9b900, 0x55555500,
179 0xf8f8f800, 0xeeeeee00, 0xacacac00, 0x0a0a0a00, 0x36363600, 0x49494900,
180 0x2a2a2a00, 0x68686800, 0x3c3c3c00, 0x38383800, 0xf1f1f100, 0xa4a4a400,
181 0x40404000, 0x28282800, 0xd3d3d300, 0x7b7b7b00, 0xbbbbbb00, 0xc9c9c900,
182 0x43434300, 0xc1c1c100, 0x15151500, 0xe3e3e300, 0xadadad00, 0xf4f4f400,
183 0x77777700, 0xc7c7c700, 0x80808000, 0x9e9e9e00 },
184{ 0x70700070, 0x2c2c002c, 0xb3b300b3, 0xc0c000c0, 0xe4e400e4, 0x57570057,
185 0xeaea00ea, 0xaeae00ae, 0x23230023, 0x6b6b006b, 0x45450045, 0xa5a500a5,
186 0xeded00ed, 0x4f4f004f, 0x1d1d001d, 0x92920092, 0x86860086, 0xafaf00af,
187 0x7c7c007c, 0x1f1f001f, 0x3e3e003e, 0xdcdc00dc, 0x5e5e005e, 0x0b0b000b,
188 0xa6a600a6, 0x39390039, 0xd5d500d5, 0x5d5d005d, 0xd9d900d9, 0x5a5a005a,
189 0x51510051, 0x6c6c006c, 0x8b8b008b, 0x9a9a009a, 0xfbfb00fb, 0xb0b000b0,
190 0x74740074, 0x2b2b002b, 0xf0f000f0, 0x84840084, 0xdfdf00df, 0xcbcb00cb,
191 0x34340034, 0x76760076, 0x6d6d006d, 0xa9a900a9, 0xd1d100d1, 0x04040004,
192 0x14140014, 0x3a3a003a, 0xdede00de, 0x11110011, 0x32320032, 0x9c9c009c,
193 0x53530053, 0xf2f200f2, 0xfefe00fe, 0xcfcf00cf, 0xc3c300c3, 0x7a7a007a,
194 0x24240024, 0xe8e800e8, 0x60600060, 0x69690069, 0xaaaa00aa, 0xa0a000a0,
195 0xa1a100a1, 0x62620062, 0x54540054, 0x1e1e001e, 0xe0e000e0, 0x64640064,
196 0x10100010, 0x00000000, 0xa3a300a3, 0x75750075, 0x8a8a008a, 0xe6e600e6,
197 0x09090009, 0xdddd00dd, 0x87870087, 0x83830083, 0xcdcd00cd, 0x90900090,
198 0x73730073, 0xf6f600f6, 0x9d9d009d, 0xbfbf00bf, 0x52520052, 0xd8d800d8,
199 0xc8c800c8, 0xc6c600c6, 0x81810081, 0x6f6f006f, 0x13130013, 0x63630063,
200 0xe9e900e9, 0xa7a700a7, 0x9f9f009f, 0xbcbc00bc, 0x29290029, 0xf9f900f9,
201 0x2f2f002f, 0xb4b400b4, 0x78780078, 0x06060006, 0xe7e700e7, 0x71710071,
202 0xd4d400d4, 0xabab00ab, 0x88880088, 0x8d8d008d, 0x72720072, 0xb9b900b9,
203 0xf8f800f8, 0xacac00ac, 0x36360036, 0x2a2a002a, 0x3c3c003c, 0xf1f100f1,
204 0x40400040, 0xd3d300d3, 0xbbbb00bb, 0x43430043, 0x15150015, 0xadad00ad,
205 0x77770077, 0x80800080, 0x82820082, 0xecec00ec, 0x27270027, 0xe5e500e5,
206 0x85850085, 0x35350035, 0x0c0c000c, 0x41410041, 0xefef00ef, 0x93930093,
207 0x19190019, 0x21210021, 0x0e0e000e, 0x4e4e004e, 0x65650065, 0xbdbd00bd,
208 0xb8b800b8, 0x8f8f008f, 0xebeb00eb, 0xcece00ce, 0x30300030, 0x5f5f005f,
209 0xc5c500c5, 0x1a1a001a, 0xe1e100e1, 0xcaca00ca, 0x47470047, 0x3d3d003d,
210 0x01010001, 0xd6d600d6, 0x56560056, 0x4d4d004d, 0x0d0d000d, 0x66660066,
211 0xcccc00cc, 0x2d2d002d, 0x12120012, 0x20200020, 0xb1b100b1, 0x99990099,
212 0x4c4c004c, 0xc2c200c2, 0x7e7e007e, 0x05050005, 0xb7b700b7, 0x31310031,
213 0x17170017, 0xd7d700d7, 0x58580058, 0x61610061, 0x1b1b001b, 0x1c1c001c,
214 0x0f0f000f, 0x16160016, 0x18180018, 0x22220022, 0x44440044, 0xb2b200b2,
215 0xb5b500b5, 0x91910091, 0x08080008, 0xa8a800a8, 0xfcfc00fc, 0x50500050,
216 0xd0d000d0, 0x7d7d007d, 0x89890089, 0x97970097, 0x5b5b005b, 0x95950095,
217 0xffff00ff, 0xd2d200d2, 0xc4c400c4, 0x48480048, 0xf7f700f7, 0xdbdb00db,
218 0x03030003, 0xdada00da, 0x3f3f003f, 0x94940094, 0x5c5c005c, 0x02020002,
219 0x4a4a004a, 0x33330033, 0x67670067, 0xf3f300f3, 0x7f7f007f, 0xe2e200e2,
220 0x9b9b009b, 0x26260026, 0x37370037, 0x3b3b003b, 0x96960096, 0x4b4b004b,
221 0xbebe00be, 0x2e2e002e, 0x79790079, 0x8c8c008c, 0x6e6e006e, 0x8e8e008e,
222 0xf5f500f5, 0xb6b600b6, 0xfdfd00fd, 0x59590059, 0x98980098, 0x6a6a006a,
223 0x46460046, 0xbaba00ba, 0x25250025, 0x42420042, 0xa2a200a2, 0xfafa00fa,
224 0x07070007, 0x55550055, 0xeeee00ee, 0x0a0a000a, 0x49490049, 0x68680068,
225 0x38380038, 0xa4a400a4, 0x28280028, 0x7b7b007b, 0xc9c900c9, 0xc1c100c1,
226 0xe3e300e3, 0xf4f400f4, 0xc7c700c7, 0x9e9e009e },
227{ 0x00e0e0e0, 0x00050505, 0x00585858, 0x00d9d9d9, 0x00676767, 0x004e4e4e,
228 0x00818181, 0x00cbcbcb, 0x00c9c9c9, 0x000b0b0b, 0x00aeaeae, 0x006a6a6a,
229 0x00d5d5d5, 0x00181818, 0x005d5d5d, 0x00828282, 0x00464646, 0x00dfdfdf,
230 0x00d6d6d6, 0x00272727, 0x008a8a8a, 0x00323232, 0x004b4b4b, 0x00424242,
231 0x00dbdbdb, 0x001c1c1c, 0x009e9e9e, 0x009c9c9c, 0x003a3a3a, 0x00cacaca,
232 0x00252525, 0x007b7b7b, 0x000d0d0d, 0x00717171, 0x005f5f5f, 0x001f1f1f,
233 0x00f8f8f8, 0x00d7d7d7, 0x003e3e3e, 0x009d9d9d, 0x007c7c7c, 0x00606060,
234 0x00b9b9b9, 0x00bebebe, 0x00bcbcbc, 0x008b8b8b, 0x00161616, 0x00343434,
235 0x004d4d4d, 0x00c3c3c3, 0x00727272, 0x00959595, 0x00ababab, 0x008e8e8e,
236 0x00bababa, 0x007a7a7a, 0x00b3b3b3, 0x00020202, 0x00b4b4b4, 0x00adadad,
237 0x00a2a2a2, 0x00acacac, 0x00d8d8d8, 0x009a9a9a, 0x00171717, 0x001a1a1a,
238 0x00353535, 0x00cccccc, 0x00f7f7f7, 0x00999999, 0x00616161, 0x005a5a5a,
239 0x00e8e8e8, 0x00242424, 0x00565656, 0x00404040, 0x00e1e1e1, 0x00636363,
240 0x00090909, 0x00333333, 0x00bfbfbf, 0x00989898, 0x00979797, 0x00858585,
241 0x00686868, 0x00fcfcfc, 0x00ececec, 0x000a0a0a, 0x00dadada, 0x006f6f6f,
242 0x00535353, 0x00626262, 0x00a3a3a3, 0x002e2e2e, 0x00080808, 0x00afafaf,
243 0x00282828, 0x00b0b0b0, 0x00747474, 0x00c2c2c2, 0x00bdbdbd, 0x00363636,
244 0x00222222, 0x00383838, 0x00646464, 0x001e1e1e, 0x00393939, 0x002c2c2c,
245 0x00a6a6a6, 0x00303030, 0x00e5e5e5, 0x00444444, 0x00fdfdfd, 0x00888888,
246 0x009f9f9f, 0x00656565, 0x00878787, 0x006b6b6b, 0x00f4f4f4, 0x00232323,
247 0x00484848, 0x00101010, 0x00d1d1d1, 0x00515151, 0x00c0c0c0, 0x00f9f9f9,
248 0x00d2d2d2, 0x00a0a0a0, 0x00555555, 0x00a1a1a1, 0x00414141, 0x00fafafa,
249 0x00434343, 0x00131313, 0x00c4c4c4, 0x002f2f2f, 0x00a8a8a8, 0x00b6b6b6,
250 0x003c3c3c, 0x002b2b2b, 0x00c1c1c1, 0x00ffffff, 0x00c8c8c8, 0x00a5a5a5,
251 0x00202020, 0x00898989, 0x00000000, 0x00909090, 0x00474747, 0x00efefef,
252 0x00eaeaea, 0x00b7b7b7, 0x00151515, 0x00060606, 0x00cdcdcd, 0x00b5b5b5,
253 0x00121212, 0x007e7e7e, 0x00bbbbbb, 0x00292929, 0x000f0f0f, 0x00b8b8b8,
254 0x00070707, 0x00040404, 0x009b9b9b, 0x00949494, 0x00212121, 0x00666666,
255 0x00e6e6e6, 0x00cecece, 0x00ededed, 0x00e7e7e7, 0x003b3b3b, 0x00fefefe,
256 0x007f7f7f, 0x00c5c5c5, 0x00a4a4a4, 0x00373737, 0x00b1b1b1, 0x004c4c4c,
257 0x00919191, 0x006e6e6e, 0x008d8d8d, 0x00767676, 0x00030303, 0x002d2d2d,
258 0x00dedede, 0x00969696, 0x00262626, 0x007d7d7d, 0x00c6c6c6, 0x005c5c5c,
259 0x00d3d3d3, 0x00f2f2f2, 0x004f4f4f, 0x00191919, 0x003f3f3f, 0x00dcdcdc,
260 0x00797979, 0x001d1d1d, 0x00525252, 0x00ebebeb, 0x00f3f3f3, 0x006d6d6d,
261 0x005e5e5e, 0x00fbfbfb, 0x00696969, 0x00b2b2b2, 0x00f0f0f0, 0x00313131,
262 0x000c0c0c, 0x00d4d4d4, 0x00cfcfcf, 0x008c8c8c, 0x00e2e2e2, 0x00757575,
263 0x00a9a9a9, 0x004a4a4a, 0x00575757, 0x00848484, 0x00111111, 0x00454545,
264 0x001b1b1b, 0x00f5f5f5, 0x00e4e4e4, 0x000e0e0e, 0x00737373, 0x00aaaaaa,
265 0x00f1f1f1, 0x00dddddd, 0x00595959, 0x00141414, 0x006c6c6c, 0x00929292,
266 0x00545454, 0x00d0d0d0, 0x00787878, 0x00707070, 0x00e3e3e3, 0x00494949,
267 0x00808080, 0x00505050, 0x00a7a7a7, 0x00f6f6f6, 0x00777777, 0x00939393,
268 0x00868686, 0x00838383, 0x002a2a2a, 0x00c7c7c7, 0x005b5b5b, 0x00e9e9e9,
269 0x00eeeeee, 0x008f8f8f, 0x00010101, 0x003d3d3d },
270{ 0x38003838, 0x41004141, 0x16001616, 0x76007676, 0xd900d9d9, 0x93009393,
271 0x60006060, 0xf200f2f2, 0x72007272, 0xc200c2c2, 0xab00abab, 0x9a009a9a,
272 0x75007575, 0x06000606, 0x57005757, 0xa000a0a0, 0x91009191, 0xf700f7f7,
273 0xb500b5b5, 0xc900c9c9, 0xa200a2a2, 0x8c008c8c, 0xd200d2d2, 0x90009090,
274 0xf600f6f6, 0x07000707, 0xa700a7a7, 0x27002727, 0x8e008e8e, 0xb200b2b2,
275 0x49004949, 0xde00dede, 0x43004343, 0x5c005c5c, 0xd700d7d7, 0xc700c7c7,
276 0x3e003e3e, 0xf500f5f5, 0x8f008f8f, 0x67006767, 0x1f001f1f, 0x18001818,
277 0x6e006e6e, 0xaf00afaf, 0x2f002f2f, 0xe200e2e2, 0x85008585, 0x0d000d0d,
278 0x53005353, 0xf000f0f0, 0x9c009c9c, 0x65006565, 0xea00eaea, 0xa300a3a3,
279 0xae00aeae, 0x9e009e9e, 0xec00ecec, 0x80008080, 0x2d002d2d, 0x6b006b6b,
280 0xa800a8a8, 0x2b002b2b, 0x36003636, 0xa600a6a6, 0xc500c5c5, 0x86008686,
281 0x4d004d4d, 0x33003333, 0xfd00fdfd, 0x66006666, 0x58005858, 0x96009696,
282 0x3a003a3a, 0x09000909, 0x95009595, 0x10001010, 0x78007878, 0xd800d8d8,
283 0x42004242, 0xcc00cccc, 0xef00efef, 0x26002626, 0xe500e5e5, 0x61006161,
284 0x1a001a1a, 0x3f003f3f, 0x3b003b3b, 0x82008282, 0xb600b6b6, 0xdb00dbdb,
285 0xd400d4d4, 0x98009898, 0xe800e8e8, 0x8b008b8b, 0x02000202, 0xeb00ebeb,
286 0x0a000a0a, 0x2c002c2c, 0x1d001d1d, 0xb000b0b0, 0x6f006f6f, 0x8d008d8d,
287 0x88008888, 0x0e000e0e, 0x19001919, 0x87008787, 0x4e004e4e, 0x0b000b0b,
288 0xa900a9a9, 0x0c000c0c, 0x79007979, 0x11001111, 0x7f007f7f, 0x22002222,
289 0xe700e7e7, 0x59005959, 0xe100e1e1, 0xda00dada, 0x3d003d3d, 0xc800c8c8,
290 0x12001212, 0x04000404, 0x74007474, 0x54005454, 0x30003030, 0x7e007e7e,
291 0xb400b4b4, 0x28002828, 0x55005555, 0x68006868, 0x50005050, 0xbe00bebe,
292 0xd000d0d0, 0xc400c4c4, 0x31003131, 0xcb00cbcb, 0x2a002a2a, 0xad00adad,
293 0x0f000f0f, 0xca00caca, 0x70007070, 0xff00ffff, 0x32003232, 0x69006969,
294 0x08000808, 0x62006262, 0x00000000, 0x24002424, 0xd100d1d1, 0xfb00fbfb,
295 0xba00baba, 0xed00eded, 0x45004545, 0x81008181, 0x73007373, 0x6d006d6d,
296 0x84008484, 0x9f009f9f, 0xee00eeee, 0x4a004a4a, 0xc300c3c3, 0x2e002e2e,
297 0xc100c1c1, 0x01000101, 0xe600e6e6, 0x25002525, 0x48004848, 0x99009999,
298 0xb900b9b9, 0xb300b3b3, 0x7b007b7b, 0xf900f9f9, 0xce00cece, 0xbf00bfbf,
299 0xdf00dfdf, 0x71007171, 0x29002929, 0xcd00cdcd, 0x6c006c6c, 0x13001313,
300 0x64006464, 0x9b009b9b, 0x63006363, 0x9d009d9d, 0xc000c0c0, 0x4b004b4b,
301 0xb700b7b7, 0xa500a5a5, 0x89008989, 0x5f005f5f, 0xb100b1b1, 0x17001717,
302 0xf400f4f4, 0xbc00bcbc, 0xd300d3d3, 0x46004646, 0xcf00cfcf, 0x37003737,
303 0x5e005e5e, 0x47004747, 0x94009494, 0xfa00fafa, 0xfc00fcfc, 0x5b005b5b,
304 0x97009797, 0xfe00fefe, 0x5a005a5a, 0xac00acac, 0x3c003c3c, 0x4c004c4c,
305 0x03000303, 0x35003535, 0xf300f3f3, 0x23002323, 0xb800b8b8, 0x5d005d5d,
306 0x6a006a6a, 0x92009292, 0xd500d5d5, 0x21002121, 0x44004444, 0x51005151,
307 0xc600c6c6, 0x7d007d7d, 0x39003939, 0x83008383, 0xdc00dcdc, 0xaa00aaaa,
308 0x7c007c7c, 0x77007777, 0x56005656, 0x05000505, 0x1b001b1b, 0xa400a4a4,
309 0x15001515, 0x34003434, 0x1e001e1e, 0x1c001c1c, 0xf800f8f8, 0x52005252,
310 0x20002020, 0x14001414, 0xe900e9e9, 0xbd00bdbd, 0xdd00dddd, 0xe400e4e4,
311 0xa100a1a1, 0xe000e0e0, 0x8a008a8a, 0xf100f1f1, 0xd600d6d6, 0x7a007a7a,
312 0xbb00bbbb, 0xe300e3e3, 0x40004040, 0x4f004f4f }
313};
314
315/* Key generation constants */
316static const u32 SIGMA[] = {
317 0xa09e667f, 0x3bcc908b, 0xb67ae858, 0x4caa73b2, 0xc6ef372f, 0xe94f82be,
318 0x54ff53a5, 0xf1d36f1c, 0x10e527fa, 0xde682d1d, 0xb05688c2, 0xb3e6c1fd
319};
320
321/* The phi algorithm given in C.2.7 of the Camellia spec document. */
93/* 322/*
94 * macros 323 * This version does not attempt to minimize amount of temporary
324 * variables, but instead explicitly exposes algorithm's parallelism.
325 * It is therefore most appropriate for platforms with not less than
326 * ~16 registers. For platforms with less registers [well, x86 to be
327 * specific] assembler version should be/is provided anyway...
95 */ 328 */
96 329#define Camellia_Feistel(_s0,_s1,_s2,_s3,_key) do {\
97/* e is pointer of subkey */ 330 register u32 _t0,_t1,_t2,_t3;\
98#define CamelliaSubkeyL(INDEX) (subkey[(INDEX)*2]) 331\
99#define CamelliaSubkeyR(INDEX) (subkey[(INDEX)*2 + 1]) 332 _t0 = _s0 ^ (_key)[0];\
100 333 _t3 = SBOX4_4404[_t0&0xff];\
101/* rotation right shift 1byte */ 334 _t1 = _s1 ^ (_key)[1];\
102#define CAMELLIA_RR8(x) (((x) >> 8) + ((x) << 24)) 335 _t3 ^= SBOX3_3033[(_t0 >> 8)&0xff];\
103/* rotation left shift 1bit */ 336 _t2 = SBOX1_1110[_t1&0xff];\
104#define CAMELLIA_RL1(x) (((x) << 1) + ((x) >> 31)) 337 _t3 ^= SBOX2_0222[(_t0 >> 16)&0xff];\
105/* rotation left shift 1byte */ 338 _t2 ^= SBOX4_4404[(_t1 >> 8)&0xff];\
106#define CAMELLIA_RL8(x) (((x) << 8) + ((x) >> 24)) 339 _t3 ^= SBOX1_1110[(_t0 >> 24)];\
107 340 _t2 ^= _t3;\
108#define CAMELLIA_ROLDQ(ll, lr, rl, rr, w0, w1, bits) \ 341 _t3 = RightRotate(_t3,8);\
109do \ 342 _t2 ^= SBOX3_3033[(_t1 >> 16)&0xff];\
110 { \ 343 _s3 ^= _t3;\
111 w0 = ll; \ 344 _t2 ^= SBOX2_0222[(_t1 >> 24)];\
112 ll = (ll << bits) + (lr >> (32 - bits)); \ 345 _s2 ^= _t2; \
113 lr = (lr << bits) + (rl >> (32 - bits)); \ 346 _s3 ^= _t2;\
114 rl = (rl << bits) + (rr >> (32 - bits)); \ 347} while(0)
115 rr = (rr << bits) + (w0 >> (32 - bits)); \
116 } while(0)
117
118#define CAMELLIA_ROLDQo32(ll, lr, rl, rr, w0, w1, bits) \
119do \
120 { \
121 w0 = ll; \
122 w1 = lr; \
123 ll = (lr << (bits - 32)) + (rl >> (64 - bits)); \
124 lr = (rl << (bits - 32)) + (rr >> (64 - bits)); \
125 rl = (rr << (bits - 32)) + (w0 >> (64 - bits)); \
126 rr = (w0 << (bits - 32)) + (w1 >> (64 - bits)); \
127 } while(0)
128
129#define CAMELLIA_SP1110(INDEX) (camellia_sp1110[(INDEX)])
130#define CAMELLIA_SP0222(INDEX) (camellia_sp0222[(INDEX)])
131#define CAMELLIA_SP3033(INDEX) (camellia_sp3033[(INDEX)])
132#define CAMELLIA_SP4404(INDEX) (camellia_sp4404[(INDEX)])
133
134#define CAMELLIA_F(xl, xr, kl, kr, yl, yr, il, ir, t0, t1) \
135do \
136 { \
137 il = xl ^ kl; \
138 ir = xr ^ kr; \
139 t0 = il >> 16; \
140 t1 = ir >> 16; \
141 yl = CAMELLIA_SP1110(ir & 0xff) \
142 ^ CAMELLIA_SP0222((t1 >> 8) & 0xff) \
143 ^ CAMELLIA_SP3033(t1 & 0xff) \
144 ^ CAMELLIA_SP4404((ir >> 8) & 0xff); \
145 yr = CAMELLIA_SP1110((t0 >> 8) & 0xff) \
146 ^ CAMELLIA_SP0222(t0 & 0xff) \
147 ^ CAMELLIA_SP3033((il >> 8) & 0xff) \
148 ^ CAMELLIA_SP4404(il & 0xff); \
149 yl ^= yr; \
150 yr = CAMELLIA_RR8(yr); \
151 yr ^= yl; \
152 } while(0)
153
154 348
155/* 349/*
156 * for speed up 350 * Note that n has to be less than 32. Rotations for larger amount
157 * 351 * of bits are achieved by "rotating" order of s-elements and
352 * adjusting n accordingly, e.g. RotLeft128(s1,s2,s3,s0,n-32).
158 */ 353 */
159#define CAMELLIA_FLS(ll, lr, rl, rr, kll, klr, krl, krr, t0, t1, t2, t3) \ 354#define RotLeft128(_s0,_s1,_s2,_s3,_n) do {\
160do \ 355 u32 _t0=_s0>>(32-_n);\
161 { \ 356 _s0 = (_s0<<_n) | (_s1>>(32-_n));\
162 t0 = kll; \ 357 _s1 = (_s1<<_n) | (_s2>>(32-_n));\
163 t0 &= ll; \ 358 _s2 = (_s2<<_n) | (_s3>>(32-_n));\
164 lr ^= CAMELLIA_RL1(t0); \ 359 _s3 = (_s3<<_n) | _t0;\
165 t1 = klr; \ 360} while (0)
166 t1 |= lr; \ 361
167 ll ^= t1; \ 362int Camellia_Ekeygen(int keyBitLength, const u8 *rawKey, KEY_TABLE_TYPE k)
168 \
169 t2 = krr; \
170 t2 |= rr; \
171 rl ^= t2; \
172 t3 = krl; \
173 t3 &= rl; \
174 rr ^= CAMELLIA_RL1(t3); \
175 } while(0)
176
177#define CAMELLIA_ROUNDSM(xl, xr, kl, kr, yl, yr, il, ir, t0, t1) \
178do \
179 { \
180 il = xl; \
181 ir = xr; \
182 t0 = il >> 16; \
183 t1 = ir >> 16; \
184 ir = CAMELLIA_SP1110(ir & 0xff) \
185 ^ CAMELLIA_SP0222((t1 >> 8) & 0xff) \
186 ^ CAMELLIA_SP3033(t1 & 0xff) \
187 ^ CAMELLIA_SP4404((ir >> 8) & 0xff); \
188 il = CAMELLIA_SP1110((t0 >> 8) & 0xff) \
189 ^ CAMELLIA_SP0222(t0 & 0xff) \
190 ^ CAMELLIA_SP3033((il >> 8) & 0xff) \
191 ^ CAMELLIA_SP4404(il & 0xff); \
192 il ^= kl; \
193 ir ^= kr; \
194 ir ^= il; \
195 il = CAMELLIA_RR8(il); \
196 il ^= ir; \
197 yl ^= ir; \
198 yr ^= il; \
199 } while(0)
200
201static const u32 camellia_sp1110[256] =
202 {
203 0x70707000,0x82828200,0x2c2c2c00,0xececec00,
204 0xb3b3b300,0x27272700,0xc0c0c000,0xe5e5e500,
205 0xe4e4e400,0x85858500,0x57575700,0x35353500,
206 0xeaeaea00,0x0c0c0c00,0xaeaeae00,0x41414100,
207 0x23232300,0xefefef00,0x6b6b6b00,0x93939300,
208 0x45454500,0x19191900,0xa5a5a500,0x21212100,
209 0xededed00,0x0e0e0e00,0x4f4f4f00,0x4e4e4e00,
210 0x1d1d1d00,0x65656500,0x92929200,0xbdbdbd00,
211 0x86868600,0xb8b8b800,0xafafaf00,0x8f8f8f00,
212 0x7c7c7c00,0xebebeb00,0x1f1f1f00,0xcecece00,
213 0x3e3e3e00,0x30303000,0xdcdcdc00,0x5f5f5f00,
214 0x5e5e5e00,0xc5c5c500,0x0b0b0b00,0x1a1a1a00,
215 0xa6a6a600,0xe1e1e100,0x39393900,0xcacaca00,
216 0xd5d5d500,0x47474700,0x5d5d5d00,0x3d3d3d00,
217 0xd9d9d900,0x01010100,0x5a5a5a00,0xd6d6d600,
218 0x51515100,0x56565600,0x6c6c6c00,0x4d4d4d00,
219 0x8b8b8b00,0x0d0d0d00,0x9a9a9a00,0x66666600,
220 0xfbfbfb00,0xcccccc00,0xb0b0b000,0x2d2d2d00,
221 0x74747400,0x12121200,0x2b2b2b00,0x20202000,
222 0xf0f0f000,0xb1b1b100,0x84848400,0x99999900,
223 0xdfdfdf00,0x4c4c4c00,0xcbcbcb00,0xc2c2c200,
224 0x34343400,0x7e7e7e00,0x76767600,0x05050500,
225 0x6d6d6d00,0xb7b7b700,0xa9a9a900,0x31313100,
226 0xd1d1d100,0x17171700,0x04040400,0xd7d7d700,
227 0x14141400,0x58585800,0x3a3a3a00,0x61616100,
228 0xdedede00,0x1b1b1b00,0x11111100,0x1c1c1c00,
229 0x32323200,0x0f0f0f00,0x9c9c9c00,0x16161600,
230 0x53535300,0x18181800,0xf2f2f200,0x22222200,
231 0xfefefe00,0x44444400,0xcfcfcf00,0xb2b2b200,
232 0xc3c3c300,0xb5b5b500,0x7a7a7a00,0x91919100,
233 0x24242400,0x08080800,0xe8e8e800,0xa8a8a800,
234 0x60606000,0xfcfcfc00,0x69696900,0x50505000,
235 0xaaaaaa00,0xd0d0d000,0xa0a0a000,0x7d7d7d00,
236 0xa1a1a100,0x89898900,0x62626200,0x97979700,
237 0x54545400,0x5b5b5b00,0x1e1e1e00,0x95959500,
238 0xe0e0e000,0xffffff00,0x64646400,0xd2d2d200,
239 0x10101000,0xc4c4c400,0x00000000,0x48484800,
240 0xa3a3a300,0xf7f7f700,0x75757500,0xdbdbdb00,
241 0x8a8a8a00,0x03030300,0xe6e6e600,0xdadada00,
242 0x09090900,0x3f3f3f00,0xdddddd00,0x94949400,
243 0x87878700,0x5c5c5c00,0x83838300,0x02020200,
244 0xcdcdcd00,0x4a4a4a00,0x90909000,0x33333300,
245 0x73737300,0x67676700,0xf6f6f600,0xf3f3f300,
246 0x9d9d9d00,0x7f7f7f00,0xbfbfbf00,0xe2e2e200,
247 0x52525200,0x9b9b9b00,0xd8d8d800,0x26262600,
248 0xc8c8c800,0x37373700,0xc6c6c600,0x3b3b3b00,
249 0x81818100,0x96969600,0x6f6f6f00,0x4b4b4b00,
250 0x13131300,0xbebebe00,0x63636300,0x2e2e2e00,
251 0xe9e9e900,0x79797900,0xa7a7a700,0x8c8c8c00,
252 0x9f9f9f00,0x6e6e6e00,0xbcbcbc00,0x8e8e8e00,
253 0x29292900,0xf5f5f500,0xf9f9f900,0xb6b6b600,
254 0x2f2f2f00,0xfdfdfd00,0xb4b4b400,0x59595900,
255 0x78787800,0x98989800,0x06060600,0x6a6a6a00,
256 0xe7e7e700,0x46464600,0x71717100,0xbababa00,
257 0xd4d4d400,0x25252500,0xababab00,0x42424200,
258 0x88888800,0xa2a2a200,0x8d8d8d00,0xfafafa00,
259 0x72727200,0x07070700,0xb9b9b900,0x55555500,
260 0xf8f8f800,0xeeeeee00,0xacacac00,0x0a0a0a00,
261 0x36363600,0x49494900,0x2a2a2a00,0x68686800,
262 0x3c3c3c00,0x38383800,0xf1f1f100,0xa4a4a400,
263 0x40404000,0x28282800,0xd3d3d300,0x7b7b7b00,
264 0xbbbbbb00,0xc9c9c900,0x43434300,0xc1c1c100,
265 0x15151500,0xe3e3e300,0xadadad00,0xf4f4f400,
266 0x77777700,0xc7c7c700,0x80808000,0x9e9e9e00,
267 };
268
269static const u32 camellia_sp0222[256] =
270 { 363 {
271 0x00e0e0e0,0x00050505,0x00585858,0x00d9d9d9, 364 register u32 s0,s1,s2,s3;
272 0x00676767,0x004e4e4e,0x00818181,0x00cbcbcb, 365
273 0x00c9c9c9,0x000b0b0b,0x00aeaeae,0x006a6a6a, 366 k[0] = s0 = GETU32(rawKey);
274 0x00d5d5d5,0x00181818,0x005d5d5d,0x00828282, 367 k[1] = s1 = GETU32(rawKey+4);
275 0x00464646,0x00dfdfdf,0x00d6d6d6,0x00272727, 368 k[2] = s2 = GETU32(rawKey+8);
276 0x008a8a8a,0x00323232,0x004b4b4b,0x00424242, 369 k[3] = s3 = GETU32(rawKey+12);
277 0x00dbdbdb,0x001c1c1c,0x009e9e9e,0x009c9c9c, 370
278 0x003a3a3a,0x00cacaca,0x00252525,0x007b7b7b, 371 if (keyBitLength != 128)
279 0x000d0d0d,0x00717171,0x005f5f5f,0x001f1f1f, 372 {
280 0x00f8f8f8,0x00d7d7d7,0x003e3e3e,0x009d9d9d, 373 k[8] = s0 = GETU32(rawKey+16);
281 0x007c7c7c,0x00606060,0x00b9b9b9,0x00bebebe, 374 k[9] = s1 = GETU32(rawKey+20);
282 0x00bcbcbc,0x008b8b8b,0x00161616,0x00343434, 375 if (keyBitLength == 192)
283 0x004d4d4d,0x00c3c3c3,0x00727272,0x00959595, 376 {
284 0x00ababab,0x008e8e8e,0x00bababa,0x007a7a7a, 377 k[10] = s2 = ~s0;
285 0x00b3b3b3,0x00020202,0x00b4b4b4,0x00adadad, 378 k[11] = s3 = ~s1;
286 0x00a2a2a2,0x00acacac,0x00d8d8d8,0x009a9a9a, 379 }
287 0x00171717,0x001a1a1a,0x00353535,0x00cccccc, 380 else
288 0x00f7f7f7,0x00999999,0x00616161,0x005a5a5a, 381 {
289 0x00e8e8e8,0x00242424,0x00565656,0x00404040, 382 k[10] = s2 = GETU32(rawKey+24);
290 0x00e1e1e1,0x00636363,0x00090909,0x00333333, 383 k[11] = s3 = GETU32(rawKey+28);
291 0x00bfbfbf,0x00989898,0x00979797,0x00858585, 384 }
292 0x00686868,0x00fcfcfc,0x00ececec,0x000a0a0a, 385 s0 ^= k[0], s1 ^= k[1], s2 ^= k[2], s3 ^= k[3];
293 0x00dadada,0x006f6f6f,0x00535353,0x00626262, 386 }
294 0x00a3a3a3,0x002e2e2e,0x00080808,0x00afafaf, 387
295 0x00282828,0x00b0b0b0,0x00747474,0x00c2c2c2, 388 /* Use the Feistel routine to scramble the key material */
296 0x00bdbdbd,0x00363636,0x00222222,0x00383838, 389 Camellia_Feistel(s0,s1,s2,s3,SIGMA+0);
297 0x00646464,0x001e1e1e,0x00393939,0x002c2c2c, 390 Camellia_Feistel(s2,s3,s0,s1,SIGMA+2);
298 0x00a6a6a6,0x00303030,0x00e5e5e5,0x00444444, 391
299 0x00fdfdfd,0x00888888,0x009f9f9f,0x00656565, 392 s0 ^= k[0], s1 ^= k[1], s2 ^= k[2], s3 ^= k[3];
300 0x00878787,0x006b6b6b,0x00f4f4f4,0x00232323, 393 Camellia_Feistel(s0,s1,s2,s3,SIGMA+4);
301 0x00484848,0x00101010,0x00d1d1d1,0x00515151, 394 Camellia_Feistel(s2,s3,s0,s1,SIGMA+6);
302 0x00c0c0c0,0x00f9f9f9,0x00d2d2d2,0x00a0a0a0, 395
303 0x00555555,0x00a1a1a1,0x00414141,0x00fafafa, 396 /* Fill the keyTable. Requires many block rotations. */
304 0x00434343,0x00131313,0x00c4c4c4,0x002f2f2f, 397 if (keyBitLength == 128)
305 0x00a8a8a8,0x00b6b6b6,0x003c3c3c,0x002b2b2b, 398 {
306 0x00c1c1c1,0x00ffffff,0x00c8c8c8,0x00a5a5a5, 399 k[ 4] = s0, k[ 5] = s1, k[ 6] = s2, k[ 7] = s3;
307 0x00202020,0x00898989,0x00000000,0x00909090, 400 RotLeft128(s0,s1,s2,s3,15); /* KA <<< 15 */
308 0x00474747,0x00efefef,0x00eaeaea,0x00b7b7b7, 401 k[12] = s0, k[13] = s1, k[14] = s2, k[15] = s3;
309 0x00151515,0x00060606,0x00cdcdcd,0x00b5b5b5, 402 RotLeft128(s0,s1,s2,s3,15); /* KA <<< 30 */
310 0x00121212,0x007e7e7e,0x00bbbbbb,0x00292929, 403 k[16] = s0, k[17] = s1, k[18] = s2, k[19] = s3;
311 0x000f0f0f,0x00b8b8b8,0x00070707,0x00040404, 404 RotLeft128(s0,s1,s2,s3,15); /* KA <<< 45 */
312 0x009b9b9b,0x00949494,0x00212121,0x00666666, 405 k[24] = s0, k[25] = s1;
313 0x00e6e6e6,0x00cecece,0x00ededed,0x00e7e7e7, 406 RotLeft128(s0,s1,s2,s3,15); /* KA <<< 60 */
314 0x003b3b3b,0x00fefefe,0x007f7f7f,0x00c5c5c5, 407 k[28] = s0, k[29] = s1, k[30] = s2, k[31] = s3;
315 0x00a4a4a4,0x00373737,0x00b1b1b1,0x004c4c4c, 408 RotLeft128(s1,s2,s3,s0,2); /* KA <<< 94 */
316 0x00919191,0x006e6e6e,0x008d8d8d,0x00767676, 409 k[40] = s1, k[41] = s2, k[42] = s3, k[43] = s0;
317 0x00030303,0x002d2d2d,0x00dedede,0x00969696, 410 RotLeft128(s1,s2,s3,s0,17); /* KA <<<111 */
318 0x00262626,0x007d7d7d,0x00c6c6c6,0x005c5c5c, 411 k[48] = s1, k[49] = s2, k[50] = s3, k[51] = s0;
319 0x00d3d3d3,0x00f2f2f2,0x004f4f4f,0x00191919, 412
320 0x003f3f3f,0x00dcdcdc,0x00797979,0x001d1d1d, 413 s0 = k[ 0], s1 = k[ 1], s2 = k[ 2], s3 = k[ 3];
321 0x00525252,0x00ebebeb,0x00f3f3f3,0x006d6d6d, 414 RotLeft128(s0,s1,s2,s3,15); /* KL <<< 15 */
322 0x005e5e5e,0x00fbfbfb,0x00696969,0x00b2b2b2, 415 k[ 8] = s0, k[ 9] = s1, k[10] = s2, k[11] = s3;
323 0x00f0f0f0,0x00313131,0x000c0c0c,0x00d4d4d4, 416 RotLeft128(s0,s1,s2,s3,30); /* KL <<< 45 */
324 0x00cfcfcf,0x008c8c8c,0x00e2e2e2,0x00757575, 417 k[20] = s0, k[21] = s1, k[22] = s2, k[23] = s3;
325 0x00a9a9a9,0x004a4a4a,0x00575757,0x00848484, 418 RotLeft128(s0,s1,s2,s3,15); /* KL <<< 60 */
326 0x00111111,0x00454545,0x001b1b1b,0x00f5f5f5, 419 k[26] = s2, k[27] = s3;
327 0x00e4e4e4,0x000e0e0e,0x00737373,0x00aaaaaa, 420 RotLeft128(s0,s1,s2,s3,17); /* KL <<< 77 */
328 0x00f1f1f1,0x00dddddd,0x00595959,0x00141414, 421 k[32] = s0, k[33] = s1, k[34] = s2, k[35] = s3;
329 0x006c6c6c,0x00929292,0x00545454,0x00d0d0d0, 422 RotLeft128(s0,s1,s2,s3,17); /* KL <<< 94 */
330 0x00787878,0x00707070,0x00e3e3e3,0x00494949, 423 k[36] = s0, k[37] = s1, k[38] = s2, k[39] = s3;
331 0x00808080,0x00505050,0x00a7a7a7,0x00f6f6f6, 424 RotLeft128(s0,s1,s2,s3,17); /* KL <<<111 */
332 0x00777777,0x00939393,0x00868686,0x00838383, 425 k[44] = s0, k[45] = s1, k[46] = s2, k[47] = s3;
333 0x002a2a2a,0x00c7c7c7,0x005b5b5b,0x00e9e9e9, 426
334 0x00eeeeee,0x008f8f8f,0x00010101,0x003d3d3d, 427 return 3; /* grand rounds */
335 }; 428 }
336 429 else
337static const u32 camellia_sp3033[256] = 430 {
338 { 431 k[12] = s0, k[13] = s1, k[14] = s2, k[15] = s3;
339 0x38003838,0x41004141,0x16001616,0x76007676, 432 s0 ^= k[8], s1 ^= k[9], s2 ^=k[10], s3 ^=k[11];
340 0xd900d9d9,0x93009393,0x60006060,0xf200f2f2, 433 Camellia_Feistel(s0,s1,s2,s3,(SIGMA+8));
341 0x72007272,0xc200c2c2,0xab00abab,0x9a009a9a, 434 Camellia_Feistel(s2,s3,s0,s1,(SIGMA+10));
342 0x75007575,0x06000606,0x57005757,0xa000a0a0, 435
343 0x91009191,0xf700f7f7,0xb500b5b5,0xc900c9c9, 436 k[ 4] = s0, k[ 5] = s1, k[ 6] = s2, k[ 7] = s3;
344 0xa200a2a2,0x8c008c8c,0xd200d2d2,0x90009090, 437 RotLeft128(s0,s1,s2,s3,30); /* KB <<< 30 */
345 0xf600f6f6,0x07000707,0xa700a7a7,0x27002727, 438 k[20] = s0, k[21] = s1, k[22] = s2, k[23] = s3;
346 0x8e008e8e,0xb200b2b2,0x49004949,0xde00dede, 439 RotLeft128(s0,s1,s2,s3,30); /* KB <<< 60 */
347 0x43004343,0x5c005c5c,0xd700d7d7,0xc700c7c7, 440 k[40] = s0, k[41] = s1, k[42] = s2, k[43] = s3;
348 0x3e003e3e,0xf500f5f5,0x8f008f8f,0x67006767, 441 RotLeft128(s1,s2,s3,s0,19); /* KB <<<111 */
349 0x1f001f1f,0x18001818,0x6e006e6e,0xaf00afaf, 442 k[64] = s1, k[65] = s2, k[66] = s3, k[67] = s0;
350 0x2f002f2f,0xe200e2e2,0x85008585,0x0d000d0d, 443
351 0x53005353,0xf000f0f0,0x9c009c9c,0x65006565, 444 s0 = k[ 8], s1 = k[ 9], s2 = k[10], s3 = k[11];
352 0xea00eaea,0xa300a3a3,0xae00aeae,0x9e009e9e, 445 RotLeft128(s0,s1,s2,s3,15); /* KR <<< 15 */
353 0xec00ecec,0x80008080,0x2d002d2d,0x6b006b6b, 446 k[ 8] = s0, k[ 9] = s1, k[10] = s2, k[11] = s3;
354 0xa800a8a8,0x2b002b2b,0x36003636,0xa600a6a6, 447 RotLeft128(s0,s1,s2,s3,15); /* KR <<< 30 */
355 0xc500c5c5,0x86008686,0x4d004d4d,0x33003333, 448 k[16] = s0, k[17] = s1, k[18] = s2, k[19] = s3;
356 0xfd00fdfd,0x66006666,0x58005858,0x96009696, 449 RotLeft128(s0,s1,s2,s3,30); /* KR <<< 60 */
357 0x3a003a3a,0x09000909,0x95009595,0x10001010, 450 k[36] = s0, k[37] = s1, k[38] = s2, k[39] = s3;
358 0x78007878,0xd800d8d8,0x42004242,0xcc00cccc, 451 RotLeft128(s1,s2,s3,s0,2); /* KR <<< 94 */
359 0xef00efef,0x26002626,0xe500e5e5,0x61006161, 452 k[52] = s1, k[53] = s2, k[54] = s3, k[55] = s0;
360 0x1a001a1a,0x3f003f3f,0x3b003b3b,0x82008282, 453
361 0xb600b6b6,0xdb00dbdb,0xd400d4d4,0x98009898, 454 s0 = k[12], s1 = k[13], s2 = k[14], s3 = k[15];
362 0xe800e8e8,0x8b008b8b,0x02000202,0xeb00ebeb, 455 RotLeft128(s0,s1,s2,s3,15); /* KA <<< 15 */
363 0x0a000a0a,0x2c002c2c,0x1d001d1d,0xb000b0b0, 456 k[12] = s0, k[13] = s1, k[14] = s2, k[15] = s3;
364 0x6f006f6f,0x8d008d8d,0x88008888,0x0e000e0e, 457 RotLeft128(s0,s1,s2,s3,30); /* KA <<< 45 */
365 0x19001919,0x87008787,0x4e004e4e,0x0b000b0b, 458 k[28] = s0, k[29] = s1, k[30] = s2, k[31] = s3;
366 0xa900a9a9,0x0c000c0c,0x79007979,0x11001111, 459 /* KA <<< 77 */
367 0x7f007f7f,0x22002222,0xe700e7e7,0x59005959, 460 k[48] = s1, k[49] = s2, k[50] = s3, k[51] = s0;
368 0xe100e1e1,0xda00dada,0x3d003d3d,0xc800c8c8, 461 RotLeft128(s1,s2,s3,s0,17); /* KA <<< 94 */
369 0x12001212,0x04000404,0x74007474,0x54005454, 462 k[56] = s1, k[57] = s2, k[58] = s3, k[59] = s0;
370 0x30003030,0x7e007e7e,0xb400b4b4,0x28002828, 463
371 0x55005555,0x68006868,0x50005050,0xbe00bebe, 464 s0 = k[ 0], s1 = k[ 1], s2 = k[ 2], s3 = k[ 3];
372 0xd000d0d0,0xc400c4c4,0x31003131,0xcb00cbcb, 465 RotLeft128(s1,s2,s3,s0,13); /* KL <<< 45 */
373 0x2a002a2a,0xad00adad,0x0f000f0f,0xca00caca, 466 k[24] = s1, k[25] = s2, k[26] = s3, k[27] = s0;
374 0x70007070,0xff00ffff,0x32003232,0x69006969, 467 RotLeft128(s1,s2,s3,s0,15); /* KL <<< 60 */
375 0x08000808,0x62006262,0x00000000,0x24002424, 468 k[32] = s1, k[33] = s2, k[34] = s3, k[35] = s0;
376 0xd100d1d1,0xfb00fbfb,0xba00baba,0xed00eded, 469 RotLeft128(s1,s2,s3,s0,17); /* KL <<< 77 */
377 0x45004545,0x81008181,0x73007373,0x6d006d6d, 470 k[44] = s1, k[45] = s2, k[46] = s3, k[47] = s0;
378 0x84008484,0x9f009f9f,0xee00eeee,0x4a004a4a, 471 RotLeft128(s2,s3,s0,s1,2); /* KL <<<111 */
379 0xc300c3c3,0x2e002e2e,0xc100c1c1,0x01000101, 472 k[60] = s2, k[61] = s3, k[62] = s0, k[63] = s1;
380 0xe600e6e6,0x25002525,0x48004848,0x99009999, 473
381 0xb900b9b9,0xb300b3b3,0x7b007b7b,0xf900f9f9, 474 return 4; /* grand rounds */
382 0xce00cece,0xbf00bfbf,0xdf00dfdf,0x71007171, 475 }
383 0x29002929,0xcd00cdcd,0x6c006c6c,0x13001313, 476 /*
384 0x64006464,0x9b009b9b,0x63006363,0x9d009d9d, 477 * It is possible to perform certain precalculations, which
385 0xc000c0c0,0x4b004b4b,0xb700b7b7,0xa500a5a5, 478 * would spare few cycles in block procedure. It's not done,
386 0x89008989,0x5f005f5f,0xb100b1b1,0x17001717, 479 * because it upsets the performance balance between key
387 0xf400f4f4,0xbc00bcbc,0xd300d3d3,0x46004646, 480 * setup and block procedures, negatively affecting overall
388 0xcf00cfcf,0x37003737,0x5e005e5e,0x47004747, 481 * throughput in applications operating on short messages
389 0x94009494,0xfa00fafa,0xfc00fcfc,0x5b005b5b, 482 * and volatile keys.
390 0x97009797,0xfe00fefe,0x5a005a5a,0xac00acac, 483 */
391 0x3c003c3c,0x4c004c4c,0x03000303,0x35003535,
392 0xf300f3f3,0x23002323,0xb800b8b8,0x5d005d5d,
393 0x6a006a6a,0x92009292,0xd500d5d5,0x21002121,
394 0x44004444,0x51005151,0xc600c6c6,0x7d007d7d,
395 0x39003939,0x83008383,0xdc00dcdc,0xaa00aaaa,
396 0x7c007c7c,0x77007777,0x56005656,0x05000505,
397 0x1b001b1b,0xa400a4a4,0x15001515,0x34003434,
398 0x1e001e1e,0x1c001c1c,0xf800f8f8,0x52005252,
399 0x20002020,0x14001414,0xe900e9e9,0xbd00bdbd,
400 0xdd00dddd,0xe400e4e4,0xa100a1a1,0xe000e0e0,
401 0x8a008a8a,0xf100f1f1,0xd600d6d6,0x7a007a7a,
402 0xbb00bbbb,0xe300e3e3,0x40004040,0x4f004f4f,
403 };
404
405static const u32 camellia_sp4404[256] =
406 {
407 0x70700070,0x2c2c002c,0xb3b300b3,0xc0c000c0,
408 0xe4e400e4,0x57570057,0xeaea00ea,0xaeae00ae,
409 0x23230023,0x6b6b006b,0x45450045,0xa5a500a5,
410 0xeded00ed,0x4f4f004f,0x1d1d001d,0x92920092,
411 0x86860086,0xafaf00af,0x7c7c007c,0x1f1f001f,
412 0x3e3e003e,0xdcdc00dc,0x5e5e005e,0x0b0b000b,
413 0xa6a600a6,0x39390039,0xd5d500d5,0x5d5d005d,
414 0xd9d900d9,0x5a5a005a,0x51510051,0x6c6c006c,
415 0x8b8b008b,0x9a9a009a,0xfbfb00fb,0xb0b000b0,
416 0x74740074,0x2b2b002b,0xf0f000f0,0x84840084,
417 0xdfdf00df,0xcbcb00cb,0x34340034,0x76760076,
418 0x6d6d006d,0xa9a900a9,0xd1d100d1,0x04040004,
419 0x14140014,0x3a3a003a,0xdede00de,0x11110011,
420 0x32320032,0x9c9c009c,0x53530053,0xf2f200f2,
421 0xfefe00fe,0xcfcf00cf,0xc3c300c3,0x7a7a007a,
422 0x24240024,0xe8e800e8,0x60600060,0x69690069,
423 0xaaaa00aa,0xa0a000a0,0xa1a100a1,0x62620062,
424 0x54540054,0x1e1e001e,0xe0e000e0,0x64640064,
425 0x10100010,0x00000000,0xa3a300a3,0x75750075,
426 0x8a8a008a,0xe6e600e6,0x09090009,0xdddd00dd,
427 0x87870087,0x83830083,0xcdcd00cd,0x90900090,
428 0x73730073,0xf6f600f6,0x9d9d009d,0xbfbf00bf,
429 0x52520052,0xd8d800d8,0xc8c800c8,0xc6c600c6,
430 0x81810081,0x6f6f006f,0x13130013,0x63630063,
431 0xe9e900e9,0xa7a700a7,0x9f9f009f,0xbcbc00bc,
432 0x29290029,0xf9f900f9,0x2f2f002f,0xb4b400b4,
433 0x78780078,0x06060006,0xe7e700e7,0x71710071,
434 0xd4d400d4,0xabab00ab,0x88880088,0x8d8d008d,
435 0x72720072,0xb9b900b9,0xf8f800f8,0xacac00ac,
436 0x36360036,0x2a2a002a,0x3c3c003c,0xf1f100f1,
437 0x40400040,0xd3d300d3,0xbbbb00bb,0x43430043,
438 0x15150015,0xadad00ad,0x77770077,0x80800080,
439 0x82820082,0xecec00ec,0x27270027,0xe5e500e5,
440 0x85850085,0x35350035,0x0c0c000c,0x41410041,
441 0xefef00ef,0x93930093,0x19190019,0x21210021,
442 0x0e0e000e,0x4e4e004e,0x65650065,0xbdbd00bd,
443 0xb8b800b8,0x8f8f008f,0xebeb00eb,0xcece00ce,
444 0x30300030,0x5f5f005f,0xc5c500c5,0x1a1a001a,
445 0xe1e100e1,0xcaca00ca,0x47470047,0x3d3d003d,
446 0x01010001,0xd6d600d6,0x56560056,0x4d4d004d,
447 0x0d0d000d,0x66660066,0xcccc00cc,0x2d2d002d,
448 0x12120012,0x20200020,0xb1b100b1,0x99990099,
449 0x4c4c004c,0xc2c200c2,0x7e7e007e,0x05050005,
450 0xb7b700b7,0x31310031,0x17170017,0xd7d700d7,
451 0x58580058,0x61610061,0x1b1b001b,0x1c1c001c,
452 0x0f0f000f,0x16160016,0x18180018,0x22220022,
453 0x44440044,0xb2b200b2,0xb5b500b5,0x91910091,
454 0x08080008,0xa8a800a8,0xfcfc00fc,0x50500050,
455 0xd0d000d0,0x7d7d007d,0x89890089,0x97970097,
456 0x5b5b005b,0x95950095,0xffff00ff,0xd2d200d2,
457 0xc4c400c4,0x48480048,0xf7f700f7,0xdbdb00db,
458 0x03030003,0xdada00da,0x3f3f003f,0x94940094,
459 0x5c5c005c,0x02020002,0x4a4a004a,0x33330033,
460 0x67670067,0xf3f300f3,0x7f7f007f,0xe2e200e2,
461 0x9b9b009b,0x26260026,0x37370037,0x3b3b003b,
462 0x96960096,0x4b4b004b,0xbebe00be,0x2e2e002e,
463 0x79790079,0x8c8c008c,0x6e6e006e,0x8e8e008e,
464 0xf5f500f5,0xb6b600b6,0xfdfd00fd,0x59590059,
465 0x98980098,0x6a6a006a,0x46460046,0xbaba00ba,
466 0x25250025,0x42420042,0xa2a200a2,0xfafa00fa,
467 0x07070007,0x55550055,0xeeee00ee,0x0a0a000a,
468 0x49490049,0x68680068,0x38380038,0xa4a400a4,
469 0x28280028,0x7b7b007b,0xc9c900c9,0xc1c100c1,
470 0xe3e300e3,0xf4f400f4,0xc7c700c7,0x9e9e009e,
471 };
472
473/**
474 * Stuff related to the Camellia key schedule
475 */
476#define subl(x) subL[(x)]
477#define subr(x) subR[(x)]
478
479void camellia_setup128(const u8 *key, u32 *subkey)
480 {
481 u32 kll, klr, krl, krr;
482 u32 il, ir, t0, t1, w0, w1;
483 u32 kw4l, kw4r, dw, tl, tr;
484 u32 subL[26];
485 u32 subR[26];
486
487 /**
488 * k == kll || klr || krl || krr (|| is concatination)
489 */
490 kll = GETU32(key );
491 klr = GETU32(key + 4);
492 krl = GETU32(key + 8);
493 krr = GETU32(key + 12);
494 /**
495 * generate KL dependent subkeys
496 */
497 /* kw1 */
498 subl(0) = kll; subr(0) = klr;
499 /* kw2 */
500 subl(1) = krl; subr(1) = krr;
501 /* rotation left shift 15bit */
502 CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15);
503 /* k3 */
504 subl(4) = kll; subr(4) = klr;
505 /* k4 */
506 subl(5) = krl; subr(5) = krr;
507 /* rotation left shift 15+30bit */
508 CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 30);
509 /* k7 */
510 subl(10) = kll; subr(10) = klr;
511 /* k8 */
512 subl(11) = krl; subr(11) = krr;
513 /* rotation left shift 15+30+15bit */
514 CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15);
515 /* k10 */
516 subl(13) = krl; subr(13) = krr;
517 /* rotation left shift 15+30+15+17 bit */
518 CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 17);
519 /* kl3 */
520 subl(16) = kll; subr(16) = klr;
521 /* kl4 */
522 subl(17) = krl; subr(17) = krr;
523 /* rotation left shift 15+30+15+17+17 bit */
524 CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 17);
525 /* k13 */
526 subl(18) = kll; subr(18) = klr;
527 /* k14 */
528 subl(19) = krl; subr(19) = krr;
529 /* rotation left shift 15+30+15+17+17+17 bit */
530 CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 17);
531 /* k17 */
532 subl(22) = kll; subr(22) = klr;
533 /* k18 */
534 subl(23) = krl; subr(23) = krr;
535
536 /* generate KA */
537 kll = subl(0); klr = subr(0);
538 krl = subl(1); krr = subr(1);
539 CAMELLIA_F(kll, klr,
540 CAMELLIA_SIGMA1L, CAMELLIA_SIGMA1R,
541 w0, w1, il, ir, t0, t1);
542 krl ^= w0; krr ^= w1;
543 CAMELLIA_F(krl, krr,
544 CAMELLIA_SIGMA2L, CAMELLIA_SIGMA2R,
545 kll, klr, il, ir, t0, t1);
546 /* current status == (kll, klr, w0, w1) */
547 CAMELLIA_F(kll, klr,
548 CAMELLIA_SIGMA3L, CAMELLIA_SIGMA3R,
549 krl, krr, il, ir, t0, t1);
550 krl ^= w0; krr ^= w1;
551 CAMELLIA_F(krl, krr,
552 CAMELLIA_SIGMA4L, CAMELLIA_SIGMA4R,
553 w0, w1, il, ir, t0, t1);
554 kll ^= w0; klr ^= w1;
555
556 /* generate KA dependent subkeys */
557 /* k1, k2 */
558 subl(2) = kll; subr(2) = klr;
559 subl(3) = krl; subr(3) = krr;
560 CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15);
561 /* k5,k6 */
562 subl(6) = kll; subr(6) = klr;
563 subl(7) = krl; subr(7) = krr;
564 CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15);
565 /* kl1, kl2 */
566 subl(8) = kll; subr(8) = klr;
567 subl(9) = krl; subr(9) = krr;
568 CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15);
569 /* k9 */
570 subl(12) = kll; subr(12) = klr;
571 CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15);
572 /* k11, k12 */
573 subl(14) = kll; subr(14) = klr;
574 subl(15) = krl; subr(15) = krr;
575 CAMELLIA_ROLDQo32(kll, klr, krl, krr, w0, w1, 34);
576 /* k15, k16 */
577 subl(20) = kll; subr(20) = klr;
578 subl(21) = krl; subr(21) = krr;
579 CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 17);
580 /* kw3, kw4 */
581 subl(24) = kll; subr(24) = klr;
582 subl(25) = krl; subr(25) = krr;
583
584
585 /* absorb kw2 to other subkeys */
586/* round 2 */
587 subl(3) ^= subl(1); subr(3) ^= subr(1);
588/* round 4 */
589 subl(5) ^= subl(1); subr(5) ^= subr(1);
590/* round 6 */
591 subl(7) ^= subl(1); subr(7) ^= subr(1);
592 subl(1) ^= subr(1) & ~subr(9);
593 dw = subl(1) & subl(9),
594 subr(1) ^= CAMELLIA_RL1(dw); /* modified for FLinv(kl2) */
595/* round 8 */
596 subl(11) ^= subl(1); subr(11) ^= subr(1);
597/* round 10 */
598 subl(13) ^= subl(1); subr(13) ^= subr(1);
599/* round 12 */
600 subl(15) ^= subl(1); subr(15) ^= subr(1);
601 subl(1) ^= subr(1) & ~subr(17);
602 dw = subl(1) & subl(17),
603 subr(1) ^= CAMELLIA_RL1(dw); /* modified for FLinv(kl4) */
604/* round 14 */
605 subl(19) ^= subl(1); subr(19) ^= subr(1);
606/* round 16 */
607 subl(21) ^= subl(1); subr(21) ^= subr(1);
608/* round 18 */
609 subl(23) ^= subl(1); subr(23) ^= subr(1);
610/* kw3 */
611 subl(24) ^= subl(1); subr(24) ^= subr(1);
612
613 /* absorb kw4 to other subkeys */
614 kw4l = subl(25); kw4r = subr(25);
615/* round 17 */
616 subl(22) ^= kw4l; subr(22) ^= kw4r;
617/* round 15 */
618 subl(20) ^= kw4l; subr(20) ^= kw4r;
619/* round 13 */
620 subl(18) ^= kw4l; subr(18) ^= kw4r;
621 kw4l ^= kw4r & ~subr(16);
622 dw = kw4l & subl(16),
623 kw4r ^= CAMELLIA_RL1(dw); /* modified for FL(kl3) */
624/* round 11 */
625 subl(14) ^= kw4l; subr(14) ^= kw4r;
626/* round 9 */
627 subl(12) ^= kw4l; subr(12) ^= kw4r;
628/* round 7 */
629 subl(10) ^= kw4l; subr(10) ^= kw4r;
630 kw4l ^= kw4r & ~subr(8);
631 dw = kw4l & subl(8),
632 kw4r ^= CAMELLIA_RL1(dw); /* modified for FL(kl1) */
633/* round 5 */
634 subl(6) ^= kw4l; subr(6) ^= kw4r;
635/* round 3 */
636 subl(4) ^= kw4l; subr(4) ^= kw4r;
637/* round 1 */
638 subl(2) ^= kw4l; subr(2) ^= kw4r;
639/* kw1 */
640 subl(0) ^= kw4l; subr(0) ^= kw4r;
641
642
643 /* key XOR is end of F-function */
644 CamelliaSubkeyL(0) = subl(0) ^ subl(2);/* kw1 */
645 CamelliaSubkeyR(0) = subr(0) ^ subr(2);
646 CamelliaSubkeyL(2) = subl(3); /* round 1 */
647 CamelliaSubkeyR(2) = subr(3);
648 CamelliaSubkeyL(3) = subl(2) ^ subl(4); /* round 2 */
649 CamelliaSubkeyR(3) = subr(2) ^ subr(4);
650 CamelliaSubkeyL(4) = subl(3) ^ subl(5); /* round 3 */
651 CamelliaSubkeyR(4) = subr(3) ^ subr(5);
652 CamelliaSubkeyL(5) = subl(4) ^ subl(6); /* round 4 */
653 CamelliaSubkeyR(5) = subr(4) ^ subr(6);
654 CamelliaSubkeyL(6) = subl(5) ^ subl(7); /* round 5 */
655 CamelliaSubkeyR(6) = subr(5) ^ subr(7);
656 tl = subl(10) ^ (subr(10) & ~subr(8));
657 dw = tl & subl(8), /* FL(kl1) */
658 tr = subr(10) ^ CAMELLIA_RL1(dw);
659 CamelliaSubkeyL(7) = subl(6) ^ tl; /* round 6 */
660 CamelliaSubkeyR(7) = subr(6) ^ tr;
661 CamelliaSubkeyL(8) = subl(8); /* FL(kl1) */
662 CamelliaSubkeyR(8) = subr(8);
663 CamelliaSubkeyL(9) = subl(9); /* FLinv(kl2) */
664 CamelliaSubkeyR(9) = subr(9);
665 tl = subl(7) ^ (subr(7) & ~subr(9));
666 dw = tl & subl(9), /* FLinv(kl2) */
667 tr = subr(7) ^ CAMELLIA_RL1(dw);
668 CamelliaSubkeyL(10) = tl ^ subl(11); /* round 7 */
669 CamelliaSubkeyR(10) = tr ^ subr(11);
670 CamelliaSubkeyL(11) = subl(10) ^ subl(12); /* round 8 */
671 CamelliaSubkeyR(11) = subr(10) ^ subr(12);
672 CamelliaSubkeyL(12) = subl(11) ^ subl(13); /* round 9 */
673 CamelliaSubkeyR(12) = subr(11) ^ subr(13);
674 CamelliaSubkeyL(13) = subl(12) ^ subl(14); /* round 10 */
675 CamelliaSubkeyR(13) = subr(12) ^ subr(14);
676 CamelliaSubkeyL(14) = subl(13) ^ subl(15); /* round 11 */
677 CamelliaSubkeyR(14) = subr(13) ^ subr(15);
678 tl = subl(18) ^ (subr(18) & ~subr(16));
679 dw = tl & subl(16), /* FL(kl3) */
680 tr = subr(18) ^ CAMELLIA_RL1(dw);
681 CamelliaSubkeyL(15) = subl(14) ^ tl; /* round 12 */
682 CamelliaSubkeyR(15) = subr(14) ^ tr;
683 CamelliaSubkeyL(16) = subl(16); /* FL(kl3) */
684 CamelliaSubkeyR(16) = subr(16);
685 CamelliaSubkeyL(17) = subl(17); /* FLinv(kl4) */
686 CamelliaSubkeyR(17) = subr(17);
687 tl = subl(15) ^ (subr(15) & ~subr(17));
688 dw = tl & subl(17), /* FLinv(kl4) */
689 tr = subr(15) ^ CAMELLIA_RL1(dw);
690 CamelliaSubkeyL(18) = tl ^ subl(19); /* round 13 */
691 CamelliaSubkeyR(18) = tr ^ subr(19);
692 CamelliaSubkeyL(19) = subl(18) ^ subl(20); /* round 14 */
693 CamelliaSubkeyR(19) = subr(18) ^ subr(20);
694 CamelliaSubkeyL(20) = subl(19) ^ subl(21); /* round 15 */
695 CamelliaSubkeyR(20) = subr(19) ^ subr(21);
696 CamelliaSubkeyL(21) = subl(20) ^ subl(22); /* round 16 */
697 CamelliaSubkeyR(21) = subr(20) ^ subr(22);
698 CamelliaSubkeyL(22) = subl(21) ^ subl(23); /* round 17 */
699 CamelliaSubkeyR(22) = subr(21) ^ subr(23);
700 CamelliaSubkeyL(23) = subl(22); /* round 18 */
701 CamelliaSubkeyR(23) = subr(22);
702 CamelliaSubkeyL(24) = subl(24) ^ subl(23); /* kw3 */
703 CamelliaSubkeyR(24) = subr(24) ^ subr(23);
704
705 /* apply the inverse of the last half of P-function */
706 dw = CamelliaSubkeyL(2) ^ CamelliaSubkeyR(2),
707 dw = CAMELLIA_RL8(dw);/* round 1 */
708 CamelliaSubkeyR(2) = CamelliaSubkeyL(2) ^ dw,
709 CamelliaSubkeyL(2) = dw;
710 dw = CamelliaSubkeyL(3) ^ CamelliaSubkeyR(3),
711 dw = CAMELLIA_RL8(dw);/* round 2 */
712 CamelliaSubkeyR(3) = CamelliaSubkeyL(3) ^ dw,
713 CamelliaSubkeyL(3) = dw;
714 dw = CamelliaSubkeyL(4) ^ CamelliaSubkeyR(4),
715 dw = CAMELLIA_RL8(dw);/* round 3 */
716 CamelliaSubkeyR(4) = CamelliaSubkeyL(4) ^ dw,
717 CamelliaSubkeyL(4) = dw;
718 dw = CamelliaSubkeyL(5) ^ CamelliaSubkeyR(5),
719 dw = CAMELLIA_RL8(dw);/* round 4 */
720 CamelliaSubkeyR(5) = CamelliaSubkeyL(5) ^ dw,
721 CamelliaSubkeyL(5) = dw;
722 dw = CamelliaSubkeyL(6) ^ CamelliaSubkeyR(6),
723 dw = CAMELLIA_RL8(dw);/* round 5 */
724 CamelliaSubkeyR(6) = CamelliaSubkeyL(6) ^ dw,
725 CamelliaSubkeyL(6) = dw;
726 dw = CamelliaSubkeyL(7) ^ CamelliaSubkeyR(7),
727 dw = CAMELLIA_RL8(dw);/* round 6 */
728 CamelliaSubkeyR(7) = CamelliaSubkeyL(7) ^ dw,
729 CamelliaSubkeyL(7) = dw;
730 dw = CamelliaSubkeyL(10) ^ CamelliaSubkeyR(10),
731 dw = CAMELLIA_RL8(dw);/* round 7 */
732 CamelliaSubkeyR(10) = CamelliaSubkeyL(10) ^ dw,
733 CamelliaSubkeyL(10) = dw;
734 dw = CamelliaSubkeyL(11) ^ CamelliaSubkeyR(11),
735 dw = CAMELLIA_RL8(dw);/* round 8 */
736 CamelliaSubkeyR(11) = CamelliaSubkeyL(11) ^ dw,
737 CamelliaSubkeyL(11) = dw;
738 dw = CamelliaSubkeyL(12) ^ CamelliaSubkeyR(12),
739 dw = CAMELLIA_RL8(dw);/* round 9 */
740 CamelliaSubkeyR(12) = CamelliaSubkeyL(12) ^ dw,
741 CamelliaSubkeyL(12) = dw;
742 dw = CamelliaSubkeyL(13) ^ CamelliaSubkeyR(13),
743 dw = CAMELLIA_RL8(dw);/* round 10 */
744 CamelliaSubkeyR(13) = CamelliaSubkeyL(13) ^ dw,
745 CamelliaSubkeyL(13) = dw;
746 dw = CamelliaSubkeyL(14) ^ CamelliaSubkeyR(14),
747 dw = CAMELLIA_RL8(dw);/* round 11 */
748 CamelliaSubkeyR(14) = CamelliaSubkeyL(14) ^ dw,
749 CamelliaSubkeyL(14) = dw;
750 dw = CamelliaSubkeyL(15) ^ CamelliaSubkeyR(15),
751 dw = CAMELLIA_RL8(dw);/* round 12 */
752 CamelliaSubkeyR(15) = CamelliaSubkeyL(15) ^ dw,
753 CamelliaSubkeyL(15) = dw;
754 dw = CamelliaSubkeyL(18) ^ CamelliaSubkeyR(18),
755 dw = CAMELLIA_RL8(dw);/* round 13 */
756 CamelliaSubkeyR(18) = CamelliaSubkeyL(18) ^ dw,
757 CamelliaSubkeyL(18) = dw;
758 dw = CamelliaSubkeyL(19) ^ CamelliaSubkeyR(19),
759 dw = CAMELLIA_RL8(dw);/* round 14 */
760 CamelliaSubkeyR(19) = CamelliaSubkeyL(19) ^ dw,
761 CamelliaSubkeyL(19) = dw;
762 dw = CamelliaSubkeyL(20) ^ CamelliaSubkeyR(20),
763 dw = CAMELLIA_RL8(dw);/* round 15 */
764 CamelliaSubkeyR(20) = CamelliaSubkeyL(20) ^ dw,
765 CamelliaSubkeyL(20) = dw;
766 dw = CamelliaSubkeyL(21) ^ CamelliaSubkeyR(21),
767 dw = CAMELLIA_RL8(dw);/* round 16 */
768 CamelliaSubkeyR(21) = CamelliaSubkeyL(21) ^ dw,
769 CamelliaSubkeyL(21) = dw;
770 dw = CamelliaSubkeyL(22) ^ CamelliaSubkeyR(22),
771 dw = CAMELLIA_RL8(dw);/* round 17 */
772 CamelliaSubkeyR(22) = CamelliaSubkeyL(22) ^ dw,
773 CamelliaSubkeyL(22) = dw;
774 dw = CamelliaSubkeyL(23) ^ CamelliaSubkeyR(23),
775 dw = CAMELLIA_RL8(dw);/* round 18 */
776 CamelliaSubkeyR(23) = CamelliaSubkeyL(23) ^ dw,
777 CamelliaSubkeyL(23) = dw;
778
779 return;
780 } 484 }
781 485
782void camellia_setup256(const u8 *key, u32 *subkey) 486void Camellia_EncryptBlock_Rounds(int grandRounds, const u8 plaintext[],
487 const KEY_TABLE_TYPE keyTable, u8 ciphertext[])
783 { 488 {
784 u32 kll,klr,krl,krr; /* left half of key */ 489 register u32 s0,s1,s2,s3;
785 u32 krll,krlr,krrl,krrr; /* right half of key */ 490 const u32 *k = keyTable,*kend = keyTable+grandRounds*16;
786 u32 il, ir, t0, t1, w0, w1; /* temporary variables */ 491
787 u32 kw4l, kw4r, dw, tl, tr; 492 s0 = GETU32(plaintext) ^ k[0];
788 u32 subL[34]; 493 s1 = GETU32(plaintext+4) ^ k[1];
789 u32 subR[34]; 494 s2 = GETU32(plaintext+8) ^ k[2];
790 495 s3 = GETU32(plaintext+12) ^ k[3];
791 /** 496 k += 4;
792 * key = (kll || klr || krl || krr || krll || krlr || krrl || krrr) 497
793 * (|| is concatination) 498 while (1)
794 */ 499 {
795 500 /* Camellia makes 6 Feistel rounds */
796 kll = GETU32(key ); 501 Camellia_Feistel(s0,s1,s2,s3,k+0);
797 klr = GETU32(key + 4); 502 Camellia_Feistel(s2,s3,s0,s1,k+2);
798 krl = GETU32(key + 8); 503 Camellia_Feistel(s0,s1,s2,s3,k+4);
799 krr = GETU32(key + 12); 504 Camellia_Feistel(s2,s3,s0,s1,k+6);
800 krll = GETU32(key + 16); 505 Camellia_Feistel(s0,s1,s2,s3,k+8);
801 krlr = GETU32(key + 20); 506 Camellia_Feistel(s2,s3,s0,s1,k+10);
802 krrl = GETU32(key + 24); 507 k += 12;
803 krrr = GETU32(key + 28); 508
804 509 if (k == kend) break;
805 /* generate KL dependent subkeys */ 510
806 /* kw1 */ 511 /* This is the same function as the diffusion function D
807 subl(0) = kll; subr(0) = klr; 512 * of the accompanying documentation. See section 3.2
808 /* kw2 */ 513 * for properties of the FLlayer function. */
809 subl(1) = krl; subr(1) = krr; 514 s1 ^= LeftRotate(s0 & k[0], 1);
810 CAMELLIA_ROLDQo32(kll, klr, krl, krr, w0, w1, 45); 515 s2 ^= s3 | k[3];
811 /* k9 */ 516 s0 ^= s1 | k[1];
812 subl(12) = kll; subr(12) = klr; 517 s3 ^= LeftRotate(s2 & k[2], 1);
813 /* k10 */ 518 k += 4;
814 subl(13) = krl; subr(13) = krr; 519 }
815 CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15); 520
816 /* kl3 */ 521 s2 ^= k[0], s3 ^= k[1], s0 ^= k[2], s1 ^= k[3];
817 subl(16) = kll; subr(16) = klr; 522
818 /* kl4 */ 523 PUTU32(ciphertext, s2);
819 subl(17) = krl; subr(17) = krr; 524 PUTU32(ciphertext+4, s3);
820 CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 17); 525 PUTU32(ciphertext+8, s0);
821 /* k17 */ 526 PUTU32(ciphertext+12,s1);
822 subl(22) = kll; subr(22) = klr;
823 /* k18 */
824 subl(23) = krl; subr(23) = krr;
825 CAMELLIA_ROLDQo32(kll, klr, krl, krr, w0, w1, 34);
826 /* k23 */
827 subl(30) = kll; subr(30) = klr;
828 /* k24 */
829 subl(31) = krl; subr(31) = krr;
830
831 /* generate KR dependent subkeys */
832 CAMELLIA_ROLDQ(krll, krlr, krrl, krrr, w0, w1, 15);
833 /* k3 */
834 subl(4) = krll; subr(4) = krlr;
835 /* k4 */
836 subl(5) = krrl; subr(5) = krrr;
837 CAMELLIA_ROLDQ(krll, krlr, krrl, krrr, w0, w1, 15);
838 /* kl1 */
839 subl(8) = krll; subr(8) = krlr;
840 /* kl2 */
841 subl(9) = krrl; subr(9) = krrr;
842 CAMELLIA_ROLDQ(krll, krlr, krrl, krrr, w0, w1, 30);
843 /* k13 */
844 subl(18) = krll; subr(18) = krlr;
845 /* k14 */
846 subl(19) = krrl; subr(19) = krrr;
847 CAMELLIA_ROLDQo32(krll, krlr, krrl, krrr, w0, w1, 34);
848 /* k19 */
849 subl(26) = krll; subr(26) = krlr;
850 /* k20 */
851 subl(27) = krrl; subr(27) = krrr;
852 CAMELLIA_ROLDQo32(krll, krlr, krrl, krrr, w0, w1, 34);
853
854 /* generate KA */
855 kll = subl(0) ^ krll; klr = subr(0) ^ krlr;
856 krl = subl(1) ^ krrl; krr = subr(1) ^ krrr;
857 CAMELLIA_F(kll, klr,
858 CAMELLIA_SIGMA1L, CAMELLIA_SIGMA1R,
859 w0, w1, il, ir, t0, t1);
860 krl ^= w0; krr ^= w1;
861 CAMELLIA_F(krl, krr,
862 CAMELLIA_SIGMA2L, CAMELLIA_SIGMA2R,
863 kll, klr, il, ir, t0, t1);
864 kll ^= krll; klr ^= krlr;
865 CAMELLIA_F(kll, klr,
866 CAMELLIA_SIGMA3L, CAMELLIA_SIGMA3R,
867 krl, krr, il, ir, t0, t1);
868 krl ^= w0 ^ krrl; krr ^= w1 ^ krrr;
869 CAMELLIA_F(krl, krr,
870 CAMELLIA_SIGMA4L, CAMELLIA_SIGMA4R,
871 w0, w1, il, ir, t0, t1);
872 kll ^= w0; klr ^= w1;
873
874 /* generate KB */
875 krll ^= kll; krlr ^= klr;
876 krrl ^= krl; krrr ^= krr;
877 CAMELLIA_F(krll, krlr,
878 CAMELLIA_SIGMA5L, CAMELLIA_SIGMA5R,
879 w0, w1, il, ir, t0, t1);
880 krrl ^= w0; krrr ^= w1;
881 CAMELLIA_F(krrl, krrr,
882 CAMELLIA_SIGMA6L, CAMELLIA_SIGMA6R,
883 w0, w1, il, ir, t0, t1);
884 krll ^= w0; krlr ^= w1;
885
886 /* generate KA dependent subkeys */
887 CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15);
888 /* k5 */
889 subl(6) = kll; subr(6) = klr;
890 /* k6 */
891 subl(7) = krl; subr(7) = krr;
892 CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 30);
893 /* k11 */
894 subl(14) = kll; subr(14) = klr;
895 /* k12 */
896 subl(15) = krl; subr(15) = krr;
897 /* rotation left shift 32bit */
898 /* kl5 */
899 subl(24) = klr; subr(24) = krl;
900 /* kl6 */
901 subl(25) = krr; subr(25) = kll;
902 /* rotation left shift 49 from k11,k12 -> k21,k22 */
903 CAMELLIA_ROLDQo32(kll, klr, krl, krr, w0, w1, 49);
904 /* k21 */
905 subl(28) = kll; subr(28) = klr;
906 /* k22 */
907 subl(29) = krl; subr(29) = krr;
908
909 /* generate KB dependent subkeys */
910 /* k1 */
911 subl(2) = krll; subr(2) = krlr;
912 /* k2 */
913 subl(3) = krrl; subr(3) = krrr;
914 CAMELLIA_ROLDQ(krll, krlr, krrl, krrr, w0, w1, 30);
915 /* k7 */
916 subl(10) = krll; subr(10) = krlr;
917 /* k8 */
918 subl(11) = krrl; subr(11) = krrr;
919 CAMELLIA_ROLDQ(krll, krlr, krrl, krrr, w0, w1, 30);
920 /* k15 */
921 subl(20) = krll; subr(20) = krlr;
922 /* k16 */
923 subl(21) = krrl; subr(21) = krrr;
924 CAMELLIA_ROLDQo32(krll, krlr, krrl, krrr, w0, w1, 51);
925 /* kw3 */
926 subl(32) = krll; subr(32) = krlr;
927 /* kw4 */
928 subl(33) = krrl; subr(33) = krrr;
929
930 /* absorb kw2 to other subkeys */
931/* round 2 */
932 subl(3) ^= subl(1); subr(3) ^= subr(1);
933/* round 4 */
934 subl(5) ^= subl(1); subr(5) ^= subr(1);
935/* round 6 */
936 subl(7) ^= subl(1); subr(7) ^= subr(1);
937 subl(1) ^= subr(1) & ~subr(9);
938 dw = subl(1) & subl(9),
939 subr(1) ^= CAMELLIA_RL1(dw); /* modified for FLinv(kl2) */
940/* round 8 */
941 subl(11) ^= subl(1); subr(11) ^= subr(1);
942/* round 10 */
943 subl(13) ^= subl(1); subr(13) ^= subr(1);
944/* round 12 */
945 subl(15) ^= subl(1); subr(15) ^= subr(1);
946 subl(1) ^= subr(1) & ~subr(17);
947 dw = subl(1) & subl(17),
948 subr(1) ^= CAMELLIA_RL1(dw); /* modified for FLinv(kl4) */
949/* round 14 */
950 subl(19) ^= subl(1); subr(19) ^= subr(1);
951/* round 16 */
952 subl(21) ^= subl(1); subr(21) ^= subr(1);
953/* round 18 */
954 subl(23) ^= subl(1); subr(23) ^= subr(1);
955 subl(1) ^= subr(1) & ~subr(25);
956 dw = subl(1) & subl(25),
957 subr(1) ^= CAMELLIA_RL1(dw); /* modified for FLinv(kl6) */
958/* round 20 */
959 subl(27) ^= subl(1); subr(27) ^= subr(1);
960/* round 22 */
961 subl(29) ^= subl(1); subr(29) ^= subr(1);
962/* round 24 */
963 subl(31) ^= subl(1); subr(31) ^= subr(1);
964/* kw3 */
965 subl(32) ^= subl(1); subr(32) ^= subr(1);
966
967
968 /* absorb kw4 to other subkeys */
969 kw4l = subl(33); kw4r = subr(33);
970/* round 23 */
971 subl(30) ^= kw4l; subr(30) ^= kw4r;
972/* round 21 */
973 subl(28) ^= kw4l; subr(28) ^= kw4r;
974/* round 19 */
975 subl(26) ^= kw4l; subr(26) ^= kw4r;
976 kw4l ^= kw4r & ~subr(24);
977 dw = kw4l & subl(24),
978 kw4r ^= CAMELLIA_RL1(dw); /* modified for FL(kl5) */
979/* round 17 */
980 subl(22) ^= kw4l; subr(22) ^= kw4r;
981/* round 15 */
982 subl(20) ^= kw4l; subr(20) ^= kw4r;
983/* round 13 */
984 subl(18) ^= kw4l; subr(18) ^= kw4r;
985 kw4l ^= kw4r & ~subr(16);
986 dw = kw4l & subl(16),
987 kw4r ^= CAMELLIA_RL1(dw); /* modified for FL(kl3) */
988/* round 11 */
989 subl(14) ^= kw4l; subr(14) ^= kw4r;
990/* round 9 */
991 subl(12) ^= kw4l; subr(12) ^= kw4r;
992/* round 7 */
993 subl(10) ^= kw4l; subr(10) ^= kw4r;
994 kw4l ^= kw4r & ~subr(8);
995 dw = kw4l & subl(8),
996 kw4r ^= CAMELLIA_RL1(dw); /* modified for FL(kl1) */
997/* round 5 */
998 subl(6) ^= kw4l; subr(6) ^= kw4r;
999/* round 3 */
1000 subl(4) ^= kw4l; subr(4) ^= kw4r;
1001/* round 1 */
1002 subl(2) ^= kw4l; subr(2) ^= kw4r;
1003/* kw1 */
1004 subl(0) ^= kw4l; subr(0) ^= kw4r;
1005
1006 /* key XOR is end of F-function */
1007 CamelliaSubkeyL(0) = subl(0) ^ subl(2);/* kw1 */
1008 CamelliaSubkeyR(0) = subr(0) ^ subr(2);
1009 CamelliaSubkeyL(2) = subl(3); /* round 1 */
1010 CamelliaSubkeyR(2) = subr(3);
1011 CamelliaSubkeyL(3) = subl(2) ^ subl(4); /* round 2 */
1012 CamelliaSubkeyR(3) = subr(2) ^ subr(4);
1013 CamelliaSubkeyL(4) = subl(3) ^ subl(5); /* round 3 */
1014 CamelliaSubkeyR(4) = subr(3) ^ subr(5);
1015 CamelliaSubkeyL(5) = subl(4) ^ subl(6); /* round 4 */
1016 CamelliaSubkeyR(5) = subr(4) ^ subr(6);
1017 CamelliaSubkeyL(6) = subl(5) ^ subl(7); /* round 5 */
1018 CamelliaSubkeyR(6) = subr(5) ^ subr(7);
1019 tl = subl(10) ^ (subr(10) & ~subr(8));
1020 dw = tl & subl(8), /* FL(kl1) */
1021 tr = subr(10) ^ CAMELLIA_RL1(dw);
1022 CamelliaSubkeyL(7) = subl(6) ^ tl; /* round 6 */
1023 CamelliaSubkeyR(7) = subr(6) ^ tr;
1024 CamelliaSubkeyL(8) = subl(8); /* FL(kl1) */
1025 CamelliaSubkeyR(8) = subr(8);
1026 CamelliaSubkeyL(9) = subl(9); /* FLinv(kl2) */
1027 CamelliaSubkeyR(9) = subr(9);
1028 tl = subl(7) ^ (subr(7) & ~subr(9));
1029 dw = tl & subl(9), /* FLinv(kl2) */
1030 tr = subr(7) ^ CAMELLIA_RL1(dw);
1031 CamelliaSubkeyL(10) = tl ^ subl(11); /* round 7 */
1032 CamelliaSubkeyR(10) = tr ^ subr(11);
1033 CamelliaSubkeyL(11) = subl(10) ^ subl(12); /* round 8 */
1034 CamelliaSubkeyR(11) = subr(10) ^ subr(12);
1035 CamelliaSubkeyL(12) = subl(11) ^ subl(13); /* round 9 */
1036 CamelliaSubkeyR(12) = subr(11) ^ subr(13);
1037 CamelliaSubkeyL(13) = subl(12) ^ subl(14); /* round 10 */
1038 CamelliaSubkeyR(13) = subr(12) ^ subr(14);
1039 CamelliaSubkeyL(14) = subl(13) ^ subl(15); /* round 11 */
1040 CamelliaSubkeyR(14) = subr(13) ^ subr(15);
1041 tl = subl(18) ^ (subr(18) & ~subr(16));
1042 dw = tl & subl(16), /* FL(kl3) */
1043 tr = subr(18) ^ CAMELLIA_RL1(dw);
1044 CamelliaSubkeyL(15) = subl(14) ^ tl; /* round 12 */
1045 CamelliaSubkeyR(15) = subr(14) ^ tr;
1046 CamelliaSubkeyL(16) = subl(16); /* FL(kl3) */
1047 CamelliaSubkeyR(16) = subr(16);
1048 CamelliaSubkeyL(17) = subl(17); /* FLinv(kl4) */
1049 CamelliaSubkeyR(17) = subr(17);
1050 tl = subl(15) ^ (subr(15) & ~subr(17));
1051 dw = tl & subl(17), /* FLinv(kl4) */
1052 tr = subr(15) ^ CAMELLIA_RL1(dw);
1053 CamelliaSubkeyL(18) = tl ^ subl(19); /* round 13 */
1054 CamelliaSubkeyR(18) = tr ^ subr(19);
1055 CamelliaSubkeyL(19) = subl(18) ^ subl(20); /* round 14 */
1056 CamelliaSubkeyR(19) = subr(18) ^ subr(20);
1057 CamelliaSubkeyL(20) = subl(19) ^ subl(21); /* round 15 */
1058 CamelliaSubkeyR(20) = subr(19) ^ subr(21);
1059 CamelliaSubkeyL(21) = subl(20) ^ subl(22); /* round 16 */
1060 CamelliaSubkeyR(21) = subr(20) ^ subr(22);
1061 CamelliaSubkeyL(22) = subl(21) ^ subl(23); /* round 17 */
1062 CamelliaSubkeyR(22) = subr(21) ^ subr(23);
1063 tl = subl(26) ^ (subr(26)
1064 & ~subr(24));
1065 dw = tl & subl(24), /* FL(kl5) */
1066 tr = subr(26) ^ CAMELLIA_RL1(dw);
1067 CamelliaSubkeyL(23) = subl(22) ^ tl; /* round 18 */
1068 CamelliaSubkeyR(23) = subr(22) ^ tr;
1069 CamelliaSubkeyL(24) = subl(24); /* FL(kl5) */
1070 CamelliaSubkeyR(24) = subr(24);
1071 CamelliaSubkeyL(25) = subl(25); /* FLinv(kl6) */
1072 CamelliaSubkeyR(25) = subr(25);
1073 tl = subl(23) ^ (subr(23) &
1074 ~subr(25));
1075 dw = tl & subl(25), /* FLinv(kl6) */
1076 tr = subr(23) ^ CAMELLIA_RL1(dw);
1077 CamelliaSubkeyL(26) = tl ^ subl(27); /* round 19 */
1078 CamelliaSubkeyR(26) = tr ^ subr(27);
1079 CamelliaSubkeyL(27) = subl(26) ^ subl(28); /* round 20 */
1080 CamelliaSubkeyR(27) = subr(26) ^ subr(28);
1081 CamelliaSubkeyL(28) = subl(27) ^ subl(29); /* round 21 */
1082 CamelliaSubkeyR(28) = subr(27) ^ subr(29);
1083 CamelliaSubkeyL(29) = subl(28) ^ subl(30); /* round 22 */
1084 CamelliaSubkeyR(29) = subr(28) ^ subr(30);
1085 CamelliaSubkeyL(30) = subl(29) ^ subl(31); /* round 23 */
1086 CamelliaSubkeyR(30) = subr(29) ^ subr(31);
1087 CamelliaSubkeyL(31) = subl(30); /* round 24 */
1088 CamelliaSubkeyR(31) = subr(30);
1089 CamelliaSubkeyL(32) = subl(32) ^ subl(31); /* kw3 */
1090 CamelliaSubkeyR(32) = subr(32) ^ subr(31);
1091
1092 /* apply the inverse of the last half of P-function */
1093 dw = CamelliaSubkeyL(2) ^ CamelliaSubkeyR(2),
1094 dw = CAMELLIA_RL8(dw);/* round 1 */
1095 CamelliaSubkeyR(2) = CamelliaSubkeyL(2) ^ dw,
1096 CamelliaSubkeyL(2) = dw;
1097 dw = CamelliaSubkeyL(3) ^ CamelliaSubkeyR(3),
1098 dw = CAMELLIA_RL8(dw);/* round 2 */
1099 CamelliaSubkeyR(3) = CamelliaSubkeyL(3) ^ dw,
1100 CamelliaSubkeyL(3) = dw;
1101 dw = CamelliaSubkeyL(4) ^ CamelliaSubkeyR(4),
1102 dw = CAMELLIA_RL8(dw);/* round 3 */
1103 CamelliaSubkeyR(4) = CamelliaSubkeyL(4) ^ dw,
1104 CamelliaSubkeyL(4) = dw;
1105 dw = CamelliaSubkeyL(5) ^ CamelliaSubkeyR(5),
1106 dw = CAMELLIA_RL8(dw);/* round 4 */
1107 CamelliaSubkeyR(5) = CamelliaSubkeyL(5) ^ dw,
1108 CamelliaSubkeyL(5) = dw;
1109 dw = CamelliaSubkeyL(6) ^ CamelliaSubkeyR(6),
1110 dw = CAMELLIA_RL8(dw);/* round 5 */
1111 CamelliaSubkeyR(6) = CamelliaSubkeyL(6) ^ dw,
1112 CamelliaSubkeyL(6) = dw;
1113 dw = CamelliaSubkeyL(7) ^ CamelliaSubkeyR(7),
1114 dw = CAMELLIA_RL8(dw);/* round 6 */
1115 CamelliaSubkeyR(7) = CamelliaSubkeyL(7) ^ dw,
1116 CamelliaSubkeyL(7) = dw;
1117 dw = CamelliaSubkeyL(10) ^ CamelliaSubkeyR(10),
1118 dw = CAMELLIA_RL8(dw);/* round 7 */
1119 CamelliaSubkeyR(10) = CamelliaSubkeyL(10) ^ dw,
1120 CamelliaSubkeyL(10) = dw;
1121 dw = CamelliaSubkeyL(11) ^ CamelliaSubkeyR(11),
1122 dw = CAMELLIA_RL8(dw);/* round 8 */
1123 CamelliaSubkeyR(11) = CamelliaSubkeyL(11) ^ dw,
1124 CamelliaSubkeyL(11) = dw;
1125 dw = CamelliaSubkeyL(12) ^ CamelliaSubkeyR(12),
1126 dw = CAMELLIA_RL8(dw);/* round 9 */
1127 CamelliaSubkeyR(12) = CamelliaSubkeyL(12) ^ dw,
1128 CamelliaSubkeyL(12) = dw;
1129 dw = CamelliaSubkeyL(13) ^ CamelliaSubkeyR(13),
1130 dw = CAMELLIA_RL8(dw);/* round 10 */
1131 CamelliaSubkeyR(13) = CamelliaSubkeyL(13) ^ dw,
1132 CamelliaSubkeyL(13) = dw;
1133 dw = CamelliaSubkeyL(14) ^ CamelliaSubkeyR(14),
1134 dw = CAMELLIA_RL8(dw);/* round 11 */
1135 CamelliaSubkeyR(14) = CamelliaSubkeyL(14) ^ dw,
1136 CamelliaSubkeyL(14) = dw;
1137 dw = CamelliaSubkeyL(15) ^ CamelliaSubkeyR(15),
1138 dw = CAMELLIA_RL8(dw);/* round 12 */
1139 CamelliaSubkeyR(15) = CamelliaSubkeyL(15) ^ dw,
1140 CamelliaSubkeyL(15) = dw;
1141 dw = CamelliaSubkeyL(18) ^ CamelliaSubkeyR(18),
1142 dw = CAMELLIA_RL8(dw);/* round 13 */
1143 CamelliaSubkeyR(18) = CamelliaSubkeyL(18) ^ dw,
1144 CamelliaSubkeyL(18) = dw;
1145 dw = CamelliaSubkeyL(19) ^ CamelliaSubkeyR(19),
1146 dw = CAMELLIA_RL8(dw);/* round 14 */
1147 CamelliaSubkeyR(19) = CamelliaSubkeyL(19) ^ dw,
1148 CamelliaSubkeyL(19) = dw;
1149 dw = CamelliaSubkeyL(20) ^ CamelliaSubkeyR(20),
1150 dw = CAMELLIA_RL8(dw);/* round 15 */
1151 CamelliaSubkeyR(20) = CamelliaSubkeyL(20) ^ dw,
1152 CamelliaSubkeyL(20) = dw;
1153 dw = CamelliaSubkeyL(21) ^ CamelliaSubkeyR(21),
1154 dw = CAMELLIA_RL8(dw);/* round 16 */
1155 CamelliaSubkeyR(21) = CamelliaSubkeyL(21) ^ dw,
1156 CamelliaSubkeyL(21) = dw;
1157 dw = CamelliaSubkeyL(22) ^ CamelliaSubkeyR(22),
1158 dw = CAMELLIA_RL8(dw);/* round 17 */
1159 CamelliaSubkeyR(22) = CamelliaSubkeyL(22) ^ dw,
1160 CamelliaSubkeyL(22) = dw;
1161 dw = CamelliaSubkeyL(23) ^ CamelliaSubkeyR(23),
1162 dw = CAMELLIA_RL8(dw);/* round 18 */
1163 CamelliaSubkeyR(23) = CamelliaSubkeyL(23) ^ dw,
1164 CamelliaSubkeyL(23) = dw;
1165 dw = CamelliaSubkeyL(26) ^ CamelliaSubkeyR(26),
1166 dw = CAMELLIA_RL8(dw);/* round 19 */
1167 CamelliaSubkeyR(26) = CamelliaSubkeyL(26) ^ dw,
1168 CamelliaSubkeyL(26) = dw;
1169 dw = CamelliaSubkeyL(27) ^ CamelliaSubkeyR(27),
1170 dw = CAMELLIA_RL8(dw);/* round 20 */
1171 CamelliaSubkeyR(27) = CamelliaSubkeyL(27) ^ dw,
1172 CamelliaSubkeyL(27) = dw;
1173 dw = CamelliaSubkeyL(28) ^ CamelliaSubkeyR(28),
1174 dw = CAMELLIA_RL8(dw);/* round 21 */
1175 CamelliaSubkeyR(28) = CamelliaSubkeyL(28) ^ dw,
1176 CamelliaSubkeyL(28) = dw;
1177 dw = CamelliaSubkeyL(29) ^ CamelliaSubkeyR(29),
1178 dw = CAMELLIA_RL8(dw);/* round 22 */
1179 CamelliaSubkeyR(29) = CamelliaSubkeyL(29) ^ dw,
1180 CamelliaSubkeyL(29) = dw;
1181 dw = CamelliaSubkeyL(30) ^ CamelliaSubkeyR(30),
1182 dw = CAMELLIA_RL8(dw);/* round 23 */
1183 CamelliaSubkeyR(30) = CamelliaSubkeyL(30) ^ dw,
1184 CamelliaSubkeyL(30) = dw;
1185 dw = CamelliaSubkeyL(31) ^ CamelliaSubkeyR(31),
1186 dw = CAMELLIA_RL8(dw);/* round 24 */
1187 CamelliaSubkeyR(31) = CamelliaSubkeyL(31) ^ dw,
1188 CamelliaSubkeyL(31) = dw;
1189
1190
1191 return;
1192 } 527 }
1193 528void Camellia_EncryptBlock(int keyBitLength, const u8 plaintext[],
1194void camellia_setup192(const u8 *key, u32 *subkey) 529 const KEY_TABLE_TYPE keyTable, u8 ciphertext[])
1195 {
1196 u8 kk[32];
1197 u32 krll, krlr, krrl,krrr;
1198
1199 memcpy(kk, key, 24);
1200 memcpy((u8 *)&krll, key+16,4);
1201 memcpy((u8 *)&krlr, key+20,4);
1202 krrl = ~krll;
1203 krrr = ~krlr;
1204 memcpy(kk+24, (u8 *)&krrl, 4);
1205 memcpy(kk+28, (u8 *)&krrr, 4);
1206 camellia_setup256(kk, subkey);
1207 return;
1208 }
1209
1210
1211/**
1212 * Stuff related to camellia encryption/decryption
1213 */
1214void camellia_encrypt128(const u32 *subkey, u32 *io)
1215 {
1216 u32 il, ir, t0, t1;
1217
1218 /* pre whitening but absorb kw2*/
1219 io[0] ^= CamelliaSubkeyL(0);
1220 io[1] ^= CamelliaSubkeyR(0);
1221 /* main iteration */
1222
1223 CAMELLIA_ROUNDSM(io[0],io[1],
1224 CamelliaSubkeyL(2),CamelliaSubkeyR(2),
1225 io[2],io[3],il,ir,t0,t1);
1226 CAMELLIA_ROUNDSM(io[2],io[3],
1227 CamelliaSubkeyL(3),CamelliaSubkeyR(3),
1228 io[0],io[1],il,ir,t0,t1);
1229 CAMELLIA_ROUNDSM(io[0],io[1],
1230 CamelliaSubkeyL(4),CamelliaSubkeyR(4),
1231 io[2],io[3],il,ir,t0,t1);
1232 CAMELLIA_ROUNDSM(io[2],io[3],
1233 CamelliaSubkeyL(5),CamelliaSubkeyR(5),
1234 io[0],io[1],il,ir,t0,t1);
1235 CAMELLIA_ROUNDSM(io[0],io[1],
1236 CamelliaSubkeyL(6),CamelliaSubkeyR(6),
1237 io[2],io[3],il,ir,t0,t1);
1238 CAMELLIA_ROUNDSM(io[2],io[3],
1239 CamelliaSubkeyL(7),CamelliaSubkeyR(7),
1240 io[0],io[1],il,ir,t0,t1);
1241
1242 CAMELLIA_FLS(io[0],io[1],io[2],io[3],
1243 CamelliaSubkeyL(8),CamelliaSubkeyR(8),
1244 CamelliaSubkeyL(9),CamelliaSubkeyR(9),
1245 t0,t1,il,ir);
1246
1247 CAMELLIA_ROUNDSM(io[0],io[1],
1248 CamelliaSubkeyL(10),CamelliaSubkeyR(10),
1249 io[2],io[3],il,ir,t0,t1);
1250 CAMELLIA_ROUNDSM(io[2],io[3],
1251 CamelliaSubkeyL(11),CamelliaSubkeyR(11),
1252 io[0],io[1],il,ir,t0,t1);
1253 CAMELLIA_ROUNDSM(io[0],io[1],
1254 CamelliaSubkeyL(12),CamelliaSubkeyR(12),
1255 io[2],io[3],il,ir,t0,t1);
1256 CAMELLIA_ROUNDSM(io[2],io[3],
1257 CamelliaSubkeyL(13),CamelliaSubkeyR(13),
1258 io[0],io[1],il,ir,t0,t1);
1259 CAMELLIA_ROUNDSM(io[0],io[1],
1260 CamelliaSubkeyL(14),CamelliaSubkeyR(14),
1261 io[2],io[3],il,ir,t0,t1);
1262 CAMELLIA_ROUNDSM(io[2],io[3],
1263 CamelliaSubkeyL(15),CamelliaSubkeyR(15),
1264 io[0],io[1],il,ir,t0,t1);
1265
1266 CAMELLIA_FLS(io[0],io[1],io[2],io[3],
1267 CamelliaSubkeyL(16),CamelliaSubkeyR(16),
1268 CamelliaSubkeyL(17),CamelliaSubkeyR(17),
1269 t0,t1,il,ir);
1270
1271 CAMELLIA_ROUNDSM(io[0],io[1],
1272 CamelliaSubkeyL(18),CamelliaSubkeyR(18),
1273 io[2],io[3],il,ir,t0,t1);
1274 CAMELLIA_ROUNDSM(io[2],io[3],
1275 CamelliaSubkeyL(19),CamelliaSubkeyR(19),
1276 io[0],io[1],il,ir,t0,t1);
1277 CAMELLIA_ROUNDSM(io[0],io[1],
1278 CamelliaSubkeyL(20),CamelliaSubkeyR(20),
1279 io[2],io[3],il,ir,t0,t1);
1280 CAMELLIA_ROUNDSM(io[2],io[3],
1281 CamelliaSubkeyL(21),CamelliaSubkeyR(21),
1282 io[0],io[1],il,ir,t0,t1);
1283 CAMELLIA_ROUNDSM(io[0],io[1],
1284 CamelliaSubkeyL(22),CamelliaSubkeyR(22),
1285 io[2],io[3],il,ir,t0,t1);
1286 CAMELLIA_ROUNDSM(io[2],io[3],
1287 CamelliaSubkeyL(23),CamelliaSubkeyR(23),
1288 io[0],io[1],il,ir,t0,t1);
1289
1290 /* post whitening but kw4 */
1291 io[2] ^= CamelliaSubkeyL(24);
1292 io[3] ^= CamelliaSubkeyR(24);
1293
1294 t0 = io[0];
1295 t1 = io[1];
1296 io[0] = io[2];
1297 io[1] = io[3];
1298 io[2] = t0;
1299 io[3] = t1;
1300
1301 return;
1302 }
1303
1304void camellia_decrypt128(const u32 *subkey, u32 *io)
1305 { 530 {
1306 u32 il,ir,t0,t1; /* temporary valiables */ 531 Camellia_EncryptBlock_Rounds(keyBitLength==128?3:4,
1307 532 plaintext,keyTable,ciphertext);
1308 /* pre whitening but absorb kw2*/
1309 io[0] ^= CamelliaSubkeyL(24);
1310 io[1] ^= CamelliaSubkeyR(24);
1311
1312 /* main iteration */
1313 CAMELLIA_ROUNDSM(io[0],io[1],
1314 CamelliaSubkeyL(23),CamelliaSubkeyR(23),
1315 io[2],io[3],il,ir,t0,t1);
1316 CAMELLIA_ROUNDSM(io[2],io[3],
1317 CamelliaSubkeyL(22),CamelliaSubkeyR(22),
1318 io[0],io[1],il,ir,t0,t1);
1319 CAMELLIA_ROUNDSM(io[0],io[1],
1320 CamelliaSubkeyL(21),CamelliaSubkeyR(21),
1321 io[2],io[3],il,ir,t0,t1);
1322 CAMELLIA_ROUNDSM(io[2],io[3],
1323 CamelliaSubkeyL(20),CamelliaSubkeyR(20),
1324 io[0],io[1],il,ir,t0,t1);
1325 CAMELLIA_ROUNDSM(io[0],io[1],
1326 CamelliaSubkeyL(19),CamelliaSubkeyR(19),
1327 io[2],io[3],il,ir,t0,t1);
1328 CAMELLIA_ROUNDSM(io[2],io[3],
1329 CamelliaSubkeyL(18),CamelliaSubkeyR(18),
1330 io[0],io[1],il,ir,t0,t1);
1331
1332 CAMELLIA_FLS(io[0],io[1],io[2],io[3],
1333 CamelliaSubkeyL(17),CamelliaSubkeyR(17),
1334 CamelliaSubkeyL(16),CamelliaSubkeyR(16),
1335 t0,t1,il,ir);
1336
1337 CAMELLIA_ROUNDSM(io[0],io[1],
1338 CamelliaSubkeyL(15),CamelliaSubkeyR(15),
1339 io[2],io[3],il,ir,t0,t1);
1340 CAMELLIA_ROUNDSM(io[2],io[3],
1341 CamelliaSubkeyL(14),CamelliaSubkeyR(14),
1342 io[0],io[1],il,ir,t0,t1);
1343 CAMELLIA_ROUNDSM(io[0],io[1],
1344 CamelliaSubkeyL(13),CamelliaSubkeyR(13),
1345 io[2],io[3],il,ir,t0,t1);
1346 CAMELLIA_ROUNDSM(io[2],io[3],
1347 CamelliaSubkeyL(12),CamelliaSubkeyR(12),
1348 io[0],io[1],il,ir,t0,t1);
1349 CAMELLIA_ROUNDSM(io[0],io[1],
1350 CamelliaSubkeyL(11),CamelliaSubkeyR(11),
1351 io[2],io[3],il,ir,t0,t1);
1352 CAMELLIA_ROUNDSM(io[2],io[3],
1353 CamelliaSubkeyL(10),CamelliaSubkeyR(10),
1354 io[0],io[1],il,ir,t0,t1);
1355
1356 CAMELLIA_FLS(io[0],io[1],io[2],io[3],
1357 CamelliaSubkeyL(9),CamelliaSubkeyR(9),
1358 CamelliaSubkeyL(8),CamelliaSubkeyR(8),
1359 t0,t1,il,ir);
1360
1361 CAMELLIA_ROUNDSM(io[0],io[1],
1362 CamelliaSubkeyL(7),CamelliaSubkeyR(7),
1363 io[2],io[3],il,ir,t0,t1);
1364 CAMELLIA_ROUNDSM(io[2],io[3],
1365 CamelliaSubkeyL(6),CamelliaSubkeyR(6),
1366 io[0],io[1],il,ir,t0,t1);
1367 CAMELLIA_ROUNDSM(io[0],io[1],
1368 CamelliaSubkeyL(5),CamelliaSubkeyR(5),
1369 io[2],io[3],il,ir,t0,t1);
1370 CAMELLIA_ROUNDSM(io[2],io[3],
1371 CamelliaSubkeyL(4),CamelliaSubkeyR(4),
1372 io[0],io[1],il,ir,t0,t1);
1373 CAMELLIA_ROUNDSM(io[0],io[1],
1374 CamelliaSubkeyL(3),CamelliaSubkeyR(3),
1375 io[2],io[3],il,ir,t0,t1);
1376 CAMELLIA_ROUNDSM(io[2],io[3],
1377 CamelliaSubkeyL(2),CamelliaSubkeyR(2),
1378 io[0],io[1],il,ir,t0,t1);
1379
1380 /* post whitening but kw4 */
1381 io[2] ^= CamelliaSubkeyL(0);
1382 io[3] ^= CamelliaSubkeyR(0);
1383
1384 t0 = io[0];
1385 t1 = io[1];
1386 io[0] = io[2];
1387 io[1] = io[3];
1388 io[2] = t0;
1389 io[3] = t1;
1390
1391 return;
1392 } 533 }
1393 534
1394/** 535void Camellia_DecryptBlock_Rounds(int grandRounds, const u8 ciphertext[],
1395 * stuff for 192 and 256bit encryption/decryption 536 const KEY_TABLE_TYPE keyTable, u8 plaintext[])
1396 */
1397void camellia_encrypt256(const u32 *subkey, u32 *io)
1398 { 537 {
1399 u32 il,ir,t0,t1; /* temporary valiables */ 538 u32 s0,s1,s2,s3;
1400 539 const u32 *k = keyTable+grandRounds*16,*kend = keyTable+4;
1401 /* pre whitening but absorb kw2*/ 540
1402 io[0] ^= CamelliaSubkeyL(0); 541 s0 = GETU32(ciphertext) ^ k[0];
1403 io[1] ^= CamelliaSubkeyR(0); 542 s1 = GETU32(ciphertext+4) ^ k[1];
1404 543 s2 = GETU32(ciphertext+8) ^ k[2];
1405 /* main iteration */ 544 s3 = GETU32(ciphertext+12) ^ k[3];
1406 CAMELLIA_ROUNDSM(io[0],io[1], 545
1407 CamelliaSubkeyL(2),CamelliaSubkeyR(2), 546 while (1)
1408 io[2],io[3],il,ir,t0,t1); 547 {
1409 CAMELLIA_ROUNDSM(io[2],io[3], 548 /* Camellia makes 6 Feistel rounds */
1410 CamelliaSubkeyL(3),CamelliaSubkeyR(3), 549 k -= 12;
1411 io[0],io[1],il,ir,t0,t1); 550 Camellia_Feistel(s0,s1,s2,s3,k+10);
1412 CAMELLIA_ROUNDSM(io[0],io[1], 551 Camellia_Feistel(s2,s3,s0,s1,k+8);
1413 CamelliaSubkeyL(4),CamelliaSubkeyR(4), 552 Camellia_Feistel(s0,s1,s2,s3,k+6);
1414 io[2],io[3],il,ir,t0,t1); 553 Camellia_Feistel(s2,s3,s0,s1,k+4);
1415 CAMELLIA_ROUNDSM(io[2],io[3], 554 Camellia_Feistel(s0,s1,s2,s3,k+2);
1416 CamelliaSubkeyL(5),CamelliaSubkeyR(5), 555 Camellia_Feistel(s2,s3,s0,s1,k+0);
1417 io[0],io[1],il,ir,t0,t1); 556
1418 CAMELLIA_ROUNDSM(io[0],io[1], 557 if (k == kend) break;
1419 CamelliaSubkeyL(6),CamelliaSubkeyR(6), 558
1420 io[2],io[3],il,ir,t0,t1); 559 /* This is the same function as the diffusion function D
1421 CAMELLIA_ROUNDSM(io[2],io[3], 560 * of the accompanying documentation. See section 3.2
1422 CamelliaSubkeyL(7),CamelliaSubkeyR(7), 561 * for properties of the FLlayer function. */
1423 io[0],io[1],il,ir,t0,t1); 562 k -= 4;
1424 563 s1 ^= LeftRotate(s0 & k[2], 1);
1425 CAMELLIA_FLS(io[0],io[1],io[2],io[3], 564 s2 ^= s3 | k[1];
1426 CamelliaSubkeyL(8),CamelliaSubkeyR(8), 565 s0 ^= s1 | k[3];
1427 CamelliaSubkeyL(9),CamelliaSubkeyR(9), 566 s3 ^= LeftRotate(s2 & k[0], 1);
1428 t0,t1,il,ir); 567 }
1429 568
1430 CAMELLIA_ROUNDSM(io[0],io[1], 569 k -= 4;
1431 CamelliaSubkeyL(10),CamelliaSubkeyR(10), 570 s2 ^= k[0], s3 ^= k[1], s0 ^= k[2], s1 ^= k[3];
1432 io[2],io[3],il,ir,t0,t1); 571
1433 CAMELLIA_ROUNDSM(io[2],io[3], 572 PUTU32(plaintext, s2);
1434 CamelliaSubkeyL(11),CamelliaSubkeyR(11), 573 PUTU32(plaintext+4, s3);
1435 io[0],io[1],il,ir,t0,t1); 574 PUTU32(plaintext+8, s0);
1436 CAMELLIA_ROUNDSM(io[0],io[1], 575 PUTU32(plaintext+12,s1);
1437 CamelliaSubkeyL(12),CamelliaSubkeyR(12),
1438 io[2],io[3],il,ir,t0,t1);
1439 CAMELLIA_ROUNDSM(io[2],io[3],
1440 CamelliaSubkeyL(13),CamelliaSubkeyR(13),
1441 io[0],io[1],il,ir,t0,t1);
1442 CAMELLIA_ROUNDSM(io[0],io[1],
1443 CamelliaSubkeyL(14),CamelliaSubkeyR(14),
1444 io[2],io[3],il,ir,t0,t1);
1445 CAMELLIA_ROUNDSM(io[2],io[3],
1446 CamelliaSubkeyL(15),CamelliaSubkeyR(15),
1447 io[0],io[1],il,ir,t0,t1);
1448
1449 CAMELLIA_FLS(io[0],io[1],io[2],io[3],
1450 CamelliaSubkeyL(16),CamelliaSubkeyR(16),
1451 CamelliaSubkeyL(17),CamelliaSubkeyR(17),
1452 t0,t1,il,ir);
1453
1454 CAMELLIA_ROUNDSM(io[0],io[1],
1455 CamelliaSubkeyL(18),CamelliaSubkeyR(18),
1456 io[2],io[3],il,ir,t0,t1);
1457 CAMELLIA_ROUNDSM(io[2],io[3],
1458 CamelliaSubkeyL(19),CamelliaSubkeyR(19),
1459 io[0],io[1],il,ir,t0,t1);
1460 CAMELLIA_ROUNDSM(io[0],io[1],
1461 CamelliaSubkeyL(20),CamelliaSubkeyR(20),
1462 io[2],io[3],il,ir,t0,t1);
1463 CAMELLIA_ROUNDSM(io[2],io[3],
1464 CamelliaSubkeyL(21),CamelliaSubkeyR(21),
1465 io[0],io[1],il,ir,t0,t1);
1466 CAMELLIA_ROUNDSM(io[0],io[1],
1467 CamelliaSubkeyL(22),CamelliaSubkeyR(22),
1468 io[2],io[3],il,ir,t0,t1);
1469 CAMELLIA_ROUNDSM(io[2],io[3],
1470 CamelliaSubkeyL(23),CamelliaSubkeyR(23),
1471 io[0],io[1],il,ir,t0,t1);
1472
1473 CAMELLIA_FLS(io[0],io[1],io[2],io[3],
1474 CamelliaSubkeyL(24),CamelliaSubkeyR(24),
1475 CamelliaSubkeyL(25),CamelliaSubkeyR(25),
1476 t0,t1,il,ir);
1477
1478 CAMELLIA_ROUNDSM(io[0],io[1],
1479 CamelliaSubkeyL(26),CamelliaSubkeyR(26),
1480 io[2],io[3],il,ir,t0,t1);
1481 CAMELLIA_ROUNDSM(io[2],io[3],
1482 CamelliaSubkeyL(27),CamelliaSubkeyR(27),
1483 io[0],io[1],il,ir,t0,t1);
1484 CAMELLIA_ROUNDSM(io[0],io[1],
1485 CamelliaSubkeyL(28),CamelliaSubkeyR(28),
1486 io[2],io[3],il,ir,t0,t1);
1487 CAMELLIA_ROUNDSM(io[2],io[3],
1488 CamelliaSubkeyL(29),CamelliaSubkeyR(29),
1489 io[0],io[1],il,ir,t0,t1);
1490 CAMELLIA_ROUNDSM(io[0],io[1],
1491 CamelliaSubkeyL(30),CamelliaSubkeyR(30),
1492 io[2],io[3],il,ir,t0,t1);
1493 CAMELLIA_ROUNDSM(io[2],io[3],
1494 CamelliaSubkeyL(31),CamelliaSubkeyR(31),
1495 io[0],io[1],il,ir,t0,t1);
1496
1497 /* post whitening but kw4 */
1498 io[2] ^= CamelliaSubkeyL(32);
1499 io[3] ^= CamelliaSubkeyR(32);
1500
1501 t0 = io[0];
1502 t1 = io[1];
1503 io[0] = io[2];
1504 io[1] = io[3];
1505 io[2] = t0;
1506 io[3] = t1;
1507
1508 return;
1509 } 576 }
1510 577void Camellia_DecryptBlock(int keyBitLength, const u8 plaintext[],
1511void camellia_decrypt256(const u32 *subkey, u32 *io) 578 const KEY_TABLE_TYPE keyTable, u8 ciphertext[])
1512 { 579 {
1513 u32 il,ir,t0,t1; /* temporary valiables */ 580 Camellia_DecryptBlock_Rounds(keyBitLength==128?3:4,
1514 581 plaintext,keyTable,ciphertext);
1515 /* pre whitening but absorb kw2*/
1516 io[0] ^= CamelliaSubkeyL(32);
1517 io[1] ^= CamelliaSubkeyR(32);
1518
1519 /* main iteration */
1520 CAMELLIA_ROUNDSM(io[0],io[1],
1521 CamelliaSubkeyL(31),CamelliaSubkeyR(31),
1522 io[2],io[3],il,ir,t0,t1);
1523 CAMELLIA_ROUNDSM(io[2],io[3],
1524 CamelliaSubkeyL(30),CamelliaSubkeyR(30),
1525 io[0],io[1],il,ir,t0,t1);
1526 CAMELLIA_ROUNDSM(io[0],io[1],
1527 CamelliaSubkeyL(29),CamelliaSubkeyR(29),
1528 io[2],io[3],il,ir,t0,t1);
1529 CAMELLIA_ROUNDSM(io[2],io[3],
1530 CamelliaSubkeyL(28),CamelliaSubkeyR(28),
1531 io[0],io[1],il,ir,t0,t1);
1532 CAMELLIA_ROUNDSM(io[0],io[1],
1533 CamelliaSubkeyL(27),CamelliaSubkeyR(27),
1534 io[2],io[3],il,ir,t0,t1);
1535 CAMELLIA_ROUNDSM(io[2],io[3],
1536 CamelliaSubkeyL(26),CamelliaSubkeyR(26),
1537 io[0],io[1],il,ir,t0,t1);
1538
1539 CAMELLIA_FLS(io[0],io[1],io[2],io[3],
1540 CamelliaSubkeyL(25),CamelliaSubkeyR(25),
1541 CamelliaSubkeyL(24),CamelliaSubkeyR(24),
1542 t0,t1,il,ir);
1543
1544 CAMELLIA_ROUNDSM(io[0],io[1],
1545 CamelliaSubkeyL(23),CamelliaSubkeyR(23),
1546 io[2],io[3],il,ir,t0,t1);
1547 CAMELLIA_ROUNDSM(io[2],io[3],
1548 CamelliaSubkeyL(22),CamelliaSubkeyR(22),
1549 io[0],io[1],il,ir,t0,t1);
1550 CAMELLIA_ROUNDSM(io[0],io[1],
1551 CamelliaSubkeyL(21),CamelliaSubkeyR(21),
1552 io[2],io[3],il,ir,t0,t1);
1553 CAMELLIA_ROUNDSM(io[2],io[3],
1554 CamelliaSubkeyL(20),CamelliaSubkeyR(20),
1555 io[0],io[1],il,ir,t0,t1);
1556 CAMELLIA_ROUNDSM(io[0],io[1],
1557 CamelliaSubkeyL(19),CamelliaSubkeyR(19),
1558 io[2],io[3],il,ir,t0,t1);
1559 CAMELLIA_ROUNDSM(io[2],io[3],
1560 CamelliaSubkeyL(18),CamelliaSubkeyR(18),
1561 io[0],io[1],il,ir,t0,t1);
1562
1563 CAMELLIA_FLS(io[0],io[1],io[2],io[3],
1564 CamelliaSubkeyL(17),CamelliaSubkeyR(17),
1565 CamelliaSubkeyL(16),CamelliaSubkeyR(16),
1566 t0,t1,il,ir);
1567
1568 CAMELLIA_ROUNDSM(io[0],io[1],
1569 CamelliaSubkeyL(15),CamelliaSubkeyR(15),
1570 io[2],io[3],il,ir,t0,t1);
1571 CAMELLIA_ROUNDSM(io[2],io[3],
1572 CamelliaSubkeyL(14),CamelliaSubkeyR(14),
1573 io[0],io[1],il,ir,t0,t1);
1574 CAMELLIA_ROUNDSM(io[0],io[1],
1575 CamelliaSubkeyL(13),CamelliaSubkeyR(13),
1576 io[2],io[3],il,ir,t0,t1);
1577 CAMELLIA_ROUNDSM(io[2],io[3],
1578 CamelliaSubkeyL(12),CamelliaSubkeyR(12),
1579 io[0],io[1],il,ir,t0,t1);
1580 CAMELLIA_ROUNDSM(io[0],io[1],
1581 CamelliaSubkeyL(11),CamelliaSubkeyR(11),
1582 io[2],io[3],il,ir,t0,t1);
1583 CAMELLIA_ROUNDSM(io[2],io[3],
1584 CamelliaSubkeyL(10),CamelliaSubkeyR(10),
1585 io[0],io[1],il,ir,t0,t1);
1586
1587 CAMELLIA_FLS(io[0],io[1],io[2],io[3],
1588 CamelliaSubkeyL(9),CamelliaSubkeyR(9),
1589 CamelliaSubkeyL(8),CamelliaSubkeyR(8),
1590 t0,t1,il,ir);
1591
1592 CAMELLIA_ROUNDSM(io[0],io[1],
1593 CamelliaSubkeyL(7),CamelliaSubkeyR(7),
1594 io[2],io[3],il,ir,t0,t1);
1595 CAMELLIA_ROUNDSM(io[2],io[3],
1596 CamelliaSubkeyL(6),CamelliaSubkeyR(6),
1597 io[0],io[1],il,ir,t0,t1);
1598 CAMELLIA_ROUNDSM(io[0],io[1],
1599 CamelliaSubkeyL(5),CamelliaSubkeyR(5),
1600 io[2],io[3],il,ir,t0,t1);
1601 CAMELLIA_ROUNDSM(io[2],io[3],
1602 CamelliaSubkeyL(4),CamelliaSubkeyR(4),
1603 io[0],io[1],il,ir,t0,t1);
1604 CAMELLIA_ROUNDSM(io[0],io[1],
1605 CamelliaSubkeyL(3),CamelliaSubkeyR(3),
1606 io[2],io[3],il,ir,t0,t1);
1607 CAMELLIA_ROUNDSM(io[2],io[3],
1608 CamelliaSubkeyL(2),CamelliaSubkeyR(2),
1609 io[0],io[1],il,ir,t0,t1);
1610
1611 /* post whitening but kw4 */
1612 io[2] ^= CamelliaSubkeyL(0);
1613 io[3] ^= CamelliaSubkeyR(0);
1614
1615 t0 = io[0];
1616 t1 = io[1];
1617 io[0] = io[2];
1618 io[1] = io[3];
1619 io[2] = t0;
1620 io[3] = t1;
1621
1622 return;
1623 } 582 }
1624
diff --git a/src/lib/libcrypto/camellia/camellia.h b/src/lib/libcrypto/camellia/camellia.h
index b8a8b6e10b..cf0457dd97 100644
--- a/src/lib/libcrypto/camellia/camellia.h
+++ b/src/lib/libcrypto/camellia/camellia.h
@@ -58,6 +58,8 @@
58#error CAMELLIA is disabled. 58#error CAMELLIA is disabled.
59#endif 59#endif
60 60
61#include <stddef.h>
62
61#define CAMELLIA_ENCRYPT 1 63#define CAMELLIA_ENCRYPT 1
62#define CAMELLIA_DECRYPT 0 64#define CAMELLIA_DECRYPT 0
63 65
@@ -74,24 +76,18 @@ extern "C" {
74#define CAMELLIA_TABLE_BYTE_LEN 272 76#define CAMELLIA_TABLE_BYTE_LEN 272
75#define CAMELLIA_TABLE_WORD_LEN (CAMELLIA_TABLE_BYTE_LEN / 4) 77#define CAMELLIA_TABLE_WORD_LEN (CAMELLIA_TABLE_BYTE_LEN / 4)
76 78
77 /* to match with WORD */ 79typedef unsigned int KEY_TABLE_TYPE[CAMELLIA_TABLE_WORD_LEN]; /* to match with WORD */
78typedef unsigned int KEY_TABLE_TYPE[CAMELLIA_TABLE_WORD_LEN];
79 80
80struct camellia_key_st 81struct camellia_key_st
81 { 82 {
82 KEY_TABLE_TYPE rd_key; 83 union {
83 int bitLength; 84 double d; /* ensures 64-bit align */
84 void (*enc)(const unsigned int *subkey, unsigned int *io); 85 KEY_TABLE_TYPE rd_key;
85 void (*dec)(const unsigned int *subkey, unsigned int *io); 86 } u;
87 int grand_rounds;
86 }; 88 };
87
88typedef struct camellia_key_st CAMELLIA_KEY; 89typedef struct camellia_key_st CAMELLIA_KEY;
89 90
90#ifdef OPENSSL_FIPS
91int private_Camellia_set_key(const unsigned char *userKey, const int bits,
92 CAMELLIA_KEY *key);
93#endif
94
95int Camellia_set_key(const unsigned char *userKey, const int bits, 91int Camellia_set_key(const unsigned char *userKey, const int bits,
96 CAMELLIA_KEY *key); 92 CAMELLIA_KEY *key);
97 93
@@ -103,25 +99,22 @@ void Camellia_decrypt(const unsigned char *in, unsigned char *out,
103void Camellia_ecb_encrypt(const unsigned char *in, unsigned char *out, 99void Camellia_ecb_encrypt(const unsigned char *in, unsigned char *out,
104 const CAMELLIA_KEY *key, const int enc); 100 const CAMELLIA_KEY *key, const int enc);
105void Camellia_cbc_encrypt(const unsigned char *in, unsigned char *out, 101void Camellia_cbc_encrypt(const unsigned char *in, unsigned char *out,
106 const unsigned long length, const CAMELLIA_KEY *key, 102 size_t length, const CAMELLIA_KEY *key,
107 unsigned char *ivec, const int enc); 103 unsigned char *ivec, const int enc);
108void Camellia_cfb128_encrypt(const unsigned char *in, unsigned char *out, 104void Camellia_cfb128_encrypt(const unsigned char *in, unsigned char *out,
109 const unsigned long length, const CAMELLIA_KEY *key, 105 size_t length, const CAMELLIA_KEY *key,
110 unsigned char *ivec, int *num, const int enc); 106 unsigned char *ivec, int *num, const int enc);
111void Camellia_cfb1_encrypt(const unsigned char *in, unsigned char *out, 107void Camellia_cfb1_encrypt(const unsigned char *in, unsigned char *out,
112 const unsigned long length, const CAMELLIA_KEY *key, 108 size_t length, const CAMELLIA_KEY *key,
113 unsigned char *ivec, int *num, const int enc); 109 unsigned char *ivec, int *num, const int enc);
114void Camellia_cfb8_encrypt(const unsigned char *in, unsigned char *out, 110void Camellia_cfb8_encrypt(const unsigned char *in, unsigned char *out,
115 const unsigned long length, const CAMELLIA_KEY *key, 111 size_t length, const CAMELLIA_KEY *key,
116 unsigned char *ivec, int *num, const int enc); 112 unsigned char *ivec, int *num, const int enc);
117void Camellia_cfbr_encrypt_block(const unsigned char *in,unsigned char *out,
118 const int nbits,const CAMELLIA_KEY *key,
119 unsigned char *ivec,const int enc);
120void Camellia_ofb128_encrypt(const unsigned char *in, unsigned char *out, 113void Camellia_ofb128_encrypt(const unsigned char *in, unsigned char *out,
121 const unsigned long length, const CAMELLIA_KEY *key, 114 size_t length, const CAMELLIA_KEY *key,
122 unsigned char *ivec, int *num); 115 unsigned char *ivec, int *num);
123void Camellia_ctr128_encrypt(const unsigned char *in, unsigned char *out, 116void Camellia_ctr128_encrypt(const unsigned char *in, unsigned char *out,
124 const unsigned long length, const CAMELLIA_KEY *key, 117 size_t length, const CAMELLIA_KEY *key,
125 unsigned char ivec[CAMELLIA_BLOCK_SIZE], 118 unsigned char ivec[CAMELLIA_BLOCK_SIZE],
126 unsigned char ecount_buf[CAMELLIA_BLOCK_SIZE], 119 unsigned char ecount_buf[CAMELLIA_BLOCK_SIZE],
127 unsigned int *num); 120 unsigned int *num);
@@ -131,4 +124,3 @@ void Camellia_ctr128_encrypt(const unsigned char *in, unsigned char *out,
131#endif 124#endif
132 125
133#endif /* !HEADER_Camellia_H */ 126#endif /* !HEADER_Camellia_H */
134
diff --git a/src/lib/libcrypto/camellia/cmll_cbc.c b/src/lib/libcrypto/camellia/cmll_cbc.c
index 4141a7b59b..4c8d455ade 100644
--- a/src/lib/libcrypto/camellia/cmll_cbc.c
+++ b/src/lib/libcrypto/camellia/cmll_cbc.c
@@ -49,225 +49,16 @@
49 * 49 *
50 */ 50 */
51 51
52#ifndef CAMELLIA_DEBUG
53# ifndef NDEBUG
54# define NDEBUG
55# endif
56#endif
57#include <assert.h>
58#include <stdio.h>
59#include <string.h>
60
61#include <openssl/camellia.h> 52#include <openssl/camellia.h>
62#include "cmll_locl.h" 53#include <openssl/modes.h>
63 54
64void Camellia_cbc_encrypt(const unsigned char *in, unsigned char *out, 55void Camellia_cbc_encrypt(const unsigned char *in, unsigned char *out,
65 const unsigned long length, const CAMELLIA_KEY *key, 56 size_t len, const CAMELLIA_KEY *key,
66 unsigned char *ivec, const int enc) { 57 unsigned char *ivec, const int enc)
67 58 {
68 unsigned long n;
69 unsigned long len = length;
70 const unsigned char *iv = ivec;
71 union { u32 t32[CAMELLIA_BLOCK_SIZE/sizeof(u32)];
72 u8 t8 [CAMELLIA_BLOCK_SIZE]; } tmp;
73 const union { long one; char little; } camellia_endian = {1};
74
75
76 assert(in && out && key && ivec);
77 assert((CAMELLIA_ENCRYPT == enc)||(CAMELLIA_DECRYPT == enc));
78 59
79 if(((size_t)in|(size_t)out|(size_t)ivec) % sizeof(u32) == 0) 60 if (enc)
80 { 61 CRYPTO_cbc128_encrypt(in,out,len,key,ivec,(block128_f)Camellia_encrypt);
81 if (CAMELLIA_ENCRYPT == enc) 62 else
82 { 63 CRYPTO_cbc128_decrypt(in,out,len,key,ivec,(block128_f)Camellia_decrypt);
83 while (len >= CAMELLIA_BLOCK_SIZE) 64 }
84 {
85 XOR4WORD2((u32 *)out,
86 (u32 *)in, (u32 *)iv);
87 if (camellia_endian.little)
88 SWAP4WORD((u32 *)out);
89 key->enc(key->rd_key, (u32 *)out);
90 if (camellia_endian.little)
91 SWAP4WORD((u32 *)out);
92 iv = out;
93 len -= CAMELLIA_BLOCK_SIZE;
94 in += CAMELLIA_BLOCK_SIZE;
95 out += CAMELLIA_BLOCK_SIZE;
96 }
97 if (len)
98 {
99 for(n=0; n < len; ++n)
100 out[n] = in[n] ^ iv[n];
101 for(n=len; n < CAMELLIA_BLOCK_SIZE; ++n)
102 out[n] = iv[n];
103 if (camellia_endian.little)
104 SWAP4WORD((u32 *)out);
105 key->enc(key->rd_key, (u32 *)out);
106 if (camellia_endian.little)
107 SWAP4WORD((u32 *)out);
108 iv = out;
109 }
110 memcpy(ivec,iv,CAMELLIA_BLOCK_SIZE);
111 }
112 else if (in != out)
113 {
114 while (len >= CAMELLIA_BLOCK_SIZE)
115 {
116 memcpy(out,in,CAMELLIA_BLOCK_SIZE);
117 if (camellia_endian.little)
118 SWAP4WORD((u32 *)out);
119 key->dec(key->rd_key,(u32 *)out);
120 if (camellia_endian.little)
121 SWAP4WORD((u32 *)out);
122 XOR4WORD((u32 *)out, (u32 *)iv);
123 iv = in;
124 len -= CAMELLIA_BLOCK_SIZE;
125 in += CAMELLIA_BLOCK_SIZE;
126 out += CAMELLIA_BLOCK_SIZE;
127 }
128 if (len)
129 {
130 memcpy(tmp.t8, in, CAMELLIA_BLOCK_SIZE);
131 if (camellia_endian.little)
132 SWAP4WORD(tmp.t32);
133 key->dec(key->rd_key, tmp.t32);
134 if (camellia_endian.little)
135 SWAP4WORD(tmp.t32);
136 for(n=0; n < len; ++n)
137 out[n] = tmp.t8[n] ^ iv[n];
138 iv = in;
139 }
140 memcpy(ivec,iv,CAMELLIA_BLOCK_SIZE);
141 }
142 else /* in == out */
143 {
144 while (len >= CAMELLIA_BLOCK_SIZE)
145 {
146 memcpy(tmp.t8, in, CAMELLIA_BLOCK_SIZE);
147 if (camellia_endian.little)
148 SWAP4WORD((u32 *)out);
149 key->dec(key->rd_key, (u32 *)out);
150 if (camellia_endian.little)
151 SWAP4WORD((u32 *)out);
152 XOR4WORD((u32 *)out, (u32 *)ivec);
153 memcpy(ivec, tmp.t8, CAMELLIA_BLOCK_SIZE);
154 len -= CAMELLIA_BLOCK_SIZE;
155 in += CAMELLIA_BLOCK_SIZE;
156 out += CAMELLIA_BLOCK_SIZE;
157 }
158 if (len)
159 {
160 memcpy(tmp.t8, in, CAMELLIA_BLOCK_SIZE);
161 if (camellia_endian.little)
162 SWAP4WORD((u32 *)out);
163 key->dec(key->rd_key,(u32 *)out);
164 if (camellia_endian.little)
165 SWAP4WORD((u32 *)out);
166 for(n=0; n < len; ++n)
167 out[n] ^= ivec[n];
168 for(n=len; n < CAMELLIA_BLOCK_SIZE; ++n)
169 out[n] = tmp.t8[n];
170 memcpy(ivec, tmp.t8, CAMELLIA_BLOCK_SIZE);
171 }
172 }
173 }
174 else /* no aligned */
175 {
176 if (CAMELLIA_ENCRYPT == enc)
177 {
178 while (len >= CAMELLIA_BLOCK_SIZE)
179 {
180 for(n=0; n < CAMELLIA_BLOCK_SIZE; ++n)
181 tmp.t8[n] = in[n] ^ iv[n];
182 if (camellia_endian.little)
183 SWAP4WORD(tmp.t32);
184 key->enc(key->rd_key, tmp.t32);
185 if (camellia_endian.little)
186 SWAP4WORD(tmp.t32);
187 memcpy(out, tmp.t8, CAMELLIA_BLOCK_SIZE);
188 iv = out;
189 len -= CAMELLIA_BLOCK_SIZE;
190 in += CAMELLIA_BLOCK_SIZE;
191 out += CAMELLIA_BLOCK_SIZE;
192 }
193 if (len)
194 {
195 for(n=0; n < len; ++n)
196 tmp.t8[n] = in[n] ^ iv[n];
197 for(n=len; n < CAMELLIA_BLOCK_SIZE; ++n)
198 tmp.t8[n] = iv[n];
199 if (camellia_endian.little)
200 SWAP4WORD(tmp.t32);
201 key->enc(key->rd_key, tmp.t32);
202 if (camellia_endian.little)
203 SWAP4WORD(tmp.t32);
204 memcpy(out, tmp.t8, CAMELLIA_BLOCK_SIZE);
205 iv = out;
206 }
207 memcpy(ivec,iv,CAMELLIA_BLOCK_SIZE);
208 }
209 else if (in != out)
210 {
211 while (len >= CAMELLIA_BLOCK_SIZE)
212 {
213 memcpy(tmp.t8,in,CAMELLIA_BLOCK_SIZE);
214 if (camellia_endian.little)
215 SWAP4WORD(tmp.t32);
216 key->dec(key->rd_key,tmp.t32);
217 if (camellia_endian.little)
218 SWAP4WORD(tmp.t32);
219 for(n=0; n < CAMELLIA_BLOCK_SIZE; ++n)
220 out[n] = tmp.t8[n] ^ iv[n];
221 iv = in;
222 len -= CAMELLIA_BLOCK_SIZE;
223 in += CAMELLIA_BLOCK_SIZE;
224 out += CAMELLIA_BLOCK_SIZE;
225 }
226 if (len)
227 {
228 memcpy(tmp.t8, in, CAMELLIA_BLOCK_SIZE);
229 if (camellia_endian.little)
230 SWAP4WORD(tmp.t32);
231 key->dec(key->rd_key, tmp.t32);
232 if (camellia_endian.little)
233 SWAP4WORD(tmp.t32);
234 for(n=0; n < len; ++n)
235 out[n] = tmp.t8[n] ^ iv[n];
236 iv = in;
237 }
238 memcpy(ivec,iv,CAMELLIA_BLOCK_SIZE);
239 }
240 else
241 {
242 while (len >= CAMELLIA_BLOCK_SIZE)
243 {
244 memcpy(tmp.t8, in, CAMELLIA_BLOCK_SIZE);
245 if (camellia_endian.little)
246 SWAP4WORD(tmp.t32);
247 key->dec(key->rd_key, tmp.t32);
248 if (camellia_endian.little)
249 SWAP4WORD(tmp.t32);
250 for(n=0; n < CAMELLIA_BLOCK_SIZE; ++n)
251 tmp.t8[n] ^= ivec[n];
252 memcpy(ivec, in, CAMELLIA_BLOCK_SIZE);
253 memcpy(out, tmp.t8, CAMELLIA_BLOCK_SIZE);
254 len -= CAMELLIA_BLOCK_SIZE;
255 in += CAMELLIA_BLOCK_SIZE;
256 out += CAMELLIA_BLOCK_SIZE;
257 }
258 if (len)
259 {
260 memcpy(tmp.t8, in, CAMELLIA_BLOCK_SIZE);
261 if (camellia_endian.little)
262 SWAP4WORD(tmp.t32);
263 key->dec(key->rd_key,tmp.t32);
264 if (camellia_endian.little)
265 SWAP4WORD(tmp.t32);
266 for(n=0; n < len; ++n)
267 tmp.t8[n] ^= ivec[n];
268 memcpy(ivec, in, CAMELLIA_BLOCK_SIZE);
269 memcpy(out,tmp.t8,len);
270 }
271 }
272 }
273}
diff --git a/src/lib/libcrypto/camellia/cmll_cfb.c b/src/lib/libcrypto/camellia/cmll_cfb.c
index af0f9f49ad..3d81b51d3f 100644
--- a/src/lib/libcrypto/camellia/cmll_cfb.c
+++ b/src/lib/libcrypto/camellia/cmll_cfb.c
@@ -105,17 +105,8 @@
105 * [including the GNU Public Licence.] 105 * [including the GNU Public Licence.]
106 */ 106 */
107 107
108#ifndef CAMELLIA_DEBUG
109# ifndef NDEBUG
110# define NDEBUG
111# endif
112#endif
113#include <assert.h>
114#include <string.h>
115
116#include <openssl/camellia.h> 108#include <openssl/camellia.h>
117#include "cmll_locl.h" 109#include <openssl/modes.h>
118#include "e_os.h"
119 110
120 111
121/* The input and output encrypted as though 128bit cfb mode is being 112/* The input and output encrypted as though 128bit cfb mode is being
@@ -124,112 +115,25 @@
124 */ 115 */
125 116
126void Camellia_cfb128_encrypt(const unsigned char *in, unsigned char *out, 117void Camellia_cfb128_encrypt(const unsigned char *in, unsigned char *out,
127 const unsigned long length, const CAMELLIA_KEY *key, 118 size_t length, const CAMELLIA_KEY *key,
128 unsigned char *ivec, int *num, const int enc) 119 unsigned char *ivec, int *num, const int enc)
129 { 120 {
130 121
131 unsigned int n; 122 CRYPTO_cfb128_encrypt(in,out,length,key,ivec,num,enc,(block128_f)Camellia_encrypt);
132 unsigned long l = length;
133 unsigned char c;
134
135 assert(in && out && key && ivec && num);
136
137 n = *num;
138
139 if (enc)
140 {
141 while (l--)
142 {
143 if (n == 0)
144 {
145 Camellia_encrypt(ivec, ivec, key);
146 }
147 ivec[n] = *(out++) = *(in++) ^ ivec[n];
148 n = (n+1) % CAMELLIA_BLOCK_SIZE;
149 }
150 }
151 else
152 {
153 while (l--)
154 {
155 if (n == 0)
156 {
157 Camellia_encrypt(ivec, ivec, key);
158 }
159 c = *(in);
160 *(out++) = *(in++) ^ ivec[n];
161 ivec[n] = c;
162 n = (n+1) % CAMELLIA_BLOCK_SIZE;
163 }
164 }
165
166 *num=n;
167 }
168
169/* This expects a single block of size nbits for both in and out. Note that
170 it corrupts any extra bits in the last byte of out */
171void Camellia_cfbr_encrypt_block(const unsigned char *in,unsigned char *out,
172 const int nbits,const CAMELLIA_KEY *key,
173 unsigned char *ivec,const int enc)
174 {
175 int n,rem,num;
176 unsigned char ovec[CAMELLIA_BLOCK_SIZE*2];
177
178 if (nbits<=0 || nbits>128) return;
179
180 /* fill in the first half of the new IV with the current IV */
181 memcpy(ovec,ivec,CAMELLIA_BLOCK_SIZE);
182 /* construct the new IV */
183 Camellia_encrypt(ivec,ivec,key);
184 num = (nbits+7)/8;
185 if (enc) /* encrypt the input */
186 for(n=0 ; n < num ; ++n)
187 out[n] = (ovec[CAMELLIA_BLOCK_SIZE+n] = in[n] ^ ivec[n]);
188 else /* decrypt the input */
189 for(n=0 ; n < num ; ++n)
190 out[n] = (ovec[CAMELLIA_BLOCK_SIZE+n] = in[n]) ^ ivec[n];
191 /* shift ovec left... */
192 rem = nbits%8;
193 num = nbits/8;
194 if(rem==0)
195 memcpy(ivec,ovec+num,CAMELLIA_BLOCK_SIZE);
196 else
197 for(n=0 ; n < CAMELLIA_BLOCK_SIZE ; ++n)
198 ivec[n] = ovec[n+num]<<rem | ovec[n+num+1]>>(8-rem);
199
200 /* it is not necessary to cleanse ovec, since the IV is not secret */
201 } 123 }
202 124
203/* N.B. This expects the input to be packed, MS bit first */ 125/* N.B. This expects the input to be packed, MS bit first */
204void Camellia_cfb1_encrypt(const unsigned char *in, unsigned char *out, 126void Camellia_cfb1_encrypt(const unsigned char *in, unsigned char *out,
205 const unsigned long length, const CAMELLIA_KEY *key, 127 size_t length, const CAMELLIA_KEY *key,
206 unsigned char *ivec, int *num, const int enc) 128 unsigned char *ivec, int *num, const int enc)
207 { 129 {
208 unsigned int n; 130 CRYPTO_cfb128_1_encrypt(in,out,length,key,ivec,num,enc,(block128_f)Camellia_encrypt);
209 unsigned char c[1],d[1];
210
211 assert(in && out && key && ivec && num);
212 assert(*num == 0);
213
214 memset(out,0,(length+7)/8);
215 for(n=0 ; n < length ; ++n)
216 {
217 c[0]=(in[n/8]&(1 << (7-n%8))) ? 0x80 : 0;
218 Camellia_cfbr_encrypt_block(c,d,1,key,ivec,enc);
219 out[n/8]=(out[n/8]&~(1 << (7-n%8)))|((d[0]&0x80) >> (n%8));
220 }
221 } 131 }
222 132
223void Camellia_cfb8_encrypt(const unsigned char *in, unsigned char *out, 133void Camellia_cfb8_encrypt(const unsigned char *in, unsigned char *out,
224 const unsigned long length, const CAMELLIA_KEY *key, 134 size_t length, const CAMELLIA_KEY *key,
225 unsigned char *ivec, int *num, const int enc) 135 unsigned char *ivec, int *num, const int enc)
226 { 136 {
227 unsigned int n; 137 CRYPTO_cfb128_8_encrypt(in,out,length,key,ivec,num,enc,(block128_f)Camellia_encrypt);
228
229 assert(in && out && key && ivec && num);
230 assert(*num == 0);
231
232 for(n=0 ; n < length ; ++n)
233 Camellia_cfbr_encrypt_block(&in[n],&out[n],8,key,ivec,enc);
234 } 138 }
235 139
diff --git a/src/lib/libcrypto/camellia/cmll_ctr.c b/src/lib/libcrypto/camellia/cmll_ctr.c
index cc21b70890..014e621a34 100644
--- a/src/lib/libcrypto/camellia/cmll_ctr.c
+++ b/src/lib/libcrypto/camellia/cmll_ctr.c
@@ -49,95 +49,16 @@
49 * 49 *
50 */ 50 */
51 51
52#ifndef CAMELLIA_DEBUG
53# ifndef NDEBUG
54# define NDEBUG
55# endif
56#endif
57#include <assert.h>
58
59#include <openssl/camellia.h> 52#include <openssl/camellia.h>
60#include "cmll_locl.h" 53#include <openssl/modes.h>
61
62/* NOTE: the IV/counter CTR mode is big-endian. The rest of the Camellia code
63 * is endian-neutral. */
64/* increment counter (128-bit int) by 1 */
65static void Camellia_ctr128_inc(unsigned char *counter)
66 {
67 unsigned long c;
68
69 /* Grab bottom dword of counter and increment */
70 c = GETU32(counter + 12);
71 c++; c &= 0xFFFFFFFF;
72 PUTU32(counter + 12, c);
73
74 /* if no overflow, we're done */
75 if (c)
76 return;
77
78 /* Grab 1st dword of counter and increment */
79 c = GETU32(counter + 8);
80 c++; c &= 0xFFFFFFFF;
81 PUTU32(counter + 8, c);
82
83 /* if no overflow, we're done */
84 if (c)
85 return;
86
87 /* Grab 2nd dword of counter and increment */
88 c = GETU32(counter + 4);
89 c++; c &= 0xFFFFFFFF;
90 PUTU32(counter + 4, c);
91
92 /* if no overflow, we're done */
93 if (c)
94 return;
95 54
96 /* Grab top dword of counter and increment */
97 c = GETU32(counter + 0);
98 c++; c &= 0xFFFFFFFF;
99 PUTU32(counter + 0, c);
100 }
101
102/* The input encrypted as though 128bit counter mode is being
103 * used. The extra state information to record how much of the
104 * 128bit block we have used is contained in *num, and the
105 * encrypted counter is kept in ecount_buf. Both *num and
106 * ecount_buf must be initialised with zeros before the first
107 * call to Camellia_ctr128_encrypt().
108 *
109 * This algorithm assumes that the counter is in the x lower bits
110 * of the IV (ivec), and that the application has full control over
111 * overflow and the rest of the IV. This implementation takes NO
112 * responsability for checking that the counter doesn't overflow
113 * into the rest of the IV when incremented.
114 */
115void Camellia_ctr128_encrypt(const unsigned char *in, unsigned char *out, 55void Camellia_ctr128_encrypt(const unsigned char *in, unsigned char *out,
116 const unsigned long length, const CAMELLIA_KEY *key, 56 size_t length, const CAMELLIA_KEY *key,
117 unsigned char ivec[CAMELLIA_BLOCK_SIZE], 57 unsigned char ivec[CAMELLIA_BLOCK_SIZE],
118 unsigned char ecount_buf[CAMELLIA_BLOCK_SIZE], 58 unsigned char ecount_buf[CAMELLIA_BLOCK_SIZE],
119 unsigned int *num) 59 unsigned int *num)
120 { 60 {
121 61
122 unsigned int n; 62 CRYPTO_ctr128_encrypt(in,out,length,key,ivec,ecount_buf,num,(block128_f)Camellia_encrypt);
123 unsigned long l=length;
124
125 assert(in && out && key && counter && num);
126 assert(*num < CAMELLIA_BLOCK_SIZE);
127
128 n = *num;
129
130 while (l--)
131 {
132 if (n == 0)
133 {
134 Camellia_encrypt(ivec, ecount_buf, key);
135 Camellia_ctr128_inc(ivec);
136 }
137 *(out++) = *(in++) ^ ecount_buf[n];
138 n = (n+1) % CAMELLIA_BLOCK_SIZE;
139 }
140
141 *num=n;
142 } 63 }
143 64
diff --git a/src/lib/libcrypto/camellia/cmll_locl.h b/src/lib/libcrypto/camellia/cmll_locl.h
index 2ac2e95435..4a4d880d16 100644
--- a/src/lib/libcrypto/camellia/cmll_locl.h
+++ b/src/lib/libcrypto/camellia/cmll_locl.h
@@ -68,98 +68,16 @@
68#ifndef HEADER_CAMELLIA_LOCL_H 68#ifndef HEADER_CAMELLIA_LOCL_H
69#define HEADER_CAMELLIA_LOCL_H 69#define HEADER_CAMELLIA_LOCL_H
70 70
71#include "openssl/e_os2.h" 71typedef unsigned int u32;
72#include <stdio.h>
73#include <stdlib.h>
74#include <string.h>
75
76typedef unsigned char u8; 72typedef unsigned char u8;
77typedef unsigned int u32;
78
79#ifdef __cplusplus
80extern "C" {
81#endif
82
83#if defined(_MSC_VER) && (defined(_M_IX86) || defined(_M_AMD64) || defined(_M_X64))
84# define SWAP(x) ( _lrotl(x, 8) & 0x00ff00ff | _lrotr(x, 8) & 0xff00ff00 )
85# define GETU32(p) SWAP(*((u32 *)(p)))
86# define PUTU32(ct, st) { *((u32 *)(ct)) = SWAP((st)); }
87# define CAMELLIA_SWAP4(x) (x = ( _lrotl(x, 8) & 0x00ff00ff | _lrotr(x, 8) & 0xff00ff00) )
88
89#else /* not windows */
90# define GETU32(pt) (((u32)(pt)[0] << 24) \
91 ^ ((u32)(pt)[1] << 16) \
92 ^ ((u32)(pt)[2] << 8) \
93 ^ ((u32)(pt)[3]))
94
95# define PUTU32(ct, st) { (ct)[0] = (u8)((st) >> 24); \
96 (ct)[1] = (u8)((st) >> 16); \
97 (ct)[2] = (u8)((st) >> 8); \
98 (ct)[3] = (u8)(st); }
99
100#if (defined (__GNUC__) && (defined(__x86_64__) || defined(__x86_64)))
101#define CAMELLIA_SWAP4(x) \
102 do{\
103 asm("bswap %1" : "+r" (x));\
104 }while(0)
105#else
106#define CAMELLIA_SWAP4(x) \
107 do{\
108 x = ((u32)x << 16) + ((u32)x >> 16);\
109 x = (((u32)x & 0xff00ff) << 8) + (((u32)x >> 8) & 0xff00ff);\
110 } while(0)
111#endif
112#endif
113
114#define COPY4WORD(dst, src) \
115 do \
116 { \
117 (dst)[0]=(src)[0]; \
118 (dst)[1]=(src)[1]; \
119 (dst)[2]=(src)[2]; \
120 (dst)[3]=(src)[3]; \
121 }while(0)
122
123#define SWAP4WORD(word) \
124 do \
125 { \
126 CAMELLIA_SWAP4((word)[0]); \
127 CAMELLIA_SWAP4((word)[1]); \
128 CAMELLIA_SWAP4((word)[2]); \
129 CAMELLIA_SWAP4((word)[3]); \
130 }while(0)
131
132#define XOR4WORD(a, b)/* a = a ^ b */ \
133 do \
134 { \
135 (a)[0]^=(b)[0]; \
136 (a)[1]^=(b)[1]; \
137 (a)[2]^=(b)[2]; \
138 (a)[3]^=(b)[3]; \
139 }while(0)
140
141#define XOR4WORD2(a, b, c)/* a = b ^ c */ \
142 do \
143 { \
144 (a)[0]=(b)[0]^(c)[0]; \
145 (a)[1]=(b)[1]^(c)[1]; \
146 (a)[2]=(b)[2]^(c)[2]; \
147 (a)[3]=(b)[3]^(c)[3]; \
148 }while(0)
149
150
151void camellia_setup128(const u8 *key, u32 *subkey);
152void camellia_setup192(const u8 *key, u32 *subkey);
153void camellia_setup256(const u8 *key, u32 *subkey);
154
155void camellia_encrypt128(const u32 *subkey, u32 *io);
156void camellia_decrypt128(const u32 *subkey, u32 *io);
157void camellia_encrypt256(const u32 *subkey, u32 *io);
158void camellia_decrypt256(const u32 *subkey, u32 *io);
159
160#ifdef __cplusplus
161}
162#endif
163 73
74int Camellia_Ekeygen(int keyBitLength, const u8 *rawKey, KEY_TABLE_TYPE keyTable);
75void Camellia_EncryptBlock_Rounds(int grandRounds, const u8 plaintext[],
76 const KEY_TABLE_TYPE keyTable, u8 ciphertext[]);
77void Camellia_DecryptBlock_Rounds(int grandRounds, const u8 ciphertext[],
78 const KEY_TABLE_TYPE keyTable, u8 plaintext[]);
79void Camellia_EncryptBlock(int keyBitLength, const u8 plaintext[],
80 const KEY_TABLE_TYPE keyTable, u8 ciphertext[]);
81void Camellia_DecryptBlock(int keyBitLength, const u8 ciphertext[],
82 const KEY_TABLE_TYPE keyTable, u8 plaintext[]);
164#endif /* #ifndef HEADER_CAMELLIA_LOCL_H */ 83#endif /* #ifndef HEADER_CAMELLIA_LOCL_H */
165
diff --git a/src/lib/libcrypto/camellia/cmll_misc.c b/src/lib/libcrypto/camellia/cmll_misc.c
index 2cd7aba9bb..f44689124b 100644
--- a/src/lib/libcrypto/camellia/cmll_misc.c
+++ b/src/lib/libcrypto/camellia/cmll_misc.c
@@ -52,78 +52,28 @@
52#include <openssl/opensslv.h> 52#include <openssl/opensslv.h>
53#include <openssl/camellia.h> 53#include <openssl/camellia.h>
54#include "cmll_locl.h" 54#include "cmll_locl.h"
55#include <openssl/crypto.h>
56#ifdef OPENSSL_FIPS
57#include <openssl/fips.h>
58#endif
59 55
60const char CAMELLIA_version[]="CAMELLIA" OPENSSL_VERSION_PTEXT; 56const char CAMELLIA_version[]="CAMELLIA" OPENSSL_VERSION_PTEXT;
61 57
62int Camellia_set_key(const unsigned char *userKey, const int bits, 58int Camellia_set_key(const unsigned char *userKey, const int bits,
63 CAMELLIA_KEY *key) 59 CAMELLIA_KEY *key)
64#ifdef OPENSSL_FIPS
65 { 60 {
66 if (FIPS_mode()) 61 if(!userKey || !key)
67 FIPS_BAD_ABORT(CAMELLIA)
68 return private_Camellia_set_key(userKey, bits, key);
69 }
70int private_Camellia_set_key(const unsigned char *userKey, const int bits,
71 CAMELLIA_KEY *key)
72#endif
73 {
74 if (!userKey || !key)
75 {
76 return -1; 62 return -1;
77 } 63 if(bits != 128 && bits != 192 && bits != 256)
78
79 switch(bits)
80 {
81 case 128:
82 camellia_setup128(userKey, (unsigned int *)key->rd_key);
83 key->enc = camellia_encrypt128;
84 key->dec = camellia_decrypt128;
85 break;
86 case 192:
87 camellia_setup192(userKey, (unsigned int *)key->rd_key);
88 key->enc = camellia_encrypt256;
89 key->dec = camellia_decrypt256;
90 break;
91 case 256:
92 camellia_setup256(userKey, (unsigned int *)key->rd_key);
93 key->enc = camellia_encrypt256;
94 key->dec = camellia_decrypt256;
95 break;
96 default:
97 return -2; 64 return -2;
98 } 65 key->grand_rounds = Camellia_Ekeygen(bits , userKey, key->u.rd_key);
99
100 key->bitLength = bits;
101 return 0; 66 return 0;
102 } 67 }
103 68
104void Camellia_encrypt(const unsigned char *in, unsigned char *out, 69void Camellia_encrypt(const unsigned char *in, unsigned char *out,
105 const CAMELLIA_KEY *key) 70 const CAMELLIA_KEY *key)
106 { 71 {
107 u32 tmp[CAMELLIA_BLOCK_SIZE/sizeof(u32)]; 72 Camellia_EncryptBlock_Rounds(key->grand_rounds, in , key->u.rd_key , out);
108 const union { long one; char little; } camellia_endian = {1};
109
110 memcpy(tmp, in, CAMELLIA_BLOCK_SIZE);
111 if (camellia_endian.little) SWAP4WORD(tmp);
112 key->enc(key->rd_key, tmp);
113 if (camellia_endian.little) SWAP4WORD(tmp);
114 memcpy(out, tmp, CAMELLIA_BLOCK_SIZE);
115 } 73 }
116 74
117void Camellia_decrypt(const unsigned char *in, unsigned char *out, 75void Camellia_decrypt(const unsigned char *in, unsigned char *out,
118 const CAMELLIA_KEY *key) 76 const CAMELLIA_KEY *key)
119 { 77 {
120 u32 tmp[CAMELLIA_BLOCK_SIZE/sizeof(u32)]; 78 Camellia_DecryptBlock_Rounds(key->grand_rounds, in , key->u.rd_key , out);
121 const union { long one; char little; } camellia_endian = {1};
122
123 memcpy(tmp, in, CAMELLIA_BLOCK_SIZE);
124 if (camellia_endian.little) SWAP4WORD(tmp);
125 key->dec(key->rd_key, tmp);
126 if (camellia_endian.little) SWAP4WORD(tmp);
127 memcpy(out, tmp, CAMELLIA_BLOCK_SIZE);
128 } 79 }
129
diff --git a/src/lib/libcrypto/camellia/cmll_ofb.c b/src/lib/libcrypto/camellia/cmll_ofb.c
index d89cf9f3b3..a482befc74 100644
--- a/src/lib/libcrypto/camellia/cmll_ofb.c
+++ b/src/lib/libcrypto/camellia/cmll_ofb.c
@@ -105,37 +105,15 @@
105 * [including the GNU Public Licence.] 105 * [including the GNU Public Licence.]
106 */ 106 */
107 107
108#ifndef CAMELLIA_DEBUG
109# ifndef NDEBUG
110# define NDEBUG
111# endif
112#endif
113#include <assert.h>
114#include <openssl/camellia.h> 108#include <openssl/camellia.h>
115#include "cmll_locl.h" 109#include <openssl/modes.h>
116 110
117/* The input and output encrypted as though 128bit ofb mode is being 111/* The input and output encrypted as though 128bit ofb mode is being
118 * used. The extra state information to record how much of the 112 * used. The extra state information to record how much of the
119 * 128bit block we have used is contained in *num; 113 * 128bit block we have used is contained in *num;
120 */ 114 */
121void Camellia_ofb128_encrypt(const unsigned char *in, unsigned char *out, 115void Camellia_ofb128_encrypt(const unsigned char *in, unsigned char *out,
122 const unsigned long length, const CAMELLIA_KEY *key, 116 size_t length, const CAMELLIA_KEY *key,
123 unsigned char *ivec, int *num) { 117 unsigned char *ivec, int *num) {
124 118 CRYPTO_ofb128_encrypt(in,out,length,key,ivec,num,(block128_f)Camellia_encrypt);
125 unsigned int n;
126 unsigned long l=length;
127
128 assert(in && out && key && ivec && num);
129
130 n = *num;
131
132 while (l--) {
133 if (n == 0) {
134 Camellia_encrypt(ivec, ivec, key);
135 }
136 *(out++) = *(in++) ^ ivec[n];
137 n = (n+1) % CAMELLIA_BLOCK_SIZE;
138 }
139
140 *num=n;
141} 119}
diff --git a/src/lib/libcrypto/cast/asm/cast-586.pl b/src/lib/libcrypto/cast/asm/cast-586.pl
index 6be0bfe572..bf6810d335 100644
--- a/src/lib/libcrypto/cast/asm/cast-586.pl
+++ b/src/lib/libcrypto/cast/asm/cast-586.pl
@@ -3,7 +3,8 @@
3# define for pentium pro friendly version 3# define for pentium pro friendly version
4$ppro=1; 4$ppro=1;
5 5
6push(@INC,"perlasm","../../perlasm"); 6$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
7push(@INC,"${dir}","${dir}../../perlasm");
7require "x86asm.pl"; 8require "x86asm.pl";
8require "cbc.pl"; 9require "cbc.pl";
9 10
diff --git a/src/lib/libcrypto/cast/c_cfb64.c b/src/lib/libcrypto/cast/c_cfb64.c
index 514c005c32..dcec13a201 100644
--- a/src/lib/libcrypto/cast/c_cfb64.c
+++ b/src/lib/libcrypto/cast/c_cfb64.c
@@ -65,7 +65,7 @@
65 */ 65 */
66 66
67void CAST_cfb64_encrypt(const unsigned char *in, unsigned char *out, 67void CAST_cfb64_encrypt(const unsigned char *in, unsigned char *out,
68 long length, CAST_KEY *schedule, unsigned char *ivec, 68 long length, const CAST_KEY *schedule, unsigned char *ivec,
69 int *num, int enc) 69 int *num, int enc)
70 { 70 {
71 register CAST_LONG v0,v1,t; 71 register CAST_LONG v0,v1,t;
@@ -119,4 +119,3 @@ void CAST_cfb64_encrypt(const unsigned char *in, unsigned char *out,
119 v0=v1=ti[0]=ti[1]=t=c=cc=0; 119 v0=v1=ti[0]=ti[1]=t=c=cc=0;
120 *num=n; 120 *num=n;
121 } 121 }
122
diff --git a/src/lib/libcrypto/cast/c_ecb.c b/src/lib/libcrypto/cast/c_ecb.c
index f2dc606226..b6a3b1fff9 100644
--- a/src/lib/libcrypto/cast/c_ecb.c
+++ b/src/lib/libcrypto/cast/c_ecb.c
@@ -63,7 +63,7 @@
63const char CAST_version[]="CAST" OPENSSL_VERSION_PTEXT; 63const char CAST_version[]="CAST" OPENSSL_VERSION_PTEXT;
64 64
65void CAST_ecb_encrypt(const unsigned char *in, unsigned char *out, 65void CAST_ecb_encrypt(const unsigned char *in, unsigned char *out,
66 CAST_KEY *ks, int enc) 66 const CAST_KEY *ks, int enc)
67 { 67 {
68 CAST_LONG l,d[2]; 68 CAST_LONG l,d[2];
69 69
@@ -77,4 +77,3 @@ void CAST_ecb_encrypt(const unsigned char *in, unsigned char *out,
77 l=d[1]; l2n(l,out); 77 l=d[1]; l2n(l,out);
78 l=d[0]=d[1]=0; 78 l=d[0]=d[1]=0;
79 } 79 }
80
diff --git a/src/lib/libcrypto/cast/c_enc.c b/src/lib/libcrypto/cast/c_enc.c
index 0fe2cffecc..357c41ebf0 100644
--- a/src/lib/libcrypto/cast/c_enc.c
+++ b/src/lib/libcrypto/cast/c_enc.c
@@ -59,9 +59,10 @@
59#include <openssl/cast.h> 59#include <openssl/cast.h>
60#include "cast_lcl.h" 60#include "cast_lcl.h"
61 61
62void CAST_encrypt(CAST_LONG *data, CAST_KEY *key) 62void CAST_encrypt(CAST_LONG *data, const CAST_KEY *key)
63 { 63 {
64 register CAST_LONG l,r,*k,t; 64 register CAST_LONG l,r,t;
65 const register CAST_LONG *k;
65 66
66 k= &(key->data[0]); 67 k= &(key->data[0]);
67 l=data[0]; 68 l=data[0];
@@ -91,9 +92,10 @@ void CAST_encrypt(CAST_LONG *data, CAST_KEY *key)
91 data[0]=r&0xffffffffL; 92 data[0]=r&0xffffffffL;
92 } 93 }
93 94
94void CAST_decrypt(CAST_LONG *data, CAST_KEY *key) 95void CAST_decrypt(CAST_LONG *data, const CAST_KEY *key)
95 { 96 {
96 register CAST_LONG l,r,*k,t; 97 register CAST_LONG l,r,t;
98 const register CAST_LONG *k;
97 99
98 k= &(key->data[0]); 100 k= &(key->data[0]);
99 l=data[0]; 101 l=data[0];
@@ -124,7 +126,7 @@ void CAST_decrypt(CAST_LONG *data, CAST_KEY *key)
124 } 126 }
125 127
126void CAST_cbc_encrypt(const unsigned char *in, unsigned char *out, long length, 128void CAST_cbc_encrypt(const unsigned char *in, unsigned char *out, long length,
127 CAST_KEY *ks, unsigned char *iv, int enc) 129 const CAST_KEY *ks, unsigned char *iv, int enc)
128 { 130 {
129 register CAST_LONG tin0,tin1; 131 register CAST_LONG tin0,tin1;
130 register CAST_LONG tout0,tout1,xor0,xor1; 132 register CAST_LONG tout0,tout1,xor0,xor1;
@@ -204,4 +206,3 @@ void CAST_cbc_encrypt(const unsigned char *in, unsigned char *out, long length,
204 tin0=tin1=tout0=tout1=xor0=xor1=0; 206 tin0=tin1=tout0=tout1=xor0=xor1=0;
205 tin[0]=tin[1]=0; 207 tin[0]=tin[1]=0;
206 } 208 }
207
diff --git a/src/lib/libcrypto/cast/c_ofb64.c b/src/lib/libcrypto/cast/c_ofb64.c
index fd0469a62f..cb3222456c 100644
--- a/src/lib/libcrypto/cast/c_ofb64.c
+++ b/src/lib/libcrypto/cast/c_ofb64.c
@@ -64,7 +64,7 @@
64 * 64bit block we have used is contained in *num; 64 * 64bit block we have used is contained in *num;
65 */ 65 */
66void CAST_ofb64_encrypt(const unsigned char *in, unsigned char *out, 66void CAST_ofb64_encrypt(const unsigned char *in, unsigned char *out,
67 long length, CAST_KEY *schedule, unsigned char *ivec, 67 long length, const CAST_KEY *schedule, unsigned char *ivec,
68 int *num) 68 int *num)
69 { 69 {
70 register CAST_LONG v0,v1,t; 70 register CAST_LONG v0,v1,t;
@@ -108,4 +108,3 @@ void CAST_ofb64_encrypt(const unsigned char *in, unsigned char *out,
108 t=v0=v1=ti[0]=ti[1]=0; 108 t=v0=v1=ti[0]=ti[1]=0;
109 *num=n; 109 *num=n;
110 } 110 }
111
diff --git a/src/lib/libcrypto/cast/c_skey.c b/src/lib/libcrypto/cast/c_skey.c
index 68e690a60c..76e40005c9 100644
--- a/src/lib/libcrypto/cast/c_skey.c
+++ b/src/lib/libcrypto/cast/c_skey.c
@@ -57,11 +57,6 @@
57 */ 57 */
58 58
59#include <openssl/cast.h> 59#include <openssl/cast.h>
60#include <openssl/crypto.h>
61#ifdef OPENSSL_FIPS
62#include <openssl/fips.h>
63#endif
64
65#include "cast_lcl.h" 60#include "cast_lcl.h"
66#include "cast_s.h" 61#include "cast_s.h"
67 62
@@ -77,7 +72,7 @@
77#define S6 CAST_S_table6 72#define S6 CAST_S_table6
78#define S7 CAST_S_table7 73#define S7 CAST_S_table7
79 74
80FIPS_NON_FIPS_VCIPHER_Init(CAST) 75void CAST_set_key(CAST_KEY *key, int len, const unsigned char *data)
81 { 76 {
82 CAST_LONG x[16]; 77 CAST_LONG x[16];
83 CAST_LONG z[16]; 78 CAST_LONG z[16];
diff --git a/src/lib/libcrypto/cast/cast.h b/src/lib/libcrypto/cast/cast.h
index 1faf5806aa..1a264f8143 100644
--- a/src/lib/libcrypto/cast/cast.h
+++ b/src/lib/libcrypto/cast/cast.h
@@ -72,7 +72,7 @@ extern "C" {
72#define CAST_ENCRYPT 1 72#define CAST_ENCRYPT 1
73#define CAST_DECRYPT 0 73#define CAST_DECRYPT 0
74 74
75#define CAST_LONG unsigned long 75#define CAST_LONG unsigned int
76 76
77#define CAST_BLOCK 8 77#define CAST_BLOCK 8
78#define CAST_KEY_LENGTH 16 78#define CAST_KEY_LENGTH 16
@@ -83,21 +83,19 @@ typedef struct cast_key_st
83 int short_key; /* Use reduced rounds for short key */ 83 int short_key; /* Use reduced rounds for short key */
84 } CAST_KEY; 84 } CAST_KEY;
85 85
86#ifdef OPENSSL_FIPS 86
87void private_CAST_set_key(CAST_KEY *key, int len, const unsigned char *data);
88#endif
89void CAST_set_key(CAST_KEY *key, int len, const unsigned char *data); 87void CAST_set_key(CAST_KEY *key, int len, const unsigned char *data);
90void CAST_ecb_encrypt(const unsigned char *in,unsigned char *out,CAST_KEY *key, 88void CAST_ecb_encrypt(const unsigned char *in, unsigned char *out, const CAST_KEY *key,
91 int enc); 89 int enc);
92void CAST_encrypt(CAST_LONG *data,CAST_KEY *key); 90void CAST_encrypt(CAST_LONG *data, const CAST_KEY *key);
93void CAST_decrypt(CAST_LONG *data,CAST_KEY *key); 91void CAST_decrypt(CAST_LONG *data, const CAST_KEY *key);
94void CAST_cbc_encrypt(const unsigned char *in, unsigned char *out, long length, 92void CAST_cbc_encrypt(const unsigned char *in, unsigned char *out, long length,
95 CAST_KEY *ks, unsigned char *iv, int enc); 93 const CAST_KEY *ks, unsigned char *iv, int enc);
96void CAST_cfb64_encrypt(const unsigned char *in, unsigned char *out, 94void CAST_cfb64_encrypt(const unsigned char *in, unsigned char *out,
97 long length, CAST_KEY *schedule, unsigned char *ivec, 95 long length, const CAST_KEY *schedule, unsigned char *ivec,
98 int *num, int enc); 96 int *num, int enc);
99void CAST_ofb64_encrypt(const unsigned char *in, unsigned char *out, 97void CAST_ofb64_encrypt(const unsigned char *in, unsigned char *out,
100 long length, CAST_KEY *schedule, unsigned char *ivec, 98 long length, const CAST_KEY *schedule, unsigned char *ivec,
101 int *num); 99 int *num);
102 100
103#ifdef __cplusplus 101#ifdef __cplusplus
diff --git a/src/lib/libcrypto/cms/cms.h b/src/lib/libcrypto/cms/cms.h
index 25f88745f2..09c45d0412 100644
--- a/src/lib/libcrypto/cms/cms.h
+++ b/src/lib/libcrypto/cms/cms.h
@@ -76,8 +76,9 @@ typedef struct CMS_Receipt_st CMS_Receipt;
76 76
77DECLARE_STACK_OF(CMS_SignerInfo) 77DECLARE_STACK_OF(CMS_SignerInfo)
78DECLARE_STACK_OF(GENERAL_NAMES) 78DECLARE_STACK_OF(GENERAL_NAMES)
79DECLARE_ASN1_FUNCTIONS_const(CMS_ContentInfo) 79DECLARE_ASN1_FUNCTIONS(CMS_ContentInfo)
80DECLARE_ASN1_FUNCTIONS_const(CMS_ReceiptRequest) 80DECLARE_ASN1_FUNCTIONS(CMS_ReceiptRequest)
81DECLARE_ASN1_PRINT_FUNCTION(CMS_ContentInfo)
81 82
82#define CMS_SIGNERINFO_ISSUER_SERIAL 0 83#define CMS_SIGNERINFO_ISSUER_SERIAL 0
83#define CMS_SIGNERINFO_KEYIDENTIFIER 1 84#define CMS_SIGNERINFO_KEYIDENTIFIER 1
@@ -124,9 +125,13 @@ int CMS_set_detached(CMS_ContentInfo *cms, int detached);
124DECLARE_PEM_rw_const(CMS, CMS_ContentInfo) 125DECLARE_PEM_rw_const(CMS, CMS_ContentInfo)
125#endif 126#endif
126 127
128int CMS_stream(unsigned char ***boundary, CMS_ContentInfo *cms);
127CMS_ContentInfo *d2i_CMS_bio(BIO *bp, CMS_ContentInfo **cms); 129CMS_ContentInfo *d2i_CMS_bio(BIO *bp, CMS_ContentInfo **cms);
128int i2d_CMS_bio(BIO *bp, CMS_ContentInfo *cms); 130int i2d_CMS_bio(BIO *bp, CMS_ContentInfo *cms);
129 131
132BIO *BIO_new_CMS(BIO *out, CMS_ContentInfo *cms);
133int i2d_CMS_bio_stream(BIO *out, CMS_ContentInfo *cms, BIO *in, int flags);
134int PEM_write_bio_CMS_stream(BIO *out, CMS_ContentInfo *cms, BIO *in, int flags);
130CMS_ContentInfo *SMIME_read_CMS(BIO *bio, BIO **bcont); 135CMS_ContentInfo *SMIME_read_CMS(BIO *bio, BIO **bcont);
131int SMIME_write_CMS(BIO *bio, CMS_ContentInfo *cms, BIO *data, int flags); 136int SMIME_write_CMS(BIO *bio, CMS_ContentInfo *cms, BIO *data, int flags);
132 137
@@ -230,6 +235,7 @@ STACK_OF(X509) *CMS_get1_certs(CMS_ContentInfo *cms);
230 235
231CMS_RevocationInfoChoice *CMS_add0_RevocationInfoChoice(CMS_ContentInfo *cms); 236CMS_RevocationInfoChoice *CMS_add0_RevocationInfoChoice(CMS_ContentInfo *cms);
232int CMS_add0_crl(CMS_ContentInfo *cms, X509_CRL *crl); 237int CMS_add0_crl(CMS_ContentInfo *cms, X509_CRL *crl);
238int CMS_add1_crl(CMS_ContentInfo *cms, X509_CRL *crl);
233STACK_OF(X509_CRL) *CMS_get1_crls(CMS_ContentInfo *cms); 239STACK_OF(X509_CRL) *CMS_get1_crls(CMS_ContentInfo *cms);
234 240
235int CMS_SignedData_init(CMS_ContentInfo *cms); 241int CMS_SignedData_init(CMS_ContentInfo *cms);
diff --git a/src/lib/libcrypto/cms/cms_asn1.c b/src/lib/libcrypto/cms/cms_asn1.c
index 7664921861..fcba4dcbcc 100644
--- a/src/lib/libcrypto/cms/cms_asn1.c
+++ b/src/lib/libcrypto/cms/cms_asn1.c
@@ -87,7 +87,8 @@ ASN1_NDEF_SEQUENCE(CMS_EncapsulatedContentInfo) = {
87} ASN1_NDEF_SEQUENCE_END(CMS_EncapsulatedContentInfo) 87} ASN1_NDEF_SEQUENCE_END(CMS_EncapsulatedContentInfo)
88 88
89/* Minor tweak to operation: free up signer key, cert */ 89/* Minor tweak to operation: free up signer key, cert */
90static int cms_si_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it) 90static int cms_si_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
91 void *exarg)
91 { 92 {
92 if(operation == ASN1_OP_FREE_POST) 93 if(operation == ASN1_OP_FREE_POST)
93 { 94 {
@@ -130,8 +131,8 @@ ASN1_NDEF_SEQUENCE(CMS_SignedData) = {
130} ASN1_NDEF_SEQUENCE_END(CMS_SignedData) 131} ASN1_NDEF_SEQUENCE_END(CMS_SignedData)
131 132
132ASN1_SEQUENCE(CMS_OriginatorInfo) = { 133ASN1_SEQUENCE(CMS_OriginatorInfo) = {
133 ASN1_IMP_SET_OF_OPT(CMS_SignedData, certificates, CMS_CertificateChoices, 0), 134 ASN1_IMP_SET_OF_OPT(CMS_OriginatorInfo, certificates, CMS_CertificateChoices, 0),
134 ASN1_IMP_SET_OF_OPT(CMS_SignedData, crls, CMS_RevocationInfoChoice, 1) 135 ASN1_IMP_SET_OF_OPT(CMS_OriginatorInfo, crls, CMS_RevocationInfoChoice, 1)
135} ASN1_SEQUENCE_END(CMS_OriginatorInfo) 136} ASN1_SEQUENCE_END(CMS_OriginatorInfo)
136 137
137ASN1_NDEF_SEQUENCE(CMS_EncryptedContentInfo) = { 138ASN1_NDEF_SEQUENCE(CMS_EncryptedContentInfo) = {
@@ -213,7 +214,8 @@ ASN1_SEQUENCE(CMS_OtherRecipientInfo) = {
213} ASN1_SEQUENCE_END(CMS_OtherRecipientInfo) 214} ASN1_SEQUENCE_END(CMS_OtherRecipientInfo)
214 215
215/* Free up RecipientInfo additional data */ 216/* Free up RecipientInfo additional data */
216static int cms_ri_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it) 217static int cms_ri_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
218 void *exarg)
217 { 219 {
218 if(operation == ASN1_OP_FREE_PRE) 220 if(operation == ASN1_OP_FREE_PRE)
219 { 221 {
@@ -300,10 +302,42 @@ ASN1_ADB(CMS_ContentInfo) = {
300 ADB_ENTRY(NID_id_smime_ct_compressedData, ASN1_NDEF_EXP(CMS_ContentInfo, d.compressedData, CMS_CompressedData, 0)), 302 ADB_ENTRY(NID_id_smime_ct_compressedData, ASN1_NDEF_EXP(CMS_ContentInfo, d.compressedData, CMS_CompressedData, 0)),
301} ASN1_ADB_END(CMS_ContentInfo, 0, contentType, 0, &cms_default_tt, NULL); 303} ASN1_ADB_END(CMS_ContentInfo, 0, contentType, 0, &cms_default_tt, NULL);
302 304
303ASN1_NDEF_SEQUENCE(CMS_ContentInfo) = { 305/* CMS streaming support */
306static int cms_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
307 void *exarg)
308 {
309 ASN1_STREAM_ARG *sarg = exarg;
310 CMS_ContentInfo *cms = NULL;
311 if (pval)
312 cms = (CMS_ContentInfo *)*pval;
313 else
314 return 1;
315 switch(operation)
316 {
317
318 case ASN1_OP_STREAM_PRE:
319 if (CMS_stream(&sarg->boundary, cms) <= 0)
320 return 0;
321 case ASN1_OP_DETACHED_PRE:
322 sarg->ndef_bio = CMS_dataInit(cms, sarg->out);
323 if (!sarg->ndef_bio)
324 return 0;
325 break;
326
327 case ASN1_OP_STREAM_POST:
328 case ASN1_OP_DETACHED_POST:
329 if (CMS_dataFinal(cms, sarg->ndef_bio) <= 0)
330 return 0;
331 break;
332
333 }
334 return 1;
335 }
336
337ASN1_NDEF_SEQUENCE_cb(CMS_ContentInfo, cms_cb) = {
304 ASN1_SIMPLE(CMS_ContentInfo, contentType, ASN1_OBJECT), 338 ASN1_SIMPLE(CMS_ContentInfo, contentType, ASN1_OBJECT),
305 ASN1_ADB_OBJECT(CMS_ContentInfo) 339 ASN1_ADB_OBJECT(CMS_ContentInfo)
306} ASN1_NDEF_SEQUENCE_END(CMS_ContentInfo) 340} ASN1_NDEF_SEQUENCE_END_cb(CMS_ContentInfo, CMS_ContentInfo)
307 341
308/* Specials for signed attributes */ 342/* Specials for signed attributes */
309 343
diff --git a/src/lib/libcrypto/cms/cms_env.c b/src/lib/libcrypto/cms/cms_env.c
index d499ae85b4..b3237d4b94 100644
--- a/src/lib/libcrypto/cms/cms_env.c
+++ b/src/lib/libcrypto/cms/cms_env.c
@@ -60,6 +60,7 @@
60#include <openssl/rand.h> 60#include <openssl/rand.h>
61#include <openssl/aes.h> 61#include <openssl/aes.h>
62#include "cms_lcl.h" 62#include "cms_lcl.h"
63#include "asn1_locl.h"
63 64
64/* CMS EnvelopedData Utilities */ 65/* CMS EnvelopedData Utilities */
65 66
@@ -151,7 +152,7 @@ CMS_RecipientInfo *CMS_add1_recipient_cert(CMS_ContentInfo *cms,
151 CMS_KeyTransRecipientInfo *ktri; 152 CMS_KeyTransRecipientInfo *ktri;
152 CMS_EnvelopedData *env; 153 CMS_EnvelopedData *env;
153 EVP_PKEY *pk = NULL; 154 EVP_PKEY *pk = NULL;
154 int type; 155 int i, type;
155 env = cms_get0_enveloped(cms); 156 env = cms_get0_enveloped(cms);
156 if (!env) 157 if (!env)
157 goto err; 158 goto err;
@@ -200,21 +201,22 @@ CMS_RecipientInfo *CMS_add1_recipient_cert(CMS_ContentInfo *cms,
200 if (!cms_set1_SignerIdentifier(ktri->rid, recip, type)) 201 if (!cms_set1_SignerIdentifier(ktri->rid, recip, type))
201 goto err; 202 goto err;
202 203
203 /* Since we have no EVP_PKEY_ASN1_METHOD in OpenSSL 0.9.8, 204 if (pk->ameth && pk->ameth->pkey_ctrl)
204 * hard code algorithm parameters.
205 */
206
207 if (pk->type == EVP_PKEY_RSA)
208 {
209 X509_ALGOR_set0(ktri->keyEncryptionAlgorithm,
210 OBJ_nid2obj(NID_rsaEncryption),
211 V_ASN1_NULL, 0);
212 }
213 else
214 { 205 {
215 CMSerr(CMS_F_CMS_ADD1_RECIPIENT_CERT, 206 i = pk->ameth->pkey_ctrl(pk, ASN1_PKEY_CTRL_CMS_ENVELOPE,
207 0, ri);
208 if (i == -2)
209 {
210 CMSerr(CMS_F_CMS_ADD1_RECIPIENT_CERT,
216 CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE); 211 CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE);
217 goto err; 212 goto err;
213 }
214 if (i <= 0)
215 {
216 CMSerr(CMS_F_CMS_ADD1_RECIPIENT_CERT,
217 CMS_R_CTRL_FAILURE);
218 goto err;
219 }
218 } 220 }
219 221
220 if (!sk_CMS_RecipientInfo_push(env->recipientInfos, ri)) 222 if (!sk_CMS_RecipientInfo_push(env->recipientInfos, ri))
@@ -301,8 +303,9 @@ static int cms_RecipientInfo_ktri_encrypt(CMS_ContentInfo *cms,
301 { 303 {
302 CMS_KeyTransRecipientInfo *ktri; 304 CMS_KeyTransRecipientInfo *ktri;
303 CMS_EncryptedContentInfo *ec; 305 CMS_EncryptedContentInfo *ec;
306 EVP_PKEY_CTX *pctx = NULL;
304 unsigned char *ek = NULL; 307 unsigned char *ek = NULL;
305 int eklen; 308 size_t eklen;
306 309
307 int ret = 0; 310 int ret = 0;
308 311
@@ -315,7 +318,22 @@ static int cms_RecipientInfo_ktri_encrypt(CMS_ContentInfo *cms,
315 ktri = ri->d.ktri; 318 ktri = ri->d.ktri;
316 ec = cms->d.envelopedData->encryptedContentInfo; 319 ec = cms->d.envelopedData->encryptedContentInfo;
317 320
318 eklen = EVP_PKEY_size(ktri->pkey); 321 pctx = EVP_PKEY_CTX_new(ktri->pkey, NULL);
322 if (!pctx)
323 return 0;
324
325 if (EVP_PKEY_encrypt_init(pctx) <= 0)
326 goto err;
327
328 if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_ENCRYPT,
329 EVP_PKEY_CTRL_CMS_ENCRYPT, 0, ri) <= 0)
330 {
331 CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_ENCRYPT, CMS_R_CTRL_ERROR);
332 goto err;
333 }
334
335 if (EVP_PKEY_encrypt(pctx, NULL, &eklen, ec->key, ec->keylen) <= 0)
336 goto err;
319 337
320 ek = OPENSSL_malloc(eklen); 338 ek = OPENSSL_malloc(eklen);
321 339
@@ -326,9 +344,7 @@ static int cms_RecipientInfo_ktri_encrypt(CMS_ContentInfo *cms,
326 goto err; 344 goto err;
327 } 345 }
328 346
329 eklen = EVP_PKEY_encrypt(ek, ec->key, ec->keylen, ktri->pkey); 347 if (EVP_PKEY_encrypt(pctx, ek, &eklen, ec->key, ec->keylen) <= 0)
330
331 if (eklen <= 0)
332 goto err; 348 goto err;
333 349
334 ASN1_STRING_set0(ktri->encryptedKey, ek, eklen); 350 ASN1_STRING_set0(ktri->encryptedKey, ek, eklen);
@@ -337,6 +353,8 @@ static int cms_RecipientInfo_ktri_encrypt(CMS_ContentInfo *cms,
337 ret = 1; 353 ret = 1;
338 354
339 err: 355 err:
356 if (pctx)
357 EVP_PKEY_CTX_free(pctx);
340 if (ek) 358 if (ek)
341 OPENSSL_free(ek); 359 OPENSSL_free(ek);
342 return ret; 360 return ret;
@@ -349,8 +367,9 @@ static int cms_RecipientInfo_ktri_decrypt(CMS_ContentInfo *cms,
349 CMS_RecipientInfo *ri) 367 CMS_RecipientInfo *ri)
350 { 368 {
351 CMS_KeyTransRecipientInfo *ktri = ri->d.ktri; 369 CMS_KeyTransRecipientInfo *ktri = ri->d.ktri;
370 EVP_PKEY_CTX *pctx = NULL;
352 unsigned char *ek = NULL; 371 unsigned char *ek = NULL;
353 int eklen; 372 size_t eklen;
354 int ret = 0; 373 int ret = 0;
355 374
356 if (ktri->pkey == NULL) 375 if (ktri->pkey == NULL)
@@ -360,7 +379,24 @@ static int cms_RecipientInfo_ktri_decrypt(CMS_ContentInfo *cms,
360 return 0; 379 return 0;
361 } 380 }
362 381
363 eklen = EVP_PKEY_size(ktri->pkey); 382 pctx = EVP_PKEY_CTX_new(ktri->pkey, NULL);
383 if (!pctx)
384 return 0;
385
386 if (EVP_PKEY_decrypt_init(pctx) <= 0)
387 goto err;
388
389 if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_DECRYPT,
390 EVP_PKEY_CTRL_CMS_DECRYPT, 0, ri) <= 0)
391 {
392 CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_DECRYPT, CMS_R_CTRL_ERROR);
393 goto err;
394 }
395
396 if (EVP_PKEY_decrypt(pctx, NULL, &eklen,
397 ktri->encryptedKey->data,
398 ktri->encryptedKey->length) <= 0)
399 goto err;
364 400
365 ek = OPENSSL_malloc(eklen); 401 ek = OPENSSL_malloc(eklen);
366 402
@@ -371,10 +407,9 @@ static int cms_RecipientInfo_ktri_decrypt(CMS_ContentInfo *cms,
371 goto err; 407 goto err;
372 } 408 }
373 409
374 eklen = EVP_PKEY_decrypt(ek, 410 if (EVP_PKEY_decrypt(pctx, ek, &eklen,
375 ktri->encryptedKey->data, 411 ktri->encryptedKey->data,
376 ktri->encryptedKey->length, ktri->pkey); 412 ktri->encryptedKey->length) <= 0)
377 if (eklen <= 0)
378 { 413 {
379 CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_DECRYPT, CMS_R_CMS_LIB); 414 CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_DECRYPT, CMS_R_CMS_LIB);
380 goto err; 415 goto err;
@@ -386,6 +421,8 @@ static int cms_RecipientInfo_ktri_decrypt(CMS_ContentInfo *cms,
386 cms->d.envelopedData->encryptedContentInfo->keylen = eklen; 421 cms->d.envelopedData->encryptedContentInfo->keylen = eklen;
387 422
388 err: 423 err:
424 if (pctx)
425 EVP_PKEY_CTX_free(pctx);
389 if (!ret && ek) 426 if (!ret && ek)
390 OPENSSL_free(ek); 427 OPENSSL_free(ek);
391 428
diff --git a/src/lib/libcrypto/cms/cms_err.c b/src/lib/libcrypto/cms/cms_err.c
index 52fa53954f..ff7b0309e5 100644
--- a/src/lib/libcrypto/cms/cms_err.c
+++ b/src/lib/libcrypto/cms/cms_err.c
@@ -1,6 +1,6 @@
1/* crypto/cms/cms_err.c */ 1/* crypto/cms/cms_err.c */
2/* ==================================================================== 2/* ====================================================================
3 * Copyright (c) 1999-2008 The OpenSSL Project. All rights reserved. 3 * Copyright (c) 1999-2007 The OpenSSL Project. All rights reserved.
4 * 4 *
5 * Redistribution and use in source and binary forms, with or without 5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions 6 * modification, are permitted provided that the following conditions
@@ -133,7 +133,7 @@ static ERR_STRING_DATA CMS_str_functs[]=
133{ERR_FUNC(CMS_F_CMS_SIGNERINFO_VERIFY_CERT), "CMS_SIGNERINFO_VERIFY_CERT"}, 133{ERR_FUNC(CMS_F_CMS_SIGNERINFO_VERIFY_CERT), "CMS_SIGNERINFO_VERIFY_CERT"},
134{ERR_FUNC(CMS_F_CMS_SIGNERINFO_VERIFY_CONTENT), "CMS_SignerInfo_verify_content"}, 134{ERR_FUNC(CMS_F_CMS_SIGNERINFO_VERIFY_CONTENT), "CMS_SignerInfo_verify_content"},
135{ERR_FUNC(CMS_F_CMS_SIGN_RECEIPT), "CMS_sign_receipt"}, 135{ERR_FUNC(CMS_F_CMS_SIGN_RECEIPT), "CMS_sign_receipt"},
136{ERR_FUNC(CMS_F_CMS_STREAM), "CMS_STREAM"}, 136{ERR_FUNC(CMS_F_CMS_STREAM), "CMS_stream"},
137{ERR_FUNC(CMS_F_CMS_UNCOMPRESS), "CMS_uncompress"}, 137{ERR_FUNC(CMS_F_CMS_UNCOMPRESS), "CMS_uncompress"},
138{ERR_FUNC(CMS_F_CMS_VERIFY), "CMS_verify"}, 138{ERR_FUNC(CMS_F_CMS_VERIFY), "CMS_verify"},
139{0,NULL} 139{0,NULL}
diff --git a/src/lib/libcrypto/cms/cms_ess.c b/src/lib/libcrypto/cms/cms_ess.c
index ed34ff3228..90c0b82fb5 100644
--- a/src/lib/libcrypto/cms/cms_ess.c
+++ b/src/lib/libcrypto/cms/cms_ess.c
@@ -63,7 +63,7 @@
63DECLARE_ASN1_ITEM(CMS_ReceiptRequest) 63DECLARE_ASN1_ITEM(CMS_ReceiptRequest)
64DECLARE_ASN1_ITEM(CMS_Receipt) 64DECLARE_ASN1_ITEM(CMS_Receipt)
65 65
66IMPLEMENT_ASN1_FUNCTIONS_const(CMS_ReceiptRequest) 66IMPLEMENT_ASN1_FUNCTIONS(CMS_ReceiptRequest)
67 67
68/* ESS services: for now just Signed Receipt related */ 68/* ESS services: for now just Signed Receipt related */
69 69
@@ -344,7 +344,7 @@ int cms_Receipt_verify(CMS_ContentInfo *cms, CMS_ContentInfo *req_cms)
344 344
345 /* Get original receipt request details */ 345 /* Get original receipt request details */
346 346
347 if (!CMS_get1_ReceiptRequest(osi, &rr)) 347 if (CMS_get1_ReceiptRequest(osi, &rr) <= 0)
348 { 348 {
349 CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_NO_RECEIPT_REQUEST); 349 CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_NO_RECEIPT_REQUEST);
350 goto err; 350 goto err;
@@ -385,7 +385,7 @@ ASN1_OCTET_STRING *cms_encode_Receipt(CMS_SignerInfo *si)
385 385
386 /* Get original receipt request details */ 386 /* Get original receipt request details */
387 387
388 if (!CMS_get1_ReceiptRequest(si, &rr)) 388 if (CMS_get1_ReceiptRequest(si, &rr) <= 0)
389 { 389 {
390 CMSerr(CMS_F_CMS_ENCODE_RECEIPT, CMS_R_NO_RECEIPT_REQUEST); 390 CMSerr(CMS_F_CMS_ENCODE_RECEIPT, CMS_R_NO_RECEIPT_REQUEST);
391 goto err; 391 goto err;
diff --git a/src/lib/libcrypto/cms/cms_io.c b/src/lib/libcrypto/cms/cms_io.c
index 30f5ddfe6d..1cb0264cc5 100644
--- a/src/lib/libcrypto/cms/cms_io.c
+++ b/src/lib/libcrypto/cms/cms_io.c
@@ -58,6 +58,25 @@
58#include "cms.h" 58#include "cms.h"
59#include "cms_lcl.h" 59#include "cms_lcl.h"
60 60
61int CMS_stream(unsigned char ***boundary, CMS_ContentInfo *cms)
62 {
63 ASN1_OCTET_STRING **pos;
64 pos = CMS_get0_content(cms);
65 if (!pos)
66 return 0;
67 if (!*pos)
68 *pos = ASN1_OCTET_STRING_new();
69 if (*pos)
70 {
71 (*pos)->flags |= ASN1_STRING_FLAG_NDEF;
72 (*pos)->flags &= ~ASN1_STRING_FLAG_CONT;
73 *boundary = &(*pos)->data;
74 return 1;
75 }
76 CMSerr(CMS_F_CMS_STREAM, ERR_R_MALLOC_FAILURE);
77 return 0;
78 }
79
61CMS_ContentInfo *d2i_CMS_bio(BIO *bp, CMS_ContentInfo **cms) 80CMS_ContentInfo *d2i_CMS_bio(BIO *bp, CMS_ContentInfo **cms)
62 { 81 {
63 return ASN1_item_d2i_bio(ASN1_ITEM_rptr(CMS_ContentInfo), bp, cms); 82 return ASN1_item_d2i_bio(ASN1_ITEM_rptr(CMS_ContentInfo), bp, cms);
@@ -70,52 +89,26 @@ int i2d_CMS_bio(BIO *bp, CMS_ContentInfo *cms)
70 89
71IMPLEMENT_PEM_rw_const(CMS, CMS_ContentInfo, PEM_STRING_CMS, CMS_ContentInfo) 90IMPLEMENT_PEM_rw_const(CMS, CMS_ContentInfo, PEM_STRING_CMS, CMS_ContentInfo)
72 91
73/* Callback for int_smime_write_ASN1 */ 92BIO *BIO_new_CMS(BIO *out, CMS_ContentInfo *cms)
74
75static int cms_output_data(BIO *out, BIO *data, ASN1_VALUE *val, int flags,
76 const ASN1_ITEM *it)
77 { 93 {
78 CMS_ContentInfo *cms = (CMS_ContentInfo *)val; 94 return BIO_new_NDEF(out, (ASN1_VALUE *)cms,
79 BIO *tmpbio, *cmsbio; 95 ASN1_ITEM_rptr(CMS_ContentInfo));
80 int r = 0; 96 }
81
82 if (!(flags & SMIME_DETACHED))
83 {
84 SMIME_crlf_copy(data, out, flags);
85 return 1;
86 }
87
88 /* Let CMS code prepend any needed BIOs */
89
90 cmsbio = CMS_dataInit(cms, out);
91
92 if (!cmsbio)
93 return 0;
94
95 /* Copy data across, passing through filter BIOs for processing */
96 SMIME_crlf_copy(data, cmsbio, flags);
97
98 /* Finalize structure */
99 if (CMS_dataFinal(cms, cmsbio) <= 0)
100 goto err;
101
102 r = 1;
103
104 err:
105
106 /* Now remove any digests prepended to the BIO */
107
108 while (cmsbio != out)
109 {
110 tmpbio = BIO_pop(cmsbio);
111 BIO_free(cmsbio);
112 cmsbio = tmpbio;
113 }
114 97
115 return 1; 98/* CMS wrappers round generalised stream and MIME routines */
116 99
100int i2d_CMS_bio_stream(BIO *out, CMS_ContentInfo *cms, BIO *in, int flags)
101 {
102 return i2d_ASN1_bio_stream(out, (ASN1_VALUE *)cms, in, flags,
103 ASN1_ITEM_rptr(CMS_ContentInfo));
117 } 104 }
118 105
106int PEM_write_bio_CMS_stream(BIO *out, CMS_ContentInfo *cms, BIO *in, int flags)
107 {
108 return PEM_write_bio_ASN1_stream(out, (ASN1_VALUE *) cms, in, flags,
109 "CMS",
110 ASN1_ITEM_rptr(CMS_ContentInfo));
111 }
119 112
120int SMIME_write_CMS(BIO *bio, CMS_ContentInfo *cms, BIO *data, int flags) 113int SMIME_write_CMS(BIO *bio, CMS_ContentInfo *cms, BIO *data, int flags)
121 { 114 {
@@ -127,9 +120,8 @@ int SMIME_write_CMS(BIO *bio, CMS_ContentInfo *cms, BIO *data, int flags)
127 else 120 else
128 mdalgs = NULL; 121 mdalgs = NULL;
129 122
130 return int_smime_write_ASN1(bio, (ASN1_VALUE *)cms, data, flags, 123 return SMIME_write_ASN1(bio, (ASN1_VALUE *)cms, data, flags,
131 ctype_nid, econt_nid, mdalgs, 124 ctype_nid, econt_nid, mdalgs,
132 cms_output_data,
133 ASN1_ITEM_rptr(CMS_ContentInfo)); 125 ASN1_ITEM_rptr(CMS_ContentInfo));
134 } 126 }
135 127
@@ -138,3 +130,4 @@ CMS_ContentInfo *SMIME_read_CMS(BIO *bio, BIO **bcont)
138 return (CMS_ContentInfo *)SMIME_read_ASN1(bio, bcont, 130 return (CMS_ContentInfo *)SMIME_read_ASN1(bio, bcont,
139 ASN1_ITEM_rptr(CMS_ContentInfo)); 131 ASN1_ITEM_rptr(CMS_ContentInfo));
140 } 132 }
133
diff --git a/src/lib/libcrypto/cms/cms_lcl.h b/src/lib/libcrypto/cms/cms_lcl.h
index 7d60fac67e..c8ecfa724a 100644
--- a/src/lib/libcrypto/cms/cms_lcl.h
+++ b/src/lib/libcrypto/cms/cms_lcl.h
@@ -406,6 +406,7 @@ struct CMS_Receipt_st
406 ASN1_OCTET_STRING *originatorSignatureValue; 406 ASN1_OCTET_STRING *originatorSignatureValue;
407 }; 407 };
408 408
409DECLARE_ASN1_FUNCTIONS(CMS_ContentInfo)
409DECLARE_ASN1_ITEM(CMS_SignerInfo) 410DECLARE_ASN1_ITEM(CMS_SignerInfo)
410DECLARE_ASN1_ITEM(CMS_IssuerAndSerialNumber) 411DECLARE_ASN1_ITEM(CMS_IssuerAndSerialNumber)
411DECLARE_ASN1_ITEM(CMS_Attributes_Sign) 412DECLARE_ASN1_ITEM(CMS_Attributes_Sign)
diff --git a/src/lib/libcrypto/cms/cms_lib.c b/src/lib/libcrypto/cms/cms_lib.c
index 8e6c1d29a5..d00fe0f87b 100644
--- a/src/lib/libcrypto/cms/cms_lib.c
+++ b/src/lib/libcrypto/cms/cms_lib.c
@@ -60,7 +60,8 @@
60#include "cms.h" 60#include "cms.h"
61#include "cms_lcl.h" 61#include "cms_lcl.h"
62 62
63IMPLEMENT_ASN1_FUNCTIONS_const(CMS_ContentInfo) 63IMPLEMENT_ASN1_FUNCTIONS(CMS_ContentInfo)
64IMPLEMENT_ASN1_PRINT_FUNCTION(CMS_ContentInfo)
64 65
65DECLARE_ASN1_ITEM(CMS_CertificateChoices) 66DECLARE_ASN1_ITEM(CMS_CertificateChoices)
66DECLARE_ASN1_ITEM(CMS_RevocationInfoChoice) 67DECLARE_ASN1_ITEM(CMS_RevocationInfoChoice)
@@ -346,20 +347,10 @@ void cms_DigestAlgorithm_set(X509_ALGOR *alg, const EVP_MD *md)
346 { 347 {
347 int param_type; 348 int param_type;
348 349
349 switch (EVP_MD_type(md)) 350 if (md->flags & EVP_MD_FLAG_DIGALGID_ABSENT)
350 {
351 case NID_sha1:
352 case NID_sha224:
353 case NID_sha256:
354 case NID_sha384:
355 case NID_sha512:
356 param_type = V_ASN1_UNDEF; 351 param_type = V_ASN1_UNDEF;
357 break; 352 else
358
359 default:
360 param_type = V_ASN1_NULL; 353 param_type = V_ASN1_NULL;
361 break;
362 }
363 354
364 X509_ALGOR_set0(alg, OBJ_nid2obj(EVP_MD_type(md)), param_type, NULL); 355 X509_ALGOR_set0(alg, OBJ_nid2obj(EVP_MD_type(md)), param_type, NULL);
365 356
@@ -415,7 +406,11 @@ int cms_DigestAlgorithm_find_ctx(EVP_MD_CTX *mctx, BIO *chain,
415 return 0; 406 return 0;
416 } 407 }
417 BIO_get_md_ctx(chain, &mtmp); 408 BIO_get_md_ctx(chain, &mtmp);
418 if (EVP_MD_CTX_type(mtmp) == nid) 409 if (EVP_MD_CTX_type(mtmp) == nid
410 /* Workaround for broken implementations that use signature
411 * algorithm OID instead of digest.
412 */
413 || EVP_MD_pkey_type(EVP_MD_CTX_md(mtmp)) == nid)
419 { 414 {
420 EVP_MD_CTX_copy_ex(mctx, mtmp); 415 EVP_MD_CTX_copy_ex(mctx, mtmp);
421 return 1; 416 return 1;
@@ -557,6 +552,15 @@ int CMS_add0_crl(CMS_ContentInfo *cms, X509_CRL *crl)
557 return 1; 552 return 1;
558 } 553 }
559 554
555int CMS_add1_crl(CMS_ContentInfo *cms, X509_CRL *crl)
556 {
557 int r;
558 r = CMS_add0_crl(cms, crl);
559 if (r > 0)
560 CRYPTO_add(&crl->references, 1, CRYPTO_LOCK_X509_CRL);
561 return r;
562 }
563
560STACK_OF(X509) *CMS_get1_certs(CMS_ContentInfo *cms) 564STACK_OF(X509) *CMS_get1_certs(CMS_ContentInfo *cms)
561 { 565 {
562 STACK_OF(X509) *certs = NULL; 566 STACK_OF(X509) *certs = NULL;
diff --git a/src/lib/libcrypto/cms/cms_sd.c b/src/lib/libcrypto/cms/cms_sd.c
index cdac3b870d..e3192b9c57 100644
--- a/src/lib/libcrypto/cms/cms_sd.c
+++ b/src/lib/libcrypto/cms/cms_sd.c
@@ -58,6 +58,7 @@
58#include <openssl/err.h> 58#include <openssl/err.h>
59#include <openssl/cms.h> 59#include <openssl/cms.h>
60#include "cms_lcl.h" 60#include "cms_lcl.h"
61#include "asn1_locl.h"
61 62
62/* CMS SignedData Utilities */ 63/* CMS SignedData Utilities */
63 64
@@ -218,10 +219,9 @@ int cms_set1_SignerIdentifier(CMS_SignerIdentifier *sid, X509 *cert, int type)
218 if (!X509_NAME_set(&sid->d.issuerAndSerialNumber->issuer, 219 if (!X509_NAME_set(&sid->d.issuerAndSerialNumber->issuer,
219 X509_get_issuer_name(cert))) 220 X509_get_issuer_name(cert)))
220 goto merr; 221 goto merr;
221 ASN1_STRING_free(sid->d.issuerAndSerialNumber->serialNumber); 222 if (!ASN1_STRING_copy(
222 sid->d.issuerAndSerialNumber->serialNumber = 223 sid->d.issuerAndSerialNumber->serialNumber,
223 ASN1_STRING_dup(X509_get_serialNumber(cert)); 224 X509_get_serialNumber(cert)))
224 if(!sid->d.issuerAndSerialNumber->serialNumber)
225 goto merr; 225 goto merr;
226 break; 226 break;
227 227
@@ -341,16 +341,22 @@ CMS_SignerInfo *CMS_add1_signer(CMS_ContentInfo *cms,
341 if (!cms_set1_SignerIdentifier(si->sid, signer, type)) 341 if (!cms_set1_SignerIdentifier(si->sid, signer, type))
342 goto err; 342 goto err;
343 343
344 /* Since no EVP_PKEY_METHOD in 0.9.8 hard code SHA1 as default */
345 if (md == NULL) 344 if (md == NULL)
346 md = EVP_sha1(); 345 {
347 346 int def_nid;
348 /* OpenSSL 0.9.8 only supports SHA1 with non-RSA keys */ 347 if (EVP_PKEY_get_default_digest_nid(pk, &def_nid) <= 0)
348 goto err;
349 md = EVP_get_digestbynid(def_nid);
350 if (md == NULL)
351 {
352 CMSerr(CMS_F_CMS_ADD1_SIGNER, CMS_R_NO_DEFAULT_DIGEST);
353 goto err;
354 }
355 }
349 356
350 if ((pk->type != EVP_PKEY_RSA) && (EVP_MD_type(md) != NID_sha1)) 357 if (!md)
351 { 358 {
352 CMSerr(CMS_F_CMS_ADD1_SIGNER, 359 CMSerr(CMS_F_CMS_ADD1_SIGNER, CMS_R_NO_DIGEST_SET);
353 CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE);
354 goto err; 360 goto err;
355 } 361 }
356 362
@@ -379,37 +385,21 @@ CMS_SignerInfo *CMS_add1_signer(CMS_ContentInfo *cms,
379 } 385 }
380 } 386 }
381 387
382 /* Since we have no EVP_PKEY_ASN1_METHOD in OpenSSL 0.9.8, 388 if (pk->ameth && pk->ameth->pkey_ctrl)
383 * hard code algorithm parameters.
384 */
385
386 switch (pk->type)
387 { 389 {
388 390 i = pk->ameth->pkey_ctrl(pk, ASN1_PKEY_CTRL_CMS_SIGN,
389 case EVP_PKEY_RSA: 391 0, si);
390 X509_ALGOR_set0(si->signatureAlgorithm, 392 if (i == -2)
391 OBJ_nid2obj(NID_rsaEncryption), 393 {
392 V_ASN1_NULL, 0); 394 CMSerr(CMS_F_CMS_ADD1_SIGNER,
393 break;
394
395 case EVP_PKEY_DSA:
396 X509_ALGOR_set0(si->signatureAlgorithm,
397 OBJ_nid2obj(NID_dsaWithSHA1),
398 V_ASN1_UNDEF, 0);
399 break;
400
401
402 case EVP_PKEY_EC:
403 X509_ALGOR_set0(si->signatureAlgorithm,
404 OBJ_nid2obj(NID_ecdsa_with_SHA1),
405 V_ASN1_UNDEF, 0);
406 break;
407
408 default:
409 CMSerr(CMS_F_CMS_ADD1_SIGNER,
410 CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE); 395 CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE);
411 goto err; 396 goto err;
412 397 }
398 if (i <= 0)
399 {
400 CMSerr(CMS_F_CMS_ADD1_SIGNER, CMS_R_CTRL_FAILURE);
401 goto err;
402 }
413 } 403 }
414 404
415 if (!(flags & CMS_NOATTR)) 405 if (!(flags & CMS_NOATTR))
@@ -626,25 +616,6 @@ void CMS_SignerInfo_get0_algs(CMS_SignerInfo *si, EVP_PKEY **pk, X509 **signer,
626 *psig = si->signatureAlgorithm; 616 *psig = si->signatureAlgorithm;
627 } 617 }
628 618
629/* In OpenSSL 0.9.8 we have the link between digest types and public
630 * key types so we need to fixup the digest type if the public key
631 * type is not appropriate.
632 */
633
634static void cms_fixup_mctx(EVP_MD_CTX *mctx, EVP_PKEY *pkey)
635 {
636 if (EVP_MD_CTX_type(mctx) != NID_sha1)
637 return;
638#ifndef OPENSSL_NO_DSA
639 if (pkey->type == EVP_PKEY_DSA)
640 mctx->digest = EVP_dss1();
641#endif
642#ifndef OPENSSL_NO_ECDSA
643 if (pkey->type == EVP_PKEY_EC)
644 mctx->digest = EVP_ecdsa();
645#endif
646 }
647
648static int cms_SignerInfo_content_sign(CMS_ContentInfo *cms, 619static int cms_SignerInfo_content_sign(CMS_ContentInfo *cms,
649 CMS_SignerInfo *si, BIO *chain) 620 CMS_SignerInfo *si, BIO *chain)
650 { 621 {
@@ -693,7 +664,6 @@ static int cms_SignerInfo_content_sign(CMS_ContentInfo *cms,
693 ERR_R_MALLOC_FAILURE); 664 ERR_R_MALLOC_FAILURE);
694 goto err; 665 goto err;
695 } 666 }
696 cms_fixup_mctx(&mctx, si->pkey);
697 if (!EVP_SignFinal(&mctx, sig, &siglen, si->pkey)) 667 if (!EVP_SignFinal(&mctx, sig, &siglen, si->pkey))
698 { 668 {
699 CMSerr(CMS_F_CMS_SIGNERINFO_CONTENT_SIGN, 669 CMSerr(CMS_F_CMS_SIGNERINFO_CONTENT_SIGN,
@@ -731,9 +701,10 @@ int cms_SignedData_final(CMS_ContentInfo *cms, BIO *chain)
731int CMS_SignerInfo_sign(CMS_SignerInfo *si) 701int CMS_SignerInfo_sign(CMS_SignerInfo *si)
732 { 702 {
733 EVP_MD_CTX mctx; 703 EVP_MD_CTX mctx;
704 EVP_PKEY_CTX *pctx;
734 unsigned char *abuf = NULL; 705 unsigned char *abuf = NULL;
735 int alen; 706 int alen;
736 unsigned int siglen; 707 size_t siglen;
737 const EVP_MD *md = NULL; 708 const EVP_MD *md = NULL;
738 709
739 md = EVP_get_digestbyobj(si->digestAlgorithm->algorithm); 710 md = EVP_get_digestbyobj(si->digestAlgorithm->algorithm);
@@ -748,40 +719,38 @@ int CMS_SignerInfo_sign(CMS_SignerInfo *si)
748 goto err; 719 goto err;
749 } 720 }
750 721
751 if (EVP_SignInit_ex(&mctx, md, NULL) <= 0) 722 if (EVP_DigestSignInit(&mctx, &pctx, md, NULL, si->pkey) <= 0)
752 goto err; 723 goto err;
753 724
754#if 0
755 if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_SIGN, 725 if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_SIGN,
756 EVP_PKEY_CTRL_CMS_SIGN, 0, si) <= 0) 726 EVP_PKEY_CTRL_CMS_SIGN, 0, si) <= 0)
757 { 727 {
758 CMSerr(CMS_F_CMS_SIGNERINFO_SIGN, CMS_R_CTRL_ERROR); 728 CMSerr(CMS_F_CMS_SIGNERINFO_SIGN, CMS_R_CTRL_ERROR);
759 goto err; 729 goto err;
760 } 730 }
761#endif
762 731
763 alen = ASN1_item_i2d((ASN1_VALUE *)si->signedAttrs,&abuf, 732 alen = ASN1_item_i2d((ASN1_VALUE *)si->signedAttrs,&abuf,
764 ASN1_ITEM_rptr(CMS_Attributes_Sign)); 733 ASN1_ITEM_rptr(CMS_Attributes_Sign));
765 if(!abuf) 734 if(!abuf)
766 goto err; 735 goto err;
767 if (EVP_SignUpdate(&mctx, abuf, alen) <= 0) 736 if (EVP_DigestSignUpdate(&mctx, abuf, alen) <= 0)
737 goto err;
738 if (EVP_DigestSignFinal(&mctx, NULL, &siglen) <= 0)
768 goto err; 739 goto err;
769 siglen = EVP_PKEY_size(si->pkey);
770 OPENSSL_free(abuf); 740 OPENSSL_free(abuf);
771 abuf = OPENSSL_malloc(siglen); 741 abuf = OPENSSL_malloc(siglen);
772 if(!abuf) 742 if(!abuf)
773 goto err; 743 goto err;
774 cms_fixup_mctx(&mctx, si->pkey); 744 if (EVP_DigestSignFinal(&mctx, abuf, &siglen) <= 0)
775 if (EVP_SignFinal(&mctx, abuf, &siglen, si->pkey) <= 0)
776 goto err; 745 goto err;
777#if 0 746
778 if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_SIGN, 747 if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_SIGN,
779 EVP_PKEY_CTRL_CMS_SIGN, 1, si) <= 0) 748 EVP_PKEY_CTRL_CMS_SIGN, 1, si) <= 0)
780 { 749 {
781 CMSerr(CMS_F_CMS_SIGNERINFO_SIGN, CMS_R_CTRL_ERROR); 750 CMSerr(CMS_F_CMS_SIGNERINFO_SIGN, CMS_R_CTRL_ERROR);
782 goto err; 751 goto err;
783 } 752 }
784#endif 753
785 EVP_MD_CTX_cleanup(&mctx); 754 EVP_MD_CTX_cleanup(&mctx);
786 755
787 ASN1_STRING_set0(si->signature, abuf, siglen); 756 ASN1_STRING_set0(si->signature, abuf, siglen);
@@ -799,6 +768,7 @@ int CMS_SignerInfo_sign(CMS_SignerInfo *si)
799int CMS_SignerInfo_verify(CMS_SignerInfo *si) 768int CMS_SignerInfo_verify(CMS_SignerInfo *si)
800 { 769 {
801 EVP_MD_CTX mctx; 770 EVP_MD_CTX mctx;
771 EVP_PKEY_CTX *pctx;
802 unsigned char *abuf = NULL; 772 unsigned char *abuf = NULL;
803 int alen, r = -1; 773 int alen, r = -1;
804 const EVP_MD *md = NULL; 774 const EVP_MD *md = NULL;
@@ -813,23 +783,22 @@ int CMS_SignerInfo_verify(CMS_SignerInfo *si)
813 if (md == NULL) 783 if (md == NULL)
814 return -1; 784 return -1;
815 EVP_MD_CTX_init(&mctx); 785 EVP_MD_CTX_init(&mctx);
816 if (EVP_VerifyInit_ex(&mctx, md, NULL) <= 0) 786 if (EVP_DigestVerifyInit(&mctx, &pctx, md, NULL, si->pkey) <= 0)
817 goto err; 787 goto err;
818 788
819 alen = ASN1_item_i2d((ASN1_VALUE *)si->signedAttrs,&abuf, 789 alen = ASN1_item_i2d((ASN1_VALUE *)si->signedAttrs,&abuf,
820 ASN1_ITEM_rptr(CMS_Attributes_Verify)); 790 ASN1_ITEM_rptr(CMS_Attributes_Verify));
821 if(!abuf) 791 if(!abuf)
822 goto err; 792 goto err;
823 r = EVP_VerifyUpdate(&mctx, abuf, alen); 793 r = EVP_DigestVerifyUpdate(&mctx, abuf, alen);
824 OPENSSL_free(abuf); 794 OPENSSL_free(abuf);
825 if (r <= 0) 795 if (r <= 0)
826 { 796 {
827 r = -1; 797 r = -1;
828 goto err; 798 goto err;
829 } 799 }
830 cms_fixup_mctx(&mctx, si->pkey); 800 r = EVP_DigestVerifyFinal(&mctx,
831 r = EVP_VerifyFinal(&mctx, 801 si->signature->data, si->signature->length);
832 si->signature->data, si->signature->length, si->pkey);
833 if (r <= 0) 802 if (r <= 0)
834 CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY, CMS_R_VERIFICATION_FAILURE); 803 CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY, CMS_R_VERIFICATION_FAILURE);
835 err: 804 err:
@@ -922,7 +891,6 @@ int CMS_SignerInfo_verify_content(CMS_SignerInfo *si, BIO *chain)
922 } 891 }
923 else 892 else
924 { 893 {
925 cms_fixup_mctx(&mctx, si->pkey);
926 r = EVP_VerifyFinal(&mctx, si->signature->data, 894 r = EVP_VerifyFinal(&mctx, si->signature->data,
927 si->signature->length, si->pkey); 895 si->signature->length, si->pkey);
928 if (r <= 0) 896 if (r <= 0)
@@ -991,17 +959,19 @@ static int cms_add_cipher_smcap(STACK_OF(X509_ALGOR) **sk, int nid, int arg)
991 return CMS_add_simple_smimecap(sk, nid, arg); 959 return CMS_add_simple_smimecap(sk, nid, arg);
992 return 1; 960 return 1;
993 } 961 }
994#if 0 962
995static int cms_add_digest_smcap(STACK_OF(X509_ALGOR) **sk, int nid, int arg) 963static int cms_add_digest_smcap(STACK_OF(X509_ALGOR) **sk, int nid, int arg)
996 { 964 {
997 if (EVP_get_digestbynid(nid)) 965 if (EVP_get_digestbynid(nid))
998 return CMS_add_simple_smimecap(sk, nid, arg); 966 return CMS_add_simple_smimecap(sk, nid, arg);
999 return 1; 967 return 1;
1000 } 968 }
1001#endif 969
1002int CMS_add_standard_smimecap(STACK_OF(X509_ALGOR) **smcap) 970int CMS_add_standard_smimecap(STACK_OF(X509_ALGOR) **smcap)
1003 { 971 {
1004 if (!cms_add_cipher_smcap(smcap, NID_aes_256_cbc, -1) 972 if (!cms_add_cipher_smcap(smcap, NID_aes_256_cbc, -1)
973 || !cms_add_digest_smcap(smcap, NID_id_GostR3411_94, -1)
974 || !cms_add_cipher_smcap(smcap, NID_id_Gost28147_89, -1)
1005 || !cms_add_cipher_smcap(smcap, NID_aes_192_cbc, -1) 975 || !cms_add_cipher_smcap(smcap, NID_aes_192_cbc, -1)
1006 || !cms_add_cipher_smcap(smcap, NID_aes_128_cbc, -1) 976 || !cms_add_cipher_smcap(smcap, NID_aes_128_cbc, -1)
1007 || !cms_add_cipher_smcap(smcap, NID_des_ede3_cbc, -1) 977 || !cms_add_cipher_smcap(smcap, NID_des_ede3_cbc, -1)
diff --git a/src/lib/libcrypto/cms/cms_smime.c b/src/lib/libcrypto/cms/cms_smime.c
index f35883aa22..4a799eb897 100644
--- a/src/lib/libcrypto/cms/cms_smime.c
+++ b/src/lib/libcrypto/cms/cms_smime.c
@@ -171,7 +171,7 @@ CMS_ContentInfo *CMS_data_create(BIO *in, unsigned int flags)
171 if (!cms) 171 if (!cms)
172 return NULL; 172 return NULL;
173 173
174 if (CMS_final(cms, in, NULL, flags)) 174 if ((flags & CMS_STREAM) || CMS_final(cms, in, NULL, flags))
175 return cms; 175 return cms;
176 176
177 CMS_ContentInfo_free(cms); 177 CMS_ContentInfo_free(cms);
@@ -214,10 +214,7 @@ CMS_ContentInfo *CMS_digest_create(BIO *in, const EVP_MD *md,
214 return NULL; 214 return NULL;
215 215
216 if(!(flags & CMS_DETACHED)) 216 if(!(flags & CMS_DETACHED))
217 {
218 flags &= ~CMS_STREAM;
219 CMS_set_detached(cms, 0); 217 CMS_set_detached(cms, 0);
220 }
221 218
222 if ((flags & CMS_STREAM) || CMS_final(cms, in, NULL, flags)) 219 if ((flags & CMS_STREAM) || CMS_final(cms, in, NULL, flags))
223 return cms; 220 return cms;
@@ -269,10 +266,7 @@ CMS_ContentInfo *CMS_EncryptedData_encrypt(BIO *in, const EVP_CIPHER *cipher,
269 return NULL; 266 return NULL;
270 267
271 if(!(flags & CMS_DETACHED)) 268 if(!(flags & CMS_DETACHED))
272 {
273 flags &= ~CMS_STREAM;
274 CMS_set_detached(cms, 0); 269 CMS_set_detached(cms, 0);
275 }
276 270
277 if ((flags & (CMS_STREAM|CMS_PARTIAL)) 271 if ((flags & (CMS_STREAM|CMS_PARTIAL))
278 || CMS_final(cms, in, NULL, flags)) 272 || CMS_final(cms, in, NULL, flags))
@@ -456,6 +450,7 @@ int CMS_verify_receipt(CMS_ContentInfo *rcms, CMS_ContentInfo *ocms,
456 X509_STORE *store, unsigned int flags) 450 X509_STORE *store, unsigned int flags)
457 { 451 {
458 int r; 452 int r;
453 flags &= ~(CMS_DETACHED|CMS_TEXT);
459 r = CMS_verify(rcms, certs, store, NULL, NULL, flags); 454 r = CMS_verify(rcms, certs, store, NULL, NULL, flags);
460 if (r <= 0) 455 if (r <= 0)
461 return r; 456 return r;
@@ -486,10 +481,7 @@ CMS_ContentInfo *CMS_sign(X509 *signcert, EVP_PKEY *pkey, STACK_OF(X509) *certs,
486 } 481 }
487 482
488 if(!(flags & CMS_DETACHED)) 483 if(!(flags & CMS_DETACHED))
489 {
490 flags &= ~CMS_STREAM;
491 CMS_set_detached(cms, 0); 484 CMS_set_detached(cms, 0);
492 }
493 485
494 if ((flags & (CMS_STREAM|CMS_PARTIAL)) 486 if ((flags & (CMS_STREAM|CMS_PARTIAL))
495 || CMS_final(cms, data, NULL, flags)) 487 || CMS_final(cms, data, NULL, flags))
@@ -517,7 +509,7 @@ CMS_ContentInfo *CMS_sign_receipt(CMS_SignerInfo *si,
517 BIO *rct_cont = NULL; 509 BIO *rct_cont = NULL;
518 int r = 0; 510 int r = 0;
519 511
520 flags &= ~CMS_STREAM; 512 flags &= ~(CMS_STREAM|CMS_TEXT);
521 /* Not really detached but avoids content being allocated */ 513 /* Not really detached but avoids content being allocated */
522 flags |= CMS_PARTIAL|CMS_BINARY|CMS_DETACHED; 514 flags |= CMS_PARTIAL|CMS_BINARY|CMS_DETACHED;
523 if (!pkey || !signcert) 515 if (!pkey || !signcert)
@@ -598,10 +590,7 @@ CMS_ContentInfo *CMS_encrypt(STACK_OF(X509) *certs, BIO *data,
598 } 590 }
599 591
600 if(!(flags & CMS_DETACHED)) 592 if(!(flags & CMS_DETACHED))
601 {
602 flags &= ~CMS_STREAM;
603 CMS_set_detached(cms, 0); 593 CMS_set_detached(cms, 0);
604 }
605 594
606 if ((flags & (CMS_STREAM|CMS_PARTIAL)) 595 if ((flags & (CMS_STREAM|CMS_PARTIAL))
607 || CMS_final(cms, data, NULL, flags)) 596 || CMS_final(cms, data, NULL, flags))
@@ -781,12 +770,9 @@ CMS_ContentInfo *CMS_compress(BIO *in, int comp_nid, unsigned int flags)
781 return NULL; 770 return NULL;
782 771
783 if(!(flags & CMS_DETACHED)) 772 if(!(flags & CMS_DETACHED))
784 {
785 flags &= ~CMS_STREAM;
786 CMS_set_detached(cms, 0); 773 CMS_set_detached(cms, 0);
787 }
788 774
789 if (CMS_final(cms, in, NULL, flags)) 775 if ((flags & CMS_STREAM) || CMS_final(cms, in, NULL, flags))
790 return cms; 776 return cms;
791 777
792 CMS_ContentInfo_free(cms); 778 CMS_ContentInfo_free(cms);
diff --git a/src/lib/libcrypto/comp/c_zlib.c b/src/lib/libcrypto/comp/c_zlib.c
index eccfd09137..8adf35f3fc 100644
--- a/src/lib/libcrypto/comp/c_zlib.c
+++ b/src/lib/libcrypto/comp/c_zlib.c
@@ -136,15 +136,6 @@ struct zlib_state
136 136
137static int zlib_stateful_ex_idx = -1; 137static int zlib_stateful_ex_idx = -1;
138 138
139static void zlib_stateful_free_ex_data(void *obj, void *item,
140 CRYPTO_EX_DATA *ad, int ind,long argl, void *argp)
141 {
142 struct zlib_state *state = (struct zlib_state *)item;
143 inflateEnd(&state->istream);
144 deflateEnd(&state->ostream);
145 OPENSSL_free(state);
146 }
147
148static int zlib_stateful_init(COMP_CTX *ctx) 139static int zlib_stateful_init(COMP_CTX *ctx)
149 { 140 {
150 int err; 141 int err;
@@ -188,6 +179,12 @@ static int zlib_stateful_init(COMP_CTX *ctx)
188 179
189static void zlib_stateful_finish(COMP_CTX *ctx) 180static void zlib_stateful_finish(COMP_CTX *ctx)
190 { 181 {
182 struct zlib_state *state =
183 (struct zlib_state *)CRYPTO_get_ex_data(&ctx->ex_data,
184 zlib_stateful_ex_idx);
185 inflateEnd(&state->istream);
186 deflateEnd(&state->ostream);
187 OPENSSL_free(state);
191 CRYPTO_free_ex_data(CRYPTO_EX_INDEX_COMP,ctx,&ctx->ex_data); 188 CRYPTO_free_ex_data(CRYPTO_EX_INDEX_COMP,ctx,&ctx->ex_data);
192 } 189 }
193 190
@@ -402,7 +399,7 @@ COMP_METHOD *COMP_zlib(void)
402 if (zlib_stateful_ex_idx == -1) 399 if (zlib_stateful_ex_idx == -1)
403 zlib_stateful_ex_idx = 400 zlib_stateful_ex_idx =
404 CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_COMP, 401 CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_COMP,
405 0,NULL,NULL,NULL,zlib_stateful_free_ex_data); 402 0,NULL,NULL,NULL,NULL);
406 CRYPTO_w_unlock(CRYPTO_LOCK_COMP); 403 CRYPTO_w_unlock(CRYPTO_LOCK_COMP);
407 if (zlib_stateful_ex_idx == -1) 404 if (zlib_stateful_ex_idx == -1)
408 goto err; 405 goto err;
@@ -784,6 +781,7 @@ static long bio_zlib_ctrl(BIO *b, int cmd, long num, void *ptr)
784 default: 781 default:
785 ret = BIO_ctrl(b->next_bio, cmd, num, ptr); 782 ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
786 break; 783 break;
784
787 } 785 }
788 786
789 return ret; 787 return ret;
diff --git a/src/lib/libcrypto/comp/comp_err.c b/src/lib/libcrypto/comp/comp_err.c
index 187d68b725..661c94c3a4 100644
--- a/src/lib/libcrypto/comp/comp_err.c
+++ b/src/lib/libcrypto/comp/comp_err.c
@@ -1,6 +1,6 @@
1/* crypto/comp/comp_err.c */ 1/* crypto/comp/comp_err.c */
2/* ==================================================================== 2/* ====================================================================
3 * Copyright (c) 1999-2008 The OpenSSL Project. All rights reserved. 3 * Copyright (c) 1999-2007 The OpenSSL Project. All rights reserved.
4 * 4 *
5 * Redistribution and use in source and binary forms, with or without 5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions 6 * modification, are permitted provided that the following conditions
diff --git a/src/lib/libcrypto/conf/README b/src/lib/libcrypto/conf/README
index ca58d0240f..96e53b34ed 100644
--- a/src/lib/libcrypto/conf/README
+++ b/src/lib/libcrypto/conf/README
@@ -1,8 +1,3 @@
1WARNING WARNING WARNING!!!
2
3This stuff is experimental, may change radically or be deleted altogether
4before OpenSSL 0.9.7 release. You have been warned!
5
6Configuration modules. These are a set of modules which can perform 1Configuration modules. These are a set of modules which can perform
7various configuration functions. 2various configuration functions.
8 3
@@ -13,7 +8,7 @@ The routines read a configuration file set up like this:
13 8
14----- 9-----
15#default section 10#default section
16openssl_init=init_section 11openssl_conf=init_section
17 12
18[init_section] 13[init_section]
19 14
@@ -30,29 +25,27 @@ path=/some/path/to/some/dso.so
30other_stuff=other_value 25other_stuff=other_value
31---- 26----
32 27
33When this file is loaded a configuration module with the specified 28When this file is loaded a configuration module with the specified string
34string (module* in the above example) is looked up and its init 29(module* in the above example) is looked up and its init function called as:
35function called as:
36 30
37int conf_init_func(CONF_IMODULE *md, CONF *cnf); 31int conf_init_func(CONF_IMODULE *md, CONF *cnf);
38 32
39The function can then take whatever action is appropriate, for example 33The function can then take whatever action is appropriate, for example further
40further lookups based on the value. Multiple instances of the same 34lookups based on the value. Multiple instances of the same config module can be
41config module can be loaded. 35loaded.
42 36
43When the application closes down the modules are cleaned up by calling 37When the application closes down the modules are cleaned up by calling an
44an optional finish function: 38optional finish function:
45 39
46void conf_finish_func(CONF_IMODULE *md); 40void conf_finish_func(CONF_IMODULE *md);
47 41
48The finish functions are called in reverse order: that is the last module 42The finish functions are called in reverse order: that is the last module
49loaded is the first one cleaned up. 43loaded is the first one cleaned up.
50 44
51If no module exists with a given name then an attempt is made to load 45If no module exists with a given name then an attempt is made to load a DSO
52a DSO with the supplied name. This might mean that "module3" attempts 46with the supplied name. This might mean that "module3" attempts to load a DSO
53to load a DSO called libmodule3.so or module3.dll for example. An explicit 47called libmodule3.so or module3.dll for example. An explicit DSO name can be
54DSO name can be given by including a separate section as in the module4 example 48given by including a separate section as in the module4 example above.
55above.
56 49
57The DSO is expected to at least contain an initialization function: 50The DSO is expected to at least contain an initialization function:
58 51
@@ -64,15 +57,17 @@ void OPENSSL_finish(CONF_IMODULE *md);
64 57
65Static modules can also be added using, 58Static modules can also be added using,
66 59
67int CONF_module_add(char *name, dso_mod_init_func *ifunc, dso_mod_finish_func *ffunc); 60int CONF_module_add(char *name, dso_mod_init_func *ifunc, dso_mod_finish_func
61*ffunc);
68 62
69where "name" is the name in the configuration file this function corresponds to. 63where "name" is the name in the configuration file this function corresponds
64to.
70 65
71A set of builtin modules (currently only an ASN1 non functional test module) can be 66A set of builtin modules (currently only an ASN1 non functional test module)
72added by calling OPENSSL_load_builtin_modules(). 67can be added by calling OPENSSL_load_builtin_modules().
73 68
74The function OPENSSL_config() is intended as a simple configuration function that 69The function OPENSSL_config() is intended as a simple configuration function
75any application can call to perform various default configuration tasks. It uses the 70that any application can call to perform various default configuration tasks.
76file openssl.cnf in the usual locations. 71It uses the file openssl.cnf in the usual locations.
77 72
78 73
diff --git a/src/lib/libcrypto/conf/conf.h b/src/lib/libcrypto/conf/conf.h
index 8aa06bc5ec..c2199978a3 100644
--- a/src/lib/libcrypto/conf/conf.h
+++ b/src/lib/libcrypto/conf/conf.h
@@ -79,8 +79,7 @@ typedef struct
79 } CONF_VALUE; 79 } CONF_VALUE;
80 80
81DECLARE_STACK_OF(CONF_VALUE) 81DECLARE_STACK_OF(CONF_VALUE)
82DECLARE_STACK_OF(CONF_MODULE) 82DECLARE_LHASH_OF(CONF_VALUE);
83DECLARE_STACK_OF(CONF_IMODULE)
84 83
85struct conf_st; 84struct conf_st;
86struct conf_method_st; 85struct conf_method_st;
@@ -105,6 +104,9 @@ struct conf_method_st
105typedef struct conf_imodule_st CONF_IMODULE; 104typedef struct conf_imodule_st CONF_IMODULE;
106typedef struct conf_module_st CONF_MODULE; 105typedef struct conf_module_st CONF_MODULE;
107 106
107DECLARE_STACK_OF(CONF_MODULE)
108DECLARE_STACK_OF(CONF_IMODULE)
109
108/* DSO module function typedefs */ 110/* DSO module function typedefs */
109typedef int conf_init_func(CONF_IMODULE *md, const CONF *cnf); 111typedef int conf_init_func(CONF_IMODULE *md, const CONF *cnf);
110typedef void conf_finish_func(CONF_IMODULE *md); 112typedef void conf_finish_func(CONF_IMODULE *md);
@@ -117,18 +119,23 @@ typedef void conf_finish_func(CONF_IMODULE *md);
117#define CONF_MFLAGS_DEFAULT_SECTION 0x20 119#define CONF_MFLAGS_DEFAULT_SECTION 0x20
118 120
119int CONF_set_default_method(CONF_METHOD *meth); 121int CONF_set_default_method(CONF_METHOD *meth);
120void CONF_set_nconf(CONF *conf,LHASH *hash); 122void CONF_set_nconf(CONF *conf,LHASH_OF(CONF_VALUE) *hash);
121LHASH *CONF_load(LHASH *conf,const char *file,long *eline); 123LHASH_OF(CONF_VALUE) *CONF_load(LHASH_OF(CONF_VALUE) *conf,const char *file,
124 long *eline);
122#ifndef OPENSSL_NO_FP_API 125#ifndef OPENSSL_NO_FP_API
123LHASH *CONF_load_fp(LHASH *conf, FILE *fp,long *eline); 126LHASH_OF(CONF_VALUE) *CONF_load_fp(LHASH_OF(CONF_VALUE) *conf, FILE *fp,
127 long *eline);
124#endif 128#endif
125LHASH *CONF_load_bio(LHASH *conf, BIO *bp,long *eline); 129LHASH_OF(CONF_VALUE) *CONF_load_bio(LHASH_OF(CONF_VALUE) *conf, BIO *bp,long *eline);
126STACK_OF(CONF_VALUE) *CONF_get_section(LHASH *conf,const char *section); 130STACK_OF(CONF_VALUE) *CONF_get_section(LHASH_OF(CONF_VALUE) *conf,
127char *CONF_get_string(LHASH *conf,const char *group,const char *name); 131 const char *section);
128long CONF_get_number(LHASH *conf,const char *group,const char *name); 132char *CONF_get_string(LHASH_OF(CONF_VALUE) *conf,const char *group,
129void CONF_free(LHASH *conf); 133 const char *name);
130int CONF_dump_fp(LHASH *conf, FILE *out); 134long CONF_get_number(LHASH_OF(CONF_VALUE) *conf,const char *group,
131int CONF_dump_bio(LHASH *conf, BIO *out); 135 const char *name);
136void CONF_free(LHASH_OF(CONF_VALUE) *conf);
137int CONF_dump_fp(LHASH_OF(CONF_VALUE) *conf, FILE *out);
138int CONF_dump_bio(LHASH_OF(CONF_VALUE) *conf, BIO *out);
132 139
133void OPENSSL_config(const char *config_name); 140void OPENSSL_config(const char *config_name);
134void OPENSSL_no_config(void); 141void OPENSSL_no_config(void);
@@ -140,7 +147,7 @@ struct conf_st
140 { 147 {
141 CONF_METHOD *meth; 148 CONF_METHOD *meth;
142 void *meth_data; 149 void *meth_data;
143 LHASH *data; 150 LHASH_OF(CONF_VALUE) *data;
144 }; 151 };
145 152
146CONF *NCONF_new(CONF_METHOD *meth); 153CONF *NCONF_new(CONF_METHOD *meth);
@@ -214,6 +221,7 @@ void ERR_load_CONF_strings(void);
214#define CONF_F_CONF_LOAD_BIO 102 221#define CONF_F_CONF_LOAD_BIO 102
215#define CONF_F_CONF_LOAD_FP 103 222#define CONF_F_CONF_LOAD_FP 103
216#define CONF_F_CONF_MODULES_LOAD 116 223#define CONF_F_CONF_MODULES_LOAD 116
224#define CONF_F_CONF_PARSE_LIST 119
217#define CONF_F_DEF_LOAD 120 225#define CONF_F_DEF_LOAD 120
218#define CONF_F_DEF_LOAD_BIO 121 226#define CONF_F_DEF_LOAD_BIO 121
219#define CONF_F_MODULE_INIT 115 227#define CONF_F_MODULE_INIT 115
@@ -233,6 +241,7 @@ void ERR_load_CONF_strings(void);
233 241
234/* Reason codes. */ 242/* Reason codes. */
235#define CONF_R_ERROR_LOADING_DSO 110 243#define CONF_R_ERROR_LOADING_DSO 110
244#define CONF_R_LIST_CANNOT_BE_NULL 115
236#define CONF_R_MISSING_CLOSE_SQUARE_BRACKET 100 245#define CONF_R_MISSING_CLOSE_SQUARE_BRACKET 100
237#define CONF_R_MISSING_EQUAL_SIGN 101 246#define CONF_R_MISSING_EQUAL_SIGN 101
238#define CONF_R_MISSING_FINISH_FUNCTION 111 247#define CONF_R_MISSING_FINISH_FUNCTION 111
diff --git a/src/lib/libcrypto/conf/conf_api.c b/src/lib/libcrypto/conf/conf_api.c
index 909d72b4b8..22617e5fa1 100644
--- a/src/lib/libcrypto/conf/conf_api.c
+++ b/src/lib/libcrypto/conf/conf_api.c
@@ -69,16 +69,12 @@
69#include <openssl/conf_api.h> 69#include <openssl/conf_api.h>
70#include "e_os.h" 70#include "e_os.h"
71 71
72static void value_free_hash(CONF_VALUE *a, LHASH *conf); 72static void value_free_hash_doall_arg(CONF_VALUE *a,
73static void value_free_stack(CONF_VALUE *a,LHASH *conf); 73 LHASH_OF(CONF_VALUE) *conf);
74static IMPLEMENT_LHASH_DOALL_ARG_FN(value_free_hash, CONF_VALUE *, LHASH *) 74static void value_free_stack_doall(CONF_VALUE *a);
75static IMPLEMENT_LHASH_DOALL_ARG_FN(value_free_stack, CONF_VALUE *, LHASH *) 75static IMPLEMENT_LHASH_DOALL_ARG_FN(value_free_hash, CONF_VALUE,
76/* We don't use function pointer casting or wrapper functions - but cast each 76 LHASH_OF(CONF_VALUE))
77 * callback parameter inside the callback functions. */ 77static IMPLEMENT_LHASH_DOALL_FN(value_free_stack, CONF_VALUE)
78/* static unsigned long hash(CONF_VALUE *v); */
79static unsigned long hash(const void *v_void);
80/* static int cmp_conf(CONF_VALUE *a,CONF_VALUE *b); */
81static int cmp_conf(const void *a_void,const void *b_void);
82 78
83/* Up until OpenSSL 0.9.5a, this was get_section */ 79/* Up until OpenSSL 0.9.5a, this was get_section */
84CONF_VALUE *_CONF_get_section(const CONF *conf, const char *section) 80CONF_VALUE *_CONF_get_section(const CONF *conf, const char *section)
@@ -88,7 +84,7 @@ CONF_VALUE *_CONF_get_section(const CONF *conf, const char *section)
88 if ((conf == NULL) || (section == NULL)) return(NULL); 84 if ((conf == NULL) || (section == NULL)) return(NULL);
89 vv.name=NULL; 85 vv.name=NULL;
90 vv.section=(char *)section; 86 vv.section=(char *)section;
91 v=(CONF_VALUE *)lh_retrieve(conf->data,&vv); 87 v=lh_CONF_VALUE_retrieve(conf->data,&vv);
92 return(v); 88 return(v);
93 } 89 }
94 90
@@ -118,7 +114,7 @@ int _CONF_add_string(CONF *conf, CONF_VALUE *section, CONF_VALUE *value)
118 return 0; 114 return 0;
119 } 115 }
120 116
121 v = (CONF_VALUE *)lh_insert(conf->data, value); 117 v = lh_CONF_VALUE_insert(conf->data, value);
122 if (v != NULL) 118 if (v != NULL)
123 { 119 {
124 (void)sk_CONF_VALUE_delete_ptr(ts,v); 120 (void)sk_CONF_VALUE_delete_ptr(ts,v);
@@ -141,24 +137,24 @@ char *_CONF_get_string(const CONF *conf, const char *section, const char *name)
141 { 137 {
142 vv.name=(char *)name; 138 vv.name=(char *)name;
143 vv.section=(char *)section; 139 vv.section=(char *)section;
144 v=(CONF_VALUE *)lh_retrieve(conf->data,&vv); 140 v=lh_CONF_VALUE_retrieve(conf->data,&vv);
145 if (v != NULL) return(v->value); 141 if (v != NULL) return(v->value);
146 if (strcmp(section,"ENV") == 0) 142 if (strcmp(section,"ENV") == 0)
147 { 143 {
148 p=Getenv(name); 144 p=getenv(name);
149 if (p != NULL) return(p); 145 if (p != NULL) return(p);
150 } 146 }
151 } 147 }
152 vv.section="default"; 148 vv.section="default";
153 vv.name=(char *)name; 149 vv.name=(char *)name;
154 v=(CONF_VALUE *)lh_retrieve(conf->data,&vv); 150 v=lh_CONF_VALUE_retrieve(conf->data,&vv);
155 if (v != NULL) 151 if (v != NULL)
156 return(v->value); 152 return(v->value);
157 else 153 else
158 return(NULL); 154 return(NULL);
159 } 155 }
160 else 156 else
161 return(Getenv(name)); 157 return(getenv(name));
162 } 158 }
163 159
164#if 0 /* There's no way to provide error checking with this function, so 160#if 0 /* There's no way to provide error checking with this function, so
@@ -182,6 +178,34 @@ long _CONF_get_number(CONF *conf, char *section, char *name)
182 } 178 }
183#endif 179#endif
184 180
181static unsigned long conf_value_hash(const CONF_VALUE *v)
182 {
183 return (lh_strhash(v->section)<<2)^lh_strhash(v->name);
184 }
185static IMPLEMENT_LHASH_HASH_FN(conf_value, CONF_VALUE)
186
187static int conf_value_cmp(const CONF_VALUE *a, const CONF_VALUE *b)
188 {
189 int i;
190
191 if (a->section != b->section)
192 {
193 i=strcmp(a->section,b->section);
194 if (i) return(i);
195 }
196
197 if ((a->name != NULL) && (b->name != NULL))
198 {
199 i=strcmp(a->name,b->name);
200 return(i);
201 }
202 else if (a->name == b->name)
203 return(0);
204 else
205 return((a->name == NULL)?-1:1);
206 }
207static IMPLEMENT_LHASH_COMP_FN(conf_value, CONF_VALUE)
208
185int _CONF_new_data(CONF *conf) 209int _CONF_new_data(CONF *conf)
186 { 210 {
187 if (conf == NULL) 211 if (conf == NULL)
@@ -189,7 +213,7 @@ int _CONF_new_data(CONF *conf)
189 return 0; 213 return 0;
190 } 214 }
191 if (conf->data == NULL) 215 if (conf->data == NULL)
192 if ((conf->data = lh_new(hash, cmp_conf)) == NULL) 216 if ((conf->data = lh_CONF_VALUE_new()) == NULL)
193 { 217 {
194 return 0; 218 return 0;
195 } 219 }
@@ -200,105 +224,73 @@ void _CONF_free_data(CONF *conf)
200 { 224 {
201 if (conf == NULL || conf->data == NULL) return; 225 if (conf == NULL || conf->data == NULL) return;
202 226
203 conf->data->down_load=0; /* evil thing to make sure the 'OPENSSL_free()' 227 lh_CONF_VALUE_down_load(conf->data)=0; /* evil thing to make
204 * works as expected */ 228 * sure the 'OPENSSL_free()' works as
205 lh_doall_arg(conf->data, LHASH_DOALL_ARG_FN(value_free_hash), 229 * expected */
206 conf->data); 230 lh_CONF_VALUE_doall_arg(conf->data,
231 LHASH_DOALL_ARG_FN(value_free_hash),
232 LHASH_OF(CONF_VALUE), conf->data);
207 233
208 /* We now have only 'section' entries in the hash table. 234 /* We now have only 'section' entries in the hash table.
209 * Due to problems with */ 235 * Due to problems with */
210 236
211 lh_doall_arg(conf->data, LHASH_DOALL_ARG_FN(value_free_stack), 237 lh_CONF_VALUE_doall(conf->data, LHASH_DOALL_FN(value_free_stack));
212 conf->data); 238 lh_CONF_VALUE_free(conf->data);
213 lh_free(conf->data);
214 } 239 }
215 240
216static void value_free_hash(CONF_VALUE *a, LHASH *conf) 241static void value_free_hash_doall_arg(CONF_VALUE *a, LHASH_OF(CONF_VALUE) *conf)
217 { 242 {
218 if (a->name != NULL) 243 if (a->name != NULL)
219 { 244 (void)lh_CONF_VALUE_delete(conf,a);
220 a=(CONF_VALUE *)lh_delete(conf,a);
221 }
222 } 245 }
223 246
224static void value_free_stack(CONF_VALUE *a, LHASH *conf) 247static void value_free_stack_doall(CONF_VALUE *a)
225 { 248 {
226 CONF_VALUE *vv; 249 CONF_VALUE *vv;
227 STACK *sk; 250 STACK_OF(CONF_VALUE) *sk;
228 int i; 251 int i;
229 252
230 if (a->name != NULL) return; 253 if (a->name != NULL) return;
231 254
232 sk=(STACK *)a->value; 255 sk=(STACK_OF(CONF_VALUE) *)a->value;
233 for (i=sk_num(sk)-1; i>=0; i--) 256 for (i=sk_CONF_VALUE_num(sk)-1; i>=0; i--)
234 { 257 {
235 vv=(CONF_VALUE *)sk_value(sk,i); 258 vv=sk_CONF_VALUE_value(sk,i);
236 OPENSSL_free(vv->value); 259 OPENSSL_free(vv->value);
237 OPENSSL_free(vv->name); 260 OPENSSL_free(vv->name);
238 OPENSSL_free(vv); 261 OPENSSL_free(vv);
239 } 262 }
240 if (sk != NULL) sk_free(sk); 263 if (sk != NULL) sk_CONF_VALUE_free(sk);
241 OPENSSL_free(a->section); 264 OPENSSL_free(a->section);
242 OPENSSL_free(a); 265 OPENSSL_free(a);
243 } 266 }
244 267
245/* static unsigned long hash(CONF_VALUE *v) */
246static unsigned long hash(const void *v_void)
247 {
248 CONF_VALUE *v = (CONF_VALUE *)v_void;
249 return((lh_strhash(v->section)<<2)^lh_strhash(v->name));
250 }
251
252/* static int cmp_conf(CONF_VALUE *a, CONF_VALUE *b) */
253static int cmp_conf(const void *a_void,const void *b_void)
254 {
255 int i;
256 CONF_VALUE *a = (CONF_VALUE *)a_void;
257 CONF_VALUE *b = (CONF_VALUE *)b_void;
258
259 if (a->section != b->section)
260 {
261 i=strcmp(a->section,b->section);
262 if (i) return(i);
263 }
264
265 if ((a->name != NULL) && (b->name != NULL))
266 {
267 i=strcmp(a->name,b->name);
268 return(i);
269 }
270 else if (a->name == b->name)
271 return(0);
272 else
273 return((a->name == NULL)?-1:1);
274 }
275
276/* Up until OpenSSL 0.9.5a, this was new_section */ 268/* Up until OpenSSL 0.9.5a, this was new_section */
277CONF_VALUE *_CONF_new_section(CONF *conf, const char *section) 269CONF_VALUE *_CONF_new_section(CONF *conf, const char *section)
278 { 270 {
279 STACK *sk=NULL; 271 STACK_OF(CONF_VALUE) *sk=NULL;
280 int ok=0,i; 272 int ok=0,i;
281 CONF_VALUE *v=NULL,*vv; 273 CONF_VALUE *v=NULL,*vv;
282 274
283 if ((sk=sk_new_null()) == NULL) 275 if ((sk=sk_CONF_VALUE_new_null()) == NULL)
284 goto err; 276 goto err;
285 if ((v=(CONF_VALUE *)OPENSSL_malloc(sizeof(CONF_VALUE))) == NULL) 277 if ((v=OPENSSL_malloc(sizeof(CONF_VALUE))) == NULL)
286 goto err; 278 goto err;
287 i=strlen(section)+1; 279 i=strlen(section)+1;
288 if ((v->section=(char *)OPENSSL_malloc(i)) == NULL) 280 if ((v->section=OPENSSL_malloc(i)) == NULL)
289 goto err; 281 goto err;
290 282
291 memcpy(v->section,section,i); 283 memcpy(v->section,section,i);
292 v->name=NULL; 284 v->name=NULL;
293 v->value=(char *)sk; 285 v->value=(char *)sk;
294 286
295 vv=(CONF_VALUE *)lh_insert(conf->data,v); 287 vv=lh_CONF_VALUE_insert(conf->data,v);
296 assert(vv == NULL); 288 assert(vv == NULL);
297 ok=1; 289 ok=1;
298err: 290err:
299 if (!ok) 291 if (!ok)
300 { 292 {
301 if (sk != NULL) sk_free(sk); 293 if (sk != NULL) sk_CONF_VALUE_free(sk);
302 if (v != NULL) OPENSSL_free(v); 294 if (v != NULL) OPENSSL_free(v);
303 v=NULL; 295 v=NULL;
304 } 296 }
diff --git a/src/lib/libcrypto/conf/conf_def.c b/src/lib/libcrypto/conf/conf_def.c
index d8bce8732a..0b571b0394 100644
--- a/src/lib/libcrypto/conf/conf_def.c
+++ b/src/lib/libcrypto/conf/conf_def.c
@@ -129,7 +129,7 @@ static CONF *def_create(CONF_METHOD *meth)
129 { 129 {
130 CONF *ret; 130 CONF *ret;
131 131
132 ret = (CONF *)OPENSSL_malloc(sizeof(CONF) + sizeof(unsigned short *)); 132 ret = OPENSSL_malloc(sizeof(CONF) + sizeof(unsigned short *));
133 if (ret) 133 if (ret)
134 if (meth->init(ret) == 0) 134 if (meth->init(ret) == 0)
135 { 135 {
@@ -145,7 +145,7 @@ static int def_init_default(CONF *conf)
145 return 0; 145 return 0;
146 146
147 conf->meth = &default_method; 147 conf->meth = &default_method;
148 conf->meth_data = (void *)CONF_type_default; 148 conf->meth_data = CONF_type_default;
149 conf->data = NULL; 149 conf->data = NULL;
150 150
151 return 1; 151 return 1;
@@ -722,7 +722,7 @@ static char *scan_dquote(CONF *conf, char *p)
722 return(p); 722 return(p);
723 } 723 }
724 724
725static void dump_value(CONF_VALUE *a, BIO *out) 725static void dump_value_doall_arg(CONF_VALUE *a, BIO *out)
726 { 726 {
727 if (a->name) 727 if (a->name)
728 BIO_printf(out, "[%s] %s=%s\n", a->section, a->name, a->value); 728 BIO_printf(out, "[%s] %s=%s\n", a->section, a->name, a->value);
@@ -730,11 +730,12 @@ static void dump_value(CONF_VALUE *a, BIO *out)
730 BIO_printf(out, "[[%s]]\n", a->section); 730 BIO_printf(out, "[[%s]]\n", a->section);
731 } 731 }
732 732
733static IMPLEMENT_LHASH_DOALL_ARG_FN(dump_value, CONF_VALUE *, BIO *) 733static IMPLEMENT_LHASH_DOALL_ARG_FN(dump_value, CONF_VALUE, BIO)
734 734
735static int def_dump(const CONF *conf, BIO *out) 735static int def_dump(const CONF *conf, BIO *out)
736 { 736 {
737 lh_doall_arg(conf->data, LHASH_DOALL_ARG_FN(dump_value), out); 737 lh_CONF_VALUE_doall_arg(conf->data, LHASH_DOALL_ARG_FN(dump_value),
738 BIO, out);
738 return 1; 739 return 1;
739 } 740 }
740 741
diff --git a/src/lib/libcrypto/conf/conf_err.c b/src/lib/libcrypto/conf/conf_err.c
index a16a5e0bd4..25bb5dc9aa 100644
--- a/src/lib/libcrypto/conf/conf_err.c
+++ b/src/lib/libcrypto/conf/conf_err.c
@@ -1,6 +1,6 @@
1/* crypto/conf/conf_err.c */ 1/* crypto/conf/conf_err.c */
2/* ==================================================================== 2/* ====================================================================
3 * Copyright (c) 1999-2005 The OpenSSL Project. All rights reserved. 3 * Copyright (c) 1999-2007 The OpenSSL Project. All rights reserved.
4 * 4 *
5 * Redistribution and use in source and binary forms, with or without 5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions 6 * modification, are permitted provided that the following conditions
@@ -75,6 +75,7 @@ static ERR_STRING_DATA CONF_str_functs[]=
75{ERR_FUNC(CONF_F_CONF_LOAD_BIO), "CONF_load_bio"}, 75{ERR_FUNC(CONF_F_CONF_LOAD_BIO), "CONF_load_bio"},
76{ERR_FUNC(CONF_F_CONF_LOAD_FP), "CONF_load_fp"}, 76{ERR_FUNC(CONF_F_CONF_LOAD_FP), "CONF_load_fp"},
77{ERR_FUNC(CONF_F_CONF_MODULES_LOAD), "CONF_modules_load"}, 77{ERR_FUNC(CONF_F_CONF_MODULES_LOAD), "CONF_modules_load"},
78{ERR_FUNC(CONF_F_CONF_PARSE_LIST), "CONF_parse_list"},
78{ERR_FUNC(CONF_F_DEF_LOAD), "DEF_LOAD"}, 79{ERR_FUNC(CONF_F_DEF_LOAD), "DEF_LOAD"},
79{ERR_FUNC(CONF_F_DEF_LOAD_BIO), "DEF_LOAD_BIO"}, 80{ERR_FUNC(CONF_F_DEF_LOAD_BIO), "DEF_LOAD_BIO"},
80{ERR_FUNC(CONF_F_MODULE_INIT), "MODULE_INIT"}, 81{ERR_FUNC(CONF_F_MODULE_INIT), "MODULE_INIT"},
@@ -97,6 +98,7 @@ static ERR_STRING_DATA CONF_str_functs[]=
97static ERR_STRING_DATA CONF_str_reasons[]= 98static ERR_STRING_DATA CONF_str_reasons[]=
98 { 99 {
99{ERR_REASON(CONF_R_ERROR_LOADING_DSO) ,"error loading dso"}, 100{ERR_REASON(CONF_R_ERROR_LOADING_DSO) ,"error loading dso"},
101{ERR_REASON(CONF_R_LIST_CANNOT_BE_NULL) ,"list cannot be null"},
100{ERR_REASON(CONF_R_MISSING_CLOSE_SQUARE_BRACKET),"missing close square bracket"}, 102{ERR_REASON(CONF_R_MISSING_CLOSE_SQUARE_BRACKET),"missing close square bracket"},
101{ERR_REASON(CONF_R_MISSING_EQUAL_SIGN) ,"missing equal sign"}, 103{ERR_REASON(CONF_R_MISSING_EQUAL_SIGN) ,"missing equal sign"},
102{ERR_REASON(CONF_R_MISSING_FINISH_FUNCTION),"missing finish function"}, 104{ERR_REASON(CONF_R_MISSING_FINISH_FUNCTION),"missing finish function"},
diff --git a/src/lib/libcrypto/conf/conf_lib.c b/src/lib/libcrypto/conf/conf_lib.c
index 2a3399d269..54046defca 100644
--- a/src/lib/libcrypto/conf/conf_lib.c
+++ b/src/lib/libcrypto/conf/conf_lib.c
@@ -69,7 +69,7 @@ static CONF_METHOD *default_CONF_method=NULL;
69 69
70/* Init a 'CONF' structure from an old LHASH */ 70/* Init a 'CONF' structure from an old LHASH */
71 71
72void CONF_set_nconf(CONF *conf, LHASH *hash) 72void CONF_set_nconf(CONF *conf, LHASH_OF(CONF_VALUE) *hash)
73 { 73 {
74 if (default_CONF_method == NULL) 74 if (default_CONF_method == NULL)
75 default_CONF_method = NCONF_default(); 75 default_CONF_method = NCONF_default();
@@ -87,9 +87,10 @@ int CONF_set_default_method(CONF_METHOD *meth)
87 return 1; 87 return 1;
88 } 88 }
89 89
90LHASH *CONF_load(LHASH *conf, const char *file, long *eline) 90LHASH_OF(CONF_VALUE) *CONF_load(LHASH_OF(CONF_VALUE) *conf, const char *file,
91 long *eline)
91 { 92 {
92 LHASH *ltmp; 93 LHASH_OF(CONF_VALUE) *ltmp;
93 BIO *in=NULL; 94 BIO *in=NULL;
94 95
95#ifdef OPENSSL_SYS_VMS 96#ifdef OPENSSL_SYS_VMS
@@ -110,10 +111,11 @@ LHASH *CONF_load(LHASH *conf, const char *file, long *eline)
110 } 111 }
111 112
112#ifndef OPENSSL_NO_FP_API 113#ifndef OPENSSL_NO_FP_API
113LHASH *CONF_load_fp(LHASH *conf, FILE *fp,long *eline) 114LHASH_OF(CONF_VALUE) *CONF_load_fp(LHASH_OF(CONF_VALUE) *conf, FILE *fp,
115 long *eline)
114 { 116 {
115 BIO *btmp; 117 BIO *btmp;
116 LHASH *ltmp; 118 LHASH_OF(CONF_VALUE) *ltmp;
117 if(!(btmp = BIO_new_fp(fp, BIO_NOCLOSE))) { 119 if(!(btmp = BIO_new_fp(fp, BIO_NOCLOSE))) {
118 CONFerr(CONF_F_CONF_LOAD_FP,ERR_R_BUF_LIB); 120 CONFerr(CONF_F_CONF_LOAD_FP,ERR_R_BUF_LIB);
119 return NULL; 121 return NULL;
@@ -124,7 +126,8 @@ LHASH *CONF_load_fp(LHASH *conf, FILE *fp,long *eline)
124 } 126 }
125#endif 127#endif
126 128
127LHASH *CONF_load_bio(LHASH *conf, BIO *bp,long *eline) 129LHASH_OF(CONF_VALUE) *CONF_load_bio(LHASH_OF(CONF_VALUE) *conf, BIO *bp,
130 long *eline)
128 { 131 {
129 CONF ctmp; 132 CONF ctmp;
130 int ret; 133 int ret;
@@ -137,7 +140,8 @@ LHASH *CONF_load_bio(LHASH *conf, BIO *bp,long *eline)
137 return NULL; 140 return NULL;
138 } 141 }
139 142
140STACK_OF(CONF_VALUE) *CONF_get_section(LHASH *conf,const char *section) 143STACK_OF(CONF_VALUE) *CONF_get_section(LHASH_OF(CONF_VALUE) *conf,
144 const char *section)
141 { 145 {
142 if (conf == NULL) 146 if (conf == NULL)
143 { 147 {
@@ -151,7 +155,8 @@ STACK_OF(CONF_VALUE) *CONF_get_section(LHASH *conf,const char *section)
151 } 155 }
152 } 156 }
153 157
154char *CONF_get_string(LHASH *conf,const char *group,const char *name) 158char *CONF_get_string(LHASH_OF(CONF_VALUE) *conf,const char *group,
159 const char *name)
155 { 160 {
156 if (conf == NULL) 161 if (conf == NULL)
157 { 162 {
@@ -165,7 +170,8 @@ char *CONF_get_string(LHASH *conf,const char *group,const char *name)
165 } 170 }
166 } 171 }
167 172
168long CONF_get_number(LHASH *conf,const char *group,const char *name) 173long CONF_get_number(LHASH_OF(CONF_VALUE) *conf,const char *group,
174 const char *name)
169 { 175 {
170 int status; 176 int status;
171 long result = 0; 177 long result = 0;
@@ -189,7 +195,7 @@ long CONF_get_number(LHASH *conf,const char *group,const char *name)
189 return result; 195 return result;
190 } 196 }
191 197
192void CONF_free(LHASH *conf) 198void CONF_free(LHASH_OF(CONF_VALUE) *conf)
193 { 199 {
194 CONF ctmp; 200 CONF ctmp;
195 CONF_set_nconf(&ctmp, conf); 201 CONF_set_nconf(&ctmp, conf);
@@ -197,7 +203,7 @@ void CONF_free(LHASH *conf)
197 } 203 }
198 204
199#ifndef OPENSSL_NO_FP_API 205#ifndef OPENSSL_NO_FP_API
200int CONF_dump_fp(LHASH *conf, FILE *out) 206int CONF_dump_fp(LHASH_OF(CONF_VALUE) *conf, FILE *out)
201 { 207 {
202 BIO *btmp; 208 BIO *btmp;
203 int ret; 209 int ret;
@@ -212,7 +218,7 @@ int CONF_dump_fp(LHASH *conf, FILE *out)
212 } 218 }
213#endif 219#endif
214 220
215int CONF_dump_bio(LHASH *conf, BIO *out) 221int CONF_dump_bio(LHASH_OF(CONF_VALUE) *conf, BIO *out)
216 { 222 {
217 CONF ctmp; 223 CONF ctmp;
218 CONF_set_nconf(&ctmp, conf); 224 CONF_set_nconf(&ctmp, conf);
diff --git a/src/lib/libcrypto/conf/conf_mall.c b/src/lib/libcrypto/conf/conf_mall.c
index 1cc1fd5534..c6f4cb2d55 100644
--- a/src/lib/libcrypto/conf/conf_mall.c
+++ b/src/lib/libcrypto/conf/conf_mall.c
@@ -63,7 +63,6 @@
63#include <openssl/dso.h> 63#include <openssl/dso.h>
64#include <openssl/x509.h> 64#include <openssl/x509.h>
65#include <openssl/asn1.h> 65#include <openssl/asn1.h>
66#include <openssl/evp.h>
67#ifndef OPENSSL_NO_ENGINE 66#ifndef OPENSSL_NO_ENGINE
68#include <openssl/engine.h> 67#include <openssl/engine.h>
69#endif 68#endif
@@ -77,6 +76,5 @@ void OPENSSL_load_builtin_modules(void)
77#ifndef OPENSSL_NO_ENGINE 76#ifndef OPENSSL_NO_ENGINE
78 ENGINE_add_conf_module(); 77 ENGINE_add_conf_module();
79#endif 78#endif
80 EVP_add_alg_module();
81 } 79 }
82 80
diff --git a/src/lib/libcrypto/conf/conf_mod.c b/src/lib/libcrypto/conf/conf_mod.c
index ee9c677d9b..df1642a0a5 100644
--- a/src/lib/libcrypto/conf/conf_mod.c
+++ b/src/lib/libcrypto/conf/conf_mod.c
@@ -582,8 +582,14 @@ int CONF_parse_list(const char *list_, int sep, int nospc,
582 { 582 {
583 int ret; 583 int ret;
584 const char *lstart, *tmpend, *p; 584 const char *lstart, *tmpend, *p;
585 lstart = list_;
586 585
586 if(list_ == NULL)
587 {
588 CONFerr(CONF_F_CONF_PARSE_LIST, CONF_R_LIST_CANNOT_BE_NULL);
589 return 0;
590 }
591
592 lstart = list_;
587 for(;;) 593 for(;;)
588 { 594 {
589 if (nospc) 595 if (nospc)
diff --git a/src/lib/libcrypto/cpt_err.c b/src/lib/libcrypto/cpt_err.c
index 9fd41fff8c..139b9284e4 100644
--- a/src/lib/libcrypto/cpt_err.c
+++ b/src/lib/libcrypto/cpt_err.c
@@ -1,6 +1,6 @@
1/* crypto/cpt_err.c */ 1/* crypto/cpt_err.c */
2/* ==================================================================== 2/* ====================================================================
3 * Copyright (c) 1999-2005 The OpenSSL Project. All rights reserved. 3 * Copyright (c) 1999-2006 The OpenSSL Project. All rights reserved.
4 * 4 *
5 * Redistribution and use in source and binary forms, with or without 5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions 6 * modification, are permitted provided that the following conditions
diff --git a/src/lib/libcrypto/cryptlib.c b/src/lib/libcrypto/cryptlib.c
index 8f9e88e403..b4449b86d6 100644
--- a/src/lib/libcrypto/cryptlib.c
+++ b/src/lib/libcrypto/cryptlib.c
@@ -1,6 +1,6 @@
1/* crypto/cryptlib.c */ 1/* crypto/cryptlib.c */
2/* ==================================================================== 2/* ====================================================================
3 * Copyright (c) 1998-2003 The OpenSSL Project. All rights reserved. 3 * Copyright (c) 1998-2006 The OpenSSL Project. All rights reserved.
4 * 4 *
5 * Redistribution and use in source and binary forms, with or without 5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions 6 * modification, are permitted provided that the following conditions
@@ -121,17 +121,279 @@
121static double SSLeay_MSVC5_hack=0.0; /* and for VC1.5 */ 121static double SSLeay_MSVC5_hack=0.0; /* and for VC1.5 */
122#endif 122#endif
123 123
124DECLARE_STACK_OF(CRYPTO_dynlock)
125
126/* real #defines in crypto.h, keep these upto date */
127static const char* const lock_names[CRYPTO_NUM_LOCKS] =
128 {
129 "<<ERROR>>",
130 "err",
131 "ex_data",
132 "x509",
133 "x509_info",
134 "x509_pkey",
135 "x509_crl",
136 "x509_req",
137 "dsa",
138 "rsa",
139 "evp_pkey",
140 "x509_store",
141 "ssl_ctx",
142 "ssl_cert",
143 "ssl_session",
144 "ssl_sess_cert",
145 "ssl",
146 "ssl_method",
147 "rand",
148 "rand2",
149 "debug_malloc",
150 "BIO",
151 "gethostbyname",
152 "getservbyname",
153 "readdir",
154 "RSA_blinding",
155 "dh",
156 "debug_malloc2",
157 "dso",
158 "dynlock",
159 "engine",
160 "ui",
161 "ecdsa",
162 "ec",
163 "ecdh",
164 "bn",
165 "ec_pre_comp",
166 "store",
167 "comp",
168 "fips",
169 "fips2",
170#if CRYPTO_NUM_LOCKS != 41
171# error "Inconsistency between crypto.h and cryptlib.c"
172#endif
173 };
174
175/* This is for applications to allocate new type names in the non-dynamic
176 array of lock names. These are numbered with positive numbers. */
177static STACK_OF(OPENSSL_STRING) *app_locks=NULL;
178
179/* For applications that want a more dynamic way of handling threads, the
180 following stack is used. These are externally numbered with negative
181 numbers. */
182static STACK_OF(CRYPTO_dynlock) *dyn_locks=NULL;
183
184
124static void (MS_FAR *locking_callback)(int mode,int type, 185static void (MS_FAR *locking_callback)(int mode,int type,
125 const char *file,int line)=NULL; 186 const char *file,int line)=0;
126static int (MS_FAR *add_lock_callback)(int *pointer,int amount, 187static int (MS_FAR *add_lock_callback)(int *pointer,int amount,
127 int type,const char *file,int line)=NULL; 188 int type,const char *file,int line)=0;
128static unsigned long (MS_FAR *id_callback)(void)=NULL; 189#ifndef OPENSSL_NO_DEPRECATED
190static unsigned long (MS_FAR *id_callback)(void)=0;
191#endif
192static void (MS_FAR *threadid_callback)(CRYPTO_THREADID *)=0;
193static struct CRYPTO_dynlock_value *(MS_FAR *dynlock_create_callback)
194 (const char *file,int line)=0;
195static void (MS_FAR *dynlock_lock_callback)(int mode,
196 struct CRYPTO_dynlock_value *l, const char *file,int line)=0;
197static void (MS_FAR *dynlock_destroy_callback)(struct CRYPTO_dynlock_value *l,
198 const char *file,int line)=0;
199
200int CRYPTO_get_new_lockid(char *name)
201 {
202 char *str;
203 int i;
204
205#if defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_WIN16)
206 /* A hack to make Visual C++ 5.0 work correctly when linking as
207 * a DLL using /MT. Without this, the application cannot use
208 * any floating point printf's.
209 * It also seems to be needed for Visual C 1.5 (win16) */
210 SSLeay_MSVC5_hack=(double)name[0]*(double)name[1];
211#endif
212
213 if ((app_locks == NULL) && ((app_locks=sk_OPENSSL_STRING_new_null()) == NULL))
214 {
215 CRYPTOerr(CRYPTO_F_CRYPTO_GET_NEW_LOCKID,ERR_R_MALLOC_FAILURE);
216 return(0);
217 }
218 if ((str=BUF_strdup(name)) == NULL)
219 {
220 CRYPTOerr(CRYPTO_F_CRYPTO_GET_NEW_LOCKID,ERR_R_MALLOC_FAILURE);
221 return(0);
222 }
223 i=sk_OPENSSL_STRING_push(app_locks,str);
224 if (!i)
225 OPENSSL_free(str);
226 else
227 i+=CRYPTO_NUM_LOCKS; /* gap of one :-) */
228 return(i);
229 }
129 230
130int CRYPTO_num_locks(void) 231int CRYPTO_num_locks(void)
131 { 232 {
132 return CRYPTO_NUM_LOCKS; 233 return CRYPTO_NUM_LOCKS;
133 } 234 }
134 235
236int CRYPTO_get_new_dynlockid(void)
237 {
238 int i = 0;
239 CRYPTO_dynlock *pointer = NULL;
240
241 if (dynlock_create_callback == NULL)
242 {
243 CRYPTOerr(CRYPTO_F_CRYPTO_GET_NEW_DYNLOCKID,CRYPTO_R_NO_DYNLOCK_CREATE_CALLBACK);
244 return(0);
245 }
246 CRYPTO_w_lock(CRYPTO_LOCK_DYNLOCK);
247 if ((dyn_locks == NULL)
248 && ((dyn_locks=sk_CRYPTO_dynlock_new_null()) == NULL))
249 {
250 CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK);
251 CRYPTOerr(CRYPTO_F_CRYPTO_GET_NEW_DYNLOCKID,ERR_R_MALLOC_FAILURE);
252 return(0);
253 }
254 CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK);
255
256 pointer = (CRYPTO_dynlock *)OPENSSL_malloc(sizeof(CRYPTO_dynlock));
257 if (pointer == NULL)
258 {
259 CRYPTOerr(CRYPTO_F_CRYPTO_GET_NEW_DYNLOCKID,ERR_R_MALLOC_FAILURE);
260 return(0);
261 }
262 pointer->references = 1;
263 pointer->data = dynlock_create_callback(__FILE__,__LINE__);
264 if (pointer->data == NULL)
265 {
266 OPENSSL_free(pointer);
267 CRYPTOerr(CRYPTO_F_CRYPTO_GET_NEW_DYNLOCKID,ERR_R_MALLOC_FAILURE);
268 return(0);
269 }
270
271 CRYPTO_w_lock(CRYPTO_LOCK_DYNLOCK);
272 /* First, try to find an existing empty slot */
273 i=sk_CRYPTO_dynlock_find(dyn_locks,NULL);
274 /* If there was none, push, thereby creating a new one */
275 if (i == -1)
276 /* Since sk_push() returns the number of items on the
277 stack, not the location of the pushed item, we need
278 to transform the returned number into a position,
279 by decreasing it. */
280 i=sk_CRYPTO_dynlock_push(dyn_locks,pointer) - 1;
281 else
282 /* If we found a place with a NULL pointer, put our pointer
283 in it. */
284 (void)sk_CRYPTO_dynlock_set(dyn_locks,i,pointer);
285 CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK);
286
287 if (i == -1)
288 {
289 dynlock_destroy_callback(pointer->data,__FILE__,__LINE__);
290 OPENSSL_free(pointer);
291 }
292 else
293 i += 1; /* to avoid 0 */
294 return -i;
295 }
296
297void CRYPTO_destroy_dynlockid(int i)
298 {
299 CRYPTO_dynlock *pointer = NULL;
300 if (i)
301 i = -i-1;
302 if (dynlock_destroy_callback == NULL)
303 return;
304
305 CRYPTO_w_lock(CRYPTO_LOCK_DYNLOCK);
306
307 if (dyn_locks == NULL || i >= sk_CRYPTO_dynlock_num(dyn_locks))
308 {
309 CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK);
310 return;
311 }
312 pointer = sk_CRYPTO_dynlock_value(dyn_locks, i);
313 if (pointer != NULL)
314 {
315 --pointer->references;
316#ifdef REF_CHECK
317 if (pointer->references < 0)
318 {
319 fprintf(stderr,"CRYPTO_destroy_dynlockid, bad reference count\n");
320 abort();
321 }
322 else
323#endif
324 if (pointer->references <= 0)
325 {
326 (void)sk_CRYPTO_dynlock_set(dyn_locks, i, NULL);
327 }
328 else
329 pointer = NULL;
330 }
331 CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK);
332
333 if (pointer)
334 {
335 dynlock_destroy_callback(pointer->data,__FILE__,__LINE__);
336 OPENSSL_free(pointer);
337 }
338 }
339
340struct CRYPTO_dynlock_value *CRYPTO_get_dynlock_value(int i)
341 {
342 CRYPTO_dynlock *pointer = NULL;
343 if (i)
344 i = -i-1;
345
346 CRYPTO_w_lock(CRYPTO_LOCK_DYNLOCK);
347
348 if (dyn_locks != NULL && i < sk_CRYPTO_dynlock_num(dyn_locks))
349 pointer = sk_CRYPTO_dynlock_value(dyn_locks, i);
350 if (pointer)
351 pointer->references++;
352
353 CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK);
354
355 if (pointer)
356 return pointer->data;
357 return NULL;
358 }
359
360struct CRYPTO_dynlock_value *(*CRYPTO_get_dynlock_create_callback(void))
361 (const char *file,int line)
362 {
363 return(dynlock_create_callback);
364 }
365
366void (*CRYPTO_get_dynlock_lock_callback(void))(int mode,
367 struct CRYPTO_dynlock_value *l, const char *file,int line)
368 {
369 return(dynlock_lock_callback);
370 }
371
372void (*CRYPTO_get_dynlock_destroy_callback(void))
373 (struct CRYPTO_dynlock_value *l, const char *file,int line)
374 {
375 return(dynlock_destroy_callback);
376 }
377
378void CRYPTO_set_dynlock_create_callback(struct CRYPTO_dynlock_value *(*func)
379 (const char *file, int line))
380 {
381 dynlock_create_callback=func;
382 }
383
384void CRYPTO_set_dynlock_lock_callback(void (*func)(int mode,
385 struct CRYPTO_dynlock_value *l, const char *file, int line))
386 {
387 dynlock_lock_callback=func;
388 }
389
390void CRYPTO_set_dynlock_destroy_callback(void (*func)
391 (struct CRYPTO_dynlock_value *l, const char *file, int line))
392 {
393 dynlock_destroy_callback=func;
394 }
395
396
135void (*CRYPTO_get_locking_callback(void))(int mode,int type,const char *file, 397void (*CRYPTO_get_locking_callback(void))(int mode,int type,const char *file,
136 int line) 398 int line)
137 { 399 {
@@ -156,6 +418,108 @@ void CRYPTO_set_add_lock_callback(int (*func)(int *num,int mount,int type,
156 add_lock_callback=func; 418 add_lock_callback=func;
157 } 419 }
158 420
421/* the memset() here and in set_pointer() seem overkill, but for the sake of
422 * CRYPTO_THREADID_cmp() this avoids any platform silliness that might cause two
423 * "equal" THREADID structs to not be memcmp()-identical. */
424void CRYPTO_THREADID_set_numeric(CRYPTO_THREADID *id, unsigned long val)
425 {
426 memset(id, 0, sizeof(*id));
427 id->val = val;
428 }
429
430static const unsigned char hash_coeffs[] = { 3, 5, 7, 11, 13, 17, 19, 23 };
431void CRYPTO_THREADID_set_pointer(CRYPTO_THREADID *id, void *ptr)
432 {
433 unsigned char *dest = (void *)&id->val;
434 unsigned int accum = 0;
435 unsigned char dnum = sizeof(id->val);
436
437 memset(id, 0, sizeof(*id));
438 id->ptr = ptr;
439 if (sizeof(id->val) >= sizeof(id->ptr))
440 {
441 /* 'ptr' can be embedded in 'val' without loss of uniqueness */
442 id->val = (unsigned long)id->ptr;
443 return;
444 }
445 /* hash ptr ==> val. Each byte of 'val' gets the mod-256 total of a
446 * linear function over the bytes in 'ptr', the co-efficients of which
447 * are a sequence of low-primes (hash_coeffs is an 8-element cycle) -
448 * the starting prime for the sequence varies for each byte of 'val'
449 * (unique polynomials unless pointers are >64-bit). For added spice,
450 * the totals accumulate rather than restarting from zero, and the index
451 * of the 'val' byte is added each time (position dependence). If I was
452 * a black-belt, I'd scan big-endian pointers in reverse to give
453 * low-order bits more play, but this isn't crypto and I'd prefer nobody
454 * mistake it as such. Plus I'm lazy. */
455 while (dnum--)
456 {
457 const unsigned char *src = (void *)&id->ptr;
458 unsigned char snum = sizeof(id->ptr);
459 while (snum--)
460 accum += *(src++) * hash_coeffs[(snum + dnum) & 7];
461 accum += dnum;
462 *(dest++) = accum & 255;
463 }
464 }
465
466int CRYPTO_THREADID_set_callback(void (*func)(CRYPTO_THREADID *))
467 {
468 if (threadid_callback)
469 return 0;
470 threadid_callback = func;
471 return 1;
472 }
473
474void (*CRYPTO_THREADID_get_callback(void))(CRYPTO_THREADID *)
475 {
476 return threadid_callback;
477 }
478
479void CRYPTO_THREADID_current(CRYPTO_THREADID *id)
480 {
481 if (threadid_callback)
482 {
483 threadid_callback(id);
484 return;
485 }
486#ifndef OPENSSL_NO_DEPRECATED
487 /* If the deprecated callback was set, fall back to that */
488 if (id_callback)
489 {
490 CRYPTO_THREADID_set_numeric(id, id_callback());
491 return;
492 }
493#endif
494 /* Else pick a backup */
495#ifdef OPENSSL_SYS_WIN16
496 CRYPTO_THREADID_set_numeric(id, (unsigned long)GetCurrentTask());
497#elif defined(OPENSSL_SYS_WIN32)
498 CRYPTO_THREADID_set_numeric(id, (unsigned long)GetCurrentThreadId());
499#elif defined(OPENSSL_SYS_BEOS)
500 CRYPTO_THREADID_set_numeric(id, (unsigned long)find_thread(NULL));
501#else
502 /* For everything else, default to using the address of 'errno' */
503 CRYPTO_THREADID_set_pointer(id, &errno);
504#endif
505 }
506
507int CRYPTO_THREADID_cmp(const CRYPTO_THREADID *a, const CRYPTO_THREADID *b)
508 {
509 return memcmp(a, b, sizeof(*a));
510 }
511
512void CRYPTO_THREADID_cpy(CRYPTO_THREADID *dest, const CRYPTO_THREADID *src)
513 {
514 memcpy(dest, src, sizeof(*src));
515 }
516
517unsigned long CRYPTO_THREADID_hash(const CRYPTO_THREADID *id)
518 {
519 return id->val;
520 }
521
522#ifndef OPENSSL_NO_DEPRECATED
159unsigned long (*CRYPTO_get_id_callback(void))(void) 523unsigned long (*CRYPTO_get_id_callback(void))(void)
160 { 524 {
161 return(id_callback); 525 return(id_callback);
@@ -178,6 +542,8 @@ unsigned long CRYPTO_thread_id(void)
178 ret=(unsigned long)GetCurrentThreadId(); 542 ret=(unsigned long)GetCurrentThreadId();
179#elif defined(GETPID_IS_MEANINGLESS) 543#elif defined(GETPID_IS_MEANINGLESS)
180 ret=1L; 544 ret=1L;
545#elif defined(OPENSSL_SYS_BEOS)
546 ret=(unsigned long)find_thread(NULL);
181#else 547#else
182 ret=(unsigned long)getpid(); 548 ret=(unsigned long)getpid();
183#endif 549#endif
@@ -186,19 +552,13 @@ unsigned long CRYPTO_thread_id(void)
186 ret=id_callback(); 552 ret=id_callback();
187 return(ret); 553 return(ret);
188 } 554 }
189 555#endif
190static void (*do_dynlock_cb)(int mode, int type, const char *file, int line);
191
192void int_CRYPTO_set_do_dynlock_callback(
193 void (*dyn_cb)(int mode, int type, const char *file, int line))
194 {
195 do_dynlock_cb = dyn_cb;
196 }
197 556
198void CRYPTO_lock(int mode, int type, const char *file, int line) 557void CRYPTO_lock(int mode, int type, const char *file, int line)
199 { 558 {
200#ifdef LOCK_DEBUG 559#ifdef LOCK_DEBUG
201 { 560 {
561 CRYPTO_THREADID id;
202 char *rw_text,*operation_text; 562 char *rw_text,*operation_text;
203 563
204 if (mode & CRYPTO_LOCK) 564 if (mode & CRYPTO_LOCK)
@@ -215,15 +575,25 @@ void CRYPTO_lock(int mode, int type, const char *file, int line)
215 else 575 else
216 rw_text="ERROR"; 576 rw_text="ERROR";
217 577
578 CRYPTO_THREADID_current(&id);
218 fprintf(stderr,"lock:%08lx:(%s)%s %-18s %s:%d\n", 579 fprintf(stderr,"lock:%08lx:(%s)%s %-18s %s:%d\n",
219 CRYPTO_thread_id(), rw_text, operation_text, 580 CRYPTO_THREADID_hash(&id), rw_text, operation_text,
220 CRYPTO_get_lock_name(type), file, line); 581 CRYPTO_get_lock_name(type), file, line);
221 } 582 }
222#endif 583#endif
223 if (type < 0) 584 if (type < 0)
224 { 585 {
225 if (do_dynlock_cb) 586 if (dynlock_lock_callback != NULL)
226 do_dynlock_cb(mode, type, file, line); 587 {
588 struct CRYPTO_dynlock_value *pointer
589 = CRYPTO_get_dynlock_value(type);
590
591 OPENSSL_assert(pointer != NULL);
592
593 dynlock_lock_callback(mode, pointer, file, line);
594
595 CRYPTO_destroy_dynlockid(type);
596 }
227 } 597 }
228 else 598 else
229 if (locking_callback != NULL) 599 if (locking_callback != NULL)
@@ -243,11 +613,14 @@ int CRYPTO_add_lock(int *pointer, int amount, int type, const char *file,
243 613
244 ret=add_lock_callback(pointer,amount,type,file,line); 614 ret=add_lock_callback(pointer,amount,type,file,line);
245#ifdef LOCK_DEBUG 615#ifdef LOCK_DEBUG
616 {
617 CRYPTO_THREADID id;
618 CRYPTO_THREADID_current(&id);
246 fprintf(stderr,"ladd:%08lx:%2d+%2d->%2d %-18s %s:%d\n", 619 fprintf(stderr,"ladd:%08lx:%2d+%2d->%2d %-18s %s:%d\n",
247 CRYPTO_thread_id(), 620 CRYPTO_THREADID_hash(&id), before,amount,ret,
248 before,amount,ret,
249 CRYPTO_get_lock_name(type), 621 CRYPTO_get_lock_name(type),
250 file,line); 622 file,line);
623 }
251#endif 624#endif
252 } 625 }
253 else 626 else
@@ -256,11 +629,15 @@ int CRYPTO_add_lock(int *pointer, int amount, int type, const char *file,
256 629
257 ret= *pointer+amount; 630 ret= *pointer+amount;
258#ifdef LOCK_DEBUG 631#ifdef LOCK_DEBUG
632 {
633 CRYPTO_THREADID id;
634 CRYPTO_THREADID_current(&id);
259 fprintf(stderr,"ladd:%08lx:%2d+%2d->%2d %-18s %s:%d\n", 635 fprintf(stderr,"ladd:%08lx:%2d+%2d->%2d %-18s %s:%d\n",
260 CRYPTO_thread_id(), 636 CRYPTO_THREADID_hash(&id),
261 *pointer,amount,ret, 637 *pointer,amount,ret,
262 CRYPTO_get_lock_name(type), 638 CRYPTO_get_lock_name(type),
263 file,line); 639 file,line);
640 }
264#endif 641#endif
265 *pointer=ret; 642 *pointer=ret;
266 CRYPTO_lock(CRYPTO_UNLOCK|CRYPTO_WRITE,type,file,line); 643 CRYPTO_lock(CRYPTO_UNLOCK|CRYPTO_WRITE,type,file,line);
@@ -268,6 +645,18 @@ int CRYPTO_add_lock(int *pointer, int amount, int type, const char *file,
268 return(ret); 645 return(ret);
269 } 646 }
270 647
648const char *CRYPTO_get_lock_name(int type)
649 {
650 if (type < 0)
651 return("dynamic");
652 else if (type < CRYPTO_NUM_LOCKS)
653 return(lock_names[type]);
654 else if (type-CRYPTO_NUM_LOCKS > sk_OPENSSL_STRING_num(app_locks))
655 return("ERROR");
656 else
657 return(sk_OPENSSL_STRING_value(app_locks,type-CRYPTO_NUM_LOCKS));
658 }
659
271#if defined(__i386) || defined(__i386__) || defined(_M_IX86) || \ 660#if defined(__i386) || defined(__i386__) || defined(_M_IX86) || \
272 defined(__INTEL__) || \ 661 defined(__INTEL__) || \
273 defined(__x86_64) || defined(__x86_64__) || defined(_M_AMD64) || defined(_M_X64) 662 defined(__x86_64) || defined(__x86_64__) || defined(_M_AMD64) || defined(_M_X64)
@@ -301,70 +690,16 @@ void OPENSSL_cpuid_setup(void)
301unsigned long *OPENSSL_ia32cap_loc(void) { return NULL; } 690unsigned long *OPENSSL_ia32cap_loc(void) { return NULL; }
302#endif 691#endif
303int OPENSSL_NONPIC_relocated = 0; 692int OPENSSL_NONPIC_relocated = 0;
304#if !defined(OPENSSL_CPUID_SETUP) 693#if !defined(OPENSSL_CPUID_SETUP) && !defined(OPENSSL_CPUID_OBJ)
305void OPENSSL_cpuid_setup(void) {} 694void OPENSSL_cpuid_setup(void) {}
306#endif 695#endif
307 696
308#if (defined(_WIN32) || defined(__CYGWIN__)) && defined(_WINDLL) 697#if (defined(_WIN32) || defined(__CYGWIN__)) && defined(_WINDLL)
309
310#ifdef OPENSSL_FIPS
311
312#include <tlhelp32.h>
313#if defined(__GNUC__) && __GNUC__>=2
314static int DllInit(void) __attribute__((constructor));
315#elif defined(_MSC_VER)
316static int DllInit(void);
317# ifdef _WIN64
318# pragma section(".CRT$XCU",read)
319 __declspec(allocate(".CRT$XCU"))
320# else
321# pragma data_seg(".CRT$XCU")
322# endif
323 static int (*p)(void) = DllInit;
324# pragma data_seg()
325#endif
326
327static int DllInit(void)
328{
329#if defined(_WIN32_WINNT)
330 union { int(*f)(void); BYTE *p; } t = { DllInit };
331 HANDLE hModuleSnap = INVALID_HANDLE_VALUE;
332 IMAGE_DOS_HEADER *dos_header;
333 IMAGE_NT_HEADERS *nt_headers;
334 MODULEENTRY32 me32 = {sizeof(me32)};
335
336 hModuleSnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE,0);
337 if (hModuleSnap != INVALID_HANDLE_VALUE &&
338 Module32First(hModuleSnap,&me32)) do
339 {
340 if (t.p >= me32.modBaseAddr &&
341 t.p < me32.modBaseAddr+me32.modBaseSize)
342 {
343 dos_header=(IMAGE_DOS_HEADER *)me32.modBaseAddr;
344 if (dos_header->e_magic==IMAGE_DOS_SIGNATURE)
345 {
346 nt_headers=(IMAGE_NT_HEADERS *)
347 ((BYTE *)dos_header+dos_header->e_lfanew);
348 if (nt_headers->Signature==IMAGE_NT_SIGNATURE &&
349 me32.modBaseAddr!=(BYTE*)nt_headers->OptionalHeader.ImageBase)
350 OPENSSL_NONPIC_relocated=1;
351 }
352 break;
353 }
354 } while (Module32Next(hModuleSnap,&me32));
355
356 if (hModuleSnap != INVALID_HANDLE_VALUE)
357 CloseHandle(hModuleSnap);
358#endif
359 OPENSSL_cpuid_setup();
360 return 0;
361}
362
363#else
364
365#ifdef __CYGWIN__ 698#ifdef __CYGWIN__
366/* pick DLL_[PROCESS|THREAD]_[ATTACH|DETACH] definitions */ 699/* pick DLL_[PROCESS|THREAD]_[ATTACH|DETACH] definitions */
367#include <windows.h> 700#include <windows.h>
701/* this has side-effect of _WIN32 getting defined, which otherwise
702 * is mutually exclusive with __CYGWIN__... */
368#endif 703#endif
369 704
370/* All we really need to do is remove the 'error' state when a thread 705/* All we really need to do is remove the 'error' state when a thread
@@ -405,16 +740,27 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason,
405 } 740 }
406#endif 741#endif
407 742
408#endif
409
410#if defined(_WIN32) && !defined(__CYGWIN__) 743#if defined(_WIN32) && !defined(__CYGWIN__)
411#include <tchar.h> 744#include <tchar.h>
745#include <signal.h>
412 746
413#if defined(_WIN32_WINNT) && _WIN32_WINNT>=0x0333 747#if defined(_WIN32_WINNT) && _WIN32_WINNT>=0x0333
414int OPENSSL_isservice(void) 748int OPENSSL_isservice(void)
415{ HWINSTA h; 749{ HWINSTA h;
416 DWORD len; 750 DWORD len;
417 WCHAR *name; 751 WCHAR *name;
752 static union { void *p; int (*f)(void); } _OPENSSL_isservice = { NULL };
753
754 if (_OPENSSL_isservice.p == NULL) {
755 HANDLE h = GetModuleHandle(NULL);
756 if (h != NULL)
757 _OPENSSL_isservice.p = GetProcAddress(h,"_OPENSSL_isservice");
758 if (_OPENSSL_isservice.p == NULL)
759 _OPENSSL_isservice.p = (void *)-1;
760 }
761
762 if (_OPENSSL_isservice.p != (void *)-1)
763 return (*_OPENSSL_isservice.f)();
418 764
419 (void)GetDesktopWindow(); /* return value is ignored */ 765 (void)GetDesktopWindow(); /* return value is ignored */
420 766
@@ -513,7 +859,7 @@ void OPENSSL_showfatal (const char *fmta,...)
513 859
514#if defined(_WIN32_WINNT) && _WIN32_WINNT>=0x0333 860#if defined(_WIN32_WINNT) && _WIN32_WINNT>=0x0333
515 /* this -------------v--- guards NT-specific calls */ 861 /* this -------------v--- guards NT-specific calls */
516 if (GetVersion() < 0x80000000 && OPENSSL_isservice()) 862 if (GetVersion() < 0x80000000 && OPENSSL_isservice() > 0)
517 { HANDLE h = RegisterEventSource(0,_T("OPENSSL")); 863 { HANDLE h = RegisterEventSource(0,_T("OPENSSL"));
518 const TCHAR *pmsg=buf; 864 const TCHAR *pmsg=buf;
519 ReportEvent(h,EVENTLOG_ERROR_TYPE,0,0,0,1,0,&pmsg,0); 865 ReportEvent(h,EVENTLOG_ERROR_TYPE,0,0,0,1,0,&pmsg,0);
@@ -539,7 +885,13 @@ void OpenSSLDie(const char *file,int line,const char *assertion)
539 OPENSSL_showfatal( 885 OPENSSL_showfatal(
540 "%s(%d): OpenSSL internal error, assertion failed: %s\n", 886 "%s(%d): OpenSSL internal error, assertion failed: %s\n",
541 file,line,assertion); 887 file,line,assertion);
888#if !defined(_WIN32) || defined(__CYGWIN__)
542 abort(); 889 abort();
890#else
891 /* Win32 abort() customarily shows a dialog, but we just did that... */
892 raise(SIGABRT);
893 _exit(3);
894#endif
543 } 895 }
544 896
545void *OPENSSL_stderr(void) { return stderr; } 897void *OPENSSL_stderr(void) { return stderr; }
diff --git a/src/lib/libcrypto/crypto.h b/src/lib/libcrypto/crypto.h
index 0e4fb0723c..b0360cec51 100644
--- a/src/lib/libcrypto/crypto.h
+++ b/src/lib/libcrypto/crypto.h
@@ -1,6 +1,6 @@
1/* crypto/crypto.h */ 1/* crypto/crypto.h */
2/* ==================================================================== 2/* ====================================================================
3 * Copyright (c) 1998-2003 The OpenSSL Project. All rights reserved. 3 * Copyright (c) 1998-2006 The OpenSSL Project. All rights reserved.
4 * 4 *
5 * Redistribution and use in source and binary forms, with or without 5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions 6 * modification, are permitted provided that the following conditions
@@ -219,13 +219,9 @@ typedef struct openssl_item_st
219#define CRYPTO_LOCK_EC_PRE_COMP 36 219#define CRYPTO_LOCK_EC_PRE_COMP 36
220#define CRYPTO_LOCK_STORE 37 220#define CRYPTO_LOCK_STORE 37
221#define CRYPTO_LOCK_COMP 38 221#define CRYPTO_LOCK_COMP 38
222#ifndef OPENSSL_FIPS
223#define CRYPTO_NUM_LOCKS 39
224#else
225#define CRYPTO_LOCK_FIPS 39 222#define CRYPTO_LOCK_FIPS 39
226#define CRYPTO_LOCK_FIPS2 40 223#define CRYPTO_LOCK_FIPS2 40
227#define CRYPTO_NUM_LOCKS 41 224#define CRYPTO_NUM_LOCKS 41
228#endif
229 225
230#define CRYPTO_LOCK 1 226#define CRYPTO_LOCK 1
231#define CRYPTO_UNLOCK 2 227#define CRYPTO_UNLOCK 2
@@ -288,9 +284,10 @@ typedef struct bio_st BIO_dummy;
288 284
289struct crypto_ex_data_st 285struct crypto_ex_data_st
290 { 286 {
291 STACK *sk; 287 STACK_OF(void) *sk;
292 int dummy; /* gcc is screwing up this data structure :-( */ 288 int dummy; /* gcc is screwing up this data structure :-( */
293 }; 289 };
290DECLARE_STACK_OF(void)
294 291
295/* This stuff is basically class callback functions 292/* This stuff is basically class callback functions
296 * The current classes are SSL_CTX, SSL, SSL_SESSION, and a few more */ 293 * The current classes are SSL_CTX, SSL, SSL_SESSION, and a few more */
@@ -347,7 +344,14 @@ DECLARE_STACK_OF(CRYPTO_EX_DATA_FUNCS)
347 344
348/* Set standard debugging functions (not done by default 345/* Set standard debugging functions (not done by default
349 * unless CRYPTO_MDEBUG is defined) */ 346 * unless CRYPTO_MDEBUG is defined) */
350void CRYPTO_malloc_debug_init(void); 347#define CRYPTO_malloc_debug_init() do {\
348 CRYPTO_set_mem_debug_functions(\
349 CRYPTO_dbg_malloc,\
350 CRYPTO_dbg_realloc,\
351 CRYPTO_dbg_free,\
352 CRYPTO_dbg_set_options,\
353 CRYPTO_dbg_get_options);\
354 } while(0)
351 355
352int CRYPTO_mem_ctrl(int mode); 356int CRYPTO_mem_ctrl(int mode);
353int CRYPTO_is_mem_check_on(void); 357int CRYPTO_is_mem_check_on(void);
@@ -420,16 +424,32 @@ void CRYPTO_set_add_lock_callback(int (*func)(int *num,int mount,int type,
420 const char *file, int line)); 424 const char *file, int line));
421int (*CRYPTO_get_add_lock_callback(void))(int *num,int mount,int type, 425int (*CRYPTO_get_add_lock_callback(void))(int *num,int mount,int type,
422 const char *file,int line); 426 const char *file,int line);
427
428/* Don't use this structure directly. */
429typedef struct crypto_threadid_st
430 {
431 void *ptr;
432 unsigned long val;
433 } CRYPTO_THREADID;
434/* Only use CRYPTO_THREADID_set_[numeric|pointer]() within callbacks */
435void CRYPTO_THREADID_set_numeric(CRYPTO_THREADID *id, unsigned long val);
436void CRYPTO_THREADID_set_pointer(CRYPTO_THREADID *id, void *ptr);
437int CRYPTO_THREADID_set_callback(void (*threadid_func)(CRYPTO_THREADID *));
438void (*CRYPTO_THREADID_get_callback(void))(CRYPTO_THREADID *);
439void CRYPTO_THREADID_current(CRYPTO_THREADID *id);
440int CRYPTO_THREADID_cmp(const CRYPTO_THREADID *a, const CRYPTO_THREADID *b);
441void CRYPTO_THREADID_cpy(CRYPTO_THREADID *dest, const CRYPTO_THREADID *src);
442unsigned long CRYPTO_THREADID_hash(const CRYPTO_THREADID *id);
443#ifndef OPENSSL_NO_DEPRECATED
423void CRYPTO_set_id_callback(unsigned long (*func)(void)); 444void CRYPTO_set_id_callback(unsigned long (*func)(void));
424unsigned long (*CRYPTO_get_id_callback(void))(void); 445unsigned long (*CRYPTO_get_id_callback(void))(void);
425unsigned long CRYPTO_thread_id(void); 446unsigned long CRYPTO_thread_id(void);
447#endif
448
426const char *CRYPTO_get_lock_name(int type); 449const char *CRYPTO_get_lock_name(int type);
427int CRYPTO_add_lock(int *pointer,int amount,int type, const char *file, 450int CRYPTO_add_lock(int *pointer,int amount,int type, const char *file,
428 int line); 451 int line);
429 452
430void int_CRYPTO_set_do_dynlock_callback(
431 void (*do_dynlock_cb)(int mode, int type, const char *file, int line));
432
433int CRYPTO_get_new_dynlockid(void); 453int CRYPTO_get_new_dynlockid(void);
434void CRYPTO_destroy_dynlockid(int i); 454void CRYPTO_destroy_dynlockid(int i);
435struct CRYPTO_dynlock_value *CRYPTO_get_dynlock_value(int i); 455struct CRYPTO_dynlock_value *CRYPTO_get_dynlock_value(int i);
@@ -454,10 +474,6 @@ int CRYPTO_set_mem_debug_functions(void (*m)(void *,int,const char *,int,int),
454 void (*f)(void *,int), 474 void (*f)(void *,int),
455 void (*so)(long), 475 void (*so)(long),
456 long (*go)(void)); 476 long (*go)(void));
457void CRYPTO_set_mem_info_functions(
458 int (*push_info_fn)(const char *info, const char *file, int line),
459 int (*pop_info_fn)(void),
460 int (*remove_all_info_fn)(void));
461void CRYPTO_get_mem_functions(void *(**m)(size_t),void *(**r)(void *, size_t), void (**f)(void *)); 477void CRYPTO_get_mem_functions(void *(**m)(size_t),void *(**r)(void *, size_t), void (**f)(void *));
462void CRYPTO_get_locked_mem_functions(void *(**m)(size_t), void (**f)(void *)); 478void CRYPTO_get_locked_mem_functions(void *(**m)(size_t), void (**f)(void *));
463void CRYPTO_get_mem_ex_functions(void *(**m)(size_t,const char *,int), 479void CRYPTO_get_mem_ex_functions(void *(**m)(size_t,const char *,int),
@@ -514,9 +530,6 @@ void CRYPTO_dbg_free(void *addr,int before_p);
514void CRYPTO_dbg_set_options(long bits); 530void CRYPTO_dbg_set_options(long bits);
515long CRYPTO_dbg_get_options(void); 531long CRYPTO_dbg_get_options(void);
516 532
517int CRYPTO_dbg_push_info(const char *info, const char *file, int line);
518int CRYPTO_dbg_pop_info(void);
519int CRYPTO_dbg_remove_all_info(void);
520 533
521#ifndef OPENSSL_NO_FP_API 534#ifndef OPENSSL_NO_FP_API
522void CRYPTO_mem_leaks_fp(FILE *); 535void CRYPTO_mem_leaks_fp(FILE *);
@@ -534,69 +547,12 @@ unsigned long *OPENSSL_ia32cap_loc(void);
534#define OPENSSL_ia32cap (*(OPENSSL_ia32cap_loc())) 547#define OPENSSL_ia32cap (*(OPENSSL_ia32cap_loc()))
535int OPENSSL_isservice(void); 548int OPENSSL_isservice(void);
536 549
537#ifdef OPENSSL_FIPS
538#define FIPS_ERROR_IGNORED(alg) OpenSSLDie(__FILE__, __LINE__, \
539 alg " previous FIPS forbidden algorithm error ignored");
540
541#define FIPS_BAD_ABORT(alg) OpenSSLDie(__FILE__, __LINE__, \
542 #alg " Algorithm forbidden in FIPS mode");
543
544#ifdef OPENSSL_FIPS_STRICT
545#define FIPS_BAD_ALGORITHM(alg) FIPS_BAD_ABORT(alg)
546#else
547#define FIPS_BAD_ALGORITHM(alg) \
548 { \
549 FIPSerr(FIPS_F_HASH_FINAL,FIPS_R_NON_FIPS_METHOD); \
550 ERR_add_error_data(2, "Algorithm=", #alg); \
551 return 0; \
552 }
553#endif
554
555/* Low level digest API blocking macro */
556
557#define FIPS_NON_FIPS_MD_Init(alg) \
558 int alg##_Init(alg##_CTX *c) \
559 { \
560 if (FIPS_mode()) \
561 FIPS_BAD_ALGORITHM(alg) \
562 return private_##alg##_Init(c); \
563 } \
564 int private_##alg##_Init(alg##_CTX *c)
565
566/* For ciphers the API often varies from cipher to cipher and each needs to
567 * be treated as a special case. Variable key length ciphers (Blowfish, RC4,
568 * CAST) however are very similar and can use a blocking macro.
569 */
570
571#define FIPS_NON_FIPS_VCIPHER_Init(alg) \
572 void alg##_set_key(alg##_KEY *key, int len, const unsigned char *data) \
573 { \
574 if (FIPS_mode()) \
575 FIPS_BAD_ABORT(alg) \
576 private_##alg##_set_key(key, len, data); \
577 } \
578 void private_##alg##_set_key(alg##_KEY *key, int len, \
579 const unsigned char *data)
580
581#else
582
583#define FIPS_NON_FIPS_VCIPHER_Init(alg) \
584 void alg##_set_key(alg##_KEY *key, int len, const unsigned char *data)
585
586#define FIPS_NON_FIPS_MD_Init(alg) \
587 int alg##_Init(alg##_CTX *c)
588
589#endif /* def OPENSSL_FIPS */
590
591/* BEGIN ERROR CODES */ 550/* BEGIN ERROR CODES */
592/* The following lines are auto generated by the script mkerr.pl. Any changes 551/* The following lines are auto generated by the script mkerr.pl. Any changes
593 * made after this point may be overwritten when the script is next run. 552 * made after this point may be overwritten when the script is next run.
594 */ 553 */
595void ERR_load_CRYPTO_strings(void); 554void ERR_load_CRYPTO_strings(void);
596 555
597#define OPENSSL_HAVE_INIT 1
598void OPENSSL_init(void);
599
600/* Error codes for the CRYPTO functions. */ 556/* Error codes for the CRYPTO functions. */
601 557
602/* Function codes. */ 558/* Function codes. */
diff --git a/src/lib/libcrypto/des/asm/crypt586.pl b/src/lib/libcrypto/des/asm/crypt586.pl
index 1d04ed6def..e36f7d44bd 100644
--- a/src/lib/libcrypto/des/asm/crypt586.pl
+++ b/src/lib/libcrypto/des/asm/crypt586.pl
@@ -6,7 +6,8 @@
6# things perfect. 6# things perfect.
7# 7#
8 8
9push(@INC,"perlasm","../../perlasm"); 9$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
10push(@INC,"${dir}","${dir}../../perlasm");
10require "x86asm.pl"; 11require "x86asm.pl";
11 12
12&asm_init($ARGV[0],"crypt586.pl"); 13&asm_init($ARGV[0],"crypt586.pl");
@@ -22,7 +23,7 @@ sub fcrypt_body
22 { 23 {
23 local($name,$do_ip)=@_; 24 local($name,$do_ip)=@_;
24 25
25 &function_begin($name,"EXTRN _DES_SPtrans:DWORD"); 26 &function_begin($name);
26 27
27 &comment(""); 28 &comment("");
28 &comment("Load the 2 words"); 29 &comment("Load the 2 words");
diff --git a/src/lib/libcrypto/des/asm/des-586.pl b/src/lib/libcrypto/des/asm/des-586.pl
index b75d3c6b3a..5b5f39cebd 100644
--- a/src/lib/libcrypto/des/asm/des-586.pl
+++ b/src/lib/libcrypto/des/asm/des-586.pl
@@ -4,7 +4,8 @@
4# Svend Olaf Mikkelsen <svolaf@inet.uni-c.dk> 4# Svend Olaf Mikkelsen <svolaf@inet.uni-c.dk>
5# 5#
6 6
7push(@INC,"perlasm","../../perlasm"); 7$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
8push(@INC,"${dir}","${dir}../../perlasm");
8require "x86asm.pl"; 9require "x86asm.pl";
9require "cbc.pl"; 10require "cbc.pl";
10require "desboth.pl"; 11require "desboth.pl";
@@ -18,29 +19,110 @@ require "desboth.pl";
18 19
19$L="edi"; 20$L="edi";
20$R="esi"; 21$R="esi";
22$trans="ebp";
23$small_footprint=1 if (grep(/\-DOPENSSL_SMALL_FOOTPRINT/,@ARGV));
24# one can discuss setting this variable to 1 unconditionally, as
25# the folded loop is only 3% slower than unrolled, but >7 times smaller
21 26
22&external_label("DES_SPtrans"); 27&public_label("DES_SPtrans");
28
29&DES_encrypt_internal();
30&DES_decrypt_internal();
23&DES_encrypt("DES_encrypt1",1); 31&DES_encrypt("DES_encrypt1",1);
24&DES_encrypt("DES_encrypt2",0); 32&DES_encrypt("DES_encrypt2",0);
25&DES_encrypt3("DES_encrypt3",1); 33&DES_encrypt3("DES_encrypt3",1);
26&DES_encrypt3("DES_decrypt3",0); 34&DES_encrypt3("DES_decrypt3",0);
27&cbc("DES_ncbc_encrypt","DES_encrypt1","DES_encrypt1",0,4,5,3,5,-1); 35&cbc("DES_ncbc_encrypt","DES_encrypt1","DES_encrypt1",0,4,5,3,5,-1);
28&cbc("DES_ede3_cbc_encrypt","DES_encrypt3","DES_decrypt3",0,6,7,3,4,5); 36&cbc("DES_ede3_cbc_encrypt","DES_encrypt3","DES_decrypt3",0,6,7,3,4,5);
37&DES_SPtrans();
29 38
30&asm_finish(); 39&asm_finish();
31 40
41sub DES_encrypt_internal()
42 {
43 &function_begin_B("_x86_DES_encrypt");
44
45 if ($small_footprint)
46 {
47 &lea("edx",&DWP(128,"ecx"));
48 &push("edx");
49 &push("ecx");
50 &set_label("eloop");
51 &D_ENCRYPT(0,$L,$R,0,$trans,"eax","ebx","ecx","edx",&swtmp(0));
52 &comment("");
53 &D_ENCRYPT(1,$R,$L,2,$trans,"eax","ebx","ecx","edx",&swtmp(0));
54 &comment("");
55 &add("ecx",16);
56 &cmp("ecx",&swtmp(1));
57 &mov(&swtmp(0),"ecx");
58 &jb(&label("eloop"));
59 &add("esp",8);
60 }
61 else
62 {
63 &push("ecx");
64 for ($i=0; $i<16; $i+=2)
65 {
66 &comment("Round $i");
67 &D_ENCRYPT($i,$L,$R,$i*2,$trans,"eax","ebx","ecx","edx",&swtmp(0));
68 &comment("Round ".sprintf("%d",$i+1));
69 &D_ENCRYPT($i+1,$R,$L,($i+1)*2,$trans,"eax","ebx","ecx","edx",&swtmp(0));
70 }
71 &add("esp",4);
72 }
73 &ret();
74
75 &function_end_B("_x86_DES_encrypt");
76 }
77
78sub DES_decrypt_internal()
79 {
80 &function_begin_B("_x86_DES_decrypt");
81
82 if ($small_footprint)
83 {
84 &push("ecx");
85 &lea("ecx",&DWP(128,"ecx"));
86 &push("ecx");
87 &set_label("dloop");
88 &D_ENCRYPT(0,$L,$R,-2,$trans,"eax","ebx","ecx","edx",&swtmp(0));
89 &comment("");
90 &D_ENCRYPT(1,$R,$L,-4,$trans,"eax","ebx","ecx","edx",&swtmp(0));
91 &comment("");
92 &sub("ecx",16);
93 &cmp("ecx",&swtmp(1));
94 &mov(&swtmp(0),"ecx");
95 &ja(&label("dloop"));
96 &add("esp",8);
97 }
98 else
99 {
100 &push("ecx");
101 for ($i=15; $i>0; $i-=2)
102 {
103 &comment("Round $i");
104 &D_ENCRYPT(15-$i,$L,$R,$i*2,$trans,"eax","ebx","ecx","edx",&swtmp(0));
105 &comment("Round ".sprintf("%d",$i-1));
106 &D_ENCRYPT(15-$i+1,$R,$L,($i-1)*2,$trans,"eax","ebx","ecx","edx",&swtmp(0));
107 }
108 &add("esp",4);
109 }
110 &ret();
111
112 &function_end_B("_x86_DES_decrypt");
113 }
114
32sub DES_encrypt 115sub DES_encrypt
33 { 116 {
34 local($name,$do_ip)=@_; 117 local($name,$do_ip)=@_;
35 118
36 &function_begin_B($name,"EXTRN _DES_SPtrans:DWORD"); 119 &function_begin_B($name);
37 120
38 &push("esi"); 121 &push("esi");
39 &push("edi"); 122 &push("edi");
40 123
41 &comment(""); 124 &comment("");
42 &comment("Load the 2 words"); 125 &comment("Load the 2 words");
43 $trans="ebp";
44 126
45 if ($do_ip) 127 if ($do_ip)
46 { 128 {
@@ -73,39 +155,20 @@ sub DES_encrypt
73 } 155 }
74 156
75 # PIC-ification:-) 157 # PIC-ification:-)
76 &picmeup($trans,"DES_SPtrans"); 158 &call (&label("pic_point"));
77 #if ($cpp) { &picmeup($trans,"DES_SPtrans"); } 159 &set_label("pic_point");
78 #else { &lea($trans,&DWP("DES_SPtrans")); } 160 &blindpop($trans);
161 &lea ($trans,&DWP(&label("DES_SPtrans")."-".&label("pic_point"),$trans));
79 162
80 &mov( "ecx", &wparam(1) ); 163 &mov( "ecx", &wparam(1) );
81 &cmp("ebx","0");
82 &je(&label("start_decrypt"));
83
84 for ($i=0; $i<16; $i+=2)
85 {
86 &comment("");
87 &comment("Round $i");
88 &D_ENCRYPT($i,$L,$R,$i*2,$trans,"eax","ebx","ecx","edx");
89
90 &comment("");
91 &comment("Round ".sprintf("%d",$i+1));
92 &D_ENCRYPT($i+1,$R,$L,($i+1)*2,$trans,"eax","ebx","ecx","edx");
93 }
94 &jmp(&label("end"));
95 164
96 &set_label("start_decrypt"); 165 &cmp("ebx","0");
97 166 &je(&label("decrypt"));
98 for ($i=15; $i>0; $i-=2) 167 &call("_x86_DES_encrypt");
99 { 168 &jmp(&label("done"));
100 &comment(""); 169 &set_label("decrypt");
101 &comment("Round $i"); 170 &call("_x86_DES_decrypt");
102 &D_ENCRYPT(15-$i,$L,$R,$i*2,$trans,"eax","ebx","ecx","edx"); 171 &set_label("done");
103 &comment("");
104 &comment("Round ".sprintf("%d",$i-1));
105 &D_ENCRYPT(15-$i+1,$R,$L,($i-1)*2,$trans,"eax","ebx","ecx","edx");
106 }
107
108 &set_label("end");
109 172
110 if ($do_ip) 173 if ($do_ip)
111 { 174 {
@@ -139,7 +202,7 @@ sub DES_encrypt
139 202
140sub D_ENCRYPT 203sub D_ENCRYPT
141 { 204 {
142 local($r,$L,$R,$S,$trans,$u,$tmp1,$tmp2,$t)=@_; 205 local($r,$L,$R,$S,$trans,$u,$tmp1,$tmp2,$t,$wp1)=@_;
143 206
144 &mov( $u, &DWP(&n2a($S*4),$tmp2,"",0)); 207 &mov( $u, &DWP(&n2a($S*4),$tmp2,"",0));
145 &xor( $tmp1, $tmp1); 208 &xor( $tmp1, $tmp1);
@@ -166,7 +229,7 @@ sub D_ENCRYPT
166 &and( $t, "0xff" ); 229 &and( $t, "0xff" );
167 &xor( $L, &DWP("0x600",$trans,$tmp1,0)); 230 &xor( $L, &DWP("0x600",$trans,$tmp1,0));
168 &xor( $L, &DWP("0x700",$trans,$tmp2,0)); 231 &xor( $L, &DWP("0x700",$trans,$tmp2,0));
169 &mov( $tmp2, &wparam(1) ); 232 &mov( $tmp2, $wp1 );
170 &xor( $L, &DWP("0x400",$trans,$u,0)); 233 &xor( $L, &DWP("0x400",$trans,$u,0));
171 &xor( $L, &DWP("0x500",$trans,$t,0)); 234 &xor( $L, &DWP("0x500",$trans,$t,0));
172 } 235 }
@@ -249,3 +312,142 @@ sub FP_new
249 &rotr($tt , 4); 312 &rotr($tt , 4);
250 } 313 }
251 314
315sub DES_SPtrans
316 {
317 &set_label("DES_SPtrans",64);
318 &data_word(0x02080800, 0x00080000, 0x02000002, 0x02080802);
319 &data_word(0x02000000, 0x00080802, 0x00080002, 0x02000002);
320 &data_word(0x00080802, 0x02080800, 0x02080000, 0x00000802);
321 &data_word(0x02000802, 0x02000000, 0x00000000, 0x00080002);
322 &data_word(0x00080000, 0x00000002, 0x02000800, 0x00080800);
323 &data_word(0x02080802, 0x02080000, 0x00000802, 0x02000800);
324 &data_word(0x00000002, 0x00000800, 0x00080800, 0x02080002);
325 &data_word(0x00000800, 0x02000802, 0x02080002, 0x00000000);
326 &data_word(0x00000000, 0x02080802, 0x02000800, 0x00080002);
327 &data_word(0x02080800, 0x00080000, 0x00000802, 0x02000800);
328 &data_word(0x02080002, 0x00000800, 0x00080800, 0x02000002);
329 &data_word(0x00080802, 0x00000002, 0x02000002, 0x02080000);
330 &data_word(0x02080802, 0x00080800, 0x02080000, 0x02000802);
331 &data_word(0x02000000, 0x00000802, 0x00080002, 0x00000000);
332 &data_word(0x00080000, 0x02000000, 0x02000802, 0x02080800);
333 &data_word(0x00000002, 0x02080002, 0x00000800, 0x00080802);
334 # nibble 1
335 &data_word(0x40108010, 0x00000000, 0x00108000, 0x40100000);
336 &data_word(0x40000010, 0x00008010, 0x40008000, 0x00108000);
337 &data_word(0x00008000, 0x40100010, 0x00000010, 0x40008000);
338 &data_word(0x00100010, 0x40108000, 0x40100000, 0x00000010);
339 &data_word(0x00100000, 0x40008010, 0x40100010, 0x00008000);
340 &data_word(0x00108010, 0x40000000, 0x00000000, 0x00100010);
341 &data_word(0x40008010, 0x00108010, 0x40108000, 0x40000010);
342 &data_word(0x40000000, 0x00100000, 0x00008010, 0x40108010);
343 &data_word(0x00100010, 0x40108000, 0x40008000, 0x00108010);
344 &data_word(0x40108010, 0x00100010, 0x40000010, 0x00000000);
345 &data_word(0x40000000, 0x00008010, 0x00100000, 0x40100010);
346 &data_word(0x00008000, 0x40000000, 0x00108010, 0x40008010);
347 &data_word(0x40108000, 0x00008000, 0x00000000, 0x40000010);
348 &data_word(0x00000010, 0x40108010, 0x00108000, 0x40100000);
349 &data_word(0x40100010, 0x00100000, 0x00008010, 0x40008000);
350 &data_word(0x40008010, 0x00000010, 0x40100000, 0x00108000);
351 # nibble 2
352 &data_word(0x04000001, 0x04040100, 0x00000100, 0x04000101);
353 &data_word(0x00040001, 0x04000000, 0x04000101, 0x00040100);
354 &data_word(0x04000100, 0x00040000, 0x04040000, 0x00000001);
355 &data_word(0x04040101, 0x00000101, 0x00000001, 0x04040001);
356 &data_word(0x00000000, 0x00040001, 0x04040100, 0x00000100);
357 &data_word(0x00000101, 0x04040101, 0x00040000, 0x04000001);
358 &data_word(0x04040001, 0x04000100, 0x00040101, 0x04040000);
359 &data_word(0x00040100, 0x00000000, 0x04000000, 0x00040101);
360 &data_word(0x04040100, 0x00000100, 0x00000001, 0x00040000);
361 &data_word(0x00000101, 0x00040001, 0x04040000, 0x04000101);
362 &data_word(0x00000000, 0x04040100, 0x00040100, 0x04040001);
363 &data_word(0x00040001, 0x04000000, 0x04040101, 0x00000001);
364 &data_word(0x00040101, 0x04000001, 0x04000000, 0x04040101);
365 &data_word(0x00040000, 0x04000100, 0x04000101, 0x00040100);
366 &data_word(0x04000100, 0x00000000, 0x04040001, 0x00000101);
367 &data_word(0x04000001, 0x00040101, 0x00000100, 0x04040000);
368 # nibble 3
369 &data_word(0x00401008, 0x10001000, 0x00000008, 0x10401008);
370 &data_word(0x00000000, 0x10400000, 0x10001008, 0x00400008);
371 &data_word(0x10401000, 0x10000008, 0x10000000, 0x00001008);
372 &data_word(0x10000008, 0x00401008, 0x00400000, 0x10000000);
373 &data_word(0x10400008, 0x00401000, 0x00001000, 0x00000008);
374 &data_word(0x00401000, 0x10001008, 0x10400000, 0x00001000);
375 &data_word(0x00001008, 0x00000000, 0x00400008, 0x10401000);
376 &data_word(0x10001000, 0x10400008, 0x10401008, 0x00400000);
377 &data_word(0x10400008, 0x00001008, 0x00400000, 0x10000008);
378 &data_word(0x00401000, 0x10001000, 0x00000008, 0x10400000);
379 &data_word(0x10001008, 0x00000000, 0x00001000, 0x00400008);
380 &data_word(0x00000000, 0x10400008, 0x10401000, 0x00001000);
381 &data_word(0x10000000, 0x10401008, 0x00401008, 0x00400000);
382 &data_word(0x10401008, 0x00000008, 0x10001000, 0x00401008);
383 &data_word(0x00400008, 0x00401000, 0x10400000, 0x10001008);
384 &data_word(0x00001008, 0x10000000, 0x10000008, 0x10401000);
385 # nibble 4
386 &data_word(0x08000000, 0x00010000, 0x00000400, 0x08010420);
387 &data_word(0x08010020, 0x08000400, 0x00010420, 0x08010000);
388 &data_word(0x00010000, 0x00000020, 0x08000020, 0x00010400);
389 &data_word(0x08000420, 0x08010020, 0x08010400, 0x00000000);
390 &data_word(0x00010400, 0x08000000, 0x00010020, 0x00000420);
391 &data_word(0x08000400, 0x00010420, 0x00000000, 0x08000020);
392 &data_word(0x00000020, 0x08000420, 0x08010420, 0x00010020);
393 &data_word(0x08010000, 0x00000400, 0x00000420, 0x08010400);
394 &data_word(0x08010400, 0x08000420, 0x00010020, 0x08010000);
395 &data_word(0x00010000, 0x00000020, 0x08000020, 0x08000400);
396 &data_word(0x08000000, 0x00010400, 0x08010420, 0x00000000);
397 &data_word(0x00010420, 0x08000000, 0x00000400, 0x00010020);
398 &data_word(0x08000420, 0x00000400, 0x00000000, 0x08010420);
399 &data_word(0x08010020, 0x08010400, 0x00000420, 0x00010000);
400 &data_word(0x00010400, 0x08010020, 0x08000400, 0x00000420);
401 &data_word(0x00000020, 0x00010420, 0x08010000, 0x08000020);
402 # nibble 5
403 &data_word(0x80000040, 0x00200040, 0x00000000, 0x80202000);
404 &data_word(0x00200040, 0x00002000, 0x80002040, 0x00200000);
405 &data_word(0x00002040, 0x80202040, 0x00202000, 0x80000000);
406 &data_word(0x80002000, 0x80000040, 0x80200000, 0x00202040);
407 &data_word(0x00200000, 0x80002040, 0x80200040, 0x00000000);
408 &data_word(0x00002000, 0x00000040, 0x80202000, 0x80200040);
409 &data_word(0x80202040, 0x80200000, 0x80000000, 0x00002040);
410 &data_word(0x00000040, 0x00202000, 0x00202040, 0x80002000);
411 &data_word(0x00002040, 0x80000000, 0x80002000, 0x00202040);
412 &data_word(0x80202000, 0x00200040, 0x00000000, 0x80002000);
413 &data_word(0x80000000, 0x00002000, 0x80200040, 0x00200000);
414 &data_word(0x00200040, 0x80202040, 0x00202000, 0x00000040);
415 &data_word(0x80202040, 0x00202000, 0x00200000, 0x80002040);
416 &data_word(0x80000040, 0x80200000, 0x00202040, 0x00000000);
417 &data_word(0x00002000, 0x80000040, 0x80002040, 0x80202000);
418 &data_word(0x80200000, 0x00002040, 0x00000040, 0x80200040);
419 # nibble 6
420 &data_word(0x00004000, 0x00000200, 0x01000200, 0x01000004);
421 &data_word(0x01004204, 0x00004004, 0x00004200, 0x00000000);
422 &data_word(0x01000000, 0x01000204, 0x00000204, 0x01004000);
423 &data_word(0x00000004, 0x01004200, 0x01004000, 0x00000204);
424 &data_word(0x01000204, 0x00004000, 0x00004004, 0x01004204);
425 &data_word(0x00000000, 0x01000200, 0x01000004, 0x00004200);
426 &data_word(0x01004004, 0x00004204, 0x01004200, 0x00000004);
427 &data_word(0x00004204, 0x01004004, 0x00000200, 0x01000000);
428 &data_word(0x00004204, 0x01004000, 0x01004004, 0x00000204);
429 &data_word(0x00004000, 0x00000200, 0x01000000, 0x01004004);
430 &data_word(0x01000204, 0x00004204, 0x00004200, 0x00000000);
431 &data_word(0x00000200, 0x01000004, 0x00000004, 0x01000200);
432 &data_word(0x00000000, 0x01000204, 0x01000200, 0x00004200);
433 &data_word(0x00000204, 0x00004000, 0x01004204, 0x01000000);
434 &data_word(0x01004200, 0x00000004, 0x00004004, 0x01004204);
435 &data_word(0x01000004, 0x01004200, 0x01004000, 0x00004004);
436 # nibble 7
437 &data_word(0x20800080, 0x20820000, 0x00020080, 0x00000000);
438 &data_word(0x20020000, 0x00800080, 0x20800000, 0x20820080);
439 &data_word(0x00000080, 0x20000000, 0x00820000, 0x00020080);
440 &data_word(0x00820080, 0x20020080, 0x20000080, 0x20800000);
441 &data_word(0x00020000, 0x00820080, 0x00800080, 0x20020000);
442 &data_word(0x20820080, 0x20000080, 0x00000000, 0x00820000);
443 &data_word(0x20000000, 0x00800000, 0x20020080, 0x20800080);
444 &data_word(0x00800000, 0x00020000, 0x20820000, 0x00000080);
445 &data_word(0x00800000, 0x00020000, 0x20000080, 0x20820080);
446 &data_word(0x00020080, 0x20000000, 0x00000000, 0x00820000);
447 &data_word(0x20800080, 0x20020080, 0x20020000, 0x00800080);
448 &data_word(0x20820000, 0x00000080, 0x00800080, 0x20020000);
449 &data_word(0x20820080, 0x00800000, 0x20800000, 0x20000080);
450 &data_word(0x00820000, 0x00020080, 0x20020080, 0x20800000);
451 &data_word(0x00000080, 0x20820000, 0x00820080, 0x00000000);
452 &data_word(0x20000000, 0x20800080, 0x00020000, 0x00820080);
453 }
diff --git a/src/lib/libcrypto/des/asm/des_enc.m4 b/src/lib/libcrypto/des/asm/des_enc.m4
index f59333a030..3280595478 100644
--- a/src/lib/libcrypto/des/asm/des_enc.m4
+++ b/src/lib/libcrypto/des/asm/des_enc.m4
@@ -1954,9 +1954,11 @@ DES_ede3_cbc_encrypt:
1954 .word LOOPS ! 280 1954 .word LOOPS ! 280
1955 .word 0x0000FC00 ! 284 1955 .word 0x0000FC00 ! 284
1956 1956
1957 .type .PIC.DES_SPtrans,#object 1957 .global DES_SPtrans
1958 .size .PIC.DES_SPtrans,2048 1958 .type DES_SPtrans,#object
1959 .size DES_SPtrans,2048
1959.align 64 1960.align 64
1961DES_SPtrans:
1960.PIC.DES_SPtrans: 1962.PIC.DES_SPtrans:
1961 ! nibble 0 1963 ! nibble 0
1962 .word 0x02080800, 0x00080000, 0x02000002, 0x02080802 1964 .word 0x02080800, 0x00080000, 0x02000002, 0x02080802
diff --git a/src/lib/libcrypto/des/des_enc.c b/src/lib/libcrypto/des/des_enc.c
index cf71965aca..828feba208 100644
--- a/src/lib/libcrypto/des/des_enc.c
+++ b/src/lib/libcrypto/des/des_enc.c
@@ -57,6 +57,7 @@
57 */ 57 */
58 58
59#include "des_locl.h" 59#include "des_locl.h"
60#include "spr.h"
60 61
61void DES_encrypt1(DES_LONG *data, DES_key_schedule *ks, int enc) 62void DES_encrypt1(DES_LONG *data, DES_key_schedule *ks, int enc)
62 { 63 {
@@ -107,12 +108,10 @@ void DES_encrypt1(DES_LONG *data, DES_key_schedule *ks, int enc)
107 D_ENCRYPT(l,r,28); /* 15 */ 108 D_ENCRYPT(l,r,28); /* 15 */
108 D_ENCRYPT(r,l,30); /* 16 */ 109 D_ENCRYPT(r,l,30); /* 16 */
109#else 110#else
110 for (i=0; i<32; i+=8) 111 for (i=0; i<32; i+=4)
111 { 112 {
112 D_ENCRYPT(l,r,i+0); /* 1 */ 113 D_ENCRYPT(l,r,i+0); /* 1 */
113 D_ENCRYPT(r,l,i+2); /* 2 */ 114 D_ENCRYPT(r,l,i+2); /* 2 */
114 D_ENCRYPT(l,r,i+4); /* 3 */
115 D_ENCRYPT(r,l,i+6); /* 4 */
116 } 115 }
117#endif 116#endif
118 } 117 }
@@ -136,12 +135,10 @@ void DES_encrypt1(DES_LONG *data, DES_key_schedule *ks, int enc)
136 D_ENCRYPT(l,r, 2); /* 2 */ 135 D_ENCRYPT(l,r, 2); /* 2 */
137 D_ENCRYPT(r,l, 0); /* 1 */ 136 D_ENCRYPT(r,l, 0); /* 1 */
138#else 137#else
139 for (i=30; i>0; i-=8) 138 for (i=30; i>0; i-=4)
140 { 139 {
141 D_ENCRYPT(l,r,i-0); /* 16 */ 140 D_ENCRYPT(l,r,i-0); /* 16 */
142 D_ENCRYPT(r,l,i-2); /* 15 */ 141 D_ENCRYPT(r,l,i-2); /* 15 */
143 D_ENCRYPT(l,r,i-4); /* 14 */
144 D_ENCRYPT(r,l,i-6); /* 13 */
145 } 142 }
146#endif 143#endif
147 } 144 }
@@ -203,12 +200,10 @@ void DES_encrypt2(DES_LONG *data, DES_key_schedule *ks, int enc)
203 D_ENCRYPT(l,r,28); /* 15 */ 200 D_ENCRYPT(l,r,28); /* 15 */
204 D_ENCRYPT(r,l,30); /* 16 */ 201 D_ENCRYPT(r,l,30); /* 16 */
205#else 202#else
206 for (i=0; i<32; i+=8) 203 for (i=0; i<32; i+=4)
207 { 204 {
208 D_ENCRYPT(l,r,i+0); /* 1 */ 205 D_ENCRYPT(l,r,i+0); /* 1 */
209 D_ENCRYPT(r,l,i+2); /* 2 */ 206 D_ENCRYPT(r,l,i+2); /* 2 */
210 D_ENCRYPT(l,r,i+4); /* 3 */
211 D_ENCRYPT(r,l,i+6); /* 4 */
212 } 207 }
213#endif 208#endif
214 } 209 }
@@ -232,12 +227,10 @@ void DES_encrypt2(DES_LONG *data, DES_key_schedule *ks, int enc)
232 D_ENCRYPT(l,r, 2); /* 2 */ 227 D_ENCRYPT(l,r, 2); /* 2 */
233 D_ENCRYPT(r,l, 0); /* 1 */ 228 D_ENCRYPT(r,l, 0); /* 1 */
234#else 229#else
235 for (i=30; i>0; i-=8) 230 for (i=30; i>0; i-=4)
236 { 231 {
237 D_ENCRYPT(l,r,i-0); /* 16 */ 232 D_ENCRYPT(l,r,i-0); /* 16 */
238 D_ENCRYPT(r,l,i-2); /* 15 */ 233 D_ENCRYPT(r,l,i-2); /* 15 */
239 D_ENCRYPT(l,r,i-4); /* 14 */
240 D_ENCRYPT(r,l,i-6); /* 13 */
241 } 234 }
242#endif 235#endif
243 } 236 }
@@ -289,8 +282,6 @@ void DES_decrypt3(DES_LONG *data, DES_key_schedule *ks1,
289 282
290#ifndef DES_DEFAULT_OPTIONS 283#ifndef DES_DEFAULT_OPTIONS
291 284
292#if !defined(OPENSSL_FIPS_DES_ASM)
293
294#undef CBC_ENC_C__DONT_UPDATE_IV 285#undef CBC_ENC_C__DONT_UPDATE_IV
295#include "ncbc_enc.c" /* DES_ncbc_encrypt */ 286#include "ncbc_enc.c" /* DES_ncbc_encrypt */
296 287
@@ -406,6 +397,4 @@ void DES_ede3_cbc_encrypt(const unsigned char *input, unsigned char *output,
406 tin[0]=tin[1]=0; 397 tin[0]=tin[1]=0;
407 } 398 }
408 399
409#endif
410
411#endif /* DES_DEFAULT_OPTIONS */ 400#endif /* DES_DEFAULT_OPTIONS */
diff --git a/src/lib/libcrypto/des/des_locl.h b/src/lib/libcrypto/des/des_locl.h
index 4b9ecff233..a3b512e9b0 100644
--- a/src/lib/libcrypto/des/des_locl.h
+++ b/src/lib/libcrypto/des/des_locl.h
@@ -61,7 +61,7 @@
61 61
62#include <openssl/e_os2.h> 62#include <openssl/e_os2.h>
63 63
64#if defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_WIN16) 64#if defined(OPENSSL_SYS_WIN32)
65#ifndef OPENSSL_SYS_MSDOS 65#ifndef OPENSSL_SYS_MSDOS
66#define OPENSSL_SYS_MSDOS 66#define OPENSSL_SYS_MSDOS
67#endif 67#endif
@@ -425,4 +425,8 @@ extern const DES_LONG DES_SPtrans[8][64];
425 425
426void fcrypt_body(DES_LONG *out,DES_key_schedule *ks, 426void fcrypt_body(DES_LONG *out,DES_key_schedule *ks,
427 DES_LONG Eswap0, DES_LONG Eswap1); 427 DES_LONG Eswap0, DES_LONG Eswap1);
428
429#ifdef OPENSSL_SMALL_FOOTPRINT
430#undef DES_UNROLL
431#endif
428#endif 432#endif
diff --git a/src/lib/libcrypto/des/ecb_enc.c b/src/lib/libcrypto/des/ecb_enc.c
index 75ae6cf8bb..0684e769b3 100644
--- a/src/lib/libcrypto/des/ecb_enc.c
+++ b/src/lib/libcrypto/des/ecb_enc.c
@@ -57,7 +57,53 @@
57 */ 57 */
58 58
59#include "des_locl.h" 59#include "des_locl.h"
60#include "spr.h" 60#include "des_ver.h"
61#include <openssl/opensslv.h>
62#include <openssl/bio.h>
63
64OPENSSL_GLOBAL const char libdes_version[]="libdes" OPENSSL_VERSION_PTEXT;
65OPENSSL_GLOBAL const char DES_version[]="DES" OPENSSL_VERSION_PTEXT;
66
67const char *DES_options(void)
68 {
69 static int init=1;
70 static char buf[32];
71
72 if (init)
73 {
74 const char *ptr,*unroll,*risc,*size;
75
76#ifdef DES_PTR
77 ptr="ptr";
78#else
79 ptr="idx";
80#endif
81#if defined(DES_RISC1) || defined(DES_RISC2)
82#ifdef DES_RISC1
83 risc="risc1";
84#endif
85#ifdef DES_RISC2
86 risc="risc2";
87#endif
88#else
89 risc="cisc";
90#endif
91#ifdef DES_UNROLL
92 unroll="16";
93#else
94 unroll="2";
95#endif
96 if (sizeof(DES_LONG) != sizeof(long))
97 size="int";
98 else
99 size="long";
100 BIO_snprintf(buf,sizeof buf,"des(%s,%s,%s,%s)",ptr,risc,unroll,
101 size);
102 init=0;
103 }
104 return(buf);
105 }
106
61 107
62void DES_ecb_encrypt(const_DES_cblock *input, DES_cblock *output, 108void DES_ecb_encrypt(const_DES_cblock *input, DES_cblock *output,
63 DES_key_schedule *ks, int enc) 109 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 e7da2ec66b..edb6620d08 100644
--- a/src/lib/libcrypto/des/enc_read.c
+++ b/src/lib/libcrypto/des/enc_read.c
@@ -63,7 +63,7 @@
63 63
64/* This has some uglies in it but it works - even over sockets. */ 64/* This has some uglies in it but it works - even over sockets. */
65/*extern int errno;*/ 65/*extern int errno;*/
66OPENSSL_IMPLEMENT_GLOBAL(int,DES_rw_mode)=DES_PCBC_MODE; 66OPENSSL_IMPLEMENT_GLOBAL(int,DES_rw_mode,DES_PCBC_MODE)
67 67
68 68
69/* 69/*
@@ -87,6 +87,9 @@ OPENSSL_IMPLEMENT_GLOBAL(int,DES_rw_mode)=DES_PCBC_MODE;
87int DES_enc_read(int fd, void *buf, int len, DES_key_schedule *sched, 87int DES_enc_read(int fd, void *buf, int len, DES_key_schedule *sched,
88 DES_cblock *iv) 88 DES_cblock *iv)
89 { 89 {
90#if defined(OPENSSL_NO_POSIX_IO)
91 return(0);
92#else
90 /* data to be unencrypted */ 93 /* data to be unencrypted */
91 int net_num=0; 94 int net_num=0;
92 static unsigned char *net=NULL; 95 static unsigned char *net=NULL;
@@ -147,7 +150,7 @@ int DES_enc_read(int fd, void *buf, int len, DES_key_schedule *sched,
147 /* first - get the length */ 150 /* first - get the length */
148 while (net_num < HDRSIZE) 151 while (net_num < HDRSIZE)
149 { 152 {
150#ifndef _WIN32 153#ifndef OPENSSL_SYS_WIN32
151 i=read(fd,(void *)&(net[net_num]),HDRSIZE-net_num); 154 i=read(fd,(void *)&(net[net_num]),HDRSIZE-net_num);
152#else 155#else
153 i=_read(fd,(void *)&(net[net_num]),HDRSIZE-net_num); 156 i=_read(fd,(void *)&(net[net_num]),HDRSIZE-net_num);
@@ -173,7 +176,11 @@ int DES_enc_read(int fd, void *buf, int len, DES_key_schedule *sched,
173 net_num=0; 176 net_num=0;
174 while (net_num < rnum) 177 while (net_num < rnum)
175 { 178 {
179#ifndef OPENSSL_SYS_WIN32
176 i=read(fd,(void *)&(net[net_num]),rnum-net_num); 180 i=read(fd,(void *)&(net[net_num]),rnum-net_num);
181#else
182 i=_read(fd,(void *)&(net[net_num]),rnum-net_num);
183#endif
177#ifdef EINTR 184#ifdef EINTR
178 if ((i == -1) && (errno == EINTR)) continue; 185 if ((i == -1) && (errno == EINTR)) continue;
179#endif 186#endif
@@ -228,5 +235,6 @@ int DES_enc_read(int fd, void *buf, int len, DES_key_schedule *sched,
228 } 235 }
229 } 236 }
230 return num; 237 return num;
238#endif /* OPENSSL_NO_POSIX_IO */
231 } 239 }
232 240
diff --git a/src/lib/libcrypto/des/enc_writ.c b/src/lib/libcrypto/des/enc_writ.c
index c2f032c9a6..2353ac1e89 100644
--- a/src/lib/libcrypto/des/enc_writ.c
+++ b/src/lib/libcrypto/des/enc_writ.c
@@ -80,6 +80,9 @@
80int DES_enc_write(int fd, const void *_buf, int len, 80int DES_enc_write(int fd, const void *_buf, int len,
81 DES_key_schedule *sched, DES_cblock *iv) 81 DES_key_schedule *sched, DES_cblock *iv)
82 { 82 {
83#if defined(OPENSSL_NO_POSIX_IO)
84 return (-1);
85#else
83#ifdef _LIBC 86#ifdef _LIBC
84 extern unsigned long time(); 87 extern unsigned long time();
85 extern int write(); 88 extern int write();
@@ -172,4 +175,5 @@ int DES_enc_write(int fd, const void *_buf, int len,
172 } 175 }
173 176
174 return(len); 177 return(len);
178#endif /* OPENSSL_NO_POSIX_IO */
175 } 179 }
diff --git a/src/lib/libcrypto/des/fcrypt_b.c b/src/lib/libcrypto/des/fcrypt_b.c
index 1390138787..8822816938 100644
--- a/src/lib/libcrypto/des/fcrypt_b.c
+++ b/src/lib/libcrypto/des/fcrypt_b.c
@@ -100,12 +100,10 @@ void fcrypt_body(DES_LONG *out, DES_key_schedule *ks, DES_LONG Eswap0,
100#ifndef DES_UNROLL 100#ifndef DES_UNROLL
101 register int i; 101 register int i;
102 102
103 for (i=0; i<32; i+=8) 103 for (i=0; i<32; i+=4)
104 { 104 {
105 D_ENCRYPT(l,r,i+0); /* 1 */ 105 D_ENCRYPT(l,r,i+0); /* 1 */
106 D_ENCRYPT(r,l,i+2); /* 2 */ 106 D_ENCRYPT(r,l,i+2); /* 2 */
107 D_ENCRYPT(l,r,i+4); /* 1 */
108 D_ENCRYPT(r,l,i+6); /* 2 */
109 } 107 }
110#else 108#else
111 D_ENCRYPT(l,r, 0); /* 1 */ 109 D_ENCRYPT(l,r, 0); /* 1 */
diff --git a/src/lib/libcrypto/des/set_key.c b/src/lib/libcrypto/des/set_key.c
index c0806d593c..3004cc3ab3 100644
--- a/src/lib/libcrypto/des/set_key.c
+++ b/src/lib/libcrypto/des/set_key.c
@@ -64,12 +64,8 @@
64 * 1.0 First working version 64 * 1.0 First working version
65 */ 65 */
66#include "des_locl.h" 66#include "des_locl.h"
67#ifdef OPENSSL_FIPS
68#include <openssl/fips.h>
69#endif
70
71 67
72OPENSSL_IMPLEMENT_GLOBAL(int,DES_check_key); /* defaults to false */ 68OPENSSL_IMPLEMENT_GLOBAL(int,DES_check_key,0) /* defaults to false */
73 69
74static const unsigned char odd_parity[256]={ 70static const unsigned char odd_parity[256]={
75 1, 1, 2, 2, 4, 4, 7, 7, 8, 8, 11, 11, 13, 13, 14, 14, 71 1, 1, 2, 2, 4, 4, 7, 7, 8, 8, 11, 11, 13, 13, 14, 14,
@@ -340,7 +336,7 @@ int DES_set_key_checked(const_DES_cblock *key, DES_key_schedule *schedule)
340 336
341void DES_set_key_unchecked(const_DES_cblock *key, DES_key_schedule *schedule) 337void DES_set_key_unchecked(const_DES_cblock *key, DES_key_schedule *schedule)
342 { 338 {
343 static int shifts2[16]={0,0,1,1,1,1,1,1,0,1,1,1,1,1,1,0}; 339 static const int shifts2[16]={0,0,1,1,1,1,1,1,0,1,1,1,1,1,1,0};
344 register DES_LONG c,d,t,s,t2; 340 register DES_LONG c,d,t,s,t2;
345 register const unsigned char *in; 341 register const unsigned char *in;
346 register DES_LONG *k; 342 register DES_LONG *k;
@@ -353,10 +349,6 @@ void DES_set_key_unchecked(const_DES_cblock *key, DES_key_schedule *schedule)
353 k = &schedule->ks->deslong[0]; 349 k = &schedule->ks->deslong[0];
354 in = &(*key)[0]; 350 in = &(*key)[0];
355 351
356#ifdef OPENSSL_FIPS
357 FIPS_selftest_check();
358#endif
359
360 c2l(in,c); 352 c2l(in,c);
361 c2l(in,d); 353 c2l(in,d);
362 354
@@ -413,4 +405,3 @@ void des_fixup_key_parity(des_cblock *key)
413 des_set_odd_parity(key); 405 des_set_odd_parity(key);
414 } 406 }
415*/ 407*/
416
diff --git a/src/lib/libcrypto/des/xcbc_enc.c b/src/lib/libcrypto/des/xcbc_enc.c
index dc0c761b71..058cab6bce 100644
--- a/src/lib/libcrypto/des/xcbc_enc.c
+++ b/src/lib/libcrypto/des/xcbc_enc.c
@@ -61,7 +61,7 @@
61/* RSA's DESX */ 61/* RSA's DESX */
62 62
63#if 0 /* broken code, preserved just in case anyone specifically looks for this */ 63#if 0 /* broken code, preserved just in case anyone specifically looks for this */
64static unsigned char desx_white_in2out[256]={ 64static const unsigned char desx_white_in2out[256]={
650xBD,0x56,0xEA,0xF2,0xA2,0xF1,0xAC,0x2A,0xB0,0x93,0xD1,0x9C,0x1B,0x33,0xFD,0xD0, 650xBD,0x56,0xEA,0xF2,0xA2,0xF1,0xAC,0x2A,0xB0,0x93,0xD1,0x9C,0x1B,0x33,0xFD,0xD0,
660x30,0x04,0xB6,0xDC,0x7D,0xDF,0x32,0x4B,0xF7,0xCB,0x45,0x9B,0x31,0xBB,0x21,0x5A, 660x30,0x04,0xB6,0xDC,0x7D,0xDF,0x32,0x4B,0xF7,0xCB,0x45,0x9B,0x31,0xBB,0x21,0x5A,
670x41,0x9F,0xE1,0xD9,0x4A,0x4D,0x9E,0xDA,0xA0,0x68,0x2C,0xC3,0x27,0x5F,0x80,0x36, 670x41,0x9F,0xE1,0xD9,0x4A,0x4D,0x9E,0xDA,0xA0,0x68,0x2C,0xC3,0x27,0x5F,0x80,0x36,
diff --git a/src/lib/libcrypto/dh/dh.h b/src/lib/libcrypto/dh/dh.h
index 10475ac4b3..849309a489 100644
--- a/src/lib/libcrypto/dh/dh.h
+++ b/src/lib/libcrypto/dh/dh.h
@@ -77,8 +77,6 @@
77# define OPENSSL_DH_MAX_MODULUS_BITS 10000 77# define OPENSSL_DH_MAX_MODULUS_BITS 10000
78#endif 78#endif
79 79
80#define OPENSSL_DH_FIPS_MIN_MODULUS_BITS 1024
81
82#define DH_FLAG_CACHE_MONT_P 0x01 80#define DH_FLAG_CACHE_MONT_P 0x01
83#define DH_FLAG_NO_EXP_CONSTTIME 0x02 /* new with 0.9.7h; the built-in DH 81#define DH_FLAG_NO_EXP_CONSTTIME 0x02 /* new with 0.9.7h; the built-in DH
84 * implementation now uses constant time 82 * implementation now uses constant time
@@ -159,7 +157,6 @@ struct dh_st
159 this for backward compatibility: */ 157 this for backward compatibility: */
160#define DH_CHECK_P_NOT_STRONG_PRIME DH_CHECK_P_NOT_SAFE_PRIME 158#define DH_CHECK_P_NOT_STRONG_PRIME DH_CHECK_P_NOT_SAFE_PRIME
161 159
162#define DHparams_dup(x) ASN1_dup_of_const(DH,i2d_DHparams,d2i_DHparams,x)
163#define d2i_DHparams_fp(fp,x) (DH *)ASN1_d2i_fp((char *(*)())DH_new, \ 160#define d2i_DHparams_fp(fp,x) (DH *)ASN1_d2i_fp((char *(*)())DH_new, \
164 (char *(*)())d2i_DHparams,(fp),(unsigned char **)(x)) 161 (char *(*)())d2i_DHparams,(fp),(unsigned char **)(x))
165#define i2d_DHparams_fp(fp,x) ASN1_i2d_fp(i2d_DHparams,(fp), \ 162#define i2d_DHparams_fp(fp,x) ASN1_i2d_fp(i2d_DHparams,(fp), \
@@ -167,12 +164,9 @@ struct dh_st
167#define d2i_DHparams_bio(bp,x) ASN1_d2i_bio_of(DH,DH_new,d2i_DHparams,bp,x) 164#define d2i_DHparams_bio(bp,x) ASN1_d2i_bio_of(DH,DH_new,d2i_DHparams,bp,x)
168#define i2d_DHparams_bio(bp,x) ASN1_i2d_bio_of_const(DH,i2d_DHparams,bp,x) 165#define i2d_DHparams_bio(bp,x) ASN1_i2d_bio_of_const(DH,i2d_DHparams,bp,x)
169 166
170const DH_METHOD *DH_OpenSSL(void); 167DH *DHparams_dup(DH *);
171 168
172#ifdef OPENSSL_FIPS 169const DH_METHOD *DH_OpenSSL(void);
173DH * FIPS_dh_new(void);
174void FIPS_dh_free(DH *dh);
175#endif
176 170
177void DH_set_default_method(const DH_METHOD *meth); 171void DH_set_default_method(const DH_METHOD *meth);
178const DH_METHOD *DH_get_default_method(void); 172const DH_METHOD *DH_get_default_method(void);
@@ -212,6 +206,18 @@ int DHparams_print(BIO *bp, const DH *x);
212int DHparams_print(char *bp, const DH *x); 206int DHparams_print(char *bp, const DH *x);
213#endif 207#endif
214 208
209#define EVP_PKEY_CTX_set_dh_paramgen_prime_len(ctx, len) \
210 EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DH, EVP_PKEY_OP_PARAMGEN, \
211 EVP_PKEY_CTRL_DH_PARAMGEN_PRIME_LEN, len, NULL)
212
213#define EVP_PKEY_CTX_set_dh_paramgen_generator(ctx, gen) \
214 EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DH, EVP_PKEY_OP_PARAMGEN, \
215 EVP_PKEY_CTRL_DH_PARAMGEN_GENERATOR, gen, NULL)
216
217#define EVP_PKEY_CTRL_DH_PARAMGEN_PRIME_LEN (EVP_PKEY_ALG_CTRL + 1)
218#define EVP_PKEY_CTRL_DH_PARAMGEN_GENERATOR (EVP_PKEY_ALG_CTRL + 2)
219
220
215/* BEGIN ERROR CODES */ 221/* BEGIN ERROR CODES */
216/* The following lines are auto generated by the script mkerr.pl. Any changes 222/* The following lines are auto generated by the script mkerr.pl. Any changes
217 * made after this point may be overwritten when the script is next run. 223 * made after this point may be overwritten when the script is next run.
@@ -222,22 +228,31 @@ void ERR_load_DH_strings(void);
222 228
223/* Function codes. */ 229/* Function codes. */
224#define DH_F_COMPUTE_KEY 102 230#define DH_F_COMPUTE_KEY 102
225#define DH_F_DHPARAMS_PRINT 100
226#define DH_F_DHPARAMS_PRINT_FP 101 231#define DH_F_DHPARAMS_PRINT_FP 101
227#define DH_F_DH_BUILTIN_GENPARAMS 106 232#define DH_F_DH_BUILTIN_GENPARAMS 106
228#define DH_F_DH_COMPUTE_KEY 107
229#define DH_F_DH_GENERATE_KEY 108
230#define DH_F_DH_GENERATE_PARAMETERS 109
231#define DH_F_DH_NEW_METHOD 105 233#define DH_F_DH_NEW_METHOD 105
234#define DH_F_DH_PARAM_DECODE 107
235#define DH_F_DH_PRIV_DECODE 110
236#define DH_F_DH_PRIV_ENCODE 111
237#define DH_F_DH_PUB_DECODE 108
238#define DH_F_DH_PUB_ENCODE 109
239#define DH_F_DO_DH_PRINT 100
232#define DH_F_GENERATE_KEY 103 240#define DH_F_GENERATE_KEY 103
233#define DH_F_GENERATE_PARAMETERS 104 241#define DH_F_GENERATE_PARAMETERS 104
242#define DH_F_PKEY_DH_DERIVE 112
243#define DH_F_PKEY_DH_KEYGEN 113
234 244
235/* Reason codes. */ 245/* Reason codes. */
236#define DH_R_BAD_GENERATOR 101 246#define DH_R_BAD_GENERATOR 101
247#define DH_R_BN_DECODE_ERROR 109
248#define DH_R_BN_ERROR 106
249#define DH_R_DECODE_ERROR 104
237#define DH_R_INVALID_PUBKEY 102 250#define DH_R_INVALID_PUBKEY 102
238#define DH_R_KEY_SIZE_TOO_SMALL 104 251#define DH_R_KEYS_NOT_SET 108
239#define DH_R_MODULUS_TOO_LARGE 103 252#define DH_R_MODULUS_TOO_LARGE 103
253#define DH_R_NO_PARAMETERS_SET 107
240#define DH_R_NO_PRIVATE_VALUE 100 254#define DH_R_NO_PRIVATE_VALUE 100
255#define DH_R_PARAMETER_ENCODING_ERROR 105
241 256
242#ifdef __cplusplus 257#ifdef __cplusplus
243} 258}
diff --git a/src/lib/libcrypto/dh/dh_ameth.c b/src/lib/libcrypto/dh/dh_ameth.c
new file mode 100644
index 0000000000..377caf96c9
--- /dev/null
+++ b/src/lib/libcrypto/dh/dh_ameth.c
@@ -0,0 +1,500 @@
1/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
2 * project 2006.
3 */
4/* ====================================================================
5 * Copyright (c) 2006 The OpenSSL Project. All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 *
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 *
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in
16 * the documentation and/or other materials provided with the
17 * distribution.
18 *
19 * 3. All advertising materials mentioning features or use of this
20 * software must display the following acknowledgment:
21 * "This product includes software developed by the OpenSSL Project
22 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
23 *
24 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
25 * endorse or promote products derived from this software without
26 * prior written permission. For written permission, please contact
27 * licensing@OpenSSL.org.
28 *
29 * 5. Products derived from this software may not be called "OpenSSL"
30 * nor may "OpenSSL" appear in their names without prior written
31 * permission of the OpenSSL Project.
32 *
33 * 6. Redistributions of any form whatsoever must retain the following
34 * acknowledgment:
35 * "This product includes software developed by the OpenSSL Project
36 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
37 *
38 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
39 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
40 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
41 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
42 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
43 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
44 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
45 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
46 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
47 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
48 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
49 * OF THE POSSIBILITY OF SUCH DAMAGE.
50 * ====================================================================
51 *
52 * This product includes cryptographic software written by Eric Young
53 * (eay@cryptsoft.com). This product includes software written by Tim
54 * Hudson (tjh@cryptsoft.com).
55 *
56 */
57
58#include <stdio.h>
59#include "cryptlib.h"
60#include <openssl/x509.h>
61#include <openssl/asn1.h>
62#include <openssl/dh.h>
63#include <openssl/bn.h>
64#include "asn1_locl.h"
65
66static void int_dh_free(EVP_PKEY *pkey)
67 {
68 DH_free(pkey->pkey.dh);
69 }
70
71static int dh_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey)
72 {
73 const unsigned char *p, *pm;
74 int pklen, pmlen;
75 int ptype;
76 void *pval;
77 ASN1_STRING *pstr;
78 X509_ALGOR *palg;
79 ASN1_INTEGER *public_key = NULL;
80
81 DH *dh = NULL;
82
83 if (!X509_PUBKEY_get0_param(NULL, &p, &pklen, &palg, pubkey))
84 return 0;
85 X509_ALGOR_get0(NULL, &ptype, &pval, palg);
86
87 if (ptype != V_ASN1_SEQUENCE)
88 {
89 DHerr(DH_F_DH_PUB_DECODE, DH_R_PARAMETER_ENCODING_ERROR);
90 goto err;
91 }
92
93 pstr = pval;
94 pm = pstr->data;
95 pmlen = pstr->length;
96
97 if (!(dh = d2i_DHparams(NULL, &pm, pmlen)))
98 {
99 DHerr(DH_F_DH_PUB_DECODE, DH_R_DECODE_ERROR);
100 goto err;
101 }
102
103 if (!(public_key=d2i_ASN1_INTEGER(NULL, &p, pklen)))
104 {
105 DHerr(DH_F_DH_PUB_DECODE, DH_R_DECODE_ERROR);
106 goto err;
107 }
108
109 /* We have parameters now set public key */
110 if (!(dh->pub_key = ASN1_INTEGER_to_BN(public_key, NULL)))
111 {
112 DHerr(DH_F_DH_PUB_DECODE, DH_R_BN_DECODE_ERROR);
113 goto err;
114 }
115
116 ASN1_INTEGER_free(public_key);
117 EVP_PKEY_assign_DH(pkey, dh);
118 return 1;
119
120 err:
121 if (public_key)
122 ASN1_INTEGER_free(public_key);
123 if (dh)
124 DH_free(dh);
125 return 0;
126
127 }
128
129static int dh_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey)
130 {
131 DH *dh;
132 void *pval = NULL;
133 int ptype;
134 unsigned char *penc = NULL;
135 int penclen;
136 ASN1_STRING *str;
137 ASN1_INTEGER *pub_key = NULL;
138
139 dh=pkey->pkey.dh;
140
141 str = ASN1_STRING_new();
142 str->length = i2d_DHparams(dh, &str->data);
143 if (str->length <= 0)
144 {
145 DHerr(DH_F_DH_PUB_ENCODE, ERR_R_MALLOC_FAILURE);
146 goto err;
147 }
148 pval = str;
149 ptype = V_ASN1_SEQUENCE;
150
151 pub_key = BN_to_ASN1_INTEGER(dh->pub_key, NULL);
152 if (!pub_key)
153 goto err;
154
155 penclen = i2d_ASN1_INTEGER(pub_key, &penc);
156
157 ASN1_INTEGER_free(pub_key);
158
159 if (penclen <= 0)
160 {
161 DHerr(DH_F_DH_PUB_ENCODE, ERR_R_MALLOC_FAILURE);
162 goto err;
163 }
164
165 if (X509_PUBKEY_set0_param(pk, OBJ_nid2obj(EVP_PKEY_DH),
166 ptype, pval, penc, penclen))
167 return 1;
168
169 err:
170 if (penc)
171 OPENSSL_free(penc);
172 if (pval)
173 ASN1_STRING_free(pval);
174
175 return 0;
176 }
177
178
179/* PKCS#8 DH is defined in PKCS#11 of all places. It is similar to DH in
180 * that the AlgorithmIdentifier contains the paramaters, the private key
181 * is explcitly included and the pubkey must be recalculated.
182 */
183
184static int dh_priv_decode(EVP_PKEY *pkey, PKCS8_PRIV_KEY_INFO *p8)
185 {
186 const unsigned char *p, *pm;
187 int pklen, pmlen;
188 int ptype;
189 void *pval;
190 ASN1_STRING *pstr;
191 X509_ALGOR *palg;
192 ASN1_INTEGER *privkey = NULL;
193
194 DH *dh = NULL;
195
196 if (!PKCS8_pkey_get0(NULL, &p, &pklen, &palg, p8))
197 return 0;
198
199 X509_ALGOR_get0(NULL, &ptype, &pval, palg);
200
201 if (ptype != V_ASN1_SEQUENCE)
202 goto decerr;
203
204 if (!(privkey=d2i_ASN1_INTEGER(NULL, &p, pklen)))
205 goto decerr;
206
207
208 pstr = pval;
209 pm = pstr->data;
210 pmlen = pstr->length;
211 if (!(dh = d2i_DHparams(NULL, &pm, pmlen)))
212 goto decerr;
213 /* We have parameters now set private key */
214 if (!(dh->priv_key = ASN1_INTEGER_to_BN(privkey, NULL)))
215 {
216 DHerr(DH_F_DH_PRIV_DECODE,DH_R_BN_ERROR);
217 goto dherr;
218 }
219 /* Calculate public key */
220 if (!DH_generate_key(dh))
221 goto dherr;
222
223 EVP_PKEY_assign_DH(pkey, dh);
224
225 ASN1_INTEGER_free(privkey);
226
227 return 1;
228
229 decerr:
230 DHerr(DH_F_DH_PRIV_DECODE, EVP_R_DECODE_ERROR);
231 dherr:
232 DH_free(dh);
233 return 0;
234 }
235
236static int dh_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey)
237{
238 ASN1_STRING *params = NULL;
239 ASN1_INTEGER *prkey = NULL;
240 unsigned char *dp = NULL;
241 int dplen;
242
243 params = ASN1_STRING_new();
244
245 if (!params)
246 {
247 DHerr(DH_F_DH_PRIV_ENCODE,ERR_R_MALLOC_FAILURE);
248 goto err;
249 }
250
251 params->length = i2d_DHparams(pkey->pkey.dh, &params->data);
252 if (params->length <= 0)
253 {
254 DHerr(DH_F_DH_PRIV_ENCODE,ERR_R_MALLOC_FAILURE);
255 goto err;
256 }
257 params->type = V_ASN1_SEQUENCE;
258
259 /* Get private key into integer */
260 prkey = BN_to_ASN1_INTEGER(pkey->pkey.dh->priv_key, NULL);
261
262 if (!prkey)
263 {
264 DHerr(DH_F_DH_PRIV_ENCODE,DH_R_BN_ERROR);
265 goto err;
266 }
267
268 dplen = i2d_ASN1_INTEGER(prkey, &dp);
269
270 ASN1_INTEGER_free(prkey);
271
272 if (!PKCS8_pkey_set0(p8, OBJ_nid2obj(NID_dhKeyAgreement), 0,
273 V_ASN1_SEQUENCE, params, dp, dplen))
274 goto err;
275
276 return 1;
277
278err:
279 if (dp != NULL)
280 OPENSSL_free(dp);
281 if (params != NULL)
282 ASN1_STRING_free(params);
283 if (prkey != NULL)
284 ASN1_INTEGER_free(prkey);
285 return 0;
286}
287
288
289static void update_buflen(const BIGNUM *b, size_t *pbuflen)
290 {
291 size_t i;
292 if (!b)
293 return;
294 if (*pbuflen < (i = (size_t)BN_num_bytes(b)))
295 *pbuflen = i;
296 }
297
298static int dh_param_decode(EVP_PKEY *pkey,
299 const unsigned char **pder, int derlen)
300 {
301 DH *dh;
302 if (!(dh = d2i_DHparams(NULL, pder, derlen)))
303 {
304 DHerr(DH_F_DH_PARAM_DECODE, ERR_R_DH_LIB);
305 return 0;
306 }
307 EVP_PKEY_assign_DH(pkey, dh);
308 return 1;
309 }
310
311static int dh_param_encode(const EVP_PKEY *pkey, unsigned char **pder)
312 {
313 return i2d_DHparams(pkey->pkey.dh, pder);
314 }
315
316static int do_dh_print(BIO *bp, const DH *x, int indent,
317 ASN1_PCTX *ctx, int ptype)
318 {
319 unsigned char *m=NULL;
320 int reason=ERR_R_BUF_LIB,ret=0;
321 size_t buf_len=0;
322
323 const char *ktype = NULL;
324
325 BIGNUM *priv_key, *pub_key;
326
327 if (ptype == 2)
328 priv_key = x->priv_key;
329 else
330 priv_key = NULL;
331
332 if (ptype > 0)
333 pub_key = x->pub_key;
334 else
335 pub_key = NULL;
336
337 update_buflen(x->p, &buf_len);
338
339 if (buf_len == 0)
340 {
341 reason = ERR_R_PASSED_NULL_PARAMETER;
342 goto err;
343 }
344
345 update_buflen(x->g, &buf_len);
346 update_buflen(pub_key, &buf_len);
347 update_buflen(priv_key, &buf_len);
348
349 if (ptype == 2)
350 ktype = "PKCS#3 DH Private-Key";
351 else if (ptype == 1)
352 ktype = "PKCS#3 DH Public-Key";
353 else
354 ktype = "PKCS#3 DH Parameters";
355
356 m= OPENSSL_malloc(buf_len+10);
357 if (m == NULL)
358 {
359 reason=ERR_R_MALLOC_FAILURE;
360 goto err;
361 }
362
363 BIO_indent(bp, indent, 128);
364 if (BIO_printf(bp,"%s: (%d bit)\n", ktype, BN_num_bits(x->p)) <= 0)
365 goto err;
366 indent += 4;
367
368 if (!ASN1_bn_print(bp,"private-key:",priv_key,m,indent)) goto err;
369 if (!ASN1_bn_print(bp,"public-key:",pub_key,m,indent)) goto err;
370
371 if (!ASN1_bn_print(bp,"prime:",x->p,m,indent)) goto err;
372 if (!ASN1_bn_print(bp,"generator:",x->g,m,indent)) goto err;
373 if (x->length != 0)
374 {
375 BIO_indent(bp, indent, 128);
376 if (BIO_printf(bp,"recommended-private-length: %d bits\n",
377 (int)x->length) <= 0) goto err;
378 }
379
380
381 ret=1;
382 if (0)
383 {
384err:
385 DHerr(DH_F_DO_DH_PRINT,reason);
386 }
387 if (m != NULL) OPENSSL_free(m);
388 return(ret);
389 }
390
391static int int_dh_size(const EVP_PKEY *pkey)
392 {
393 return(DH_size(pkey->pkey.dh));
394 }
395
396static int dh_bits(const EVP_PKEY *pkey)
397 {
398 return BN_num_bits(pkey->pkey.dh->p);
399 }
400
401static int dh_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b)
402 {
403 if ( BN_cmp(a->pkey.dh->p,b->pkey.dh->p) ||
404 BN_cmp(a->pkey.dh->g,b->pkey.dh->g))
405 return 0;
406 else
407 return 1;
408 }
409
410static int dh_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from)
411 {
412 BIGNUM *a;
413
414 if ((a=BN_dup(from->pkey.dh->p)) == NULL)
415 return 0;
416 if (to->pkey.dh->p != NULL)
417 BN_free(to->pkey.dh->p);
418 to->pkey.dh->p=a;
419
420 if ((a=BN_dup(from->pkey.dh->g)) == NULL)
421 return 0;
422 if (to->pkey.dh->g != NULL)
423 BN_free(to->pkey.dh->g);
424 to->pkey.dh->g=a;
425
426 return 1;
427 }
428
429static int dh_missing_parameters(const EVP_PKEY *a)
430 {
431 if (!a->pkey.dh->p || !a->pkey.dh->g)
432 return 1;
433 return 0;
434 }
435
436static int dh_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b)
437 {
438 if (dh_cmp_parameters(a, b) == 0)
439 return 0;
440 if (BN_cmp(b->pkey.dh->pub_key,a->pkey.dh->pub_key) != 0)
441 return 0;
442 else
443 return 1;
444 }
445
446static int dh_param_print(BIO *bp, const EVP_PKEY *pkey, int indent,
447 ASN1_PCTX *ctx)
448 {
449 return do_dh_print(bp, pkey->pkey.dh, indent, ctx, 0);
450 }
451
452static int dh_public_print(BIO *bp, const EVP_PKEY *pkey, int indent,
453 ASN1_PCTX *ctx)
454 {
455 return do_dh_print(bp, pkey->pkey.dh, indent, ctx, 1);
456 }
457
458static int dh_private_print(BIO *bp, const EVP_PKEY *pkey, int indent,
459 ASN1_PCTX *ctx)
460 {
461 return do_dh_print(bp, pkey->pkey.dh, indent, ctx, 2);
462 }
463
464int DHparams_print(BIO *bp, const DH *x)
465 {
466 return do_dh_print(bp, x, 4, NULL, 0);
467 }
468
469const EVP_PKEY_ASN1_METHOD dh_asn1_meth =
470 {
471 EVP_PKEY_DH,
472 EVP_PKEY_DH,
473 0,
474
475 "DH",
476 "OpenSSL PKCS#3 DH method",
477
478 dh_pub_decode,
479 dh_pub_encode,
480 dh_pub_cmp,
481 dh_public_print,
482
483 dh_priv_decode,
484 dh_priv_encode,
485 dh_private_print,
486
487 int_dh_size,
488 dh_bits,
489
490 dh_param_decode,
491 dh_param_encode,
492 dh_missing_parameters,
493 dh_copy_parameters,
494 dh_cmp_parameters,
495 dh_param_print,
496
497 int_dh_free,
498 0
499 };
500
diff --git a/src/lib/libcrypto/dh/dh_asn1.c b/src/lib/libcrypto/dh/dh_asn1.c
index 76740af2bd..0b4357d605 100644
--- a/src/lib/libcrypto/dh/dh_asn1.c
+++ b/src/lib/libcrypto/dh/dh_asn1.c
@@ -3,7 +3,7 @@
3 * project 2000. 3 * project 2000.
4 */ 4 */
5/* ==================================================================== 5/* ====================================================================
6 * Copyright (c) 2000 The OpenSSL Project. All rights reserved. 6 * Copyright (c) 2000-2005 The OpenSSL Project. All rights reserved.
7 * 7 *
8 * Redistribution and use in source and binary forms, with or without 8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions 9 * modification, are permitted provided that the following conditions
@@ -64,7 +64,8 @@
64#include <openssl/asn1t.h> 64#include <openssl/asn1t.h>
65 65
66/* Override the default free and new methods */ 66/* Override the default free and new methods */
67static int dh_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it) 67static int dh_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
68 void *exarg)
68{ 69{
69 if(operation == ASN1_OP_NEW_PRE) { 70 if(operation == ASN1_OP_NEW_PRE) {
70 *pval = (ASN1_VALUE *)DH_new(); 71 *pval = (ASN1_VALUE *)DH_new();
@@ -85,3 +86,8 @@ ASN1_SEQUENCE_cb(DHparams, dh_cb) = {
85} ASN1_SEQUENCE_END_cb(DH, DHparams) 86} ASN1_SEQUENCE_END_cb(DH, DHparams)
86 87
87IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(DH, DHparams, DHparams) 88IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(DH, DHparams, DHparams)
89
90DH *DHparams_dup(DH *dh)
91 {
92 return ASN1_item_dup(ASN1_ITEM_rptr(DHparams), dh);
93 }
diff --git a/src/lib/libcrypto/dh/dh_check.c b/src/lib/libcrypto/dh/dh_check.c
index 316cb9221d..066898174e 100644
--- a/src/lib/libcrypto/dh/dh_check.c
+++ b/src/lib/libcrypto/dh/dh_check.c
@@ -70,8 +70,6 @@
70 * should hold. 70 * should hold.
71 */ 71 */
72 72
73#ifndef OPENSSL_FIPS
74
75int DH_check(const DH *dh, int *ret) 73int DH_check(const DH *dh, int *ret)
76 { 74 {
77 int ok=0; 75 int ok=0;
@@ -130,11 +128,11 @@ int DH_check_pub_key(const DH *dh, const BIGNUM *pub_key, int *ret)
130 q=BN_new(); 128 q=BN_new();
131 if (q == NULL) goto err; 129 if (q == NULL) goto err;
132 BN_set_word(q,1); 130 BN_set_word(q,1);
133 if (BN_cmp(pub_key,q) <= 0) 131 if (BN_cmp(pub_key,q)<=0)
134 *ret|=DH_CHECK_PUBKEY_TOO_SMALL; 132 *ret|=DH_CHECK_PUBKEY_TOO_SMALL;
135 BN_copy(q,dh->p); 133 BN_copy(q,dh->p);
136 BN_sub_word(q,1); 134 BN_sub_word(q,1);
137 if (BN_cmp(pub_key,q) >= 0) 135 if (BN_cmp(pub_key,q)>=0)
138 *ret|=DH_CHECK_PUBKEY_TOO_LARGE; 136 *ret|=DH_CHECK_PUBKEY_TOO_LARGE;
139 137
140 ok = 1; 138 ok = 1;
@@ -142,5 +140,3 @@ err:
142 if (q != NULL) BN_free(q); 140 if (q != NULL) BN_free(q);
143 return(ok); 141 return(ok);
144 } 142 }
145
146#endif
diff --git a/src/lib/libcrypto/dh/dh_err.c b/src/lib/libcrypto/dh/dh_err.c
index 13263c81c1..d5cf0c22a3 100644
--- a/src/lib/libcrypto/dh/dh_err.c
+++ b/src/lib/libcrypto/dh/dh_err.c
@@ -1,6 +1,6 @@
1/* crypto/dh/dh_err.c */ 1/* crypto/dh/dh_err.c */
2/* ==================================================================== 2/* ====================================================================
3 * Copyright (c) 1999-2007 The OpenSSL Project. All rights reserved. 3 * Copyright (c) 1999-2006 The OpenSSL Project. All rights reserved.
4 * 4 *
5 * Redistribution and use in source and binary forms, with or without 5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions 6 * modification, are permitted provided that the following conditions
@@ -71,25 +71,34 @@
71static ERR_STRING_DATA DH_str_functs[]= 71static ERR_STRING_DATA DH_str_functs[]=
72 { 72 {
73{ERR_FUNC(DH_F_COMPUTE_KEY), "COMPUTE_KEY"}, 73{ERR_FUNC(DH_F_COMPUTE_KEY), "COMPUTE_KEY"},
74{ERR_FUNC(DH_F_DHPARAMS_PRINT), "DHparams_print"},
75{ERR_FUNC(DH_F_DHPARAMS_PRINT_FP), "DHparams_print_fp"}, 74{ERR_FUNC(DH_F_DHPARAMS_PRINT_FP), "DHparams_print_fp"},
76{ERR_FUNC(DH_F_DH_BUILTIN_GENPARAMS), "DH_BUILTIN_GENPARAMS"}, 75{ERR_FUNC(DH_F_DH_BUILTIN_GENPARAMS), "DH_BUILTIN_GENPARAMS"},
77{ERR_FUNC(DH_F_DH_COMPUTE_KEY), "DH_compute_key"},
78{ERR_FUNC(DH_F_DH_GENERATE_KEY), "DH_generate_key"},
79{ERR_FUNC(DH_F_DH_GENERATE_PARAMETERS), "DH_generate_parameters"},
80{ERR_FUNC(DH_F_DH_NEW_METHOD), "DH_new_method"}, 76{ERR_FUNC(DH_F_DH_NEW_METHOD), "DH_new_method"},
77{ERR_FUNC(DH_F_DH_PARAM_DECODE), "DH_PARAM_DECODE"},
78{ERR_FUNC(DH_F_DH_PRIV_DECODE), "DH_PRIV_DECODE"},
79{ERR_FUNC(DH_F_DH_PRIV_ENCODE), "DH_PRIV_ENCODE"},
80{ERR_FUNC(DH_F_DH_PUB_DECODE), "DH_PUB_DECODE"},
81{ERR_FUNC(DH_F_DH_PUB_ENCODE), "DH_PUB_ENCODE"},
82{ERR_FUNC(DH_F_DO_DH_PRINT), "DO_DH_PRINT"},
81{ERR_FUNC(DH_F_GENERATE_KEY), "GENERATE_KEY"}, 83{ERR_FUNC(DH_F_GENERATE_KEY), "GENERATE_KEY"},
82{ERR_FUNC(DH_F_GENERATE_PARAMETERS), "GENERATE_PARAMETERS"}, 84{ERR_FUNC(DH_F_GENERATE_PARAMETERS), "GENERATE_PARAMETERS"},
85{ERR_FUNC(DH_F_PKEY_DH_DERIVE), "PKEY_DH_DERIVE"},
86{ERR_FUNC(DH_F_PKEY_DH_KEYGEN), "PKEY_DH_KEYGEN"},
83{0,NULL} 87{0,NULL}
84 }; 88 };
85 89
86static ERR_STRING_DATA DH_str_reasons[]= 90static ERR_STRING_DATA DH_str_reasons[]=
87 { 91 {
88{ERR_REASON(DH_R_BAD_GENERATOR) ,"bad generator"}, 92{ERR_REASON(DH_R_BAD_GENERATOR) ,"bad generator"},
93{ERR_REASON(DH_R_BN_DECODE_ERROR) ,"bn decode error"},
94{ERR_REASON(DH_R_BN_ERROR) ,"bn error"},
95{ERR_REASON(DH_R_DECODE_ERROR) ,"decode error"},
89{ERR_REASON(DH_R_INVALID_PUBKEY) ,"invalid public key"}, 96{ERR_REASON(DH_R_INVALID_PUBKEY) ,"invalid public key"},
90{ERR_REASON(DH_R_KEY_SIZE_TOO_SMALL) ,"key size too small"}, 97{ERR_REASON(DH_R_KEYS_NOT_SET) ,"keys not set"},
91{ERR_REASON(DH_R_MODULUS_TOO_LARGE) ,"modulus too large"}, 98{ERR_REASON(DH_R_MODULUS_TOO_LARGE) ,"modulus too large"},
99{ERR_REASON(DH_R_NO_PARAMETERS_SET) ,"no parameters set"},
92{ERR_REASON(DH_R_NO_PRIVATE_VALUE) ,"no private value"}, 100{ERR_REASON(DH_R_NO_PRIVATE_VALUE) ,"no private value"},
101{ERR_REASON(DH_R_PARAMETER_ENCODING_ERROR),"parameter encoding error"},
93{0,NULL} 102{0,NULL}
94 }; 103 };
95 104
diff --git a/src/lib/libcrypto/dh/dh_gen.c b/src/lib/libcrypto/dh/dh_gen.c
index 999e1deb40..cfd5b11868 100644
--- a/src/lib/libcrypto/dh/dh_gen.c
+++ b/src/lib/libcrypto/dh/dh_gen.c
@@ -66,8 +66,6 @@
66#include <openssl/bn.h> 66#include <openssl/bn.h>
67#include <openssl/dh.h> 67#include <openssl/dh.h>
68 68
69#ifndef OPENSSL_FIPS
70
71static int dh_builtin_genparams(DH *ret, int prime_len, int generator, BN_GENCB *cb); 69static int dh_builtin_genparams(DH *ret, int prime_len, int generator, BN_GENCB *cb);
72 70
73int DH_generate_parameters_ex(DH *ret, int prime_len, int generator, BN_GENCB *cb) 71int DH_generate_parameters_ex(DH *ret, int prime_len, int generator, BN_GENCB *cb)
@@ -175,5 +173,3 @@ err:
175 } 173 }
176 return ok; 174 return ok;
177 } 175 }
178
179#endif
diff --git a/src/lib/libcrypto/dh/dh_key.c b/src/lib/libcrypto/dh/dh_key.c
index 79dd331863..e7db440342 100644
--- a/src/lib/libcrypto/dh/dh_key.c
+++ b/src/lib/libcrypto/dh/dh_key.c
@@ -62,8 +62,6 @@
62#include <openssl/rand.h> 62#include <openssl/rand.h>
63#include <openssl/dh.h> 63#include <openssl/dh.h>
64 64
65#ifndef OPENSSL_FIPS
66
67static int generate_key(DH *dh); 65static int generate_key(DH *dh);
68static int compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh); 66static int compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh);
69static int dh_bn_mod_exp(const DH *dh, BIGNUM *r, 67static int dh_bn_mod_exp(const DH *dh, BIGNUM *r,
@@ -263,5 +261,3 @@ static int dh_finish(DH *dh)
263 BN_MONT_CTX_free(dh->method_mont_p); 261 BN_MONT_CTX_free(dh->method_mont_p);
264 return(1); 262 return(1);
265 } 263 }
266
267#endif
diff --git a/src/lib/libcrypto/dh/dh_pmeth.c b/src/lib/libcrypto/dh/dh_pmeth.c
new file mode 100644
index 0000000000..5ae72b7d4c
--- /dev/null
+++ b/src/lib/libcrypto/dh/dh_pmeth.c
@@ -0,0 +1,254 @@
1/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
2 * project 2006.
3 */
4/* ====================================================================
5 * Copyright (c) 2006 The OpenSSL Project. All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 *
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 *
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in
16 * the documentation and/or other materials provided with the
17 * distribution.
18 *
19 * 3. All advertising materials mentioning features or use of this
20 * software must display the following acknowledgment:
21 * "This product includes software developed by the OpenSSL Project
22 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
23 *
24 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
25 * endorse or promote products derived from this software without
26 * prior written permission. For written permission, please contact
27 * licensing@OpenSSL.org.
28 *
29 * 5. Products derived from this software may not be called "OpenSSL"
30 * nor may "OpenSSL" appear in their names without prior written
31 * permission of the OpenSSL Project.
32 *
33 * 6. Redistributions of any form whatsoever must retain the following
34 * acknowledgment:
35 * "This product includes software developed by the OpenSSL Project
36 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
37 *
38 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
39 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
40 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
41 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
42 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
43 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
44 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
45 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
46 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
47 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
48 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
49 * OF THE POSSIBILITY OF SUCH DAMAGE.
50 * ====================================================================
51 *
52 * This product includes cryptographic software written by Eric Young
53 * (eay@cryptsoft.com). This product includes software written by Tim
54 * Hudson (tjh@cryptsoft.com).
55 *
56 */
57
58#include <stdio.h>
59#include "cryptlib.h"
60#include <openssl/asn1t.h>
61#include <openssl/x509.h>
62#include <openssl/evp.h>
63#include <openssl/dh.h>
64#include <openssl/bn.h>
65#include "evp_locl.h"
66
67/* DH pkey context structure */
68
69typedef struct
70 {
71 /* Parameter gen parameters */
72 int prime_len;
73 int generator;
74 int use_dsa;
75 /* Keygen callback info */
76 int gentmp[2];
77 /* message digest */
78 } DH_PKEY_CTX;
79
80static int pkey_dh_init(EVP_PKEY_CTX *ctx)
81 {
82 DH_PKEY_CTX *dctx;
83 dctx = OPENSSL_malloc(sizeof(DH_PKEY_CTX));
84 if (!dctx)
85 return 0;
86 dctx->prime_len = 1024;
87 dctx->generator = 2;
88 dctx->use_dsa = 0;
89
90 ctx->data = dctx;
91 ctx->keygen_info = dctx->gentmp;
92 ctx->keygen_info_count = 2;
93
94 return 1;
95 }
96
97static int pkey_dh_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src)
98 {
99 DH_PKEY_CTX *dctx, *sctx;
100 if (!pkey_dh_init(dst))
101 return 0;
102 sctx = src->data;
103 dctx = dst->data;
104 dctx->prime_len = sctx->prime_len;
105 dctx->generator = sctx->generator;
106 dctx->use_dsa = sctx->use_dsa;
107 return 1;
108 }
109
110static void pkey_dh_cleanup(EVP_PKEY_CTX *ctx)
111 {
112 DH_PKEY_CTX *dctx = ctx->data;
113 if (dctx)
114 OPENSSL_free(dctx);
115 }
116
117static int pkey_dh_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
118 {
119 DH_PKEY_CTX *dctx = ctx->data;
120 switch (type)
121 {
122 case EVP_PKEY_CTRL_DH_PARAMGEN_PRIME_LEN:
123 if (p1 < 256)
124 return -2;
125 dctx->prime_len = p1;
126 return 1;
127
128 case EVP_PKEY_CTRL_DH_PARAMGEN_GENERATOR:
129 dctx->generator = p1;
130 return 1;
131
132 case EVP_PKEY_CTRL_PEER_KEY:
133 /* Default behaviour is OK */
134 return 1;
135
136 default:
137 return -2;
138
139 }
140 }
141
142
143static int pkey_dh_ctrl_str(EVP_PKEY_CTX *ctx,
144 const char *type, const char *value)
145 {
146 if (!strcmp(type, "dh_paramgen_prime_len"))
147 {
148 int len;
149 len = atoi(value);
150 return EVP_PKEY_CTX_set_dh_paramgen_prime_len(ctx, len);
151 }
152 if (!strcmp(type, "dh_paramgen_generator"))
153 {
154 int len;
155 len = atoi(value);
156 return EVP_PKEY_CTX_set_dh_paramgen_generator(ctx, len);
157 }
158 return -2;
159 }
160
161static int pkey_dh_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
162 {
163 DH *dh = NULL;
164 DH_PKEY_CTX *dctx = ctx->data;
165 BN_GENCB *pcb, cb;
166 int ret;
167 if (ctx->pkey_gencb)
168 {
169 pcb = &cb;
170 evp_pkey_set_cb_translate(pcb, ctx);
171 }
172 else
173 pcb = NULL;
174 dh = DH_new();
175 if (!dh)
176 return 0;
177 ret = DH_generate_parameters_ex(dh,
178 dctx->prime_len, dctx->generator, pcb);
179 if (ret)
180 EVP_PKEY_assign_DH(pkey, dh);
181 else
182 DH_free(dh);
183 return ret;
184 }
185
186static int pkey_dh_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
187 {
188 DH *dh = NULL;
189 if (ctx->pkey == NULL)
190 {
191 DHerr(DH_F_PKEY_DH_KEYGEN, DH_R_NO_PARAMETERS_SET);
192 return 0;
193 }
194 dh = DH_new();
195 if (!dh)
196 return 0;
197 EVP_PKEY_assign_DH(pkey, dh);
198 /* Note: if error return, pkey is freed by parent routine */
199 if (!EVP_PKEY_copy_parameters(pkey, ctx->pkey))
200 return 0;
201 return DH_generate_key(pkey->pkey.dh);
202 }
203
204static int pkey_dh_derive(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen)
205 {
206 int ret;
207 if (!ctx->pkey || !ctx->peerkey)
208 {
209 DHerr(DH_F_PKEY_DH_DERIVE, DH_R_KEYS_NOT_SET);
210 return 0;
211 }
212 ret = DH_compute_key(key, ctx->peerkey->pkey.dh->pub_key,
213 ctx->pkey->pkey.dh);
214 if (ret < 0)
215 return ret;
216 *keylen = ret;
217 return 1;
218 }
219
220const EVP_PKEY_METHOD dh_pkey_meth =
221 {
222 EVP_PKEY_DH,
223 EVP_PKEY_FLAG_AUTOARGLEN,
224 pkey_dh_init,
225 pkey_dh_copy,
226 pkey_dh_cleanup,
227
228 0,
229 pkey_dh_paramgen,
230
231 0,
232 pkey_dh_keygen,
233
234 0,
235 0,
236
237 0,
238 0,
239
240 0,0,
241
242 0,0,0,0,
243
244 0,0,
245
246 0,0,
247
248 0,
249 pkey_dh_derive,
250
251 pkey_dh_ctrl,
252 pkey_dh_ctrl_str
253
254 };
diff --git a/src/lib/libcrypto/dh/dh_prn.c b/src/lib/libcrypto/dh/dh_prn.c
new file mode 100644
index 0000000000..ae58c2ac87
--- /dev/null
+++ b/src/lib/libcrypto/dh/dh_prn.c
@@ -0,0 +1,80 @@
1/* crypto/asn1/t_pkey.c */
2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3 * All rights reserved.
4 *
5 * This package is an SSL implementation written
6 * by Eric Young (eay@cryptsoft.com).
7 * The implementation was written so as to conform with Netscapes SSL.
8 *
9 * This library is free for commercial and non-commercial use as long as
10 * the following conditions are aheared to. The following conditions
11 * apply to all code found in this distribution, be it the RC4, RSA,
12 * lhash, DES, etc., code; not just the SSL code. The SSL documentation
13 * included with this distribution is covered by the same copyright terms
14 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15 *
16 * Copyright remains Eric Young's, and as such any Copyright notices in
17 * the code are not to be removed.
18 * If this package is used in a product, Eric Young should be given attribution
19 * as the author of the parts of the library used.
20 * This can be in the form of a textual message at program startup or
21 * in documentation (online or textual) provided with the package.
22 *
23 * Redistribution and use in source and binary forms, with or without
24 * modification, are permitted provided that the following conditions
25 * are met:
26 * 1. Redistributions of source code must retain the copyright
27 * notice, this list of conditions and the following disclaimer.
28 * 2. Redistributions in binary form must reproduce the above copyright
29 * notice, this list of conditions and the following disclaimer in the
30 * documentation and/or other materials provided with the distribution.
31 * 3. All advertising materials mentioning features or use of this software
32 * must display the following acknowledgement:
33 * "This product includes cryptographic software written by
34 * Eric Young (eay@cryptsoft.com)"
35 * The word 'cryptographic' can be left out if the rouines from the library
36 * being used are not cryptographic related :-).
37 * 4. If you include any Windows specific code (or a derivative thereof) from
38 * the apps directory (application code) you must include an acknowledgement:
39 * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40 *
41 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51 * SUCH DAMAGE.
52 *
53 * The licence and distribution terms for any publically available version or
54 * derivative of this code cannot be changed. i.e. this code cannot simply be
55 * copied and put under another distribution licence
56 * [including the GNU Public Licence.]
57 */
58
59#include <stdio.h>
60#include "cryptlib.h"
61#include <openssl/evp.h>
62#include <openssl/dh.h>
63
64#ifndef OPENSSL_NO_FP_API
65int DHparams_print_fp(FILE *fp, const DH *x)
66 {
67 BIO *b;
68 int ret;
69
70 if ((b=BIO_new(BIO_s_file())) == NULL)
71 {
72 DHerr(DH_F_DHPARAMS_PRINT_FP,ERR_R_BUF_LIB);
73 return(0);
74 }
75 BIO_set_fp(b,fp,BIO_NOCLOSE);
76 ret=DHparams_print(b, x);
77 BIO_free(b);
78 return(ret);
79 }
80#endif
diff --git a/src/lib/libcrypto/doc/DSA_get_ex_new_index.pod b/src/lib/libcrypto/doc/DSA_get_ex_new_index.pod
index 4612e708ec..fb6efc1182 100644
--- a/src/lib/libcrypto/doc/DSA_get_ex_new_index.pod
+++ b/src/lib/libcrypto/doc/DSA_get_ex_new_index.pod
@@ -6,7 +6,7 @@ DSA_get_ex_new_index, DSA_set_ex_data, DSA_get_ex_data - add application specifi
6 6
7=head1 SYNOPSIS 7=head1 SYNOPSIS
8 8
9 #include <openssl/DSA.h> 9 #include <openssl/dsa.h>
10 10
11 int DSA_get_ex_new_index(long argl, void *argp, 11 int DSA_get_ex_new_index(long argl, void *argp,
12 CRYPTO_EX_new *new_func, 12 CRYPTO_EX_new *new_func,
diff --git a/src/lib/libcrypto/doc/EVP_DigestInit.pod b/src/lib/libcrypto/doc/EVP_DigestInit.pod
index 130cd7f60a..5b477ac6ec 100644
--- a/src/lib/libcrypto/doc/EVP_DigestInit.pod
+++ b/src/lib/libcrypto/doc/EVP_DigestInit.pod
@@ -64,9 +64,9 @@ EVP digest routines
64 64
65The EVP digest routines are a high level interface to message digests. 65The EVP digest routines are a high level interface to message digests.
66 66
67EVP_MD_CTX_init() initializes digest contet B<ctx>. 67EVP_MD_CTX_init() initializes digest context B<ctx>.
68 68
69EVP_MD_CTX_create() allocates, initializes and returns a digest contet. 69EVP_MD_CTX_create() allocates, initializes and returns a digest context.
70 70
71EVP_DigestInit_ex() sets up digest context B<ctx> to use a digest 71EVP_DigestInit_ex() sets up digest context B<ctx> to use a digest
72B<type> from ENGINE B<impl>. B<ctx> must be initialized before calling this 72B<type> from ENGINE B<impl>. B<ctx> must be initialized before calling this
@@ -102,7 +102,7 @@ the passed context B<ctx> does not have to be initialized, and it always
102uses the default digest implementation. 102uses the default digest implementation.
103 103
104EVP_DigestFinal() is similar to EVP_DigestFinal_ex() except the digest 104EVP_DigestFinal() is similar to EVP_DigestFinal_ex() except the digest
105contet B<ctx> is automatically cleaned up. 105context B<ctx> is automatically cleaned up.
106 106
107EVP_MD_CTX_copy() is similar to EVP_MD_CTX_copy_ex() except the destination 107EVP_MD_CTX_copy() is similar to EVP_MD_CTX_copy_ex() except the destination
108B<out> does not have to be initialized. 108B<out> does not have to be initialized.
@@ -132,7 +132,9 @@ return B<EVP_MD> structures for the MD2, MD5, SHA, SHA1, MDC2 and RIPEMD160 dige
132algorithms respectively. The associated signature algorithm is RSA in each case. 132algorithms respectively. The associated signature algorithm is RSA in each case.
133 133
134EVP_dss() and EVP_dss1() return B<EVP_MD> structures for SHA and SHA1 digest 134EVP_dss() and EVP_dss1() return B<EVP_MD> structures for SHA and SHA1 digest
135algorithms but using DSS (DSA) for the signature algorithm. 135algorithms but using DSS (DSA) for the signature algorithm. Note: there is
136no need to use these pseudo-digests in OpenSSL 1.0.0 and later, they are
137however retained for compatibility.
136 138
137EVP_md_null() is a "null" message digest that does nothing: i.e. the hash it 139EVP_md_null() is a "null" message digest that does nothing: i.e. the hash it
138returns is of zero length. 140returns is of zero length.
@@ -228,12 +230,6 @@ digest name passed on the command line.
228 printf("\n"); 230 printf("\n");
229 } 231 }
230 232
231=head1 BUGS
232
233The link between digests and signing algorithms results in a situation where
234EVP_sha1() must be used with RSA and EVP_dss1() must be used with DSS
235even though they are identical digests.
236
237=head1 SEE ALSO 233=head1 SEE ALSO
238 234
239L<evp(3)|evp(3)>, L<hmac(3)|hmac(3)>, L<md2(3)|md2(3)>, 235L<evp(3)|evp(3)>, L<hmac(3)|hmac(3)>, L<md2(3)|md2(3)>,
@@ -253,4 +249,11 @@ EVP_md_null(), EVP_md2(), EVP_md5(), EVP_sha(), EVP_sha1(),
253EVP_dss(), EVP_dss1(), EVP_mdc2() and EVP_ripemd160() were 249EVP_dss(), EVP_dss1(), EVP_mdc2() and EVP_ripemd160() were
254changed to return truely const EVP_MD * in OpenSSL 0.9.7. 250changed to return truely const EVP_MD * in OpenSSL 0.9.7.
255 251
252The link between digests and signing algorithms was fixed in OpenSSL 1.0 and
253later, so now EVP_sha1() can be used with RSA and DSA, there is no need to
254use EVP_dss1() any more.
255
256OpenSSL 1.0 and later does not include the MD2 digest algorithm in the
257default configuration due to its security weaknesses.
258
256=cut 259=cut
diff --git a/src/lib/libcrypto/doc/EVP_DigestSignInit.pod b/src/lib/libcrypto/doc/EVP_DigestSignInit.pod
new file mode 100644
index 0000000000..37d960e3b2
--- /dev/null
+++ b/src/lib/libcrypto/doc/EVP_DigestSignInit.pod
@@ -0,0 +1,87 @@
1=pod
2
3=head1 NAME
4
5EVP_DigestSignInit, EVP_DigestSignUpdate, EVP_DigestSignFinal - EVP signing functions
6
7=head1 SYNOPSIS
8
9 #include <openssl/evp.h>
10
11 int EVP_DigestSignInit(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx,
12 const EVP_MD *type, ENGINE *e, EVP_PKEY *pkey);
13 int EVP_DigestSignUpdate(EVP_MD_CTX *ctx, const void *d, unsigned int cnt);
14 int EVP_DigestSignFinal(EVP_MD_CTX *ctx, unsigned char *sig, size_t *siglen);
15
16=head1 DESCRIPTION
17
18The EVP signature routines are a high level interface to digital signatures.
19
20EVP_DigestSignInit() sets up signing context B<ctx> to use digest B<type> from
21ENGINE B<impl> and private key B<pkey>. B<ctx> must be initialized with
22EVP_MD_CTX_init() before calling this function. If B<pctx> is not NULL the
23EVP_PKEY_CTX of the signing operation will be written to B<*pctx>: this can
24be used to set alternative signing options.
25
26EVP_DigestSignUpdate() hashes B<cnt> bytes of data at B<d> into the
27signature context B<ctx>. This function can be called several times on the
28same B<ctx> to include additional data. This function is currently implemented
29usig a macro.
30
31EVP_DigestSignFinal() signs the data in B<ctx> places the signature in B<sig>.
32If B<sig> is B<NULL> then the maximum size of the output buffer is written to
33the B<siglen> parameter. If B<sig> is not B<NULL> then before the call the
34B<siglen> parameter should contain the length of the B<sig> buffer, if the
35call is successful the signature is written to B<sig> and the amount of data
36written to B<siglen>.
37
38=head1 RETURN VALUES
39
40EVP_DigestSignInit() EVP_DigestSignUpdate() and EVP_DigestSignaFinal() return
411 for success and 0 or a negative value for failure. In particular a return
42value of -2 indicates the operation is not supported by the public key
43algorithm.
44
45The error codes can be obtained from L<ERR_get_error(3)|ERR_get_error(3)>.
46
47=head1 NOTES
48
49The B<EVP> interface to digital signatures should almost always be used in
50preference to the low level interfaces. This is because the code then becomes
51transparent to the algorithm used and much more flexible.
52
53In previous versions of OpenSSL there was a link between message digest types
54and public key algorithms. This meant that "clone" digests such as EVP_dss1()
55needed to be used to sign using SHA1 and DSA. This is no longer necessary and
56the use of clone digest is now discouraged.
57
58For some key types and parameters the random number generator must be seeded
59or the operation will fail.
60
61The call to EVP_DigestSignFinal() internally finalizes a copy of the digest
62context. This means that calls to EVP_DigestSignUpdate() and
63EVP_DigestSignFinal() can be called later to digest and sign additional data.
64
65Since only a copy of the digest context is ever finalized the context must
66be cleaned up after use by calling EVP_MD_CTX_cleanup() or a memory leak
67will occur.
68
69The use of EVP_PKEY_size() with these functions is discouraged because some
70signature operations may have a signature length which depends on the
71parameters set. As a result EVP_PKEY_size() would have to return a value
72which indicates the maximum possible signature for any set of parameters.
73
74=head1 SEE ALSO
75
76L<EVP_DigestVerifyInit(3)|EVP_DigestVerifyInit(3)>,
77L<EVP_DigestInit(3)|EVP_DigestInit(3)>, L<err(3)|err(3)>,
78L<evp(3)|evp(3)>, L<hmac(3)|hmac(3)>, L<md2(3)|md2(3)>,
79L<md5(3)|md5(3)>, L<mdc2(3)|mdc2(3)>, L<ripemd(3)|ripemd(3)>,
80L<sha(3)|sha(3)>, L<dgst(1)|dgst(1)>
81
82=head1 HISTORY
83
84EVP_DigestSignInit(), EVP_DigestSignUpdate() and EVP_DigestSignFinal()
85were first added to OpenSSL 1.0.0.
86
87=cut
diff --git a/src/lib/libcrypto/doc/EVP_DigestVerifyInit.pod b/src/lib/libcrypto/doc/EVP_DigestVerifyInit.pod
new file mode 100644
index 0000000000..f224488978
--- /dev/null
+++ b/src/lib/libcrypto/doc/EVP_DigestVerifyInit.pod
@@ -0,0 +1,82 @@
1=pod
2
3=head1 NAME
4
5EVP_DigestVerifyInit, EVP_DigestVerifyUpdate, EVP_DigestVerifyFinal - EVP signature verification functions
6
7=head1 SYNOPSIS
8
9 #include <openssl/evp.h>
10
11 int EVP_DigestVerifyInit(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx,
12 const EVP_MD *type, ENGINE *e, EVP_PKEY *pkey);
13 int EVP_DigestVerifyUpdate(EVP_MD_CTX *ctx, const void *d, unsigned int cnt);
14 int EVP_DigestVerifyFinal(EVP_MD_CTX *ctx, unsigned char *sig, size_t siglen);
15
16=head1 DESCRIPTION
17
18The EVP signature routines are a high level interface to digital signatures.
19
20EVP_DigestVerifyInit() sets up verification context B<ctx> to use digest
21B<type> from ENGINE B<impl> and public key B<pkey>. B<ctx> must be initialized
22with EVP_MD_CTX_init() before calling this function. If B<pctx> is not NULL the
23EVP_PKEY_CTX of the verification operation will be written to B<*pctx>: this
24can be used to set alternative verification options.
25
26EVP_DigestVerifyUpdate() hashes B<cnt> bytes of data at B<d> into the
27verification context B<ctx>. This function can be called several times on the
28same B<ctx> to include additional data. This function is currently implemented
29using a macro.
30
31EVP_DigestVerifyFinal() verifies the data in B<ctx> against the signature in
32B<sig> of length B<siglen>.
33
34=head1 RETURN VALUES
35
36EVP_DigestVerifyInit() and EVP_DigestVerifyUpdate() return 1 for success and 0
37or a negative value for failure. In particular a return value of -2 indicates
38the operation is not supported by the public key algorithm.
39
40Unlike other functions the return value 0 from EVP_DigestVerifyFinal() only
41indicates that the signature did not not verify successfully (that is tbs did
42not match the original data or the signature was of invalid form) it is not an
43indication of a more serious error.
44
45The error codes can be obtained from L<ERR_get_error(3)|ERR_get_error(3)>.
46
47=head1 NOTES
48
49The B<EVP> interface to digital signatures should almost always be used in
50preference to the low level interfaces. This is because the code then becomes
51transparent to the algorithm used and much more flexible.
52
53In previous versions of OpenSSL there was a link between message digest types
54and public key algorithms. This meant that "clone" digests such as EVP_dss1()
55needed to be used to sign using SHA1 and DSA. This is no longer necessary and
56the use of clone digest is now discouraged.
57
58For some key types and parameters the random number generator must be seeded
59or the operation will fail.
60
61The call to EVP_DigestVerifyFinal() internally finalizes a copy of the digest
62context. This means that calls to EVP_VerifyUpdate() and EVP_VerifyFinal() can
63be called later to digest and verify additional data.
64
65Since only a copy of the digest context is ever finalized the context must
66be cleaned up after use by calling EVP_MD_CTX_cleanup() or a memory leak
67will occur.
68
69=head1 SEE ALSO
70
71L<EVP_DigestSignInit(3)|EVP_DigestSignInit(3)>,
72L<EVP_DigestInit(3)|EVP_DigestInit(3)>, L<err(3)|err(3)>,
73L<evp(3)|evp(3)>, L<hmac(3)|hmac(3)>, L<md2(3)|md2(3)>,
74L<md5(3)|md5(3)>, L<mdc2(3)|mdc2(3)>, L<ripemd(3)|ripemd(3)>,
75L<sha(3)|sha(3)>, L<dgst(1)|dgst(1)>
76
77=head1 HISTORY
78
79EVP_DigestVerifyInit(), EVP_DigestVerifyUpdate() and EVP_DigestVerifyFinal()
80were first added to OpenSSL 1.0.0.
81
82=cut
diff --git a/src/lib/libcrypto/doc/EVP_PKEY_CTX_ctrl.pod b/src/lib/libcrypto/doc/EVP_PKEY_CTX_ctrl.pod
new file mode 100644
index 0000000000..f2f455990f
--- /dev/null
+++ b/src/lib/libcrypto/doc/EVP_PKEY_CTX_ctrl.pod
@@ -0,0 +1,128 @@
1=pod
2
3=head1 NAME
4
5EVP_PKEY_ctrl, EVP_PKEY_ctrl_str - algorithm specific control operations
6
7=head1 SYNOPSIS
8
9 #include <openssl/evp.h>
10
11 int EVP_PKEY_CTX_ctrl(EVP_PKEY_CTX *ctx, int keytype, int optype,
12 int cmd, int p1, void *p2);
13 int EVP_PKEY_CTX_ctrl_str(EVP_PKEY_CTX *ctx, const char *type,
14 const char *value);
15
16 int EVP_PKEY_get_default_digest_nid(EVP_PKEY *pkey, int *pnid);
17
18 #include <openssl/rsa.h>
19
20 int EVP_PKEY_CTX_set_signature_md(EVP_PKEY_CTX *ctx, const EVP_MD *md);
21
22 int EVP_PKEY_CTX_set_rsa_padding(EVP_PKEY_CTX *ctx, int pad);
23 int EVP_PKEY_CTX_set_rsa_pss_saltlen(EVP_PKEY_CTX *ctx, int len);
24 int EVP_PKEY_CTX_set_rsa_rsa_keygen_bits(EVP_PKEY_CTX *ctx, int mbits);
25 int EVP_PKEY_CTX_set_rsa_keygen_pubexp(EVP_PKEY_CTX *ctx, BIGNUM *pubexp);
26
27 #include <openssl/dsa.h>
28 int EVP_PKEY_CTX_set_dsa_paramgen_bits(EVP_PKEY_CTX *ctx, int nbits);
29
30 #include <openssl/dh.h>
31 int EVP_PKEY_CTX_set_dh_paramgen_prime_len(EVP_PKEY_CTX *ctx, int len);
32 int EVP_PKEY_CTX_set_dh_paramgen_generator(EVP_PKEY_CTX *ctx, int gen);
33
34 #include <openssl/ec.h>
35 int EVP_PKEY_CTX_set_ec_paramgen_curve_nid(EVP_PKEY_CTX *ctx, int nid);
36
37=head1 DESCRIPTION
38
39The function EVP_PKEY_CTX_ctrl() sends a control operation to the context
40B<ctx>. The key type used must match B<keytype> if it is not -1. The parameter
41B<optype> is a mask indicating which operations the control can be applied to.
42The control command is indicated in B<cmd> and any additional arguments in
43B<p1> and B<p2>.
44
45Applications will not normally call EVP_PKEY_CTX_ctrl() directly but will
46instead call one of the algorithm specific macros below.
47
48The function EVP_PKEY_ctrl_str() allows an application to send an algorithm
49specific control operation to a context B<ctx> in string form. This is
50intended to be used for options specified on the command line or in text
51files. The commands supported are documented in the openssl utility
52command line pages for the option B<-pkeyopt> which is supported by the
53B<pkeyutl>, B<genpkey> and B<req> commands.
54
55All the remaining "functions" are implemented as macros.
56
57The EVP_PKEY_CTX_set_signature_md() macro sets the message digest type used
58in a signature. It can be used with any public key algorithm supporting
59signature operations.
60
61The macro EVP_PKEY_CTX_set_rsa_padding() sets the RSA padding mode for B<ctx>.
62The B<pad> parameter can take the value RSA_PKCS1_PADDING for PKCS#1 padding,
63RSA_SSLV23_PADDING for SSLv23 padding, RSA_NO_PADDING for no padding,
64RSA_PKCS1_OAEP_PADDING for OAEP padding (encrypt and decrypt only),
65RSA_X931_PADDING for X9.31 padding (signature operations only) and
66RSA_PKCS1_PSS_PADDING (sign and verify only).
67
68Two RSA padding modes behave differently if EVP_PKEY_CTX_set_signature_md()
69is used. If this macro is called for PKCS#1 padding the plaintext buffer is
70an actual digest value and is encapsulated in a DigestInfo structure according
71to PKCS#1 when signing and this structure is expected (and stripped off) when
72verifying. If this control is not used with RSA and PKCS#1 padding then the
73supplied data is used directly and not encapsulated. In the case of X9.31
74padding for RSA the algorithm identifier byte is added or checked and removed
75if this control is called. If it is not called then the first byte of the plaintext buffer is expected to be the algorithm identifier byte.
76
77The EVP_PKEY_CTX_set_rsa_pss_saltlen() macro sets the RSA PSS salt length to
78B<len> as its name implies it is only supported for PSS padding. Two special
79values are supported: -1 sets the salt length to the digest length. When
80signing -2 sets the salt length to the maximum permissible value. When
81verifying -2 causes the salt length to be automatically determined based on the
82B<PSS> block structure. If this macro is not called a salt length value of -2
83is used by default.
84
85The EVP_PKEY_CTX_set_rsa_rsa_keygen_bits() macro sets the RSA key length for
86RSA key genration to B<bits>. If not specified 1024 bits is used.
87
88The EVP_PKEY_CTX_set_rsa_keygen_pubexp() macro sets the public exponent value
89for RSA key generation to B<pubexp> currently it should be an odd integer. The
90B<pubexp> pointer is used internally by this function so it should not be
91modified or free after the call. If this macro is not called then 65537 is used.
92
93The macro EVP_PKEY_CTX_set_dsa_paramgen_bits() sets the number of bits used
94for DSA parameter generation to B<bits>. If not specified 1024 is used.
95
96The macro EVP_PKEY_CTX_set_dh_paramgen_prime_len() sets the length of the DH
97prime parameter B<p> for DH parameter generation. If this macro is not called
98then 1024 is used.
99
100The EVP_PKEY_CTX_set_dh_paramgen_generator() macro sets DH generator to B<gen>
101for DH parameter generation. If not specified 2 is used.
102
103The EVP_PKEY_CTX_set_ec_paramgen_curve_nid() sets the EC curve for EC parameter
104generation to B<nid>. For EC parameter generation this macro must be called
105or an error occurs because there is no default curve.
106
107=head1 RETURN VALUES
108
109EVP_PKEY_CTX_ctrl() and its macros return a positive value for success and 0
110or a negative value for failure. In particular a return value of -2
111indicates the operation is not supported by the public key algorithm.
112
113=head1 SEE ALSO
114
115L<EVP_PKEY_CTX_new(3)|EVP_PKEY_CTX_new(3)>,
116L<EVP_PKEY_encrypt(3)|EVP_PKEY_encrypt(3)>,
117L<EVP_PKEY_decrypt(3)|EVP_PKEY_decrypt(3)>,
118L<EVP_PKEY_sign(3)|EVP_PKEY_sign(3)>,
119L<EVP_PKEY_verify(3)|EVP_PKEY_verify(3)>,
120L<EVP_PKEY_verifyrecover(3)|EVP_PKEY_verifyrecover(3)>,
121L<EVP_PKEY_derive(3)|EVP_PKEY_derive(3)>
122L<EVP_PKEY_keygen(3)|EVP_PKEY_keygen(3)>
123
124=head1 HISTORY
125
126These functions were first added to OpenSSL 1.0.0.
127
128=cut
diff --git a/src/lib/libcrypto/doc/EVP_PKEY_CTX_new.pod b/src/lib/libcrypto/doc/EVP_PKEY_CTX_new.pod
new file mode 100644
index 0000000000..a9af867580
--- /dev/null
+++ b/src/lib/libcrypto/doc/EVP_PKEY_CTX_new.pod
@@ -0,0 +1,52 @@
1=pod
2
3=head1 NAME
4
5EVP_PKEY_CTX_new, EVP_PKEY_CTX_new_id, EVP_PKEY_CTX_dup, EVP_PKEY_CTX_free - public key algorithm context functions.
6
7=head1 SYNOPSIS
8
9 #include <openssl/evp.h>
10
11 EVP_PKEY_CTX *EVP_PKEY_CTX_new(EVP_PKEY *pkey, ENGINE *e);
12 EVP_PKEY_CTX *EVP_PKEY_CTX_new_id(int id, ENGINE *e);
13 EVP_PKEY_CTX *EVP_PKEY_CTX_dup(EVP_PKEY_CTX *ctx);
14 void EVP_PKEY_CTX_free(EVP_PKEY_CTX *ctx);
15
16=head1 DESCRIPTION
17
18The EVP_PKEY_CTX_new() function allocates public key algorithm context using
19the algorithm specified in B<pkey> and ENGINE B<e>.
20
21The EVP_PKEY_CTX_new_id() function allocates public key algorithm context
22using the algorithm specified by B<id> and ENGINE B<e>. It is normally used
23when no B<EVP_PKEY> structure is associated with the operations, for example
24during parameter generation of key genration for some algorithms.
25
26EVP_PKEY_CTX_dup() duplicates the context B<ctx>.
27
28EVP_PKEY_CTX_free() frees up the context B<ctx>.
29
30=head1 NOTES
31
32The B<EVP_PKEY_CTX> structure is an opaque public key algorithm context used
33by the OpenSSL high level public key API. Contexts B<MUST NOT> be shared between
34threads: that is it is not permissible to use the same context simultaneously
35in two threads.
36
37=head1 RETURN VALUES
38
39EVP_PKEY_CTX_new(), EVP_PKEY_CTX_new_id(), EVP_PKEY_CTX_dup() returns either
40the newly allocated B<EVP_PKEY_CTX> structure of B<NULL> if an error occurred.
41
42EVP_PKEY_CTX_free() does not return a value.
43
44=head1 SEE ALSO
45
46L<EVP_PKEY_new(3)|EVP_PKEY_new(3)>
47
48=head1 HISTORY
49
50These functions were first added to OpenSSL 1.0.0.
51
52=cut
diff --git a/src/lib/libcrypto/doc/EVP_PKEY_cmp.pod b/src/lib/libcrypto/doc/EVP_PKEY_cmp.pod
new file mode 100644
index 0000000000..4f8185e36c
--- /dev/null
+++ b/src/lib/libcrypto/doc/EVP_PKEY_cmp.pod
@@ -0,0 +1,61 @@
1=pod
2
3=head1 NAME
4
5EVP_PKEY_copy_parameters, EVP_PKEY_missing_parameters, EVP_PKEY_cmp_parameters, EVP_PKEY_cmp - public key parameter and comparison functions
6
7=head1 SYNOPSIS
8
9 #include <openssl/evp.h>
10
11 int EVP_PKEY_missing_parameters(const EVP_PKEY *pkey);
12 int EVP_PKEY_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from);
13
14 int EVP_PKEY_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b);
15 int EVP_PKEY_cmp(const EVP_PKEY *a, const EVP_PKEY *b);
16
17=head1 DESCRIPTION
18
19The function EVP_PKEY_missing_parameters() returns 1 if the public key
20parameters of B<pkey> are missing and 0 if they are present or the algorithm
21doesn't use parameters.
22
23The function EVP_PKEY_copy_parameters() copies the parameters from key
24B<from> to key B<to>.
25
26The funcion EVP_PKEY_cmp_parameters() compares the parameters of keys
27B<a> and B<b>.
28
29The funcion EVP_PKEY_cmp() compares the public key components and paramters
30(if present) of keys B<a> and B<b>.
31
32=head1 NOTES
33
34The main purpose of the functions EVP_PKEY_missing_parameters() and
35EVP_PKEY_copy_parameters() is to handle public keys in certificates where the
36parameters are sometimes omitted from a public key if they are inherited from
37the CA that signed it.
38
39Since OpenSSL private keys contain public key components too the function
40EVP_PKEY_cmp() can also be used to determine if a private key matches
41a public key.
42
43=head1 RETURN VALUES
44
45The function EVP_PKEY_missing_parameters() returns 1 if the public key
46parameters of B<pkey> are missing and 0 if they are present or the algorithm
47doesn't use parameters.
48
49These functions EVP_PKEY_copy_parameters() returns 1 for success and 0 for
50failure.
51
52The function EVP_PKEY_cmp_parameters() and EVP_PKEY_cmp() return 1 if the
53keys match, 0 if they don't match, -1 if the key types are different and
54-2 if the operation is not supported.
55
56=head1 SEE ALSO
57
58L<EVP_PKEY_CTX_new(3)|EVP_PKEY_CTX_new(3)>,
59L<EVP_PKEY_keygen(3)|EVP_PKEY_keygen(3)>
60
61=cut
diff --git a/src/lib/libcrypto/doc/EVP_PKEY_decrypt.pod b/src/lib/libcrypto/doc/EVP_PKEY_decrypt.pod
new file mode 100644
index 0000000000..42b2a8c44e
--- /dev/null
+++ b/src/lib/libcrypto/doc/EVP_PKEY_decrypt.pod
@@ -0,0 +1,93 @@
1=pod
2
3=head1 NAME
4
5EVP_PKEY_decrypt_init, EVP_PKEY_decrypt - decrypt using a public key algorithm
6
7=head1 SYNOPSIS
8
9 #include <openssl/evp.h>
10
11 int EVP_PKEY_decrypt_init(EVP_PKEY_CTX *ctx);
12 int EVP_PKEY_decrypt(EVP_PKEY_CTX *ctx,
13 unsigned char *out, size_t *outlen,
14 const unsigned char *in, size_t inlen);
15
16=head1 DESCRIPTION
17
18The EVP_PKEY_decrypt_init() function initializes a public key algorithm
19context using key B<pkey> for a decryption operation.
20
21The EVP_PKEY_decrypt() function performs a public key decryption operation
22using B<ctx>. The data to be decrypted is specified using the B<in> and
23B<inlen> parameters. If B<out> is B<NULL> then the maximum size of the output
24buffer is written to the B<outlen> parameter. If B<out> is not B<NULL> then
25before the call the B<outlen> parameter should contain the length of the
26B<out> buffer, if the call is successful the decrypted data is written to
27B<out> and the amount of data written to B<outlen>.
28
29=head1 NOTES
30
31After the call to EVP_PKEY_decrypt_init() algorithm specific control
32operations can be performed to set any appropriate parameters for the
33operation.
34
35The function EVP_PKEY_decrypt() can be called more than once on the same
36context if several operations are performed using the same parameters.
37
38=head1 RETURN VALUES
39
40EVP_PKEY_decrypt_init() and EVP_PKEY_decrypt() return 1 for success and 0
41or a negative value for failure. In particular a return value of -2
42indicates the operation is not supported by the public key algorithm.
43
44=head1 EXAMPLE
45
46Decrypt data using OAEP (for RSA keys):
47
48 #include <openssl/evp.h>
49 #include <openssl/rsa.h>
50
51 EVP_PKEY_CTX *ctx;
52 unsigned char *out, *in;
53 size_t outlen, inlen;
54 EVP_PKEY *key;
55 /* NB: assumes key in, inlen are already set up
56 * and that key is an RSA private key
57 */
58 ctx = EVP_PKEY_CTX_new(key);
59 if (!ctx)
60 /* Error occurred */
61 if (EVP_PKEY_decrypt_init(ctx) <= 0)
62 /* Error */
63 if (EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_OAEP_PADDING) <= 0)
64 /* Error */
65
66 /* Determine buffer length */
67 if (EVP_PKEY_decrypt(ctx, NULL, &outlen, in, inlen) <= 0)
68 /* Error */
69
70 out = OPENSSL_malloc(outlen);
71
72 if (!out)
73 /* malloc failure */
74
75 if (EVP_PKEY_decrypt(ctx, out, &outlen, in, inlen) <= 0)
76 /* Error */
77
78 /* Decrypted data is outlen bytes written to buffer out */
79
80=head1 SEE ALSO
81
82L<EVP_PKEY_CTX_new(3)|EVP_PKEY_CTX_new(3)>,
83L<EVP_PKEY_encrypt(3)|EVP_PKEY_encrypt(3)>,
84L<EVP_PKEY_sign(3)|EVP_PKEY_sign(3)>,
85L<EVP_PKEY_verify(3)|EVP_PKEY_verify(3)>,
86L<EVP_PKEY_verifyrecover(3)|EVP_PKEY_verifyrecover(3)>,
87L<EVP_PKEY_derive(3)|EVP_PKEY_derive(3)>
88
89=head1 HISTORY
90
91These functions were first added to OpenSSL 1.0.0.
92
93=cut
diff --git a/src/lib/libcrypto/doc/EVP_PKEY_derive.pod b/src/lib/libcrypto/doc/EVP_PKEY_derive.pod
new file mode 100644
index 0000000000..d9d6d76c72
--- /dev/null
+++ b/src/lib/libcrypto/doc/EVP_PKEY_derive.pod
@@ -0,0 +1,93 @@
1=pod
2
3=head1 NAME
4
5EVP_PKEY_derive_init, EVP_PKEY_derive_set_peer, EVP_PKEY_derive - derive public key algorithm shared secret.
6
7=head1 SYNOPSIS
8
9 #include <openssl/evp.h>
10
11 int EVP_PKEY_derive_init(EVP_PKEY_CTX *ctx);
12 int EVP_PKEY_derive_set_peer(EVP_PKEY_CTX *ctx, EVP_PKEY *peer);
13 int EVP_PKEY_derive(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen);
14
15=head1 DESCRIPTION
16
17The EVP_PKEY_derive_init() function initializes a public key algorithm
18context using key B<pkey> for shared secret derivation.
19
20The EVP_PKEY_derive_set_peer() function sets the peer key: this will normally
21be a public key.
22
23The EVP_PKEY_derive() derives a shared secret using B<ctx>.
24If B<key> is B<NULL> then the maximum size of the output buffer is written to
25the B<keylen> parameter. If B<key> is not B<NULL> then before the call the
26B<keylen> parameter should contain the length of the B<key> buffer, if the call
27is successful the shared secret is written to B<key> and the amount of data
28written to B<keylen>.
29
30=head1 NOTES
31
32After the call to EVP_PKEY_derive_init() algorithm specific control
33operations can be performed to set any appropriate parameters for the
34operation.
35
36The function EVP_PKEY_derive() can be called more than once on the same
37context if several operations are performed using the same parameters.
38
39=head1 RETURN VALUES
40
41EVP_PKEY_derive_init() and EVP_PKEY_derive() return 1 for success and 0
42or a negative value for failure. In particular a return value of -2
43indicates the operation is not supported by the public key algorithm.
44
45=head1 EXAMPLE
46
47Derive shared secret (for example DH or EC keys):
48
49 #include <openssl/evp.h>
50 #include <openssl/rsa.h>
51
52 EVP_PKEY_CTX *ctx;
53 unsigned char *skey;
54 size_t skeylen;
55 EVP_PKEY *pkey, *peerkey;
56 /* NB: assumes pkey, peerkey have been already set up */
57
58 ctx = EVP_PKEY_CTX_new(pkey);
59 if (!ctx)
60 /* Error occurred */
61 if (EVP_PKEY_derive_init(ctx) <= 0)
62 /* Error */
63 if (EVP_PKEY_derive_set_peer(ctx, peerkey) <= 0)
64 /* Error */
65
66 /* Determine buffer length */
67 if (EVP_PKEY_derive(ctx, NULL, &skeylen) <= 0)
68 /* Error */
69
70 skey = OPENSSL_malloc(skeylen);
71
72 if (!skey)
73 /* malloc failure */
74
75 if (EVP_PKEY_derive(ctx, skey, &skeylen) <= 0)
76 /* Error */
77
78 /* Shared secret is skey bytes written to buffer skey */
79
80=head1 SEE ALSO
81
82L<EVP_PKEY_CTX_new(3)|EVP_PKEY_CTX_new(3)>,
83L<EVP_PKEY_encrypt(3)|EVP_PKEY_encrypt(3)>,
84L<EVP_PKEY_decrypt(3)|EVP_PKEY_decrypt(3)>,
85L<EVP_PKEY_sign(3)|EVP_PKEY_sign(3)>,
86L<EVP_PKEY_verify(3)|EVP_PKEY_verify(3)>,
87L<EVP_PKEY_verifyrecover(3)|EVP_PKEY_verifyrecover(3)>,
88
89=head1 HISTORY
90
91These functions were first added to OpenSSL 1.0.0.
92
93=cut
diff --git a/src/lib/libcrypto/doc/EVP_PKEY_encrypt.pod b/src/lib/libcrypto/doc/EVP_PKEY_encrypt.pod
new file mode 100644
index 0000000000..91c9c5d0a5
--- /dev/null
+++ b/src/lib/libcrypto/doc/EVP_PKEY_encrypt.pod
@@ -0,0 +1,93 @@
1=pod
2
3=head1 NAME
4
5EVP_PKEY_encrypt_init, EVP_PKEY_encrypt - encrypt using a public key algorithm
6
7=head1 SYNOPSIS
8
9 #include <openssl/evp.h>
10
11 int EVP_PKEY_encrypt_init(EVP_PKEY_CTX *ctx);
12 int EVP_PKEY_encrypt(EVP_PKEY_CTX *ctx,
13 unsigned char *out, size_t *outlen,
14 const unsigned char *in, size_t inlen);
15
16=head1 DESCRIPTION
17
18The EVP_PKEY_encrypt_init() function initializes a public key algorithm
19context using key B<pkey> for an encryption operation.
20
21The EVP_PKEY_encrypt() function performs a public key encryption operation
22using B<ctx>. The data to be encrypted is specified using the B<in> and
23B<inlen> parameters. If B<out> is B<NULL> then the maximum size of the output
24buffer is written to the B<outlen> parameter. If B<out> is not B<NULL> then
25before the call the B<outlen> parameter should contain the length of the
26B<out> buffer, if the call is successful the encrypted data is written to
27B<out> and the amount of data written to B<outlen>.
28
29=head1 NOTES
30
31After the call to EVP_PKEY_encrypt_init() algorithm specific control
32operations can be performed to set any appropriate parameters for the
33operation.
34
35The function EVP_PKEY_encrypt() can be called more than once on the same
36context if several operations are performed using the same parameters.
37
38=head1 RETURN VALUES
39
40EVP_PKEY_encrypt_init() and EVP_PKEY_encrypt() return 1 for success and 0
41or a negative value for failure. In particular a return value of -2
42indicates the operation is not supported by the public key algorithm.
43
44=head1 EXAMPLE
45
46Encrypt data using OAEP (for RSA keys):
47
48 #include <openssl/evp.h>
49 #include <openssl/rsa.h>
50
51 EVP_PKEY_CTX *ctx;
52 unsigned char *out, *in;
53 size_t outlen, inlen;
54 EVP_PKEY *key;
55 /* NB: assumes key in, inlen are already set up
56 * and that key is an RSA public key
57 */
58 ctx = EVP_PKEY_CTX_new(key);
59 if (!ctx)
60 /* Error occurred */
61 if (EVP_PKEY_encrypt_init(ctx) <= 0)
62 /* Error */
63 if (EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_OAEP_PADDING) <= 0)
64 /* Error */
65
66 /* Determine buffer length */
67 if (EVP_PKEY_encrypt(ctx, NULL, &outlen, in, inlen) <= 0)
68 /* Error */
69
70 out = OPENSSL_malloc(outlen);
71
72 if (!out)
73 /* malloc failure */
74
75 if (EVP_PKEY_encrypt(ctx, out, &outlen, in, inlen) <= 0)
76 /* Error */
77
78 /* Encrypted data is outlen bytes written to buffer out */
79
80=head1 SEE ALSO
81
82L<EVP_PKEY_CTX_new(3)|EVP_PKEY_CTX_new(3)>,
83L<EVP_PKEY_decrypt(3)|EVP_PKEY_decrypt(3)>,
84L<EVP_PKEY_sign(3)|EVP_PKEY_sign(3)>,
85L<EVP_PKEY_verify(3)|EVP_PKEY_verify(3)>,
86L<EVP_PKEY_verifyrecover(3)|EVP_PKEY_verifyrecover(3)>,
87L<EVP_PKEY_derive(3)|EVP_PKEY_derive(3)>
88
89=head1 HISTORY
90
91These functions were first added to OpenSSL 1.0.0.
92
93=cut
diff --git a/src/lib/libcrypto/doc/EVP_PKEY_get_default_digest.pod b/src/lib/libcrypto/doc/EVP_PKEY_get_default_digest.pod
new file mode 100644
index 0000000000..1a9c7954c5
--- /dev/null
+++ b/src/lib/libcrypto/doc/EVP_PKEY_get_default_digest.pod
@@ -0,0 +1,41 @@
1=pod
2
3=head1 NAME
4
5EVP_PKEY_get_default_digest_nid - get default signature digest
6
7=head1 SYNOPSIS
8
9 #include <openssl/evp.h>
10 int EVP_PKEY_get_default_digest_nid(EVP_PKEY *pkey, int *pnid);
11
12=head1 DESCRIPTION
13
14The EVP_PKEY_get_default_digest_nid() function sets B<pnid> to the default
15message digest NID for the public key signature operations associated with key
16B<pkey>.
17
18=head1 NOTES
19
20For all current standard OpenSSL public key algorithms SHA1 is returned.
21
22=head1 RETURN VALUES
23
24The EVP_PKEY_get_default_digest_nid() function returns 1 if the message digest
25is advisory (that is other digests can be used) and 2 if it is mandatory (other
26digests can not be used). It returns 0 or a negative value for failure. In
27particular a return value of -2 indicates the operation is not supported by the
28public key algorithm.
29
30=head1 SEE ALSO
31
32L<EVP_PKEY_CTX_new(3)|EVP_PKEY_CTX_new(3)>,
33L<EVP_PKEY_sign(3)|EVP_PKEY_sign(3)>,
34L<EVP_PKEY_verify(3)|EVP_PKEY_verify(3)>,
35L<EVP_PKEY_verifyrecover(3)|EVP_PKEY_verifyrecover(3)>,
36
37=head1 HISTORY
38
39This function was first added to OpenSSL 1.0.0.
40
41=cut
diff --git a/src/lib/libcrypto/doc/EVP_PKEY_keygen.pod b/src/lib/libcrypto/doc/EVP_PKEY_keygen.pod
new file mode 100644
index 0000000000..37c6fe9503
--- /dev/null
+++ b/src/lib/libcrypto/doc/EVP_PKEY_keygen.pod
@@ -0,0 +1,161 @@
1=pod
2
3=head1 NAME
4
5EVP_PKEY_keygen_init, EVP_PKEY_keygen, EVP_PKEY_paramgen_init, EVP_PKEY_paramgen, EVP_PKEY_CTX_set_cb, EVP_PKEY_CTX_get_cb, EVP_PKEY_CTX_get_keygen_info, EVP_PKEVP_PKEY_CTX_set_app_data, EVP_PKEY_CTX_get_app_data - key and parameter generation functions
6
7=head1 SYNOPSIS
8
9 #include <openssl/evp.h>
10
11 int EVP_PKEY_keygen_init(EVP_PKEY_CTX *ctx);
12 int EVP_PKEY_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey);
13 int EVP_PKEY_paramgen_init(EVP_PKEY_CTX *ctx);
14 int EVP_PKEY_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey);
15
16 typedef int EVP_PKEY_gen_cb(EVP_PKEY_CTX *ctx);
17
18 void EVP_PKEY_CTX_set_cb(EVP_PKEY_CTX *ctx, EVP_PKEY_gen_cb *cb);
19 EVP_PKEY_gen_cb *EVP_PKEY_CTX_get_cb(EVP_PKEY_CTX *ctx);
20
21 int EVP_PKEY_CTX_get_keygen_info(EVP_PKEY_CTX *ctx, int idx);
22
23 void EVP_PKEY_CTX_set_app_data(EVP_PKEY_CTX *ctx, void *data);
24 void *EVP_PKEY_CTX_get_app_data(EVP_PKEY_CTX *ctx);
25
26=head1 DESCRIPTION
27
28The EVP_PKEY_keygen_init() function initializes a public key algorithm
29context using key B<pkey> for a key genration operation.
30
31The EVP_PKEY_keygen() function performs a key generation operation, the
32generated key is written to B<ppkey>.
33
34The functions EVP_PKEY_paramgen_init() and EVP_PKEY_paramgen() are similar
35except parameters are generated.
36
37The function EVP_PKEY_set_cb() sets the key or parameter generation callback
38to B<cb>. The function EVP_PKEY_CTX_get_cb() returns the key or parameter
39generation callback.
40
41The function EVP_PKEY_CTX_get_keygen_info() returns parameters associated
42with the generation operation. If B<idx> is -1 the total number of
43parameters available is returned. Any non negative value returns the value of
44that parameter. EVP_PKEY_CTX_gen_keygen_info() with a non-negative value for
45B<idx> should only be called within the generation callback.
46
47If the callback returns 0 then the key genration operation is aborted and an
48error occurs. This might occur during a time consuming operation where
49a user clicks on a "cancel" button.
50
51The functions EVP_PKEY_CTX_set_app_data() and EVP_PKEY_CTX_get_app_data() set
52and retrieve an opaque pointer. This can be used to set some application
53defined value which can be retrieved in the callback: for example a handle
54which is used to update a "progress dialog".
55
56=head1 NOTES
57
58After the call to EVP_PKEY_keygen_init() or EVP_PKEY_paramgen_init() algorithm
59specific control operations can be performed to set any appropriate parameters
60for the operation.
61
62The functions EVP_PKEY_keygen() and EVP_PKEY_paramgen() can be called more than
63once on the same context if several operations are performed using the same
64parameters.
65
66The meaning of the parameters passed to the callback will depend on the
67algorithm and the specifiic implementation of the algorithm. Some might not
68give any useful information at all during key or parameter generation. Others
69might not even call the callback.
70
71The operation performed by key or parameter generation depends on the algorithm
72used. In some cases (e.g. EC with a supplied named curve) the "generation"
73option merely sets the appropriate fields in an EVP_PKEY structure.
74
75In OpenSSL an EVP_PKEY structure containing a private key also contains the
76public key components and parameters (if any). An OpenSSL private key is
77equivalent to what some libraries call a "key pair". A private key can be used
78in functions which require the use of a public key or parameters.
79
80=head1 RETURN VALUES
81
82EVP_PKEY_keygen_init(), EVP_PKEY_paramgen_init(), EVP_PKEY_keygen() and
83EVP_PKEY_paramgen() return 1 for success and 0 or a negative value for failure.
84In particular a return value of -2 indicates the operation is not supported by
85the public key algorithm.
86
87=head1 EXAMPLES
88
89Generate a 2048 bit RSA key:
90
91 #include <openssl/evp.h>
92 #include <openssl/rsa.h>
93
94 EVP_PKEY_CTX *ctx;
95 EVP_PKEY *pkey = NULL;
96 ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_RSA, NULL);
97 if (!ctx)
98 /* Error occurred */
99 if (EVP_PKEY_keygen_init(ctx) <= 0)
100 /* Error */
101 if (EVP_PKEY_CTX_set_rsa_keygen_bits(ctx, 2048) <= 0)
102 /* Error */
103
104 /* Generate key */
105 if (EVP_PKEY_keygen(ctx, &pkey) <= 0)
106 /* Error */
107
108Generate a key from a set of parameters:
109
110 #include <openssl/evp.h>
111 #include <openssl/rsa.h>
112
113 EVP_PKEY_CTX *ctx;
114 EVP_PKEY *pkey = NULL, *param;
115 /* Assumed param is set up already */
116 ctx = EVP_PKEY_CTX_new(param);
117 if (!ctx)
118 /* Error occurred */
119 if (EVP_PKEY_keygen_init(ctx) <= 0)
120 /* Error */
121
122 /* Generate key */
123 if (EVP_PKEY_keygen(ctx, &pkey) <= 0)
124 /* Error */
125
126Example of generation callback for OpenSSL public key implementations:
127
128 /* Application data is a BIO to output status to */
129
130 EVP_PKEY_CTX_set_app_data(ctx, status_bio);
131
132 static int genpkey_cb(EVP_PKEY_CTX *ctx)
133 {
134 char c='*';
135 BIO *b = EVP_PKEY_CTX_get_app_data(ctx);
136 int p;
137 p = EVP_PKEY_CTX_get_keygen_info(ctx, 0);
138 if (p == 0) c='.';
139 if (p == 1) c='+';
140 if (p == 2) c='*';
141 if (p == 3) c='\n';
142 BIO_write(b,&c,1);
143 (void)BIO_flush(b);
144 return 1;
145 }
146
147=head1 SEE ALSO
148
149L<EVP_PKEY_CTX_new(3)|EVP_PKEY_CTX_new(3)>,
150L<EVP_PKEY_encrypt(3)|EVP_PKEY_encrypt(3)>,
151L<EVP_PKEY_decrypt(3)|EVP_PKEY_decrypt(3)>,
152L<EVP_PKEY_sign(3)|EVP_PKEY_sign(3)>,
153L<EVP_PKEY_verify(3)|EVP_PKEY_verify(3)>,
154L<EVP_PKEY_verifyrecover(3)|EVP_PKEY_verifyrecover(3)>,
155L<EVP_PKEY_derive(3)|EVP_PKEY_derive(3)>
156
157=head1 HISTORY
158
159These functions were first added to OpenSSL 1.0.0.
160
161=cut
diff --git a/src/lib/libcrypto/doc/EVP_PKEY_print_private.pod b/src/lib/libcrypto/doc/EVP_PKEY_print_private.pod
new file mode 100644
index 0000000000..ce9d70d7a7
--- /dev/null
+++ b/src/lib/libcrypto/doc/EVP_PKEY_print_private.pod
@@ -0,0 +1,53 @@
1=pod
2
3=head1 NAME
4
5EVP_PKEY_print_public, EVP_PKEY_print_private, EVP_PKEY_print_params - public key algorithm printing routines.
6
7=head1 SYNOPSIS
8
9 #include <openssl/evp.h>
10
11 int EVP_PKEY_print_public(BIO *out, const EVP_PKEY *pkey,
12 int indent, ASN1_PCTX *pctx);
13 int EVP_PKEY_print_private(BIO *out, const EVP_PKEY *pkey,
14 int indent, ASN1_PCTX *pctx);
15 int EVP_PKEY_print_params(BIO *out, const EVP_PKEY *pkey,
16 int indent, ASN1_PCTX *pctx);
17
18=head1 DESCRIPTION
19
20The functions EVP_PKEY_print_public(), EVP_PKEY_print_private() and
21EVP_PKEY_print_params() print out the public, private or parameter components
22of key B<pkey> respectively. The key is sent to BIO B<out> in human readable
23form. The parameter B<indent> indicated how far the printout should be indented.
24
25The B<pctx> parameter allows the print output to be finely tuned by using
26ASN1 printing options. If B<pctx> is set to NULL then default values will
27be used.
28
29=head1 NOTES
30
31Currently no public key algorithms include any options in the B<pctx> parameter
32parameter.
33
34If the key does not include all the components indicated by the function then
35only those contained in the key will be printed. For example passing a public
36key to EVP_PKEY_print_private() will only print the public components.
37
38=head1 RETURN VALUES
39
40These functions all return 1 for success and 0 or a negative value for failure.
41In particular a return value of -2 indicates the operation is not supported by
42the public key algorithm.
43
44=head1 SEE ALSO
45
46L<EVP_PKEY_CTX_new(3)|EVP_PKEY_CTX_new(3)>,
47L<EVP_PKEY_keygen(3)|EVP_PKEY_keygen(3)>
48
49=head1 HISTORY
50
51These functions were first added to OpenSSL 1.0.0.
52
53=cut
diff --git a/src/lib/libcrypto/doc/EVP_PKEY_sign.pod b/src/lib/libcrypto/doc/EVP_PKEY_sign.pod
new file mode 100644
index 0000000000..2fb52c3486
--- /dev/null
+++ b/src/lib/libcrypto/doc/EVP_PKEY_sign.pod
@@ -0,0 +1,96 @@
1=pod
2
3=head1 NAME
4
5EVP_PKEY_sign_init, EVP_PKEY_sign - sign using a public key algorithm
6
7=head1 SYNOPSIS
8
9 #include <openssl/evp.h>
10
11 int EVP_PKEY_sign_init(EVP_PKEY_CTX *ctx);
12 int EVP_PKEY_sign(EVP_PKEY_CTX *ctx,
13 unsigned char *sig, size_t *siglen,
14 const unsigned char *tbs, size_t tbslen);
15
16=head1 DESCRIPTION
17
18The EVP_PKEY_sign_init() function initializes a public key algorithm
19context using key B<pkey> for a signing operation.
20
21The EVP_PKEY_sign() function performs a public key signing operation
22using B<ctx>. The data to be signed is specified using the B<tbs> and
23B<tbslen> parameters. If B<sig> is B<NULL> then the maximum size of the output
24buffer is written to the B<siglen> parameter. If B<sig> is not B<NULL> then
25before the call the B<siglen> parameter should contain the length of the
26B<sig> buffer, if the call is successful the signature is written to
27B<sig> and the amount of data written to B<siglen>.
28
29=head1 NOTES
30
31After the call to EVP_PKEY_sign_init() algorithm specific control
32operations can be performed to set any appropriate parameters for the
33operation.
34
35The function EVP_PKEY_sign() can be called more than once on the same
36context if several operations are performed using the same parameters.
37
38=head1 RETURN VALUES
39
40EVP_PKEY_sign_init() and EVP_PKEY_sign() return 1 for success and 0
41or a negative value for failure. In particular a return value of -2
42indicates the operation is not supported by the public key algorithm.
43
44=head1 EXAMPLE
45
46Sign data using RSA with PKCS#1 padding and SHA256 digest:
47
48 #include <openssl/evp.h>
49 #include <openssl/rsa.h>
50
51 EVP_PKEY_CTX *ctx;
52 unsigned char *md, *sig;
53 size_t mdlen, siglen;
54 EVP_PKEY *signing_key;
55 /* NB: assumes signing_key, md and mdlen are already set up
56 * and that signing_key is an RSA private key
57 */
58 ctx = EVP_PKEY_CTX_new(signing_key);
59 if (!ctx)
60 /* Error occurred */
61 if (EVP_PKEY_sign_init(ctx) <= 0)
62 /* Error */
63 if (EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_PADDING) <= 0)
64 /* Error */
65 if (EVP_PKEY_CTX_set_signature_md(ctx, EVP_sha256()) <= 0)
66 /* Error */
67
68 /* Determine buffer length */
69 if (EVP_PKEY_sign(ctx, NULL, &siglen, md, mdlen) <= 0)
70 /* Error */
71
72 sig = OPENSSL_malloc(siglen);
73
74 if (!sig)
75 /* malloc failure */
76
77 if (EVP_PKEY_sign(ctx, sig, &siglen, md, mdlen) <= 0)
78 /* Error */
79
80 /* Signature is siglen bytes written to buffer sig */
81
82
83=head1 SEE ALSO
84
85L<EVP_PKEY_CTX_new(3)|EVP_PKEY_CTX_new(3)>,
86L<EVP_PKEY_encrypt(3)|EVP_PKEY_encrypt(3)>,
87L<EVP_PKEY_decrypt(3)|EVP_PKEY_decrypt(3)>,
88L<EVP_PKEY_verify(3)|EVP_PKEY_verify(3)>,
89L<EVP_PKEY_verifyrecover(3)|EVP_PKEY_verifyrecover(3)>,
90L<EVP_PKEY_derive(3)|EVP_PKEY_derive(3)>
91
92=head1 HISTORY
93
94These functions were first added to OpenSSL 1.0.0.
95
96=cut
diff --git a/src/lib/libcrypto/doc/EVP_PKEY_verify.pod b/src/lib/libcrypto/doc/EVP_PKEY_verify.pod
new file mode 100644
index 0000000000..10633da3f2
--- /dev/null
+++ b/src/lib/libcrypto/doc/EVP_PKEY_verify.pod
@@ -0,0 +1,91 @@
1=pod
2
3=head1 NAME
4
5EVP_PKEY_verify_init, EVP_PKEY_verify - signature verification using a public key algorithm
6
7=head1 SYNOPSIS
8
9 #include <openssl/evp.h>
10
11 int EVP_PKEY_verify_init(EVP_PKEY_CTX *ctx);
12 int EVP_PKEY_verify(EVP_PKEY_CTX *ctx,
13 const unsigned char *sig, size_t siglen,
14 const unsigned char *tbs, size_t tbslen);
15
16=head1 DESCRIPTION
17
18The EVP_PKEY_verify_init() function initializes a public key algorithm
19context using key B<pkey> for a signature verification operation.
20
21The EVP_PKEY_verify() function performs a public key verification operation
22using B<ctx>. The signature is specified using the B<sig> and
23B<siglen> parameters. The verified data (i.e. the data believed originally
24signed) is specified using the B<tbs> and B<tbslen> parameters.
25
26=head1 NOTES
27
28After the call to EVP_PKEY_verify_init() algorithm specific control
29operations can be performed to set any appropriate parameters for the
30operation.
31
32The function EVP_PKEY_verify() can be called more than once on the same
33context if several operations are performed using the same parameters.
34
35=head1 RETURN VALUES
36
37EVP_PKEY_verify_init() and EVP_PKEY_verify() return 1 if the verification was
38successful and 0 if it failed. Unlike other functions the return value 0 from
39EVP_PKEY_verify() only indicates that the signature did not not verify
40successfully (that is tbs did not match the original data or the signature was
41of invalid form) it is not an indication of a more serious error.
42
43A negative value indicates an error other that signature verification failure.
44In particular a return value of -2 indicates the operation is not supported by
45the public key algorithm.
46
47=head1 EXAMPLE
48
49Verify signature using PKCS#1 and SHA256 digest:
50
51 #include <openssl/evp.h>
52 #include <openssl/rsa.h>
53
54 EVP_PKEY_CTX *ctx;
55 unsigned char *md, *sig;
56 size_t mdlen, siglen;
57 EVP_PKEY *verify_key;
58 /* NB: assumes verify_key, sig, siglen md and mdlen are already set up
59 * and that verify_key is an RSA public key
60 */
61 ctx = EVP_PKEY_CTX_new(verify_key);
62 if (!ctx)
63 /* Error occurred */
64 if (EVP_PKEY_verify_init(ctx) <= 0)
65 /* Error */
66 if (EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_PADDING) <= 0)
67 /* Error */
68 if (EVP_PKEY_CTX_set_signature_md(ctx, EVP_sha256()) <= 0)
69 /* Error */
70
71 /* Perform operation */
72 ret = EVP_PKEY_verify(ctx, md, mdlen, sig, siglen);
73
74 /* ret == 1 indicates success, 0 verify failure and < 0 for some
75 * other error.
76 */
77
78=head1 SEE ALSO
79
80L<EVP_PKEY_CTX_new(3)|EVP_PKEY_CTX_new(3)>,
81L<EVP_PKEY_encrypt(3)|EVP_PKEY_encrypt(3)>,
82L<EVP_PKEY_decrypt(3)|EVP_PKEY_decrypt(3)>,
83L<EVP_PKEY_sign(3)|EVP_PKEY_sign(3)>,
84L<EVP_PKEY_verifyrecover(3)|EVP_PKEY_verifyrecover(3)>,
85L<EVP_PKEY_derive(3)|EVP_PKEY_derive(3)>
86
87=head1 HISTORY
88
89These functions were first added to OpenSSL 1.0.0.
90
91=cut
diff --git a/src/lib/libcrypto/doc/EVP_SignInit.pod b/src/lib/libcrypto/doc/EVP_SignInit.pod
index b6e62ce7f6..620a623ab6 100644
--- a/src/lib/libcrypto/doc/EVP_SignInit.pod
+++ b/src/lib/libcrypto/doc/EVP_SignInit.pod
@@ -77,6 +77,15 @@ will occur.
77Older versions of this documentation wrongly stated that calls to 77Older versions of this documentation wrongly stated that calls to
78EVP_SignUpdate() could not be made after calling EVP_SignFinal(). 78EVP_SignUpdate() could not be made after calling EVP_SignFinal().
79 79
80Since the private key is passed in the call to EVP_SignFinal() any error
81relating to the private key (for example an unsuitable key and digest
82combination) will not be indicated until after potentially large amounts of
83data have been passed through EVP_SignUpdate().
84
85It is not possible to change the signing parameters using these function.
86
87The previous two bugs are fixed in the newer EVP_SignDigest*() function.
88
80=head1 SEE ALSO 89=head1 SEE ALSO
81 90
82L<EVP_VerifyInit(3)|EVP_VerifyInit(3)>, 91L<EVP_VerifyInit(3)|EVP_VerifyInit(3)>,
diff --git a/src/lib/libcrypto/doc/EVP_VerifyInit.pod b/src/lib/libcrypto/doc/EVP_VerifyInit.pod
index b6afaedee5..9097f09410 100644
--- a/src/lib/libcrypto/doc/EVP_VerifyInit.pod
+++ b/src/lib/libcrypto/doc/EVP_VerifyInit.pod
@@ -67,6 +67,15 @@ will occur.
67Older versions of this documentation wrongly stated that calls to 67Older versions of this documentation wrongly stated that calls to
68EVP_VerifyUpdate() could not be made after calling EVP_VerifyFinal(). 68EVP_VerifyUpdate() could not be made after calling EVP_VerifyFinal().
69 69
70Since the public key is passed in the call to EVP_SignFinal() any error
71relating to the private key (for example an unsuitable key and digest
72combination) will not be indicated until after potentially large amounts of
73data have been passed through EVP_SignUpdate().
74
75It is not possible to change the signing parameters using these function.
76
77The previous two bugs are fixed in the newer EVP_VerifyDigest*() function.
78
70=head1 SEE ALSO 79=head1 SEE ALSO
71 80
72L<evp(3)|evp(3)>, 81L<evp(3)|evp(3)>,
diff --git a/src/lib/libcrypto/doc/OBJ_nid2obj.pod b/src/lib/libcrypto/doc/OBJ_nid2obj.pod
index 7dcc07923f..1e45dd40f6 100644
--- a/src/lib/libcrypto/doc/OBJ_nid2obj.pod
+++ b/src/lib/libcrypto/doc/OBJ_nid2obj.pod
@@ -8,6 +8,8 @@ functions
8 8
9=head1 SYNOPSIS 9=head1 SYNOPSIS
10 10
11 #include <openssl/objects.h>
12
11 ASN1_OBJECT * OBJ_nid2obj(int n); 13 ASN1_OBJECT * OBJ_nid2obj(int n);
12 const char * OBJ_nid2ln(int n); 14 const char * OBJ_nid2ln(int n);
13 const char * OBJ_nid2sn(int n); 15 const char * OBJ_nid2sn(int n);
diff --git a/src/lib/libcrypto/doc/PEM_write_bio_CMS_stream.pod b/src/lib/libcrypto/doc/PEM_write_bio_CMS_stream.pod
new file mode 100644
index 0000000000..e070c45c2e
--- /dev/null
+++ b/src/lib/libcrypto/doc/PEM_write_bio_CMS_stream.pod
@@ -0,0 +1,41 @@
1=pod
2
3=head1 NAME
4
5 PEM_write_bio_CMS_stream - output CMS_ContentInfo structure in PEM format.
6
7=head1 SYNOPSIS
8
9 #include <openssl/cms.h>
10 #include <openssl/pem.h>
11
12 int PEM_write_bio_CMS_stream(BIO *out, CMS_ContentInfo *cms, BIO *data, int flags);
13
14=head1 DESCRIPTION
15
16PEM_write_bio_CMS_stream() outputs a CMS_ContentInfo structure in PEM format.
17
18It is otherwise identical to the function SMIME_write_CMS().
19
20=head1 NOTES
21
22This function is effectively a version of the PEM_write_bio_CMS() supporting
23streaming.
24
25=head1 RETURN VALUES
26
27PEM_write_bio_CMS_stream() returns 1 for success or 0 for failure.
28
29=head1 SEE ALSO
30
31L<ERR_get_error(3)|ERR_get_error(3)>, L<CMS_sign(3)|CMS_sign(3)>,
32L<CMS_verify(3)|CMS_verify(3)>, L<CMS_encrypt(3)|CMS_encrypt(3)>
33L<CMS_decrypt(3)|CMS_decrypt(3)>,
34L<SMIME_write_CMS(3)|SMIME_write_CMS(3)>,
35L<i2d_CMS_bio_stream(3)|i2d_CMS_bio_stream(3)>
36
37=head1 HISTORY
38
39PEM_write_bio_CMS_stream() was added to OpenSSL 1.0.0
40
41=cut
diff --git a/src/lib/libcrypto/doc/PEM_write_bio_PKCS7_stream.pod b/src/lib/libcrypto/doc/PEM_write_bio_PKCS7_stream.pod
new file mode 100644
index 0000000000..16fc9b6845
--- /dev/null
+++ b/src/lib/libcrypto/doc/PEM_write_bio_PKCS7_stream.pod
@@ -0,0 +1,41 @@
1=pod
2
3=head1 NAME
4
5PEM_write_bio_PKCS7_stream - output PKCS7 structure in PEM format.
6
7=head1 SYNOPSIS
8
9 #include <openssl/pkcs7.h>
10 #include <openssl/pem.h>
11
12 int PEM_write_bio_PKCS7_stream(BIO *out, PKCS7 *p7, BIO *data, int flags);
13
14=head1 DESCRIPTION
15
16PEM_write_bio_PKCS7_stream() outputs a PKCS7 structure in PEM format.
17
18It is otherwise identical to the function SMIME_write_PKCS7().
19
20=head1 NOTES
21
22This function is effectively a version of the PEM_write_bio_PKCS7() supporting
23streaming.
24
25=head1 RETURN VALUES
26
27PEM_write_bio_PKCS7_stream() returns 1 for success or 0 for failure.
28
29=head1 SEE ALSO
30
31L<ERR_get_error(3)|ERR_get_error(3)>, L<PKCS7_sign(3)|PKCS7_sign(3)>,
32L<PKCS7_verify(3)|PKCS7_verify(3)>, L<PKCS7_encrypt(3)|PKCS7_encrypt(3)>
33L<PKCS7_decrypt(3)|PKCS7_decrypt(3)>,
34L<SMIME_write_PKCS7(3)|SMIME_write_PKCS7(3)>,
35L<i2d_PKCS7_bio_stream(3)|i2d_PKCS7_bio_stream(3)>
36
37=head1 HISTORY
38
39PEM_write_bio_PKCS7_stream() was added to OpenSSL 1.0.0
40
41=cut
diff --git a/src/lib/libcrypto/doc/PKCS12_parse.pod b/src/lib/libcrypto/doc/PKCS12_parse.pod
index 51344f883a..c54cf2ad61 100644
--- a/src/lib/libcrypto/doc/PKCS12_parse.pod
+++ b/src/lib/libcrypto/doc/PKCS12_parse.pod
@@ -20,24 +20,31 @@ certificate to B<*cert> and any additional certificates to B<*ca>.
20 20
21=head1 NOTES 21=head1 NOTES
22 22
23The parameters B<pkey> and B<cert> cannot be B<NULL>. B<ca> can be <NULL> 23The parameters B<pkey> and B<cert> cannot be B<NULL>. B<ca> can be <NULL> in
24in which case additional certificates will be discarded. B<*ca> can also 24which case additional certificates will be discarded. B<*ca> can also be a
25be a valid STACK in which case additional certificates are appended to 25valid STACK in which case additional certificates are appended to B<*ca>. If
26B<*ca>. If B<*ca> is B<NULL> a new STACK will be allocated. 26B<*ca> is B<NULL> a new STACK will be allocated.
27 27
28The B<friendlyName> and B<localKeyID> attributes (if present) on each certificate 28The B<friendlyName> and B<localKeyID> attributes (if present) on each
29will be stored in the B<alias> and B<keyid> attributes of the B<X509> structure. 29certificate will be stored in the B<alias> and B<keyid> attributes of the
30B<X509> structure.
31
32=head1 RETURN VALUES
33
34PKCS12_parse() returns 1 for success and zero if an error occurred.
35
36The error can be obtained from L<ERR_get_error(3)|ERR_get_error(3)>
30 37
31=head1 BUGS 38=head1 BUGS
32 39
33Only a single private key and corresponding certificate is returned by this function. 40Only a single private key and corresponding certificate is returned by this
34More complex PKCS#12 files with multiple private keys will only return the first 41function. More complex PKCS#12 files with multiple private keys will only
35match. 42return the first match.
36 43
37Only B<friendlyName> and B<localKeyID> attributes are currently stored in certificates. 44Only B<friendlyName> and B<localKeyID> attributes are currently stored in
38Other attributes are discarded. 45certificates. Other attributes are discarded.
39 46
40Attributes currently cannot be store in the private key B<EVP_PKEY> structure. 47Attributes currently cannot be stored in the private key B<EVP_PKEY> structure.
41 48
42=head1 SEE ALSO 49=head1 SEE ALSO
43 50
diff --git a/src/lib/libcrypto/doc/PKCS7_decrypt.pod b/src/lib/libcrypto/doc/PKCS7_decrypt.pod
index b0ca067b89..325699d0b6 100644
--- a/src/lib/libcrypto/doc/PKCS7_decrypt.pod
+++ b/src/lib/libcrypto/doc/PKCS7_decrypt.pod
@@ -6,7 +6,9 @@ PKCS7_decrypt - decrypt content from a PKCS#7 envelopedData structure
6 6
7=head1 SYNOPSIS 7=head1 SYNOPSIS
8 8
9int PKCS7_decrypt(PKCS7 *p7, EVP_PKEY *pkey, X509 *cert, BIO *data, int flags); 9 #include <openssl/pkcs7.h>
10
11 int PKCS7_decrypt(PKCS7 *p7, EVP_PKEY *pkey, X509 *cert, BIO *data, int flags);
10 12
11=head1 DESCRIPTION 13=head1 DESCRIPTION
12 14
diff --git a/src/lib/libcrypto/doc/PKCS7_encrypt.pod b/src/lib/libcrypto/doc/PKCS7_encrypt.pod
index 1a507b22a2..2cd925a7e0 100644
--- a/src/lib/libcrypto/doc/PKCS7_encrypt.pod
+++ b/src/lib/libcrypto/doc/PKCS7_encrypt.pod
@@ -6,7 +6,9 @@ PKCS7_encrypt - create a PKCS#7 envelopedData structure
6 6
7=head1 SYNOPSIS 7=head1 SYNOPSIS
8 8
9PKCS7 *PKCS7_encrypt(STACK_OF(X509) *certs, BIO *in, const EVP_CIPHER *cipher, int flags); 9 #include <openssl/pkcs7.h>
10
11 PKCS7 *PKCS7_encrypt(STACK_OF(X509) *certs, BIO *in, const EVP_CIPHER *cipher, int flags);
10 12
11=head1 DESCRIPTION 13=head1 DESCRIPTION
12 14
@@ -16,43 +18,55 @@ B<cipher> is the symmetric cipher to use. B<flags> is an optional set of flags.
16 18
17=head1 NOTES 19=head1 NOTES
18 20
19Only RSA keys are supported in PKCS#7 and envelopedData so the recipient certificates 21Only RSA keys are supported in PKCS#7 and envelopedData so the recipient
20supplied to this function must all contain RSA public keys, though they do not have to 22certificates supplied to this function must all contain RSA public keys, though
21be signed using the RSA algorithm. 23they do not have to be signed using the RSA algorithm.
22 24
23EVP_des_ede3_cbc() (triple DES) is the algorithm of choice for S/MIME use because 25EVP_des_ede3_cbc() (triple DES) is the algorithm of choice for S/MIME use
24most clients will support it. 26because most clients will support it.
25 27
26Some old "export grade" clients may only support weak encryption using 40 or 64 bit 28Some old "export grade" clients may only support weak encryption using 40 or 64
27RC2. These can be used by passing EVP_rc2_40_cbc() and EVP_rc2_64_cbc() respectively. 29bit RC2. These can be used by passing EVP_rc2_40_cbc() and EVP_rc2_64_cbc()
30respectively.
28 31
29The algorithm passed in the B<cipher> parameter must support ASN1 encoding of its 32The algorithm passed in the B<cipher> parameter must support ASN1 encoding of
30parameters. 33its parameters.
31 34
32Many browsers implement a "sign and encrypt" option which is simply an S/MIME 35Many browsers implement a "sign and encrypt" option which is simply an S/MIME
33envelopedData containing an S/MIME signed message. This can be readily produced 36envelopedData containing an S/MIME signed message. This can be readily produced
34by storing the S/MIME signed message in a memory BIO and passing it to 37by storing the S/MIME signed message in a memory BIO and passing it to
35PKCS7_encrypt(). 38PKCS7_encrypt().
36 39
37The following flags can be passed in the B<flags> parameter. 40The following flags can be passed in the B<flags> parameter.
38 41
39If the B<PKCS7_TEXT> flag is set MIME headers for type B<text/plain> are prepended 42If the B<PKCS7_TEXT> flag is set MIME headers for type B<text/plain> are
40to the data. 43prepended to the data.
41 44
42Normally the supplied content is translated into MIME canonical format (as required 45Normally the supplied content is translated into MIME canonical format (as
43by the S/MIME specifications) if B<PKCS7_BINARY> is set no translation occurs. This 46required by the S/MIME specifications) if B<PKCS7_BINARY> is set no translation
44option should be used if the supplied data is in binary format otherwise the translation 47occurs. This option should be used if the supplied data is in binary format
45will corrupt it. If B<PKCS7_BINARY> is set then B<PKCS7_TEXT> is ignored. 48otherwise the translation will corrupt it. If B<PKCS7_BINARY> is set then
49B<PKCS7_TEXT> is ignored.
46 50
47=head1 RETURN VALUES 51If the B<PKCS7_STREAM> flag is set a partial B<PKCS7> structure is output
52suitable for streaming I/O: no data is read from the BIO B<in>.
48 53
49PKCS7_encrypt() returns either a valid PKCS7 structure or NULL if an error occurred. 54=head1 NOTES
50The error can be obtained from ERR_get_error(3).
51 55
52=head1 BUGS 56If the flag B<PKCS7_STREAM> is set the returned B<PKCS7> structure is B<not>
57complete and outputting its contents via a function that does not
58properly finalize the B<PKCS7> structure will give unpredictable
59results.
53 60
54The lack of single pass processing and need to hold all data in memory as 61Several functions including SMIME_write_PKCS7(), i2d_PKCS7_bio_stream(),
55mentioned in PKCS7_sign() also applies to PKCS7_verify(). 62PEM_write_bio_PKCS7_stream() finalize the structure. Alternatively finalization
63can be performed by obtaining the streaming ASN1 B<BIO> directly using
64BIO_new_PKCS7().
65
66=head1 RETURN VALUES
67
68PKCS7_encrypt() returns either a PKCS7 structure or NULL if an error occurred.
69The error can be obtained from ERR_get_error(3).
56 70
57=head1 SEE ALSO 71=head1 SEE ALSO
58 72
@@ -61,5 +75,6 @@ L<ERR_get_error(3)|ERR_get_error(3)>, L<PKCS7_decrypt(3)|PKCS7_decrypt(3)>
61=head1 HISTORY 75=head1 HISTORY
62 76
63PKCS7_decrypt() was added to OpenSSL 0.9.5 77PKCS7_decrypt() was added to OpenSSL 0.9.5
78The B<PKCS7_STREAM> flag was first supported in OpenSSL 1.0.0.
64 79
65=cut 80=cut
diff --git a/src/lib/libcrypto/doc/PKCS7_sign.pod b/src/lib/libcrypto/doc/PKCS7_sign.pod
index ffd0c734b0..64a35144f8 100644
--- a/src/lib/libcrypto/doc/PKCS7_sign.pod
+++ b/src/lib/libcrypto/doc/PKCS7_sign.pod
@@ -6,14 +6,16 @@ PKCS7_sign - create a PKCS#7 signedData structure
6 6
7=head1 SYNOPSIS 7=head1 SYNOPSIS
8 8
9PKCS7 *PKCS7_sign(X509 *signcert, EVP_PKEY *pkey, STACK_OF(X509) *certs, BIO *data, int flags); 9 #include <openssl/pkcs7.h>
10
11 PKCS7 *PKCS7_sign(X509 *signcert, EVP_PKEY *pkey, STACK_OF(X509) *certs, BIO *data, int flags);
10 12
11=head1 DESCRIPTION 13=head1 DESCRIPTION
12 14
13PKCS7_sign() creates and returns a PKCS#7 signedData structure. B<signcert> 15PKCS7_sign() creates and returns a PKCS#7 signedData structure. B<signcert> is
14is the certificate to sign with, B<pkey> is the corresponsding private key. 16the certificate to sign with, B<pkey> is the corresponsding private key.
15B<certs> is an optional additional set of certificates to include in the 17B<certs> is an optional additional set of certificates to include in the PKCS#7
16PKCS#7 structure (for example any intermediate CAs in the chain). 18structure (for example any intermediate CAs in the chain).
17 19
18The data to be signed is read from BIO B<data>. 20The data to be signed is read from BIO B<data>.
19 21
@@ -21,72 +23,83 @@ B<flags> is an optional set of flags.
21 23
22=head1 NOTES 24=head1 NOTES
23 25
24Any of the following flags (ored together) can be passed in the B<flags> parameter. 26Any of the following flags (ored together) can be passed in the B<flags>
27parameter.
25 28
26Many S/MIME clients expect the signed content to include valid MIME headers. If 29Many S/MIME clients expect the signed content to include valid MIME headers. If
27the B<PKCS7_TEXT> flag is set MIME headers for type B<text/plain> are prepended 30the B<PKCS7_TEXT> flag is set MIME headers for type B<text/plain> are prepended
28to the data. 31to the data.
29 32
30If B<PKCS7_NOCERTS> is set the signer's certificate will not be included in the 33If B<PKCS7_NOCERTS> is set the signer's certificate will not be included in the
31PKCS7 structure, the signer's certificate must still be supplied in the B<signcert> 34PKCS7 structure, the signer's certificate must still be supplied in the
32parameter though. This can reduce the size of the signature if the signers certificate 35B<signcert> parameter though. This can reduce the size of the signature if the
33can be obtained by other means: for example a previously signed message. 36signers certificate can be obtained by other means: for example a previously
34 37signed message.
35The data being signed is included in the PKCS7 structure, unless B<PKCS7_DETACHED> 38
36is set in which case it is omitted. This is used for PKCS7 detached signatures 39The data being signed is included in the PKCS7 structure, unless
37which are used in S/MIME plaintext signed messages for example. 40B<PKCS7_DETACHED> is set in which case it is omitted. This is used for PKCS7
41detached signatures which are used in S/MIME plaintext signed messages for
42example.
43
44Normally the supplied content is translated into MIME canonical format (as
45required by the S/MIME specifications) if B<PKCS7_BINARY> is set no translation
46occurs. This option should be used if the supplied data is in binary format
47otherwise the translation will corrupt it.
48
49The signedData structure includes several PKCS#7 autenticatedAttributes
50including the signing time, the PKCS#7 content type and the supported list of
51ciphers in an SMIMECapabilities attribute. If B<PKCS7_NOATTR> is set then no
52authenticatedAttributes will be used. If B<PKCS7_NOSMIMECAP> is set then just
53the SMIMECapabilities are omitted.
38 54
39Normally the supplied content is translated into MIME canonical format (as required 55If present the SMIMECapabilities attribute indicates support for the following
40by the S/MIME specifications) if B<PKCS7_BINARY> is set no translation occurs. This 56algorithms: triple DES, 128 bit RC2, 64 bit RC2, DES and 40 bit RC2. If any of
41option should be used if the supplied data is in binary format otherwise the translation 57these algorithms is disabled then it will not be included.
42will corrupt it.
43 58
44The signedData structure includes several PKCS#7 autenticatedAttributes including 59If the flags B<PKCS7_STREAM> is set then the returned B<PKCS7> structure is
45the signing time, the PKCS#7 content type and the supported list of ciphers in 60just initialized ready to perform the signing operation. The signing is however
46an SMIMECapabilities attribute. If B<PKCS7_NOATTR> is set then no authenticatedAttributes 61B<not> performed and the data to be signed is not read from the B<data>
47will be used. If B<PKCS7_NOSMIMECAP> is set then just the SMIMECapabilities are 62parameter. Signing is deferred until after the data has been written. In this
48omitted. 63way data can be signed in a single pass.
49 64
50If present the SMIMECapabilities attribute indicates support for the following 65If the B<PKCS7_PARTIAL> flag is set a partial B<PKCS7> structure is output to
51algorithms: triple DES, 128 bit RC2, 64 bit RC2, DES and 40 bit RC2. If any 66which additional signers and capabilities can be added before finalization.
52of these algorithms is disabled then it will not be included.
53 67
54If the flags B<PKCS7_PARTSIGN> is set then the returned B<PKCS7> structure
55is just initialized ready to perform the signing operation. The signing
56is however B<not> performed and the data to be signed is not read from
57the B<data> parameter. Signing is deferred until after the data has been
58written. In this way data can be signed in a single pass. Currently the
59flag B<PKCS7_DETACHED> B<must> also be set.
60 68
61=head1 NOTES 69=head1 NOTES
62 70
63Currently the flag B<PKCS7_PARTSIGN> is only supported for detached 71If the flag B<PKCS7_STREAM> is set the returned B<PKCS7> structure is B<not>
64data. If this flag is set the returned B<PKCS7> structure is B<not> 72complete and outputting its contents via a function that does not properly
65complete and outputting its contents via a function that does not 73finalize the B<PKCS7> structure will give unpredictable results.
66properly finalize the B<PKCS7> structure will give unpredictable
67results.
68 74
69At present only the SMIME_write_PKCS7() function properly finalizes the 75Several functions including SMIME_write_PKCS7(), i2d_PKCS7_bio_stream(),
70structure. 76PEM_write_bio_PKCS7_stream() finalize the structure. Alternatively finalization
77can be performed by obtaining the streaming ASN1 B<BIO> directly using
78BIO_new_PKCS7().
71 79
72=head1 BUGS 80If a signer is specified it will use the default digest for the signing
81algorithm. This is B<SHA1> for both RSA and DSA keys.
82
83In OpenSSL 1.0.0 the B<certs>, B<signcert> and B<pkey> parameters can all be
84B<NULL> if the B<PKCS7_PARTIAL> flag is set. One or more signers can be added
85using the function B<PKCS7_sign_add_signer()>. B<PKCS7_final()> must also be
86called to finalize the structure if streaming is not enabled. Alternative
87signing digests can also be specified using this method.
73 88
74PKCS7_sign() is somewhat limited. It does not support multiple signers, some 89In OpenSSL 1.0.0 if B<signcert> and B<pkey> are NULL then a certificates only
75advanced attributes such as counter signatures are not supported. 90PKCS#7 structure is output.
76 91
77The SHA1 digest algorithm is currently always used. 92In versions of OpenSSL before 1.0.0 the B<signcert> and B<pkey> parameters must
93B<NOT> be NULL.
78 94
79When the signed data is not detached it will be stored in memory within the 95=head1 BUGS
80B<PKCS7> structure. This effectively limits the size of messages which can be
81signed due to memory restraints. There should be a way to sign data without
82having to hold it all in memory, this would however require fairly major
83revisions of the OpenSSL ASN1 code.
84 96
97Some advanced attributes such as counter signatures are not supported.
85 98
86=head1 RETURN VALUES 99=head1 RETURN VALUES
87 100
88PKCS7_sign() returns either a valid PKCS7 structure or NULL if an error occurred. 101PKCS7_sign() returns either a valid PKCS7 structure or NULL if an error
89The error can be obtained from ERR_get_error(3). 102occurred. The error can be obtained from ERR_get_error(3).
90 103
91=head1 SEE ALSO 104=head1 SEE ALSO
92 105
@@ -96,6 +109,8 @@ L<ERR_get_error(3)|ERR_get_error(3)>, L<PKCS7_verify(3)|PKCS7_verify(3)>
96 109
97PKCS7_sign() was added to OpenSSL 0.9.5 110PKCS7_sign() was added to OpenSSL 0.9.5
98 111
99The B<PKCS7_PARTSIGN> flag was added in OpenSSL 0.9.8 112The B<PKCS7_PARTIAL> flag was added in OpenSSL 1.0.0
113
114The B<PKCS7_STREAM> flag was added in OpenSSL 1.0.0
100 115
101=cut 116=cut
diff --git a/src/lib/libcrypto/doc/PKCS7_sign_add_signer.pod b/src/lib/libcrypto/doc/PKCS7_sign_add_signer.pod
new file mode 100644
index 0000000000..ebec4d57de
--- /dev/null
+++ b/src/lib/libcrypto/doc/PKCS7_sign_add_signer.pod
@@ -0,0 +1,87 @@
1=pod
2
3=head1 NAME
4
5PKCS7_sign_add_signer - add a signer PKCS7 signed data structure.
6
7=head1 SYNOPSIS
8
9 #include <openssl/pkcs7.h>
10
11 PKCS7_SIGNER_INFO *PKCS7_sign_add_signer(PKCS7 *p7, X509 *signcert, EVP_PKEY *pkey, const EVP_MD *md, int flags);
12
13
14=head1 DESCRIPTION
15
16PKCS7_sign_add_signer() adds a signer with certificate B<signcert> and private
17key B<pkey> using message digest B<md> to a PKCS7 signed data structure
18B<p7>.
19
20The PKCS7 structure should be obtained from an initial call to PKCS7_sign()
21with the flag B<PKCS7_PARTIAL> set or in the case or re-signing a valid PKCS7
22signed data structure.
23
24If the B<md> parameter is B<NULL> then the default digest for the public
25key algorithm will be used.
26
27Unless the B<PKCS7_REUSE_DIGEST> flag is set the returned PKCS7 structure
28is not complete and must be finalized either by streaming (if applicable) or
29a call to PKCS7_final().
30
31
32=head1 NOTES
33
34The main purpose of this function is to provide finer control over a PKCS#7
35signed data structure where the simpler PKCS7_sign() function defaults are
36not appropriate. For example if multiple signers or non default digest
37algorithms are needed.
38
39Any of the following flags (ored together) can be passed in the B<flags>
40parameter.
41
42If B<PKCS7_REUSE_DIGEST> is set then an attempt is made to copy the content
43digest value from the PKCS7 struture: to add a signer to an existing structure.
44An error occurs if a matching digest value cannot be found to copy. The
45returned PKCS7 structure will be valid and finalized when this flag is set.
46
47If B<PKCS7_PARTIAL> is set in addition to B<PKCS7_REUSE_DIGEST> then the
48B<PKCS7_SIGNER_INO> structure will not be finalized so additional attributes
49can be added. In this case an explicit call to PKCS7_SIGNER_INFO_sign() is
50needed to finalize it.
51
52If B<PKCS7_NOCERTS> is set the signer's certificate will not be included in the
53PKCS7 structure, the signer's certificate must still be supplied in the
54B<signcert> parameter though. This can reduce the size of the signature if the
55signers certificate can be obtained by other means: for example a previously
56signed message.
57
58The signedData structure includes several PKCS#7 autenticatedAttributes
59including the signing time, the PKCS#7 content type and the supported list of
60ciphers in an SMIMECapabilities attribute. If B<PKCS7_NOATTR> is set then no
61authenticatedAttributes will be used. If B<PKCS7_NOSMIMECAP> is set then just
62the SMIMECapabilities are omitted.
63
64If present the SMIMECapabilities attribute indicates support for the following
65algorithms: triple DES, 128 bit RC2, 64 bit RC2, DES and 40 bit RC2. If any of
66these algorithms is disabled then it will not be included.
67
68
69PKCS7_sign_add_signers() returns an internal pointer to the PKCS7_SIGNER_INFO
70structure just added, this can be used to set additional attributes
71before it is finalized.
72
73=head1 RETURN VALUES
74
75PKCS7_sign_add_signers() returns an internal pointer to the PKCS7_SIGNER_INFO
76structure just added or NULL if an error occurs.
77
78=head1 SEE ALSO
79
80L<ERR_get_error(3)|ERR_get_error(3)>, L<PKCS7_sign(3)|PKCS7_sign(3)>,
81L<PKCS7_final(3)|PKCS7_final(3)>,
82
83=head1 HISTORY
84
85PPKCS7_sign_add_signer() was added to OpenSSL 1.0.0
86
87=cut
diff --git a/src/lib/libcrypto/doc/PKCS7_verify.pod b/src/lib/libcrypto/doc/PKCS7_verify.pod
index 3490b5dc82..7c10a4cc3c 100644
--- a/src/lib/libcrypto/doc/PKCS7_verify.pod
+++ b/src/lib/libcrypto/doc/PKCS7_verify.pod
@@ -6,9 +6,11 @@ PKCS7_verify - verify a PKCS#7 signedData structure
6 6
7=head1 SYNOPSIS 7=head1 SYNOPSIS
8 8
9int PKCS7_verify(PKCS7 *p7, STACK_OF(X509) *certs, X509_STORE *store, BIO *indata, BIO *out, int flags); 9 #include <openssl/pkcs7.h>
10 10
11STACK_OF(X509) *PKCS7_get0_signers(PKCS7 *p7, STACK_OF(X509) *certs, int flags); 11 int PKCS7_verify(PKCS7 *p7, STACK_OF(X509) *certs, X509_STORE *store, BIO *indata, BIO *out, int flags);
12
13 STACK_OF(X509) *PKCS7_get0_signers(PKCS7 *p7, STACK_OF(X509) *certs, int flags);
12 14
13=head1 DESCRIPTION 15=head1 DESCRIPTION
14 16
diff --git a/src/lib/libcrypto/doc/SMIME_read_CMS.pod b/src/lib/libcrypto/doc/SMIME_read_CMS.pod
new file mode 100644
index 0000000000..acc5524c14
--- /dev/null
+++ b/src/lib/libcrypto/doc/SMIME_read_CMS.pod
@@ -0,0 +1,70 @@
1=pod
2
3=head1 NAME
4
5 SMIME_read_CMS - parse S/MIME message.
6
7=head1 SYNOPSIS
8
9 #include <openssl/cms.h>
10
11 CMS_ContentInfo *SMIME_read_CMS(BIO *in, BIO **bcont);
12
13=head1 DESCRIPTION
14
15SMIME_read_CMS() parses a message in S/MIME format.
16
17B<in> is a BIO to read the message from.
18
19If cleartext signing is used then the content is saved in a memory bio which is
20written to B<*bcont>, otherwise B<*bcont> is set to NULL.
21
22The parsed CMS_ContentInfo structure is returned or NULL if an
23error occurred.
24
25=head1 NOTES
26
27If B<*bcont> is not NULL then the message is clear text signed. B<*bcont> can
28then be passed to CMS_verify() with the B<CMS_DETACHED> flag set.
29
30Otherwise the type of the returned structure can be determined
31using CMS_get0_type().
32
33To support future functionality if B<bcont> is not NULL B<*bcont> should be
34initialized to NULL. For example:
35
36 BIO *cont = NULL;
37 CMS_ContentInfo *cms;
38
39 cms = SMIME_read_CMS(in, &cont);
40
41=head1 BUGS
42
43The MIME parser used by SMIME_read_CMS() is somewhat primitive. While it will
44handle most S/MIME messages more complex compound formats may not work.
45
46The parser assumes that the CMS_ContentInfo structure is always base64 encoded
47and will not handle the case where it is in binary format or uses quoted
48printable format.
49
50The use of a memory BIO to hold the signed content limits the size of message
51which can be processed due to memory restraints: a streaming single pass option
52should be available.
53
54=head1 RETURN VALUES
55
56SMIME_read_CMS() returns a valid B<CMS_ContentInfo> structure or B<NULL>
57if an error occurred. The error can be obtained from ERR_get_error(3).
58
59=head1 SEE ALSO
60
61L<ERR_get_error(3)|ERR_get_error(3)>, L<CMS_type(3)|CMS_type(3)>
62L<SMIME_read_CMS(3)|SMIME_read_CMS(3)>, L<CMS_sign(3)|CMS_sign(3)>,
63L<CMS_verify(3)|CMS_verify(3)>, L<CMS_encrypt(3)|CMS_encrypt(3)>
64L<CMS_decrypt(3)|CMS_decrypt(3)>
65
66=head1 HISTORY
67
68SMIME_read_CMS() was added to OpenSSL 0.9.8
69
70=cut
diff --git a/src/lib/libcrypto/doc/SMIME_read_PKCS7.pod b/src/lib/libcrypto/doc/SMIME_read_PKCS7.pod
index ffafa37887..9d46715941 100644
--- a/src/lib/libcrypto/doc/SMIME_read_PKCS7.pod
+++ b/src/lib/libcrypto/doc/SMIME_read_PKCS7.pod
@@ -6,7 +6,9 @@ SMIME_read_PKCS7 - parse S/MIME message.
6 6
7=head1 SYNOPSIS 7=head1 SYNOPSIS
8 8
9PKCS7 *SMIME_read_PKCS7(BIO *in, BIO **bcont); 9 #include <openssl/pkcs7.h>
10
11 PKCS7 *SMIME_read_PKCS7(BIO *in, BIO **bcont);
10 12
11=head1 DESCRIPTION 13=head1 DESCRIPTION
12 14
diff --git a/src/lib/libcrypto/doc/SMIME_write_CMS.pod b/src/lib/libcrypto/doc/SMIME_write_CMS.pod
new file mode 100644
index 0000000000..04bedfb429
--- /dev/null
+++ b/src/lib/libcrypto/doc/SMIME_write_CMS.pod
@@ -0,0 +1,64 @@
1=pod
2
3=head1 NAME
4
5 SMIME_write_CMS - convert CMS structure to S/MIME format.
6
7=head1 SYNOPSIS
8
9 #include <openssl/cms.h>
10
11 int SMIME_write_CMS(BIO *out, CMS_ContentInfo *cms, BIO *data, int flags);
12
13=head1 DESCRIPTION
14
15SMIME_write_CMS() adds the appropriate MIME headers to a CMS
16structure to produce an S/MIME message.
17
18B<out> is the BIO to write the data to. B<cms> is the appropriate
19B<CMS_ContentInfo> structure. If streaming is enabled then the content must be
20supplied in the B<data> argument. B<flags> is an optional set of flags.
21
22=head1 NOTES
23
24The following flags can be passed in the B<flags> parameter.
25
26If B<CMS_DETACHED> is set then cleartext signing will be used, this option only
27makes sense for SignedData where B<CMS_DETACHED> is also set when CMS_sign() is
28called.
29
30If the B<CMS_TEXT> flag is set MIME headers for type B<text/plain> are added to
31the content, this only makes sense if B<CMS_DETACHED> is also set.
32
33If the B<CMS_STREAM> flag is set streaming is performed. This flag should only
34be set if B<CMS_STREAM> was also set in the previous call to a CMS_ContentInfo
35creation function.
36
37If cleartext signing is being used and B<CMS_STREAM> not set then the data must
38be read twice: once to compute the signature in CMS_sign() and once to output
39the S/MIME message.
40
41If streaming is performed the content is output in BER format using indefinite
42length constructed encoding except in the case of signed data with detached
43content where the content is absent and DER format is used.
44
45=head1 BUGS
46
47SMIME_write_CMS() always base64 encodes CMS structures, there should be an
48option to disable this.
49
50=head1 RETURN VALUES
51
52SMIME_write_CMS() returns 1 for success or 0 for failure.
53
54=head1 SEE ALSO
55
56L<ERR_get_error(3)|ERR_get_error(3)>, L<CMS_sign(3)|CMS_sign(3)>,
57L<CMS_verify(3)|CMS_verify(3)>, L<CMS_encrypt(3)|CMS_encrypt(3)>
58L<CMS_decrypt(3)|CMS_decrypt(3)>
59
60=head1 HISTORY
61
62SMIME_write_CMS() was added to OpenSSL 0.9.8
63
64=cut
diff --git a/src/lib/libcrypto/doc/SMIME_write_PKCS7.pod b/src/lib/libcrypto/doc/SMIME_write_PKCS7.pod
index 61945b3887..ca6bd02763 100644
--- a/src/lib/libcrypto/doc/SMIME_write_PKCS7.pod
+++ b/src/lib/libcrypto/doc/SMIME_write_PKCS7.pod
@@ -6,17 +6,18 @@ SMIME_write_PKCS7 - convert PKCS#7 structure to S/MIME format.
6 6
7=head1 SYNOPSIS 7=head1 SYNOPSIS
8 8
9int SMIME_write_PKCS7(BIO *out, PKCS7 *p7, BIO *data, int flags); 9 #include <openssl/pkcs7.h>
10
11 int SMIME_write_PKCS7(BIO *out, PKCS7 *p7, BIO *data, int flags);
10 12
11=head1 DESCRIPTION 13=head1 DESCRIPTION
12 14
13SMIME_write_PKCS7() adds the appropriate MIME headers to a PKCS#7 15SMIME_write_PKCS7() adds the appropriate MIME headers to a PKCS#7
14structure to produce an S/MIME message. 16structure to produce an S/MIME message.
15 17
16B<out> is the BIO to write the data to. B<p7> is the appropriate 18B<out> is the BIO to write the data to. B<p7> is the appropriate B<PKCS7>
17B<PKCS7> structure. If cleartext signing (B<multipart/signed>) is 19structure. If streaming is enabled then the content must be supplied in the
18being used then the signed data must be supplied in the B<data> 20B<data> argument. B<flags> is an optional set of flags.
19argument. B<flags> is an optional set of flags.
20 21
21=head1 NOTES 22=head1 NOTES
22 23
@@ -30,15 +31,18 @@ If the B<PKCS7_TEXT> flag is set MIME headers for type B<text/plain>
30are added to the content, this only makes sense if B<PKCS7_DETACHED> 31are added to the content, this only makes sense if B<PKCS7_DETACHED>
31is also set. 32is also set.
32 33
33If the B<PKCS7_PARTSIGN> flag is set the signed data is finalized 34If the B<PKCS7_STREAM> flag is set streaming is performed. This flag should
34and output along with the content. This flag should only be set 35only be set if B<PKCS7_STREAM> was also set in the previous call to
35if B<PKCS7_DETACHED> is also set and the previous call to PKCS7_sign() 36PKCS7_sign() or B<PKCS7_encrypt()>.
36also set these flags.
37 37
38If cleartext signing is being used and B<PKCS7_PARTSIGN> not set then 38If cleartext signing is being used and B<PKCS7_STREAM> not set then
39the data must be read twice: once to compute the signature in PKCS7_sign() 39the data must be read twice: once to compute the signature in PKCS7_sign()
40and once to output the S/MIME message. 40and once to output the S/MIME message.
41 41
42If streaming is performed the content is output in BER format using indefinite
43length constructuted encoding except in the case of signed data with detached
44content where the content is absent and DER format is used.
45
42=head1 BUGS 46=head1 BUGS
43 47
44SMIME_write_PKCS7() always base64 encodes PKCS#7 structures, there 48SMIME_write_PKCS7() always base64 encodes PKCS#7 structures, there
diff --git a/src/lib/libcrypto/doc/X509_NAME_ENTRY_get_object.pod b/src/lib/libcrypto/doc/X509_NAME_ENTRY_get_object.pod
index 11b35f6fd3..41902c0d45 100644
--- a/src/lib/libcrypto/doc/X509_NAME_ENTRY_get_object.pod
+++ b/src/lib/libcrypto/doc/X509_NAME_ENTRY_get_object.pod
@@ -9,15 +9,17 @@ X509_NAME_ENTRY_create_by_OBJ - X509_NAME_ENTRY utility functions
9 9
10=head1 SYNOPSIS 10=head1 SYNOPSIS
11 11
12ASN1_OBJECT * X509_NAME_ENTRY_get_object(X509_NAME_ENTRY *ne); 12 #include <openssl/x509.h>
13ASN1_STRING * X509_NAME_ENTRY_get_data(X509_NAME_ENTRY *ne);
14 13
15int X509_NAME_ENTRY_set_object(X509_NAME_ENTRY *ne, ASN1_OBJECT *obj); 14 ASN1_OBJECT * X509_NAME_ENTRY_get_object(X509_NAME_ENTRY *ne);
16int X509_NAME_ENTRY_set_data(X509_NAME_ENTRY *ne, int type, const unsigned char *bytes, int len); 15 ASN1_STRING * X509_NAME_ENTRY_get_data(X509_NAME_ENTRY *ne);
17 16
18X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_txt(X509_NAME_ENTRY **ne, const char *field, int type, const unsigned char *bytes, int len); 17 int X509_NAME_ENTRY_set_object(X509_NAME_ENTRY *ne, ASN1_OBJECT *obj);
19X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_NID(X509_NAME_ENTRY **ne, int nid, int type,unsigned char *bytes, int len); 18 int X509_NAME_ENTRY_set_data(X509_NAME_ENTRY *ne, int type, const unsigned char *bytes, int len);
20X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_OBJ(X509_NAME_ENTRY **ne, ASN1_OBJECT *obj, int type, const unsigned char *bytes, int len); 19
20 X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_txt(X509_NAME_ENTRY **ne, const char *field, int type, const unsigned char *bytes, int len);
21 X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_NID(X509_NAME_ENTRY **ne, int nid, int type,unsigned char *bytes, int len);
22 X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_OBJ(X509_NAME_ENTRY **ne, ASN1_OBJECT *obj, int type, const unsigned char *bytes, int len);
21 23
22=head1 DESCRIPTION 24=head1 DESCRIPTION
23 25
diff --git a/src/lib/libcrypto/doc/X509_NAME_add_entry_by_txt.pod b/src/lib/libcrypto/doc/X509_NAME_add_entry_by_txt.pod
index e2ab4b0d2b..1afd008cb3 100644
--- a/src/lib/libcrypto/doc/X509_NAME_add_entry_by_txt.pod
+++ b/src/lib/libcrypto/doc/X509_NAME_add_entry_by_txt.pod
@@ -7,15 +7,17 @@ X509_NAME_add_entry, X509_NAME_delete_entry - X509_NAME modification functions
7 7
8=head1 SYNOPSIS 8=head1 SYNOPSIS
9 9
10int X509_NAME_add_entry_by_txt(X509_NAME *name, const char *field, int type, const unsigned char *bytes, int len, int loc, int set); 10 #include <openssl/x509.h>
11 11
12int X509_NAME_add_entry_by_OBJ(X509_NAME *name, ASN1_OBJECT *obj, int type, unsigned char *bytes, int len, int loc, int set); 12 int X509_NAME_add_entry_by_txt(X509_NAME *name, const char *field, int type, const unsigned char *bytes, int len, int loc, int set);
13 13
14int X509_NAME_add_entry_by_NID(X509_NAME *name, int nid, int type, unsigned char *bytes, int len, int loc, int set); 14 int X509_NAME_add_entry_by_OBJ(X509_NAME *name, ASN1_OBJECT *obj, int type, unsigned char *bytes, int len, int loc, int set);
15 15
16int X509_NAME_add_entry(X509_NAME *name,X509_NAME_ENTRY *ne, int loc, int set); 16 int X509_NAME_add_entry_by_NID(X509_NAME *name, int nid, int type, unsigned char *bytes, int len, int loc, int set);
17 17
18X509_NAME_ENTRY *X509_NAME_delete_entry(X509_NAME *name, int loc); 18 int X509_NAME_add_entry(X509_NAME *name,X509_NAME_ENTRY *ne, int loc, int set);
19
20 X509_NAME_ENTRY *X509_NAME_delete_entry(X509_NAME *name, int loc);
19 21
20=head1 DESCRIPTION 22=head1 DESCRIPTION
21 23
diff --git a/src/lib/libcrypto/doc/X509_NAME_get_index_by_NID.pod b/src/lib/libcrypto/doc/X509_NAME_get_index_by_NID.pod
index 333323d734..3b1f9ff43b 100644
--- a/src/lib/libcrypto/doc/X509_NAME_get_index_by_NID.pod
+++ b/src/lib/libcrypto/doc/X509_NAME_get_index_by_NID.pod
@@ -8,14 +8,16 @@ X509_NAME lookup and enumeration functions
8 8
9=head1 SYNOPSIS 9=head1 SYNOPSIS
10 10
11int X509_NAME_get_index_by_NID(X509_NAME *name,int nid,int lastpos); 11 #include <openssl/x509.h>
12int X509_NAME_get_index_by_OBJ(X509_NAME *name,ASN1_OBJECT *obj, int lastpos);
13 12
14int X509_NAME_entry_count(X509_NAME *name); 13 int X509_NAME_get_index_by_NID(X509_NAME *name,int nid,int lastpos);
15X509_NAME_ENTRY *X509_NAME_get_entry(X509_NAME *name, int loc); 14 int X509_NAME_get_index_by_OBJ(X509_NAME *name,ASN1_OBJECT *obj, int lastpos);
16 15
17int X509_NAME_get_text_by_NID(X509_NAME *name, int nid, char *buf,int len); 16 int X509_NAME_entry_count(X509_NAME *name);
18int X509_NAME_get_text_by_OBJ(X509_NAME *name, ASN1_OBJECT *obj, char *buf,int len); 17 X509_NAME_ENTRY *X509_NAME_get_entry(X509_NAME *name, int loc);
18
19 int X509_NAME_get_text_by_NID(X509_NAME *name, int nid, char *buf,int len);
20 int X509_NAME_get_text_by_OBJ(X509_NAME *name, ASN1_OBJECT *obj, char *buf,int len);
19 21
20=head1 DESCRIPTION 22=head1 DESCRIPTION
21 23
diff --git a/src/lib/libcrypto/doc/X509_STORE_CTX_get_error.pod b/src/lib/libcrypto/doc/X509_STORE_CTX_get_error.pod
new file mode 100644
index 0000000000..a883f6c097
--- /dev/null
+++ b/src/lib/libcrypto/doc/X509_STORE_CTX_get_error.pod
@@ -0,0 +1,303 @@
1=pod
2
3=head1 NAME
4
5X509_STORE_CTX_get_error, X509_STORE_CTX_set_error, X509_STORE_CTX_get_error_depth, X509_STORE_CTX_get_current_cert, X509_STORE_CTX_get1_chain, X509_verify_cert_error_string - get or set certificate verification status information
6
7=head1 SYNOPSIS
8
9 #include <openssl/x509.h>
10 #include <openssl/x509_vfy.h>
11
12 int X509_STORE_CTX_get_error(X509_STORE_CTX *ctx);
13 void X509_STORE_CTX_set_error(X509_STORE_CTX *ctx,int s);
14 int X509_STORE_CTX_get_error_depth(X509_STORE_CTX *ctx);
15 X509 * X509_STORE_CTX_get_current_cert(X509_STORE_CTX *ctx);
16
17 STACK_OF(X509) *X509_STORE_CTX_get1_chain(X509_STORE_CTX *ctx);
18
19 const char *X509_verify_cert_error_string(long n);
20
21=head1 DESCRIPTION
22
23These functions are typically called after X509_verify_cert() has indicated
24an error or in a verification callback to determine the nature of an error.
25
26X509_STORE_CTX_get_error() returns the error code of B<ctx>, see
27the B<ERROR CODES> section for a full description of all error codes.
28
29X509_STORE_CTX_set_error() sets the error code of B<ctx> to B<s>. For example
30it might be used in a verification callback to set an error based on additional
31checks.
32
33X509_STORE_CTX_get_error_depth() returns the B<depth> of the error. This is a
34non-negative integer representing where in the certificate chain the error
35occurred. If it is zero it occured in the end entity certificate, one if
36it is the certificate which signed the end entity certificate and so on.
37
38X509_STORE_CTX_get_current_cert() returns the certificate in B<ctx> which
39caused the error or B<NULL> if no certificate is relevant.
40
41X509_STORE_CTX_get1_chain() returns a complete validate chain if a previous
42call to X509_verify_cert() is successful. If the call to X509_verify_cert()
43is B<not> successful the returned chain may be incomplete or invalid. The
44returned chain persists after the B<ctx> structure is freed, when it is
45no longer needed it should be free up using:
46
47 sk_X509_pop_free(chain, X509_free);
48
49X509_verify_cert_error_string() returns a human readable error string for
50verification error B<n>.
51
52=head1 RETURN VALUES
53
54X509_STORE_CTX_get_error() returns B<X509_V_OK> or an error code.
55
56X509_STORE_CTX_get_error_depth() returns a non-negative error depth.
57
58X509_STORE_CTX_get_current_cert() returns the cerificate which caused the
59error or B<NULL> if no certificate is relevant to the error.
60
61X509_verify_cert_error_string() returns a human readable error string for
62verification error B<n>.
63
64=head1 ERROR CODES
65
66A list of error codes and messages is shown below. Some of the
67error codes are defined but currently never returned: these are described as
68"unused".
69
70=over 4
71
72=item B<X509_V_OK: ok>
73
74the operation was successful.
75
76=item B<X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT: unable to get issuer certificate>
77
78the issuer certificate could not be found: this occurs if the issuer certificate
79of an untrusted certificate cannot be found.
80
81=item B<X509_V_ERR_UNABLE_TO_GET_CRL: unable to get certificate CRL>
82
83the CRL of a certificate could not be found.
84
85=item B<X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE: unable to decrypt certificate's signature>
86
87the certificate signature could not be decrypted. This means that the actual
88signature value could not be determined rather than it not matching the
89expected value, this is only meaningful for RSA keys.
90
91=item B<X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE: unable to decrypt CRL's signature>
92
93the CRL signature could not be decrypted: this means that the actual signature
94value could not be determined rather than it not matching the expected value.
95Unused.
96
97=item B<X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY: unable to decode issuer public key>
98
99the public key in the certificate SubjectPublicKeyInfo could not be read.
100
101=item B<X509_V_ERR_CERT_SIGNATURE_FAILURE: certificate signature failure>
102
103the signature of the certificate is invalid.
104
105=item B<X509_V_ERR_CRL_SIGNATURE_FAILURE: CRL signature failure>
106
107the signature of the certificate is invalid.
108
109=item B<X509_V_ERR_CERT_NOT_YET_VALID: certificate is not yet valid>
110
111the certificate is not yet valid: the notBefore date is after the current time.
112
113=item B<X509_V_ERR_CERT_HAS_EXPIRED: certificate has expired>
114
115the certificate has expired: that is the notAfter date is before the current time.
116
117=item B<X509_V_ERR_CRL_NOT_YET_VALID: CRL is not yet valid>
118
119the CRL is not yet valid.
120
121=item B<X509_V_ERR_CRL_HAS_EXPIRED: CRL has expired>
122
123the CRL has expired.
124
125=item B<X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD: format error in certificate's notBefore field>
126
127the certificate notBefore field contains an invalid time.
128
129=item B<X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD: format error in certificate's notAfter field>
130
131the certificate notAfter field contains an invalid time.
132
133=item B<X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD: format error in CRL's lastUpdate field>
134
135the CRL lastUpdate field contains an invalid time.
136
137=item B<X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD: format error in CRL's nextUpdate field>
138
139the CRL nextUpdate field contains an invalid time.
140
141=item B<X509_V_ERR_OUT_OF_MEM: out of memory>
142
143an error occurred trying to allocate memory. This should never happen.
144
145=item B<X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT: self signed certificate>
146
147the passed certificate is self signed and the same certificate cannot be found
148in the list of trusted certificates.
149
150=item B<X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN: self signed certificate in certificate chain>
151
152the certificate chain could be built up using the untrusted certificates but
153the root could not be found locally.
154
155=item B<X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY: unable to get local issuer certificate>
156
157the issuer certificate of a locally looked up certificate could not be found.
158This normally means the list of trusted certificates is not complete.
159
160=item B<X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE: unable to verify the first certificate>
161
162no signatures could be verified because the chain contains only one certificate
163and it is not self signed.
164
165=item B<X509_V_ERR_CERT_CHAIN_TOO_LONG: certificate chain too long>
166
167the certificate chain length is greater than the supplied maximum depth. Unused.
168
169=item B<X509_V_ERR_CERT_REVOKED: certificate revoked>
170
171the certificate has been revoked.
172
173=item B<X509_V_ERR_INVALID_CA: invalid CA certificate>
174
175a CA certificate is invalid. Either it is not a CA or its extensions are not
176consistent with the supplied purpose.
177
178=item B<X509_V_ERR_PATH_LENGTH_EXCEEDED: path length constraint exceeded>
179
180the basicConstraints pathlength parameter has been exceeded.
181
182=item B<X509_V_ERR_INVALID_PURPOSE: unsupported certificate purpose>
183
184the supplied certificate cannot be used for the specified purpose.
185
186=item B<X509_V_ERR_CERT_UNTRUSTED: certificate not trusted>
187
188the root CA is not marked as trusted for the specified purpose.
189
190=item B<X509_V_ERR_CERT_REJECTED: certificate rejected>
191
192the root CA is marked to reject the specified purpose.
193
194=item B<X509_V_ERR_SUBJECT_ISSUER_MISMATCH: subject issuer mismatch>
195
196the current candidate issuer certificate was rejected because its subject name
197did not match the issuer name of the current certificate. This is only set
198if issuer check debugging is enabled it is used for status notification and
199is B<not> in itself an error.
200
201=item B<X509_V_ERR_AKID_SKID_MISMATCH: authority and subject key identifier mismatch>
202
203the current candidate issuer certificate was rejected because its subject key
204identifier was present and did not match the authority key identifier current
205certificate. This is only set if issuer check debugging is enabled it is used
206for status notification and is B<not> in itself an error.
207
208=item B<X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH: authority and issuer serial number mismatch>
209
210the current candidate issuer certificate was rejected because its issuer name
211and serial number was present and did not match the authority key identifier of
212the current certificate. This is only set if issuer check debugging is enabled
213it is used for status notification and is B<not> in itself an error.
214
215=item B<X509_V_ERR_KEYUSAGE_NO_CERTSIGN:key usage does not include certificate signing>
216
217the current candidate issuer certificate was rejected because its keyUsage
218extension does not permit certificate signing. This is only set if issuer check
219debugging is enabled it is used for status notification and is B<not> in itself
220an error.
221
222=item B<X509_V_ERR_INVALID_EXTENSION: invalid or inconsistent certificate extension>
223
224A certificate extension had an invalid value (for example an incorrect
225encoding) or some value inconsistent with other extensions.
226
227
228=item B<X509_V_ERR_INVALID_POLICY_EXTENSION: invalid or inconsistent certificate policy extension>
229
230A certificate policies extension had an invalid value (for example an incorrect
231encoding) or some value inconsistent with other extensions. This error only
232occurs if policy processing is enabled.
233
234=item B<X509_V_ERR_NO_EXPLICIT_POLICY: no explicit policy>
235
236The verification flags were set to require and explicit policy but none was
237present.
238
239=item B<X509_V_ERR_DIFFERENT_CRL_SCOPE: Different CRL scope>
240
241The only CRLs that could be found did not match the scope of the certificate.
242
243=item B<X509_V_ERR_UNSUPPORTED_EXTENSION_FEATURE: Unsupported extension feature>
244
245Some feature of a certificate extension is not supported. Unused.
246
247=item B<X509_V_ERR_PERMITTED_VIOLATION: permitted subtree violation>
248
249A name constraint violation occured in the permitted subtrees.
250
251=item B<X509_V_ERR_EXCLUDED_VIOLATION: excluded subtree violation>
252
253A name constraint violation occured in the excluded subtrees.
254
255=item B<X509_V_ERR_SUBTREE_MINMAX: name constraints minimum and maximum not supported>
256
257A certificate name constraints extension included a minimum or maximum field:
258this is not supported.
259
260=item B<X509_V_ERR_UNSUPPORTED_CONSTRAINT_TYPE: unsupported name constraint type>
261
262An unsupported name constraint type was encountered. OpenSSL currently only
263supports directory name, DNS name, email and URI types.
264
265=item B<X509_V_ERR_UNSUPPORTED_CONSTRAINT_SYNTAX: unsupported or invalid name constraint syntax>
266
267The format of the name constraint is not recognised: for example an email
268address format of a form not mentioned in RFC3280. This could be caused by
269a garbage extension or some new feature not currently supported.
270
271=item B<X509_V_ERR_CRL_PATH_VALIDATION_ERROR: CRL path validation error>
272
273An error occured when attempting to verify the CRL path. This error can only
274happen if extended CRL checking is enabled.
275
276=item B<X509_V_ERR_APPLICATION_VERIFICATION: application verification failure>
277
278an application specific error. This will never be returned unless explicitly
279set by an application.
280
281=head1 NOTES
282
283The above functions should be used instead of directly referencing the fields
284in the B<X509_VERIFY_CTX> structure.
285
286In versions of OpenSSL before 1.0 the current certificate returned by
287X509_STORE_CTX_get_current_cert() was never B<NULL>. Applications should
288check the return value before printing out any debugging information relating
289to the current certificate.
290
291If an unrecognised error code is passed to X509_verify_cert_error_string() the
292numerical value of the unknown code is returned in a static buffer. This is not
293thread safe but will never happen unless an invalid code is passed.
294
295=head1 SEE ALSO
296
297L<X509_verify_cert(3)|X509_verify_cert(3)>
298
299=head1 HISTORY
300
301TBA
302
303=cut
diff --git a/src/lib/libcrypto/doc/X509_STORE_CTX_get_ex_new_index.pod b/src/lib/libcrypto/doc/X509_STORE_CTX_get_ex_new_index.pod
new file mode 100644
index 0000000000..8d6b9dda47
--- /dev/null
+++ b/src/lib/libcrypto/doc/X509_STORE_CTX_get_ex_new_index.pod
@@ -0,0 +1,41 @@
1=pod
2
3=head1 NAME
4
5X509_STORE_CTX_get_ex_new_index, X509_STORE_CTX_set_ex_data, X509_STORE_CTX_get_ex_data - add application specific data to X509_STORE_CTX structures
6
7=head1 SYNOPSIS
8
9 #include <openssl/x509_vfy.h>
10
11 int X509_STORE_CTX_get_ex_new_index(long argl, void *argp,
12 CRYPTO_EX_new *new_func,
13 CRYPTO_EX_dup *dup_func,
14 CRYPTO_EX_free *free_func);
15
16 int X509_STORE_CTX_set_ex_data(X509_STORE_CTX *d, int idx, void *arg);
17
18 char *X509_STORE_CTX_get_ex_data(X509_STORE_CTX *d, int idx);
19
20=head1 DESCRIPTION
21
22These functions handle application specific data in X509_STORE_CTX structures.
23Their usage is identical to that of RSA_get_ex_new_index(), RSA_set_ex_data()
24and RSA_get_ex_data() as described in L<RSA_get_ex_new_index(3)>.
25
26=head1 NOTES
27
28This mechanism is used internally by the B<ssl> library to store the B<SSL>
29structure associated with a verification operation in an B<X509_STORE_CTX>
30structure.
31
32=head1 SEE ALSO
33
34L<RSA_get_ex_new_index(3)|RSA_get_ex_new_index(3)>
35
36=head1 HISTORY
37
38X509_STORE_CTX_get_ex_new_index(), X509_STORE_CTX_set_ex_data() and
39X509_STORE_CTX_get_ex_data() are available since OpenSSL 0.9.5.
40
41=cut
diff --git a/src/lib/libcrypto/doc/X509_STORE_CTX_new.pod b/src/lib/libcrypto/doc/X509_STORE_CTX_new.pod
new file mode 100644
index 0000000000..b17888f149
--- /dev/null
+++ b/src/lib/libcrypto/doc/X509_STORE_CTX_new.pod
@@ -0,0 +1,122 @@
1=pod
2
3=head1 NAME
4
5X509_STORE_CTX_new, X509_STORE_CTX_cleanup, X509_STORE_CTX_free, X509_STORE_CTX_init, X509_STORE_CTX_trusted_stack, X509_STORE_CTX_set_cert, X509_STORE_CTX_set_chain, X509_STORE_CTX_set0_crls, X509_STORE_CTX_get0_param, X509_STORE_CTX_set0_param, X509_STORE_CTX_set_default - X509_STORE_CTX initialisation
6
7=head1 SYNOPSIS
8
9 #include <openssl/x509_vfy.h>
10
11 X509_STORE_CTX *X509_STORE_CTX_new(void);
12 void X509_STORE_CTX_cleanup(X509_STORE_CTX *ctx);
13 void X509_STORE_CTX_free(X509_STORE_CTX *ctx);
14
15 int X509_STORE_CTX_init(X509_STORE_CTX *ctx, X509_STORE *store,
16 X509 *x509, STACK_OF(X509) *chain);
17
18 void X509_STORE_CTX_trusted_stack(X509_STORE_CTX *ctx, STACK_OF(X509) *sk);
19
20 void X509_STORE_CTX_set_cert(X509_STORE_CTX *ctx,X509 *x);
21 void X509_STORE_CTX_set_chain(X509_STORE_CTX *ctx,STACK_OF(X509) *sk);
22 void X509_STORE_CTX_set0_crls(X509_STORE_CTX *ctx, STACK_OF(X509_CRL) *sk);
23
24 X509_VERIFY_PARAM *X509_STORE_CTX_get0_param(X509_STORE_CTX *ctx);
25 void X509_STORE_CTX_set0_param(X509_STORE_CTX *ctx, X509_VERIFY_PARAM *param);
26 int X509_STORE_CTX_set_default(X509_STORE_CTX *ctx, const char *name);
27
28=head1 DESCRIPTION
29
30These functions initialise an B<X509_STORE_CTX> structure for subsequent use
31by X509_verify_cert().
32
33X509_STORE_CTX_new() returns a newly initialised B<X509_STORE_CTX> structure.
34
35X509_STORE_CTX_cleanup() internally cleans up an B<X509_STORE_CTX> structure.
36The context can then be reused with an new call to X509_STORE_CTX_init().
37
38X509_STORE_CTX_free() completely frees up B<ctx>. After this call B<ctx>
39is no longer valid.
40
41X509_STORE_CTX_init() sets up B<ctx> for a subsequent verification operation.
42The trusted certificate store is set to B<store>, the end entity certificate
43to be verified is set to B<x509> and a set of additional certificates (which
44will be untrusted but may be used to build the chain) in B<chain>. Any or
45all of the B<store>, B<x509> and B<chain> parameters can be B<NULL>.
46
47X509_STORE_CTX_trusted_stack() sets the set of trusted certificates of B<ctx>
48to B<sk>. This is an alternative way of specifying trusted certificates
49instead of using an B<X509_STORE>.
50
51X509_STORE_CTX_set_cert() sets the certificate to be vertified in B<ctx> to
52B<x>.
53
54X509_STORE_CTX_set_chain() sets the additional certificate chain used by B<ctx>
55to B<sk>.
56
57X509_STORE_CTX_set0_crls() sets a set of CRLs to use to aid certificate
58verification to B<sk>. These CRLs will only be used if CRL verification is
59enabled in the associated B<X509_VERIFY_PARAM> structure. This might be
60used where additional "useful" CRLs are supplied as part of a protocol,
61for example in a PKCS#7 structure.
62
63X509_VERIFY_PARAM *X509_STORE_CTX_get0_param() retrieves an intenal pointer
64to the verification parameters associated with B<ctx>.
65
66X509_STORE_CTX_set0_param() sets the intenal verification parameter pointer
67to B<param>. After this call B<param> should not be used.
68
69X509_STORE_CTX_set_default() looks up and sets the default verification
70method to B<name>. This uses the function X509_VERIFY_PARAM_lookup() to
71find an appropriate set of parameters from B<name>.
72
73=head1 NOTES
74
75The certificates and CRLs in a store are used internally and should B<not>
76be freed up until after the associated B<X509_STORE_CTX> is freed. Legacy
77applications might implicitly use an B<X509_STORE_CTX> like this:
78
79 X509_STORE_CTX ctx;
80 X509_STORE_CTX_init(&ctx, store, cert, chain);
81
82this is B<not> recommended in new applications they should instead do:
83
84 X509_STORE_CTX *ctx;
85 ctx = X509_STORE_CTX_new();
86 if (ctx == NULL)
87 /* Bad error */
88 X509_STORE_CTX_init(ctx, store, cert, chain);
89
90=head1 BUGS
91
92The certificates and CRLs in a context are used internally and should B<not>
93be freed up until after the associated B<X509_STORE_CTX> is freed. Copies
94should be made or reference counts increased instead.
95
96=head1 RETURN VALUES
97
98X509_STORE_CTX_new() returns an newly allocates context or B<NULL> is an
99error occurred.
100
101X509_STORE_CTX_init() returns 1 for success or 0 if an error occurred.
102
103X509_STORE_CTX_get0_param() returns a pointer to an B<X509_VERIFY_PARAM>
104structure or B<NULL> if an error occurred.
105
106X509_STORE_CTX_cleanup(), X509_STORE_CTX_free(), X509_STORE_CTX_trusted_stack(),
107X509_STORE_CTX_set_cert(), X509_STORE_CTX_set_chain(),
108X509_STORE_CTX_set0_crls() and X509_STORE_CTX_set0_param() do not return
109values.
110
111X509_STORE_CTX_set_default() returns 1 for success or 0 if an error occurred.
112
113=head1 SEE ALSO
114
115L<X509_verify_cert(3)|X509_verify_cert(3)>
116L<X509_VERIFY_PARAM_set_flags(3)|X509_VERIFY_PARAM_set_flags(3)>
117
118=head1 HISTORY
119
120X509_STORE_CTX_set0_crls() was first added to OpenSSL 1.0.0
121
122=cut
diff --git a/src/lib/libcrypto/doc/X509_STORE_CTX_set_verify_cb.pod b/src/lib/libcrypto/doc/X509_STORE_CTX_set_verify_cb.pod
new file mode 100644
index 0000000000..b9787a6ca6
--- /dev/null
+++ b/src/lib/libcrypto/doc/X509_STORE_CTX_set_verify_cb.pod
@@ -0,0 +1,161 @@
1=pod
2
3=head1 NAME
4
5X509_STORE_CTX_set_verify_cb - set verification callback
6
7=head1 SYNOPSIS
8
9 #include <openssl/x509_vfy.h>
10
11 void X509_STORE_CTX_set_verify_cb(X509_STORE_CTX *ctx,
12 int (*verify_cb)(int ok, X509_STORE_CTX *ctx));
13
14=head1 DESCRIPTION
15
16X509_STORE_CTX_set_verify_cb() sets the verification callback of B<ctx> to
17B<verify_cb> overwriting any existing callback.
18
19The verification callback can be used to customise the operation of certificate
20verification, either by overriding error conditions or logging errors for
21debugging purposes.
22
23However a verification callback is B<not> essential and the default operation
24is often sufficient.
25
26The B<ok> parameter to the callback indicates the value the callback should
27return to retain the default behaviour. If it is zero then and error condition
28is indicated. If it is 1 then no error occurred. If the flag
29B<X509_V_FLAG_NOTIFY_POLICY> is set then B<ok> is set to 2 to indicate the
30policy checking is complete.
31
32The B<ctx> parameter to the callback is the B<X509_STORE_CTX> structure that
33is performing the verification operation. A callback can examine this
34structure and receive additional information about the error, for example
35by calling X509_STORE_CTX_get_current_cert(). Additional application data can
36be passed to the callback via the B<ex_data> mechanism.
37
38=head1 WARNING
39
40In general a verification callback should B<NOT> unconditionally return 1 in
41all circumstances because this will allow verification to succeed no matter
42what the error. This effectively removes all security from the application
43because B<any> certificate (including untrusted generated ones) will be
44accepted.
45
46=head1 NOTES
47
48The verification callback can be set and inherited from the parent structure
49performing the operation. In some cases (such as S/MIME verification) the
50B<X509_STORE_CTX> structure is created and destroyed internally and the
51only way to set a custom verification callback is by inheriting it from the
52associated B<X509_STORE>.
53
54=head1 RETURN VALUES
55
56X509_STORE_CTX_set_verify_cb() does not return a value.
57
58=head1 EXAMPLES
59
60Default callback operation:
61
62 int verify_callback(int ok, X509_STORE_CTX *ctx)
63 {
64 return ok;
65 }
66
67Simple example, suppose a certificate in the chain is expired and we wish
68to continue after this error:
69
70 int verify_callback(int ok, X509_STORE_CTX *ctx)
71 {
72 /* Tolerate certificate expiration */
73 if (X509_STORE_CTX_get_error(ctx) == X509_V_ERR_CERT_HAS_EXPIRED)
74 return 1;
75 /* Otherwise don't override */
76 return ok;
77 }
78
79More complex example, we don't wish to continue after B<any> certificate has
80expired just one specific case:
81
82 int verify_callback(int ok, X509_STORE_CTX *ctx)
83 {
84 int err = X509_STORE_CTX_get_error(ctx);
85 X509 *err_cert = X509_STORE_CTX_get_current_cert(ctx);
86 if (err == X509_V_ERR_CERT_HAS_EXPIRED)
87 {
88 if (check_is_acceptable_expired_cert(err_cert)
89 return 1;
90 }
91 return ok;
92 }
93
94Full featured logging callback. In this case the B<bio_err> is assumed to be
95a global logging B<BIO>, an alternative would to store a BIO in B<ctx> using
96B<ex_data>.
97
98 int verify_callback(int ok, X509_STORE_CTX *ctx)
99 {
100 X509 *err_cert;
101 int err,depth;
102
103 err_cert = X509_STORE_CTX_get_current_cert(ctx);
104 err = X509_STORE_CTX_get_error(ctx);
105 depth = X509_STORE_CTX_get_error_depth(ctx);
106
107 BIO_printf(bio_err,"depth=%d ",depth);
108 if (err_cert)
109 {
110 X509_NAME_print_ex(bio_err, X509_get_subject_name(err_cert),
111 0, XN_FLAG_ONELINE);
112 BIO_puts(bio_err, "\n");
113 }
114 else
115 BIO_puts(bio_err, "<no cert>\n");
116 if (!ok)
117 BIO_printf(bio_err,"verify error:num=%d:%s\n",err,
118 X509_verify_cert_error_string(err));
119 switch (err)
120 {
121 case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT:
122 BIO_puts(bio_err,"issuer= ");
123 X509_NAME_print_ex(bio_err, X509_get_issuer_name(err_cert),
124 0, XN_FLAG_ONELINE);
125 BIO_puts(bio_err, "\n");
126 break;
127 case X509_V_ERR_CERT_NOT_YET_VALID:
128 case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD:
129 BIO_printf(bio_err,"notBefore=");
130 ASN1_TIME_print(bio_err,X509_get_notBefore(err_cert));
131 BIO_printf(bio_err,"\n");
132 break;
133 case X509_V_ERR_CERT_HAS_EXPIRED:
134 case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD:
135 BIO_printf(bio_err,"notAfter=");
136 ASN1_TIME_print(bio_err,X509_get_notAfter(err_cert));
137 BIO_printf(bio_err,"\n");
138 break;
139 case X509_V_ERR_NO_EXPLICIT_POLICY:
140 policies_print(bio_err, ctx);
141 break;
142 }
143 if (err == X509_V_OK && ok == 2)
144 /* print out policies */
145
146 BIO_printf(bio_err,"verify return:%d\n",ok);
147 return(ok);
148 }
149
150=head1 SEE ALSO
151
152L<X509_STORE_CTX_get_error(3)|X509_STORE_CTX_get_error(3)>
153L<X509_STORE_set_verify_cb_func(3)|X509_STORE_set_verify_cb_func(3)>
154L<X509_STORE_CTX_get_ex_new_index(3)|X509_STORE_CTX_get_ex_new_index(3)>
155
156=head1 HISTORY
157
158X509_STORE_CTX_set_verify_cb() is available in all versions of SSLeay and
159OpenSSL.
160
161=cut
diff --git a/src/lib/libcrypto/doc/X509_STORE_set_verify_cb_func.pod b/src/lib/libcrypto/doc/X509_STORE_set_verify_cb_func.pod
new file mode 100644
index 0000000000..29e3bbe3bc
--- /dev/null
+++ b/src/lib/libcrypto/doc/X509_STORE_set_verify_cb_func.pod
@@ -0,0 +1,54 @@
1=pod
2
3=head1 NAME
4
5X509_STORE_set_verify_cb_func, X509_STORE_set_verify_cb - set verification callback
6
7=head1 SYNOPSIS
8
9 #include <openssl/x509_vfy.h>
10
11 void X509_STORE_set_verify_cb(X509_STORE *st,
12 int (*verify_cb)(int ok, X509_STORE_CTX *ctx));
13
14 void X509_STORE_set_verify_cb_func(X509_STORE *st,
15 int (*verify_cb)(int ok, X509_STORE_CTX *ctx));
16
17=head1 DESCRIPTION
18
19X509_STORE_set_verify_cb() sets the verification callback of B<ctx> to
20B<verify_cb> overwriting any existing callback.
21
22X509_STORE_set_verify_cb_func() also sets the verification callback but it
23is implemented as a macro.
24
25=head1 NOTES
26
27The verification callback from an B<X509_STORE> is inherited by
28the corresponding B<X509_STORE_CTX> structure when it is initialized. This can
29be used to set the verification callback when the B<X509_STORE_CTX> is
30otherwise inaccessible (for example during S/MIME verification).
31
32=head1 BUGS
33
34The macro version of this function was the only one available before
35OpenSSL 1.0.0.
36
37=head1 RETURN VALUES
38
39X509_STORE_set_verify_cb() and X509_STORE_set_verify_cb_func() do not return
40a value.
41
42=head1 SEE ALSO
43
44L<X509_STORE_CTX_set_verify_cb(3)|X509_STORE_CTX_set_verify_cb(3)>
45L<CMS_verify(3)|CMS_verify(3)>
46
47=head1 HISTORY
48
49X509_STORE_set_verify_cb_func() is available in all versions of SSLeay and
50OpenSSL.
51
52X509_STORE_set_verify_cb() was added to OpenSSL 1.0.0.
53
54=cut
diff --git a/src/lib/libcrypto/doc/X509_VERIFY_PARAM_set_flags.pod b/src/lib/libcrypto/doc/X509_VERIFY_PARAM_set_flags.pod
new file mode 100644
index 0000000000..b68eece033
--- /dev/null
+++ b/src/lib/libcrypto/doc/X509_VERIFY_PARAM_set_flags.pod
@@ -0,0 +1,171 @@
1=pod
2
3=head1 NAME
4
5X509_VERIFY_PARAM_set_flags, X509_VERIFY_PARAM_clear_flags, X509_VERIFY_PARAM_get_flags, X509_VERIFY_PARAM_set_purpose, X509_VERIFY_PARAM_set_trust, X509_VERIFY_PARAM_set_depth, X509_VERIFY_PARAM_get_depth, X509_VERIFY_PARAM_set_time, X509_VERIFY_PARAM_add0_policy, X509_VERIFY_PARAM_set1_policies - X509 verification parameters
6
7=head1 SYNOPSIS
8
9 #include <openssl/x509_vfy.h>
10
11 int X509_VERIFY_PARAM_set_flags(X509_VERIFY_PARAM *param, unsigned long flags);
12 int X509_VERIFY_PARAM_clear_flags(X509_VERIFY_PARAM *param,
13 unsigned long flags);
14 unsigned long X509_VERIFY_PARAM_get_flags(X509_VERIFY_PARAM *param);
15
16 int X509_VERIFY_PARAM_set_purpose(X509_VERIFY_PARAM *param, int purpose);
17 int X509_VERIFY_PARAM_set_trust(X509_VERIFY_PARAM *param, int trust);
18
19 void X509_VERIFY_PARAM_set_time(X509_VERIFY_PARAM *param, time_t t);
20
21 int X509_VERIFY_PARAM_add0_policy(X509_VERIFY_PARAM *param,
22 ASN1_OBJECT *policy);
23 int X509_VERIFY_PARAM_set1_policies(X509_VERIFY_PARAM *param,
24 STACK_OF(ASN1_OBJECT) *policies);
25
26 void X509_VERIFY_PARAM_set_depth(X509_VERIFY_PARAM *param, int depth);
27 int X509_VERIFY_PARAM_get_depth(const X509_VERIFY_PARAM *param);
28
29=head1 DESCRIPTION
30
31These functions manipulate the B<X509_VERIFY_PARAM> structure associated with
32a certificate verification operation.
33
34The X509_VERIFY_PARAM_set_flags() function sets the flags in B<param> by oring
35it with B<flags>. See the B<VERIFICATION FLAGS> section for a complete
36description of values the B<flags> parameter can take.
37
38X509_VERIFY_PARAM_get_flags() returns the flags in B<param>.
39
40X509_VERIFY_PARAM_clear_flags() clears the flags B<flags> in B<param>.
41
42X509_VERIFY_PARAM_set_purpose() sets the verification purpose in B<param>
43to B<purpose>. This determines the acceptable purpose of the certificate
44chain, for example SSL client or SSL server.
45
46X509_VERIFY_PARAM_set_trust() sets the trust setting in B<param> to
47B<trust>.
48
49X509_VERIFY_PARAM_set_time() sets the verification time in B<param> to
50B<t>. Normally the current time is used.
51
52X509_VERIFY_PARAM_add0_policy() enables policy checking (it is disabled
53by default) and adds B<policy> to the acceptable policy set.
54
55X509_VERIFY_PARAM_set1_policies() enables policy checking (it is disabled
56by default) and sets the acceptable policy set to B<policies>. Any existing
57policy set is cleared. The B<policies> parameter can be B<NULL> to clear
58an existing policy set.
59
60X509_VERIFY_PARAM_set_depth() sets the maximum verification depth to B<depth>.
61That is the maximum number of untrusted CA certificates that can appear in a
62chain.
63
64=head1 RETURN VALUES
65
66X509_VERIFY_PARAM_set_flags(), X509_VERIFY_PARAM_clear_flags(),
67X509_VERIFY_PARAM_set_purpose(), X509_VERIFY_PARAM_set_trust(),
68X509_VERIFY_PARAM_add0_policy() and X509_VERIFY_PARAM_set1_policies() return 1
69for success and 0 for failure.
70
71X509_VERIFY_PARAM_get_flags() returns the current verification flags.
72
73X509_VERIFY_PARAM_set_time() and X509_VERIFY_PARAM_set_depth() do not return
74values.
75
76X509_VERIFY_PARAM_get_depth() returns the current verification depth.
77
78=head1 VERIFICATION FLAGS
79
80The verification flags consists of zero or more of the following flags
81ored together.
82
83B<X509_V_FLAG_CRL_CHECK> enables CRL checking for the certificate chain leaf
84certificate. An error occurs if a suitable CRL cannot be found.
85
86B<X509_V_FLAG_CRL_CHECK_ALL> enables CRL checking for the entire certificate
87chain.
88
89B<X509_V_FLAG_IGNORE_CRITICAL> disabled critical extension checking. By default
90any unhandled critical extensions in certificates or (if checked) CRLs results
91in a fatal error. If this flag is set unhandled critical extensions are
92ignored. B<WARNING> setting this option for anything other than debugging
93purposes can be a security risk. Finer control over which extensions are
94supported can be performed in the verification callback.
95
96THe B<X509_V_FLAG_X509_STRICT> flag disables workarounds for some broken
97certificates and makes the verification strictly apply B<X509> rules.
98
99B<X509_V_FLAG_ALLOW_PROXY_CERTS> enables proxy certificate verification.
100
101B<X509_V_FLAG_POLICY_CHECK> enables certificate policy checking, by default
102no policy checking is peformed. Additional information is sent to the
103verification callback relating to policy checking.
104
105B<X509_V_FLAG_EXPLICIT_POLICY>, B<X509_V_FLAG_INHIBIT_ANY> and
106B<X509_V_FLAG_INHIBIT_MAP> set the B<require explicit policy>, B<inhibit any
107policy> and B<inhibit policy mapping> flags respectively as defined in
108B<RFC3280>. Policy checking is automatically enabled if any of these flags
109are set.
110
111If B<X509_V_FLAG_NOTIFY_POLICY> is set and the policy checking is successful
112a special status code is set to the verification callback. This permits it
113to examine the valid policy tree and perform additional checks or simply
114log it for debugging purposes.
115
116By default some addtional features such as indirect CRLs and CRLs signed by
117different keys are disabled. If B<X509_V_FLAG_EXTENDED_CRL_SUPPORT> is set
118they are enabled.
119
120If B<X509_V_FLAG_USE_DELTAS> ise set delta CRLs (if present) are used to
121determine certificate status. If not set deltas are ignored.
122
123B<X509_V_FLAG_CHECK_SS_SIGNATURE> enables checking of the root CA self signed
124cerificate signature. By default this check is disabled because it doesn't
125add any additional security but in some cases applications might want to
126check the signature anyway. A side effect of not checking the root CA
127signature is that disabled or unsupported message digests on the root CA
128are not treated as fatal errors.
129
130The B<X509_V_FLAG_CB_ISSUER_CHECK> flag enables debugging of certificate
131issuer checks. It is B<not> needed unless you are logging certificate
132verification. If this flag is set then additional status codes will be sent
133to the verification callback and it B<must> be prepared to handle such cases
134without assuming they are hard errors.
135
136=head1 NOTES
137
138The above functions should be used to manipulate verification parameters
139instead of legacy functions which work in specific structures such as
140X509_STORE_CTX_set_flags().
141
142=head1 BUGS
143
144Delta CRL checking is currently primitive. Only a single delta can be used and
145(partly due to limitations of B<X509_STORE>) constructed CRLs are not
146maintained.
147
148If CRLs checking is enable CRLs are expected to be available in the
149corresponding B<X509_STORE> structure. No attempt is made to download
150CRLs from the CRL distribution points extension.
151
152=head1 EXAMPLE
153
154Enable CRL checking when performing certificate verification during SSL
155connections associated with an B<SSL_CTX> structure B<ctx>:
156
157 X509_VERIFY_PARAM *param;
158 param = X509_VERIFY_PARAM_new();
159 X509_VERIFY_PARAM_set_flags(param, X509_V_FLAG_CRL_CHECK);
160 SSL_CTX_set1_param(ctx, param);
161 X509_VERIFY_PARAM_free(param);
162
163=head1 SEE ALSO
164
165L<X509_verify_cert(3)|X509_verify_cert(3)>
166
167=head1 HISTORY
168
169TBA
170
171=cut
diff --git a/src/lib/libcrypto/doc/X509_new.pod b/src/lib/libcrypto/doc/X509_new.pod
index fd5fc65ce1..d38872335f 100644
--- a/src/lib/libcrypto/doc/X509_new.pod
+++ b/src/lib/libcrypto/doc/X509_new.pod
@@ -6,6 +6,8 @@ X509_new, X509_free - X509 certificate ASN1 allocation functions
6 6
7=head1 SYNOPSIS 7=head1 SYNOPSIS
8 8
9 #include <openssl/x509.h>
10
9 X509 *X509_new(void); 11 X509 *X509_new(void);
10 void X509_free(X509 *a); 12 void X509_free(X509 *a);
11 13
diff --git a/src/lib/libcrypto/doc/X509_verify_cert.pod b/src/lib/libcrypto/doc/X509_verify_cert.pod
new file mode 100644
index 0000000000..5253bdcd70
--- /dev/null
+++ b/src/lib/libcrypto/doc/X509_verify_cert.pod
@@ -0,0 +1,53 @@
1=pod
2
3=head1 NAME
4
5X509_verify_cert - discover and verify X509 certificte chain
6
7=head1 SYNOPSIS
8
9 #include <openssl/x509.h>
10
11 int X509_verify_cert(X509_STORE_CTX *ctx);
12
13=head1 DESCRIPTION
14
15The X509_verify_cert() function attempts to discover and validate a
16certificate chain based on parameters in B<ctx>. A complete description of
17the process is contained in the L<verify(1)|verify(1)> manual page.
18
19=head1 RETURN VALUES
20
21If a complete chain can be built and validated this function returns 1,
22otherwise it return zero, in exceptional circumstances it can also
23return a negative code.
24
25If the function fails additional error information can be obtained by
26examining B<ctx> using, for example X509_STORE_CTX_get_error().
27
28=head1 NOTES
29
30Applications rarely call this function directly but it is used by
31OpenSSL internally for certificate validation, in both the S/MIME and
32SSL/TLS code.
33
34The negative return value from X509_verify_cert() can only occur if no
35certificate is set in B<ctx> (due to a programming error) or if a retry
36operation is requested during internal lookups (which never happens with
37standard lookup methods). It is however recommended that application check
38for <= 0 return value on error.
39
40=head1 BUGS
41
42This function uses the header B<x509.h> as opposed to most chain verification
43functiosn which use B<x509_vfy.h>.
44
45=head1 SEE ALSO
46
47L<X509_STORE_CTX_get_error(3)|X509_STORE_CTX_get_error(3)>
48
49=head1 HISTORY
50
51X509_verify_cert() is available in all versions of SSLeay and OpenSSL.
52
53=cut
diff --git a/src/lib/libcrypto/doc/d2i_RSAPublicKey.pod b/src/lib/libcrypto/doc/d2i_RSAPublicKey.pod
index 279b29c873..aa6078bcf6 100644
--- a/src/lib/libcrypto/doc/d2i_RSAPublicKey.pod
+++ b/src/lib/libcrypto/doc/d2i_RSAPublicKey.pod
@@ -11,21 +11,21 @@ d2i_Netscape_RSA - RSA public and private key encoding functions.
11 #include <openssl/rsa.h> 11 #include <openssl/rsa.h>
12 #include <openssl/x509.h> 12 #include <openssl/x509.h>
13 13
14 RSA * d2i_RSAPublicKey(RSA **a, unsigned char **pp, long length); 14 RSA * d2i_RSAPublicKey(RSA **a, const unsigned char **pp, long length);
15 15
16 int i2d_RSAPublicKey(RSA *a, unsigned char **pp); 16 int i2d_RSAPublicKey(RSA *a, unsigned char **pp);
17 17
18 RSA * d2i_RSA_PUBKEY(RSA **a, unsigned char **pp, long length); 18 RSA * d2i_RSA_PUBKEY(RSA **a, const unsigned char **pp, long length);
19 19
20 int i2d_RSA_PUBKEY(RSA *a, unsigned char **pp); 20 int i2d_RSA_PUBKEY(RSA *a, unsigned char **pp);
21 21
22 RSA * d2i_RSAPrivateKey(RSA **a, unsigned char **pp, long length); 22 RSA * d2i_RSAPrivateKey(RSA **a, const unsigned char **pp, long length);
23 23
24 int i2d_RSAPrivateKey(RSA *a, unsigned char **pp); 24 int i2d_RSAPrivateKey(RSA *a, unsigned char **pp);
25 25
26 int i2d_Netscape_RSA(RSA *a, unsigned char **pp, int (*cb)()); 26 int i2d_Netscape_RSA(RSA *a, unsigned char **pp, int (*cb)());
27 27
28 RSA * d2i_Netscape_RSA(RSA **a, unsigned char **pp, long length, int (*cb)()); 28 RSA * d2i_Netscape_RSA(RSA **a, const unsigned char **pp, long length, int (*cb)());
29 29
30=head1 DESCRIPTION 30=head1 DESCRIPTION
31 31
diff --git a/src/lib/libcrypto/doc/d2i_X509.pod b/src/lib/libcrypto/doc/d2i_X509.pod
index 5bfa18afbb..298ec54a4c 100644
--- a/src/lib/libcrypto/doc/d2i_X509.pod
+++ b/src/lib/libcrypto/doc/d2i_X509.pod
@@ -15,8 +15,8 @@ i2d_X509_fp - X509 encode and decode functions
15 X509 *d2i_X509_bio(BIO *bp, X509 **x); 15 X509 *d2i_X509_bio(BIO *bp, X509 **x);
16 X509 *d2i_X509_fp(FILE *fp, X509 **x); 16 X509 *d2i_X509_fp(FILE *fp, X509 **x);
17 17
18 int i2d_X509_bio(X509 *x, BIO *bp); 18 int i2d_X509_bio(BIO *bp, X509 *x);
19 int i2d_X509_fp(X509 *x, FILE *fp); 19 int i2d_X509_fp(FILE *fp, X509 *x);
20 20
21=head1 DESCRIPTION 21=head1 DESCRIPTION
22 22
@@ -212,11 +212,11 @@ d2i_X509(), d2i_X509_bio() and d2i_X509_fp() return a valid B<X509> structure
212or B<NULL> if an error occurs. The error code that can be obtained by 212or B<NULL> if an error occurs. The error code that can be obtained by
213L<ERR_get_error(3)|ERR_get_error(3)>. 213L<ERR_get_error(3)|ERR_get_error(3)>.
214 214
215i2d_X509(), i2d_X509_bio() and i2d_X509_fp() return a the number of bytes 215i2d_X509() returns the number of bytes successfully encoded or a negative
216successfully encoded or a negative value if an error occurs. The error code 216value if an error occurs. The error code can be obtained by
217can be obtained by L<ERR_get_error(3)|ERR_get_error(3)>. 217L<ERR_get_error(3)|ERR_get_error(3)>.
218 218
219i2d_X509_bio() and i2d_X509_fp() returns 1 for success and 0 if an error 219i2d_X509_bio() and i2d_X509_fp() return 1 for success and 0 if an error
220occurs The error code can be obtained by L<ERR_get_error(3)|ERR_get_error(3)>. 220occurs The error code can be obtained by L<ERR_get_error(3)|ERR_get_error(3)>.
221 221
222=head1 SEE ALSO 222=head1 SEE ALSO
diff --git a/src/lib/libcrypto/doc/d2i_X509_CRL.pod b/src/lib/libcrypto/doc/d2i_X509_CRL.pod
index e7295a5d61..224f9e082b 100644
--- a/src/lib/libcrypto/doc/d2i_X509_CRL.pod
+++ b/src/lib/libcrypto/doc/d2i_X509_CRL.pod
@@ -15,8 +15,8 @@ i2d_X509_CRL_bio, i2d_X509_CRL_fp - PKCS#10 certificate request functions.
15 X509_CRL *d2i_X509_CRL_bio(BIO *bp, X509_CRL **x); 15 X509_CRL *d2i_X509_CRL_bio(BIO *bp, X509_CRL **x);
16 X509_CRL *d2i_X509_CRL_fp(FILE *fp, X509_CRL **x); 16 X509_CRL *d2i_X509_CRL_fp(FILE *fp, X509_CRL **x);
17 17
18 int i2d_X509_CRL_bio(X509_CRL *x, BIO *bp); 18 int i2d_X509_CRL_bio(BIO *bp, X509_CRL *x);
19 int i2d_X509_CRL_fp(X509_CRL *x, FILE *fp); 19 int i2d_X509_CRL_fp(FILE *fp, X509_CRL *x);
20 20
21=head1 DESCRIPTION 21=head1 DESCRIPTION
22 22
diff --git a/src/lib/libcrypto/doc/d2i_X509_REQ.pod b/src/lib/libcrypto/doc/d2i_X509_REQ.pod
index ae32a3891d..91c0c1974b 100644
--- a/src/lib/libcrypto/doc/d2i_X509_REQ.pod
+++ b/src/lib/libcrypto/doc/d2i_X509_REQ.pod
@@ -15,8 +15,8 @@ i2d_X509_REQ_bio, i2d_X509_REQ_fp - PKCS#10 certificate request functions.
15 X509_REQ *d2i_X509_REQ_bio(BIO *bp, X509_REQ **x); 15 X509_REQ *d2i_X509_REQ_bio(BIO *bp, X509_REQ **x);
16 X509_REQ *d2i_X509_REQ_fp(FILE *fp, X509_REQ **x); 16 X509_REQ *d2i_X509_REQ_fp(FILE *fp, X509_REQ **x);
17 17
18 int i2d_X509_REQ_bio(X509_REQ *x, BIO *bp); 18 int i2d_X509_REQ_bio(BIO *bp, X509_REQ *x);
19 int i2d_X509_REQ_fp(X509_REQ *x, FILE *fp); 19 int i2d_X509_REQ_fp(FILE *fp, X509_REQ *x);
20 20
21=head1 DESCRIPTION 21=head1 DESCRIPTION
22 22
diff --git a/src/lib/libcrypto/doc/evp.pod b/src/lib/libcrypto/doc/evp.pod
index b3ca14314f..9faa349243 100644
--- a/src/lib/libcrypto/doc/evp.pod
+++ b/src/lib/libcrypto/doc/evp.pod
@@ -22,14 +22,24 @@ digital signatures.
22Symmetric encryption is available with the B<EVP_Encrypt>I<...> 22Symmetric encryption is available with the B<EVP_Encrypt>I<...>
23functions. The B<EVP_Digest>I<...> functions provide message digests. 23functions. The B<EVP_Digest>I<...> functions provide message digests.
24 24
25The B<EVP_PKEY>I<...> functions provide a high level interface to
26asymmetric algorithms.
27
25Algorithms are loaded with OpenSSL_add_all_algorithms(3). 28Algorithms are loaded with OpenSSL_add_all_algorithms(3).
26 29
27All the symmetric algorithms (ciphers) and digests can be replaced by ENGINE 30All the symmetric algorithms (ciphers), digests and asymmetric algorithms
28modules providing alternative implementations. If ENGINE implementations of 31(public key algorithms) can be replaced by ENGINE modules providing alternative
29ciphers or digests are registered as defaults, then the various EVP functions 32implementations. If ENGINE implementations of ciphers or digests are registered
30will automatically use those implementations automatically in preference to 33as defaults, then the various EVP functions will automatically use those
31built in software implementations. For more information, consult the engine(3) 34implementations automatically in preference to built in software
32man page. 35implementations. For more information, consult the engine(3) man page.
36
37Although low level algorithm specific functions exist for many algorithms
38their use is discouraged. They cannot be used with an ENGINE and ENGINE
39versions of new algorithms cannot be accessed using the low level functions.
40Also makes code harder to adapt to new algorithms and some options are not
41cleanly supported at the low level and some operations are more efficient
42using the high level interface.
33 43
34=head1 SEE ALSO 44=head1 SEE ALSO
35 45
diff --git a/src/lib/libcrypto/doc/i2d_CMS_bio_stream.pod b/src/lib/libcrypto/doc/i2d_CMS_bio_stream.pod
new file mode 100644
index 0000000000..558bdd0812
--- /dev/null
+++ b/src/lib/libcrypto/doc/i2d_CMS_bio_stream.pod
@@ -0,0 +1,44 @@
1=pod
2
3=head1 NAME
4
5 i2d_CMS_bio_stream - output CMS_ContentInfo structure in BER format.
6
7=head1 SYNOPSIS
8
9 #include <openssl/cms.h>
10
11 int i2d_CMS_bio_stream(BIO *out, CMS_ContentInfo *cms, BIO *data, int flags);
12
13=head1 DESCRIPTION
14
15i2d_CMS_bio_stream() outputs a CMS_ContentInfo structure in BER format.
16
17It is otherwise identical to the function SMIME_write_CMS().
18
19=head1 NOTES
20
21This function is effectively a version of the i2d_CMS_bio() supporting
22streaming.
23
24=head1 BUGS
25
26The prefix "i2d" is arguably wrong because the function outputs BER format.
27
28=head1 RETURN VALUES
29
30i2d_CMS_bio_stream() returns 1 for success or 0 for failure.
31
32=head1 SEE ALSO
33
34L<ERR_get_error(3)|ERR_get_error(3)>, L<CMS_sign(3)|CMS_sign(3)>,
35L<CMS_verify(3)|CMS_verify(3)>, L<CMS_encrypt(3)|CMS_encrypt(3)>
36L<CMS_decrypt(3)|CMS_decrypt(3)>,
37L<SMIME_write_CMS(3)|SMIME_write_CMS(3)>,
38L<PEM_write_bio_CMS_stream(3)|PEM_write_bio_CMS_stream(3)>
39
40=head1 HISTORY
41
42i2d_CMS_bio_stream() was added to OpenSSL 1.0.0
43
44=cut
diff --git a/src/lib/libcrypto/doc/i2d_PKCS7_bio_stream.pod b/src/lib/libcrypto/doc/i2d_PKCS7_bio_stream.pod
new file mode 100644
index 0000000000..dc4d884c59
--- /dev/null
+++ b/src/lib/libcrypto/doc/i2d_PKCS7_bio_stream.pod
@@ -0,0 +1,44 @@
1=pod
2
3=head1 NAME
4
5i2d_PKCS7_bio_stream - output PKCS7 structure in BER format.
6
7=head1 SYNOPSIS
8
9 #include <openssl/pkcs7.h>
10
11 int i2d_PKCS7_bio_stream(BIO *out, PKCS7 *p7, BIO *data, int flags);
12
13=head1 DESCRIPTION
14
15i2d_PKCS7_bio_stream() outputs a PKCS7 structure in BER format.
16
17It is otherwise identical to the function SMIME_write_PKCS7().
18
19=head1 NOTES
20
21This function is effectively a version of the d2i_PKCS7_bio() supporting
22streaming.
23
24=head1 BUGS
25
26The prefix "d2i" is arguably wrong because the function outputs BER format.
27
28=head1 RETURN VALUES
29
30i2d_PKCS7_bio_stream() returns 1 for success or 0 for failure.
31
32=head1 SEE ALSO
33
34L<ERR_get_error(3)|ERR_get_error(3)>, L<PKCS7_sign(3)|PKCS7_sign(3)>,
35L<PKCS7_verify(3)|PKCS7_verify(3)>, L<PKCS7_encrypt(3)|PKCS7_encrypt(3)>
36L<PKCS7_decrypt(3)|PKCS7_decrypt(3)>,
37L<SMIME_write_PKCS7(3)|SMIME_write_PKCS7(3)>,
38L<PEM_write_bio_PKCS7_stream(3)|PEM_write_bio_PKCS7_stream(3)>
39
40=head1 HISTORY
41
42i2d_PKCS7_bio_stream() was added to OpenSSL 1.0.0
43
44=cut
diff --git a/src/lib/libcrypto/dsa/dsa.h b/src/lib/libcrypto/dsa/dsa.h
index 702c50d6dc..ac50a5c846 100644
--- a/src/lib/libcrypto/dsa/dsa.h
+++ b/src/lib/libcrypto/dsa/dsa.h
@@ -88,8 +88,6 @@
88# define OPENSSL_DSA_MAX_MODULUS_BITS 10000 88# define OPENSSL_DSA_MAX_MODULUS_BITS 10000
89#endif 89#endif
90 90
91#define OPENSSL_DSA_FIPS_MIN_MODULUS_BITS 1024
92
93#define DSA_FLAG_CACHE_MONT_P 0x01 91#define DSA_FLAG_CACHE_MONT_P 0x01
94#define DSA_FLAG_NO_EXP_CONSTTIME 0x02 /* new with 0.9.7h; the built-in DSA 92#define DSA_FLAG_NO_EXP_CONSTTIME 0x02 /* new with 0.9.7h; the built-in DSA
95 * implementation now uses constant time 93 * implementation now uses constant time
@@ -99,25 +97,6 @@
99 * be used for all exponents. 97 * be used for all exponents.
100 */ 98 */
101 99
102/* If this flag is set the DSA method is FIPS compliant and can be used
103 * in FIPS mode. This is set in the validated module method. If an
104 * application sets this flag in its own methods it is its reposibility
105 * to ensure the result is compliant.
106 */
107
108#define DSA_FLAG_FIPS_METHOD 0x0400
109
110/* If this flag is set the operations normally disabled in FIPS mode are
111 * permitted it is then the applications responsibility to ensure that the
112 * usage is compliant.
113 */
114
115#define DSA_FLAG_NON_FIPS_ALLOW 0x0400
116
117#ifdef OPENSSL_FIPS
118#define FIPS_DSA_SIZE_T int
119#endif
120
121#ifdef __cplusplus 100#ifdef __cplusplus
122extern "C" { 101extern "C" {
123#endif 102#endif
@@ -139,7 +118,7 @@ struct dsa_method
139 int (*dsa_sign_setup)(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp, 118 int (*dsa_sign_setup)(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp,
140 BIGNUM **rp); 119 BIGNUM **rp);
141 int (*dsa_do_verify)(const unsigned char *dgst, int dgst_len, 120 int (*dsa_do_verify)(const unsigned char *dgst, int dgst_len,
142 DSA_SIG *sig, DSA *dsa); 121 DSA_SIG *sig, DSA *dsa);
143 int (*dsa_mod_exp)(DSA *dsa, BIGNUM *rr, BIGNUM *a1, BIGNUM *p1, 122 int (*dsa_mod_exp)(DSA *dsa, BIGNUM *rr, BIGNUM *a1, BIGNUM *p1,
144 BIGNUM *a2, BIGNUM *p2, BIGNUM *m, BN_CTX *ctx, 123 BIGNUM *a2, BIGNUM *p2, BIGNUM *m, BN_CTX *ctx,
145 BN_MONT_CTX *in_mont); 124 BN_MONT_CTX *in_mont);
@@ -152,7 +131,7 @@ struct dsa_method
152 char *app_data; 131 char *app_data;
153 /* If this is non-NULL, it is used to generate DSA parameters */ 132 /* If this is non-NULL, it is used to generate DSA parameters */
154 int (*dsa_paramgen)(DSA *dsa, int bits, 133 int (*dsa_paramgen)(DSA *dsa, int bits,
155 unsigned char *seed, int seed_len, 134 const unsigned char *seed, int seed_len,
156 int *counter_ret, unsigned long *h_ret, 135 int *counter_ret, unsigned long *h_ret,
157 BN_GENCB *cb); 136 BN_GENCB *cb);
158 /* If this is non-NULL, it is used to generate DSA keys */ 137 /* If this is non-NULL, it is used to generate DSA keys */
@@ -186,7 +165,6 @@ struct dsa_st
186 ENGINE *engine; 165 ENGINE *engine;
187 }; 166 };
188 167
189#define DSAparams_dup(x) ASN1_dup_of_const(DSA,i2d_DSAparams,d2i_DSAparams,x)
190#define d2i_DSAparams_fp(fp,x) (DSA *)ASN1_d2i_fp((char *(*)())DSA_new, \ 168#define d2i_DSAparams_fp(fp,x) (DSA *)ASN1_d2i_fp((char *(*)())DSA_new, \
191 (char *(*)())d2i_DSAparams,(fp),(unsigned char **)(x)) 169 (char *(*)())d2i_DSAparams,(fp),(unsigned char **)(x))
192#define i2d_DSAparams_fp(fp,x) ASN1_i2d_fp(i2d_DSAparams,(fp), \ 170#define i2d_DSAparams_fp(fp,x) ASN1_i2d_fp(i2d_DSAparams,(fp), \
@@ -195,6 +173,7 @@ struct dsa_st
195#define i2d_DSAparams_bio(bp,x) ASN1_i2d_bio_of_const(DSA,i2d_DSAparams,bp,x) 173#define i2d_DSAparams_bio(bp,x) ASN1_i2d_bio_of_const(DSA,i2d_DSAparams,bp,x)
196 174
197 175
176DSA *DSAparams_dup(DSA *x);
198DSA_SIG * DSA_SIG_new(void); 177DSA_SIG * DSA_SIG_new(void);
199void DSA_SIG_free(DSA_SIG *a); 178void DSA_SIG_free(DSA_SIG *a);
200int i2d_DSA_SIG(const DSA_SIG *a, unsigned char **pp); 179int i2d_DSA_SIG(const DSA_SIG *a, unsigned char **pp);
@@ -210,11 +189,6 @@ void DSA_set_default_method(const DSA_METHOD *);
210const DSA_METHOD *DSA_get_default_method(void); 189const DSA_METHOD *DSA_get_default_method(void);
211int DSA_set_method(DSA *dsa, const DSA_METHOD *); 190int DSA_set_method(DSA *dsa, const DSA_METHOD *);
212 191
213#ifdef OPENSSL_FIPS
214DSA * FIPS_dsa_new(void);
215void FIPS_dsa_free (DSA *r);
216#endif
217
218DSA * DSA_new(void); 192DSA * DSA_new(void);
219DSA * DSA_new_method(ENGINE *engine); 193DSA * DSA_new_method(ENGINE *engine);
220void DSA_free (DSA *r); 194void DSA_free (DSA *r);
@@ -246,7 +220,7 @@ DSA * DSA_generate_parameters(int bits,
246 220
247/* New version */ 221/* New version */
248int DSA_generate_parameters_ex(DSA *dsa, int bits, 222int DSA_generate_parameters_ex(DSA *dsa, int bits,
249 unsigned char *seed,int seed_len, 223 const unsigned char *seed,int seed_len,
250 int *counter_ret, unsigned long *h_ret, BN_GENCB *cb); 224 int *counter_ret, unsigned long *h_ret, BN_GENCB *cb);
251 225
252int DSA_generate_key(DSA *a); 226int DSA_generate_key(DSA *a);
@@ -275,10 +249,13 @@ int DSA_print_fp(FILE *bp, const DSA *x, int off);
275DH *DSA_dup_DH(const DSA *r); 249DH *DSA_dup_DH(const DSA *r);
276#endif 250#endif
277 251
278#ifdef OPENSSL_FIPS 252#define EVP_PKEY_CTX_set_dsa_paramgen_bits(ctx, nbits) \
279int FIPS_dsa_sig_encode(unsigned char *out, DSA_SIG *sig); 253 EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DSA, EVP_PKEY_OP_PARAMGEN, \
280int FIPS_dsa_sig_decode(DSA_SIG *sig, const unsigned char *in, int inlen); 254 EVP_PKEY_CTRL_DSA_PARAMGEN_BITS, nbits, NULL)
281#endif 255
256#define EVP_PKEY_CTRL_DSA_PARAMGEN_BITS (EVP_PKEY_ALG_CTRL + 1)
257#define EVP_PKEY_CTRL_DSA_PARAMGEN_Q_BITS (EVP_PKEY_ALG_CTRL + 2)
258#define EVP_PKEY_CTRL_DSA_PARAMGEN_MD (EVP_PKEY_ALG_CTRL + 3)
282 259
283/* BEGIN ERROR CODES */ 260/* BEGIN ERROR CODES */
284/* The following lines are auto generated by the script mkerr.pl. Any changes 261/* The following lines are auto generated by the script mkerr.pl. Any changes
@@ -290,33 +267,39 @@ void ERR_load_DSA_strings(void);
290 267
291/* Function codes. */ 268/* Function codes. */
292#define DSA_F_D2I_DSA_SIG 110 269#define DSA_F_D2I_DSA_SIG 110
270#define DSA_F_DO_DSA_PRINT 104
293#define DSA_F_DSAPARAMS_PRINT 100 271#define DSA_F_DSAPARAMS_PRINT 100
294#define DSA_F_DSAPARAMS_PRINT_FP 101 272#define DSA_F_DSAPARAMS_PRINT_FP 101
295#define DSA_F_DSA_BUILTIN_KEYGEN 119
296#define DSA_F_DSA_BUILTIN_PARAMGEN 118
297#define DSA_F_DSA_DO_SIGN 112 273#define DSA_F_DSA_DO_SIGN 112
298#define DSA_F_DSA_DO_VERIFY 113 274#define DSA_F_DSA_DO_VERIFY 113
299#define DSA_F_DSA_GENERATE_PARAMETERS 117
300#define DSA_F_DSA_NEW_METHOD 103 275#define DSA_F_DSA_NEW_METHOD 103
301#define DSA_F_DSA_PRINT 104 276#define DSA_F_DSA_PARAM_DECODE 119
302#define DSA_F_DSA_PRINT_FP 105 277#define DSA_F_DSA_PRINT_FP 105
303#define DSA_F_DSA_SET_DEFAULT_METHOD 115 278#define DSA_F_DSA_PRIV_DECODE 115
304#define DSA_F_DSA_SET_METHOD 116 279#define DSA_F_DSA_PRIV_ENCODE 116
280#define DSA_F_DSA_PUB_DECODE 117
281#define DSA_F_DSA_PUB_ENCODE 118
305#define DSA_F_DSA_SIGN 106 282#define DSA_F_DSA_SIGN 106
306#define DSA_F_DSA_SIGN_SETUP 107 283#define DSA_F_DSA_SIGN_SETUP 107
307#define DSA_F_DSA_SIG_NEW 109 284#define DSA_F_DSA_SIG_NEW 109
308#define DSA_F_DSA_VERIFY 108 285#define DSA_F_DSA_VERIFY 108
309#define DSA_F_I2D_DSA_SIG 111 286#define DSA_F_I2D_DSA_SIG 111
287#define DSA_F_OLD_DSA_PRIV_DECODE 122
288#define DSA_F_PKEY_DSA_CTRL 120
289#define DSA_F_PKEY_DSA_KEYGEN 121
310#define DSA_F_SIG_CB 114 290#define DSA_F_SIG_CB 114
311 291
312/* Reason codes. */ 292/* Reason codes. */
313#define DSA_R_BAD_Q_VALUE 102 293#define DSA_R_BAD_Q_VALUE 102
294#define DSA_R_BN_DECODE_ERROR 108
295#define DSA_R_BN_ERROR 109
314#define DSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE 100 296#define DSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE 100
315#define DSA_R_KEY_SIZE_TOO_SMALL 106 297#define DSA_R_DECODE_ERROR 104
298#define DSA_R_INVALID_DIGEST_TYPE 106
316#define DSA_R_MISSING_PARAMETERS 101 299#define DSA_R_MISSING_PARAMETERS 101
317#define DSA_R_MODULUS_TOO_LARGE 103 300#define DSA_R_MODULUS_TOO_LARGE 103
318#define DSA_R_NON_FIPS_METHOD 104 301#define DSA_R_NO_PARAMETERS_SET 107
319#define DSA_R_OPERATION_NOT_ALLOWED_IN_FIPS_MODE 105 302#define DSA_R_PARAMETER_ENCODING_ERROR 105
320 303
321#ifdef __cplusplus 304#ifdef __cplusplus
322} 305}
diff --git a/src/lib/libcrypto/dsa/dsa_ameth.c b/src/lib/libcrypto/dsa/dsa_ameth.c
new file mode 100644
index 0000000000..6413aae46e
--- /dev/null
+++ b/src/lib/libcrypto/dsa/dsa_ameth.c
@@ -0,0 +1,657 @@
1/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
2 * project 2006.
3 */
4/* ====================================================================
5 * Copyright (c) 2006 The OpenSSL Project. All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 *
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 *
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in
16 * the documentation and/or other materials provided with the
17 * distribution.
18 *
19 * 3. All advertising materials mentioning features or use of this
20 * software must display the following acknowledgment:
21 * "This product includes software developed by the OpenSSL Project
22 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
23 *
24 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
25 * endorse or promote products derived from this software without
26 * prior written permission. For written permission, please contact
27 * licensing@OpenSSL.org.
28 *
29 * 5. Products derived from this software may not be called "OpenSSL"
30 * nor may "OpenSSL" appear in their names without prior written
31 * permission of the OpenSSL Project.
32 *
33 * 6. Redistributions of any form whatsoever must retain the following
34 * acknowledgment:
35 * "This product includes software developed by the OpenSSL Project
36 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
37 *
38 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
39 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
40 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
41 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
42 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
43 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
44 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
45 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
46 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
47 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
48 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
49 * OF THE POSSIBILITY OF SUCH DAMAGE.
50 * ====================================================================
51 *
52 * This product includes cryptographic software written by Eric Young
53 * (eay@cryptsoft.com). This product includes software written by Tim
54 * Hudson (tjh@cryptsoft.com).
55 *
56 */
57
58#include <stdio.h>
59#include "cryptlib.h"
60#include <openssl/x509.h>
61#include <openssl/asn1.h>
62#include <openssl/dsa.h>
63#include <openssl/bn.h>
64#ifndef OPENSSL_NO_CMS
65#include <openssl/cms.h>
66#endif
67#include "asn1_locl.h"
68
69static int dsa_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey)
70 {
71 const unsigned char *p, *pm;
72 int pklen, pmlen;
73 int ptype;
74 void *pval;
75 ASN1_STRING *pstr;
76 X509_ALGOR *palg;
77 ASN1_INTEGER *public_key = NULL;
78
79 DSA *dsa = NULL;
80
81 if (!X509_PUBKEY_get0_param(NULL, &p, &pklen, &palg, pubkey))
82 return 0;
83 X509_ALGOR_get0(NULL, &ptype, &pval, palg);
84
85
86 if (ptype == V_ASN1_SEQUENCE)
87 {
88 pstr = pval;
89 pm = pstr->data;
90 pmlen = pstr->length;
91
92 if (!(dsa = d2i_DSAparams(NULL, &pm, pmlen)))
93 {
94 DSAerr(DSA_F_DSA_PUB_DECODE, DSA_R_DECODE_ERROR);
95 goto err;
96 }
97
98 }
99 else if ((ptype == V_ASN1_NULL) || (ptype == V_ASN1_UNDEF))
100 {
101 if (!(dsa = DSA_new()))
102 {
103 DSAerr(DSA_F_DSA_PUB_DECODE, ERR_R_MALLOC_FAILURE);
104 goto err;
105 }
106 }
107 else
108 {
109 DSAerr(DSA_F_DSA_PUB_DECODE, DSA_R_PARAMETER_ENCODING_ERROR);
110 goto err;
111 }
112
113 if (!(public_key=d2i_ASN1_INTEGER(NULL, &p, pklen)))
114 {
115 DSAerr(DSA_F_DSA_PUB_DECODE, DSA_R_DECODE_ERROR);
116 goto err;
117 }
118
119 if (!(dsa->pub_key = ASN1_INTEGER_to_BN(public_key, NULL)))
120 {
121 DSAerr(DSA_F_DSA_PUB_DECODE, DSA_R_BN_DECODE_ERROR);
122 goto err;
123 }
124
125 ASN1_INTEGER_free(public_key);
126 EVP_PKEY_assign_DSA(pkey, dsa);
127 return 1;
128
129 err:
130 if (public_key)
131 ASN1_INTEGER_free(public_key);
132 if (dsa)
133 DSA_free(dsa);
134 return 0;
135
136 }
137
138static int dsa_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey)
139 {
140 DSA *dsa;
141 void *pval = NULL;
142 int ptype;
143 unsigned char *penc = NULL;
144 int penclen;
145
146 dsa=pkey->pkey.dsa;
147 if (pkey->save_parameters && dsa->p && dsa->q && dsa->g)
148 {
149 ASN1_STRING *str;
150 str = ASN1_STRING_new();
151 str->length = i2d_DSAparams(dsa, &str->data);
152 if (str->length <= 0)
153 {
154 DSAerr(DSA_F_DSA_PUB_ENCODE, ERR_R_MALLOC_FAILURE);
155 goto err;
156 }
157 pval = str;
158 ptype = V_ASN1_SEQUENCE;
159 }
160 else
161 ptype = V_ASN1_UNDEF;
162
163 dsa->write_params=0;
164
165 penclen = i2d_DSAPublicKey(dsa, &penc);
166
167 if (penclen <= 0)
168 {
169 DSAerr(DSA_F_DSA_PUB_ENCODE, ERR_R_MALLOC_FAILURE);
170 goto err;
171 }
172
173 if (X509_PUBKEY_set0_param(pk, OBJ_nid2obj(EVP_PKEY_DSA),
174 ptype, pval, penc, penclen))
175 return 1;
176
177 err:
178 if (penc)
179 OPENSSL_free(penc);
180 if (pval)
181 ASN1_STRING_free(pval);
182
183 return 0;
184 }
185
186/* In PKCS#8 DSA: you just get a private key integer and parameters in the
187 * AlgorithmIdentifier the pubkey must be recalculated.
188 */
189
190static int dsa_priv_decode(EVP_PKEY *pkey, PKCS8_PRIV_KEY_INFO *p8)
191 {
192 const unsigned char *p, *pm;
193 int pklen, pmlen;
194 int ptype;
195 void *pval;
196 ASN1_STRING *pstr;
197 X509_ALGOR *palg;
198 ASN1_INTEGER *privkey = NULL;
199 BN_CTX *ctx = NULL;
200
201 STACK_OF(ASN1_TYPE) *ndsa = NULL;
202 DSA *dsa = NULL;
203
204 if (!PKCS8_pkey_get0(NULL, &p, &pklen, &palg, p8))
205 return 0;
206 X509_ALGOR_get0(NULL, &ptype, &pval, palg);
207
208 /* Check for broken DSA PKCS#8, UGH! */
209 if (*p == (V_ASN1_SEQUENCE|V_ASN1_CONSTRUCTED))
210 {
211 ASN1_TYPE *t1, *t2;
212 if(!(ndsa = d2i_ASN1_SEQUENCE_ANY(NULL, &p, pklen)))
213 goto decerr;
214 if (sk_ASN1_TYPE_num(ndsa) != 2)
215 goto decerr;
216 /* Handle Two broken types:
217 * SEQUENCE {parameters, priv_key}
218 * SEQUENCE {pub_key, priv_key}
219 */
220
221 t1 = sk_ASN1_TYPE_value(ndsa, 0);
222 t2 = sk_ASN1_TYPE_value(ndsa, 1);
223 if (t1->type == V_ASN1_SEQUENCE)
224 {
225 p8->broken = PKCS8_EMBEDDED_PARAM;
226 pval = t1->value.ptr;
227 }
228 else if (ptype == V_ASN1_SEQUENCE)
229 p8->broken = PKCS8_NS_DB;
230 else
231 goto decerr;
232
233 if (t2->type != V_ASN1_INTEGER)
234 goto decerr;
235
236 privkey = t2->value.integer;
237 }
238 else
239 {
240 const unsigned char *q = p;
241 if (!(privkey=d2i_ASN1_INTEGER(NULL, &p, pklen)))
242 goto decerr;
243 if (privkey->type == V_ASN1_NEG_INTEGER)
244 {
245 p8->broken = PKCS8_NEG_PRIVKEY;
246 ASN1_INTEGER_free(privkey);
247 if (!(privkey=d2i_ASN1_UINTEGER(NULL, &q, pklen)))
248 goto decerr;
249 }
250 if (ptype != V_ASN1_SEQUENCE)
251 goto decerr;
252 }
253
254 pstr = pval;
255 pm = pstr->data;
256 pmlen = pstr->length;
257 if (!(dsa = d2i_DSAparams(NULL, &pm, pmlen)))
258 goto decerr;
259 /* We have parameters now set private key */
260 if (!(dsa->priv_key = ASN1_INTEGER_to_BN(privkey, NULL)))
261 {
262 DSAerr(DSA_F_DSA_PRIV_DECODE,DSA_R_BN_ERROR);
263 goto dsaerr;
264 }
265 /* Calculate public key */
266 if (!(dsa->pub_key = BN_new()))
267 {
268 DSAerr(DSA_F_DSA_PRIV_DECODE, ERR_R_MALLOC_FAILURE);
269 goto dsaerr;
270 }
271 if (!(ctx = BN_CTX_new()))
272 {
273 DSAerr(DSA_F_DSA_PRIV_DECODE, ERR_R_MALLOC_FAILURE);
274 goto dsaerr;
275 }
276
277 if (!BN_mod_exp(dsa->pub_key, dsa->g, dsa->priv_key, dsa->p, ctx))
278 {
279 DSAerr(DSA_F_DSA_PRIV_DECODE,DSA_R_BN_ERROR);
280 goto dsaerr;
281 }
282
283 EVP_PKEY_assign_DSA(pkey, dsa);
284 BN_CTX_free (ctx);
285 if(ndsa)
286 sk_ASN1_TYPE_pop_free(ndsa, ASN1_TYPE_free);
287 else
288 ASN1_INTEGER_free(privkey);
289
290 return 1;
291
292 decerr:
293 DSAerr(DSA_F_DSA_PRIV_DECODE, EVP_R_DECODE_ERROR);
294 dsaerr:
295 BN_CTX_free (ctx);
296 if (privkey)
297 ASN1_INTEGER_free(privkey);
298 sk_ASN1_TYPE_pop_free(ndsa, ASN1_TYPE_free);
299 DSA_free(dsa);
300 return 0;
301 }
302
303static int dsa_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey)
304{
305 ASN1_STRING *params = NULL;
306 ASN1_INTEGER *prkey = NULL;
307 unsigned char *dp = NULL;
308 int dplen;
309
310 params = ASN1_STRING_new();
311
312 if (!params)
313 {
314 DSAerr(DSA_F_DSA_PRIV_ENCODE,ERR_R_MALLOC_FAILURE);
315 goto err;
316 }
317
318 params->length = i2d_DSAparams(pkey->pkey.dsa, &params->data);
319 if (params->length <= 0)
320 {
321 DSAerr(DSA_F_DSA_PRIV_ENCODE,ERR_R_MALLOC_FAILURE);
322 goto err;
323 }
324 params->type = V_ASN1_SEQUENCE;
325
326 /* Get private key into integer */
327 prkey = BN_to_ASN1_INTEGER(pkey->pkey.dsa->priv_key, NULL);
328
329 if (!prkey)
330 {
331 DSAerr(DSA_F_DSA_PRIV_ENCODE,DSA_R_BN_ERROR);
332 goto err;
333 }
334
335 dplen = i2d_ASN1_INTEGER(prkey, &dp);
336
337 ASN1_INTEGER_free(prkey);
338
339 if (!PKCS8_pkey_set0(p8, OBJ_nid2obj(NID_dsa), 0,
340 V_ASN1_SEQUENCE, params, dp, dplen))
341 goto err;
342
343 return 1;
344
345err:
346 if (dp != NULL)
347 OPENSSL_free(dp);
348 if (params != NULL)
349 ASN1_STRING_free(params);
350 if (prkey != NULL)
351 ASN1_INTEGER_free(prkey);
352 return 0;
353}
354
355static int int_dsa_size(const EVP_PKEY *pkey)
356 {
357 return(DSA_size(pkey->pkey.dsa));
358 }
359
360static int dsa_bits(const EVP_PKEY *pkey)
361 {
362 return BN_num_bits(pkey->pkey.dsa->p);
363 }
364
365static int dsa_missing_parameters(const EVP_PKEY *pkey)
366 {
367 DSA *dsa;
368 dsa=pkey->pkey.dsa;
369 if ((dsa->p == NULL) || (dsa->q == NULL) || (dsa->g == NULL))
370 return 1;
371 return 0;
372 }
373
374static int dsa_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from)
375 {
376 BIGNUM *a;
377
378 if ((a=BN_dup(from->pkey.dsa->p)) == NULL)
379 return 0;
380 if (to->pkey.dsa->p != NULL)
381 BN_free(to->pkey.dsa->p);
382 to->pkey.dsa->p=a;
383
384 if ((a=BN_dup(from->pkey.dsa->q)) == NULL)
385 return 0;
386 if (to->pkey.dsa->q != NULL)
387 BN_free(to->pkey.dsa->q);
388 to->pkey.dsa->q=a;
389
390 if ((a=BN_dup(from->pkey.dsa->g)) == NULL)
391 return 0;
392 if (to->pkey.dsa->g != NULL)
393 BN_free(to->pkey.dsa->g);
394 to->pkey.dsa->g=a;
395 return 1;
396 }
397
398static int dsa_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b)
399 {
400 if ( BN_cmp(a->pkey.dsa->p,b->pkey.dsa->p) ||
401 BN_cmp(a->pkey.dsa->q,b->pkey.dsa->q) ||
402 BN_cmp(a->pkey.dsa->g,b->pkey.dsa->g))
403 return 0;
404 else
405 return 1;
406 }
407
408static int dsa_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b)
409 {
410 if (BN_cmp(b->pkey.dsa->pub_key,a->pkey.dsa->pub_key) != 0)
411 return 0;
412 else
413 return 1;
414 }
415
416static void int_dsa_free(EVP_PKEY *pkey)
417 {
418 DSA_free(pkey->pkey.dsa);
419 }
420
421static void update_buflen(const BIGNUM *b, size_t *pbuflen)
422 {
423 size_t i;
424 if (!b)
425 return;
426 if (*pbuflen < (i = (size_t)BN_num_bytes(b)))
427 *pbuflen = i;
428 }
429
430static int do_dsa_print(BIO *bp, const DSA *x, int off, int ptype)
431 {
432 unsigned char *m=NULL;
433 int ret=0;
434 size_t buf_len=0;
435 const char *ktype = NULL;
436
437 const BIGNUM *priv_key, *pub_key;
438
439 if (ptype == 2)
440 priv_key = x->priv_key;
441 else
442 priv_key = NULL;
443
444 if (ptype > 0)
445 pub_key = x->pub_key;
446 else
447 pub_key = NULL;
448
449 if (ptype == 2)
450 ktype = "Private-Key";
451 else if (ptype == 1)
452 ktype = "Public-Key";
453 else
454 ktype = "DSA-Parameters";
455
456 update_buflen(x->p, &buf_len);
457 update_buflen(x->q, &buf_len);
458 update_buflen(x->g, &buf_len);
459 update_buflen(priv_key, &buf_len);
460 update_buflen(pub_key, &buf_len);
461
462 m=(unsigned char *)OPENSSL_malloc(buf_len+10);
463 if (m == NULL)
464 {
465 DSAerr(DSA_F_DO_DSA_PRINT,ERR_R_MALLOC_FAILURE);
466 goto err;
467 }
468
469 if (priv_key)
470 {
471 if(!BIO_indent(bp,off,128))
472 goto err;
473 if (BIO_printf(bp,"%s: (%d bit)\n",ktype, BN_num_bits(x->p))
474 <= 0) goto err;
475 }
476
477 if (!ASN1_bn_print(bp,"priv:",priv_key,m,off))
478 goto err;
479 if (!ASN1_bn_print(bp,"pub: ",pub_key,m,off))
480 goto err;
481 if (!ASN1_bn_print(bp,"P: ",x->p,m,off)) goto err;
482 if (!ASN1_bn_print(bp,"Q: ",x->q,m,off)) goto err;
483 if (!ASN1_bn_print(bp,"G: ",x->g,m,off)) goto err;
484 ret=1;
485err:
486 if (m != NULL) OPENSSL_free(m);
487 return(ret);
488 }
489
490static int dsa_param_decode(EVP_PKEY *pkey,
491 const unsigned char **pder, int derlen)
492 {
493 DSA *dsa;
494 if (!(dsa = d2i_DSAparams(NULL, pder, derlen)))
495 {
496 DSAerr(DSA_F_DSA_PARAM_DECODE, ERR_R_DSA_LIB);
497 return 0;
498 }
499 EVP_PKEY_assign_DSA(pkey, dsa);
500 return 1;
501 }
502
503static int dsa_param_encode(const EVP_PKEY *pkey, unsigned char **pder)
504 {
505 return i2d_DSAparams(pkey->pkey.dsa, pder);
506 }
507
508static int dsa_param_print(BIO *bp, const EVP_PKEY *pkey, int indent,
509 ASN1_PCTX *ctx)
510 {
511 return do_dsa_print(bp, pkey->pkey.dsa, indent, 0);
512 }
513
514static int dsa_pub_print(BIO *bp, const EVP_PKEY *pkey, int indent,
515 ASN1_PCTX *ctx)
516 {
517 return do_dsa_print(bp, pkey->pkey.dsa, indent, 1);
518 }
519
520
521static int dsa_priv_print(BIO *bp, const EVP_PKEY *pkey, int indent,
522 ASN1_PCTX *ctx)
523 {
524 return do_dsa_print(bp, pkey->pkey.dsa, indent, 2);
525 }
526
527static int old_dsa_priv_decode(EVP_PKEY *pkey,
528 const unsigned char **pder, int derlen)
529 {
530 DSA *dsa;
531 if (!(dsa = d2i_DSAPrivateKey (NULL, pder, derlen)))
532 {
533 DSAerr(DSA_F_OLD_DSA_PRIV_DECODE, ERR_R_DSA_LIB);
534 return 0;
535 }
536 EVP_PKEY_assign_DSA(pkey, dsa);
537 return 1;
538 }
539
540static int old_dsa_priv_encode(const EVP_PKEY *pkey, unsigned char **pder)
541 {
542 return i2d_DSAPrivateKey(pkey->pkey.dsa, pder);
543 }
544
545static int dsa_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2)
546 {
547 switch (op)
548 {
549 case ASN1_PKEY_CTRL_PKCS7_SIGN:
550 if (arg1 == 0)
551 {
552 int snid, hnid;
553 X509_ALGOR *alg1, *alg2;
554 PKCS7_SIGNER_INFO_get0_algs(arg2, NULL, &alg1, &alg2);
555 if (alg1 == NULL || alg1->algorithm == NULL)
556 return -1;
557 hnid = OBJ_obj2nid(alg1->algorithm);
558 if (hnid == NID_undef)
559 return -1;
560 if (!OBJ_find_sigid_by_algs(&snid, hnid, EVP_PKEY_id(pkey)))
561 return -1;
562 X509_ALGOR_set0(alg2, OBJ_nid2obj(snid), V_ASN1_UNDEF, 0);
563 }
564 return 1;
565#ifndef OPENSSL_NO_CMS
566 case ASN1_PKEY_CTRL_CMS_SIGN:
567 if (arg1 == 0)
568 {
569 int snid, hnid;
570 X509_ALGOR *alg1, *alg2;
571 CMS_SignerInfo_get0_algs(arg2, NULL, NULL, &alg1, &alg2);
572 if (alg1 == NULL || alg1->algorithm == NULL)
573 return -1;
574 hnid = OBJ_obj2nid(alg1->algorithm);
575 if (hnid == NID_undef)
576 return -1;
577 if (!OBJ_find_sigid_by_algs(&snid, hnid, EVP_PKEY_id(pkey)))
578 return -1;
579 X509_ALGOR_set0(alg2, OBJ_nid2obj(snid), V_ASN1_UNDEF, 0);
580 }
581 return 1;
582#endif
583
584 case ASN1_PKEY_CTRL_DEFAULT_MD_NID:
585 *(int *)arg2 = NID_sha1;
586 return 2;
587
588 default:
589 return -2;
590
591 }
592
593 }
594
595/* NB these are sorted in pkey_id order, lowest first */
596
597const EVP_PKEY_ASN1_METHOD dsa_asn1_meths[] =
598 {
599
600 {
601 EVP_PKEY_DSA2,
602 EVP_PKEY_DSA,
603 ASN1_PKEY_ALIAS
604 },
605
606 {
607 EVP_PKEY_DSA1,
608 EVP_PKEY_DSA,
609 ASN1_PKEY_ALIAS
610 },
611
612 {
613 EVP_PKEY_DSA4,
614 EVP_PKEY_DSA,
615 ASN1_PKEY_ALIAS
616 },
617
618 {
619 EVP_PKEY_DSA3,
620 EVP_PKEY_DSA,
621 ASN1_PKEY_ALIAS
622 },
623
624 {
625 EVP_PKEY_DSA,
626 EVP_PKEY_DSA,
627 0,
628
629 "DSA",
630 "OpenSSL DSA method",
631
632 dsa_pub_decode,
633 dsa_pub_encode,
634 dsa_pub_cmp,
635 dsa_pub_print,
636
637 dsa_priv_decode,
638 dsa_priv_encode,
639 dsa_priv_print,
640
641 int_dsa_size,
642 dsa_bits,
643
644 dsa_param_decode,
645 dsa_param_encode,
646 dsa_missing_parameters,
647 dsa_copy_parameters,
648 dsa_cmp_parameters,
649 dsa_param_print,
650
651 int_dsa_free,
652 dsa_pkey_ctrl,
653 old_dsa_priv_decode,
654 old_dsa_priv_encode
655 }
656 };
657
diff --git a/src/lib/libcrypto/dsa/dsa_asn1.c b/src/lib/libcrypto/dsa/dsa_asn1.c
index 0645facb4b..c37460b2d6 100644
--- a/src/lib/libcrypto/dsa/dsa_asn1.c
+++ b/src/lib/libcrypto/dsa/dsa_asn1.c
@@ -3,7 +3,7 @@
3 * project 2000. 3 * project 2000.
4 */ 4 */
5/* ==================================================================== 5/* ====================================================================
6 * Copyright (c) 2000 The OpenSSL Project. All rights reserved. 6 * Copyright (c) 2000-2005 The OpenSSL Project. All rights reserved.
7 * 7 *
8 * Redistribution and use in source and binary forms, with or without 8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions 9 * modification, are permitted provided that the following conditions
@@ -61,24 +61,23 @@
61#include <openssl/dsa.h> 61#include <openssl/dsa.h>
62#include <openssl/asn1.h> 62#include <openssl/asn1.h>
63#include <openssl/asn1t.h> 63#include <openssl/asn1t.h>
64#include <openssl/bn.h>
65#ifdef OPENSSL_FIPS
66#include <openssl/fips.h>
67#endif
68
69 64
70/* Override the default new methods */ 65/* Override the default new methods */
71static int sig_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it) 66static int sig_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
67 void *exarg)
72{ 68{
73 if(operation == ASN1_OP_NEW_PRE) { 69 if(operation == ASN1_OP_NEW_PRE) {
74 DSA_SIG *sig; 70 DSA_SIG *sig;
75 sig = OPENSSL_malloc(sizeof(DSA_SIG)); 71 sig = OPENSSL_malloc(sizeof(DSA_SIG));
72 if (!sig)
73 {
74 DSAerr(DSA_F_SIG_CB, ERR_R_MALLOC_FAILURE);
75 return 0;
76 }
76 sig->r = NULL; 77 sig->r = NULL;
77 sig->s = NULL; 78 sig->s = NULL;
78 *pval = (ASN1_VALUE *)sig; 79 *pval = (ASN1_VALUE *)sig;
79 if(sig) return 2; 80 return 2;
80 DSAerr(DSA_F_SIG_CB, ERR_R_MALLOC_FAILURE);
81 return 0;
82 } 81 }
83 return 1; 82 return 1;
84} 83}
@@ -88,10 +87,11 @@ ASN1_SEQUENCE_cb(DSA_SIG, sig_cb) = {
88 ASN1_SIMPLE(DSA_SIG, s, CBIGNUM) 87 ASN1_SIMPLE(DSA_SIG, s, CBIGNUM)
89} ASN1_SEQUENCE_END_cb(DSA_SIG, DSA_SIG) 88} ASN1_SEQUENCE_END_cb(DSA_SIG, DSA_SIG)
90 89
91IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(DSA_SIG,DSA_SIG,DSA_SIG) 90IMPLEMENT_ASN1_FUNCTIONS_const(DSA_SIG)
92 91
93/* Override the default free and new methods */ 92/* Override the default free and new methods */
94static int dsa_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it) 93static int dsa_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
94 void *exarg)
95{ 95{
96 if(operation == ASN1_OP_NEW_PRE) { 96 if(operation == ASN1_OP_NEW_PRE) {
97 *pval = (ASN1_VALUE *)DSA_new(); 97 *pval = (ASN1_VALUE *)DSA_new();
@@ -144,75 +144,7 @@ ASN1_CHOICE_cb(DSAPublicKey, dsa_cb) = {
144 144
145IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(DSA, DSAPublicKey, DSAPublicKey) 145IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(DSA, DSAPublicKey, DSAPublicKey)
146 146
147int DSA_sign(int type, const unsigned char *dgst, int dlen, unsigned char *sig, 147DSA *DSAparams_dup(DSA *dsa)
148 unsigned int *siglen, DSA *dsa)
149 {
150 DSA_SIG *s;
151#ifdef OPENSSL_FIPS
152 if(FIPS_mode() && !(dsa->flags & DSA_FLAG_NON_FIPS_ALLOW))
153 {
154 DSAerr(DSA_F_DSA_SIGN, DSA_R_OPERATION_NOT_ALLOWED_IN_FIPS_MODE);
155 return 0;
156 }
157#endif
158 s=DSA_do_sign(dgst,dlen,dsa);
159 if (s == NULL)
160 {
161 *siglen=0;
162 return(0);
163 }
164 *siglen=i2d_DSA_SIG(s,&sig);
165 DSA_SIG_free(s);
166 return(1);
167 }
168
169int DSA_size(const DSA *r)
170 {
171 int ret,i;
172 ASN1_INTEGER bs;
173 unsigned char buf[4]; /* 4 bytes looks really small.
174 However, i2d_ASN1_INTEGER() will not look
175 beyond the first byte, as long as the second
176 parameter is NULL. */
177
178 i=BN_num_bits(r->q);
179 bs.length=(i+7)/8;
180 bs.data=buf;
181 bs.type=V_ASN1_INTEGER;
182 /* If the top bit is set the asn1 encoding is 1 larger. */
183 buf[0]=0xff;
184
185 i=i2d_ASN1_INTEGER(&bs,NULL);
186 i+=i; /* r and s */
187 ret=ASN1_object_size(1,i,V_ASN1_SEQUENCE);
188 return(ret);
189 }
190
191/* data has already been hashed (probably with SHA or SHA-1). */
192/* returns
193 * 1: correct signature
194 * 0: incorrect signature
195 * -1: error
196 */
197int DSA_verify(int type, const unsigned char *dgst, int dgst_len,
198 const unsigned char *sigbuf, int siglen, DSA *dsa)
199 { 148 {
200 DSA_SIG *s; 149 return ASN1_item_dup(ASN1_ITEM_rptr(DSAparams), dsa);
201 int ret=-1;
202#ifdef OPENSSL_FIPS
203 if(FIPS_mode() && !(dsa->flags & DSA_FLAG_NON_FIPS_ALLOW))
204 {
205 DSAerr(DSA_F_DSA_VERIFY, DSA_R_OPERATION_NOT_ALLOWED_IN_FIPS_MODE);
206 return 0;
207 }
208#endif
209
210 s = DSA_SIG_new();
211 if (s == NULL) return(ret);
212 if (d2i_DSA_SIG(&s,&sigbuf,siglen) == NULL) goto err;
213 ret=DSA_do_verify(dgst,dgst_len,s,dsa);
214err:
215 DSA_SIG_free(s);
216 return(ret);
217 } 150 }
218
diff --git a/src/lib/libcrypto/dsa/dsa_err.c b/src/lib/libcrypto/dsa/dsa_err.c
index 872839af94..bba984e92e 100644
--- a/src/lib/libcrypto/dsa/dsa_err.c
+++ b/src/lib/libcrypto/dsa/dsa_err.c
@@ -1,6 +1,6 @@
1/* crypto/dsa/dsa_err.c */ 1/* crypto/dsa/dsa_err.c */
2/* ==================================================================== 2/* ====================================================================
3 * Copyright (c) 1999-2007 The OpenSSL Project. All rights reserved. 3 * Copyright (c) 1999-2006 The OpenSSL Project. All rights reserved.
4 * 4 *
5 * Redistribution and use in source and binary forms, with or without 5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions 6 * modification, are permitted provided that the following conditions
@@ -71,23 +71,26 @@
71static ERR_STRING_DATA DSA_str_functs[]= 71static ERR_STRING_DATA DSA_str_functs[]=
72 { 72 {
73{ERR_FUNC(DSA_F_D2I_DSA_SIG), "d2i_DSA_SIG"}, 73{ERR_FUNC(DSA_F_D2I_DSA_SIG), "d2i_DSA_SIG"},
74{ERR_FUNC(DSA_F_DO_DSA_PRINT), "DO_DSA_PRINT"},
74{ERR_FUNC(DSA_F_DSAPARAMS_PRINT), "DSAparams_print"}, 75{ERR_FUNC(DSA_F_DSAPARAMS_PRINT), "DSAparams_print"},
75{ERR_FUNC(DSA_F_DSAPARAMS_PRINT_FP), "DSAparams_print_fp"}, 76{ERR_FUNC(DSA_F_DSAPARAMS_PRINT_FP), "DSAparams_print_fp"},
76{ERR_FUNC(DSA_F_DSA_BUILTIN_KEYGEN), "DSA_BUILTIN_KEYGEN"},
77{ERR_FUNC(DSA_F_DSA_BUILTIN_PARAMGEN), "DSA_BUILTIN_PARAMGEN"},
78{ERR_FUNC(DSA_F_DSA_DO_SIGN), "DSA_do_sign"}, 77{ERR_FUNC(DSA_F_DSA_DO_SIGN), "DSA_do_sign"},
79{ERR_FUNC(DSA_F_DSA_DO_VERIFY), "DSA_do_verify"}, 78{ERR_FUNC(DSA_F_DSA_DO_VERIFY), "DSA_do_verify"},
80{ERR_FUNC(DSA_F_DSA_GENERATE_PARAMETERS), "DSA_generate_parameters"},
81{ERR_FUNC(DSA_F_DSA_NEW_METHOD), "DSA_new_method"}, 79{ERR_FUNC(DSA_F_DSA_NEW_METHOD), "DSA_new_method"},
82{ERR_FUNC(DSA_F_DSA_PRINT), "DSA_print"}, 80{ERR_FUNC(DSA_F_DSA_PARAM_DECODE), "DSA_PARAM_DECODE"},
83{ERR_FUNC(DSA_F_DSA_PRINT_FP), "DSA_print_fp"}, 81{ERR_FUNC(DSA_F_DSA_PRINT_FP), "DSA_print_fp"},
84{ERR_FUNC(DSA_F_DSA_SET_DEFAULT_METHOD), "DSA_set_default_method"}, 82{ERR_FUNC(DSA_F_DSA_PRIV_DECODE), "DSA_PRIV_DECODE"},
85{ERR_FUNC(DSA_F_DSA_SET_METHOD), "DSA_set_method"}, 83{ERR_FUNC(DSA_F_DSA_PRIV_ENCODE), "DSA_PRIV_ENCODE"},
84{ERR_FUNC(DSA_F_DSA_PUB_DECODE), "DSA_PUB_DECODE"},
85{ERR_FUNC(DSA_F_DSA_PUB_ENCODE), "DSA_PUB_ENCODE"},
86{ERR_FUNC(DSA_F_DSA_SIGN), "DSA_sign"}, 86{ERR_FUNC(DSA_F_DSA_SIGN), "DSA_sign"},
87{ERR_FUNC(DSA_F_DSA_SIGN_SETUP), "DSA_sign_setup"}, 87{ERR_FUNC(DSA_F_DSA_SIGN_SETUP), "DSA_sign_setup"},
88{ERR_FUNC(DSA_F_DSA_SIG_NEW), "DSA_SIG_new"}, 88{ERR_FUNC(DSA_F_DSA_SIG_NEW), "DSA_SIG_new"},
89{ERR_FUNC(DSA_F_DSA_VERIFY), "DSA_verify"}, 89{ERR_FUNC(DSA_F_DSA_VERIFY), "DSA_verify"},
90{ERR_FUNC(DSA_F_I2D_DSA_SIG), "i2d_DSA_SIG"}, 90{ERR_FUNC(DSA_F_I2D_DSA_SIG), "i2d_DSA_SIG"},
91{ERR_FUNC(DSA_F_OLD_DSA_PRIV_DECODE), "OLD_DSA_PRIV_DECODE"},
92{ERR_FUNC(DSA_F_PKEY_DSA_CTRL), "PKEY_DSA_CTRL"},
93{ERR_FUNC(DSA_F_PKEY_DSA_KEYGEN), "PKEY_DSA_KEYGEN"},
91{ERR_FUNC(DSA_F_SIG_CB), "SIG_CB"}, 94{ERR_FUNC(DSA_F_SIG_CB), "SIG_CB"},
92{0,NULL} 95{0,NULL}
93 }; 96 };
@@ -95,12 +98,15 @@ static ERR_STRING_DATA DSA_str_functs[]=
95static ERR_STRING_DATA DSA_str_reasons[]= 98static ERR_STRING_DATA DSA_str_reasons[]=
96 { 99 {
97{ERR_REASON(DSA_R_BAD_Q_VALUE) ,"bad q value"}, 100{ERR_REASON(DSA_R_BAD_Q_VALUE) ,"bad q value"},
101{ERR_REASON(DSA_R_BN_DECODE_ERROR) ,"bn decode error"},
102{ERR_REASON(DSA_R_BN_ERROR) ,"bn error"},
98{ERR_REASON(DSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE),"data too large for key size"}, 103{ERR_REASON(DSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE),"data too large for key size"},
99{ERR_REASON(DSA_R_KEY_SIZE_TOO_SMALL) ,"key size too small"}, 104{ERR_REASON(DSA_R_DECODE_ERROR) ,"decode error"},
105{ERR_REASON(DSA_R_INVALID_DIGEST_TYPE) ,"invalid digest type"},
100{ERR_REASON(DSA_R_MISSING_PARAMETERS) ,"missing parameters"}, 106{ERR_REASON(DSA_R_MISSING_PARAMETERS) ,"missing parameters"},
101{ERR_REASON(DSA_R_MODULUS_TOO_LARGE) ,"modulus too large"}, 107{ERR_REASON(DSA_R_MODULUS_TOO_LARGE) ,"modulus too large"},
102{ERR_REASON(DSA_R_NON_FIPS_METHOD) ,"non fips method"}, 108{ERR_REASON(DSA_R_NO_PARAMETERS_SET) ,"no parameters set"},
103{ERR_REASON(DSA_R_OPERATION_NOT_ALLOWED_IN_FIPS_MODE),"operation not allowed in fips mode"}, 109{ERR_REASON(DSA_R_PARAMETER_ENCODING_ERROR),"parameter encoding error"},
104{0,NULL} 110{0,NULL}
105 }; 111 };
106 112
diff --git a/src/lib/libcrypto/dsa/dsa_gen.c b/src/lib/libcrypto/dsa/dsa_gen.c
index 6f1728e3cf..0fcd25f8b0 100644
--- a/src/lib/libcrypto/dsa/dsa_gen.c
+++ b/src/lib/libcrypto/dsa/dsa_gen.c
@@ -74,69 +74,88 @@
74#ifndef OPENSSL_NO_SHA 74#ifndef OPENSSL_NO_SHA
75 75
76#include <stdio.h> 76#include <stdio.h>
77#include <time.h>
78#include "cryptlib.h" 77#include "cryptlib.h"
79#include <openssl/evp.h> 78#include <openssl/evp.h>
80#include <openssl/bn.h> 79#include <openssl/bn.h>
81#include <openssl/dsa.h>
82#include <openssl/rand.h> 80#include <openssl/rand.h>
83#include <openssl/sha.h> 81#include <openssl/sha.h>
84 82#include "dsa_locl.h"
85#ifndef OPENSSL_FIPS
86
87static int dsa_builtin_paramgen(DSA *ret, int bits,
88 unsigned char *seed_in, int seed_len,
89 int *counter_ret, unsigned long *h_ret, BN_GENCB *cb);
90 83
91int DSA_generate_parameters_ex(DSA *ret, int bits, 84int DSA_generate_parameters_ex(DSA *ret, int bits,
92 unsigned char *seed_in, int seed_len, 85 const unsigned char *seed_in, int seed_len,
93 int *counter_ret, unsigned long *h_ret, BN_GENCB *cb) 86 int *counter_ret, unsigned long *h_ret, BN_GENCB *cb)
94 { 87 {
95 if(ret->meth->dsa_paramgen) 88 if(ret->meth->dsa_paramgen)
96 return ret->meth->dsa_paramgen(ret, bits, seed_in, seed_len, 89 return ret->meth->dsa_paramgen(ret, bits, seed_in, seed_len,
97 counter_ret, h_ret, cb); 90 counter_ret, h_ret, cb);
98 return dsa_builtin_paramgen(ret, bits, seed_in, seed_len, 91 else
99 counter_ret, h_ret, cb); 92 {
93 const EVP_MD *evpmd;
94 size_t qbits = bits >= 2048 ? 256 : 160;
95
96 if (bits >= 2048)
97 {
98 qbits = 256;
99 evpmd = EVP_sha256();
100 }
101 else
102 {
103 qbits = 160;
104 evpmd = EVP_sha1();
105 }
106
107 return dsa_builtin_paramgen(ret, bits, qbits, evpmd,
108 seed_in, seed_len, counter_ret, h_ret, cb);
109 }
100 } 110 }
101 111
102static int dsa_builtin_paramgen(DSA *ret, int bits, 112int dsa_builtin_paramgen(DSA *ret, size_t bits, size_t qbits,
103 unsigned char *seed_in, int seed_len, 113 const EVP_MD *evpmd, const unsigned char *seed_in, size_t seed_len,
104 int *counter_ret, unsigned long *h_ret, BN_GENCB *cb) 114 int *counter_ret, unsigned long *h_ret, BN_GENCB *cb)
105 { 115 {
106 int ok=0; 116 int ok=0;
107 unsigned char seed[SHA_DIGEST_LENGTH]; 117 unsigned char seed[SHA256_DIGEST_LENGTH];
108 unsigned char md[SHA_DIGEST_LENGTH]; 118 unsigned char md[SHA256_DIGEST_LENGTH];
109 unsigned char buf[SHA_DIGEST_LENGTH],buf2[SHA_DIGEST_LENGTH]; 119 unsigned char buf[SHA256_DIGEST_LENGTH],buf2[SHA256_DIGEST_LENGTH];
110 BIGNUM *r0,*W,*X,*c,*test; 120 BIGNUM *r0,*W,*X,*c,*test;
111 BIGNUM *g=NULL,*q=NULL,*p=NULL; 121 BIGNUM *g=NULL,*q=NULL,*p=NULL;
112 BN_MONT_CTX *mont=NULL; 122 BN_MONT_CTX *mont=NULL;
113 int k,n=0,i,b,m=0; 123 int i, k,n=0,b,m=0, qsize = qbits >> 3;
114 int counter=0; 124 int counter=0;
115 int r=0; 125 int r=0;
116 BN_CTX *ctx=NULL; 126 BN_CTX *ctx=NULL;
117 unsigned int h=2; 127 unsigned int h=2;
118 128
119 if (bits < 512) bits=512; 129 if (qsize != SHA_DIGEST_LENGTH && qsize != SHA224_DIGEST_LENGTH &&
120 bits=(bits+63)/64*64; 130 qsize != SHA256_DIGEST_LENGTH)
131 /* invalid q size */
132 return 0;
133
134 if (evpmd == NULL)
135 /* use SHA1 as default */
136 evpmd = EVP_sha1();
137
138 if (bits < 512)
139 bits = 512;
140
141 bits = (bits+63)/64*64;
121 142
122 /* NB: seed_len == 0 is special case: copy generated seed to 143 /* NB: seed_len == 0 is special case: copy generated seed to
123 * seed_in if it is not NULL. 144 * seed_in if it is not NULL.
124 */ 145 */
125 if (seed_len && (seed_len < 20)) 146 if (seed_len && (seed_len < (size_t)qsize))
126 seed_in = NULL; /* seed buffer too small -- ignore */ 147 seed_in = NULL; /* seed buffer too small -- ignore */
127 if (seed_len > 20) 148 if (seed_len > (size_t)qsize)
128 seed_len = 20; /* App. 2.2 of FIPS PUB 186 allows larger SEED, 149 seed_len = qsize; /* App. 2.2 of FIPS PUB 186 allows larger SEED,
129 * but our internal buffers are restricted to 160 bits*/ 150 * but our internal buffers are restricted to 160 bits*/
130 if ((seed_in != NULL) && (seed_len == 20)) 151 if (seed_in != NULL)
131 { 152 memcpy(seed, seed_in, seed_len);
132 memcpy(seed,seed_in,seed_len); 153
133 /* set seed_in to NULL to avoid it being copied back */ 154 if ((ctx=BN_CTX_new()) == NULL)
134 seed_in = NULL; 155 goto err;
135 }
136
137 if ((ctx=BN_CTX_new()) == NULL) goto err;
138 156
139 if ((mont=BN_MONT_CTX_new()) == NULL) goto err; 157 if ((mont=BN_MONT_CTX_new()) == NULL)
158 goto err;
140 159
141 BN_CTX_start(ctx); 160 BN_CTX_start(ctx);
142 r0 = BN_CTX_get(ctx); 161 r0 = BN_CTX_get(ctx);
@@ -163,7 +182,7 @@ static int dsa_builtin_paramgen(DSA *ret, int bits,
163 182
164 if (!seed_len) 183 if (!seed_len)
165 { 184 {
166 RAND_pseudo_bytes(seed,SHA_DIGEST_LENGTH); 185 RAND_pseudo_bytes(seed, qsize);
167 seed_is_random = 1; 186 seed_is_random = 1;
168 } 187 }
169 else 188 else
@@ -171,25 +190,27 @@ static int dsa_builtin_paramgen(DSA *ret, int bits,
171 seed_is_random = 0; 190 seed_is_random = 0;
172 seed_len=0; /* use random seed if 'seed_in' turns out to be bad*/ 191 seed_len=0; /* use random seed if 'seed_in' turns out to be bad*/
173 } 192 }
174 memcpy(buf,seed,SHA_DIGEST_LENGTH); 193 memcpy(buf , seed, qsize);
175 memcpy(buf2,seed,SHA_DIGEST_LENGTH); 194 memcpy(buf2, seed, qsize);
176 /* precompute "SEED + 1" for step 7: */ 195 /* precompute "SEED + 1" for step 7: */
177 for (i=SHA_DIGEST_LENGTH-1; i >= 0; i--) 196 for (i = qsize-1; i >= 0; i--)
178 { 197 {
179 buf[i]++; 198 buf[i]++;
180 if (buf[i] != 0) break; 199 if (buf[i] != 0)
200 break;
181 } 201 }
182 202
183 /* step 2 */ 203 /* step 2 */
184 EVP_Digest(seed,SHA_DIGEST_LENGTH,md,NULL,HASH, NULL); 204 EVP_Digest(seed, qsize, md, NULL, evpmd, NULL);
185 EVP_Digest(buf,SHA_DIGEST_LENGTH,buf2,NULL,HASH, NULL); 205 EVP_Digest(buf, qsize, buf2, NULL, evpmd, NULL);
186 for (i=0; i<SHA_DIGEST_LENGTH; i++) 206 for (i = 0; i < qsize; i++)
187 md[i]^=buf2[i]; 207 md[i]^=buf2[i];
188 208
189 /* step 3 */ 209 /* step 3 */
190 md[0]|=0x80; 210 md[0] |= 0x80;
191 md[SHA_DIGEST_LENGTH-1]|=0x01; 211 md[qsize-1] |= 0x01;
192 if (!BN_bin2bn(md,SHA_DIGEST_LENGTH,q)) goto err; 212 if (!BN_bin2bn(md, qsize, q))
213 goto err;
193 214
194 /* step 4 */ 215 /* step 4 */
195 r = BN_is_prime_fasttest_ex(q, DSS_prime_checks, ctx, 216 r = BN_is_prime_fasttest_ex(q, DSS_prime_checks, ctx,
@@ -224,18 +245,19 @@ static int dsa_builtin_paramgen(DSA *ret, int bits,
224 for (k=0; k<=n; k++) 245 for (k=0; k<=n; k++)
225 { 246 {
226 /* obtain "SEED + offset + k" by incrementing: */ 247 /* obtain "SEED + offset + k" by incrementing: */
227 for (i=SHA_DIGEST_LENGTH-1; i >= 0; i--) 248 for (i = qsize-1; i >= 0; i--)
228 { 249 {
229 buf[i]++; 250 buf[i]++;
230 if (buf[i] != 0) break; 251 if (buf[i] != 0)
252 break;
231 } 253 }
232 254
233 EVP_Digest(buf,SHA_DIGEST_LENGTH,md,NULL,HASH, NULL); 255 EVP_Digest(buf, qsize, md ,NULL, evpmd, NULL);
234 256
235 /* step 8 */ 257 /* step 8 */
236 if (!BN_bin2bn(md,SHA_DIGEST_LENGTH,r0)) 258 if (!BN_bin2bn(md, qsize, r0))
237 goto err; 259 goto err;
238 if (!BN_lshift(r0,r0,160*k)) goto err; 260 if (!BN_lshift(r0,r0,(qsize << 3)*k)) goto err;
239 if (!BN_add(W,W,r0)) goto err; 261 if (!BN_add(W,W,r0)) goto err;
240 } 262 }
241 263
@@ -309,7 +331,6 @@ err:
309 ok=0; 331 ok=0;
310 goto err; 332 goto err;
311 } 333 }
312 if (seed_in != NULL) memcpy(seed_in,seed,20);
313 if (counter_ret != NULL) *counter_ret=counter; 334 if (counter_ret != NULL) *counter_ret=counter;
314 if (h_ret != NULL) *h_ret=h; 335 if (h_ret != NULL) *h_ret=h;
315 } 336 }
@@ -322,4 +343,3 @@ err:
322 return ok; 343 return ok;
323 } 344 }
324#endif 345#endif
325#endif
diff --git a/src/lib/libcrypto/dsa/dsa_key.c b/src/lib/libcrypto/dsa/dsa_key.c
index 5e39124230..c4aa86bc6d 100644
--- a/src/lib/libcrypto/dsa/dsa_key.c
+++ b/src/lib/libcrypto/dsa/dsa_key.c
@@ -64,8 +64,6 @@
64#include <openssl/dsa.h> 64#include <openssl/dsa.h>
65#include <openssl/rand.h> 65#include <openssl/rand.h>
66 66
67#ifndef OPENSSL_FIPS
68
69static int dsa_builtin_keygen(DSA *dsa); 67static int dsa_builtin_keygen(DSA *dsa);
70 68
71int DSA_generate_key(DSA *dsa) 69int DSA_generate_key(DSA *dsa)
@@ -128,5 +126,3 @@ err:
128 return(ok); 126 return(ok);
129 } 127 }
130#endif 128#endif
131
132#endif
diff --git a/src/lib/libcrypto/dsa/dsa_lib.c b/src/lib/libcrypto/dsa/dsa_lib.c
index 7ac9dc8c89..e9b75902db 100644
--- a/src/lib/libcrypto/dsa/dsa_lib.c
+++ b/src/lib/libcrypto/dsa/dsa_lib.c
@@ -76,14 +76,6 @@ static const DSA_METHOD *default_DSA_method = NULL;
76 76
77void DSA_set_default_method(const DSA_METHOD *meth) 77void DSA_set_default_method(const DSA_METHOD *meth)
78 { 78 {
79#ifdef OPENSSL_FIPS
80 if (FIPS_mode() && !(meth->flags & DSA_FLAG_FIPS_METHOD))
81 {
82 DSAerr(DSA_F_DSA_SET_DEFAULT_METHOD, DSA_R_NON_FIPS_METHOD);
83 return;
84 }
85#endif
86
87 default_DSA_method = meth; 79 default_DSA_method = meth;
88 } 80 }
89 81
@@ -104,13 +96,6 @@ int DSA_set_method(DSA *dsa, const DSA_METHOD *meth)
104 /* NB: The caller is specifically setting a method, so it's not up to us 96 /* NB: The caller is specifically setting a method, so it's not up to us
105 * to deal with which ENGINE it comes from. */ 97 * to deal with which ENGINE it comes from. */
106 const DSA_METHOD *mtmp; 98 const DSA_METHOD *mtmp;
107#ifdef OPENSSL_FIPS
108 if (FIPS_mode() && !(meth->flags & DSA_FLAG_FIPS_METHOD))
109 {
110 DSAerr(DSA_F_DSA_SET_METHOD, DSA_R_NON_FIPS_METHOD);
111 return 0;
112 }
113#endif
114 mtmp = dsa->meth; 99 mtmp = dsa->meth;
115 if (mtmp->finish) mtmp->finish(dsa); 100 if (mtmp->finish) mtmp->finish(dsa);
116#ifndef OPENSSL_NO_ENGINE 101#ifndef OPENSSL_NO_ENGINE
@@ -162,18 +147,6 @@ DSA *DSA_new_method(ENGINE *engine)
162 } 147 }
163 } 148 }
164#endif 149#endif
165#ifdef OPENSSL_FIPS
166 if (FIPS_mode() && !(ret->meth->flags & DSA_FLAG_FIPS_METHOD))
167 {
168 DSAerr(DSA_F_DSA_NEW_METHOD, DSA_R_NON_FIPS_METHOD);
169#ifndef OPENSSL_NO_ENGINE
170 if (ret->engine)
171 ENGINE_finish(ret->engine);
172#endif
173 OPENSSL_free(ret);
174 return NULL;
175 }
176#endif
177 150
178 ret->pad=0; 151 ret->pad=0;
179 ret->version=0; 152 ret->version=0;
@@ -260,6 +233,28 @@ int DSA_up_ref(DSA *r)
260 return ((i > 1) ? 1 : 0); 233 return ((i > 1) ? 1 : 0);
261 } 234 }
262 235
236int DSA_size(const DSA *r)
237 {
238 int ret,i;
239 ASN1_INTEGER bs;
240 unsigned char buf[4]; /* 4 bytes looks really small.
241 However, i2d_ASN1_INTEGER() will not look
242 beyond the first byte, as long as the second
243 parameter is NULL. */
244
245 i=BN_num_bits(r->q);
246 bs.length=(i+7)/8;
247 bs.data=buf;
248 bs.type=V_ASN1_INTEGER;
249 /* If the top bit is set the asn1 encoding is 1 larger. */
250 buf[0]=0xff;
251
252 i=i2d_ASN1_INTEGER(&bs,NULL);
253 i+=i; /* r and s */
254 ret=ASN1_object_size(1,i,V_ASN1_SEQUENCE);
255 return(ret);
256 }
257
263int DSA_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func, 258int DSA_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
264 CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func) 259 CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func)
265 { 260 {
diff --git a/src/lib/libcrypto/dsa/dsa_locl.h b/src/lib/libcrypto/dsa/dsa_locl.h
new file mode 100644
index 0000000000..2b8cfee3db
--- /dev/null
+++ b/src/lib/libcrypto/dsa/dsa_locl.h
@@ -0,0 +1,59 @@
1/* ====================================================================
2 * Copyright (c) 2007 The OpenSSL Project. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 *
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in
13 * the documentation and/or other materials provided with the
14 * distribution.
15 *
16 * 3. All advertising materials mentioning features or use of this
17 * software must display the following acknowledgment:
18 * "This product includes software developed by the OpenSSL Project
19 * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
20 *
21 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
22 * endorse or promote products derived from this software without
23 * prior written permission. For written permission, please contact
24 * openssl-core@openssl.org.
25 *
26 * 5. Products derived from this software may not be called "OpenSSL"
27 * nor may "OpenSSL" appear in their names without prior written
28 * permission of the OpenSSL Project.
29 *
30 * 6. Redistributions of any form whatsoever must retain the following
31 * acknowledgment:
32 * "This product includes software developed by the OpenSSL Project
33 * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
34 *
35 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
36 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
37 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
38 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
39 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
40 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
41 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
42 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
43 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
44 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
45 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
46 * OF THE POSSIBILITY OF SUCH DAMAGE.
47 * ====================================================================
48 *
49 * This product includes cryptographic software written by Eric Young
50 * (eay@cryptsoft.com). This product includes software written by Tim
51 * Hudson (tjh@cryptsoft.com).
52 *
53 */
54
55#include <openssl/dsa.h>
56
57int dsa_builtin_paramgen(DSA *ret, size_t bits, size_t qbits,
58 const EVP_MD *evpmd, const unsigned char *seed_in, size_t seed_len,
59 int *counter_ret, unsigned long *h_ret, BN_GENCB *cb);
diff --git a/src/lib/libcrypto/dsa/dsa_ossl.c b/src/lib/libcrypto/dsa/dsa_ossl.c
index 412cf1d88b..4fead07e80 100644
--- a/src/lib/libcrypto/dsa/dsa_ossl.c
+++ b/src/lib/libcrypto/dsa/dsa_ossl.c
@@ -61,16 +61,15 @@
61#include <stdio.h> 61#include <stdio.h>
62#include "cryptlib.h" 62#include "cryptlib.h"
63#include <openssl/bn.h> 63#include <openssl/bn.h>
64#include <openssl/sha.h>
64#include <openssl/dsa.h> 65#include <openssl/dsa.h>
65#include <openssl/rand.h> 66#include <openssl/rand.h>
66#include <openssl/asn1.h> 67#include <openssl/asn1.h>
67 68
68#ifndef OPENSSL_FIPS
69
70static DSA_SIG *dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa); 69static DSA_SIG *dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa);
71static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp); 70static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp);
72static int dsa_do_verify(const unsigned char *dgst, int dgst_len, DSA_SIG *sig, 71static int dsa_do_verify(const unsigned char *dgst, int dgst_len, DSA_SIG *sig,
73 DSA *dsa); 72 DSA *dsa);
74static int dsa_init(DSA *dsa); 73static int dsa_init(DSA *dsa);
75static int dsa_finish(DSA *dsa); 74static int dsa_finish(DSA *dsa);
76 75
@@ -135,7 +134,7 @@ static DSA_SIG *dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa)
135 BIGNUM m; 134 BIGNUM m;
136 BIGNUM xr; 135 BIGNUM xr;
137 BN_CTX *ctx=NULL; 136 BN_CTX *ctx=NULL;
138 int i,reason=ERR_R_BN_LIB; 137 int reason=ERR_R_BN_LIB;
139 DSA_SIG *ret=NULL; 138 DSA_SIG *ret=NULL;
140 139
141 BN_init(&m); 140 BN_init(&m);
@@ -150,8 +149,9 @@ static DSA_SIG *dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa)
150 s=BN_new(); 149 s=BN_new();
151 if (s == NULL) goto err; 150 if (s == NULL) goto err;
152 151
153 i=BN_num_bytes(dsa->q); /* should be 20 */ 152 /* reject a excessive digest length (currently at most
154 if ((dlen > i) || (dlen > 50)) 153 * dsa-with-SHA256 is supported) */
154 if (dlen > SHA256_DIGEST_LENGTH)
155 { 155 {
156 reason=DSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE; 156 reason=DSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE;
157 goto err; 157 goto err;
@@ -172,7 +172,14 @@ static DSA_SIG *dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa)
172 dsa->r=NULL; 172 dsa->r=NULL;
173 } 173 }
174 174
175 if (BN_bin2bn(dgst,dlen,&m) == NULL) goto err; 175
176 if (dlen > BN_num_bytes(dsa->q))
177 /* if the digest length is greater than the size of q use the
178 * BN_num_bits(dsa->q) leftmost bits of the digest, see
179 * fips 186-3, 4.2 */
180 dlen = BN_num_bytes(dsa->q);
181 if (BN_bin2bn(dgst,dlen,&m) == NULL)
182 goto err;
176 183
177 /* Compute s = inv(k) (m + xr) mod q */ 184 /* Compute s = inv(k) (m + xr) mod q */
178 if (!BN_mod_mul(&xr,dsa->priv_key,r,dsa->q,ctx)) goto err;/* s = xr */ 185 if (!BN_mod_mul(&xr,dsa->priv_key,r,dsa->q,ctx)) goto err;/* s = xr */
@@ -283,30 +290,31 @@ err:
283 if (!ret) 290 if (!ret)
284 { 291 {
285 DSAerr(DSA_F_DSA_SIGN_SETUP,ERR_R_BN_LIB); 292 DSAerr(DSA_F_DSA_SIGN_SETUP,ERR_R_BN_LIB);
286 if (kinv != NULL) BN_clear_free(kinv); 293 if (r != NULL)
287 if (r != NULL) BN_clear_free(r); 294 BN_clear_free(r);
288 } 295 }
289 if (ctx_in == NULL) BN_CTX_free(ctx); 296 if (ctx_in == NULL) BN_CTX_free(ctx);
290 if (kinv != NULL) BN_clear_free(kinv);
291 BN_clear_free(&k); 297 BN_clear_free(&k);
292 BN_clear_free(&kq); 298 BN_clear_free(&kq);
293 return(ret); 299 return(ret);
294 } 300 }
295 301
296static int dsa_do_verify(const unsigned char *dgst, int dgst_len, DSA_SIG *sig, 302static int dsa_do_verify(const unsigned char *dgst, int dgst_len, DSA_SIG *sig,
297 DSA *dsa) 303 DSA *dsa)
298 { 304 {
299 BN_CTX *ctx; 305 BN_CTX *ctx;
300 BIGNUM u1,u2,t1; 306 BIGNUM u1,u2,t1;
301 BN_MONT_CTX *mont=NULL; 307 BN_MONT_CTX *mont=NULL;
302 int ret = -1; 308 int ret = -1, i;
303 if (!dsa->p || !dsa->q || !dsa->g) 309 if (!dsa->p || !dsa->q || !dsa->g)
304 { 310 {
305 DSAerr(DSA_F_DSA_DO_VERIFY,DSA_R_MISSING_PARAMETERS); 311 DSAerr(DSA_F_DSA_DO_VERIFY,DSA_R_MISSING_PARAMETERS);
306 return -1; 312 return -1;
307 } 313 }
308 314
309 if (BN_num_bits(dsa->q) != 160) 315 i = BN_num_bits(dsa->q);
316 /* fips 186-3 allows only different sizes for q */
317 if (i != 160 && i != 224 && i != 256)
310 { 318 {
311 DSAerr(DSA_F_DSA_DO_VERIFY,DSA_R_BAD_Q_VALUE); 319 DSAerr(DSA_F_DSA_DO_VERIFY,DSA_R_BAD_Q_VALUE);
312 return -1; 320 return -1;
@@ -318,6 +326,14 @@ static int dsa_do_verify(const unsigned char *dgst, int dgst_len, DSA_SIG *sig,
318 return -1; 326 return -1;
319 } 327 }
320 328
329 /* reject a excessive digest length (currently at most
330 * dsa-with-SHA256 is supported) */
331 if (dgst_len > SHA256_DIGEST_LENGTH)
332 {
333 DSAerr(DSA_F_DSA_DO_VERIFY,DSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE);
334 return -1;
335 }
336
321 BN_init(&u1); 337 BN_init(&u1);
322 BN_init(&u2); 338 BN_init(&u2);
323 BN_init(&t1); 339 BN_init(&t1);
@@ -342,6 +358,11 @@ static int dsa_do_verify(const unsigned char *dgst, int dgst_len, DSA_SIG *sig,
342 if ((BN_mod_inverse(&u2,sig->s,dsa->q,ctx)) == NULL) goto err; 358 if ((BN_mod_inverse(&u2,sig->s,dsa->q,ctx)) == NULL) goto err;
343 359
344 /* save M in u1 */ 360 /* save M in u1 */
361 if (dgst_len > (i >> 3))
362 /* if the digest length is greater than the size of q use the
363 * BN_num_bits(dsa->q) leftmost bits of the digest, see
364 * fips 186-3, 4.2 */
365 dgst_len = (i >> 3);
345 if (BN_bin2bn(dgst,dgst_len,&u1) == NULL) goto err; 366 if (BN_bin2bn(dgst,dgst_len,&u1) == NULL) goto err;
346 367
347 /* u1 = M * w mod q */ 368 /* u1 = M * w mod q */
@@ -393,4 +414,3 @@ static int dsa_finish(DSA *dsa)
393 return(1); 414 return(1);
394} 415}
395 416
396#endif
diff --git a/src/lib/libcrypto/dsa/dsa_pmeth.c b/src/lib/libcrypto/dsa/dsa_pmeth.c
new file mode 100644
index 0000000000..4ce91e20c6
--- /dev/null
+++ b/src/lib/libcrypto/dsa/dsa_pmeth.c
@@ -0,0 +1,315 @@
1/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
2 * project 2006.
3 */
4/* ====================================================================
5 * Copyright (c) 2006 The OpenSSL Project. All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 *
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 *
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in
16 * the documentation and/or other materials provided with the
17 * distribution.
18 *
19 * 3. All advertising materials mentioning features or use of this
20 * software must display the following acknowledgment:
21 * "This product includes software developed by the OpenSSL Project
22 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
23 *
24 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
25 * endorse or promote products derived from this software without
26 * prior written permission. For written permission, please contact
27 * licensing@OpenSSL.org.
28 *
29 * 5. Products derived from this software may not be called "OpenSSL"
30 * nor may "OpenSSL" appear in their names without prior written
31 * permission of the OpenSSL Project.
32 *
33 * 6. Redistributions of any form whatsoever must retain the following
34 * acknowledgment:
35 * "This product includes software developed by the OpenSSL Project
36 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
37 *
38 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
39 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
40 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
41 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
42 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
43 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
44 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
45 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
46 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
47 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
48 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
49 * OF THE POSSIBILITY OF SUCH DAMAGE.
50 * ====================================================================
51 *
52 * This product includes cryptographic software written by Eric Young
53 * (eay@cryptsoft.com). This product includes software written by Tim
54 * Hudson (tjh@cryptsoft.com).
55 *
56 */
57
58#include <stdio.h>
59#include "cryptlib.h"
60#include <openssl/asn1t.h>
61#include <openssl/x509.h>
62#include <openssl/evp.h>
63#include <openssl/bn.h>
64#include "evp_locl.h"
65#include "dsa_locl.h"
66
67/* DSA pkey context structure */
68
69typedef struct
70 {
71 /* Parameter gen parameters */
72 int nbits; /* size of p in bits (default: 1024) */
73 int qbits; /* size of q in bits (default: 160) */
74 const EVP_MD *pmd; /* MD for parameter generation */
75 /* Keygen callback info */
76 int gentmp[2];
77 /* message digest */
78 const EVP_MD *md; /* MD for the signature */
79 } DSA_PKEY_CTX;
80
81static int pkey_dsa_init(EVP_PKEY_CTX *ctx)
82 {
83 DSA_PKEY_CTX *dctx;
84 dctx = OPENSSL_malloc(sizeof(DSA_PKEY_CTX));
85 if (!dctx)
86 return 0;
87 dctx->nbits = 1024;
88 dctx->qbits = 160;
89 dctx->pmd = NULL;
90 dctx->md = NULL;
91
92 ctx->data = dctx;
93 ctx->keygen_info = dctx->gentmp;
94 ctx->keygen_info_count = 2;
95
96 return 1;
97 }
98
99static int pkey_dsa_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src)
100 {
101 DSA_PKEY_CTX *dctx, *sctx;
102 if (!pkey_dsa_init(dst))
103 return 0;
104 sctx = src->data;
105 dctx = dst->data;
106 dctx->nbits = sctx->nbits;
107 dctx->qbits = sctx->qbits;
108 dctx->pmd = sctx->pmd;
109 dctx->md = sctx->md;
110 return 1;
111 }
112
113static void pkey_dsa_cleanup(EVP_PKEY_CTX *ctx)
114 {
115 DSA_PKEY_CTX *dctx = ctx->data;
116 if (dctx)
117 OPENSSL_free(dctx);
118 }
119
120static int pkey_dsa_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen,
121 const unsigned char *tbs, size_t tbslen)
122 {
123 int ret, type;
124 unsigned int sltmp;
125 DSA_PKEY_CTX *dctx = ctx->data;
126 DSA *dsa = ctx->pkey->pkey.dsa;
127
128 if (dctx->md)
129 type = EVP_MD_type(dctx->md);
130 else
131 type = NID_sha1;
132
133 ret = DSA_sign(type, tbs, tbslen, sig, &sltmp, dsa);
134
135 if (ret <= 0)
136 return ret;
137 *siglen = sltmp;
138 return 1;
139 }
140
141static int pkey_dsa_verify(EVP_PKEY_CTX *ctx,
142 const unsigned char *sig, size_t siglen,
143 const unsigned char *tbs, size_t tbslen)
144 {
145 int ret, type;
146 DSA_PKEY_CTX *dctx = ctx->data;
147 DSA *dsa = ctx->pkey->pkey.dsa;
148
149 if (dctx->md)
150 type = EVP_MD_type(dctx->md);
151 else
152 type = NID_sha1;
153
154 ret = DSA_verify(type, tbs, tbslen, sig, siglen, dsa);
155
156 return ret;
157 }
158
159static int pkey_dsa_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
160 {
161 DSA_PKEY_CTX *dctx = ctx->data;
162 switch (type)
163 {
164 case EVP_PKEY_CTRL_DSA_PARAMGEN_BITS:
165 if (p1 < 256)
166 return -2;
167 dctx->nbits = p1;
168 return 1;
169
170 case EVP_PKEY_CTRL_DSA_PARAMGEN_Q_BITS:
171 if (p1 != 160 && p1 != 224 && p1 && p1 != 256)
172 return -2;
173 dctx->qbits = p1;
174 return 1;
175
176 case EVP_PKEY_CTRL_DSA_PARAMGEN_MD:
177 if (EVP_MD_type((const EVP_MD *)p2) != NID_sha1 &&
178 EVP_MD_type((const EVP_MD *)p2) != NID_sha224 &&
179 EVP_MD_type((const EVP_MD *)p2) != NID_sha256)
180 {
181 DSAerr(DSA_F_PKEY_DSA_CTRL, DSA_R_INVALID_DIGEST_TYPE);
182 return 0;
183 }
184 dctx->md = p2;
185 return 1;
186
187 case EVP_PKEY_CTRL_MD:
188 if (EVP_MD_type((const EVP_MD *)p2) != NID_sha1 &&
189 EVP_MD_type((const EVP_MD *)p2) != NID_dsa &&
190 EVP_MD_type((const EVP_MD *)p2) != NID_sha224 &&
191 EVP_MD_type((const EVP_MD *)p2) != NID_sha256)
192 {
193 DSAerr(DSA_F_PKEY_DSA_CTRL, DSA_R_INVALID_DIGEST_TYPE);
194 return 0;
195 }
196 dctx->md = p2;
197 return 1;
198
199 case EVP_PKEY_CTRL_DIGESTINIT:
200 case EVP_PKEY_CTRL_PKCS7_SIGN:
201 case EVP_PKEY_CTRL_CMS_SIGN:
202 return 1;
203
204 case EVP_PKEY_CTRL_PEER_KEY:
205 DSAerr(DSA_F_PKEY_DSA_CTRL,
206 EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
207 return -2;
208 default:
209 return -2;
210
211 }
212 }
213
214static int pkey_dsa_ctrl_str(EVP_PKEY_CTX *ctx,
215 const char *type, const char *value)
216 {
217 if (!strcmp(type, "dsa_paramgen_bits"))
218 {
219 int nbits;
220 nbits = atoi(value);
221 return EVP_PKEY_CTX_set_dsa_paramgen_bits(ctx, nbits);
222 }
223 if (!strcmp(type, "dsa_paramgen_q_bits"))
224 {
225 int qbits = atoi(value);
226 return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DSA, EVP_PKEY_OP_PARAMGEN,
227 EVP_PKEY_CTRL_DSA_PARAMGEN_Q_BITS, qbits, NULL);
228 }
229 if (!strcmp(type, "dsa_paramgen_md"))
230 {
231 return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DSA, EVP_PKEY_OP_PARAMGEN,
232 EVP_PKEY_CTRL_DSA_PARAMGEN_MD, 0,
233 (void *)EVP_get_digestbyname(value));
234 }
235 return -2;
236 }
237
238static int pkey_dsa_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
239 {
240 DSA *dsa = NULL;
241 DSA_PKEY_CTX *dctx = ctx->data;
242 BN_GENCB *pcb, cb;
243 int ret;
244 if (ctx->pkey_gencb)
245 {
246 pcb = &cb;
247 evp_pkey_set_cb_translate(pcb, ctx);
248 }
249 else
250 pcb = NULL;
251 dsa = DSA_new();
252 if (!dsa)
253 return 0;
254 ret = dsa_builtin_paramgen(dsa, dctx->nbits, dctx->qbits, dctx->pmd,
255 NULL, 0, NULL, NULL, pcb);
256 if (ret)
257 EVP_PKEY_assign_DSA(pkey, dsa);
258 else
259 DSA_free(dsa);
260 return ret;
261 }
262
263static int pkey_dsa_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
264 {
265 DSA *dsa = NULL;
266 if (ctx->pkey == NULL)
267 {
268 DSAerr(DSA_F_PKEY_DSA_KEYGEN, DSA_R_NO_PARAMETERS_SET);
269 return 0;
270 }
271 dsa = DSA_new();
272 if (!dsa)
273 return 0;
274 EVP_PKEY_assign_DSA(pkey, dsa);
275 /* Note: if error return, pkey is freed by parent routine */
276 if (!EVP_PKEY_copy_parameters(pkey, ctx->pkey))
277 return 0;
278 return DSA_generate_key(pkey->pkey.dsa);
279 }
280
281const EVP_PKEY_METHOD dsa_pkey_meth =
282 {
283 EVP_PKEY_DSA,
284 EVP_PKEY_FLAG_AUTOARGLEN,
285 pkey_dsa_init,
286 pkey_dsa_copy,
287 pkey_dsa_cleanup,
288
289 0,
290 pkey_dsa_paramgen,
291
292 0,
293 pkey_dsa_keygen,
294
295 0,
296 pkey_dsa_sign,
297
298 0,
299 pkey_dsa_verify,
300
301 0,0,
302
303 0,0,0,0,
304
305 0,0,
306
307 0,0,
308
309 0,0,
310
311 pkey_dsa_ctrl,
312 pkey_dsa_ctrl_str
313
314
315 };
diff --git a/src/lib/libcrypto/dsa/dsa_prn.c b/src/lib/libcrypto/dsa/dsa_prn.c
new file mode 100644
index 0000000000..6f29f5e240
--- /dev/null
+++ b/src/lib/libcrypto/dsa/dsa_prn.c
@@ -0,0 +1,121 @@
1/* crypto/dsa/dsa_prn.c */
2/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
3 * project 2006.
4 */
5/* ====================================================================
6 * Copyright (c) 2006 The OpenSSL Project. All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 *
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 *
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in
17 * the documentation and/or other materials provided with the
18 * distribution.
19 *
20 * 3. All advertising materials mentioning features or use of this
21 * software must display the following acknowledgment:
22 * "This product includes software developed by the OpenSSL Project
23 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
24 *
25 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
26 * endorse or promote products derived from this software without
27 * prior written permission. For written permission, please contact
28 * licensing@OpenSSL.org.
29 *
30 * 5. Products derived from this software may not be called "OpenSSL"
31 * nor may "OpenSSL" appear in their names without prior written
32 * permission of the OpenSSL Project.
33 *
34 * 6. Redistributions of any form whatsoever must retain the following
35 * acknowledgment:
36 * "This product includes software developed by the OpenSSL Project
37 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
38 *
39 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
40 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
43 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
50 * OF THE POSSIBILITY OF SUCH DAMAGE.
51 * ====================================================================
52 *
53 * This product includes cryptographic software written by Eric Young
54 * (eay@cryptsoft.com). This product includes software written by Tim
55 * Hudson (tjh@cryptsoft.com).
56 *
57 */
58
59#include <stdio.h>
60#include "cryptlib.h"
61#include <openssl/evp.h>
62#include <openssl/dsa.h>
63
64#ifndef OPENSSL_NO_FP_API
65int DSA_print_fp(FILE *fp, const DSA *x, int off)
66 {
67 BIO *b;
68 int ret;
69
70 if ((b=BIO_new(BIO_s_file())) == NULL)
71 {
72 DSAerr(DSA_F_DSA_PRINT_FP,ERR_R_BUF_LIB);
73 return(0);
74 }
75 BIO_set_fp(b,fp,BIO_NOCLOSE);
76 ret=DSA_print(b,x,off);
77 BIO_free(b);
78 return(ret);
79 }
80
81int DSAparams_print_fp(FILE *fp, const DSA *x)
82 {
83 BIO *b;
84 int ret;
85
86 if ((b=BIO_new(BIO_s_file())) == NULL)
87 {
88 DSAerr(DSA_F_DSAPARAMS_PRINT_FP,ERR_R_BUF_LIB);
89 return(0);
90 }
91 BIO_set_fp(b,fp,BIO_NOCLOSE);
92 ret=DSAparams_print(b, x);
93 BIO_free(b);
94 return(ret);
95 }
96#endif
97
98int DSA_print(BIO *bp, const DSA *x, int off)
99 {
100 EVP_PKEY *pk;
101 int ret;
102 pk = EVP_PKEY_new();
103 if (!pk || !EVP_PKEY_set1_DSA(pk, (DSA *)x))
104 return 0;
105 ret = EVP_PKEY_print_private(bp, pk, off, NULL);
106 EVP_PKEY_free(pk);
107 return ret;
108 }
109
110int DSAparams_print(BIO *bp, const DSA *x)
111 {
112 EVP_PKEY *pk;
113 int ret;
114 pk = EVP_PKEY_new();
115 if (!pk || !EVP_PKEY_set1_DSA(pk, (DSA *)x))
116 return 0;
117 ret = EVP_PKEY_print_params(bp, pk, 4, NULL);
118 EVP_PKEY_free(pk);
119 return ret;
120 }
121
diff --git a/src/lib/libcrypto/dsa/dsa_sign.c b/src/lib/libcrypto/dsa/dsa_sign.c
index 4cfbbe57a8..17555e5892 100644
--- a/src/lib/libcrypto/dsa/dsa_sign.c
+++ b/src/lib/libcrypto/dsa/dsa_sign.c
@@ -58,38 +58,33 @@
58 58
59/* Original version from Steven Schoch <schoch@sheba.arc.nasa.gov> */ 59/* Original version from Steven Schoch <schoch@sheba.arc.nasa.gov> */
60 60
61#include <stdio.h>
62#include "cryptlib.h" 61#include "cryptlib.h"
63#include <openssl/bn.h>
64#include <openssl/dsa.h> 62#include <openssl/dsa.h>
65#include <openssl/rand.h> 63#include <openssl/rand.h>
66#include <openssl/asn1.h>
67#ifdef OPENSSL_FIPS
68#include <openssl/fips.h>
69#endif
70
71 64
72DSA_SIG * DSA_do_sign(const unsigned char *dgst, int dlen, DSA *dsa) 65DSA_SIG * DSA_do_sign(const unsigned char *dgst, int dlen, DSA *dsa)
73 { 66 {
74#ifdef OPENSSL_FIPS
75 if(FIPS_mode() && !(dsa->flags & DSA_FLAG_NON_FIPS_ALLOW))
76 {
77 DSAerr(DSA_F_DSA_DO_SIGN, DSA_R_OPERATION_NOT_ALLOWED_IN_FIPS_MODE);
78 return NULL;
79 }
80#endif
81 return dsa->meth->dsa_do_sign(dgst, dlen, dsa); 67 return dsa->meth->dsa_do_sign(dgst, dlen, dsa);
82 } 68 }
83 69
84int DSA_sign_setup(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp) 70int DSA_sign(int type, const unsigned char *dgst, int dlen, unsigned char *sig,
71 unsigned int *siglen, DSA *dsa)
85 { 72 {
86#ifdef OPENSSL_FIPS 73 DSA_SIG *s;
87 if(FIPS_mode() && !(dsa->flags & DSA_FLAG_NON_FIPS_ALLOW)) 74 RAND_seed(dgst, dlen);
75 s=DSA_do_sign(dgst,dlen,dsa);
76 if (s == NULL)
88 { 77 {
89 DSAerr(DSA_F_DSA_SIGN_SETUP, DSA_R_OPERATION_NOT_ALLOWED_IN_FIPS_MODE); 78 *siglen=0;
90 return 0; 79 return(0);
91 } 80 }
92#endif 81 *siglen=i2d_DSA_SIG(s,&sig);
82 DSA_SIG_free(s);
83 return(1);
84 }
85
86int DSA_sign_setup(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp)
87 {
93 return dsa->meth->dsa_sign_setup(dsa, ctx_in, kinvp, rp); 88 return dsa->meth->dsa_sign_setup(dsa, ctx_in, kinvp, rp);
94 } 89 }
95 90
diff --git a/src/lib/libcrypto/dsa/dsa_vrf.c b/src/lib/libcrypto/dsa/dsa_vrf.c
index c75e423048..226a75ff3f 100644
--- a/src/lib/libcrypto/dsa/dsa_vrf.c
+++ b/src/lib/libcrypto/dsa/dsa_vrf.c
@@ -58,27 +58,32 @@
58 58
59/* Original version from Steven Schoch <schoch@sheba.arc.nasa.gov> */ 59/* Original version from Steven Schoch <schoch@sheba.arc.nasa.gov> */
60 60
61#include <stdio.h>
62#include "cryptlib.h" 61#include "cryptlib.h"
63#include <openssl/bn.h>
64#include <openssl/dsa.h> 62#include <openssl/dsa.h>
65#include <openssl/rand.h>
66#include <openssl/asn1.h>
67#ifdef OPENSSL_FIPS
68#include <openssl/fips.h>
69#endif
70
71#include <openssl/asn1_mac.h>
72 63
73int DSA_do_verify(const unsigned char *dgst, int dgst_len, DSA_SIG *sig, 64int DSA_do_verify(const unsigned char *dgst, int dgst_len, DSA_SIG *sig,
74 DSA *dsa) 65 DSA *dsa)
75 { 66 {
76#ifdef OPENSSL_FIPS
77 if(FIPS_mode() && !(dsa->flags & DSA_FLAG_NON_FIPS_ALLOW))
78 {
79 DSAerr(DSA_F_DSA_DO_VERIFY, DSA_R_OPERATION_NOT_ALLOWED_IN_FIPS_MODE);
80 return 0;
81 }
82#endif
83 return dsa->meth->dsa_do_verify(dgst, dgst_len, sig, dsa); 67 return dsa->meth->dsa_do_verify(dgst, dgst_len, sig, dsa);
84 } 68 }
69
70/* data has already been hashed (probably with SHA or SHA-1). */
71/* returns
72 * 1: correct signature
73 * 0: incorrect signature
74 * -1: error
75 */
76int DSA_verify(int type, const unsigned char *dgst, int dgst_len,
77 const unsigned char *sigbuf, int siglen, DSA *dsa)
78 {
79 DSA_SIG *s;
80 int ret=-1;
81
82 s = DSA_SIG_new();
83 if (s == NULL) return(ret);
84 if (d2i_DSA_SIG(&s,&sigbuf,siglen) == NULL) goto err;
85 ret=DSA_do_verify(dgst,dgst_len,s,dsa);
86err:
87 DSA_SIG_free(s);
88 return(ret);
89 }
diff --git a/src/lib/libcrypto/dso/dso.h b/src/lib/libcrypto/dso/dso.h
index 3e51913a72..839f2e0617 100644
--- a/src/lib/libcrypto/dso/dso.h
+++ b/src/lib/libcrypto/dso/dso.h
@@ -170,6 +170,11 @@ typedef struct dso_meth_st
170 /* [De]Initialisation handlers. */ 170 /* [De]Initialisation handlers. */
171 int (*init)(DSO *dso); 171 int (*init)(DSO *dso);
172 int (*finish)(DSO *dso); 172 int (*finish)(DSO *dso);
173
174 /* Return pathname of the module containing location */
175 int (*pathbyaddr)(void *addr,char *path,int sz);
176 /* Perform global symbol lookup, i.e. among *all* modules */
177 void *(*globallookup)(const char *symname);
173 } DSO_METHOD; 178 } DSO_METHOD;
174 179
175/**********************************************************************/ 180/**********************************************************************/
@@ -183,7 +188,7 @@ struct dso_st
183 * for use in the dso_bind handler. All in all, let each 188 * for use in the dso_bind handler. All in all, let each
184 * method control its own destiny. "Handles" and such go in 189 * method control its own destiny. "Handles" and such go in
185 * a STACK. */ 190 * a STACK. */
186 STACK *meth_data; 191 STACK_OF(void) *meth_data;
187 int references; 192 int references;
188 int flags; 193 int flags;
189 /* For use by applications etc ... use this for your bits'n'pieces, 194 /* For use by applications etc ... use this for your bits'n'pieces,
@@ -296,6 +301,30 @@ DSO_METHOD *DSO_METHOD_win32(void);
296/* If VMS is defined, use shared images. If not, return NULL. */ 301/* If VMS is defined, use shared images. If not, return NULL. */
297DSO_METHOD *DSO_METHOD_vms(void); 302DSO_METHOD *DSO_METHOD_vms(void);
298 303
304/* This function writes null-terminated pathname of DSO module
305 * containing 'addr' into 'sz' large caller-provided 'path' and
306 * returns the number of characters [including trailing zero]
307 * written to it. If 'sz' is 0 or negative, 'path' is ignored and
308 * required amount of charachers [including trailing zero] to
309 * accomodate pathname is returned. If 'addr' is NULL, then
310 * pathname of cryptolib itself is returned. Negative or zero
311 * return value denotes error.
312 */
313int DSO_pathbyaddr(void *addr,char *path,int sz);
314
315/* This function should be used with caution! It looks up symbols in
316 * *all* loaded modules and if module gets unloaded by somebody else
317 * attempt to dereference the pointer is doomed to have fatal
318 * consequences. Primary usage for this function is to probe *core*
319 * system functionality, e.g. check if getnameinfo(3) is available
320 * at run-time without bothering about OS-specific details such as
321 * libc.so.versioning or where does it actually reside: in libc
322 * itself or libsocket. */
323void *DSO_global_lookup(const char *name);
324
325/* If BeOS is defined, use shared images. If not, return NULL. */
326DSO_METHOD *DSO_METHOD_beos(void);
327
299/* BEGIN ERROR CODES */ 328/* BEGIN ERROR CODES */
300/* The following lines are auto generated by the script mkerr.pl. Any changes 329/* The following lines are auto generated by the script mkerr.pl. Any changes
301 * made after this point may be overwritten when the script is next run. 330 * made after this point may be overwritten when the script is next run.
@@ -305,6 +334,11 @@ void ERR_load_DSO_strings(void);
305/* Error codes for the DSO functions. */ 334/* Error codes for the DSO functions. */
306 335
307/* Function codes. */ 336/* Function codes. */
337#define DSO_F_BEOS_BIND_FUNC 144
338#define DSO_F_BEOS_BIND_VAR 145
339#define DSO_F_BEOS_LOAD 146
340#define DSO_F_BEOS_NAME_CONVERTER 147
341#define DSO_F_BEOS_UNLOAD 148
308#define DSO_F_DLFCN_BIND_FUNC 100 342#define DSO_F_DLFCN_BIND_FUNC 100
309#define DSO_F_DLFCN_BIND_VAR 101 343#define DSO_F_DLFCN_BIND_VAR 101
310#define DSO_F_DLFCN_LOAD 102 344#define DSO_F_DLFCN_LOAD 102
@@ -324,22 +358,29 @@ void ERR_load_DSO_strings(void);
324#define DSO_F_DSO_FREE 111 358#define DSO_F_DSO_FREE 111
325#define DSO_F_DSO_GET_FILENAME 127 359#define DSO_F_DSO_GET_FILENAME 127
326#define DSO_F_DSO_GET_LOADED_FILENAME 128 360#define DSO_F_DSO_GET_LOADED_FILENAME 128
361#define DSO_F_DSO_GLOBAL_LOOKUP 139
327#define DSO_F_DSO_LOAD 112 362#define DSO_F_DSO_LOAD 112
328#define DSO_F_DSO_MERGE 132 363#define DSO_F_DSO_MERGE 132
329#define DSO_F_DSO_NEW_METHOD 113 364#define DSO_F_DSO_NEW_METHOD 113
365#define DSO_F_DSO_PATHBYADDR 140
330#define DSO_F_DSO_SET_FILENAME 129 366#define DSO_F_DSO_SET_FILENAME 129
331#define DSO_F_DSO_SET_NAME_CONVERTER 122 367#define DSO_F_DSO_SET_NAME_CONVERTER 122
332#define DSO_F_DSO_UP_REF 114 368#define DSO_F_DSO_UP_REF 114
369#define DSO_F_GLOBAL_LOOKUP_FUNC 138
370#define DSO_F_PATHBYADDR 137
333#define DSO_F_VMS_BIND_SYM 115 371#define DSO_F_VMS_BIND_SYM 115
334#define DSO_F_VMS_LOAD 116 372#define DSO_F_VMS_LOAD 116
335#define DSO_F_VMS_MERGER 133 373#define DSO_F_VMS_MERGER 133
336#define DSO_F_VMS_UNLOAD 117 374#define DSO_F_VMS_UNLOAD 117
337#define DSO_F_WIN32_BIND_FUNC 118 375#define DSO_F_WIN32_BIND_FUNC 118
338#define DSO_F_WIN32_BIND_VAR 119 376#define DSO_F_WIN32_BIND_VAR 119
377#define DSO_F_WIN32_GLOBALLOOKUP 142
378#define DSO_F_WIN32_GLOBALLOOKUP_FUNC 143
339#define DSO_F_WIN32_JOINER 135 379#define DSO_F_WIN32_JOINER 135
340#define DSO_F_WIN32_LOAD 120 380#define DSO_F_WIN32_LOAD 120
341#define DSO_F_WIN32_MERGER 134 381#define DSO_F_WIN32_MERGER 134
342#define DSO_F_WIN32_NAME_CONVERTER 125 382#define DSO_F_WIN32_NAME_CONVERTER 125
383#define DSO_F_WIN32_PATHBYADDR 141
343#define DSO_F_WIN32_SPLITTER 136 384#define DSO_F_WIN32_SPLITTER 136
344#define DSO_F_WIN32_UNLOAD 121 385#define DSO_F_WIN32_UNLOAD 121
345 386
diff --git a/src/lib/libcrypto/dso/dso_dlfcn.c b/src/lib/libcrypto/dso/dso_dlfcn.c
index 1fd10104c5..14bd322fb8 100644
--- a/src/lib/libcrypto/dso/dso_dlfcn.c
+++ b/src/lib/libcrypto/dso/dso_dlfcn.c
@@ -56,6 +56,16 @@
56 * 56 *
57 */ 57 */
58 58
59/* We need to do this early, because stdio.h includes the header files
60 that handle _GNU_SOURCE and other similar macros. Defining it later
61 is simply too late, because those headers are protected from re-
62 inclusion. */
63#ifdef __linux
64# ifndef _GNU_SOURCE
65# define _GNU_SOURCE /* make sure dladdr is declared */
66# endif
67#endif
68
59#include <stdio.h> 69#include <stdio.h>
60#include "cryptlib.h" 70#include "cryptlib.h"
61#include <openssl/dso.h> 71#include <openssl/dso.h>
@@ -68,7 +78,16 @@ DSO_METHOD *DSO_METHOD_dlfcn(void)
68#else 78#else
69 79
70#ifdef HAVE_DLFCN_H 80#ifdef HAVE_DLFCN_H
71#include <dlfcn.h> 81# ifdef __osf__
82# define __EXTENSIONS__
83# endif
84# include <dlfcn.h>
85# define HAVE_DLINFO 1
86# if defined(_AIX) || defined(__CYGWIN__) || \
87 defined(__SCO_VERSION__) || defined(_SCO_ELF) || \
88 (defined(__OpenBSD__) && !defined(RTLD_SELF))
89# undef HAVE_DLINFO
90# endif
72#endif 91#endif
73 92
74/* Part of the hack in "dlfcn_load" ... */ 93/* Part of the hack in "dlfcn_load" ... */
@@ -87,6 +106,8 @@ static long dlfcn_ctrl(DSO *dso, int cmd, long larg, void *parg);
87static char *dlfcn_name_converter(DSO *dso, const char *filename); 106static char *dlfcn_name_converter(DSO *dso, const char *filename);
88static char *dlfcn_merger(DSO *dso, const char *filespec1, 107static char *dlfcn_merger(DSO *dso, const char *filespec1,
89 const char *filespec2); 108 const char *filespec2);
109static int dlfcn_pathbyaddr(void *addr,char *path,int sz);
110static void *dlfcn_globallookup(const char *name);
90 111
91static DSO_METHOD dso_meth_dlfcn = { 112static DSO_METHOD dso_meth_dlfcn = {
92 "OpenSSL 'dlfcn' shared library method", 113 "OpenSSL 'dlfcn' shared library method",
@@ -103,7 +124,9 @@ static DSO_METHOD dso_meth_dlfcn = {
103 dlfcn_name_converter, 124 dlfcn_name_converter,
104 dlfcn_merger, 125 dlfcn_merger,
105 NULL, /* init */ 126 NULL, /* init */
106 NULL /* finish */ 127 NULL, /* finish */
128 dlfcn_pathbyaddr,
129 dlfcn_globallookup
107 }; 130 };
108 131
109DSO_METHOD *DSO_METHOD_dlfcn(void) 132DSO_METHOD *DSO_METHOD_dlfcn(void)
@@ -163,7 +186,7 @@ static int dlfcn_load(DSO *dso)
163 ERR_add_error_data(4, "filename(", filename, "): ", dlerror()); 186 ERR_add_error_data(4, "filename(", filename, "): ", dlerror());
164 goto err; 187 goto err;
165 } 188 }
166 if(!sk_push(dso->meth_data, (char *)ptr)) 189 if(!sk_void_push(dso->meth_data, (char *)ptr))
167 { 190 {
168 DSOerr(DSO_F_DLFCN_LOAD,DSO_R_STACK_ERROR); 191 DSOerr(DSO_F_DLFCN_LOAD,DSO_R_STACK_ERROR);
169 goto err; 192 goto err;
@@ -188,15 +211,15 @@ static int dlfcn_unload(DSO *dso)
188 DSOerr(DSO_F_DLFCN_UNLOAD,ERR_R_PASSED_NULL_PARAMETER); 211 DSOerr(DSO_F_DLFCN_UNLOAD,ERR_R_PASSED_NULL_PARAMETER);
189 return(0); 212 return(0);
190 } 213 }
191 if(sk_num(dso->meth_data) < 1) 214 if(sk_void_num(dso->meth_data) < 1)
192 return(1); 215 return(1);
193 ptr = (void *)sk_pop(dso->meth_data); 216 ptr = sk_void_pop(dso->meth_data);
194 if(ptr == NULL) 217 if(ptr == NULL)
195 { 218 {
196 DSOerr(DSO_F_DLFCN_UNLOAD,DSO_R_NULL_HANDLE); 219 DSOerr(DSO_F_DLFCN_UNLOAD,DSO_R_NULL_HANDLE);
197 /* Should push the value back onto the stack in 220 /* Should push the value back onto the stack in
198 * case of a retry. */ 221 * case of a retry. */
199 sk_push(dso->meth_data, (char *)ptr); 222 sk_void_push(dso->meth_data, ptr);
200 return(0); 223 return(0);
201 } 224 }
202 /* For now I'm not aware of any errors associated with dlclose() */ 225 /* For now I'm not aware of any errors associated with dlclose() */
@@ -213,12 +236,12 @@ static void *dlfcn_bind_var(DSO *dso, const char *symname)
213 DSOerr(DSO_F_DLFCN_BIND_VAR,ERR_R_PASSED_NULL_PARAMETER); 236 DSOerr(DSO_F_DLFCN_BIND_VAR,ERR_R_PASSED_NULL_PARAMETER);
214 return(NULL); 237 return(NULL);
215 } 238 }
216 if(sk_num(dso->meth_data) < 1) 239 if(sk_void_num(dso->meth_data) < 1)
217 { 240 {
218 DSOerr(DSO_F_DLFCN_BIND_VAR,DSO_R_STACK_ERROR); 241 DSOerr(DSO_F_DLFCN_BIND_VAR,DSO_R_STACK_ERROR);
219 return(NULL); 242 return(NULL);
220 } 243 }
221 ptr = (void *)sk_value(dso->meth_data, sk_num(dso->meth_data) - 1); 244 ptr = sk_void_value(dso->meth_data, sk_void_num(dso->meth_data) - 1);
222 if(ptr == NULL) 245 if(ptr == NULL)
223 { 246 {
224 DSOerr(DSO_F_DLFCN_BIND_VAR,DSO_R_NULL_HANDLE); 247 DSOerr(DSO_F_DLFCN_BIND_VAR,DSO_R_NULL_HANDLE);
@@ -237,32 +260,35 @@ static void *dlfcn_bind_var(DSO *dso, const char *symname)
237static DSO_FUNC_TYPE dlfcn_bind_func(DSO *dso, const char *symname) 260static DSO_FUNC_TYPE dlfcn_bind_func(DSO *dso, const char *symname)
238 { 261 {
239 void *ptr; 262 void *ptr;
240 DSO_FUNC_TYPE sym, *tsym = &sym; 263 union {
264 DSO_FUNC_TYPE sym;
265 void *dlret;
266 } u;
241 267
242 if((dso == NULL) || (symname == NULL)) 268 if((dso == NULL) || (symname == NULL))
243 { 269 {
244 DSOerr(DSO_F_DLFCN_BIND_FUNC,ERR_R_PASSED_NULL_PARAMETER); 270 DSOerr(DSO_F_DLFCN_BIND_FUNC,ERR_R_PASSED_NULL_PARAMETER);
245 return(NULL); 271 return(NULL);
246 } 272 }
247 if(sk_num(dso->meth_data) < 1) 273 if(sk_void_num(dso->meth_data) < 1)
248 { 274 {
249 DSOerr(DSO_F_DLFCN_BIND_FUNC,DSO_R_STACK_ERROR); 275 DSOerr(DSO_F_DLFCN_BIND_FUNC,DSO_R_STACK_ERROR);
250 return(NULL); 276 return(NULL);
251 } 277 }
252 ptr = (void *)sk_value(dso->meth_data, sk_num(dso->meth_data) - 1); 278 ptr = sk_void_value(dso->meth_data, sk_void_num(dso->meth_data) - 1);
253 if(ptr == NULL) 279 if(ptr == NULL)
254 { 280 {
255 DSOerr(DSO_F_DLFCN_BIND_FUNC,DSO_R_NULL_HANDLE); 281 DSOerr(DSO_F_DLFCN_BIND_FUNC,DSO_R_NULL_HANDLE);
256 return(NULL); 282 return(NULL);
257 } 283 }
258 *(void **)(tsym) = dlsym(ptr, symname); 284 u.dlret = dlsym(ptr, symname);
259 if(sym == NULL) 285 if(u.dlret == NULL)
260 { 286 {
261 DSOerr(DSO_F_DLFCN_BIND_FUNC,DSO_R_SYM_FAILURE); 287 DSOerr(DSO_F_DLFCN_BIND_FUNC,DSO_R_SYM_FAILURE);
262 ERR_add_error_data(4, "symname(", symname, "): ", dlerror()); 288 ERR_add_error_data(4, "symname(", symname, "): ", dlerror());
263 return(NULL); 289 return(NULL);
264 } 290 }
265 return(sym); 291 return u.sym;
266 } 292 }
267 293
268static char *dlfcn_merger(DSO *dso, const char *filespec1, 294static char *dlfcn_merger(DSO *dso, const char *filespec1,
@@ -278,13 +304,12 @@ static char *dlfcn_merger(DSO *dso, const char *filespec1,
278 } 304 }
279 /* If the first file specification is a rooted path, it rules. 305 /* If the first file specification is a rooted path, it rules.
280 same goes if the second file specification is missing. */ 306 same goes if the second file specification is missing. */
281 if (!filespec2 || filespec1[0] == '/') 307 if (!filespec2 || (filespec1 != NULL && filespec1[0] == '/'))
282 { 308 {
283 merged = OPENSSL_malloc(strlen(filespec1) + 1); 309 merged = OPENSSL_malloc(strlen(filespec1) + 1);
284 if(!merged) 310 if(!merged)
285 { 311 {
286 DSOerr(DSO_F_DLFCN_MERGER, 312 DSOerr(DSO_F_DLFCN_MERGER, ERR_R_MALLOC_FAILURE);
287 ERR_R_MALLOC_FAILURE);
288 return(NULL); 313 return(NULL);
289 } 314 }
290 strcpy(merged, filespec1); 315 strcpy(merged, filespec1);
@@ -310,7 +335,7 @@ static char *dlfcn_merger(DSO *dso, const char *filespec1,
310 { 335 {
311 int spec2len, len; 336 int spec2len, len;
312 337
313 spec2len = (filespec2 ? strlen(filespec2) : 0); 338 spec2len = strlen(filespec2);
314 len = spec2len + (filespec1 ? strlen(filespec1) : 0); 339 len = spec2len + (filespec1 ? strlen(filespec1) : 0);
315 340
316 if(filespec2 && filespec2[spec2len - 1] == '/') 341 if(filespec2 && filespec2[spec2len - 1] == '/')
@@ -332,6 +357,15 @@ static char *dlfcn_merger(DSO *dso, const char *filespec1,
332 return(merged); 357 return(merged);
333 } 358 }
334 359
360#ifdef OPENSSL_SYS_MACOSX
361#define DSO_ext ".dylib"
362#define DSO_extlen 6
363#else
364#define DSO_ext ".so"
365#define DSO_extlen 3
366#endif
367
368
335static char *dlfcn_name_converter(DSO *dso, const char *filename) 369static char *dlfcn_name_converter(DSO *dso, const char *filename)
336 { 370 {
337 char *translated; 371 char *translated;
@@ -342,8 +376,8 @@ static char *dlfcn_name_converter(DSO *dso, const char *filename)
342 transform = (strstr(filename, "/") == NULL); 376 transform = (strstr(filename, "/") == NULL);
343 if(transform) 377 if(transform)
344 { 378 {
345 /* We will convert this to "%s.so" or "lib%s.so" */ 379 /* We will convert this to "%s.so" or "lib%s.so" etc */
346 rsize += 3; /* The length of ".so" */ 380 rsize += DSO_extlen; /* The length of ".so" */
347 if ((DSO_flags(dso) & DSO_FLAG_NAME_TRANSLATION_EXT_ONLY) == 0) 381 if ((DSO_flags(dso) & DSO_FLAG_NAME_TRANSLATION_EXT_ONLY) == 0)
348 rsize += 3; /* The length of "lib" */ 382 rsize += 3; /* The length of "lib" */
349 } 383 }
@@ -357,13 +391,92 @@ static char *dlfcn_name_converter(DSO *dso, const char *filename)
357 if(transform) 391 if(transform)
358 { 392 {
359 if ((DSO_flags(dso) & DSO_FLAG_NAME_TRANSLATION_EXT_ONLY) == 0) 393 if ((DSO_flags(dso) & DSO_FLAG_NAME_TRANSLATION_EXT_ONLY) == 0)
360 sprintf(translated, "lib%s.so", filename); 394 sprintf(translated, "lib%s" DSO_ext, filename);
361 else 395 else
362 sprintf(translated, "%s.so", filename); 396 sprintf(translated, "%s" DSO_ext, filename);
363 } 397 }
364 else 398 else
365 sprintf(translated, "%s", filename); 399 sprintf(translated, "%s", filename);
366 return(translated); 400 return(translated);
367 } 401 }
368 402
403#ifdef __sgi
404/*
405This is a quote from IRIX manual for dladdr(3c):
406
407 <dlfcn.h> does not contain a prototype for dladdr or definition of
408 Dl_info. The #include <dlfcn.h> in the SYNOPSIS line is traditional,
409 but contains no dladdr prototype and no IRIX library contains an
410 implementation. Write your own declaration based on the code below.
411
412 The following code is dependent on internal interfaces that are not
413 part of the IRIX compatibility guarantee; however, there is no future
414 intention to change this interface, so on a practical level, the code
415 below is safe to use on IRIX.
416*/
417#include <rld_interface.h>
418#ifndef _RLD_INTERFACE_DLFCN_H_DLADDR
419#define _RLD_INTERFACE_DLFCN_H_DLADDR
420typedef struct Dl_info {
421 const char * dli_fname;
422 void * dli_fbase;
423 const char * dli_sname;
424 void * dli_saddr;
425 int dli_version;
426 int dli_reserved1;
427 long dli_reserved[4];
428} Dl_info;
429#else
430typedef struct Dl_info Dl_info;
431#endif
432#define _RLD_DLADDR 14
433
434static int dladdr(void *address, Dl_info *dl)
435{
436 void *v;
437 v = _rld_new_interface(_RLD_DLADDR,address,dl);
438 return (int)v;
439}
440#endif /* __sgi */
441
442static int dlfcn_pathbyaddr(void *addr,char *path,int sz)
443 {
444#ifdef HAVE_DLINFO
445 Dl_info dli;
446 int len;
447
448 if (addr == NULL)
449 {
450 union { int(*f)(void*,char*,int); void *p; } t =
451 { dlfcn_pathbyaddr };
452 addr = t.p;
453 }
454
455 if (dladdr(addr,&dli))
456 {
457 len = (int)strlen(dli.dli_fname);
458 if (sz <= 0) return len+1;
459 if (len >= sz) len=sz-1;
460 memcpy(path,dli.dli_fname,len);
461 path[len++]=0;
462 return len;
463 }
464
465 ERR_add_error_data(4, "dlfcn_pathbyaddr(): ", dlerror());
466#endif
467 return -1;
468 }
469
470static void *dlfcn_globallookup(const char *name)
471 {
472 void *ret = NULL,*handle = dlopen(NULL,RTLD_LAZY);
473
474 if (handle)
475 {
476 ret = dlsym(handle,name);
477 dlclose(handle);
478 }
479
480 return ret;
481 }
369#endif /* DSO_DLFCN */ 482#endif /* DSO_DLFCN */
diff --git a/src/lib/libcrypto/dso/dso_err.c b/src/lib/libcrypto/dso/dso_err.c
index a8b0a210de..2bb07c2514 100644
--- a/src/lib/libcrypto/dso/dso_err.c
+++ b/src/lib/libcrypto/dso/dso_err.c
@@ -1,6 +1,6 @@
1/* crypto/dso/dso_err.c */ 1/* crypto/dso/dso_err.c */
2/* ==================================================================== 2/* ====================================================================
3 * Copyright (c) 1999-2005 The OpenSSL Project. All rights reserved. 3 * Copyright (c) 1999-2006 The OpenSSL Project. All rights reserved.
4 * 4 *
5 * Redistribution and use in source and binary forms, with or without 5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions 6 * modification, are permitted provided that the following conditions
@@ -70,6 +70,11 @@
70 70
71static ERR_STRING_DATA DSO_str_functs[]= 71static ERR_STRING_DATA DSO_str_functs[]=
72 { 72 {
73{ERR_FUNC(DSO_F_BEOS_BIND_FUNC), "BEOS_BIND_FUNC"},
74{ERR_FUNC(DSO_F_BEOS_BIND_VAR), "BEOS_BIND_VAR"},
75{ERR_FUNC(DSO_F_BEOS_LOAD), "BEOS_LOAD"},
76{ERR_FUNC(DSO_F_BEOS_NAME_CONVERTER), "BEOS_NAME_CONVERTER"},
77{ERR_FUNC(DSO_F_BEOS_UNLOAD), "BEOS_UNLOAD"},
73{ERR_FUNC(DSO_F_DLFCN_BIND_FUNC), "DLFCN_BIND_FUNC"}, 78{ERR_FUNC(DSO_F_DLFCN_BIND_FUNC), "DLFCN_BIND_FUNC"},
74{ERR_FUNC(DSO_F_DLFCN_BIND_VAR), "DLFCN_BIND_VAR"}, 79{ERR_FUNC(DSO_F_DLFCN_BIND_VAR), "DLFCN_BIND_VAR"},
75{ERR_FUNC(DSO_F_DLFCN_LOAD), "DLFCN_LOAD"}, 80{ERR_FUNC(DSO_F_DLFCN_LOAD), "DLFCN_LOAD"},
@@ -89,22 +94,29 @@ static ERR_STRING_DATA DSO_str_functs[]=
89{ERR_FUNC(DSO_F_DSO_FREE), "DSO_free"}, 94{ERR_FUNC(DSO_F_DSO_FREE), "DSO_free"},
90{ERR_FUNC(DSO_F_DSO_GET_FILENAME), "DSO_get_filename"}, 95{ERR_FUNC(DSO_F_DSO_GET_FILENAME), "DSO_get_filename"},
91{ERR_FUNC(DSO_F_DSO_GET_LOADED_FILENAME), "DSO_get_loaded_filename"}, 96{ERR_FUNC(DSO_F_DSO_GET_LOADED_FILENAME), "DSO_get_loaded_filename"},
97{ERR_FUNC(DSO_F_DSO_GLOBAL_LOOKUP), "DSO_global_lookup"},
92{ERR_FUNC(DSO_F_DSO_LOAD), "DSO_load"}, 98{ERR_FUNC(DSO_F_DSO_LOAD), "DSO_load"},
93{ERR_FUNC(DSO_F_DSO_MERGE), "DSO_merge"}, 99{ERR_FUNC(DSO_F_DSO_MERGE), "DSO_merge"},
94{ERR_FUNC(DSO_F_DSO_NEW_METHOD), "DSO_new_method"}, 100{ERR_FUNC(DSO_F_DSO_NEW_METHOD), "DSO_new_method"},
101{ERR_FUNC(DSO_F_DSO_PATHBYADDR), "DSO_pathbyaddr"},
95{ERR_FUNC(DSO_F_DSO_SET_FILENAME), "DSO_set_filename"}, 102{ERR_FUNC(DSO_F_DSO_SET_FILENAME), "DSO_set_filename"},
96{ERR_FUNC(DSO_F_DSO_SET_NAME_CONVERTER), "DSO_set_name_converter"}, 103{ERR_FUNC(DSO_F_DSO_SET_NAME_CONVERTER), "DSO_set_name_converter"},
97{ERR_FUNC(DSO_F_DSO_UP_REF), "DSO_up_ref"}, 104{ERR_FUNC(DSO_F_DSO_UP_REF), "DSO_up_ref"},
105{ERR_FUNC(DSO_F_GLOBAL_LOOKUP_FUNC), "GLOBAL_LOOKUP_FUNC"},
106{ERR_FUNC(DSO_F_PATHBYADDR), "PATHBYADDR"},
98{ERR_FUNC(DSO_F_VMS_BIND_SYM), "VMS_BIND_SYM"}, 107{ERR_FUNC(DSO_F_VMS_BIND_SYM), "VMS_BIND_SYM"},
99{ERR_FUNC(DSO_F_VMS_LOAD), "VMS_LOAD"}, 108{ERR_FUNC(DSO_F_VMS_LOAD), "VMS_LOAD"},
100{ERR_FUNC(DSO_F_VMS_MERGER), "VMS_MERGER"}, 109{ERR_FUNC(DSO_F_VMS_MERGER), "VMS_MERGER"},
101{ERR_FUNC(DSO_F_VMS_UNLOAD), "VMS_UNLOAD"}, 110{ERR_FUNC(DSO_F_VMS_UNLOAD), "VMS_UNLOAD"},
102{ERR_FUNC(DSO_F_WIN32_BIND_FUNC), "WIN32_BIND_FUNC"}, 111{ERR_FUNC(DSO_F_WIN32_BIND_FUNC), "WIN32_BIND_FUNC"},
103{ERR_FUNC(DSO_F_WIN32_BIND_VAR), "WIN32_BIND_VAR"}, 112{ERR_FUNC(DSO_F_WIN32_BIND_VAR), "WIN32_BIND_VAR"},
113{ERR_FUNC(DSO_F_WIN32_GLOBALLOOKUP), "WIN32_GLOBALLOOKUP"},
114{ERR_FUNC(DSO_F_WIN32_GLOBALLOOKUP_FUNC), "WIN32_GLOBALLOOKUP_FUNC"},
104{ERR_FUNC(DSO_F_WIN32_JOINER), "WIN32_JOINER"}, 115{ERR_FUNC(DSO_F_WIN32_JOINER), "WIN32_JOINER"},
105{ERR_FUNC(DSO_F_WIN32_LOAD), "WIN32_LOAD"}, 116{ERR_FUNC(DSO_F_WIN32_LOAD), "WIN32_LOAD"},
106{ERR_FUNC(DSO_F_WIN32_MERGER), "WIN32_MERGER"}, 117{ERR_FUNC(DSO_F_WIN32_MERGER), "WIN32_MERGER"},
107{ERR_FUNC(DSO_F_WIN32_NAME_CONVERTER), "WIN32_NAME_CONVERTER"}, 118{ERR_FUNC(DSO_F_WIN32_NAME_CONVERTER), "WIN32_NAME_CONVERTER"},
119{ERR_FUNC(DSO_F_WIN32_PATHBYADDR), "WIN32_PATHBYADDR"},
108{ERR_FUNC(DSO_F_WIN32_SPLITTER), "WIN32_SPLITTER"}, 120{ERR_FUNC(DSO_F_WIN32_SPLITTER), "WIN32_SPLITTER"},
109{ERR_FUNC(DSO_F_WIN32_UNLOAD), "WIN32_UNLOAD"}, 121{ERR_FUNC(DSO_F_WIN32_UNLOAD), "WIN32_UNLOAD"},
110{0,NULL} 122{0,NULL}
diff --git a/src/lib/libcrypto/dso/dso_lib.c b/src/lib/libcrypto/dso/dso_lib.c
index 49bdd71309..8a15b794ab 100644
--- a/src/lib/libcrypto/dso/dso_lib.c
+++ b/src/lib/libcrypto/dso/dso_lib.c
@@ -107,7 +107,7 @@ DSO *DSO_new_method(DSO_METHOD *meth)
107 return(NULL); 107 return(NULL);
108 } 108 }
109 memset(ret, 0, sizeof(DSO)); 109 memset(ret, 0, sizeof(DSO));
110 ret->meth_data = sk_new_null(); 110 ret->meth_data = sk_void_new_null();
111 if(ret->meth_data == NULL) 111 if(ret->meth_data == NULL)
112 { 112 {
113 /* sk_new doesn't generate any errors so we do */ 113 /* sk_new doesn't generate any errors so we do */
@@ -163,7 +163,7 @@ int DSO_free(DSO *dso)
163 return(0); 163 return(0);
164 } 164 }
165 165
166 sk_free(dso->meth_data); 166 sk_void_free(dso->meth_data);
167 if(dso->filename != NULL) 167 if(dso->filename != NULL)
168 OPENSSL_free(dso->filename); 168 OPENSSL_free(dso->filename);
169 if(dso->loaded_filename != NULL) 169 if(dso->loaded_filename != NULL)
@@ -399,13 +399,6 @@ char *DSO_merge(DSO *dso, const char *filespec1, const char *filespec2)
399 DSOerr(DSO_F_DSO_MERGE,ERR_R_PASSED_NULL_PARAMETER); 399 DSOerr(DSO_F_DSO_MERGE,ERR_R_PASSED_NULL_PARAMETER);
400 return(NULL); 400 return(NULL);
401 } 401 }
402 if(filespec1 == NULL)
403 filespec1 = dso->filename;
404 if(filespec1 == NULL)
405 {
406 DSOerr(DSO_F_DSO_MERGE,DSO_R_NO_FILE_SPECIFICATION);
407 return(NULL);
408 }
409 if((dso->flags & DSO_FLAG_NO_NAME_TRANSLATION) == 0) 402 if((dso->flags & DSO_FLAG_NO_NAME_TRANSLATION) == 0)
410 { 403 {
411 if(dso->merger != NULL) 404 if(dso->merger != NULL)
@@ -464,3 +457,27 @@ const char *DSO_get_loaded_filename(DSO *dso)
464 } 457 }
465 return(dso->loaded_filename); 458 return(dso->loaded_filename);
466 } 459 }
460
461int DSO_pathbyaddr(void *addr,char *path,int sz)
462 {
463 DSO_METHOD *meth = default_DSO_meth;
464 if (meth == NULL) meth = DSO_METHOD_openssl();
465 if (meth->pathbyaddr == NULL)
466 {
467 DSOerr(DSO_F_DSO_PATHBYADDR,DSO_R_UNSUPPORTED);
468 return -1;
469 }
470 return (*meth->pathbyaddr)(addr,path,sz);
471 }
472
473void *DSO_global_lookup(const char *name)
474 {
475 DSO_METHOD *meth = default_DSO_meth;
476 if (meth == NULL) meth = DSO_METHOD_openssl();
477 if (meth->globallookup == NULL)
478 {
479 DSOerr(DSO_F_DSO_GLOBAL_LOOKUP,DSO_R_UNSUPPORTED);
480 return NULL;
481 }
482 return (*meth->globallookup)(name);
483 }
diff --git a/src/lib/libcrypto/dso/dso_null.c b/src/lib/libcrypto/dso/dso_null.c
index 4972984651..49d842d1f5 100644
--- a/src/lib/libcrypto/dso/dso_null.c
+++ b/src/lib/libcrypto/dso/dso_null.c
@@ -78,7 +78,9 @@ static DSO_METHOD dso_meth_null = {
78 NULL, /* dso_name_converter */ 78 NULL, /* dso_name_converter */
79 NULL, /* dso_merger */ 79 NULL, /* dso_merger */
80 NULL, /* init */ 80 NULL, /* init */
81 NULL /* finish */ 81 NULL, /* finish */
82 NULL, /* pathbyaddr */
83 NULL /* globallookup */
82 }; 84 };
83 85
84DSO_METHOD *DSO_METHOD_null(void) 86DSO_METHOD *DSO_METHOD_null(void)
diff --git a/src/lib/libcrypto/dso/dso_openssl.c b/src/lib/libcrypto/dso/dso_openssl.c
index a4395ebffe..b17e8e8e9e 100644
--- a/src/lib/libcrypto/dso/dso_openssl.c
+++ b/src/lib/libcrypto/dso/dso_openssl.c
@@ -74,6 +74,8 @@ DSO_METHOD *DSO_METHOD_openssl(void)
74 return(DSO_METHOD_win32()); 74 return(DSO_METHOD_win32());
75#elif defined(DSO_VMS) 75#elif defined(DSO_VMS)
76 return(DSO_METHOD_vms()); 76 return(DSO_METHOD_vms());
77#elif defined(DSO_BEOS)
78 return(DSO_METHOD_beos());
77#else 79#else
78 return(DSO_METHOD_null()); 80 return(DSO_METHOD_null());
79#endif 81#endif
diff --git a/src/lib/libcrypto/ec/ec.h b/src/lib/libcrypto/ec/ec.h
index 8bc2a235b1..ee7078130c 100644
--- a/src/lib/libcrypto/ec/ec.h
+++ b/src/lib/libcrypto/ec/ec.h
@@ -2,8 +2,12 @@
2/* 2/*
3 * Originally written by Bodo Moeller for the OpenSSL project. 3 * Originally written by Bodo Moeller for the OpenSSL project.
4 */ 4 */
5/**
6 * \file crypto/ec/ec.h Include file for the OpenSSL EC functions
7 * \author Originally written by Bodo Moeller for the OpenSSL project
8 */
5/* ==================================================================== 9/* ====================================================================
6 * Copyright (c) 1998-2003 The OpenSSL Project. All rights reserved. 10 * Copyright (c) 1998-2005 The OpenSSL Project. All rights reserved.
7 * 11 *
8 * Redistribution and use in source and binary forms, with or without 12 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions 13 * modification, are permitted provided that the following conditions
@@ -92,15 +96,21 @@ extern "C" {
92# endif 96# endif
93#endif 97#endif
94 98
95 99
96#ifndef OPENSSL_ECC_MAX_FIELD_BITS 100#ifndef OPENSSL_ECC_MAX_FIELD_BITS
97# define OPENSSL_ECC_MAX_FIELD_BITS 661 101# define OPENSSL_ECC_MAX_FIELD_BITS 661
98#endif 102#endif
99 103
104/** Enum for the point conversion form as defined in X9.62 (ECDSA)
105 * for the encoding of a elliptic curve point (x,y) */
100typedef enum { 106typedef enum {
101 /* values as defined in X9.62 (ECDSA) and elsewhere */ 107 /** the point is encoded as z||x, where the octet z specifies
108 * which solution of the quadratic equation y is */
102 POINT_CONVERSION_COMPRESSED = 2, 109 POINT_CONVERSION_COMPRESSED = 2,
110 /** the point is encoded as z||x||y, where z is the octet 0x02 */
103 POINT_CONVERSION_UNCOMPRESSED = 4, 111 POINT_CONVERSION_UNCOMPRESSED = 4,
112 /** the point is encoded as z||x||y, where the octet z specifies
113 * which solution of the quadratic equation y is */
104 POINT_CONVERSION_HYBRID = 6 114 POINT_CONVERSION_HYBRID = 6
105} point_conversion_form_t; 115} point_conversion_form_t;
106 116
@@ -121,37 +131,129 @@ typedef struct ec_group_st
121typedef struct ec_point_st EC_POINT; 131typedef struct ec_point_st EC_POINT;
122 132
123 133
124/* EC_METHODs for curves over GF(p). 134/********************************************************************/
125 * EC_GFp_simple_method provides the basis for the optimized methods. 135/* EC_METHODs for curves over GF(p) */
136/********************************************************************/
137
138/** Returns the basic GFp ec methods which provides the basis for the
139 * optimized methods.
140 * \return EC_METHOD object
126 */ 141 */
127const EC_METHOD *EC_GFp_simple_method(void); 142const EC_METHOD *EC_GFp_simple_method(void);
143
144/** Returns GFp methods using montgomery multiplication.
145 * \return EC_METHOD object
146 */
128const EC_METHOD *EC_GFp_mont_method(void); 147const EC_METHOD *EC_GFp_mont_method(void);
148
149/** Returns GFp methods using optimized methods for NIST recommended curves
150 * \return EC_METHOD object
151 */
129const EC_METHOD *EC_GFp_nist_method(void); 152const EC_METHOD *EC_GFp_nist_method(void);
130 153
131/* EC_METHOD for curves over GF(2^m). 154
155/********************************************************************/
156/* EC_METHOD for curves over GF(2^m) */
157/********************************************************************/
158
159/** Returns the basic GF2m ec method
160 * \return EC_METHOD object
132 */ 161 */
133const EC_METHOD *EC_GF2m_simple_method(void); 162const EC_METHOD *EC_GF2m_simple_method(void);
134 163
135 164
136EC_GROUP *EC_GROUP_new(const EC_METHOD *); 165/********************************************************************/
137void EC_GROUP_free(EC_GROUP *); 166/* EC_GROUP functions */
138void EC_GROUP_clear_free(EC_GROUP *); 167/********************************************************************/
139int EC_GROUP_copy(EC_GROUP *, const EC_GROUP *);
140EC_GROUP *EC_GROUP_dup(const EC_GROUP *);
141 168
142const EC_METHOD *EC_GROUP_method_of(const EC_GROUP *); 169/** Creates a new EC_GROUP object
143int EC_METHOD_get_field_type(const EC_METHOD *); 170 * \param meth EC_METHOD to use
171 * \return newly created EC_GROUP object or NULL in case of an error.
172 */
173EC_GROUP *EC_GROUP_new(const EC_METHOD *meth);
144 174
145int EC_GROUP_set_generator(EC_GROUP *, const EC_POINT *generator, const BIGNUM *order, const BIGNUM *cofactor); 175/** Frees a EC_GROUP object
146const EC_POINT *EC_GROUP_get0_generator(const EC_GROUP *); 176 * \param group EC_GROUP object to be freed.
147int EC_GROUP_get_order(const EC_GROUP *, BIGNUM *order, BN_CTX *); 177 */
148int EC_GROUP_get_cofactor(const EC_GROUP *, BIGNUM *cofactor, BN_CTX *); 178void EC_GROUP_free(EC_GROUP *group);
149 179
150void EC_GROUP_set_curve_name(EC_GROUP *, int nid); 180/** Clears and frees a EC_GROUP object
151int EC_GROUP_get_curve_name(const EC_GROUP *); 181 * \param group EC_GROUP object to be cleared and freed.
182 */
183void EC_GROUP_clear_free(EC_GROUP *group);
152 184
153void EC_GROUP_set_asn1_flag(EC_GROUP *, int flag); 185/** Copies EC_GROUP objects. Note: both EC_GROUPs must use the same EC_METHOD.
154int EC_GROUP_get_asn1_flag(const EC_GROUP *); 186 * \param dst destination EC_GROUP object
187 * \param src source EC_GROUP object
188 * \return 1 on success and 0 if an error occurred.
189 */
190int EC_GROUP_copy(EC_GROUP *dst, const EC_GROUP *src);
191
192/** Creates a new EC_GROUP object and copies the copies the content
193 * form src to the newly created EC_KEY object
194 * \param src source EC_GROUP object
195 * \return newly created EC_GROUP object or NULL in case of an error.
196 */
197EC_GROUP *EC_GROUP_dup(const EC_GROUP *src);
198
199/** Returns the EC_METHOD of the EC_GROUP object.
200 * \param group EC_GROUP object
201 * \return EC_METHOD used in this EC_GROUP object.
202 */
203const EC_METHOD *EC_GROUP_method_of(const EC_GROUP *group);
204
205/** Returns the field type of the EC_METHOD.
206 * \param meth EC_METHOD object
207 * \return NID of the underlying field type OID.
208 */
209int EC_METHOD_get_field_type(const EC_METHOD *meth);
210
211/** Sets the generator and it's order/cofactor of a EC_GROUP object.
212 * \param group EC_GROUP object
213 * \param generator EC_POINT object with the generator.
214 * \param order the order of the group generated by the generator.
215 * \param cofactor the index of the sub-group generated by the generator
216 * in the group of all points on the elliptic curve.
217 * \return 1 on success and 0 if an error occured
218 */
219int EC_GROUP_set_generator(EC_GROUP *group, const EC_POINT *generator, const BIGNUM *order, const BIGNUM *cofactor);
220
221/** Returns the generator of a EC_GROUP object.
222 * \param group EC_GROUP object
223 * \return the currently used generator (possibly NULL).
224 */
225const EC_POINT *EC_GROUP_get0_generator(const EC_GROUP *group);
226
227/** Gets the order of a EC_GROUP
228 * \param group EC_GROUP object
229 * \param order BIGNUM to which the order is copied
230 * \param ctx BN_CTX object (optional)
231 * \return 1 on success and 0 if an error occured
232 */
233int EC_GROUP_get_order(const EC_GROUP *group, BIGNUM *order, BN_CTX *ctx);
234
235/** Gets the cofactor of a EC_GROUP
236 * \param group EC_GROUP object
237 * \param cofactor BIGNUM to which the cofactor is copied
238 * \param ctx BN_CTX object (optional)
239 * \return 1 on success and 0 if an error occured
240 */
241int EC_GROUP_get_cofactor(const EC_GROUP *group, BIGNUM *cofactor, BN_CTX *ctx);
242
243/** Sets the name of a EC_GROUP object
244 * \param group EC_GROUP object
245 * \param nid NID of the curve name OID
246 */
247void EC_GROUP_set_curve_name(EC_GROUP *group, int nid);
248
249/** Returns the curve name of a EC_GROUP object
250 * \param group EC_GROUP object
251 * \return NID of the curve name OID or 0 if not set.
252 */
253int EC_GROUP_get_curve_name(const EC_GROUP *group);
254
255void EC_GROUP_set_asn1_flag(EC_GROUP *group, int flag);
256int EC_GROUP_get_asn1_flag(const EC_GROUP *group);
155 257
156void EC_GROUP_set_point_conversion_form(EC_GROUP *, point_conversion_form_t); 258void EC_GROUP_set_point_conversion_form(EC_GROUP *, point_conversion_form_t);
157point_conversion_form_t EC_GROUP_get_point_conversion_form(const EC_GROUP *); 259point_conversion_form_t EC_GROUP_get_point_conversion_form(const EC_GROUP *);
@@ -160,36 +262,114 @@ unsigned char *EC_GROUP_get0_seed(const EC_GROUP *);
160size_t EC_GROUP_get_seed_len(const EC_GROUP *); 262size_t EC_GROUP_get_seed_len(const EC_GROUP *);
161size_t EC_GROUP_set_seed(EC_GROUP *, const unsigned char *, size_t len); 263size_t EC_GROUP_set_seed(EC_GROUP *, const unsigned char *, size_t len);
162 264
163int EC_GROUP_set_curve_GFp(EC_GROUP *, const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *); 265/** Sets the parameter of a ec over GFp defined by y^2 = x^3 + a*x + b
164int EC_GROUP_get_curve_GFp(const EC_GROUP *, BIGNUM *p, BIGNUM *a, BIGNUM *b, BN_CTX *); 266 * \param group EC_GROUP object
165int EC_GROUP_set_curve_GF2m(EC_GROUP *, const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *); 267 * \param p BIGNUM with the prime number
166int EC_GROUP_get_curve_GF2m(const EC_GROUP *, BIGNUM *p, BIGNUM *a, BIGNUM *b, BN_CTX *); 268 * \param a BIGNUM with parameter a of the equation
269 * \param b BIGNUM with parameter b of the equation
270 * \param ctx BN_CTX object (optional)
271 * \return 1 on success and 0 if an error occured
272 */
273int EC_GROUP_set_curve_GFp(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx);
274
275/** Gets the parameter of the ec over GFp defined by y^2 = x^3 + a*x + b
276 * \param group EC_GROUP object
277 * \param p BIGNUM for the prime number
278 * \param a BIGNUM for parameter a of the equation
279 * \param b BIGNUM for parameter b of the equation
280 * \param ctx BN_CTX object (optional)
281 * \return 1 on success and 0 if an error occured
282 */
283int EC_GROUP_get_curve_GFp(const EC_GROUP *group, BIGNUM *p, BIGNUM *a, BIGNUM *b, BN_CTX *ctx);
284
285/** Sets the parameter of a ec over GF2m defined by y^2 + x*y = x^3 + a*x^2 + b
286 * \param group EC_GROUP object
287 * \param p BIGNUM with the polynomial defining the underlying field
288 * \param a BIGNUM with parameter a of the equation
289 * \param b BIGNUM with parameter b of the equation
290 * \param ctx BN_CTX object (optional)
291 * \return 1 on success and 0 if an error occured
292 */
293int EC_GROUP_set_curve_GF2m(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx);
294
295/** Gets the parameter of the ec over GF2m defined by y^2 + x*y = x^3 + a*x^2 + b
296 * \param group EC_GROUP object
297 * \param p BIGNUM for the polynomial defining the underlying field
298 * \param a BIGNUM for parameter a of the equation
299 * \param b BIGNUM for parameter b of the equation
300 * \param ctx BN_CTX object (optional)
301 * \return 1 on success and 0 if an error occured
302 */
303int EC_GROUP_get_curve_GF2m(const EC_GROUP *group, BIGNUM *p, BIGNUM *a, BIGNUM *b, BN_CTX *ctx);
167 304
168/* returns the number of bits needed to represent a field element */ 305/** Returns the number of bits needed to represent a field element
169int EC_GROUP_get_degree(const EC_GROUP *); 306 * \param group EC_GROUP object
307 * \return number of bits needed to represent a field element
308 */
309int EC_GROUP_get_degree(const EC_GROUP *group);
170 310
171/* EC_GROUP_check() returns 1 if 'group' defines a valid group, 0 otherwise */ 311/** Checks whether the parameter in the EC_GROUP define a valid ec group
312 * \param group EC_GROUP object
313 * \param ctx BN_CTX object (optional)
314 * \return 1 if group is a valid ec group and 0 otherwise
315 */
172int EC_GROUP_check(const EC_GROUP *group, BN_CTX *ctx); 316int EC_GROUP_check(const EC_GROUP *group, BN_CTX *ctx);
173/* EC_GROUP_check_discriminant() returns 1 if the discriminant of the
174 * elliptic curve is not zero, 0 otherwise */
175int EC_GROUP_check_discriminant(const EC_GROUP *, BN_CTX *);
176 317
177/* EC_GROUP_cmp() returns 0 if both groups are equal and 1 otherwise */ 318/** Checks whether the discriminant of the elliptic curve is zero or not
178int EC_GROUP_cmp(const EC_GROUP *, const EC_GROUP *, BN_CTX *); 319 * \param group EC_GROUP object
320 * \param ctx BN_CTX object (optional)
321 * \return 1 if the discriminant is not zero and 0 otherwise
322 */
323int EC_GROUP_check_discriminant(const EC_GROUP *group, BN_CTX *ctx);
324
325/** Compares two EC_GROUP objects
326 * \param a first EC_GROUP object
327 * \param b second EC_GROUP object
328 * \param ctx BN_CTX object (optional)
329 * \return 0 if both groups are equal and 1 otherwise
330 */
331int EC_GROUP_cmp(const EC_GROUP *a, const EC_GROUP *b, BN_CTX *ctx);
179 332
180/* EC_GROUP_new_GF*() calls EC_GROUP_new() and EC_GROUP_set_GF*() 333/* EC_GROUP_new_GF*() calls EC_GROUP_new() and EC_GROUP_set_GF*()
181 * after choosing an appropriate EC_METHOD */ 334 * after choosing an appropriate EC_METHOD */
182EC_GROUP *EC_GROUP_new_curve_GFp(const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *);
183EC_GROUP *EC_GROUP_new_curve_GF2m(const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *);
184 335
185/* EC_GROUP_new_by_curve_name() creates a EC_GROUP structure 336/** Creates a new EC_GROUP object with the specified parameters defined
186 * specified by a curve name (in form of a NID) */ 337 * over GFp (defined by the equation y^2 = x^3 + a*x + b)
338 * \param p BIGNUM with the prime number
339 * \param a BIGNUM with the parameter a of the equation
340 * \param b BIGNUM with the parameter b of the equation
341 * \param ctx BN_CTX object (optional)
342 * \return newly created EC_GROUP object with the specified parameters
343 */
344EC_GROUP *EC_GROUP_new_curve_GFp(const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx);
345
346/** Creates a new EC_GROUP object with the specified parameters defined
347 * over GF2m (defined by the equation y^2 + x*y = x^3 + a*x^2 + b)
348 * \param p BIGNUM with the polynomial defining the underlying field
349 * \param a BIGNUM with the parameter a of the equation
350 * \param b BIGNUM with the parameter b of the equation
351 * \param ctx BN_CTX object (optional)
352 * \return newly created EC_GROUP object with the specified parameters
353 */
354EC_GROUP *EC_GROUP_new_curve_GF2m(const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx);
355
356/** Creates a EC_GROUP object with a curve specified by a NID
357 * \param nid NID of the OID of the curve name
358 * \return newly created EC_GROUP object with specified curve or NULL
359 * if an error occurred
360 */
187EC_GROUP *EC_GROUP_new_by_curve_name(int nid); 361EC_GROUP *EC_GROUP_new_by_curve_name(int nid);
188/* handling of internal curves */ 362
363
364/********************************************************************/
365/* handling of internal curves */
366/********************************************************************/
367
189typedef struct { 368typedef struct {
190 int nid; 369 int nid;
191 const char *comment; 370 const char *comment;
192 } EC_builtin_curve; 371 } EC_builtin_curve;
372
193/* EC_builtin_curves(EC_builtin_curve *r, size_t size) returns number 373/* EC_builtin_curves(EC_builtin_curve *r, size_t size) returns number
194 * of all available curves or zero if a error occurred. 374 * of all available curves or zero if a error occurred.
195 * In case r ist not zero nitems EC_builtin_curve structures 375 * In case r ist not zero nitems EC_builtin_curve structures
@@ -197,39 +377,168 @@ typedef struct {
197size_t EC_get_builtin_curves(EC_builtin_curve *r, size_t nitems); 377size_t EC_get_builtin_curves(EC_builtin_curve *r, size_t nitems);
198 378
199 379
200/* EC_POINT functions */ 380/********************************************************************/
381/* EC_POINT functions */
382/********************************************************************/
383
384/** Creates a new EC_POINT object for the specified EC_GROUP
385 * \param group EC_GROUP the underlying EC_GROUP object
386 * \return newly created EC_POINT object or NULL if an error occurred
387 */
388EC_POINT *EC_POINT_new(const EC_GROUP *group);
389
390/** Frees a EC_POINT object
391 * \param point EC_POINT object to be freed
392 */
393void EC_POINT_free(EC_POINT *point);
394
395/** Clears and frees a EC_POINT object
396 * \param point EC_POINT object to be cleared and freed
397 */
398void EC_POINT_clear_free(EC_POINT *point);
399
400/** Copies EC_POINT object
401 * \param dst destination EC_POINT object
402 * \param src source EC_POINT object
403 * \return 1 on success and 0 if an error occured
404 */
405int EC_POINT_copy(EC_POINT *dst, const EC_POINT *src);
201 406
202EC_POINT *EC_POINT_new(const EC_GROUP *); 407/** Creates a new EC_POINT object and copies the content of the supplied
203void EC_POINT_free(EC_POINT *); 408 * EC_POINT
204void EC_POINT_clear_free(EC_POINT *); 409 * \param src source EC_POINT object
205int EC_POINT_copy(EC_POINT *, const EC_POINT *); 410 * \param group underlying the EC_GROUP object
206EC_POINT *EC_POINT_dup(const EC_POINT *, const EC_GROUP *); 411 * \return newly created EC_POINT object or NULL if an error occurred
412 */
413EC_POINT *EC_POINT_dup(const EC_POINT *src, const EC_GROUP *group);
207 414
208const EC_METHOD *EC_POINT_method_of(const EC_POINT *); 415/** Returns the EC_METHOD used in EC_POINT object
209 416 * \param point EC_POINT object
210int EC_POINT_set_to_infinity(const EC_GROUP *, EC_POINT *); 417 * \return the EC_METHOD used
211int EC_POINT_set_Jprojective_coordinates_GFp(const EC_GROUP *, EC_POINT *, 418 */
212 const BIGNUM *x, const BIGNUM *y, const BIGNUM *z, BN_CTX *); 419const EC_METHOD *EC_POINT_method_of(const EC_POINT *point);
213int EC_POINT_get_Jprojective_coordinates_GFp(const EC_GROUP *, const EC_POINT *, 420
214 BIGNUM *x, BIGNUM *y, BIGNUM *z, BN_CTX *); 421/** Sets a point to infinity (neutral element)
215int EC_POINT_set_affine_coordinates_GFp(const EC_GROUP *, EC_POINT *, 422 * \param group underlying EC_GROUP object
216 const BIGNUM *x, const BIGNUM *y, BN_CTX *); 423 * \param point EC_POINT to set to infinity
217int EC_POINT_get_affine_coordinates_GFp(const EC_GROUP *, const EC_POINT *, 424 * \return 1 on success and 0 if an error occured
218 BIGNUM *x, BIGNUM *y, BN_CTX *); 425 */
219int EC_POINT_set_compressed_coordinates_GFp(const EC_GROUP *, EC_POINT *, 426int EC_POINT_set_to_infinity(const EC_GROUP *group, EC_POINT *point);
220 const BIGNUM *x, int y_bit, BN_CTX *); 427
221 428/** Sets the jacobian projective coordinates of a EC_POINT over GFp
222int EC_POINT_set_affine_coordinates_GF2m(const EC_GROUP *, EC_POINT *, 429 * \param group underlying EC_GROUP object
223 const BIGNUM *x, const BIGNUM *y, BN_CTX *); 430 * \param p EC_POINT object
224int EC_POINT_get_affine_coordinates_GF2m(const EC_GROUP *, const EC_POINT *, 431 * \param x BIGNUM with the x-coordinate
225 BIGNUM *x, BIGNUM *y, BN_CTX *); 432 * \param y BIGNUM with the y-coordinate
226int EC_POINT_set_compressed_coordinates_GF2m(const EC_GROUP *, EC_POINT *, 433 * \param z BIGNUM with the z-coordinate
227 const BIGNUM *x, int y_bit, BN_CTX *); 434 * \param ctx BN_CTX object (optional)
228 435 * \return 1 on success and 0 if an error occured
229size_t EC_POINT_point2oct(const EC_GROUP *, const EC_POINT *, point_conversion_form_t form, 436 */
230 unsigned char *buf, size_t len, BN_CTX *); 437int EC_POINT_set_Jprojective_coordinates_GFp(const EC_GROUP *group, EC_POINT *p,
231int EC_POINT_oct2point(const EC_GROUP *, EC_POINT *, 438 const BIGNUM *x, const BIGNUM *y, const BIGNUM *z, BN_CTX *ctx);
232 const unsigned char *buf, size_t len, BN_CTX *); 439
440/** Gets the jacobian projective coordinates of a EC_POINT over GFp
441 * \param group underlying EC_GROUP object
442 * \param p EC_POINT object
443 * \param x BIGNUM for the x-coordinate
444 * \param y BIGNUM for the y-coordinate
445 * \param z BIGNUM for the z-coordinate
446 * \param ctx BN_CTX object (optional)
447 * \return 1 on success and 0 if an error occured
448 */
449int EC_POINT_get_Jprojective_coordinates_GFp(const EC_GROUP *group,
450 const EC_POINT *p, BIGNUM *x, BIGNUM *y, BIGNUM *z, BN_CTX *ctx);
451
452/** Sets the affine coordinates of a EC_POINT over GFp
453 * \param group underlying EC_GROUP object
454 * \param p EC_POINT object
455 * \param x BIGNUM with the x-coordinate
456 * \param y BIGNUM with the y-coordinate
457 * \param ctx BN_CTX object (optional)
458 * \return 1 on success and 0 if an error occured
459 */
460int EC_POINT_set_affine_coordinates_GFp(const EC_GROUP *group, EC_POINT *p,
461 const BIGNUM *x, const BIGNUM *y, BN_CTX *ctx);
462
463/** Gets the affine coordinates of a EC_POINT over GFp
464 * \param group underlying EC_GROUP object
465 * \param p EC_POINT object
466 * \param x BIGNUM for the x-coordinate
467 * \param y BIGNUM for the y-coordinate
468 * \param ctx BN_CTX object (optional)
469 * \return 1 on success and 0 if an error occured
470 */
471int EC_POINT_get_affine_coordinates_GFp(const EC_GROUP *group,
472 const EC_POINT *p, BIGNUM *x, BIGNUM *y, BN_CTX *ctx);
473
474/** Sets the x9.62 compressed coordinates of a EC_POINT over GFp
475 * \param group underlying EC_GROUP object
476 * \param p EC_POINT object
477 * \param x BIGNUM with x-coordinate
478 * \param y_bit integer with the y-Bit (either 0 or 1)
479 * \param ctx BN_CTX object (optional)
480 * \return 1 on success and 0 if an error occured
481 */
482int EC_POINT_set_compressed_coordinates_GFp(const EC_GROUP *group, EC_POINT *p,
483 const BIGNUM *x, int y_bit, BN_CTX *ctx);
484
485/** Sets the affine coordinates of a EC_POINT over GF2m
486 * \param group underlying EC_GROUP object
487 * \param p EC_POINT object
488 * \param x BIGNUM with the x-coordinate
489 * \param y BIGNUM with the y-coordinate
490 * \param ctx BN_CTX object (optional)
491 * \return 1 on success and 0 if an error occured
492 */
493int EC_POINT_set_affine_coordinates_GF2m(const EC_GROUP *group, EC_POINT *p,
494 const BIGNUM *x, const BIGNUM *y, BN_CTX *ctx);
495
496/** Gets the affine coordinates of a EC_POINT over GF2m
497 * \param group underlying EC_GROUP object
498 * \param p EC_POINT object
499 * \param x BIGNUM for the x-coordinate
500 * \param y BIGNUM for the y-coordinate
501 * \param ctx BN_CTX object (optional)
502 * \return 1 on success and 0 if an error occured
503 */
504int EC_POINT_get_affine_coordinates_GF2m(const EC_GROUP *group,
505 const EC_POINT *p, BIGNUM *x, BIGNUM *y, BN_CTX *ctx);
506
507/** Sets the x9.62 compressed coordinates of a EC_POINT over GF2m
508 * \param group underlying EC_GROUP object
509 * \param p EC_POINT object
510 * \param x BIGNUM with x-coordinate
511 * \param y_bit integer with the y-Bit (either 0 or 1)
512 * \param ctx BN_CTX object (optional)
513 * \return 1 on success and 0 if an error occured
514 */
515int EC_POINT_set_compressed_coordinates_GF2m(const EC_GROUP *group, EC_POINT *p,
516 const BIGNUM *x, int y_bit, BN_CTX *ctx);
517
518/** Encodes a EC_POINT object to a octet string
519 * \param group underlying EC_GROUP object
520 * \param p EC_POINT object
521 * \param form point conversion form
522 * \param buf memory buffer for the result. If NULL the function returns
523 * required buffer size.
524 * \param len length of the memory buffer
525 * \param ctx BN_CTX object (optional)
526 * \return the length of the encoded octet string or 0 if an error occurred
527 */
528size_t EC_POINT_point2oct(const EC_GROUP *group, const EC_POINT *p,
529 point_conversion_form_t form,
530 unsigned char *buf, size_t len, BN_CTX *ctx);
531
532/** Decodes a EC_POINT from a octet string
533 * \param group underlying EC_GROUP object
534 * \param p EC_POINT object
535 * \param buf memory buffer with the encoded ec point
536 * \param len length of the encoded ec point
537 * \param ctx BN_CTX object (optional)
538 * \return 1 on success and 0 if an error occured
539 */
540int EC_POINT_oct2point(const EC_GROUP *group, EC_POINT *p,
541 const unsigned char *buf, size_t len, BN_CTX *ctx);
233 542
234/* other interfaces to point2oct/oct2point: */ 543/* other interfaces to point2oct/oct2point: */
235BIGNUM *EC_POINT_point2bn(const EC_GROUP *, const EC_POINT *, 544BIGNUM *EC_POINT_point2bn(const EC_GROUP *, const EC_POINT *,
@@ -241,29 +550,105 @@ char *EC_POINT_point2hex(const EC_GROUP *, const EC_POINT *,
241EC_POINT *EC_POINT_hex2point(const EC_GROUP *, const char *, 550EC_POINT *EC_POINT_hex2point(const EC_GROUP *, const char *,
242 EC_POINT *, BN_CTX *); 551 EC_POINT *, BN_CTX *);
243 552
244int EC_POINT_add(const EC_GROUP *, EC_POINT *r, const EC_POINT *a, const EC_POINT *b, BN_CTX *);
245int EC_POINT_dbl(const EC_GROUP *, EC_POINT *r, const EC_POINT *a, BN_CTX *);
246int EC_POINT_invert(const EC_GROUP *, EC_POINT *, BN_CTX *);
247 553
248int EC_POINT_is_at_infinity(const EC_GROUP *, const EC_POINT *); 554/********************************************************************/
249int EC_POINT_is_on_curve(const EC_GROUP *, const EC_POINT *, BN_CTX *); 555/* functions for doing EC_POINT arithmetic */
250int EC_POINT_cmp(const EC_GROUP *, const EC_POINT *a, const EC_POINT *b, BN_CTX *); 556/********************************************************************/
557
558/** Computes the sum of two EC_POINT
559 * \param group underlying EC_GROUP object
560 * \param r EC_POINT object for the result (r = a + b)
561 * \param a EC_POINT object with the first summand
562 * \param b EC_POINT object with the second summand
563 * \param ctx BN_CTX object (optional)
564 * \return 1 on success and 0 if an error occured
565 */
566int EC_POINT_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, const EC_POINT *b, BN_CTX *ctx);
567
568/** Computes the double of a EC_POINT
569 * \param group underlying EC_GROUP object
570 * \param r EC_POINT object for the result (r = 2 * a)
571 * \param a EC_POINT object
572 * \param ctx BN_CTX object (optional)
573 * \return 1 on success and 0 if an error occured
574 */
575int EC_POINT_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, BN_CTX *ctx);
576
577/** Computes the inverse of a EC_POINT
578 * \param group underlying EC_GROUP object
579 * \param a EC_POINT object to be inverted (it's used for the result as well)
580 * \param ctx BN_CTX object (optional)
581 * \return 1 on success and 0 if an error occured
582 */
583int EC_POINT_invert(const EC_GROUP *group, EC_POINT *a, BN_CTX *ctx);
584
585/** Checks whether the point is the neutral element of the group
586 * \param group the underlying EC_GROUP object
587 * \param p EC_POINT object
588 * \return 1 if the point is the neutral element and 0 otherwise
589 */
590int EC_POINT_is_at_infinity(const EC_GROUP *group, const EC_POINT *p);
591
592/** Checks whether the point is on the curve
593 * \param group underlying EC_GROUP object
594 * \param point EC_POINT object to check
595 * \param ctx BN_CTX object (optional)
596 * \return 1 if point if on the curve and 0 otherwise
597 */
598int EC_POINT_is_on_curve(const EC_GROUP *group, const EC_POINT *point, BN_CTX *ctx);
599
600/** Compares two EC_POINTs
601 * \param group underlying EC_GROUP object
602 * \param a first EC_POINT object
603 * \param b second EC_POINT object
604 * \param ctx BN_CTX object (optional)
605 * \return 0 if both points are equal and a value != 0 otherwise
606 */
607int EC_POINT_cmp(const EC_GROUP *group, const EC_POINT *a, const EC_POINT *b, BN_CTX *ctx);
251 608
252int EC_POINT_make_affine(const EC_GROUP *, EC_POINT *, BN_CTX *); 609int EC_POINT_make_affine(const EC_GROUP *, EC_POINT *, BN_CTX *);
253int EC_POINTs_make_affine(const EC_GROUP *, size_t num, EC_POINT *[], BN_CTX *); 610int EC_POINTs_make_affine(const EC_GROUP *, size_t num, EC_POINT *[], BN_CTX *);
254 611
612/** Computes r = generator * n sum_{i=0}^num p[i] * m[i]
613 * \param group underlying EC_GROUP object
614 * \param r EC_POINT object for the result
615 * \param n BIGNUM with the multiplier for the group generator (optional)
616 * \param num number futher summands
617 * \param p array of size num of EC_POINT objects
618 * \param m array of size num of BIGNUM objects
619 * \param ctx BN_CTX object (optional)
620 * \return 1 on success and 0 if an error occured
621 */
622int EC_POINTs_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *n, size_t num, const EC_POINT *p[], const BIGNUM *m[], BN_CTX *ctx);
623
624/** Computes r = generator * n + q * m
625 * \param group underlying EC_GROUP object
626 * \param r EC_POINT object for the result
627 * \param n BIGNUM with the multiplier for the group generator (optional)
628 * \param q EC_POINT object with the first factor of the second summand
629 * \param m BIGNUM with the second factor of the second summand
630 * \param ctx BN_CTX object (optional)
631 * \return 1 on success and 0 if an error occured
632 */
633int EC_POINT_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *n, const EC_POINT *q, const BIGNUM *m, BN_CTX *ctx);
255 634
256int EC_POINTs_mul(const EC_GROUP *, EC_POINT *r, const BIGNUM *, size_t num, const EC_POINT *[], const BIGNUM *[], BN_CTX *); 635/** Stores multiples of generator for faster point multiplication
257int EC_POINT_mul(const EC_GROUP *, EC_POINT *r, const BIGNUM *, const EC_POINT *, const BIGNUM *, BN_CTX *); 636 * \param group EC_GROUP object
258 637 * \param ctx BN_CTX object (optional)
259/* EC_GROUP_precompute_mult() stores multiples of generator for faster point multiplication */ 638 * \return 1 on success and 0 if an error occured
260int EC_GROUP_precompute_mult(EC_GROUP *, BN_CTX *); 639 */
261/* EC_GROUP_have_precompute_mult() reports whether such precomputation has been done */ 640int EC_GROUP_precompute_mult(EC_GROUP *group, BN_CTX *ctx);
262int EC_GROUP_have_precompute_mult(const EC_GROUP *);
263 641
642/** Reports whether a precomputation has been done
643 * \param group EC_GROUP object
644 * \return 1 if a pre-computation has been done and 0 otherwise
645 */
646int EC_GROUP_have_precompute_mult(const EC_GROUP *group);
264 647
265 648
266/* ASN1 stuff */ 649/********************************************************************/
650/* ASN1 stuff */
651/********************************************************************/
267 652
268/* EC_GROUP_get_basis_type() returns the NID of the basis type 653/* EC_GROUP_get_basis_type() returns the NID of the basis type
269 * used to represent the field elements */ 654 * used to represent the field elements */
@@ -293,28 +678,96 @@ int ECPKParameters_print(BIO *bp, const EC_GROUP *x, int off);
293int ECPKParameters_print_fp(FILE *fp, const EC_GROUP *x, int off); 678int ECPKParameters_print_fp(FILE *fp, const EC_GROUP *x, int off);
294#endif 679#endif
295 680
296/* the EC_KEY stuff */ 681
682/********************************************************************/
683/* EC_KEY functions */
684/********************************************************************/
685
297typedef struct ec_key_st EC_KEY; 686typedef struct ec_key_st EC_KEY;
298 687
299/* some values for the encoding_flag */ 688/* some values for the encoding_flag */
300#define EC_PKEY_NO_PARAMETERS 0x001 689#define EC_PKEY_NO_PARAMETERS 0x001
301#define EC_PKEY_NO_PUBKEY 0x002 690#define EC_PKEY_NO_PUBKEY 0x002
302 691
692/** Creates a new EC_KEY object.
693 * \return EC_KEY object or NULL if an error occurred.
694 */
303EC_KEY *EC_KEY_new(void); 695EC_KEY *EC_KEY_new(void);
696
697/** Creates a new EC_KEY object using a named curve as underlying
698 * EC_GROUP object.
699 * \param nid NID of the named curve.
700 * \return EC_KEY object or NULL if an error occurred.
701 */
304EC_KEY *EC_KEY_new_by_curve_name(int nid); 702EC_KEY *EC_KEY_new_by_curve_name(int nid);
305void EC_KEY_free(EC_KEY *); 703
306EC_KEY *EC_KEY_copy(EC_KEY *, const EC_KEY *); 704/** Frees a EC_KEY object.
307EC_KEY *EC_KEY_dup(const EC_KEY *); 705 * \param key EC_KEY object to be freed.
308 706 */
309int EC_KEY_up_ref(EC_KEY *); 707void EC_KEY_free(EC_KEY *key);
310 708
311const EC_GROUP *EC_KEY_get0_group(const EC_KEY *); 709/** Copies a EC_KEY object.
312int EC_KEY_set_group(EC_KEY *, const EC_GROUP *); 710 * \param dst destination EC_KEY object
313const BIGNUM *EC_KEY_get0_private_key(const EC_KEY *); 711 * \param src src EC_KEY object
314int EC_KEY_set_private_key(EC_KEY *, const BIGNUM *); 712 * \return dst or NULL if an error occurred.
315const EC_POINT *EC_KEY_get0_public_key(const EC_KEY *); 713 */
316int EC_KEY_set_public_key(EC_KEY *, const EC_POINT *); 714EC_KEY *EC_KEY_copy(EC_KEY *dst, const EC_KEY *src);
317unsigned EC_KEY_get_enc_flags(const EC_KEY *); 715
716/** Creates a new EC_KEY object and copies the content from src to it.
717 * \param src the source EC_KEY object
718 * \return newly created EC_KEY object or NULL if an error occurred.
719 */
720EC_KEY *EC_KEY_dup(const EC_KEY *src);
721
722/** Increases the internal reference count of a EC_KEY object.
723 * \param key EC_KEY object
724 * \return 1 on success and 0 if an error occurred.
725 */
726int EC_KEY_up_ref(EC_KEY *key);
727
728/** Returns the EC_GROUP object of a EC_KEY object
729 * \param key EC_KEY object
730 * \return the EC_GROUP object (possibly NULL).
731 */
732const EC_GROUP *EC_KEY_get0_group(const EC_KEY *key);
733
734/** Sets the EC_GROUP of a EC_KEY object.
735 * \param key EC_KEY object
736 * \param group EC_GROUP to use in the EC_KEY object (note: the EC_KEY
737 * object will use an own copy of the EC_GROUP).
738 * \return 1 on success and 0 if an error occurred.
739 */
740int EC_KEY_set_group(EC_KEY *key, const EC_GROUP *group);
741
742/** Returns the private key of a EC_KEY object.
743 * \param key EC_KEY object
744 * \return a BIGNUM with the private key (possibly NULL).
745 */
746const BIGNUM *EC_KEY_get0_private_key(const EC_KEY *key);
747
748/** Sets the private key of a EC_KEY object.
749 * \param key EC_KEY object
750 * \param prv BIGNUM with the private key (note: the EC_KEY object
751 * will use an own copy of the BIGNUM).
752 * \return 1 on success and 0 if an error occurred.
753 */
754int EC_KEY_set_private_key(EC_KEY *key, const BIGNUM *prv);
755
756/** Returns the public key of a EC_KEY object.
757 * \param key the EC_KEY object
758 * \return a EC_POINT object with the public key (possibly NULL)
759 */
760const EC_POINT *EC_KEY_get0_public_key(const EC_KEY *key);
761
762/** Sets the public key of a EC_KEY object.
763 * \param key EC_KEY object
764 * \param pub EC_POINT object with the public key (note: the EC_KEY object
765 * will use an own copy of the EC_POINT object).
766 * \return 1 on success and 0 if an error occurred.
767 */
768int EC_KEY_set_public_key(EC_KEY *key, const EC_POINT *pub);
769
770unsigned EC_KEY_get_enc_flags(const EC_KEY *key);
318void EC_KEY_set_enc_flags(EC_KEY *, unsigned int); 771void EC_KEY_set_enc_flags(EC_KEY *, unsigned int);
319point_conversion_form_t EC_KEY_get_conv_form(const EC_KEY *); 772point_conversion_form_t EC_KEY_get_conv_form(const EC_KEY *);
320void EC_KEY_set_conv_form(EC_KEY *, point_conversion_form_t); 773void EC_KEY_set_conv_form(EC_KEY *, point_conversion_form_t);
@@ -325,31 +778,126 @@ void EC_KEY_insert_key_method_data(EC_KEY *, void *data,
325 void *(*dup_func)(void *), void (*free_func)(void *), void (*clear_free_func)(void *)); 778 void *(*dup_func)(void *), void (*free_func)(void *), void (*clear_free_func)(void *));
326/* wrapper functions for the underlying EC_GROUP object */ 779/* wrapper functions for the underlying EC_GROUP object */
327void EC_KEY_set_asn1_flag(EC_KEY *, int); 780void EC_KEY_set_asn1_flag(EC_KEY *, int);
328int EC_KEY_precompute_mult(EC_KEY *, BN_CTX *ctx); 781
329 782/** Creates a table of pre-computed multiples of the generator to
330/* EC_KEY_generate_key() creates a ec private (public) key */ 783 * accelerate further EC_KEY operations.
331int EC_KEY_generate_key(EC_KEY *); 784 * \param key EC_KEY object
332/* EC_KEY_check_key() */ 785 * \param ctx BN_CTX object (optional)
333int EC_KEY_check_key(const EC_KEY *); 786 * \return 1 on success and 0 if an error occurred.
334 787 */
335/* de- and encoding functions for SEC1 ECPrivateKey */ 788int EC_KEY_precompute_mult(EC_KEY *key, BN_CTX *ctx);
336EC_KEY *d2i_ECPrivateKey(EC_KEY **a, const unsigned char **in, long len); 789
337int i2d_ECPrivateKey(EC_KEY *a, unsigned char **out); 790/** Creates a new ec private (and optional a new public) key.
338/* de- and encoding functions for EC parameters */ 791 * \param key EC_KEY object
339EC_KEY *d2i_ECParameters(EC_KEY **a, const unsigned char **in, long len); 792 * \return 1 on success and 0 if an error occurred.
340int i2d_ECParameters(EC_KEY *a, unsigned char **out); 793 */
341/* de- and encoding functions for EC public key 794int EC_KEY_generate_key(EC_KEY *key);
342 * (octet string, not DER -- hence 'o2i' and 'i2o') */ 795
343EC_KEY *o2i_ECPublicKey(EC_KEY **a, const unsigned char **in, long len); 796/** Verifies that a private and/or public key is valid.
344int i2o_ECPublicKey(EC_KEY *a, unsigned char **out); 797 * \param key the EC_KEY object
798 * \return 1 on success and 0 otherwise.
799 */
800int EC_KEY_check_key(const EC_KEY *key);
801
802
803/********************************************************************/
804/* de- and encoding functions for SEC1 ECPrivateKey */
805/********************************************************************/
806
807/** Decodes a private key from a memory buffer.
808 * \param key a pointer to a EC_KEY object which should be used (or NULL)
809 * \param in pointer to memory with the DER encoded private key
810 * \param len length of the DER encoded private key
811 * \return the decoded private key or NULL if an error occurred.
812 */
813EC_KEY *d2i_ECPrivateKey(EC_KEY **key, const unsigned char **in, long len);
814
815/** Encodes a private key object and stores the result in a buffer.
816 * \param key the EC_KEY object to encode
817 * \param out the buffer for the result (if NULL the function returns number
818 * of bytes needed).
819 * \return 1 on success and 0 if an error occurred.
820 */
821int i2d_ECPrivateKey(EC_KEY *key, unsigned char **out);
822
823
824/********************************************************************/
825/* de- and encoding functions for EC parameters */
826/********************************************************************/
827
828/** Decodes ec parameter from a memory buffer.
829 * \param key a pointer to a EC_KEY object which should be used (or NULL)
830 * \param in pointer to memory with the DER encoded ec parameters
831 * \param len length of the DER encoded ec parameters
832 * \return a EC_KEY object with the decoded parameters or NULL if an error
833 * occurred.
834 */
835EC_KEY *d2i_ECParameters(EC_KEY **key, const unsigned char **in, long len);
836
837/** Encodes ec parameter and stores the result in a buffer.
838 * \param key the EC_KEY object with ec paramters to encode
839 * \param out the buffer for the result (if NULL the function returns number
840 * of bytes needed).
841 * \return 1 on success and 0 if an error occurred.
842 */
843int i2d_ECParameters(EC_KEY *key, unsigned char **out);
844
845
846/********************************************************************/
847/* de- and encoding functions for EC public key */
848/* (octet string, not DER -- hence 'o2i' and 'i2o') */
849/********************************************************************/
850
851/** Decodes a ec public key from a octet string.
852 * \param key a pointer to a EC_KEY object which should be used
853 * \param in memory buffer with the encoded public key
854 * \param len length of the encoded public key
855 * \return EC_KEY object with decoded public key or NULL if an error
856 * occurred.
857 */
858EC_KEY *o2i_ECPublicKey(EC_KEY **key, const unsigned char **in, long len);
859
860/** Encodes a ec public key in an octet string.
861 * \param key the EC_KEY object with the public key
862 * \param out the buffer for the result (if NULL the function returns number
863 * of bytes needed).
864 * \return 1 on success and 0 if an error occurred
865 */
866int i2o_ECPublicKey(EC_KEY *key, unsigned char **out);
345 867
346#ifndef OPENSSL_NO_BIO 868#ifndef OPENSSL_NO_BIO
347int ECParameters_print(BIO *bp, const EC_KEY *x); 869/** Prints out the ec parameters on human readable form.
348int EC_KEY_print(BIO *bp, const EC_KEY *x, int off); 870 * \param bp BIO object to which the information is printed
871 * \param key EC_KEY object
872 * \return 1 on success and 0 if an error occurred
873 */
874int ECParameters_print(BIO *bp, const EC_KEY *key);
875
876/** Prints out the contents of a EC_KEY object
877 * \param bp BIO object to which the information is printed
878 * \param key EC_KEY object
879 * \param off line offset
880 * \return 1 on success and 0 if an error occurred
881 */
882int EC_KEY_print(BIO *bp, const EC_KEY *key, int off);
883
349#endif 884#endif
350#ifndef OPENSSL_NO_FP_API 885#ifndef OPENSSL_NO_FP_API
351int ECParameters_print_fp(FILE *fp, const EC_KEY *x); 886/** Prints out the ec parameters on human readable form.
352int EC_KEY_print_fp(FILE *fp, const EC_KEY *x, int off); 887 * \param fp file descriptor to which the information is printed
888 * \param key EC_KEY object
889 * \return 1 on success and 0 if an error occurred
890 */
891int ECParameters_print_fp(FILE *fp, const EC_KEY *key);
892
893/** Prints out the contents of a EC_KEY object
894 * \param fp file descriptor to which the information is printed
895 * \param key EC_KEY object
896 * \param off line offset
897 * \return 1 on success and 0 if an error occurred
898 */
899int EC_KEY_print_fp(FILE *fp, const EC_KEY *key, int off);
900
353#endif 901#endif
354 902
355#define ECParameters_dup(x) ASN1_dup_of(EC_KEY,i2d_ECParameters,d2i_ECParameters,x) 903#define ECParameters_dup(x) ASN1_dup_of(EC_KEY,i2d_ECParameters,d2i_ECParameters,x)
@@ -362,6 +910,13 @@ int EC_KEY_print_fp(FILE *fp, const EC_KEY *x, int off);
362# endif 910# endif
363#endif 911#endif
364 912
913#define EVP_PKEY_CTX_set_ec_paramgen_curve_nid(ctx, nid) \
914 EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, EVP_PKEY_OP_PARAMGEN, \
915 EVP_PKEY_CTRL_EC_PARAMGEN_CURVE_NID, nid, NULL)
916
917
918#define EVP_PKEY_CTRL_EC_PARAMGEN_CURVE_NID (EVP_PKEY_ALG_CTRL + 1)
919
365/* BEGIN ERROR CODES */ 920/* BEGIN ERROR CODES */
366/* The following lines are auto generated by the script mkerr.pl. Any changes 921/* The following lines are auto generated by the script mkerr.pl. Any changes
367 * made after this point may be overwritten when the script is next run. 922 * made after this point may be overwritten when the script is next run.
@@ -375,6 +930,14 @@ void ERR_load_EC_strings(void);
375#define EC_F_D2I_ECPARAMETERS 144 930#define EC_F_D2I_ECPARAMETERS 144
376#define EC_F_D2I_ECPKPARAMETERS 145 931#define EC_F_D2I_ECPKPARAMETERS 145
377#define EC_F_D2I_ECPRIVATEKEY 146 932#define EC_F_D2I_ECPRIVATEKEY 146
933#define EC_F_DO_EC_KEY_PRINT 221
934#define EC_F_ECKEY_PARAM2TYPE 223
935#define EC_F_ECKEY_PARAM_DECODE 212
936#define EC_F_ECKEY_PRIV_DECODE 213
937#define EC_F_ECKEY_PRIV_ENCODE 214
938#define EC_F_ECKEY_PUB_DECODE 215
939#define EC_F_ECKEY_PUB_ENCODE 216
940#define EC_F_ECKEY_TYPE2PARAM 220
378#define EC_F_ECPARAMETERS_PRINT 147 941#define EC_F_ECPARAMETERS_PRINT 147
379#define EC_F_ECPARAMETERS_PRINT_FP 148 942#define EC_F_ECPARAMETERS_PRINT_FP 148
380#define EC_F_ECPKPARAMETERS_PRINT 149 943#define EC_F_ECPKPARAMETERS_PRINT 149
@@ -448,7 +1011,6 @@ void ERR_load_EC_strings(void);
448#define EC_F_EC_KEY_PRINT 180 1011#define EC_F_EC_KEY_PRINT 180
449#define EC_F_EC_KEY_PRINT_FP 181 1012#define EC_F_EC_KEY_PRINT_FP 181
450#define EC_F_EC_POINTS_MAKE_AFFINE 136 1013#define EC_F_EC_POINTS_MAKE_AFFINE 136
451#define EC_F_EC_POINTS_MUL 138
452#define EC_F_EC_POINT_ADD 112 1014#define EC_F_EC_POINT_ADD 112
453#define EC_F_EC_POINT_CMP 113 1015#define EC_F_EC_POINT_CMP 113
454#define EC_F_EC_POINT_COPY 114 1016#define EC_F_EC_POINT_COPY 114
@@ -479,21 +1041,31 @@ void ERR_load_EC_strings(void);
479#define EC_F_I2D_ECPRIVATEKEY 192 1041#define EC_F_I2D_ECPRIVATEKEY 192
480#define EC_F_I2O_ECPUBLICKEY 151 1042#define EC_F_I2O_ECPUBLICKEY 151
481#define EC_F_O2I_ECPUBLICKEY 152 1043#define EC_F_O2I_ECPUBLICKEY 152
1044#define EC_F_OLD_EC_PRIV_DECODE 222
1045#define EC_F_PKEY_EC_CTRL 197
1046#define EC_F_PKEY_EC_CTRL_STR 198
1047#define EC_F_PKEY_EC_DERIVE 217
1048#define EC_F_PKEY_EC_KEYGEN 199
1049#define EC_F_PKEY_EC_PARAMGEN 219
1050#define EC_F_PKEY_EC_SIGN 218
482 1051
483/* Reason codes. */ 1052/* Reason codes. */
484#define EC_R_ASN1_ERROR 115 1053#define EC_R_ASN1_ERROR 115
485#define EC_R_ASN1_UNKNOWN_FIELD 116 1054#define EC_R_ASN1_UNKNOWN_FIELD 116
486#define EC_R_BUFFER_TOO_SMALL 100 1055#define EC_R_BUFFER_TOO_SMALL 100
487#define EC_R_D2I_ECPKPARAMETERS_FAILURE 117 1056#define EC_R_D2I_ECPKPARAMETERS_FAILURE 117
1057#define EC_R_DECODE_ERROR 142
488#define EC_R_DISCRIMINANT_IS_ZERO 118 1058#define EC_R_DISCRIMINANT_IS_ZERO 118
489#define EC_R_EC_GROUP_NEW_BY_NAME_FAILURE 119 1059#define EC_R_EC_GROUP_NEW_BY_NAME_FAILURE 119
490#define EC_R_FIELD_TOO_LARGE 138 1060#define EC_R_FIELD_TOO_LARGE 143
491#define EC_R_GROUP2PKPARAMETERS_FAILURE 120 1061#define EC_R_GROUP2PKPARAMETERS_FAILURE 120
492#define EC_R_I2D_ECPKPARAMETERS_FAILURE 121 1062#define EC_R_I2D_ECPKPARAMETERS_FAILURE 121
493#define EC_R_INCOMPATIBLE_OBJECTS 101 1063#define EC_R_INCOMPATIBLE_OBJECTS 101
494#define EC_R_INVALID_ARGUMENT 112 1064#define EC_R_INVALID_ARGUMENT 112
495#define EC_R_INVALID_COMPRESSED_POINT 110 1065#define EC_R_INVALID_COMPRESSED_POINT 110
496#define EC_R_INVALID_COMPRESSION_BIT 109 1066#define EC_R_INVALID_COMPRESSION_BIT 109
1067#define EC_R_INVALID_CURVE 141
1068#define EC_R_INVALID_DIGEST_TYPE 138
497#define EC_R_INVALID_ENCODING 102 1069#define EC_R_INVALID_ENCODING 102
498#define EC_R_INVALID_FIELD 103 1070#define EC_R_INVALID_FIELD 103
499#define EC_R_INVALID_FORM 104 1071#define EC_R_INVALID_FORM 104
@@ -501,6 +1073,7 @@ void ERR_load_EC_strings(void);
501#define EC_R_INVALID_PENTANOMIAL_BASIS 132 1073#define EC_R_INVALID_PENTANOMIAL_BASIS 132
502#define EC_R_INVALID_PRIVATE_KEY 123 1074#define EC_R_INVALID_PRIVATE_KEY 123
503#define EC_R_INVALID_TRINOMIAL_BASIS 137 1075#define EC_R_INVALID_TRINOMIAL_BASIS 137
1076#define EC_R_KEYS_NOT_SET 140
504#define EC_R_MISSING_PARAMETERS 124 1077#define EC_R_MISSING_PARAMETERS 124
505#define EC_R_MISSING_PRIVATE_KEY 125 1078#define EC_R_MISSING_PRIVATE_KEY 125
506#define EC_R_NOT_A_NIST_PRIME 135 1079#define EC_R_NOT_A_NIST_PRIME 135
@@ -508,6 +1081,7 @@ void ERR_load_EC_strings(void);
508#define EC_R_NOT_IMPLEMENTED 126 1081#define EC_R_NOT_IMPLEMENTED 126
509#define EC_R_NOT_INITIALIZED 111 1082#define EC_R_NOT_INITIALIZED 111
510#define EC_R_NO_FIELD_MOD 133 1083#define EC_R_NO_FIELD_MOD 133
1084#define EC_R_NO_PARAMETERS_SET 139
511#define EC_R_PASSED_NULL_PARAMETER 134 1085#define EC_R_PASSED_NULL_PARAMETER 134
512#define EC_R_PKPARAMETERS2GROUP_FAILURE 127 1086#define EC_R_PKPARAMETERS2GROUP_FAILURE 127
513#define EC_R_POINT_AT_INFINITY 106 1087#define EC_R_POINT_AT_INFINITY 106
diff --git a/src/lib/libcrypto/ec/ec2_mult.c b/src/lib/libcrypto/ec/ec2_mult.c
index ff368fd7d7..ab631a50a2 100644
--- a/src/lib/libcrypto/ec/ec2_mult.c
+++ b/src/lib/libcrypto/ec/ec2_mult.c
@@ -76,7 +76,7 @@
76 * coordinates. 76 * coordinates.
77 * Uses algorithm Mdouble in appendix of 77 * Uses algorithm Mdouble in appendix of
78 * Lopez, J. and Dahab, R. "Fast multiplication on elliptic curves over 78 * Lopez, J. and Dahab, R. "Fast multiplication on elliptic curves over
79 * GF(2^m) without precomputation". 79 * GF(2^m) without precomputation" (CHES '99, LNCS 1717).
80 * modified to not require precomputation of c=b^{2^{m-1}}. 80 * modified to not require precomputation of c=b^{2^{m-1}}.
81 */ 81 */
82static int gf2m_Mdouble(const EC_GROUP *group, BIGNUM *x, BIGNUM *z, BN_CTX *ctx) 82static int gf2m_Mdouble(const EC_GROUP *group, BIGNUM *x, BIGNUM *z, BN_CTX *ctx)
@@ -107,8 +107,8 @@ static int gf2m_Mdouble(const EC_GROUP *group, BIGNUM *x, BIGNUM *z, BN_CTX *ctx
107/* Compute the x-coordinate x1/z1 for the point (x1/z1)+(x2/x2) in Montgomery 107/* Compute the x-coordinate x1/z1 for the point (x1/z1)+(x2/x2) in Montgomery
108 * projective coordinates. 108 * projective coordinates.
109 * Uses algorithm Madd in appendix of 109 * Uses algorithm Madd in appendix of
110 * Lopex, J. and Dahab, R. "Fast multiplication on elliptic curves over 110 * Lopez, J. and Dahab, R. "Fast multiplication on elliptic curves over
111 * GF(2^m) without precomputation". 111 * GF(2^m) without precomputation" (CHES '99, LNCS 1717).
112 */ 112 */
113static int gf2m_Madd(const EC_GROUP *group, const BIGNUM *x, BIGNUM *x1, BIGNUM *z1, 113static int gf2m_Madd(const EC_GROUP *group, const BIGNUM *x, BIGNUM *x1, BIGNUM *z1,
114 const BIGNUM *x2, const BIGNUM *z2, BN_CTX *ctx) 114 const BIGNUM *x2, const BIGNUM *z2, BN_CTX *ctx)
@@ -140,8 +140,8 @@ static int gf2m_Madd(const EC_GROUP *group, const BIGNUM *x, BIGNUM *x1, BIGNUM
140 140
141/* Compute the x, y affine coordinates from the point (x1, z1) (x2, z2) 141/* Compute the x, y affine coordinates from the point (x1, z1) (x2, z2)
142 * using Montgomery point multiplication algorithm Mxy() in appendix of 142 * using Montgomery point multiplication algorithm Mxy() in appendix of
143 * Lopex, J. and Dahab, R. "Fast multiplication on elliptic curves over 143 * Lopez, J. and Dahab, R. "Fast multiplication on elliptic curves over
144 * GF(2^m) without precomputation". 144 * GF(2^m) without precomputation" (CHES '99, LNCS 1717).
145 * Returns: 145 * Returns:
146 * 0 on error 146 * 0 on error
147 * 1 if return value should be the point at infinity 147 * 1 if return value should be the point at infinity
@@ -209,15 +209,15 @@ static int gf2m_Mxy(const EC_GROUP *group, const BIGNUM *x, const BIGNUM *y, BIG
209/* Computes scalar*point and stores the result in r. 209/* Computes scalar*point and stores the result in r.
210 * point can not equal r. 210 * point can not equal r.
211 * Uses algorithm 2P of 211 * Uses algorithm 2P of
212 * Lopex, J. and Dahab, R. "Fast multiplication on elliptic curves over 212 * Lopez, J. and Dahab, R. "Fast multiplication on elliptic curves over
213 * GF(2^m) without precomputation". 213 * GF(2^m) without precomputation" (CHES '99, LNCS 1717).
214 */ 214 */
215static int ec_GF2m_montgomery_point_multiply(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar, 215static int ec_GF2m_montgomery_point_multiply(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
216 const EC_POINT *point, BN_CTX *ctx) 216 const EC_POINT *point, BN_CTX *ctx)
217 { 217 {
218 BIGNUM *x1, *x2, *z1, *z2; 218 BIGNUM *x1, *x2, *z1, *z2;
219 int ret = 0, i, j; 219 int ret = 0, i;
220 BN_ULONG mask; 220 BN_ULONG mask,word;
221 221
222 if (r == point) 222 if (r == point)
223 { 223 {
@@ -251,22 +251,24 @@ static int ec_GF2m_montgomery_point_multiply(const EC_GROUP *group, EC_POINT *r,
251 if (!BN_GF2m_add(x2, x2, &group->b)) goto err; /* x2 = x^4 + b */ 251 if (!BN_GF2m_add(x2, x2, &group->b)) goto err; /* x2 = x^4 + b */
252 252
253 /* find top most bit and go one past it */ 253 /* find top most bit and go one past it */
254 i = scalar->top - 1; j = BN_BITS2 - 1; 254 i = scalar->top - 1;
255 mask = BN_TBIT; 255 mask = BN_TBIT;
256 while (!(scalar->d[i] & mask)) { mask >>= 1; j--; } 256 word = scalar->d[i];
257 mask >>= 1; j--; 257 while (!(word & mask)) mask >>= 1;
258 mask >>= 1;
258 /* if top most bit was at word break, go to next word */ 259 /* if top most bit was at word break, go to next word */
259 if (!mask) 260 if (!mask)
260 { 261 {
261 i--; j = BN_BITS2 - 1; 262 i--;
262 mask = BN_TBIT; 263 mask = BN_TBIT;
263 } 264 }
264 265
265 for (; i >= 0; i--) 266 for (; i >= 0; i--)
266 { 267 {
267 for (; j >= 0; j--) 268 word = scalar->d[i];
269 while (mask)
268 { 270 {
269 if (scalar->d[i] & mask) 271 if (word & mask)
270 { 272 {
271 if (!gf2m_Madd(group, &point->X, x1, z1, x2, z2, ctx)) goto err; 273 if (!gf2m_Madd(group, &point->X, x1, z1, x2, z2, ctx)) goto err;
272 if (!gf2m_Mdouble(group, x2, z2, ctx)) goto err; 274 if (!gf2m_Mdouble(group, x2, z2, ctx)) goto err;
@@ -278,7 +280,6 @@ static int ec_GF2m_montgomery_point_multiply(const EC_GROUP *group, EC_POINT *r,
278 } 280 }
279 mask >>= 1; 281 mask >>= 1;
280 } 282 }
281 j = BN_BITS2 - 1;
282 mask = BN_TBIT; 283 mask = BN_TBIT;
283 } 284 }
284 285
diff --git a/src/lib/libcrypto/ec/ec2_smpl.c b/src/lib/libcrypto/ec/ec2_smpl.c
index 5cd1eac41f..cf357b462a 100644
--- a/src/lib/libcrypto/ec/ec2_smpl.c
+++ b/src/lib/libcrypto/ec/ec2_smpl.c
@@ -14,7 +14,7 @@
14 * 14 *
15 */ 15 */
16/* ==================================================================== 16/* ====================================================================
17 * Copyright (c) 1998-2003 The OpenSSL Project. All rights reserved. 17 * Copyright (c) 1998-2005 The OpenSSL Project. All rights reserved.
18 * 18 *
19 * Redistribution and use in source and binary forms, with or without 19 * Redistribution and use in source and binary forms, with or without
20 * modification, are permitted provided that the following conditions 20 * modification, are permitted provided that the following conditions
@@ -157,6 +157,7 @@ void ec_GF2m_simple_group_clear_finish(EC_GROUP *group)
157 group->poly[2] = 0; 157 group->poly[2] = 0;
158 group->poly[3] = 0; 158 group->poly[3] = 0;
159 group->poly[4] = 0; 159 group->poly[4] = 0;
160 group->poly[5] = -1;
160 } 161 }
161 162
162 163
@@ -174,8 +175,9 @@ int ec_GF2m_simple_group_copy(EC_GROUP *dest, const EC_GROUP *src)
174 dest->poly[2] = src->poly[2]; 175 dest->poly[2] = src->poly[2];
175 dest->poly[3] = src->poly[3]; 176 dest->poly[3] = src->poly[3];
176 dest->poly[4] = src->poly[4]; 177 dest->poly[4] = src->poly[4];
177 bn_wexpand(&dest->a, (int)(dest->poly[0] + BN_BITS2 - 1) / BN_BITS2); 178 dest->poly[5] = src->poly[5];
178 bn_wexpand(&dest->b, (int)(dest->poly[0] + BN_BITS2 - 1) / BN_BITS2); 179 if (bn_wexpand(&dest->a, (int)(dest->poly[0] + BN_BITS2 - 1) / BN_BITS2) == NULL) return 0;
180 if (bn_wexpand(&dest->b, (int)(dest->poly[0] + BN_BITS2 - 1) / BN_BITS2) == NULL) return 0;
179 for (i = dest->a.top; i < dest->a.dmax; i++) dest->a.d[i] = 0; 181 for (i = dest->a.top; i < dest->a.dmax; i++) dest->a.d[i] = 0;
180 for (i = dest->b.top; i < dest->b.dmax; i++) dest->b.d[i] = 0; 182 for (i = dest->b.top; i < dest->b.dmax; i++) dest->b.d[i] = 0;
181 return 1; 183 return 1;
@@ -190,7 +192,7 @@ int ec_GF2m_simple_group_set_curve(EC_GROUP *group,
190 192
191 /* group->field */ 193 /* group->field */
192 if (!BN_copy(&group->field, p)) goto err; 194 if (!BN_copy(&group->field, p)) goto err;
193 i = BN_GF2m_poly2arr(&group->field, group->poly, 5); 195 i = BN_GF2m_poly2arr(&group->field, group->poly, 6) - 1;
194 if ((i != 5) && (i != 3)) 196 if ((i != 5) && (i != 3))
195 { 197 {
196 ECerr(EC_F_EC_GF2M_SIMPLE_GROUP_SET_CURVE, EC_R_UNSUPPORTED_FIELD); 198 ECerr(EC_F_EC_GF2M_SIMPLE_GROUP_SET_CURVE, EC_R_UNSUPPORTED_FIELD);
@@ -199,12 +201,12 @@ int ec_GF2m_simple_group_set_curve(EC_GROUP *group,
199 201
200 /* group->a */ 202 /* group->a */
201 if (!BN_GF2m_mod_arr(&group->a, a, group->poly)) goto err; 203 if (!BN_GF2m_mod_arr(&group->a, a, group->poly)) goto err;
202 bn_wexpand(&group->a, (int)(group->poly[0] + BN_BITS2 - 1) / BN_BITS2); 204 if(bn_wexpand(&group->a, (int)(group->poly[0] + BN_BITS2 - 1) / BN_BITS2) == NULL) goto err;
203 for (i = group->a.top; i < group->a.dmax; i++) group->a.d[i] = 0; 205 for (i = group->a.top; i < group->a.dmax; i++) group->a.d[i] = 0;
204 206
205 /* group->b */ 207 /* group->b */
206 if (!BN_GF2m_mod_arr(&group->b, b, group->poly)) goto err; 208 if (!BN_GF2m_mod_arr(&group->b, b, group->poly)) goto err;
207 bn_wexpand(&group->b, (int)(group->poly[0] + BN_BITS2 - 1) / BN_BITS2); 209 if(bn_wexpand(&group->b, (int)(group->poly[0] + BN_BITS2 - 1) / BN_BITS2) == NULL) goto err;
208 for (i = group->b.top; i < group->b.dmax; i++) group->b.d[i] = 0; 210 for (i = group->b.top; i < group->b.dmax; i++) group->b.d[i] = 0;
209 211
210 ret = 1; 212 ret = 1;
@@ -404,18 +406,94 @@ int ec_GF2m_simple_point_get_affine_coordinates(const EC_GROUP *group, const EC_
404 } 406 }
405 407
406 408
407/* Include patented algorithms. */ 409/* Calculates and sets the affine coordinates of an EC_POINT from the given
408#include "ec2_smpt.c" 410 * compressed coordinates. Uses algorithm 2.3.4 of SEC 1.
411 * Note that the simple implementation only uses affine coordinates.
412 *
413 * The method is from the following publication:
414 *
415 * Harper, Menezes, Vanstone:
416 * "Public-Key Cryptosystems with Very Small Key Lengths",
417 * EUROCRYPT '92, Springer-Verlag LNCS 658,
418 * published February 1993
419 *
420 * US Patents 6,141,420 and 6,618,483 (Vanstone, Mullin, Agnew) describe
421 * the same method, but claim no priority date earlier than July 29, 1994
422 * (and additionally fail to cite the EUROCRYPT '92 publication as prior art).
423 */
424int ec_GF2m_simple_set_compressed_coordinates(const EC_GROUP *group, EC_POINT *point,
425 const BIGNUM *x_, int y_bit, BN_CTX *ctx)
426 {
427 BN_CTX *new_ctx = NULL;
428 BIGNUM *tmp, *x, *y, *z;
429 int ret = 0, z0;
430
431 /* clear error queue */
432 ERR_clear_error();
433
434 if (ctx == NULL)
435 {
436 ctx = new_ctx = BN_CTX_new();
437 if (ctx == NULL)
438 return 0;
439 }
440
441 y_bit = (y_bit != 0) ? 1 : 0;
442
443 BN_CTX_start(ctx);
444 tmp = BN_CTX_get(ctx);
445 x = BN_CTX_get(ctx);
446 y = BN_CTX_get(ctx);
447 z = BN_CTX_get(ctx);
448 if (z == NULL) goto err;
449
450 if (!BN_GF2m_mod_arr(x, x_, group->poly)) goto err;
451 if (BN_is_zero(x))
452 {
453 if (!BN_GF2m_mod_sqrt_arr(y, &group->b, group->poly, ctx)) goto err;
454 }
455 else
456 {
457 if (!group->meth->field_sqr(group, tmp, x, ctx)) goto err;
458 if (!group->meth->field_div(group, tmp, &group->b, tmp, ctx)) goto err;
459 if (!BN_GF2m_add(tmp, &group->a, tmp)) goto err;
460 if (!BN_GF2m_add(tmp, x, tmp)) goto err;
461 if (!BN_GF2m_mod_solve_quad_arr(z, tmp, group->poly, ctx))
462 {
463 unsigned long err = ERR_peek_last_error();
464
465 if (ERR_GET_LIB(err) == ERR_LIB_BN && ERR_GET_REASON(err) == BN_R_NO_SOLUTION)
466 {
467 ERR_clear_error();
468 ECerr(EC_F_EC_GF2M_SIMPLE_SET_COMPRESSED_COORDINATES, EC_R_INVALID_COMPRESSED_POINT);
469 }
470 else
471 ECerr(EC_F_EC_GF2M_SIMPLE_SET_COMPRESSED_COORDINATES, ERR_R_BN_LIB);
472 goto err;
473 }
474 z0 = (BN_is_odd(z)) ? 1 : 0;
475 if (!group->meth->field_mul(group, y, x, z, ctx)) goto err;
476 if (z0 != y_bit)
477 {
478 if (!BN_GF2m_add(y, y, x)) goto err;
479 }
480 }
481
482 if (!EC_POINT_set_affine_coordinates_GF2m(group, point, x, y, ctx)) goto err;
483
484 ret = 1;
485
486 err:
487 BN_CTX_end(ctx);
488 if (new_ctx != NULL)
489 BN_CTX_free(new_ctx);
490 return ret;
491 }
409 492
410 493
411/* Converts an EC_POINT to an octet string. 494/* Converts an EC_POINT to an octet string.
412 * If buf is NULL, the encoded length will be returned. 495 * If buf is NULL, the encoded length will be returned.
413 * If the length len of buf is smaller than required an error will be returned. 496 * If the length len of buf is smaller than required an error will be returned.
414 *
415 * The point compression section of this function is patented by Certicom Corp.
416 * under US Patent 6,141,420. Point compression is disabled by default and can
417 * be enabled by defining the preprocessor macro OPENSSL_EC_BIN_PT_COMP at
418 * Configure-time.
419 */ 497 */
420size_t ec_GF2m_simple_point2oct(const EC_GROUP *group, const EC_POINT *point, point_conversion_form_t form, 498size_t ec_GF2m_simple_point2oct(const EC_GROUP *group, const EC_POINT *point, point_conversion_form_t form,
421 unsigned char *buf, size_t len, BN_CTX *ctx) 499 unsigned char *buf, size_t len, BN_CTX *ctx)
@@ -426,14 +504,6 @@ size_t ec_GF2m_simple_point2oct(const EC_GROUP *group, const EC_POINT *point, po
426 BIGNUM *x, *y, *yxi; 504 BIGNUM *x, *y, *yxi;
427 size_t field_len, i, skip; 505 size_t field_len, i, skip;
428 506
429#ifndef OPENSSL_EC_BIN_PT_COMP
430 if ((form == POINT_CONVERSION_COMPRESSED) || (form == POINT_CONVERSION_HYBRID))
431 {
432 ECerr(EC_F_EC_GF2M_SIMPLE_POINT2OCT, ERR_R_DISABLED);
433 goto err;
434 }
435#endif
436
437 if ((form != POINT_CONVERSION_COMPRESSED) 507 if ((form != POINT_CONVERSION_COMPRESSED)
438 && (form != POINT_CONVERSION_UNCOMPRESSED) 508 && (form != POINT_CONVERSION_UNCOMPRESSED)
439 && (form != POINT_CONVERSION_HYBRID)) 509 && (form != POINT_CONVERSION_HYBRID))
@@ -488,13 +558,11 @@ size_t ec_GF2m_simple_point2oct(const EC_GROUP *group, const EC_POINT *point, po
488 if (!EC_POINT_get_affine_coordinates_GF2m(group, point, x, y, ctx)) goto err; 558 if (!EC_POINT_get_affine_coordinates_GF2m(group, point, x, y, ctx)) goto err;
489 559
490 buf[0] = form; 560 buf[0] = form;
491#ifdef OPENSSL_EC_BIN_PT_COMP
492 if ((form != POINT_CONVERSION_UNCOMPRESSED) && !BN_is_zero(x)) 561 if ((form != POINT_CONVERSION_UNCOMPRESSED) && !BN_is_zero(x))
493 { 562 {
494 if (!group->meth->field_div(group, yxi, y, x, ctx)) goto err; 563 if (!group->meth->field_div(group, yxi, y, x, ctx)) goto err;
495 if (BN_is_odd(yxi)) buf[0]++; 564 if (BN_is_odd(yxi)) buf[0]++;
496 } 565 }
497#endif
498 566
499 i = 1; 567 i = 1;
500 568
diff --git a/src/lib/libcrypto/ec/ec_ameth.c b/src/lib/libcrypto/ec/ec_ameth.c
new file mode 100644
index 0000000000..c00f7d746c
--- /dev/null
+++ b/src/lib/libcrypto/ec/ec_ameth.c
@@ -0,0 +1,659 @@
1/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
2 * project 2006.
3 */
4/* ====================================================================
5 * Copyright (c) 2006 The OpenSSL Project. All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 *
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 *
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in
16 * the documentation and/or other materials provided with the
17 * distribution.
18 *
19 * 3. All advertising materials mentioning features or use of this
20 * software must display the following acknowledgment:
21 * "This product includes software developed by the OpenSSL Project
22 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
23 *
24 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
25 * endorse or promote products derived from this software without
26 * prior written permission. For written permission, please contact
27 * licensing@OpenSSL.org.
28 *
29 * 5. Products derived from this software may not be called "OpenSSL"
30 * nor may "OpenSSL" appear in their names without prior written
31 * permission of the OpenSSL Project.
32 *
33 * 6. Redistributions of any form whatsoever must retain the following
34 * acknowledgment:
35 * "This product includes software developed by the OpenSSL Project
36 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
37 *
38 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
39 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
40 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
41 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
42 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
43 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
44 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
45 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
46 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
47 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
48 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
49 * OF THE POSSIBILITY OF SUCH DAMAGE.
50 * ====================================================================
51 *
52 * This product includes cryptographic software written by Eric Young
53 * (eay@cryptsoft.com). This product includes software written by Tim
54 * Hudson (tjh@cryptsoft.com).
55 *
56 */
57
58#include <stdio.h>
59#include "cryptlib.h"
60#include <openssl/x509.h>
61#include <openssl/ec.h>
62#include <openssl/bn.h>
63#ifndef OPENSSL_NO_CMS
64#include <openssl/cms.h>
65#endif
66#include "asn1_locl.h"
67
68static int eckey_param2type(int *pptype, void **ppval, EC_KEY *ec_key)
69 {
70 const EC_GROUP *group;
71 int nid;
72 if (ec_key == NULL || (group = EC_KEY_get0_group(ec_key)) == NULL)
73 {
74 ECerr(EC_F_ECKEY_PARAM2TYPE, EC_R_MISSING_PARAMETERS);
75 return 0;
76 }
77 if (EC_GROUP_get_asn1_flag(group)
78 && (nid = EC_GROUP_get_curve_name(group)))
79 /* we have a 'named curve' => just set the OID */
80 {
81 *ppval = OBJ_nid2obj(nid);
82 *pptype = V_ASN1_OBJECT;
83 }
84 else /* explicit parameters */
85 {
86 ASN1_STRING *pstr = NULL;
87 pstr = ASN1_STRING_new();
88 if (!pstr)
89 return 0;
90 pstr->length = i2d_ECParameters(ec_key, &pstr->data);
91 if (pstr->length < 0)
92 {
93 ASN1_STRING_free(pstr);
94 ECerr(EC_F_ECKEY_PARAM2TYPE, ERR_R_EC_LIB);
95 return 0;
96 }
97 *ppval = pstr;
98 *pptype = V_ASN1_SEQUENCE;
99 }
100 return 1;
101 }
102
103static int eckey_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey)
104 {
105 EC_KEY *ec_key = pkey->pkey.ec;
106 void *pval = NULL;
107 int ptype;
108 unsigned char *penc = NULL, *p;
109 int penclen;
110
111 if (!eckey_param2type(&ptype, &pval, ec_key))
112 {
113 ECerr(EC_F_ECKEY_PUB_ENCODE, ERR_R_EC_LIB);
114 return 0;
115 }
116 penclen = i2o_ECPublicKey(ec_key, NULL);
117 if (penclen <= 0)
118 goto err;
119 penc = OPENSSL_malloc(penclen);
120 if (!penc)
121 goto err;
122 p = penc;
123 penclen = i2o_ECPublicKey(ec_key, &p);
124 if (penclen <= 0)
125 goto err;
126 if (X509_PUBKEY_set0_param(pk, OBJ_nid2obj(EVP_PKEY_EC),
127 ptype, pval, penc, penclen))
128 return 1;
129 err:
130 if (ptype == V_ASN1_OBJECT)
131 ASN1_OBJECT_free(pval);
132 else
133 ASN1_STRING_free(pval);
134 if (penc)
135 OPENSSL_free(penc);
136 return 0;
137 }
138
139static EC_KEY *eckey_type2param(int ptype, void *pval)
140 {
141 EC_KEY *eckey = NULL;
142 if (ptype == V_ASN1_SEQUENCE)
143 {
144 ASN1_STRING *pstr = pval;
145 const unsigned char *pm = NULL;
146 int pmlen;
147 pm = pstr->data;
148 pmlen = pstr->length;
149 if (!(eckey = d2i_ECParameters(NULL, &pm, pmlen)))
150 {
151 ECerr(EC_F_ECKEY_TYPE2PARAM, EC_R_DECODE_ERROR);
152 goto ecerr;
153 }
154 }
155 else if (ptype == V_ASN1_OBJECT)
156 {
157 ASN1_OBJECT *poid = pval;
158 EC_GROUP *group;
159
160 /* type == V_ASN1_OBJECT => the parameters are given
161 * by an asn1 OID
162 */
163 if ((eckey = EC_KEY_new()) == NULL)
164 {
165 ECerr(EC_F_ECKEY_TYPE2PARAM, ERR_R_MALLOC_FAILURE);
166 goto ecerr;
167 }
168 group = EC_GROUP_new_by_curve_name(OBJ_obj2nid(poid));
169 if (group == NULL)
170 goto ecerr;
171 EC_GROUP_set_asn1_flag(group, OPENSSL_EC_NAMED_CURVE);
172 if (EC_KEY_set_group(eckey, group) == 0)
173 goto ecerr;
174 EC_GROUP_free(group);
175 }
176 else
177 {
178 ECerr(EC_F_ECKEY_TYPE2PARAM, EC_R_DECODE_ERROR);
179 goto ecerr;
180 }
181
182 return eckey;
183
184 ecerr:
185 if (eckey)
186 EC_KEY_free(eckey);
187 return NULL;
188 }
189
190static int eckey_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey)
191 {
192 const unsigned char *p = NULL;
193 void *pval;
194 int ptype, pklen;
195 EC_KEY *eckey = NULL;
196 X509_ALGOR *palg;
197
198 if (!X509_PUBKEY_get0_param(NULL, &p, &pklen, &palg, pubkey))
199 return 0;
200 X509_ALGOR_get0(NULL, &ptype, &pval, palg);
201
202 eckey = eckey_type2param(ptype, pval);
203
204 if (!eckey)
205 {
206 ECerr(EC_F_ECKEY_PUB_DECODE, ERR_R_EC_LIB);
207 return 0;
208 }
209
210 /* We have parameters now set public key */
211 if (!o2i_ECPublicKey(&eckey, &p, pklen))
212 {
213 ECerr(EC_F_ECKEY_PUB_DECODE, EC_R_DECODE_ERROR);
214 goto ecerr;
215 }
216
217 EVP_PKEY_assign_EC_KEY(pkey, eckey);
218 return 1;
219
220 ecerr:
221 if (eckey)
222 EC_KEY_free(eckey);
223 return 0;
224 }
225
226static int eckey_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b)
227 {
228 int r;
229 const EC_GROUP *group = EC_KEY_get0_group(b->pkey.ec);
230 const EC_POINT *pa = EC_KEY_get0_public_key(a->pkey.ec),
231 *pb = EC_KEY_get0_public_key(b->pkey.ec);
232 r = EC_POINT_cmp(group, pa, pb, NULL);
233 if (r == 0)
234 return 1;
235 if (r == 1)
236 return 0;
237 return -2;
238 }
239
240static int eckey_priv_decode(EVP_PKEY *pkey, PKCS8_PRIV_KEY_INFO *p8)
241 {
242 const unsigned char *p = NULL;
243 void *pval;
244 int ptype, pklen;
245 EC_KEY *eckey = NULL;
246 X509_ALGOR *palg;
247
248 if (!PKCS8_pkey_get0(NULL, &p, &pklen, &palg, p8))
249 return 0;
250 X509_ALGOR_get0(NULL, &ptype, &pval, palg);
251
252 eckey = eckey_type2param(ptype, pval);
253
254 if (!eckey)
255 goto ecliberr;
256
257 /* We have parameters now set private key */
258 if (!d2i_ECPrivateKey(&eckey, &p, pklen))
259 {
260 ECerr(EC_F_ECKEY_PRIV_DECODE, EC_R_DECODE_ERROR);
261 goto ecerr;
262 }
263
264 /* calculate public key (if necessary) */
265 if (EC_KEY_get0_public_key(eckey) == NULL)
266 {
267 const BIGNUM *priv_key;
268 const EC_GROUP *group;
269 EC_POINT *pub_key;
270 /* the public key was not included in the SEC1 private
271 * key => calculate the public key */
272 group = EC_KEY_get0_group(eckey);
273 pub_key = EC_POINT_new(group);
274 if (pub_key == NULL)
275 {
276 ECerr(EC_F_ECKEY_PRIV_DECODE, ERR_R_EC_LIB);
277 goto ecliberr;
278 }
279 if (!EC_POINT_copy(pub_key, EC_GROUP_get0_generator(group)))
280 {
281 EC_POINT_free(pub_key);
282 ECerr(EC_F_ECKEY_PRIV_DECODE, ERR_R_EC_LIB);
283 goto ecliberr;
284 }
285 priv_key = EC_KEY_get0_private_key(eckey);
286 if (!EC_POINT_mul(group, pub_key, priv_key, NULL, NULL, NULL))
287 {
288 EC_POINT_free(pub_key);
289 ECerr(EC_F_ECKEY_PRIV_DECODE, ERR_R_EC_LIB);
290 goto ecliberr;
291 }
292 if (EC_KEY_set_public_key(eckey, pub_key) == 0)
293 {
294 EC_POINT_free(pub_key);
295 ECerr(EC_F_ECKEY_PRIV_DECODE, ERR_R_EC_LIB);
296 goto ecliberr;
297 }
298 EC_POINT_free(pub_key);
299 }
300
301 EVP_PKEY_assign_EC_KEY(pkey, eckey);
302 return 1;
303
304 ecliberr:
305 ECerr(EC_F_ECKEY_PRIV_DECODE, ERR_R_EC_LIB);
306 ecerr:
307 if (eckey)
308 EC_KEY_free(eckey);
309 return 0;
310 }
311
312static int eckey_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey)
313{
314 EC_KEY *ec_key;
315 unsigned char *ep, *p;
316 int eplen, ptype;
317 void *pval;
318 unsigned int tmp_flags, old_flags;
319
320 ec_key = pkey->pkey.ec;
321
322 if (!eckey_param2type(&ptype, &pval, ec_key))
323 {
324 ECerr(EC_F_ECKEY_PRIV_ENCODE, EC_R_DECODE_ERROR);
325 return 0;
326 }
327
328 /* set the private key */
329
330 /* do not include the parameters in the SEC1 private key
331 * see PKCS#11 12.11 */
332 old_flags = EC_KEY_get_enc_flags(ec_key);
333 tmp_flags = old_flags | EC_PKEY_NO_PARAMETERS;
334 EC_KEY_set_enc_flags(ec_key, tmp_flags);
335 eplen = i2d_ECPrivateKey(ec_key, NULL);
336 if (!eplen)
337 {
338 EC_KEY_set_enc_flags(ec_key, old_flags);
339 ECerr(EC_F_ECKEY_PRIV_ENCODE, ERR_R_EC_LIB);
340 return 0;
341 }
342 ep = (unsigned char *) OPENSSL_malloc(eplen);
343 if (!ep)
344 {
345 EC_KEY_set_enc_flags(ec_key, old_flags);
346 ECerr(EC_F_ECKEY_PRIV_ENCODE, ERR_R_MALLOC_FAILURE);
347 return 0;
348 }
349 p = ep;
350 if (!i2d_ECPrivateKey(ec_key, &p))
351 {
352 EC_KEY_set_enc_flags(ec_key, old_flags);
353 OPENSSL_free(ep);
354 ECerr(EC_F_ECKEY_PRIV_ENCODE, ERR_R_EC_LIB);
355 }
356 /* restore old encoding flags */
357 EC_KEY_set_enc_flags(ec_key, old_flags);
358
359 if (!PKCS8_pkey_set0(p8, OBJ_nid2obj(NID_X9_62_id_ecPublicKey), 0,
360 ptype, pval, ep, eplen))
361 return 0;
362
363 return 1;
364}
365
366static int int_ec_size(const EVP_PKEY *pkey)
367 {
368 return ECDSA_size(pkey->pkey.ec);
369 }
370
371static int ec_bits(const EVP_PKEY *pkey)
372 {
373 BIGNUM *order = BN_new();
374 const EC_GROUP *group;
375 int ret;
376
377 if (!order)
378 {
379 ERR_clear_error();
380 return 0;
381 }
382 group = EC_KEY_get0_group(pkey->pkey.ec);
383 if (!EC_GROUP_get_order(group, order, NULL))
384 {
385 ERR_clear_error();
386 return 0;
387 }
388
389 ret = BN_num_bits(order);
390 BN_free(order);
391 return ret;
392 }
393
394static int ec_missing_parameters(const EVP_PKEY *pkey)
395 {
396 if (EC_KEY_get0_group(pkey->pkey.ec) == NULL)
397 return 1;
398 return 0;
399 }
400
401static int ec_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from)
402 {
403 EC_GROUP *group = EC_GROUP_dup(EC_KEY_get0_group(from->pkey.ec));
404 if (group == NULL)
405 return 0;
406 if (EC_KEY_set_group(to->pkey.ec, group) == 0)
407 return 0;
408 EC_GROUP_free(group);
409 return 1;
410 }
411
412static int ec_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b)
413 {
414 const EC_GROUP *group_a = EC_KEY_get0_group(a->pkey.ec),
415 *group_b = EC_KEY_get0_group(b->pkey.ec);
416 if (EC_GROUP_cmp(group_a, group_b, NULL))
417 return 0;
418 else
419 return 1;
420 }
421
422static void int_ec_free(EVP_PKEY *pkey)
423 {
424 EC_KEY_free(pkey->pkey.ec);
425 }
426
427static int do_EC_KEY_print(BIO *bp, const EC_KEY *x, int off, int ktype)
428 {
429 unsigned char *buffer=NULL;
430 const char *ecstr;
431 size_t buf_len=0, i;
432 int ret=0, reason=ERR_R_BIO_LIB;
433 BIGNUM *pub_key=NULL, *order=NULL;
434 BN_CTX *ctx=NULL;
435 const EC_GROUP *group;
436 const EC_POINT *public_key;
437 const BIGNUM *priv_key;
438
439 if (x == NULL || (group = EC_KEY_get0_group(x)) == NULL)
440 {
441 reason = ERR_R_PASSED_NULL_PARAMETER;
442 goto err;
443 }
444
445 ctx = BN_CTX_new();
446 if (ctx == NULL)
447 {
448 reason = ERR_R_MALLOC_FAILURE;
449 goto err;
450 }
451
452 if (ktype > 0)
453 {
454 public_key = EC_KEY_get0_public_key(x);
455 if ((pub_key = EC_POINT_point2bn(group, public_key,
456 EC_KEY_get_conv_form(x), NULL, ctx)) == NULL)
457 {
458 reason = ERR_R_EC_LIB;
459 goto err;
460 }
461 if (pub_key)
462 buf_len = (size_t)BN_num_bytes(pub_key);
463 }
464
465 if (ktype == 2)
466 {
467 priv_key = EC_KEY_get0_private_key(x);
468 if (priv_key && (i = (size_t)BN_num_bytes(priv_key)) > buf_len)
469 buf_len = i;
470 }
471 else
472 priv_key = NULL;
473
474 if (ktype > 0)
475 {
476 buf_len += 10;
477 if ((buffer = OPENSSL_malloc(buf_len)) == NULL)
478 {
479 reason = ERR_R_MALLOC_FAILURE;
480 goto err;
481 }
482 }
483 if (ktype == 2)
484 ecstr = "Private-Key";
485 else if (ktype == 1)
486 ecstr = "Public-Key";
487 else
488 ecstr = "ECDSA-Parameters";
489
490 if (!BIO_indent(bp, off, 128))
491 goto err;
492 if ((order = BN_new()) == NULL)
493 goto err;
494 if (!EC_GROUP_get_order(group, order, NULL))
495 goto err;
496 if (BIO_printf(bp, "%s: (%d bit)\n", ecstr,
497 BN_num_bits(order)) <= 0) goto err;
498
499 if ((priv_key != NULL) && !ASN1_bn_print(bp, "priv:", priv_key,
500 buffer, off))
501 goto err;
502 if ((pub_key != NULL) && !ASN1_bn_print(bp, "pub: ", pub_key,
503 buffer, off))
504 goto err;
505 if (!ECPKParameters_print(bp, group, off))
506 goto err;
507 ret=1;
508err:
509 if (!ret)
510 ECerr(EC_F_DO_EC_KEY_PRINT, reason);
511 if (pub_key)
512 BN_free(pub_key);
513 if (order)
514 BN_free(order);
515 if (ctx)
516 BN_CTX_free(ctx);
517 if (buffer != NULL)
518 OPENSSL_free(buffer);
519 return(ret);
520 }
521
522static int eckey_param_decode(EVP_PKEY *pkey,
523 const unsigned char **pder, int derlen)
524 {
525 EC_KEY *eckey;
526 if (!(eckey = d2i_ECParameters(NULL, pder, derlen)))
527 {
528 ECerr(EC_F_ECKEY_PARAM_DECODE, ERR_R_EC_LIB);
529 return 0;
530 }
531 EVP_PKEY_assign_EC_KEY(pkey, eckey);
532 return 1;
533 }
534
535static int eckey_param_encode(const EVP_PKEY *pkey, unsigned char **pder)
536 {
537 return i2d_ECParameters(pkey->pkey.ec, pder);
538 }
539
540static int eckey_param_print(BIO *bp, const EVP_PKEY *pkey, int indent,
541 ASN1_PCTX *ctx)
542 {
543 return do_EC_KEY_print(bp, pkey->pkey.ec, indent, 0);
544 }
545
546static int eckey_pub_print(BIO *bp, const EVP_PKEY *pkey, int indent,
547 ASN1_PCTX *ctx)
548 {
549 return do_EC_KEY_print(bp, pkey->pkey.ec, indent, 1);
550 }
551
552
553static int eckey_priv_print(BIO *bp, const EVP_PKEY *pkey, int indent,
554 ASN1_PCTX *ctx)
555 {
556 return do_EC_KEY_print(bp, pkey->pkey.ec, indent, 2);
557 }
558
559static int old_ec_priv_decode(EVP_PKEY *pkey,
560 const unsigned char **pder, int derlen)
561 {
562 EC_KEY *ec;
563 if (!(ec = d2i_ECPrivateKey (NULL, pder, derlen)))
564 {
565 ECerr(EC_F_OLD_EC_PRIV_DECODE, EC_R_DECODE_ERROR);
566 return 0;
567 }
568 EVP_PKEY_assign_EC_KEY(pkey, ec);
569 return 1;
570 }
571
572static int old_ec_priv_encode(const EVP_PKEY *pkey, unsigned char **pder)
573 {
574 return i2d_ECPrivateKey(pkey->pkey.ec, pder);
575 }
576
577static int ec_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2)
578 {
579 switch (op)
580 {
581 case ASN1_PKEY_CTRL_PKCS7_SIGN:
582 if (arg1 == 0)
583 {
584 int snid, hnid;
585 X509_ALGOR *alg1, *alg2;
586 PKCS7_SIGNER_INFO_get0_algs(arg2, NULL, &alg1, &alg2);
587 if (alg1 == NULL || alg1->algorithm == NULL)
588 return -1;
589 hnid = OBJ_obj2nid(alg1->algorithm);
590 if (hnid == NID_undef)
591 return -1;
592 if (!OBJ_find_sigid_by_algs(&snid, hnid, EVP_PKEY_id(pkey)))
593 return -1;
594 X509_ALGOR_set0(alg2, OBJ_nid2obj(snid), V_ASN1_UNDEF, 0);
595 }
596 return 1;
597#ifndef OPENSSL_NO_CMS
598 case ASN1_PKEY_CTRL_CMS_SIGN:
599 if (arg1 == 0)
600 {
601 int snid, hnid;
602 X509_ALGOR *alg1, *alg2;
603 CMS_SignerInfo_get0_algs(arg2, NULL, NULL,
604 &alg1, &alg2);
605 if (alg1 == NULL || alg1->algorithm == NULL)
606 return -1;
607 hnid = OBJ_obj2nid(alg1->algorithm);
608 if (hnid == NID_undef)
609 return -1;
610 if (!OBJ_find_sigid_by_algs(&snid, hnid, EVP_PKEY_id(pkey)))
611 return -1;
612 X509_ALGOR_set0(alg2, OBJ_nid2obj(snid), V_ASN1_UNDEF, 0);
613 }
614 return 1;
615#endif
616
617 case ASN1_PKEY_CTRL_DEFAULT_MD_NID:
618 *(int *)arg2 = NID_sha1;
619 return 2;
620
621 default:
622 return -2;
623
624 }
625
626 }
627
628const EVP_PKEY_ASN1_METHOD eckey_asn1_meth =
629 {
630 EVP_PKEY_EC,
631 EVP_PKEY_EC,
632 0,
633 "EC",
634 "OpenSSL EC algorithm",
635
636 eckey_pub_decode,
637 eckey_pub_encode,
638 eckey_pub_cmp,
639 eckey_pub_print,
640
641 eckey_priv_decode,
642 eckey_priv_encode,
643 eckey_priv_print,
644
645 int_ec_size,
646 ec_bits,
647
648 eckey_param_decode,
649 eckey_param_encode,
650 ec_missing_parameters,
651 ec_copy_parameters,
652 ec_cmp_parameters,
653 eckey_param_print,
654
655 int_ec_free,
656 ec_pkey_ctrl,
657 old_ec_priv_decode,
658 old_ec_priv_encode
659 };
diff --git a/src/lib/libcrypto/ec/ec_curve.c b/src/lib/libcrypto/ec/ec_curve.c
index beac20969b..23274e4031 100644
--- a/src/lib/libcrypto/ec/ec_curve.c
+++ b/src/lib/libcrypto/ec/ec_curve.c
@@ -73,926 +73,1690 @@
73#include <openssl/err.h> 73#include <openssl/err.h>
74#include <openssl/obj_mac.h> 74#include <openssl/obj_mac.h>
75 75
76typedef struct ec_curve_data_st { 76typedef struct {
77 int field_type; /* either NID_X9_62_prime_field or 77 int field_type, /* either NID_X9_62_prime_field or
78 * NID_X9_62_characteristic_two_field */ 78 * NID_X9_62_characteristic_two_field */
79 const char *p; /* either a prime number or a polynomial */ 79 seed_len,
80 const char *a; 80 param_len;
81 const char *b; 81 unsigned int cofactor; /* promoted to BN_ULONG */
82 const char *x; /* the x coordinate of the generator */
83 const char *y; /* the y coordinate of the generator */
84 const char *order; /* the order of the group generated by the
85 * generator */
86 const BN_ULONG cofactor;/* the cofactor */
87 const unsigned char *seed;/* the seed (optional) */
88 size_t seed_len;
89 const char *comment; /* a short description of the curve */
90} EC_CURVE_DATA; 82} EC_CURVE_DATA;
91 83
92/* the nist prime curves */ 84/* the nist prime curves */
93static const unsigned char _EC_NIST_PRIME_192_SEED[] = { 85static const struct { EC_CURVE_DATA h; unsigned char data[20+24*6]; }
94 0x30,0x45,0xAE,0x6F,0xC8,0x42,0x2F,0x64,0xED,0x57, 86 _EC_NIST_PRIME_192 = {
95 0x95,0x28,0xD3,0x81,0x20,0xEA,0xE1,0x21,0x96,0xD5}; 87 { NID_X9_62_prime_field,20,24,1 },
96static const EC_CURVE_DATA _EC_NIST_PRIME_192 = { 88 { 0x30,0x45,0xAE,0x6F,0xC8,0x42,0x2F,0x64,0xED,0x57, /* seed */
97 NID_X9_62_prime_field, 89 0x95,0x28,0xD3,0x81,0x20,0xEA,0xE1,0x21,0x96,0xD5,
98 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF", 90
99 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC", 91 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* p */
100 "64210519E59C80E70FA7E9AB72243049FEB8DEECC146B9B1", 92 0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xFF,0xFF,
101 "188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF1012", 93 0xFF,0xFF,0xFF,0xFF,
102 "07192b95ffc8da78631011ed6b24cdd573f977a11e794811", 94 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* a */
103 "FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22831",1, 95 0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xFF,0xFF,
104 _EC_NIST_PRIME_192_SEED, 20, 96 0xFF,0xFF,0xFF,0xFC,
105 "NIST/X9.62/SECG curve over a 192 bit prime field" 97 0x64,0x21,0x05,0x19,0xE5,0x9C,0x80,0xE7,0x0F,0xA7, /* b */
98 0xE9,0xAB,0x72,0x24,0x30,0x49,0xFE,0xB8,0xDE,0xEC,
99 0xC1,0x46,0xB9,0xB1,
100 0x18,0x8D,0xA8,0x0E,0xB0,0x30,0x90,0xF6,0x7C,0xBF, /* x */
101 0x20,0xEB,0x43,0xA1,0x88,0x00,0xF4,0xFF,0x0A,0xFD,
102 0x82,0xFF,0x10,0x12,
103 0x07,0x19,0x2b,0x95,0xff,0xc8,0xda,0x78,0x63,0x10, /* y */
104 0x11,0xed,0x6b,0x24,0xcd,0xd5,0x73,0xf9,0x77,0xa1,
105 0x1e,0x79,0x48,0x11,
106 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* order */
107 0xFF,0xFF,0x99,0xDE,0xF8,0x36,0x14,0x6B,0xC9,0xB1,
108 0xB4,0xD2,0x28,0x31 }
106 }; 109 };
107 110
108static const unsigned char _EC_NIST_PRIME_224_SEED[] = { 111static const struct { EC_CURVE_DATA h; unsigned char data[20+28*6]; }
109 0xBD,0x71,0x34,0x47,0x99,0xD5,0xC7,0xFC,0xDC,0x45, 112 _EC_NIST_PRIME_224 = {
110 0xB5,0x9F,0xA3,0xB9,0xAB,0x8F,0x6A,0x94,0x8B,0xC5}; 113 { NID_X9_62_prime_field,20,28,1 },
111static const EC_CURVE_DATA _EC_NIST_PRIME_224 = { 114 { 0xBD,0x71,0x34,0x47,0x99,0xD5,0xC7,0xFC,0xDC,0x45, /* seed */
112 NID_X9_62_prime_field, 115 0xB5,0x9F,0xA3,0xB9,0xAB,0x8F,0x6A,0x94,0x8B,0xC5,
113 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001", 116
114 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFE", 117 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* p */
115 "B4050A850C04B3ABF54132565044B0B7D7BFD8BA270B39432355FFB4", 118 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,
116 "B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21", 119 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,
117 "bd376388b5f723fb4c22dfe6cd4375a05a07476444d5819985007e34", 120 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* a */
118 "FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D",1, 121 0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xFF,0xFF,
119 _EC_NIST_PRIME_224_SEED, 20, 122 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,
120 "NIST/SECG curve over a 224 bit prime field" 123 0xB4,0x05,0x0A,0x85,0x0C,0x04,0xB3,0xAB,0xF5,0x41, /* b */
124 0x32,0x56,0x50,0x44,0xB0,0xB7,0xD7,0xBF,0xD8,0xBA,
125 0x27,0x0B,0x39,0x43,0x23,0x55,0xFF,0xB4,
126 0xB7,0x0E,0x0C,0xBD,0x6B,0xB4,0xBF,0x7F,0x32,0x13, /* x */
127 0x90,0xB9,0x4A,0x03,0xC1,0xD3,0x56,0xC2,0x11,0x22,
128 0x34,0x32,0x80,0xD6,0x11,0x5C,0x1D,0x21,
129 0xbd,0x37,0x63,0x88,0xb5,0xf7,0x23,0xfb,0x4c,0x22, /* y */
130 0xdf,0xe6,0xcd,0x43,0x75,0xa0,0x5a,0x07,0x47,0x64,
131 0x44,0xd5,0x81,0x99,0x85,0x00,0x7e,0x34,
132 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* order */
133 0xFF,0xFF,0xFF,0xFF,0x16,0xA2,0xE0,0xB8,0xF0,0x3E,
134 0x13,0xDD,0x29,0x45,0x5C,0x5C,0x2A,0x3D }
121 }; 135 };
122 136
123static const unsigned char _EC_NIST_PRIME_384_SEED[] = { 137static const struct { EC_CURVE_DATA h; unsigned char data[20+48*6]; }
124 0xA3,0x35,0x92,0x6A,0xA3,0x19,0xA2,0x7A,0x1D,0x00, 138 _EC_NIST_PRIME_384 = {
125 0x89,0x6A,0x67,0x73,0xA4,0x82,0x7A,0xCD,0xAC,0x73}; 139 { NID_X9_62_prime_field,20,48,1 },
126static const EC_CURVE_DATA _EC_NIST_PRIME_384 = { 140 { 0xA3,0x35,0x92,0x6A,0xA3,0x19,0xA2,0x7A,0x1D,0x00, /* seed */
127 NID_X9_62_prime_field, 141 0x89,0x6A,0x67,0x73,0xA4,0x82,0x7A,0xCD,0xAC,0x73,
128 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFF" 142
129 "FFF0000000000000000FFFFFFFF", 143 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* p */
130 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFF" 144 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
131 "FFF0000000000000000FFFFFFFC", 145 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
132 "B3312FA7E23EE7E4988E056BE3F82D19181D9C6EFE8141120314088F5013875AC6563" 146 0xFF,0xFE,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,
133 "98D8A2ED19D2A85C8EDD3EC2AEF", 147 0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,
134 "AA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B9859F741E082542A385502F" 148 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* a */
135 "25DBF55296C3A545E3872760AB7", 149 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
136 "3617de4a96262c6f5d9e98bf9292dc29f8f41dbd289a147ce9da3113b5f0b8c00a60b" 150 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
137 "1ce1d7e819d7a431d7c90ea0e5f", 151 0xFF,0xFE,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,
138 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7634D81F4372DDF581A0" 152 0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFC,
139 "DB248B0A77AECEC196ACCC52973",1, 153 0xB3,0x31,0x2F,0xA7,0xE2,0x3E,0xE7,0xE4,0x98,0x8E, /* b */
140 _EC_NIST_PRIME_384_SEED, 20, 154 0x05,0x6B,0xE3,0xF8,0x2D,0x19,0x18,0x1D,0x9C,0x6E,
141 "NIST/SECG curve over a 384 bit prime field" 155 0xFE,0x81,0x41,0x12,0x03,0x14,0x08,0x8F,0x50,0x13,
156 0x87,0x5A,0xC6,0x56,0x39,0x8D,0x8A,0x2E,0xD1,0x9D,
157 0x2A,0x85,0xC8,0xED,0xD3,0xEC,0x2A,0xEF,
158 0xAA,0x87,0xCA,0x22,0xBE,0x8B,0x05,0x37,0x8E,0xB1, /* x */
159 0xC7,0x1E,0xF3,0x20,0xAD,0x74,0x6E,0x1D,0x3B,0x62,
160 0x8B,0xA7,0x9B,0x98,0x59,0xF7,0x41,0xE0,0x82,0x54,
161 0x2A,0x38,0x55,0x02,0xF2,0x5D,0xBF,0x55,0x29,0x6C,
162 0x3A,0x54,0x5E,0x38,0x72,0x76,0x0A,0xB7,
163 0x36,0x17,0xde,0x4a,0x96,0x26,0x2c,0x6f,0x5d,0x9e, /* y */
164 0x98,0xbf,0x92,0x92,0xdc,0x29,0xf8,0xf4,0x1d,0xbd,
165 0x28,0x9a,0x14,0x7c,0xe9,0xda,0x31,0x13,0xb5,0xf0,
166 0xb8,0xc0,0x0a,0x60,0xb1,0xce,0x1d,0x7e,0x81,0x9d,
167 0x7a,0x43,0x1d,0x7c,0x90,0xea,0x0e,0x5f,
168 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* order */
169 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
170 0xFF,0xFF,0xFF,0xFF,0xC7,0x63,0x4D,0x81,0xF4,0x37,
171 0x2D,0xDF,0x58,0x1A,0x0D,0xB2,0x48,0xB0,0xA7,0x7A,
172 0xEC,0xEC,0x19,0x6A,0xCC,0xC5,0x29,0x73 }
142 }; 173 };
143 174
144static const unsigned char _EC_NIST_PRIME_521_SEED[] = { 175static const struct { EC_CURVE_DATA h; unsigned char data[20+66*6]; }
145 0xD0,0x9E,0x88,0x00,0x29,0x1C,0xB8,0x53,0x96,0xCC, 176 _EC_NIST_PRIME_521 = {
146 0x67,0x17,0x39,0x32,0x84,0xAA,0xA0,0xDA,0x64,0xBA}; 177 { NID_X9_62_prime_field,20,66,1 },
147static const EC_CURVE_DATA _EC_NIST_PRIME_521 = { 178 { 0xD0,0x9E,0x88,0x00,0x29,0x1C,0xB8,0x53,0x96,0xCC, /* seed */
148 NID_X9_62_prime_field, 179 0x67,0x17,0x39,0x32,0x84,0xAA,0xA0,0xDA,0x64,0xBA,
149 "1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" 180
150 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", 181 0x01,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* p */
151 "1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" 182 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
152 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC", 183 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
153 "051953EB9618E1C9A1F929A21A0B68540EEA2DA725B99B315F3B8B489918EF109E156" 184 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
154 "193951EC7E937B1652C0BD3BB1BF073573DF883D2C34F1EF451FD46B503F00", 185 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
155 "C6858E06B70404E9CD9E3ECB662395B4429C648139053FB521F828AF606B4D3DBAA14" 186 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
156 "B5E77EFE75928FE1DC127A2FFA8DE3348B3C1856A429BF97E7E31C2E5BD66", 187 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
157 "011839296a789a3bc0045c8a5fb42c7d1bd998f54449579b446817afbd17273e662c9" 188 0x01,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* a */
158 "7ee72995ef42640c550b9013fad0761353c7086a272c24088be94769fd16650", 189 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
159 "1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA51" 190 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
160 "868783BF2F966B7FCC0148F709A5D03BB5C9B8899C47AEBB6FB71E91386409",1, 191 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
161 _EC_NIST_PRIME_521_SEED, 20, 192 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
162 "NIST/SECG curve over a 521 bit prime field" 193 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
194 0xFF,0xFF,0xFF,0xFF,0xFF,0xFC,
195 0x00,0x51,0x95,0x3E,0xB9,0x61,0x8E,0x1C,0x9A,0x1F, /* b */
196 0x92,0x9A,0x21,0xA0,0xB6,0x85,0x40,0xEE,0xA2,0xDA,
197 0x72,0x5B,0x99,0xB3,0x15,0xF3,0xB8,0xB4,0x89,0x91,
198 0x8E,0xF1,0x09,0xE1,0x56,0x19,0x39,0x51,0xEC,0x7E,
199 0x93,0x7B,0x16,0x52,0xC0,0xBD,0x3B,0xB1,0xBF,0x07,
200 0x35,0x73,0xDF,0x88,0x3D,0x2C,0x34,0xF1,0xEF,0x45,
201 0x1F,0xD4,0x6B,0x50,0x3F,0x00,
202 0x00,0xC6,0x85,0x8E,0x06,0xB7,0x04,0x04,0xE9,0xCD, /* x */
203 0x9E,0x3E,0xCB,0x66,0x23,0x95,0xB4,0x42,0x9C,0x64,
204 0x81,0x39,0x05,0x3F,0xB5,0x21,0xF8,0x28,0xAF,0x60,
205 0x6B,0x4D,0x3D,0xBA,0xA1,0x4B,0x5E,0x77,0xEF,0xE7,
206 0x59,0x28,0xFE,0x1D,0xC1,0x27,0xA2,0xFF,0xA8,0xDE,
207 0x33,0x48,0xB3,0xC1,0x85,0x6A,0x42,0x9B,0xF9,0x7E,
208 0x7E,0x31,0xC2,0xE5,0xBD,0x66,
209 0x01,0x18,0x39,0x29,0x6a,0x78,0x9a,0x3b,0xc0,0x04, /* y */
210 0x5c,0x8a,0x5f,0xb4,0x2c,0x7d,0x1b,0xd9,0x98,0xf5,
211 0x44,0x49,0x57,0x9b,0x44,0x68,0x17,0xaf,0xbd,0x17,
212 0x27,0x3e,0x66,0x2c,0x97,0xee,0x72,0x99,0x5e,0xf4,
213 0x26,0x40,0xc5,0x50,0xb9,0x01,0x3f,0xad,0x07,0x61,
214 0x35,0x3c,0x70,0x86,0xa2,0x72,0xc2,0x40,0x88,0xbe,
215 0x94,0x76,0x9f,0xd1,0x66,0x50,
216 0x01,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* order */
217 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
218 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
219 0xFF,0xFF,0xFF,0xFA,0x51,0x86,0x87,0x83,0xBF,0x2F,
220 0x96,0x6B,0x7F,0xCC,0x01,0x48,0xF7,0x09,0xA5,0xD0,
221 0x3B,0xB5,0xC9,0xB8,0x89,0x9C,0x47,0xAE,0xBB,0x6F,
222 0xB7,0x1E,0x91,0x38,0x64,0x09 }
163 }; 223 };
224
164/* the x9.62 prime curves (minus the nist prime curves) */ 225/* the x9.62 prime curves (minus the nist prime curves) */
165static const unsigned char _EC_X9_62_PRIME_192V2_SEED[] = { 226static const struct { EC_CURVE_DATA h; unsigned char data[20+24*6]; }
166 0x31,0xA9,0x2E,0xE2,0x02,0x9F,0xD1,0x0D,0x90,0x1B, 227 _EC_X9_62_PRIME_192V2 = {
167 0x11,0x3E,0x99,0x07,0x10,0xF0,0xD2,0x1A,0xC6,0xB6}; 228 { NID_X9_62_prime_field,20,24,1 },
168static const EC_CURVE_DATA _EC_X9_62_PRIME_192V2 = { 229 { 0x31,0xA9,0x2E,0xE2,0x02,0x9F,0xD1,0x0D,0x90,0x1B, /* seed */
169 NID_X9_62_prime_field, 230 0x11,0x3E,0x99,0x07,0x10,0xF0,0xD2,0x1A,0xC6,0xB6,
170 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF", 231
171 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC", 232 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* p */
172 "CC22D6DFB95C6B25E49C0D6364A4E5980C393AA21668D953", 233 0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xFF,0xFF,
173 "EEA2BAE7E1497842F2DE7769CFE9C989C072AD696F48034A", 234 0xFF,0xFF,0xFF,0xFF,
174 "6574d11d69b6ec7a672bb82a083df2f2b0847de970b2de15", 235 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* a */
175 "FFFFFFFFFFFFFFFFFFFFFFFE5FB1A724DC80418648D8DD31",1, 236 0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xFF,0xFF,
176 _EC_X9_62_PRIME_192V2_SEED, 20, 237 0xFF,0xFF,0xFF,0xFC,
177 "X9.62 curve over a 192 bit prime field" 238 0xCC,0x22,0xD6,0xDF,0xB9,0x5C,0x6B,0x25,0xE4,0x9C, /* b */
239 0x0D,0x63,0x64,0xA4,0xE5,0x98,0x0C,0x39,0x3A,0xA2,
240 0x16,0x68,0xD9,0x53,
241 0xEE,0xA2,0xBA,0xE7,0xE1,0x49,0x78,0x42,0xF2,0xDE, /* x */
242 0x77,0x69,0xCF,0xE9,0xC9,0x89,0xC0,0x72,0xAD,0x69,
243 0x6F,0x48,0x03,0x4A,
244 0x65,0x74,0xd1,0x1d,0x69,0xb6,0xec,0x7a,0x67,0x2b, /* y */
245 0xb8,0x2a,0x08,0x3d,0xf2,0xf2,0xb0,0x84,0x7d,0xe9,
246 0x70,0xb2,0xde,0x15,
247 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* order */
248 0xFF,0xFE,0x5F,0xB1,0xA7,0x24,0xDC,0x80,0x41,0x86,
249 0x48,0xD8,0xDD,0x31 }
178 }; 250 };
179 251
180static const unsigned char _EC_X9_62_PRIME_192V3_SEED[] = { 252static const struct { EC_CURVE_DATA h; unsigned char data[20+24*6]; }
181 0xC4,0x69,0x68,0x44,0x35,0xDE,0xB3,0x78,0xC4,0xB6, 253 _EC_X9_62_PRIME_192V3 = {
182 0x5C,0xA9,0x59,0x1E,0x2A,0x57,0x63,0x05,0x9A,0x2E}; 254 { NID_X9_62_prime_field,20,24,1 },
183static const EC_CURVE_DATA _EC_X9_62_PRIME_192V3 = { 255 { 0xC4,0x69,0x68,0x44,0x35,0xDE,0xB3,0x78,0xC4,0xB6, /* seed */
184 NID_X9_62_prime_field, 256 0x5C,0xA9,0x59,0x1E,0x2A,0x57,0x63,0x05,0x9A,0x2E,
185 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF", 257
186 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC", 258 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* p */
187 "22123DC2395A05CAA7423DAECCC94760A7D462256BD56916", 259 0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xFF,0xFF,
188 "7D29778100C65A1DA1783716588DCE2B8B4AEE8E228F1896", 260 0xFF,0xFF,0xFF,0xFF,
189 "38a90f22637337334b49dcb66a6dc8f9978aca7648a943b0", 261 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* a */
190 "FFFFFFFFFFFFFFFFFFFFFFFF7A62D031C83F4294F640EC13",1, 262 0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xFF,0xFF,
191 _EC_X9_62_PRIME_192V3_SEED, 20, 263 0xFF,0xFF,0xFF,0xFC,
192 "X9.62 curve over a 192 bit prime field" 264 0x22,0x12,0x3D,0xC2,0x39,0x5A,0x05,0xCA,0xA7,0x42, /* b */
265 0x3D,0xAE,0xCC,0xC9,0x47,0x60,0xA7,0xD4,0x62,0x25,
266 0x6B,0xD5,0x69,0x16,
267 0x7D,0x29,0x77,0x81,0x00,0xC6,0x5A,0x1D,0xA1,0x78, /* x */
268 0x37,0x16,0x58,0x8D,0xCE,0x2B,0x8B,0x4A,0xEE,0x8E,
269 0x22,0x8F,0x18,0x96,
270 0x38,0xa9,0x0f,0x22,0x63,0x73,0x37,0x33,0x4b,0x49, /* y */
271 0xdc,0xb6,0x6a,0x6d,0xc8,0xf9,0x97,0x8a,0xca,0x76,
272 0x48,0xa9,0x43,0xb0,
273 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* order */
274 0xFF,0xFF,0x7A,0x62,0xD0,0x31,0xC8,0x3F,0x42,0x94,
275 0xF6,0x40,0xEC,0x13 }
193 }; 276 };
194 277
195static const unsigned char _EC_X9_62_PRIME_239V1_SEED[] = { 278static const struct { EC_CURVE_DATA h; unsigned char data[20+30*6]; }
196 0xE4,0x3B,0xB4,0x60,0xF0,0xB8,0x0C,0xC0,0xC0,0xB0, 279 _EC_X9_62_PRIME_239V1 = {
197 0x75,0x79,0x8E,0x94,0x80,0x60,0xF8,0x32,0x1B,0x7D}; 280 { NID_X9_62_prime_field,20,30,1 },
198static const EC_CURVE_DATA _EC_X9_62_PRIME_239V1 = { 281 { 0xE4,0x3B,0xB4,0x60,0xF0,0xB8,0x0C,0xC0,0xC0,0xB0, /* seed */
199 NID_X9_62_prime_field, 282 0x75,0x79,0x8E,0x94,0x80,0x60,0xF8,0x32,0x1B,0x7D,
200 "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFF", 283
201 "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFC", 284 0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* p */
202 "6B016C3BDCF18941D0D654921475CA71A9DB2FB27D1D37796185C2942C0A", 285 0xFF,0xFF,0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0x80,0x00,
203 "0FFA963CDCA8816CCC33B8642BEDF905C3D358573D3F27FBBD3B3CB9AAAF", 286 0x00,0x00,0x00,0x00,0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,
204 "7debe8e4e90a5dae6e4054ca530ba04654b36818ce226b39fccb7b02f1ae", 287
205 "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFF9E5E9A9F5D9071FBD1522688909D0B",1, 288 0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* a */
206 _EC_X9_62_PRIME_239V1_SEED, 20, 289 0xFF,0xFF,0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0x80,0x00,
207 "X9.62 curve over a 239 bit prime field" 290 0x00,0x00,0x00,0x00,0x7F,0xFF,0xFF,0xFF,0xFF,0xFC,
291
292 0x6B,0x01,0x6C,0x3B,0xDC,0xF1,0x89,0x41,0xD0,0xD6, /* b */
293 0x54,0x92,0x14,0x75,0xCA,0x71,0xA9,0xDB,0x2F,0xB2,
294 0x7D,0x1D,0x37,0x79,0x61,0x85,0xC2,0x94,0x2C,0x0A,
295
296 0x0F,0xFA,0x96,0x3C,0xDC,0xA8,0x81,0x6C,0xCC,0x33, /* x */
297 0xB8,0x64,0x2B,0xED,0xF9,0x05,0xC3,0xD3,0x58,0x57,
298 0x3D,0x3F,0x27,0xFB,0xBD,0x3B,0x3C,0xB9,0xAA,0xAF,
299
300 0x7d,0xeb,0xe8,0xe4,0xe9,0x0a,0x5d,0xae,0x6e,0x40, /* y */
301 0x54,0xca,0x53,0x0b,0xa0,0x46,0x54,0xb3,0x68,0x18,
302 0xce,0x22,0x6b,0x39,0xfc,0xcb,0x7b,0x02,0xf1,0xae,
303
304 0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* order */
305 0xFF,0xFF,0x7F,0xFF,0xFF,0x9E,0x5E,0x9A,0x9F,0x5D,
306 0x90,0x71,0xFB,0xD1,0x52,0x26,0x88,0x90,0x9D,0x0B }
208 }; 307 };
209 308
210static const unsigned char _EC_X9_62_PRIME_239V2_SEED[] = { 309static const struct { EC_CURVE_DATA h; unsigned char data[20+30*6]; }
211 0xE8,0xB4,0x01,0x16,0x04,0x09,0x53,0x03,0xCA,0x3B, 310 _EC_X9_62_PRIME_239V2 = {
212 0x80,0x99,0x98,0x2B,0xE0,0x9F,0xCB,0x9A,0xE6,0x16}; 311 { NID_X9_62_prime_field,20,30,1 },
213static const EC_CURVE_DATA _EC_X9_62_PRIME_239V2 = { 312 { 0xE8,0xB4,0x01,0x16,0x04,0x09,0x53,0x03,0xCA,0x3B, /* seed */
214 NID_X9_62_prime_field, 313 0x80,0x99,0x98,0x2B,0xE0,0x9F,0xCB,0x9A,0xE6,0x16,
215 "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFF", 314
216 "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFC", 315 0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* p */
217 "617FAB6832576CBBFED50D99F0249C3FEE58B94BA0038C7AE84C8C832F2C", 316 0xFF,0xFF,0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0x80,0x00,
218 "38AF09D98727705120C921BB5E9E26296A3CDCF2F35757A0EAFD87B830E7", 317 0x00,0x00,0x00,0x00,0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,
219 "5b0125e4dbea0ec7206da0fc01d9b081329fb555de6ef460237dff8be4ba", 318
220 "7FFFFFFFFFFFFFFFFFFFFFFF800000CFA7E8594377D414C03821BC582063",1, 319 0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* a */
221 _EC_X9_62_PRIME_239V2_SEED, 20, 320 0xFF,0xFF,0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0x80,0x00,
222 "X9.62 curve over a 239 bit prime field" 321 0x00,0x00,0x00,0x00,0x7F,0xFF,0xFF,0xFF,0xFF,0xFC,
322
323 0x61,0x7F,0xAB,0x68,0x32,0x57,0x6C,0xBB,0xFE,0xD5, /* b */
324 0x0D,0x99,0xF0,0x24,0x9C,0x3F,0xEE,0x58,0xB9,0x4B,
325 0xA0,0x03,0x8C,0x7A,0xE8,0x4C,0x8C,0x83,0x2F,0x2C,
326
327 0x38,0xAF,0x09,0xD9,0x87,0x27,0x70,0x51,0x20,0xC9, /* x */
328 0x21,0xBB,0x5E,0x9E,0x26,0x29,0x6A,0x3C,0xDC,0xF2,
329 0xF3,0x57,0x57,0xA0,0xEA,0xFD,0x87,0xB8,0x30,0xE7,
330
331 0x5b,0x01,0x25,0xe4,0xdb,0xea,0x0e,0xc7,0x20,0x6d, /* y */
332 0xa0,0xfc,0x01,0xd9,0xb0,0x81,0x32,0x9f,0xb5,0x55,
333 0xde,0x6e,0xf4,0x60,0x23,0x7d,0xff,0x8b,0xe4,0xba,
334
335 0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* order */
336 0xFF,0xFF,0x80,0x00,0x00,0xCF,0xA7,0xE8,0x59,0x43,
337 0x77,0xD4,0x14,0xC0,0x38,0x21,0xBC,0x58,0x20,0x63 }
223 }; 338 };
224 339
225static const unsigned char _EC_X9_62_PRIME_239V3_SEED[] = { 340static const struct { EC_CURVE_DATA h; unsigned char data[20+30*6]; }
226 0x7D,0x73,0x74,0x16,0x8F,0xFE,0x34,0x71,0xB6,0x0A, 341 _EC_X9_62_PRIME_239V3 = {
227 0x85,0x76,0x86,0xA1,0x94,0x75,0xD3,0xBF,0xA2,0xFF}; 342 { NID_X9_62_prime_field,20,30,1 },
228static const EC_CURVE_DATA _EC_X9_62_PRIME_239V3 = { 343 { 0x7D,0x73,0x74,0x16,0x8F,0xFE,0x34,0x71,0xB6,0x0A, /* seed */
229 NID_X9_62_prime_field, 344 0x85,0x76,0x86,0xA1,0x94,0x75,0xD3,0xBF,0xA2,0xFF,
230 "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFF", 345
231 "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFC", 346 0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* p */
232 "255705FA2A306654B1F4CB03D6A750A30C250102D4988717D9BA15AB6D3E", 347 0xFF,0xFF,0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0x80,0x00,
233 "6768AE8E18BB92CFCF005C949AA2C6D94853D0E660BBF854B1C9505FE95A", 348 0x00,0x00,0x00,0x00,0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,
234 "1607e6898f390c06bc1d552bad226f3b6fcfe48b6e818499af18e3ed6cf3", 349
235 "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFF975DEB41B3A6057C3C432146526551",1, 350 0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* a */
236 _EC_X9_62_PRIME_239V3_SEED, 20, 351 0xFF,0xFF,0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0x80,0x00,
237 "X9.62 curve over a 239 bit prime field" 352 0x00,0x00,0x00,0x00,0x7F,0xFF,0xFF,0xFF,0xFF,0xFC,
353
354 0x25,0x57,0x05,0xFA,0x2A,0x30,0x66,0x54,0xB1,0xF4, /* b */
355 0xCB,0x03,0xD6,0xA7,0x50,0xA3,0x0C,0x25,0x01,0x02,
356 0xD4,0x98,0x87,0x17,0xD9,0xBA,0x15,0xAB,0x6D,0x3E,
357
358 0x67,0x68,0xAE,0x8E,0x18,0xBB,0x92,0xCF,0xCF,0x00, /* x */
359 0x5C,0x94,0x9A,0xA2,0xC6,0xD9,0x48,0x53,0xD0,0xE6,
360 0x60,0xBB,0xF8,0x54,0xB1,0xC9,0x50,0x5F,0xE9,0x5A,
361
362 0x16,0x07,0xe6,0x89,0x8f,0x39,0x0c,0x06,0xbc,0x1d, /* y */
363 0x55,0x2b,0xad,0x22,0x6f,0x3b,0x6f,0xcf,0xe4,0x8b,
364 0x6e,0x81,0x84,0x99,0xaf,0x18,0xe3,0xed,0x6c,0xf3,
365
366 0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* order */
367 0xFF,0xFF,0x7F,0xFF,0xFF,0x97,0x5D,0xEB,0x41,0xB3,
368 0xA6,0x05,0x7C,0x3C,0x43,0x21,0x46,0x52,0x65,0x51 }
238 }; 369 };
239 370
240static const unsigned char _EC_X9_62_PRIME_256V1_SEED[] = { 371
241 0xC4,0x9D,0x36,0x08,0x86,0xE7,0x04,0x93,0x6A,0x66, 372static const struct { EC_CURVE_DATA h; unsigned char data[20+32*6]; }
242 0x78,0xE1,0x13,0x9D,0x26,0xB7,0x81,0x9F,0x7E,0x90}; 373 _EC_X9_62_PRIME_256V1 = {
243static const EC_CURVE_DATA _EC_X9_62_PRIME_256V1 = { 374 { NID_X9_62_prime_field,20,32,1 },
244 NID_X9_62_prime_field, 375 { 0xC4,0x9D,0x36,0x08,0x86,0xE7,0x04,0x93,0x6A,0x66, /* seed */
245 "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF", 376 0x78,0xE1,0x13,0x9D,0x26,0xB7,0x81,0x9F,0x7E,0x90,
246 "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC", 377
247 "5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B", 378 0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x01,0x00,0x00, /* p */
248 "6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296", 379 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
249 "4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5", 380 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
250 "FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551",1, 381 0xFF,0xFF,
251 _EC_X9_62_PRIME_256V1_SEED, 20, 382 0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x01,0x00,0x00, /* a */
252 "X9.62/SECG curve over a 256 bit prime field" 383 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
384 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
385 0xFF,0xFC,
386 0x5A,0xC6,0x35,0xD8,0xAA,0x3A,0x93,0xE7,0xB3,0xEB, /* b */
387 0xBD,0x55,0x76,0x98,0x86,0xBC,0x65,0x1D,0x06,0xB0,
388 0xCC,0x53,0xB0,0xF6,0x3B,0xCE,0x3C,0x3E,0x27,0xD2,
389 0x60,0x4B,
390 0x6B,0x17,0xD1,0xF2,0xE1,0x2C,0x42,0x47,0xF8,0xBC, /* x */
391 0xE6,0xE5,0x63,0xA4,0x40,0xF2,0x77,0x03,0x7D,0x81,
392 0x2D,0xEB,0x33,0xA0,0xF4,0xA1,0x39,0x45,0xD8,0x98,
393 0xC2,0x96,
394 0x4f,0xe3,0x42,0xe2,0xfe,0x1a,0x7f,0x9b,0x8e,0xe7, /* y */
395 0xeb,0x4a,0x7c,0x0f,0x9e,0x16,0x2b,0xce,0x33,0x57,
396 0x6b,0x31,0x5e,0xce,0xcb,0xb6,0x40,0x68,0x37,0xbf,
397 0x51,0xf5,
398 0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0xFF,0xFF, /* order */
399 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xBC,0xE6,0xFA,0xAD,
400 0xA7,0x17,0x9E,0x84,0xF3,0xB9,0xCA,0xC2,0xFC,0x63,
401 0x25,0x51 }
253 }; 402 };
403
254/* the secg prime curves (minus the nist and x9.62 prime curves) */ 404/* the secg prime curves (minus the nist and x9.62 prime curves) */
255static const unsigned char _EC_SECG_PRIME_112R1_SEED[] = { 405static const struct { EC_CURVE_DATA h; unsigned char data[20+14*6]; }
256 0x00,0xF5,0x0B,0x02,0x8E,0x4D,0x69,0x6E,0x67,0x68, 406 _EC_SECG_PRIME_112R1 = {
257 0x75,0x61,0x51,0x75,0x29,0x04,0x72,0x78,0x3F,0xB1}; 407 { NID_X9_62_prime_field,20,14,1 },
258static const EC_CURVE_DATA _EC_SECG_PRIME_112R1 = { 408 { 0x00,0xF5,0x0B,0x02,0x8E,0x4D,0x69,0x6E,0x67,0x68, /* seed */
259 NID_X9_62_prime_field, 409 0x75,0x61,0x51,0x75,0x29,0x04,0x72,0x78,0x3F,0xB1,
260 "DB7C2ABF62E35E668076BEAD208B", 410
261 "DB7C2ABF62E35E668076BEAD2088", 411 0xDB,0x7C,0x2A,0xBF,0x62,0xE3,0x5E,0x66,0x80,0x76, /* p */
262 "659EF8BA043916EEDE8911702B22", 412 0xBE,0xAD,0x20,0x8B,
263 "09487239995A5EE76B55F9C2F098", 413 0xDB,0x7C,0x2A,0xBF,0x62,0xE3,0x5E,0x66,0x80,0x76, /* a */
264 "a89ce5af8724c0a23e0e0ff77500", 414 0xBE,0xAD,0x20,0x88,
265 "DB7C2ABF62E35E7628DFAC6561C5",1, 415 0x65,0x9E,0xF8,0xBA,0x04,0x39,0x16,0xEE,0xDE,0x89, /* b */
266 _EC_SECG_PRIME_112R1_SEED, 20, 416 0x11,0x70,0x2B,0x22,
267 "SECG/WTLS curve over a 112 bit prime field" 417 0x09,0x48,0x72,0x39,0x99,0x5A,0x5E,0xE7,0x6B,0x55, /* x */
418 0xF9,0xC2,0xF0,0x98,
419 0xa8,0x9c,0xe5,0xaf,0x87,0x24,0xc0,0xa2,0x3e,0x0e, /* y */
420 0x0f,0xf7,0x75,0x00,
421 0xDB,0x7C,0x2A,0xBF,0x62,0xE3,0x5E,0x76,0x28,0xDF, /* order */
422 0xAC,0x65,0x61,0xC5 }
268 }; 423 };
269 424
270static const unsigned char _EC_SECG_PRIME_112R2_SEED[] = { 425static const struct { EC_CURVE_DATA h; unsigned char data[20+14*6]; }
271 0x00,0x27,0x57,0xA1,0x11,0x4D,0x69,0x6E,0x67,0x68, 426 _EC_SECG_PRIME_112R2 = {
272 0x75,0x61,0x51,0x75,0x53,0x16,0xC0,0x5E,0x0B,0xD4}; 427 { NID_X9_62_prime_field,20,14,4 },
273static const EC_CURVE_DATA _EC_SECG_PRIME_112R2 = { 428 { 0x00,0x27,0x57,0xA1,0x11,0x4D,0x69,0x6E,0x67,0x68, /* seed */
274 NID_X9_62_prime_field, 429 0x75,0x61,0x51,0x75,0x53,0x16,0xC0,0x5E,0x0B,0xD4,
275 "DB7C2ABF62E35E668076BEAD208B", 430
276 "6127C24C05F38A0AAAF65C0EF02C", 431 0xDB,0x7C,0x2A,0xBF,0x62,0xE3,0x5E,0x66,0x80,0x76, /* p */
277 "51DEF1815DB5ED74FCC34C85D709", 432 0xBE,0xAD,0x20,0x8B,
278 "4BA30AB5E892B4E1649DD0928643", 433 0x61,0x27,0xC2,0x4C,0x05,0xF3,0x8A,0x0A,0xAA,0xF6, /* a */
279 "adcd46f5882e3747def36e956e97", 434 0x5C,0x0E,0xF0,0x2C,
280 "36DF0AAFD8B8D7597CA10520D04B",4, 435 0x51,0xDE,0xF1,0x81,0x5D,0xB5,0xED,0x74,0xFC,0xC3, /* b */
281 _EC_SECG_PRIME_112R2_SEED, 20, 436 0x4C,0x85,0xD7,0x09,
282 "SECG curve over a 112 bit prime field" 437 0x4B,0xA3,0x0A,0xB5,0xE8,0x92,0xB4,0xE1,0x64,0x9D, /* x */
438 0xD0,0x92,0x86,0x43,
439 0xad,0xcd,0x46,0xf5,0x88,0x2e,0x37,0x47,0xde,0xf3, /* y */
440 0x6e,0x95,0x6e,0x97,
441 0x36,0xDF,0x0A,0xAF,0xD8,0xB8,0xD7,0x59,0x7C,0xA1, /* order */
442 0x05,0x20,0xD0,0x4B }
283 }; 443 };
284 444
285static const unsigned char _EC_SECG_PRIME_128R1_SEED[] = { 445static const struct { EC_CURVE_DATA h; unsigned char data[20+16*6]; }
286 0x00,0x0E,0x0D,0x4D,0x69,0x6E,0x67,0x68,0x75,0x61, 446 _EC_SECG_PRIME_128R1 = {
287 0x51,0x75,0x0C,0xC0,0x3A,0x44,0x73,0xD0,0x36,0x79}; 447 { NID_X9_62_prime_field,20,16,1 },
288static const EC_CURVE_DATA _EC_SECG_PRIME_128R1 = { 448 { 0x00,0x0E,0x0D,0x4D,0x69,0x6E,0x67,0x68,0x75,0x61, /* seed */
289 NID_X9_62_prime_field, 449 0x51,0x75,0x0C,0xC0,0x3A,0x44,0x73,0xD0,0x36,0x79,
290 "FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFF", 450
291 "FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFC", 451 0xFF,0xFF,0xFF,0xFD,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* p */
292 "E87579C11079F43DD824993C2CEE5ED3", 452 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
293 "161FF7528B899B2D0C28607CA52C5B86", 453 0xFF,0xFF,0xFF,0xFD,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* a */
294 "cf5ac8395bafeb13c02da292dded7a83", 454 0xFF,0xFF,0xFF,0xFF,0xFF,0xFC,
295 "FFFFFFFE0000000075A30D1B9038A115",1, 455 0xE8,0x75,0x79,0xC1,0x10,0x79,0xF4,0x3D,0xD8,0x24, /* b */
296 _EC_SECG_PRIME_128R1_SEED, 20, 456 0x99,0x3C,0x2C,0xEE,0x5E,0xD3,
297 "SECG curve over a 128 bit prime field" 457 0x16,0x1F,0xF7,0x52,0x8B,0x89,0x9B,0x2D,0x0C,0x28, /* x */
458 0x60,0x7C,0xA5,0x2C,0x5B,0x86,
459 0xcf,0x5a,0xc8,0x39,0x5b,0xaf,0xeb,0x13,0xc0,0x2d, /* y */
460 0xa2,0x92,0xdd,0xed,0x7a,0x83,
461 0xFF,0xFF,0xFF,0xFE,0x00,0x00,0x00,0x00,0x75,0xA3, /* order */
462 0x0D,0x1B,0x90,0x38,0xA1,0x15 }
298 }; 463 };
299 464
300static const unsigned char _EC_SECG_PRIME_128R2_SEED[] = { 465static const struct { EC_CURVE_DATA h; unsigned char data[20+16*6]; }
301 0x00,0x4D,0x69,0x6E,0x67,0x68,0x75,0x61,0x51,0x75, 466 _EC_SECG_PRIME_128R2 = {
302 0x12,0xD8,0xF0,0x34,0x31,0xFC,0xE6,0x3B,0x88,0xF4}; 467 { NID_X9_62_prime_field,20,16,4 },
303static const EC_CURVE_DATA _EC_SECG_PRIME_128R2 = { 468 { 0x00,0x4D,0x69,0x6E,0x67,0x68,0x75,0x61,0x51,0x75, /* seed */
304 NID_X9_62_prime_field, 469 0x12,0xD8,0xF0,0x34,0x31,0xFC,0xE6,0x3B,0x88,0xF4,
305 "FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFF", 470
306 "D6031998D1B3BBFEBF59CC9BBFF9AEE1", 471 0xFF,0xFF,0xFF,0xFD,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* p */
307 "5EEEFCA380D02919DC2C6558BB6D8A5D", 472 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
308 "7B6AA5D85E572983E6FB32A7CDEBC140", 473 0xD6,0x03,0x19,0x98,0xD1,0xB3,0xBB,0xFE,0xBF,0x59, /* a */
309 "27b6916a894d3aee7106fe805fc34b44", 474 0xCC,0x9B,0xBF,0xF9,0xAE,0xE1,
310 "3FFFFFFF7FFFFFFFBE0024720613B5A3",4, 475 0x5E,0xEE,0xFC,0xA3,0x80,0xD0,0x29,0x19,0xDC,0x2C, /* b */
311 _EC_SECG_PRIME_128R2_SEED, 20, 476 0x65,0x58,0xBB,0x6D,0x8A,0x5D,
312 "SECG curve over a 128 bit prime field" 477 0x7B,0x6A,0xA5,0xD8,0x5E,0x57,0x29,0x83,0xE6,0xFB, /* x */
478 0x32,0xA7,0xCD,0xEB,0xC1,0x40,
479 0x27,0xb6,0x91,0x6a,0x89,0x4d,0x3a,0xee,0x71,0x06, /* y */
480 0xfe,0x80,0x5f,0xc3,0x4b,0x44,
481 0x3F,0xFF,0xFF,0xFF,0x7F,0xFF,0xFF,0xFF,0xBE,0x00, /* order */
482 0x24,0x72,0x06,0x13,0xB5,0xA3 }
313 }; 483 };
314 484
315static const EC_CURVE_DATA _EC_SECG_PRIME_160K1 = { 485static const struct { EC_CURVE_DATA h; unsigned char data[0+21*6]; }
316 NID_X9_62_prime_field, 486 _EC_SECG_PRIME_160K1 = {
317 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC73", 487 { NID_X9_62_prime_field,0,21,1 },
318 "0", 488 { /* no seed */
319 "7", 489 0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* p */
320 "3B4C382CE37AA192A4019E763036F4F5DD4D7EBB", 490 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xAC,
321 "938cf935318fdced6bc28286531733c3f03c4fee", 491 0x73,
322 "0100000000000000000001B8FA16DFAB9ACA16B6B3",1, 492 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* a */
323 NULL, 0, 493 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
324 "SECG curve over a 160 bit prime field" 494 0x00,
495 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* b */
496 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
497 0x07,
498 0x00,0x3B,0x4C,0x38,0x2C,0xE3,0x7A,0xA1,0x92,0xA4, /* x */
499 0x01,0x9E,0x76,0x30,0x36,0xF4,0xF5,0xDD,0x4D,0x7E,
500 0xBB,
501 0x00,0x93,0x8c,0xf9,0x35,0x31,0x8f,0xdc,0xed,0x6b, /* y */
502 0xc2,0x82,0x86,0x53,0x17,0x33,0xc3,0xf0,0x3c,0x4f,
503 0xee,
504 0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* order */
505 0x01,0xB8,0xFA,0x16,0xDF,0xAB,0x9A,0xCA,0x16,0xB6,
506 0xB3 }
325 }; 507 };
326 508
327static const unsigned char _EC_SECG_PRIME_160R1_SEED[] = { 509static const struct { EC_CURVE_DATA h; unsigned char data[20+21*6]; }
328 0x10,0x53,0xCD,0xE4,0x2C,0x14,0xD6,0x96,0xE6,0x76, 510 _EC_SECG_PRIME_160R1 = {
329 0x87,0x56,0x15,0x17,0x53,0x3B,0xF3,0xF8,0x33,0x45}; 511 { NID_X9_62_prime_field,20,21,1 },
330static const EC_CURVE_DATA _EC_SECG_PRIME_160R1 = { 512 { 0x10,0x53,0xCD,0xE4,0x2C,0x14,0xD6,0x96,0xE6,0x76, /* seed */
331 NID_X9_62_prime_field, 513 0x87,0x56,0x15,0x17,0x53,0x3B,0xF3,0xF8,0x33,0x45,
332 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFF", 514
333 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFC", 515 0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* p */
334 "1C97BEFC54BD7A8B65ACF89F81D4D4ADC565FA45", 516 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x7F,0xFF,0xFF,
335 "4A96B5688EF573284664698968C38BB913CBFC82", 517 0xFF,
336 "23a628553168947d59dcc912042351377ac5fb32", 518 0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* a */
337 "0100000000000000000001F4C8F927AED3CA752257",1, 519 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x7F,0xFF,0xFF,
338 _EC_SECG_PRIME_160R1_SEED, 20, 520 0xFC,
339 "SECG curve over a 160 bit prime field" 521 0x00,0x1C,0x97,0xBE,0xFC,0x54,0xBD,0x7A,0x8B,0x65, /* b */
522 0xAC,0xF8,0x9F,0x81,0xD4,0xD4,0xAD,0xC5,0x65,0xFA,
523 0x45,
524 0x00,0x4A,0x96,0xB5,0x68,0x8E,0xF5,0x73,0x28,0x46, /* x */
525 0x64,0x69,0x89,0x68,0xC3,0x8B,0xB9,0x13,0xCB,0xFC,
526 0x82,
527 0x00,0x23,0xa6,0x28,0x55,0x31,0x68,0x94,0x7d,0x59, /* y */
528 0xdc,0xc9,0x12,0x04,0x23,0x51,0x37,0x7a,0xc5,0xfb,
529 0x32,
530 0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* order */
531 0x01,0xF4,0xC8,0xF9,0x27,0xAE,0xD3,0xCA,0x75,0x22,
532 0x57 }
340 }; 533 };
341 534
342static const unsigned char _EC_SECG_PRIME_160R2_SEED[] = { 535static const struct { EC_CURVE_DATA h; unsigned char data[20+21*6]; }
343 0xB9,0x9B,0x99,0xB0,0x99,0xB3,0x23,0xE0,0x27,0x09, 536 _EC_SECG_PRIME_160R2 = {
344 0xA4,0xD6,0x96,0xE6,0x76,0x87,0x56,0x15,0x17,0x51}; 537 { NID_X9_62_prime_field,20,21,1 },
345static const EC_CURVE_DATA _EC_SECG_PRIME_160R2 = { 538 { 0xB9,0x9B,0x99,0xB0,0x99,0xB3,0x23,0xE0,0x27,0x09, /* seed */
346 NID_X9_62_prime_field, 539 0xA4,0xD6,0x96,0xE6,0x76,0x87,0x56,0x15,0x17,0x51,
347 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC73", 540
348 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC70", 541 0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* p */
349 "B4E134D3FB59EB8BAB57274904664D5AF50388BA", 542 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xAC,
350 "52DCB034293A117E1F4FF11B30F7199D3144CE6D", 543 0x73,
351 "feaffef2e331f296e071fa0df9982cfea7d43f2e", 544 0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* a */
352 "0100000000000000000000351EE786A818F3A1A16B",1, 545 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xAC,
353 _EC_SECG_PRIME_160R2_SEED, 20, 546 0x70,
354 "SECG/WTLS curve over a 160 bit prime field" 547 0x00,0xB4,0xE1,0x34,0xD3,0xFB,0x59,0xEB,0x8B,0xAB, /* b */
548 0x57,0x27,0x49,0x04,0x66,0x4D,0x5A,0xF5,0x03,0x88,
549 0xBA,
550 0x00,0x52,0xDC,0xB0,0x34,0x29,0x3A,0x11,0x7E,0x1F, /* x */
551 0x4F,0xF1,0x1B,0x30,0xF7,0x19,0x9D,0x31,0x44,0xCE,
552 0x6D,
553 0x00,0xfe,0xaf,0xfe,0xf2,0xe3,0x31,0xf2,0x96,0xe0, /* y */
554 0x71,0xfa,0x0d,0xf9,0x98,0x2c,0xfe,0xa7,0xd4,0x3f,
555 0x2e,
556 0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* order */
557 0x00,0x35,0x1E,0xE7,0x86,0xA8,0x18,0xF3,0xA1,0xA1,
558 0x6B }
355 }; 559 };
356 560
357static const EC_CURVE_DATA _EC_SECG_PRIME_192K1 = { 561static const struct { EC_CURVE_DATA h; unsigned char data[0+24*6]; }
358 NID_X9_62_prime_field, 562 _EC_SECG_PRIME_192K1 = {
359 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFEE37", 563 { NID_X9_62_prime_field,0,24,1 },
360 "0", 564 { /* no seed */
361 "3", 565 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* p */
362 "DB4FF10EC057E9AE26B07D0280B7F4341DA5D1B1EAE06C7D", 566 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,
363 "9b2f2f6d9c5628a7844163d015be86344082aa88d95e2f9d", 567 0xFF,0xFF,0xEE,0x37,
364 "FFFFFFFFFFFFFFFFFFFFFFFE26F2FC170F69466A74DEFD8D",1, 568 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* a */
365 NULL, 20, 569 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
366 "SECG curve over a 192 bit prime field" 570 0x00,0x00,0x00,0x00,
571 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* b */
572 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
573 0x00,0x00,0x00,0x03,
574 0xDB,0x4F,0xF1,0x0E,0xC0,0x57,0xE9,0xAE,0x26,0xB0, /* x */
575 0x7D,0x02,0x80,0xB7,0xF4,0x34,0x1D,0xA5,0xD1,0xB1,
576 0xEA,0xE0,0x6C,0x7D,
577 0x9b,0x2f,0x2f,0x6d,0x9c,0x56,0x28,0xa7,0x84,0x41, /* y */
578 0x63,0xd0,0x15,0xbe,0x86,0x34,0x40,0x82,0xaa,0x88,
579 0xd9,0x5e,0x2f,0x9d,
580 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* order */
581 0xFF,0xFE,0x26,0xF2,0xFC,0x17,0x0F,0x69,0x46,0x6A,
582 0x74,0xDE,0xFD,0x8D }
367 }; 583 };
368 584
369static const EC_CURVE_DATA _EC_SECG_PRIME_224K1 = { 585static const struct { EC_CURVE_DATA h; unsigned char data[0+29*6]; }
370 NID_X9_62_prime_field, 586 _EC_SECG_PRIME_224K1 = {
371 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFE56D", 587 { NID_X9_62_prime_field,0,29,1 },
372 "0", 588 { /* no seed */
373 "5", 589 0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* p */
374 "A1455B334DF099DF30FC28A169A467E9E47075A90F7E650EB6B7A45C", 590 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
375 "7e089fed7fba344282cafbd6f7e319f7c0b0bd59e2ca4bdb556d61a5", 591 0xFF,0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xE5,0x6D,
376 "010000000000000000000000000001DCE8D2EC6184CAF0A971769FB1F7",1, 592 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* a */
377 NULL, 20, 593 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
378 "SECG curve over a 224 bit prime field" 594 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
595 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* b */
596 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
597 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x05,
598 0x00,0xA1,0x45,0x5B,0x33,0x4D,0xF0,0x99,0xDF,0x30, /* x */
599 0xFC,0x28,0xA1,0x69,0xA4,0x67,0xE9,0xE4,0x70,0x75,
600 0xA9,0x0F,0x7E,0x65,0x0E,0xB6,0xB7,0xA4,0x5C,
601 0x00,0x7e,0x08,0x9f,0xed,0x7f,0xba,0x34,0x42,0x82, /* y */
602 0xca,0xfb,0xd6,0xf7,0xe3,0x19,0xf7,0xc0,0xb0,0xbd,
603 0x59,0xe2,0xca,0x4b,0xdb,0x55,0x6d,0x61,0xa5,
604 0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* order */
605 0x00,0x00,0x00,0x00,0x01,0xDC,0xE8,0xD2,0xEC,0x61,
606 0x84,0xCA,0xF0,0xA9,0x71,0x76,0x9F,0xB1,0xF7 }
379 }; 607 };
380 608
381static const EC_CURVE_DATA _EC_SECG_PRIME_256K1 = { 609static const struct { EC_CURVE_DATA h; unsigned char data[0+32*6]; }
382 NID_X9_62_prime_field, 610 _EC_SECG_PRIME_256K1 = {
383 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F", 611 { NID_X9_62_prime_field,0,32,1 },
384 "0", 612 { /* no seed */
385 "7", 613 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* p */
386 "79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798", 614 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
387 "483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8", 615 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,
388 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141",1, 616 0xFC,0x2F,
389 NULL, 20, 617 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* a */
390 "SECG curve over a 256 bit prime field" 618 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
619 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
620 0x00,0x00,
621 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* b */
622 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
623 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
624 0x00,0x07,
625 0x79,0xBE,0x66,0x7E,0xF9,0xDC,0xBB,0xAC,0x55,0xA0, /* x */
626 0x62,0x95,0xCE,0x87,0x0B,0x07,0x02,0x9B,0xFC,0xDB,
627 0x2D,0xCE,0x28,0xD9,0x59,0xF2,0x81,0x5B,0x16,0xF8,
628 0x17,0x98,
629 0x48,0x3a,0xda,0x77,0x26,0xa3,0xc4,0x65,0x5d,0xa4, /* y */
630 0xfb,0xfc,0x0e,0x11,0x08,0xa8,0xfd,0x17,0xb4,0x48,
631 0xa6,0x85,0x54,0x19,0x9c,0x47,0xd0,0x8f,0xfb,0x10,
632 0xd4,0xb8,
633 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* order */
634 0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0xBA,0xAE,0xDC,0xE6,
635 0xAF,0x48,0xA0,0x3B,0xBF,0xD2,0x5E,0x8C,0xD0,0x36,
636 0x41,0x41 }
391 }; 637 };
392 638
393/* some wap/wtls curves */ 639/* some wap/wtls curves */
394static const EC_CURVE_DATA _EC_WTLS_8 = { 640static const struct { EC_CURVE_DATA h; unsigned char data[0+15*6]; }
395 NID_X9_62_prime_field, 641 _EC_WTLS_8 = {
396 "FFFFFFFFFFFFFFFFFFFFFFFFFDE7", 642 { NID_X9_62_prime_field,0,15,1 },
397 "0", 643 { /* no seed */
398 "3", 644 0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* p */
399 "1", 645 0xFF,0xFF,0xFF,0xFD,0xE7,
400 "2", 646 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* a */
401 "0100000000000001ECEA551AD837E9",1, 647 0x00,0x00,0x00,0x00,0x00,
402 NULL, 20, 648 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* b */
403 "WTLS curve over a 112 bit prime field" 649 0x00,0x00,0x00,0x00,0x03,
650 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* x */
651 0x00,0x00,0x00,0x00,0x01,
652 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* y */
653 0x00,0x00,0x00,0x00,0x02,
654 0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0xEC,0xEA, /* order */
655 0x55,0x1A,0xD8,0x37,0xE9 }
404 }; 656 };
405 657
406static const EC_CURVE_DATA _EC_WTLS_9 = { 658static const struct { EC_CURVE_DATA h; unsigned char data[0+21*6]; }
407 NID_X9_62_prime_field, 659 _EC_WTLS_9 = {
408 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC808F", 660 { NID_X9_62_prime_field,0,21,1 },
409 "0", 661 { /* no seed */
410 "3", 662 0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* p */
411 "1", 663 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFC,0x80,
412 "2", 664 0x8F,
413 "0100000000000000000001CDC98AE0E2DE574ABF33",1, 665 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* a */
414 NULL, 20, 666 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
415 "WTLS curve over a 160 bit prime field" 667 0x00,
668 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* b */
669 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
670 0x03,
671 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* x */
672 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
673 0x01,
674 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* y */
675 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
676 0x02,
677 0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* order */
678 0x01,0xCD,0xC9,0x8A,0xE0,0xE2,0xDE,0x57,0x4A,0xBF,
679 0x33 }
416 }; 680 };
417 681
418static const EC_CURVE_DATA _EC_WTLS_12 = { 682static const struct { EC_CURVE_DATA h; unsigned char data[0+28*6]; }
419 NID_X9_62_prime_field, 683 _EC_WTLS_12 = {
420 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001", 684 { NID_X9_62_prime_field,0,28,1 },
421 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFE", 685 { /* no seed */
422 "B4050A850C04B3ABF54132565044B0B7D7BFD8BA270B39432355FFB4", 686 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* p */
423 "B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21", 687 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,
424 "bd376388b5f723fb4c22dfe6cd4375a05a07476444d5819985007e34", 688 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,
425 "FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D", 1, 689 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* a */
426 NULL, 0, 690 0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xFF,0xFF,
427 "WTLS curvs over a 224 bit prime field" 691 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,
692 0xB4,0x05,0x0A,0x85,0x0C,0x04,0xB3,0xAB,0xF5,0x41, /* b */
693 0x32,0x56,0x50,0x44,0xB0,0xB7,0xD7,0xBF,0xD8,0xBA,
694 0x27,0x0B,0x39,0x43,0x23,0x55,0xFF,0xB4,
695 0xB7,0x0E,0x0C,0xBD,0x6B,0xB4,0xBF,0x7F,0x32,0x13, /* x */
696 0x90,0xB9,0x4A,0x03,0xC1,0xD3,0x56,0xC2,0x11,0x22,
697 0x34,0x32,0x80,0xD6,0x11,0x5C,0x1D,0x21,
698 0xbd,0x37,0x63,0x88,0xb5,0xf7,0x23,0xfb,0x4c,0x22, /* y */
699 0xdf,0xe6,0xcd,0x43,0x75,0xa0,0x5a,0x07,0x47,0x64,
700 0x44,0xd5,0x81,0x99,0x85,0x00,0x7e,0x34,
701 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* order */
702 0xFF,0xFF,0xFF,0xFF,0x16,0xA2,0xE0,0xB8,0xF0,0x3E,
703 0x13,0xDD,0x29,0x45,0x5C,0x5C,0x2A,0x3D }
428 }; 704 };
429 705
430/* characteristic two curves */ 706/* characteristic two curves */
431static const unsigned char _EC_SECG_CHAR2_113R1_SEED[] = { 707static const struct { EC_CURVE_DATA h; unsigned char data[20+15*6]; }
432 0x10,0xE7,0x23,0xAB,0x14,0xD6,0x96,0xE6,0x76,0x87, 708 _EC_SECG_CHAR2_113R1 = {
433 0x56,0x15,0x17,0x56,0xFE,0xBF,0x8F,0xCB,0x49,0xA9}; 709 { NID_X9_62_characteristic_two_field,20,15,2 },
434static const EC_CURVE_DATA _EC_SECG_CHAR2_113R1 = { 710 { 0x10,0xE7,0x23,0xAB,0x14,0xD6,0x96,0xE6,0x76,0x87, /* seed */
435 NID_X9_62_characteristic_two_field, 711 0x56,0x15,0x17,0x56,0xFE,0xBF,0x8F,0xCB,0x49,0xA9,
436 "020000000000000000000000000201", 712
437 "003088250CA6E7C7FE649CE85820F7", 713 0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* p */
438 "00E8BEE4D3E2260744188BE0E9C723", 714 0x00,0x00,0x00,0x02,0x01,
439 "009D73616F35F4AB1407D73562C10F", 715 0x00,0x30,0x88,0x25,0x0C,0xA6,0xE7,0xC7,0xFE,0x64, /* a */
440 "00A52830277958EE84D1315ED31886", 716 0x9C,0xE8,0x58,0x20,0xF7,
441 "0100000000000000D9CCEC8A39E56F", 2, 717 0x00,0xE8,0xBE,0xE4,0xD3,0xE2,0x26,0x07,0x44,0x18, /* b */
442 _EC_SECG_CHAR2_113R1_SEED, 20, 718 0x8B,0xE0,0xE9,0xC7,0x23,
443 "SECG curve over a 113 bit binary field" 719 0x00,0x9D,0x73,0x61,0x6F,0x35,0xF4,0xAB,0x14,0x07, /* x */
720 0xD7,0x35,0x62,0xC1,0x0F,
721 0x00,0xA5,0x28,0x30,0x27,0x79,0x58,0xEE,0x84,0xD1, /* y */
722 0x31,0x5E,0xD3,0x18,0x86,
723 0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xD9,0xCC, /* order */
724 0xEC,0x8A,0x39,0xE5,0x6F }
444 }; 725 };
445 726
446static const unsigned char _EC_SECG_CHAR2_113R2_SEED[] = { 727static const struct { EC_CURVE_DATA h; unsigned char data[20+15*6]; }
447 0x10,0xC0,0xFB,0x15,0x76,0x08,0x60,0xDE,0xF1,0xEE, 728 _EC_SECG_CHAR2_113R2 = {
448 0xF4,0xD6,0x96,0xE6,0x76,0x87,0x56,0x15,0x17,0x5D}; 729 { NID_X9_62_characteristic_two_field,20,15,2 },
449static const EC_CURVE_DATA _EC_SECG_CHAR2_113R2 = { 730 { 0x10,0xC0,0xFB,0x15,0x76,0x08,0x60,0xDE,0xF1,0xEE, /* seed */
450 NID_X9_62_characteristic_two_field, 731 0xF4,0xD6,0x96,0xE6,0x76,0x87,0x56,0x15,0x17,0x5D,
451 "020000000000000000000000000201", 732
452 "00689918DBEC7E5A0DD6DFC0AA55C7", 733 0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* p */
453 "0095E9A9EC9B297BD4BF36E059184F", 734 0x00,0x00,0x00,0x02,0x01,
454 "01A57A6A7B26CA5EF52FCDB8164797", 735 0x00,0x68,0x99,0x18,0xDB,0xEC,0x7E,0x5A,0x0D,0xD6, /* a */
455 "00B3ADC94ED1FE674C06E695BABA1D", 736 0xDF,0xC0,0xAA,0x55,0xC7,
456 "010000000000000108789B2496AF93", 2, 737 0x00,0x95,0xE9,0xA9,0xEC,0x9B,0x29,0x7B,0xD4,0xBF, /* b */
457 _EC_SECG_CHAR2_113R2_SEED, 20, 738 0x36,0xE0,0x59,0x18,0x4F,
458 "SECG curve over a 113 bit binary field" 739 0x01,0xA5,0x7A,0x6A,0x7B,0x26,0xCA,0x5E,0xF5,0x2F, /* x */
740 0xCD,0xB8,0x16,0x47,0x97,
741 0x00,0xB3,0xAD,0xC9,0x4E,0xD1,0xFE,0x67,0x4C,0x06, /* y */
742 0xE6,0x95,0xBA,0xBA,0x1D,
743 0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x08,0x78, /* order */
744 0x9B,0x24,0x96,0xAF,0x93 }
459 }; 745 };
460 746
461static const unsigned char _EC_SECG_CHAR2_131R1_SEED[] = { 747static const struct { EC_CURVE_DATA h; unsigned char data[20+17*6]; }
462 0x4D,0x69,0x6E,0x67,0x68,0x75,0x61,0x51,0x75,0x98, 748 _EC_SECG_CHAR2_131R1 = {
463 0x5B,0xD3,0xAD,0xBA,0xDA,0x21,0xB4,0x3A,0x97,0xE2}; 749 { NID_X9_62_characteristic_two_field,20,17,2 },
464static const EC_CURVE_DATA _EC_SECG_CHAR2_131R1 = { 750 { 0x4D,0x69,0x6E,0x67,0x68,0x75,0x61,0x51,0x75,0x98, /* seed */
465 NID_X9_62_characteristic_two_field, 751 0x5B,0xD3,0xAD,0xBA,0xDA,0x21,0xB4,0x3A,0x97,0xE2,
466 "080000000000000000000000000000010D", 752
467 "07A11B09A76B562144418FF3FF8C2570B8", 753 0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* p */
468 "0217C05610884B63B9C6C7291678F9D341", 754 0x00,0x00,0x00,0x00,0x00,0x01,0x0D,
469 "0081BAF91FDF9833C40F9C181343638399", 755 0x07,0xA1,0x1B,0x09,0xA7,0x6B,0x56,0x21,0x44,0x41, /* a */
470 "078C6E7EA38C001F73C8134B1B4EF9E150", 756 0x8F,0xF3,0xFF,0x8C,0x25,0x70,0xB8,
471 "0400000000000000023123953A9464B54D", 2, 757 0x02,0x17,0xC0,0x56,0x10,0x88,0x4B,0x63,0xB9,0xC6, /* b */
472 _EC_SECG_CHAR2_131R1_SEED, 20, 758 0xC7,0x29,0x16,0x78,0xF9,0xD3,0x41,
473 "SECG/WTLS curve over a 131 bit binary field" 759 0x00,0x81,0xBA,0xF9,0x1F,0xDF,0x98,0x33,0xC4,0x0F, /* x */
760 0x9C,0x18,0x13,0x43,0x63,0x83,0x99,
761 0x07,0x8C,0x6E,0x7E,0xA3,0x8C,0x00,0x1F,0x73,0xC8, /* y */
762 0x13,0x4B,0x1B,0x4E,0xF9,0xE1,0x50,
763 0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x31, /* order */
764 0x23,0x95,0x3A,0x94,0x64,0xB5,0x4D }
474 }; 765 };
475 766
476static const unsigned char _EC_SECG_CHAR2_131R2_SEED[] = { 767static const struct { EC_CURVE_DATA h; unsigned char data[20+17*6]; }
477 0x98,0x5B,0xD3,0xAD,0xBA,0xD4,0xD6,0x96,0xE6,0x76, 768 _EC_SECG_CHAR2_131R2 = {
478 0x87,0x56,0x15,0x17,0x5A,0x21,0xB4,0x3A,0x97,0xE3}; 769 { NID_X9_62_characteristic_two_field,20,17,2 },
479static const EC_CURVE_DATA _EC_SECG_CHAR2_131R2 = { 770 { 0x98,0x5B,0xD3,0xAD,0xBA,0xD4,0xD6,0x96,0xE6,0x76, /* seed */
480 NID_X9_62_characteristic_two_field, 771 0x87,0x56,0x15,0x17,0x5A,0x21,0xB4,0x3A,0x97,0xE3,
481 "080000000000000000000000000000010D", 772
482 "03E5A88919D7CAFCBF415F07C2176573B2", 773 0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* p */
483 "04B8266A46C55657AC734CE38F018F2192", 774 0x00,0x00,0x00,0x00,0x00,0x01,0x0D,
484 "0356DCD8F2F95031AD652D23951BB366A8", 775 0x03,0xE5,0xA8,0x89,0x19,0xD7,0xCA,0xFC,0xBF,0x41, /* a */
485 "0648F06D867940A5366D9E265DE9EB240F", 776 0x5F,0x07,0xC2,0x17,0x65,0x73,0xB2,
486 "0400000000000000016954A233049BA98F", 2, 777 0x04,0xB8,0x26,0x6A,0x46,0xC5,0x56,0x57,0xAC,0x73, /* b */
487 _EC_SECG_CHAR2_131R2_SEED, 20, 778 0x4C,0xE3,0x8F,0x01,0x8F,0x21,0x92,
488 "SECG curve over a 131 bit binary field" 779 0x03,0x56,0xDC,0xD8,0xF2,0xF9,0x50,0x31,0xAD,0x65, /* x */
780 0x2D,0x23,0x95,0x1B,0xB3,0x66,0xA8,
781 0x06,0x48,0xF0,0x6D,0x86,0x79,0x40,0xA5,0x36,0x6D, /* y */
782 0x9E,0x26,0x5D,0xE9,0xEB,0x24,0x0F,
783 0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x69, /* order */
784 0x54,0xA2,0x33,0x04,0x9B,0xA9,0x8F }
489 }; 785 };
490 786
491static const EC_CURVE_DATA _EC_NIST_CHAR2_163K = { 787static const struct { EC_CURVE_DATA h; unsigned char data[0+21*6]; }
492 NID_X9_62_characteristic_two_field, 788 _EC_NIST_CHAR2_163K = {
493 "0800000000000000000000000000000000000000C9", 789 { NID_X9_62_characteristic_two_field,0,21,2 },
494 "1", 790 { /* no seed */
495 "1", 791 0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* p */
496 "02FE13C0537BBC11ACAA07D793DE4E6D5E5C94EEE8", 792 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
497 "0289070FB05D38FF58321F2E800536D538CCDAA3D9", 793 0xC9,
498 "04000000000000000000020108A2E0CC0D99F8A5EF", 2, 794 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* a */
499 NULL, 0, 795 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
500 "NIST/SECG/WTLS curve over a 163 bit binary field" 796 0x01,
797 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* b */
798 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
799 0x01,
800 0x02,0xFE,0x13,0xC0,0x53,0x7B,0xBC,0x11,0xAC,0xAA, /* x */
801 0x07,0xD7,0x93,0xDE,0x4E,0x6D,0x5E,0x5C,0x94,0xEE,
802 0xE8,
803 0x02,0x89,0x07,0x0F,0xB0,0x5D,0x38,0xFF,0x58,0x32, /* y */
804 0x1F,0x2E,0x80,0x05,0x36,0xD5,0x38,0xCC,0xDA,0xA3,
805 0xD9,
806 0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* order */
807 0x02,0x01,0x08,0xA2,0xE0,0xCC,0x0D,0x99,0xF8,0xA5,
808 0xEF }
501 }; 809 };
502 810
503static const unsigned char _EC_SECG_CHAR2_163R1_SEED[] = { 811static const struct { EC_CURVE_DATA h; unsigned char data[0+21*6]; }
504 0x24,0xB7,0xB1,0x37,0xC8,0xA1,0x4D,0x69,0x6E,0x67, 812 _EC_SECG_CHAR2_163R1 = {
505 0x68,0x75,0x61,0x51,0x75,0x6F,0xD0,0xDA,0x2E,0x5C}; 813 { NID_X9_62_characteristic_two_field,0,21,2 },
506static const EC_CURVE_DATA _EC_SECG_CHAR2_163R1 = { 814 { /* no seed */
507 NID_X9_62_characteristic_two_field, 815#if 0
508 "0800000000000000000000000000000000000000C9",
509 "07B6882CAAEFA84F9554FF8428BD88E246D2782AE2",
510 "0713612DCDDCB40AAB946BDA29CA91F73AF958AFD9",
511 "0369979697AB43897789566789567F787A7876A654",
512 "00435EDB42EFAFB2989D51FEFCE3C80988F41FF883",
513 "03FFFFFFFFFFFFFFFFFFFF48AAB689C29CA710279B", 2,
514/* The algorithm used to derive the curve parameters from 816/* The algorithm used to derive the curve parameters from
515 * the seed used here is slightly different than the 817 * the seed used here is slightly different than the
516 * algorithm described in X9.62 . 818 * algorithm described in X9.62 . */
517 */ 819 0x24,0xB7,0xB1,0x37,0xC8,0xA1,0x4D,0x69,0x6E,0x67,
518#if 0 820 0x68,0x75,0x61,0x51,0x75,0x6F,0xD0,0xDA,0x2E,0x5C,
519 _EC_SECG_CHAR2_163R1_SEED, 20,
520#else
521 NULL, 0,
522#endif 821#endif
523 "SECG curve over a 163 bit binary field" 822 0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* p */
823 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
824 0xC9,
825 0x07,0xB6,0x88,0x2C,0xAA,0xEF,0xA8,0x4F,0x95,0x54, /* a */
826 0xFF,0x84,0x28,0xBD,0x88,0xE2,0x46,0xD2,0x78,0x2A,
827 0xE2,
828 0x07,0x13,0x61,0x2D,0xCD,0xDC,0xB4,0x0A,0xAB,0x94, /* b */
829 0x6B,0xDA,0x29,0xCA,0x91,0xF7,0x3A,0xF9,0x58,0xAF,
830 0xD9,
831 0x03,0x69,0x97,0x96,0x97,0xAB,0x43,0x89,0x77,0x89, /* x */
832 0x56,0x67,0x89,0x56,0x7F,0x78,0x7A,0x78,0x76,0xA6,
833 0x54,
834 0x00,0x43,0x5E,0xDB,0x42,0xEF,0xAF,0xB2,0x98,0x9D, /* y */
835 0x51,0xFE,0xFC,0xE3,0xC8,0x09,0x88,0xF4,0x1F,0xF8,
836 0x83,
837 0x03,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* order */
838 0xFF,0x48,0xAA,0xB6,0x89,0xC2,0x9C,0xA7,0x10,0x27,
839 0x9B }
524 }; 840 };
525 841
526static const unsigned char _EC_NIST_CHAR2_163B_SEED[] = { 842static const struct { EC_CURVE_DATA h; unsigned char data[0+21*6]; }
527 0x85,0xE2,0x5B,0xFE,0x5C,0x86,0x22,0x6C,0xDB,0x12, 843 _EC_NIST_CHAR2_163B = {
528 0x01,0x6F,0x75,0x53,0xF9,0xD0,0xE6,0x93,0xA2,0x68}; 844 { NID_X9_62_characteristic_two_field,0,21,2 },
529static const EC_CURVE_DATA _EC_NIST_CHAR2_163B ={ 845 { /* no seed */
530 NID_X9_62_characteristic_two_field,
531 "0800000000000000000000000000000000000000C9",
532 "1",
533 "020A601907B8C953CA1481EB10512F78744A3205FD",
534 "03F0EBA16286A2D57EA0991168D4994637E8343E36",
535 "00D51FBC6C71A0094FA2CDD545B11C5C0C797324F1",
536 "040000000000000000000292FE77E70C12A4234C33", 2,
537/* The seed here was used to created the curve parameters in normal
538 * basis representation (and not the polynomial representation used here)
539 */
540#if 0 846#if 0
541 _EC_NIST_CHAR2_163B_SEED, 20, 847/* The seed here was used to created the curve parameters in normal
542#else 848 * basis representation (and not the polynomial representation used here) */
543 NULL, 0, 849 0x85,0xE2,0x5B,0xFE,0x5C,0x86,0x22,0x6C,0xDB,0x12,
850 0x01,0x6F,0x75,0x53,0xF9,0xD0,0xE6,0x93,0xA2,0x68,
544#endif 851#endif
545 "NIST/SECG curve over a 163 bit binary field" 852 0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* p */
853 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
854 0xC9,
855 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* a */
856 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
857 0x01,
858 0x02,0x0A,0x60,0x19,0x07,0xB8,0xC9,0x53,0xCA,0x14, /* b */
859 0x81,0xEB,0x10,0x51,0x2F,0x78,0x74,0x4A,0x32,0x05,
860 0xFD,
861 0x03,0xF0,0xEB,0xA1,0x62,0x86,0xA2,0xD5,0x7E,0xA0, /* x */
862 0x99,0x11,0x68,0xD4,0x99,0x46,0x37,0xE8,0x34,0x3E,
863 0x36,
864 0x00,0xD5,0x1F,0xBC,0x6C,0x71,0xA0,0x09,0x4F,0xA2, /* y */
865 0xCD,0xD5,0x45,0xB1,0x1C,0x5C,0x0C,0x79,0x73,0x24,
866 0xF1,
867 0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* order */
868 0x02,0x92,0xFE,0x77,0xE7,0x0C,0x12,0xA4,0x23,0x4C,
869 0x33 }
546 }; 870 };
547 871
548static const unsigned char _EC_SECG_CHAR2_193R1_SEED[] = { 872static const struct { EC_CURVE_DATA h; unsigned char data[20+25*6]; }
549 0x10,0x3F,0xAE,0xC7,0x4D,0x69,0x6E,0x67,0x68,0x75, 873 _EC_SECG_CHAR2_193R1 = {
550 0x61,0x51,0x75,0x77,0x7F,0xC5,0xB1,0x91,0xEF,0x30}; 874 { NID_X9_62_characteristic_two_field,20,25,2 },
551static const EC_CURVE_DATA _EC_SECG_CHAR2_193R1 = { 875 { 0x10,0x3F,0xAE,0xC7,0x4D,0x69,0x6E,0x67,0x68,0x75, /* seed */
552 NID_X9_62_characteristic_two_field, 876 0x61,0x51,0x75,0x77,0x7F,0xC5,0xB1,0x91,0xEF,0x30,
553 "02000000000000000000000000000000000000000000008001", 877
554 "0017858FEB7A98975169E171F77B4087DE098AC8A911DF7B01", 878 0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* p */
555 "00FDFB49BFE6C3A89FACADAA7A1E5BBC7CC1C2E5D831478814", 879 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
556 "01F481BC5F0FF84A74AD6CDF6FDEF4BF6179625372D8C0C5E1", 880 0x00,0x00,0x00,0x80,0x01,
557 "0025E399F2903712CCF3EA9E3A1AD17FB0B3201B6AF7CE1B05", 881 0x00,0x17,0x85,0x8F,0xEB,0x7A,0x98,0x97,0x51,0x69, /* a */
558 "01000000000000000000000000C7F34A778F443ACC920EBA49", 2, 882 0xE1,0x71,0xF7,0x7B,0x40,0x87,0xDE,0x09,0x8A,0xC8,
559 _EC_SECG_CHAR2_193R1_SEED, 20, 883 0xA9,0x11,0xDF,0x7B,0x01,
560 "SECG curve over a 193 bit binary field" 884 0x00,0xFD,0xFB,0x49,0xBF,0xE6,0xC3,0xA8,0x9F,0xAC, /* b */
885 0xAD,0xAA,0x7A,0x1E,0x5B,0xBC,0x7C,0xC1,0xC2,0xE5,
886 0xD8,0x31,0x47,0x88,0x14,
887 0x01,0xF4,0x81,0xBC,0x5F,0x0F,0xF8,0x4A,0x74,0xAD, /* x */
888 0x6C,0xDF,0x6F,0xDE,0xF4,0xBF,0x61,0x79,0x62,0x53,
889 0x72,0xD8,0xC0,0xC5,0xE1,
890 0x00,0x25,0xE3,0x99,0xF2,0x90,0x37,0x12,0xCC,0xF3, /* y */
891 0xEA,0x9E,0x3A,0x1A,0xD1,0x7F,0xB0,0xB3,0x20,0x1B,
892 0x6A,0xF7,0xCE,0x1B,0x05,
893 0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* order */
894 0x00,0x00,0x00,0xC7,0xF3,0x4A,0x77,0x8F,0x44,0x3A,
895 0xCC,0x92,0x0E,0xBA,0x49 }
561 }; 896 };
562 897
563static const unsigned char _EC_SECG_CHAR2_193R2_SEED[] = { 898static const struct { EC_CURVE_DATA h; unsigned char data[20+25*6]; }
564 0x10,0xB7,0xB4,0xD6,0x96,0xE6,0x76,0x87,0x56,0x15, 899 _EC_SECG_CHAR2_193R2 = {
565 0x17,0x51,0x37,0xC8,0xA1,0x6F,0xD0,0xDA,0x22,0x11}; 900 { NID_X9_62_characteristic_two_field,20,25,2 },
566static const EC_CURVE_DATA _EC_SECG_CHAR2_193R2 = { 901 { 0x10,0xB7,0xB4,0xD6,0x96,0xE6,0x76,0x87,0x56,0x15, /* seed */
567 NID_X9_62_characteristic_two_field, 902 0x17,0x51,0x37,0xC8,0xA1,0x6F,0xD0,0xDA,0x22,0x11,
568 "02000000000000000000000000000000000000000000008001", 903
569 "0163F35A5137C2CE3EA6ED8667190B0BC43ECD69977702709B", 904 0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* p */
570 "00C9BB9E8927D4D64C377E2AB2856A5B16E3EFB7F61D4316AE", 905 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
571 "00D9B67D192E0367C803F39E1A7E82CA14A651350AAE617E8F", 906 0x00,0x00,0x00,0x80,0x01,
572 "01CE94335607C304AC29E7DEFBD9CA01F596F927224CDECF6C", 907 0x01,0x63,0xF3,0x5A,0x51,0x37,0xC2,0xCE,0x3E,0xA6, /* a */
573 "010000000000000000000000015AAB561B005413CCD4EE99D5", 2, 908 0xED,0x86,0x67,0x19,0x0B,0x0B,0xC4,0x3E,0xCD,0x69,
574 _EC_SECG_CHAR2_193R2_SEED, 20, 909 0x97,0x77,0x02,0x70,0x9B,
575 "SECG curve over a 193 bit binary field" 910 0x00,0xC9,0xBB,0x9E,0x89,0x27,0xD4,0xD6,0x4C,0x37, /* b */
911 0x7E,0x2A,0xB2,0x85,0x6A,0x5B,0x16,0xE3,0xEF,0xB7,
912 0xF6,0x1D,0x43,0x16,0xAE,
913 0x00,0xD9,0xB6,0x7D,0x19,0x2E,0x03,0x67,0xC8,0x03, /* x */
914 0xF3,0x9E,0x1A,0x7E,0x82,0xCA,0x14,0xA6,0x51,0x35,
915 0x0A,0xAE,0x61,0x7E,0x8F,
916 0x01,0xCE,0x94,0x33,0x56,0x07,0xC3,0x04,0xAC,0x29, /* y */
917 0xE7,0xDE,0xFB,0xD9,0xCA,0x01,0xF5,0x96,0xF9,0x27,
918 0x22,0x4C,0xDE,0xCF,0x6C,
919 0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* order */
920 0x00,0x00,0x01,0x5A,0xAB,0x56,0x1B,0x00,0x54,0x13,
921 0xCC,0xD4,0xEE,0x99,0xD5 }
576 }; 922 };
577 923
578static const EC_CURVE_DATA _EC_NIST_CHAR2_233K = { 924static const struct { EC_CURVE_DATA h; unsigned char data[0+30*6]; }
579 NID_X9_62_characteristic_two_field, 925 _EC_NIST_CHAR2_233K = {
580 "020000000000000000000000000000000000000004000000000000000001", 926 { NID_X9_62_characteristic_two_field,0,30,4 },
581 "0", 927 { /* no seed */
582 "1", 928 0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
583 "017232BA853A7E731AF129F22FF4149563A419C26BF50A4C9D6EEFAD6126", 929 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
584 "01DB537DECE819B7F70F555A67C427A8CD9BF18AEB9B56E0C11056FAE6A3", 930 0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,
585 "008000000000000000000000000000069D5BB915BCD46EFB1AD5F173ABDF", 4, 931
586 NULL, 0, 932 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* a */
587 "NIST/SECG/WTLS curve over a 233 bit binary field" 933 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
934 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
935
936 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* b */
937 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
938 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,
939
940 0x01,0x72,0x32,0xBA,0x85,0x3A,0x7E,0x73,0x1A,0xF1, /* x */
941 0x29,0xF2,0x2F,0xF4,0x14,0x95,0x63,0xA4,0x19,0xC2,
942 0x6B,0xF5,0x0A,0x4C,0x9D,0x6E,0xEF,0xAD,0x61,0x26,
943
944 0x01,0xDB,0x53,0x7D,0xEC,0xE8,0x19,0xB7,0xF7,0x0F, /* y */
945 0x55,0x5A,0x67,0xC4,0x27,0xA8,0xCD,0x9B,0xF1,0x8A,
946 0xEB,0x9B,0x56,0xE0,0xC1,0x10,0x56,0xFA,0xE6,0xA3,
947
948 0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* order */
949 0x00,0x00,0x00,0x00,0x00,0x06,0x9D,0x5B,0xB9,0x15,
950 0xBC,0xD4,0x6E,0xFB,0x1A,0xD5,0xF1,0x73,0xAB,0xDF }
588 }; 951 };
589 952
590static const unsigned char _EC_NIST_CHAR2_233B_SEED[] = { 953static const struct { EC_CURVE_DATA h; unsigned char data[20+30*6]; }
591 0x74,0xD5,0x9F,0xF0,0x7F,0x6B,0x41,0x3D,0x0E,0xA1, 954 _EC_NIST_CHAR2_233B = {
592 0x4B,0x34,0x4B,0x20,0xA2,0xDB,0x04,0x9B,0x50,0xC3}; 955 { NID_X9_62_characteristic_two_field,20,30,2 },
593static const EC_CURVE_DATA _EC_NIST_CHAR2_233B = { 956 { 0x74,0xD5,0x9F,0xF0,0x7F,0x6B,0x41,0x3D,0x0E,0xA1, /* seed */
594 NID_X9_62_characteristic_two_field, 957 0x4B,0x34,0x4B,0x20,0xA2,0xDB,0x04,0x9B,0x50,0xC3,
595 "020000000000000000000000000000000000000004000000000000000001", 958
596 "000000000000000000000000000000000000000000000000000000000001", 959 0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* p */
597 "0066647EDE6C332C7F8C0923BB58213B333B20E9CE4281FE115F7D8F90AD", 960 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
598 "00FAC9DFCBAC8313BB2139F1BB755FEF65BC391F8B36F8F8EB7371FD558B", 961 0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,
599 "01006A08A41903350678E58528BEBF8A0BEFF867A7CA36716F7E01F81052", 962
600 "01000000000000000000000000000013E974E72F8A6922031D2603CFE0D7", 2, 963 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* a */
601 _EC_NIST_CHAR2_233B_SEED, 20, 964 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
602 "NIST/SECG/WTLS curve over a 233 bit binary field" 965 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,
966
967 0x00,0x66,0x64,0x7E,0xDE,0x6C,0x33,0x2C,0x7F,0x8C, /* b */
968 0x09,0x23,0xBB,0x58,0x21,0x3B,0x33,0x3B,0x20,0xE9,
969 0xCE,0x42,0x81,0xFE,0x11,0x5F,0x7D,0x8F,0x90,0xAD,
970
971 0x00,0xFA,0xC9,0xDF,0xCB,0xAC,0x83,0x13,0xBB,0x21, /* x */
972 0x39,0xF1,0xBB,0x75,0x5F,0xEF,0x65,0xBC,0x39,0x1F,
973 0x8B,0x36,0xF8,0xF8,0xEB,0x73,0x71,0xFD,0x55,0x8B,
974
975 0x01,0x00,0x6A,0x08,0xA4,0x19,0x03,0x35,0x06,0x78, /* y */
976 0xE5,0x85,0x28,0xBE,0xBF,0x8A,0x0B,0xEF,0xF8,0x67,
977 0xA7,0xCA,0x36,0x71,0x6F,0x7E,0x01,0xF8,0x10,0x52,
978
979 0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* order */
980 0x00,0x00,0x00,0x00,0x00,0x13,0xE9,0x74,0xE7,0x2F,
981 0x8A,0x69,0x22,0x03,0x1D,0x26,0x03,0xCF,0xE0,0xD7 }
603 }; 982 };
604 983
605static const EC_CURVE_DATA _EC_SECG_CHAR2_239K1 = { 984static const struct { EC_CURVE_DATA h; unsigned char data[0+30*6]; }
606 NID_X9_62_characteristic_two_field, 985 _EC_SECG_CHAR2_239K1 = {
607 "800000000000000000004000000000000000000000000000000000000001", 986 { NID_X9_62_characteristic_two_field,0,30,4 },
608 "0", 987 { /* no seed */
609 "1", 988 0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
610 "29A0B6A887A983E9730988A68727A8B2D126C44CC2CC7B2A6555193035DC", 989 0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
611 "76310804F12E549BDB011C103089E73510ACB275FC312A5DC6B76553F0CA", 990 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,
612 "2000000000000000000000000000005A79FEC67CB6E91F1C1DA800E478A5", 4, 991
613 NULL, 0, 992 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* a */
614 "SECG curve over a 239 bit binary field" 993 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
994 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
995
996 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* b */
997 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
998 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,
999
1000 0x29,0xA0,0xB6,0xA8,0x87,0xA9,0x83,0xE9,0x73,0x09, /* x */
1001 0x88,0xA6,0x87,0x27,0xA8,0xB2,0xD1,0x26,0xC4,0x4C,
1002 0xC2,0xCC,0x7B,0x2A,0x65,0x55,0x19,0x30,0x35,0xDC,
1003
1004 0x76,0x31,0x08,0x04,0xF1,0x2E,0x54,0x9B,0xDB,0x01, /* y */
1005 0x1C,0x10,0x30,0x89,0xE7,0x35,0x10,0xAC,0xB2,0x75,
1006 0xFC,0x31,0x2A,0x5D,0xC6,0xB7,0x65,0x53,0xF0,0xCA,
1007
1008 0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* order */
1009 0x00,0x00,0x00,0x00,0x00,0x5A,0x79,0xFE,0xC6,0x7C,
1010 0xB6,0xE9,0x1F,0x1C,0x1D,0xA8,0x00,0xE4,0x78,0xA5 }
615 }; 1011 };
616 1012
617static const EC_CURVE_DATA _EC_NIST_CHAR2_283K = { 1013static const struct { EC_CURVE_DATA h; unsigned char data[0+36*6]; }
618 NID_X9_62_characteristic_two_field, 1014 _EC_NIST_CHAR2_283K = {
619 "080000000000000000000000000000000000000000000000000000000000000000001" 1015 { NID_X9_62_characteristic_two_field,0,36,4 },
620 "0A1", 1016 { /* no seed */
621 "0", 1017 0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
622 "1", 1018 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
623 "0503213F78CA44883F1A3B8162F188E553CD265F23C1567A16876913B0C2AC2458492" 1019 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
624 "836", 1020 0x00,0x00,0x00,0x00,0x10,0xA1,
625 "01CCDA380F1C9E318D90F95D07E5426FE87E45C0E8184698E45962364E34116177DD2" 1021 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* a */
626 "259", 1022 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
627 "01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9AE2ED07577265DFF7F94451E061E163" 1023 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
628 "C61", 4, 1024 0x00,0x00,0x00,0x00,0x00,0x00,
629 NULL, 20, 1025 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* b */
630 "NIST/SECG curve over a 283 bit binary field" 1026 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1027 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1028 0x00,0x00,0x00,0x00,0x00,0x01,
1029 0x05,0x03,0x21,0x3F,0x78,0xCA,0x44,0x88,0x3F,0x1A, /* x */
1030 0x3B,0x81,0x62,0xF1,0x88,0xE5,0x53,0xCD,0x26,0x5F,
1031 0x23,0xC1,0x56,0x7A,0x16,0x87,0x69,0x13,0xB0,0xC2,
1032 0xAC,0x24,0x58,0x49,0x28,0x36,
1033 0x01,0xCC,0xDA,0x38,0x0F,0x1C,0x9E,0x31,0x8D,0x90, /* y */
1034 0xF9,0x5D,0x07,0xE5,0x42,0x6F,0xE8,0x7E,0x45,0xC0,
1035 0xE8,0x18,0x46,0x98,0xE4,0x59,0x62,0x36,0x4E,0x34,
1036 0x11,0x61,0x77,0xDD,0x22,0x59,
1037 0x01,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* order */
1038 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xE9,0xAE,
1039 0x2E,0xD0,0x75,0x77,0x26,0x5D,0xFF,0x7F,0x94,0x45,
1040 0x1E,0x06,0x1E,0x16,0x3C,0x61 }
631 }; 1041 };
632 1042
633static const unsigned char _EC_NIST_CHAR2_283B_SEED[] = { 1043static const struct { EC_CURVE_DATA h; unsigned char data[20+36*6]; }
634 0x77,0xE2,0xB0,0x73,0x70,0xEB,0x0F,0x83,0x2A,0x6D, 1044 _EC_NIST_CHAR2_283B = {
635 0xD5,0xB6,0x2D,0xFC,0x88,0xCD,0x06,0xBB,0x84,0xBE}; 1045 { NID_X9_62_characteristic_two_field,20,36,2 },
636static const EC_CURVE_DATA _EC_NIST_CHAR2_283B = { 1046 { 0x77,0xE2,0xB0,0x73,0x70,0xEB,0x0F,0x83,0x2A,0x6D, /* no seed */
637 NID_X9_62_characteristic_two_field, 1047 0xD5,0xB6,0x2D,0xFC,0x88,0xCD,0x06,0xBB,0x84,0xBE,
638 "080000000000000000000000000000000000000000000000000000000000000000001" 1048
639 "0A1", 1049 0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* p */
640 "000000000000000000000000000000000000000000000000000000000000000000000" 1050 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
641 "001", 1051 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
642 "027B680AC8B8596DA5A4AF8A19A0303FCA97FD7645309FA2A581485AF6263E313B79A" 1052 0x00,0x00,0x00,0x00,0x10,0xA1,
643 "2F5", 1053 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* a */
644 "05F939258DB7DD90E1934F8C70B0DFEC2EED25B8557EAC9C80E2E198F8CDBECD86B12" 1054 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
645 "053", 1055 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
646 "03676854FE24141CB98FE6D4B20D02B4516FF702350EDDB0826779C813F0DF45BE811" 1056 0x00,0x00,0x00,0x00,0x00,0x01,
647 "2F4", 1057 0x02,0x7B,0x68,0x0A,0xC8,0xB8,0x59,0x6D,0xA5,0xA4, /* b */
648 "03FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF90399660FC938A90165B042A7CEFADB" 1058 0xAF,0x8A,0x19,0xA0,0x30,0x3F,0xCA,0x97,0xFD,0x76,
649 "307", 2, 1059 0x45,0x30,0x9F,0xA2,0xA5,0x81,0x48,0x5A,0xF6,0x26,
650 _EC_NIST_CHAR2_283B_SEED, 20, 1060 0x3E,0x31,0x3B,0x79,0xA2,0xF5,
651 "NIST/SECG curve over a 283 bit binary field" 1061 0x05,0xF9,0x39,0x25,0x8D,0xB7,0xDD,0x90,0xE1,0x93, /* x */
1062 0x4F,0x8C,0x70,0xB0,0xDF,0xEC,0x2E,0xED,0x25,0xB8,
1063 0x55,0x7E,0xAC,0x9C,0x80,0xE2,0xE1,0x98,0xF8,0xCD,
1064 0xBE,0xCD,0x86,0xB1,0x20,0x53,
1065 0x03,0x67,0x68,0x54,0xFE,0x24,0x14,0x1C,0xB9,0x8F, /* y */
1066 0xE6,0xD4,0xB2,0x0D,0x02,0xB4,0x51,0x6F,0xF7,0x02,
1067 0x35,0x0E,0xDD,0xB0,0x82,0x67,0x79,0xC8,0x13,0xF0,
1068 0xDF,0x45,0xBE,0x81,0x12,0xF4,
1069 0x03,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* order */
1070 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xEF,0x90,
1071 0x39,0x96,0x60,0xFC,0x93,0x8A,0x90,0x16,0x5B,0x04,
1072 0x2A,0x7C,0xEF,0xAD,0xB3,0x07 }
652 }; 1073 };
653 1074
654static const EC_CURVE_DATA _EC_NIST_CHAR2_409K = { 1075static const struct { EC_CURVE_DATA h; unsigned char data[0+52*6]; }
655 NID_X9_62_characteristic_two_field, 1076 _EC_NIST_CHAR2_409K = {
656 "020000000000000000000000000000000000000000000000000000000000000000000" 1077 { NID_X9_62_characteristic_two_field,0,52,4 },
657 "00000000000008000000000000000000001", 1078 { /* no seed */
658 "0", 1079 0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* p */
659 "1", 1080 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
660 "0060F05F658F49C1AD3AB1890F7184210EFD0987E307C84C27ACCFB8F9F67CC2C4601" 1081 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
661 "89EB5AAAA62EE222EB1B35540CFE9023746", 1082 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
662 "01E369050B7C4E42ACBA1DACBF04299C3460782F918EA427E6325165E9EA10E3DA5F6" 1083 0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
663 "C42E9C55215AA9CA27A5863EC48D8E0286B", 1084 0x00,0x01,
664 "007FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5F83B2D4EA20400" 1085 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* a */
665 "EC4557D5ED3E3E7CA5B4B5C83B8E01E5FCF", 4, 1086 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
666 NULL, 0, 1087 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
667 "NIST/SECG curve over a 409 bit binary field" 1088 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1089 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1090 0x00,0x00,
1091 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* b */
1092 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1093 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1094 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1095 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1096 0x00,0x01,
1097 0x00,0x60,0xF0,0x5F,0x65,0x8F,0x49,0xC1,0xAD,0x3A, /* x */
1098 0xB1,0x89,0x0F,0x71,0x84,0x21,0x0E,0xFD,0x09,0x87,
1099 0xE3,0x07,0xC8,0x4C,0x27,0xAC,0xCF,0xB8,0xF9,0xF6,
1100 0x7C,0xC2,0xC4,0x60,0x18,0x9E,0xB5,0xAA,0xAA,0x62,
1101 0xEE,0x22,0x2E,0xB1,0xB3,0x55,0x40,0xCF,0xE9,0x02,
1102 0x37,0x46,
1103 0x01,0xE3,0x69,0x05,0x0B,0x7C,0x4E,0x42,0xAC,0xBA, /* y */
1104 0x1D,0xAC,0xBF,0x04,0x29,0x9C,0x34,0x60,0x78,0x2F,
1105 0x91,0x8E,0xA4,0x27,0xE6,0x32,0x51,0x65,0xE9,0xEA,
1106 0x10,0xE3,0xDA,0x5F,0x6C,0x42,0xE9,0xC5,0x52,0x15,
1107 0xAA,0x9C,0xA2,0x7A,0x58,0x63,0xEC,0x48,0xD8,0xE0,
1108 0x28,0x6B,
1109 0x00,0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* order */
1110 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
1111 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0x5F,0x83,0xB2,
1112 0xD4,0xEA,0x20,0x40,0x0E,0xC4,0x55,0x7D,0x5E,0xD3,
1113 0xE3,0xE7,0xCA,0x5B,0x4B,0x5C,0x83,0xB8,0xE0,0x1E,
1114 0x5F,0xCF }
668 }; 1115 };
669 1116
670static const unsigned char _EC_NIST_CHAR2_409B_SEED[] = { 1117static const struct { EC_CURVE_DATA h; unsigned char data[20+52*6]; }
671 0x40,0x99,0xB5,0xA4,0x57,0xF9,0xD6,0x9F,0x79,0x21, 1118 _EC_NIST_CHAR2_409B = {
672 0x3D,0x09,0x4C,0x4B,0xCD,0x4D,0x42,0x62,0x21,0x0B}; 1119 { NID_X9_62_characteristic_two_field,20,52,2 },
673static const EC_CURVE_DATA _EC_NIST_CHAR2_409B = { 1120 { 0x40,0x99,0xB5,0xA4,0x57,0xF9,0xD6,0x9F,0x79,0x21, /* seed */
674 NID_X9_62_characteristic_two_field, 1121 0x3D,0x09,0x4C,0x4B,0xCD,0x4D,0x42,0x62,0x21,0x0B,
675 "020000000000000000000000000000000000000000000000000000000000000000000" 1122
676 "00000000000008000000000000000000001", 1123 0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* p */
677 "000000000000000000000000000000000000000000000000000000000000000000000" 1124 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
678 "00000000000000000000000000000000001", 1125 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
679 "0021A5C2C8EE9FEB5C4B9A753B7B476B7FD6422EF1F3DD674761FA99D6AC27C8A9A19" 1126 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
680 "7B272822F6CD57A55AA4F50AE317B13545F", 1127 0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
681 "015D4860D088DDB3496B0C6064756260441CDE4AF1771D4DB01FFE5B34E59703DC255" 1128 0x00,0x01,
682 "A868A1180515603AEAB60794E54BB7996A7", 1129 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* a */
683 "0061B1CFAB6BE5F32BBFA78324ED106A7636B9C5A7BD198D0158AA4F5488D08F38514" 1130 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
684 "F1FDF4B4F40D2181B3681C364BA0273C706", 1131 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
685 "010000000000000000000000000000000000000000000000000001E2AAD6A612F3330" 1132 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
686 "7BE5FA47C3C9E052F838164CD37D9A21173", 2, 1133 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
687 _EC_NIST_CHAR2_409B_SEED, 20, 1134 0x00,0x01,
688 "NIST/SECG curve over a 409 bit binary field" 1135 0x00,0x21,0xA5,0xC2,0xC8,0xEE,0x9F,0xEB,0x5C,0x4B, /* b */
1136 0x9A,0x75,0x3B,0x7B,0x47,0x6B,0x7F,0xD6,0x42,0x2E,
1137 0xF1,0xF3,0xDD,0x67,0x47,0x61,0xFA,0x99,0xD6,0xAC,
1138 0x27,0xC8,0xA9,0xA1,0x97,0xB2,0x72,0x82,0x2F,0x6C,
1139 0xD5,0x7A,0x55,0xAA,0x4F,0x50,0xAE,0x31,0x7B,0x13,
1140 0x54,0x5F,
1141 0x01,0x5D,0x48,0x60,0xD0,0x88,0xDD,0xB3,0x49,0x6B, /* x */
1142 0x0C,0x60,0x64,0x75,0x62,0x60,0x44,0x1C,0xDE,0x4A,
1143 0xF1,0x77,0x1D,0x4D,0xB0,0x1F,0xFE,0x5B,0x34,0xE5,
1144 0x97,0x03,0xDC,0x25,0x5A,0x86,0x8A,0x11,0x80,0x51,
1145 0x56,0x03,0xAE,0xAB,0x60,0x79,0x4E,0x54,0xBB,0x79,
1146 0x96,0xA7,
1147 0x00,0x61,0xB1,0xCF,0xAB,0x6B,0xE5,0xF3,0x2B,0xBF, /* y */
1148 0xA7,0x83,0x24,0xED,0x10,0x6A,0x76,0x36,0xB9,0xC5,
1149 0xA7,0xBD,0x19,0x8D,0x01,0x58,0xAA,0x4F,0x54,0x88,
1150 0xD0,0x8F,0x38,0x51,0x4F,0x1F,0xDF,0x4B,0x4F,0x40,
1151 0xD2,0x18,0x1B,0x36,0x81,0xC3,0x64,0xBA,0x02,0x73,
1152 0xC7,0x06,
1153 0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* order */
1154 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1155 0x00,0x00,0x00,0x00,0x00,0x00,0x01,0xE2,0xAA,0xD6,
1156 0xA6,0x12,0xF3,0x33,0x07,0xBE,0x5F,0xA4,0x7C,0x3C,
1157 0x9E,0x05,0x2F,0x83,0x81,0x64,0xCD,0x37,0xD9,0xA2,
1158 0x11,0x73 }
689 }; 1159 };
690 1160
691static const EC_CURVE_DATA _EC_NIST_CHAR2_571K = { 1161static const struct { EC_CURVE_DATA h; unsigned char data[0+72*6]; }
692 NID_X9_62_characteristic_two_field, 1162 _EC_NIST_CHAR2_571K = {
693 "800000000000000000000000000000000000000000000000000000000000000000000" 1163 { NID_X9_62_characteristic_two_field,0,72,4 },
694 "000000000000000000000000000000000000000000000000000000000000000000000" 1164 { /* no seed */
695 "00425", 1165 0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* p */
696 "0", 1166 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
697 "1", 1167 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
698 "026EB7A859923FBC82189631F8103FE4AC9CA2970012D5D46024804801841CA443709" 1168 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
699 "58493B205E647DA304DB4CEB08CBBD1BA39494776FB988B47174DCA88C7E2945283A0" 1169 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
700 "1C8972", 1170 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
701 "0349DC807F4FBF374F4AEADE3BCA95314DD58CEC9F307A54FFC61EFC006D8A2C9D497" 1171 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
702 "9C0AC44AEA74FBEBBB9F772AEDCB620B01A7BA7AF1B320430C8591984F601CD4C143E" 1172 0x04,0x25,
703 "F1C7A3", 1173 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* a */
704 "020000000000000000000000000000000000000000000000000000000000000000000" 1174 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
705 "000131850E1F19A63E4B391A8DB917F4138B630D84BE5D639381E91DEB45CFE778F63" 1175 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
706 "7C1001", 4, 1176 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
707 NULL, 0, 1177 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
708 "NIST/SECG curve over a 571 bit binary field" 1178 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1179 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1180 0x00,0x00,
1181 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* b */
1182 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1183 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1184 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1185 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1186 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1187 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1188 0x00,0x01,
1189 0x02,0x6E,0xB7,0xA8,0x59,0x92,0x3F,0xBC,0x82,0x18, /* x */
1190 0x96,0x31,0xF8,0x10,0x3F,0xE4,0xAC,0x9C,0xA2,0x97,
1191 0x00,0x12,0xD5,0xD4,0x60,0x24,0x80,0x48,0x01,0x84,
1192 0x1C,0xA4,0x43,0x70,0x95,0x84,0x93,0xB2,0x05,0xE6,
1193 0x47,0xDA,0x30,0x4D,0xB4,0xCE,0xB0,0x8C,0xBB,0xD1,
1194 0xBA,0x39,0x49,0x47,0x76,0xFB,0x98,0x8B,0x47,0x17,
1195 0x4D,0xCA,0x88,0xC7,0xE2,0x94,0x52,0x83,0xA0,0x1C,
1196 0x89,0x72,
1197 0x03,0x49,0xDC,0x80,0x7F,0x4F,0xBF,0x37,0x4F,0x4A, /* y */
1198 0xEA,0xDE,0x3B,0xCA,0x95,0x31,0x4D,0xD5,0x8C,0xEC,
1199 0x9F,0x30,0x7A,0x54,0xFF,0xC6,0x1E,0xFC,0x00,0x6D,
1200 0x8A,0x2C,0x9D,0x49,0x79,0xC0,0xAC,0x44,0xAE,0xA7,
1201 0x4F,0xBE,0xBB,0xB9,0xF7,0x72,0xAE,0xDC,0xB6,0x20,
1202 0xB0,0x1A,0x7B,0xA7,0xAF,0x1B,0x32,0x04,0x30,0xC8,
1203 0x59,0x19,0x84,0xF6,0x01,0xCD,0x4C,0x14,0x3E,0xF1,
1204 0xC7,0xA3,
1205 0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* order */
1206 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1207 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1208 0x00,0x00,0x00,0x00,0x00,0x00,0x13,0x18,0x50,0xE1,
1209 0xF1,0x9A,0x63,0xE4,0xB3,0x91,0xA8,0xDB,0x91,0x7F,
1210 0x41,0x38,0xB6,0x30,0xD8,0x4B,0xE5,0xD6,0x39,0x38,
1211 0x1E,0x91,0xDE,0xB4,0x5C,0xFE,0x77,0x8F,0x63,0x7C,
1212 0x10,0x01 }
709 }; 1213 };
710 1214
711static const unsigned char _EC_NIST_CHAR2_571B_SEED[] = { 1215static const struct { EC_CURVE_DATA h; unsigned char data[20+72*6]; }
712 0x2A,0xA0,0x58,0xF7,0x3A,0x0E,0x33,0xAB,0x48,0x6B, 1216 _EC_NIST_CHAR2_571B = {
713 0x0F,0x61,0x04,0x10,0xC5,0x3A,0x7F,0x13,0x23,0x10}; 1217 { NID_X9_62_characteristic_two_field,20,72,2 },
714static const EC_CURVE_DATA _EC_NIST_CHAR2_571B = { 1218 { 0x2A,0xA0,0x58,0xF7,0x3A,0x0E,0x33,0xAB,0x48,0x6B, /* seed */
715 NID_X9_62_characteristic_two_field, 1219 0x0F,0x61,0x04,0x10,0xC5,0x3A,0x7F,0x13,0x23,0x10,
716 "800000000000000000000000000000000000000000000000000000000000000000000" 1220
717 "000000000000000000000000000000000000000000000000000000000000000000000" 1221 0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* p */
718 "00425", 1222 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
719 "000000000000000000000000000000000000000000000000000000000000000000000" 1223 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
720 "000000000000000000000000000000000000000000000000000000000000000000000" 1224 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
721 "000001", 1225 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
722 "02F40E7E2221F295DE297117B7F3D62F5C6A97FFCB8CEFF1CD6BA8CE4A9A18AD84FFA" 1226 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
723 "BBD8EFA59332BE7AD6756A66E294AFD185A78FF12AA520E4DE739BACA0C7FFEFF7F29" 1227 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
724 "55727A", 1228 0x04,0x25,
725 "0303001D34B856296C16C0D40D3CD7750A93D1D2955FA80AA5F40FC8DB7B2ABDBDE53" 1229 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* a */
726 "950F4C0D293CDD711A35B67FB1499AE60038614F1394ABFA3B4C850D927E1E7769C8E" 1230 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
727 "EC2D19", 1231 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
728 "037BF27342DA639B6DCCFFFEB73D69D78C6C27A6009CBBCA1980F8533921E8A684423" 1232 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
729 "E43BAB08A576291AF8F461BB2A8B3531D2F0485C19B16E2F1516E23DD3C1A4827AF1B" 1233 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
730 "8AC15B", 1234 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
731 "03FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" 1235 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
732 "FFFE661CE18FF55987308059B186823851EC7DD9CA1161DE93D5174D66E8382E9BB2F" 1236 0x00,0x01,
733 "E84E47", 2, 1237 0x02,0xF4,0x0E,0x7E,0x22,0x21,0xF2,0x95,0xDE,0x29, /* b */
734 _EC_NIST_CHAR2_571B_SEED, 20, 1238 0x71,0x17,0xB7,0xF3,0xD6,0x2F,0x5C,0x6A,0x97,0xFF,
735 "NIST/SECG curve over a 571 bit binary field" 1239 0xCB,0x8C,0xEF,0xF1,0xCD,0x6B,0xA8,0xCE,0x4A,0x9A,
1240 0x18,0xAD,0x84,0xFF,0xAB,0xBD,0x8E,0xFA,0x59,0x33,
1241 0x2B,0xE7,0xAD,0x67,0x56,0xA6,0x6E,0x29,0x4A,0xFD,
1242 0x18,0x5A,0x78,0xFF,0x12,0xAA,0x52,0x0E,0x4D,0xE7,
1243 0x39,0xBA,0xCA,0x0C,0x7F,0xFE,0xFF,0x7F,0x29,0x55,
1244 0x72,0x7A,
1245 0x03,0x03,0x00,0x1D,0x34,0xB8,0x56,0x29,0x6C,0x16, /* x */
1246 0xC0,0xD4,0x0D,0x3C,0xD7,0x75,0x0A,0x93,0xD1,0xD2,
1247 0x95,0x5F,0xA8,0x0A,0xA5,0xF4,0x0F,0xC8,0xDB,0x7B,
1248 0x2A,0xBD,0xBD,0xE5,0x39,0x50,0xF4,0xC0,0xD2,0x93,
1249 0xCD,0xD7,0x11,0xA3,0x5B,0x67,0xFB,0x14,0x99,0xAE,
1250 0x60,0x03,0x86,0x14,0xF1,0x39,0x4A,0xBF,0xA3,0xB4,
1251 0xC8,0x50,0xD9,0x27,0xE1,0xE7,0x76,0x9C,0x8E,0xEC,
1252 0x2D,0x19,
1253 0x03,0x7B,0xF2,0x73,0x42,0xDA,0x63,0x9B,0x6D,0xCC, /* y */
1254 0xFF,0xFE,0xB7,0x3D,0x69,0xD7,0x8C,0x6C,0x27,0xA6,
1255 0x00,0x9C,0xBB,0xCA,0x19,0x80,0xF8,0x53,0x39,0x21,
1256 0xE8,0xA6,0x84,0x42,0x3E,0x43,0xBA,0xB0,0x8A,0x57,
1257 0x62,0x91,0xAF,0x8F,0x46,0x1B,0xB2,0xA8,0xB3,0x53,
1258 0x1D,0x2F,0x04,0x85,0xC1,0x9B,0x16,0xE2,0xF1,0x51,
1259 0x6E,0x23,0xDD,0x3C,0x1A,0x48,0x27,0xAF,0x1B,0x8A,
1260 0xC1,0x5B,
1261 0x03,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* order */
1262 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
1263 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
1264 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xE6,0x61,0xCE,0x18,
1265 0xFF,0x55,0x98,0x73,0x08,0x05,0x9B,0x18,0x68,0x23,
1266 0x85,0x1E,0xC7,0xDD,0x9C,0xA1,0x16,0x1D,0xE9,0x3D,
1267 0x51,0x74,0xD6,0x6E,0x83,0x82,0xE9,0xBB,0x2F,0xE8,
1268 0x4E,0x47 }
736 }; 1269 };
737 1270
738static const unsigned char _EC_X9_62_CHAR2_163V1_SEED[] = { 1271static const struct { EC_CURVE_DATA h; unsigned char data[20+21*6]; }
739 0xD2,0xC0,0xFB,0x15,0x76,0x08,0x60,0xDE,0xF1,0xEE, 1272 _EC_X9_62_CHAR2_163V1 = {
740 0xF4,0xD6,0x96,0xE6,0x76,0x87,0x56,0x15,0x17,0x54}; 1273 { NID_X9_62_characteristic_two_field,20,21,2 },
741static const EC_CURVE_DATA _EC_X9_62_CHAR2_163V1 = { 1274 { 0xD2,0xC0,0xFB,0x15,0x76,0x08,0x60,0xDE,0xF1,0xEE,
742 NID_X9_62_characteristic_two_field, 1275 0xF4,0xD6,0x96,0xE6,0x76,0x87,0x56,0x15,0x17,0x54, /* seed */
743 "080000000000000000000000000000000000000107", 1276
744 "072546B5435234A422E0789675F432C89435DE5242", 1277 0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* p */
745 "00C9517D06D5240D3CFF38C74B20B6CD4D6F9DD4D9", 1278 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,
746 "07AF69989546103D79329FCC3D74880F33BBE803CB", 1279 0x07,
747 "01EC23211B5966ADEA1D3F87F7EA5848AEF0B7CA9F", 1280 0x07,0x25,0x46,0xB5,0x43,0x52,0x34,0xA4,0x22,0xE0, /* a */
748 "0400000000000000000001E60FC8821CC74DAEAFC1", 2, 1281 0x78,0x96,0x75,0xF4,0x32,0xC8,0x94,0x35,0xDE,0x52,
749 _EC_X9_62_CHAR2_163V1_SEED, 20, 1282 0x42,
750 "X9.62 curve over a 163 bit binary field" 1283 0x00,0xC9,0x51,0x7D,0x06,0xD5,0x24,0x0D,0x3C,0xFF, /* b */
1284 0x38,0xC7,0x4B,0x20,0xB6,0xCD,0x4D,0x6F,0x9D,0xD4,
1285 0xD9,
1286 0x07,0xAF,0x69,0x98,0x95,0x46,0x10,0x3D,0x79,0x32, /* x */
1287 0x9F,0xCC,0x3D,0x74,0x88,0x0F,0x33,0xBB,0xE8,0x03,
1288 0xCB,
1289 0x01,0xEC,0x23,0x21,0x1B,0x59,0x66,0xAD,0xEA,0x1D, /* y */
1290 0x3F,0x87,0xF7,0xEA,0x58,0x48,0xAE,0xF0,0xB7,0xCA,
1291 0x9F,
1292 0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* order */
1293 0x01,0xE6,0x0F,0xC8,0x82,0x1C,0xC7,0x4D,0xAE,0xAF,
1294 0xC1 }
751 }; 1295 };
752 1296
753static const unsigned char _EC_X9_62_CHAR2_163V2_SEED[] = { 1297static const struct { EC_CURVE_DATA h; unsigned char data[20+21*6]; }
754 0x53,0x81,0x4C,0x05,0x0D,0x44,0xD6,0x96,0xE6,0x76, 1298 _EC_X9_62_CHAR2_163V2 = {
755 0x87,0x56,0x15,0x17,0x58,0x0C,0xA4,0xE2,0x9F,0xFD}; 1299 { NID_X9_62_characteristic_two_field,20,21,2 },
756static const EC_CURVE_DATA _EC_X9_62_CHAR2_163V2 = { 1300 { 0x53,0x81,0x4C,0x05,0x0D,0x44,0xD6,0x96,0xE6,0x76, /* seed */
757 NID_X9_62_characteristic_two_field, 1301 0x87,0x56,0x15,0x17,0x58,0x0C,0xA4,0xE2,0x9F,0xFD,
758 "080000000000000000000000000000000000000107", 1302
759 "0108B39E77C4B108BED981ED0E890E117C511CF072", 1303 0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* p */
760 "0667ACEB38AF4E488C407433FFAE4F1C811638DF20", 1304 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,
761 "0024266E4EB5106D0A964D92C4860E2671DB9B6CC5", 1305 0x07,
762 "079F684DDF6684C5CD258B3890021B2386DFD19FC5", 1306 0x01,0x08,0xB3,0x9E,0x77,0xC4,0xB1,0x08,0xBE,0xD9, /* a */
763 "03FFFFFFFFFFFFFFFFFFFDF64DE1151ADBB78F10A7", 2, 1307 0x81,0xED,0x0E,0x89,0x0E,0x11,0x7C,0x51,0x1C,0xF0,
764 _EC_X9_62_CHAR2_163V2_SEED, 20, 1308 0x72,
765 "X9.62 curve over a 163 bit binary field" 1309 0x06,0x67,0xAC,0xEB,0x38,0xAF,0x4E,0x48,0x8C,0x40, /* b */
1310 0x74,0x33,0xFF,0xAE,0x4F,0x1C,0x81,0x16,0x38,0xDF,
1311 0x20,
1312 0x00,0x24,0x26,0x6E,0x4E,0xB5,0x10,0x6D,0x0A,0x96, /* x */
1313 0x4D,0x92,0xC4,0x86,0x0E,0x26,0x71,0xDB,0x9B,0x6C,
1314 0xC5,
1315 0x07,0x9F,0x68,0x4D,0xDF,0x66,0x84,0xC5,0xCD,0x25, /* y */
1316 0x8B,0x38,0x90,0x02,0x1B,0x23,0x86,0xDF,0xD1,0x9F,
1317 0xC5,
1318 0x03,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* order */
1319 0xFD,0xF6,0x4D,0xE1,0x15,0x1A,0xDB,0xB7,0x8F,0x10,
1320 0xA7 }
766 }; 1321 };
767 1322
768static const unsigned char _EC_X9_62_CHAR2_163V3_SEED[] = { 1323static const struct { EC_CURVE_DATA h; unsigned char data[20+21*6]; }
769 0x50,0xCB,0xF1,0xD9,0x5C,0xA9,0x4D,0x69,0x6E,0x67, 1324 _EC_X9_62_CHAR2_163V3 = {
770 0x68,0x75,0x61,0x51,0x75,0xF1,0x6A,0x36,0xA3,0xB8}; 1325 { NID_X9_62_characteristic_two_field,20,21,2 },
771static const EC_CURVE_DATA _EC_X9_62_CHAR2_163V3 = { 1326 { 0x50,0xCB,0xF1,0xD9,0x5C,0xA9,0x4D,0x69,0x6E,0x67, /* seed */
772 NID_X9_62_characteristic_two_field, 1327 0x68,0x75,0x61,0x51,0x75,0xF1,0x6A,0x36,0xA3,0xB8,
773 "080000000000000000000000000000000000000107", 1328
774 "07A526C63D3E25A256A007699F5447E32AE456B50E", 1329 0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* p */
775 "03F7061798EB99E238FD6F1BF95B48FEEB4854252B", 1330 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,
776 "02F9F87B7C574D0BDECF8A22E6524775F98CDEBDCB", 1331 0x07,
777 "05B935590C155E17EA48EB3FF3718B893DF59A05D0", 1332 0x07,0xA5,0x26,0xC6,0x3D,0x3E,0x25,0xA2,0x56,0xA0, /* a */
778 "03FFFFFFFFFFFFFFFFFFFE1AEE140F110AFF961309", 2, 1333 0x07,0x69,0x9F,0x54,0x47,0xE3,0x2A,0xE4,0x56,0xB5,
779 _EC_X9_62_CHAR2_163V3_SEED, 20, 1334 0x0E,
780 "X9.62 curve over a 163 bit binary field" 1335 0x03,0xF7,0x06,0x17,0x98,0xEB,0x99,0xE2,0x38,0xFD, /* b */
1336 0x6F,0x1B,0xF9,0x5B,0x48,0xFE,0xEB,0x48,0x54,0x25,
1337 0x2B,
1338 0x02,0xF9,0xF8,0x7B,0x7C,0x57,0x4D,0x0B,0xDE,0xCF, /* x */
1339 0x8A,0x22,0xE6,0x52,0x47,0x75,0xF9,0x8C,0xDE,0xBD,
1340 0xCB,
1341 0x05,0xB9,0x35,0x59,0x0C,0x15,0x5E,0x17,0xEA,0x48, /* y */
1342 0xEB,0x3F,0xF3,0x71,0x8B,0x89,0x3D,0xF5,0x9A,0x05,
1343 0xD0,
1344 0x03,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* order */
1345 0xFE,0x1A,0xEE,0x14,0x0F,0x11,0x0A,0xFF,0x96,0x13,
1346 0x09 }
781 }; 1347 };
782 1348
783static const EC_CURVE_DATA _EC_X9_62_CHAR2_176V1 = { 1349static const struct { EC_CURVE_DATA h; unsigned char data[0+23*6]; }
784 NID_X9_62_characteristic_two_field, 1350 _EC_X9_62_CHAR2_176V1 = {
785 "0100000000000000000000000000000000080000000007", 1351 { NID_X9_62_characteristic_two_field,0,23,0xFF6E },
786 "E4E6DB2995065C407D9D39B8D0967B96704BA8E9C90B", 1352 { /* no seed */
787 "5DDA470ABE6414DE8EC133AE28E9BBD7FCEC0AE0FFF2", 1353 0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* p */
788 "8D16C2866798B600F9F08BB4A8E860F3298CE04A5798", 1354 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x00,
789 "6FA4539C2DADDDD6BAB5167D61B436E1D92BB16A562C", 1355 0x00,0x00,0x07,
790 "00010092537397ECA4F6145799D62B0A19CE06FE26AD", 0xFF6E, 1356 0x00,0xE4,0xE6,0xDB,0x29,0x95,0x06,0x5C,0x40,0x7D, /* a */
791 NULL, 0, 1357 0x9D,0x39,0xB8,0xD0,0x96,0x7B,0x96,0x70,0x4B,0xA8,
792 "X9.62 curve over a 176 bit binary field" 1358 0xE9,0xC9,0x0B,
1359 0x00,0x5D,0xDA,0x47,0x0A,0xBE,0x64,0x14,0xDE,0x8E, /* b */
1360 0xC1,0x33,0xAE,0x28,0xE9,0xBB,0xD7,0xFC,0xEC,0x0A,
1361 0xE0,0xFF,0xF2,
1362 0x00,0x8D,0x16,0xC2,0x86,0x67,0x98,0xB6,0x00,0xF9, /* x */
1363 0xF0,0x8B,0xB4,0xA8,0xE8,0x60,0xF3,0x29,0x8C,0xE0,
1364 0x4A,0x57,0x98,
1365 0x00,0x6F,0xA4,0x53,0x9C,0x2D,0xAD,0xDD,0xD6,0xBA, /* y */
1366 0xB5,0x16,0x7D,0x61,0xB4,0x36,0xE1,0xD9,0x2B,0xB1,
1367 0x6A,0x56,0x2C,
1368 0x00,0x00,0x01,0x00,0x92,0x53,0x73,0x97,0xEC,0xA4, /* order */
1369 0xF6,0x14,0x57,0x99,0xD6,0x2B,0x0A,0x19,0xCE,0x06,
1370 0xFE,0x26,0xAD }
793 }; 1371 };
794 1372
795static const unsigned char _EC_X9_62_CHAR2_191V1_SEED[] = { 1373static const struct { EC_CURVE_DATA h; unsigned char data[20+24*6]; }
796 0x4E,0x13,0xCA,0x54,0x27,0x44,0xD6,0x96,0xE6,0x76, 1374 _EC_X9_62_CHAR2_191V1 = {
797 0x87,0x56,0x15,0x17,0x55,0x2F,0x27,0x9A,0x8C,0x84}; 1375 { NID_X9_62_characteristic_two_field,20,24,2 },
798static const EC_CURVE_DATA _EC_X9_62_CHAR2_191V1 = { 1376 { 0x4E,0x13,0xCA,0x54,0x27,0x44,0xD6,0x96,0xE6,0x76, /* seed */
799 NID_X9_62_characteristic_two_field, 1377 0x87,0x56,0x15,0x17,0x55,0x2F,0x27,0x9A,0x8C,0x84,
800 "800000000000000000000000000000000000000000000201", 1378
801 "2866537B676752636A68F56554E12640276B649EF7526267", 1379 0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* p */
802 "2E45EF571F00786F67B0081B9495A3D95462F5DE0AA185EC", 1380 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
803 "36B3DAF8A23206F9C4F299D7B21A9C369137F2C84AE1AA0D", 1381 0x00,0x00,0x02,0x01,
804 "765BE73433B3F95E332932E70EA245CA2418EA0EF98018FB", 1382 0x28,0x66,0x53,0x7B,0x67,0x67,0x52,0x63,0x6A,0x68, /* a */
805 "40000000000000000000000004A20E90C39067C893BBB9A5", 2, 1383 0xF5,0x65,0x54,0xE1,0x26,0x40,0x27,0x6B,0x64,0x9E,
806 _EC_X9_62_CHAR2_191V1_SEED, 20, 1384 0xF7,0x52,0x62,0x67,
807 "X9.62 curve over a 191 bit binary field" 1385 0x2E,0x45,0xEF,0x57,0x1F,0x00,0x78,0x6F,0x67,0xB0, /* b */
1386 0x08,0x1B,0x94,0x95,0xA3,0xD9,0x54,0x62,0xF5,0xDE,
1387 0x0A,0xA1,0x85,0xEC,
1388 0x36,0xB3,0xDA,0xF8,0xA2,0x32,0x06,0xF9,0xC4,0xF2, /* x */
1389 0x99,0xD7,0xB2,0x1A,0x9C,0x36,0x91,0x37,0xF2,0xC8,
1390 0x4A,0xE1,0xAA,0x0D,
1391 0x76,0x5B,0xE7,0x34,0x33,0xB3,0xF9,0x5E,0x33,0x29, /* y */
1392 0x32,0xE7,0x0E,0xA2,0x45,0xCA,0x24,0x18,0xEA,0x0E,
1393 0xF9,0x80,0x18,0xFB,
1394 0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* order */
1395 0x00,0x00,0x04,0xA2,0x0E,0x90,0xC3,0x90,0x67,0xC8,
1396 0x93,0xBB,0xB9,0xA5 }
808 }; 1397 };
809 1398
810static const unsigned char _EC_X9_62_CHAR2_191V2_SEED[] = { 1399static const struct { EC_CURVE_DATA h; unsigned char data[20+24*6]; }
811 0x08,0x71,0xEF,0x2F,0xEF,0x24,0xD6,0x96,0xE6,0x76, 1400 _EC_X9_62_CHAR2_191V2 = {
812 0x87,0x56,0x15,0x17,0x58,0xBE,0xE0,0xD9,0x5C,0x15}; 1401 { NID_X9_62_characteristic_two_field,20,24,4 },
813static const EC_CURVE_DATA _EC_X9_62_CHAR2_191V2 = { 1402 { 0x08,0x71,0xEF,0x2F,0xEF,0x24,0xD6,0x96,0xE6,0x76, /* seed */
814 NID_X9_62_characteristic_two_field, 1403 0x87,0x56,0x15,0x17,0x58,0xBE,0xE0,0xD9,0x5C,0x15,
815 "800000000000000000000000000000000000000000000201", 1404
816 "401028774D7777C7B7666D1366EA432071274F89FF01E718", 1405 0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* p */
817 "0620048D28BCBD03B6249C99182B7C8CD19700C362C46A01", 1406 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
818 "3809B2B7CC1B28CC5A87926AAD83FD28789E81E2C9E3BF10", 1407 0x00,0x00,0x02,0x01,
819 "17434386626D14F3DBF01760D9213A3E1CF37AEC437D668A", 1408 0x40,0x10,0x28,0x77,0x4D,0x77,0x77,0xC7,0xB7,0x66, /* a */
820 "20000000000000000000000050508CB89F652824E06B8173", 4, 1409 0x6D,0x13,0x66,0xEA,0x43,0x20,0x71,0x27,0x4F,0x89,
821 _EC_X9_62_CHAR2_191V2_SEED, 20, 1410 0xFF,0x01,0xE7,0x18,
822 "X9.62 curve over a 191 bit binary field" 1411 0x06,0x20,0x04,0x8D,0x28,0xBC,0xBD,0x03,0xB6,0x24, /* b */
1412 0x9C,0x99,0x18,0x2B,0x7C,0x8C,0xD1,0x97,0x00,0xC3,
1413 0x62,0xC4,0x6A,0x01,
1414 0x38,0x09,0xB2,0xB7,0xCC,0x1B,0x28,0xCC,0x5A,0x87, /* x */
1415 0x92,0x6A,0xAD,0x83,0xFD,0x28,0x78,0x9E,0x81,0xE2,
1416 0xC9,0xE3,0xBF,0x10,
1417 0x17,0x43,0x43,0x86,0x62,0x6D,0x14,0xF3,0xDB,0xF0, /* y */
1418 0x17,0x60,0xD9,0x21,0x3A,0x3E,0x1C,0xF3,0x7A,0xEC,
1419 0x43,0x7D,0x66,0x8A,
1420 0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* order */
1421 0x00,0x00,0x50,0x50,0x8C,0xB8,0x9F,0x65,0x28,0x24,
1422 0xE0,0x6B,0x81,0x73 }
823 }; 1423 };
824 1424
825static const unsigned char _EC_X9_62_CHAR2_191V3_SEED[] = { 1425static const struct { EC_CURVE_DATA h; unsigned char data[20+24*6]; }
826 0xE0,0x53,0x51,0x2D,0xC6,0x84,0xD6,0x96,0xE6,0x76, 1426 _EC_X9_62_CHAR2_191V3 = {
827 0x87,0x56,0x15,0x17,0x50,0x67,0xAE,0x78,0x6D,0x1F}; 1427 { NID_X9_62_characteristic_two_field,20,24,6 },
828static const EC_CURVE_DATA _EC_X9_62_CHAR2_191V3 = { 1428 { 0xE0,0x53,0x51,0x2D,0xC6,0x84,0xD6,0x96,0xE6,0x76, /* seed */
829 NID_X9_62_characteristic_two_field, 1429 0x87,0x56,0x15,0x17,0x50,0x67,0xAE,0x78,0x6D,0x1F,
830 "800000000000000000000000000000000000000000000201", 1430
831 "6C01074756099122221056911C77D77E77A777E7E7E77FCB", 1431 0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* p */
832 "71FE1AF926CF847989EFEF8DB459F66394D90F32AD3F15E8", 1432 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
833 "375D4CE24FDE434489DE8746E71786015009E66E38A926DD", 1433 0x00,0x00,0x02,0x01,
834 "545A39176196575D985999366E6AD34CE0A77CD7127B06BE", 1434 0x6C,0x01,0x07,0x47,0x56,0x09,0x91,0x22,0x22,0x10, /* a */
835 "155555555555555555555555610C0B196812BFB6288A3EA3", 6, 1435 0x56,0x91,0x1C,0x77,0xD7,0x7E,0x77,0xA7,0x77,0xE7,
836 _EC_X9_62_CHAR2_191V3_SEED, 20, 1436 0xE7,0xE7,0x7F,0xCB,
837 "X9.62 curve over a 191 bit binary field" 1437 0x71,0xFE,0x1A,0xF9,0x26,0xCF,0x84,0x79,0x89,0xEF, /* b */
1438 0xEF,0x8D,0xB4,0x59,0xF6,0x63,0x94,0xD9,0x0F,0x32,
1439 0xAD,0x3F,0x15,0xE8,
1440 0x37,0x5D,0x4C,0xE2,0x4F,0xDE,0x43,0x44,0x89,0xDE, /* x */
1441 0x87,0x46,0xE7,0x17,0x86,0x01,0x50,0x09,0xE6,0x6E,
1442 0x38,0xA9,0x26,0xDD,
1443 0x54,0x5A,0x39,0x17,0x61,0x96,0x57,0x5D,0x98,0x59, /* y */
1444 0x99,0x36,0x6E,0x6A,0xD3,0x4C,0xE0,0xA7,0x7C,0xD7,
1445 0x12,0x7B,0x06,0xBE,
1446 0x15,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, /* order */
1447 0x55,0x55,0x61,0x0C,0x0B,0x19,0x68,0x12,0xBF,0xB6,
1448 0x28,0x8A,0x3E,0xA3 }
838 }; 1449 };
839 1450
840static const EC_CURVE_DATA _EC_X9_62_CHAR2_208W1 = { 1451static const struct { EC_CURVE_DATA h; unsigned char data[0+27*6]; }
841 NID_X9_62_characteristic_two_field, 1452 _EC_X9_62_CHAR2_208W1 = {
842 "010000000000000000000000000000000800000000000000000007", 1453 { NID_X9_62_characteristic_two_field,0,27,0xFE48 },
843 "0000000000000000000000000000000000000000000000000000", 1454 { /* no seed */
844 "C8619ED45A62E6212E1160349E2BFA844439FAFC2A3FD1638F9E", 1455 0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* p */
845 "89FDFBE4ABE193DF9559ECF07AC0CE78554E2784EB8C1ED1A57A", 1456 0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x00,0x00,
846 "0F55B51A06E78E9AC38A035FF520D8B01781BEB1A6BB08617DE3", 1457 0x00,0x00,0x00,0x00,0x00,0x00,0x07,
847 "000101BAF95C9723C57B6C21DA2EFF2D5ED588BDD5717E212F9D", 0xFE48, 1458 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* a */
848 NULL, 0, 1459 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
849 "X9.62 curve over a 208 bit binary field" 1460 0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1461 0x00,0xC8,0x61,0x9E,0xD4,0x5A,0x62,0xE6,0x21,0x2E, /* b */
1462 0x11,0x60,0x34,0x9E,0x2B,0xFA,0x84,0x44,0x39,0xFA,
1463 0xFC,0x2A,0x3F,0xD1,0x63,0x8F,0x9E,
1464 0x00,0x89,0xFD,0xFB,0xE4,0xAB,0xE1,0x93,0xDF,0x95, /* x */
1465 0x59,0xEC,0xF0,0x7A,0xC0,0xCE,0x78,0x55,0x4E,0x27,
1466 0x84,0xEB,0x8C,0x1E,0xD1,0xA5,0x7A,
1467 0x00,0x0F,0x55,0xB5,0x1A,0x06,0xE7,0x8E,0x9A,0xC3, /* y */
1468 0x8A,0x03,0x5F,0xF5,0x20,0xD8,0xB0,0x17,0x81,0xBE,
1469 0xB1,0xA6,0xBB,0x08,0x61,0x7D,0xE3,
1470 0x00,0x00,0x01,0x01,0xBA,0xF9,0x5C,0x97,0x23,0xC5, /* order */
1471 0x7B,0x6C,0x21,0xDA,0x2E,0xFF,0x2D,0x5E,0xD5,0x88,
1472 0xBD,0xD5,0x71,0x7E,0x21,0x2F,0x9D }
850 }; 1473 };
851 1474
852static const unsigned char _EC_X9_62_CHAR2_239V1_SEED[] = { 1475static const struct { EC_CURVE_DATA h; unsigned char data[20+30*6]; }
853 0xD3,0x4B,0x9A,0x4D,0x69,0x6E,0x67,0x68,0x75,0x61, 1476 _EC_X9_62_CHAR2_239V1 = {
854 0x51,0x75,0xCA,0x71,0xB9,0x20,0xBF,0xEF,0xB0,0x5D}; 1477 { NID_X9_62_characteristic_two_field,20,30,4 },
855static const EC_CURVE_DATA _EC_X9_62_CHAR2_239V1 = { 1478 { 0xD3,0x4B,0x9A,0x4D,0x69,0x6E,0x67,0x68,0x75,0x61, /* seed */
856 NID_X9_62_characteristic_two_field, 1479 0x51,0x75,0xCA,0x71,0xB9,0x20,0xBF,0xEF,0xB0,0x5D,
857 "800000000000000000000000000000000000000000000000001000000001", 1480
858 "32010857077C5431123A46B808906756F543423E8D27877578125778AC76", 1481 0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* p */
859 "790408F2EEDAF392B012EDEFB3392F30F4327C0CA3F31FC383C422AA8C16", 1482 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
860 "57927098FA932E7C0A96D3FD5B706EF7E5F5C156E16B7E7C86038552E91D", 1483 0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x01,
861 "61D8EE5077C33FECF6F1A16B268DE469C3C7744EA9A971649FC7A9616305", 1484
862 "2000000000000000000000000000000F4D42FFE1492A4993F1CAD666E447", 4, 1485 0x32,0x01,0x08,0x57,0x07,0x7C,0x54,0x31,0x12,0x3A, /* a */
863 _EC_X9_62_CHAR2_239V1_SEED, 20, 1486 0x46,0xB8,0x08,0x90,0x67,0x56,0xF5,0x43,0x42,0x3E,
864 "X9.62 curve over a 239 bit binary field" 1487 0x8D,0x27,0x87,0x75,0x78,0x12,0x57,0x78,0xAC,0x76,
1488
1489 0x79,0x04,0x08,0xF2,0xEE,0xDA,0xF3,0x92,0xB0,0x12, /* b */
1490 0xED,0xEF,0xB3,0x39,0x2F,0x30,0xF4,0x32,0x7C,0x0C,
1491 0xA3,0xF3,0x1F,0xC3,0x83,0xC4,0x22,0xAA,0x8C,0x16,
1492
1493 0x57,0x92,0x70,0x98,0xFA,0x93,0x2E,0x7C,0x0A,0x96, /* x */
1494 0xD3,0xFD,0x5B,0x70,0x6E,0xF7,0xE5,0xF5,0xC1,0x56,
1495 0xE1,0x6B,0x7E,0x7C,0x86,0x03,0x85,0x52,0xE9,0x1D,
1496
1497 0x61,0xD8,0xEE,0x50,0x77,0xC3,0x3F,0xEC,0xF6,0xF1, /* y */
1498 0xA1,0x6B,0x26,0x8D,0xE4,0x69,0xC3,0xC7,0x74,0x4E,
1499 0xA9,0xA9,0x71,0x64,0x9F,0xC7,0xA9,0x61,0x63,0x05,
1500
1501 0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* order */
1502 0x00,0x00,0x00,0x00,0x00,0x0F,0x4D,0x42,0xFF,0xE1,
1503 0x49,0x2A,0x49,0x93,0xF1,0xCA,0xD6,0x66,0xE4,0x47 }
865 }; 1504 };
866 1505
867static const unsigned char _EC_X9_62_CHAR2_239V2_SEED[] = { 1506static const struct { EC_CURVE_DATA h; unsigned char data[20+30*6]; }
868 0x2A,0xA6,0x98,0x2F,0xDF,0xA4,0xD6,0x96,0xE6,0x76, 1507 _EC_X9_62_CHAR2_239V2 = {
869 0x87,0x56,0x15,0x17,0x5D,0x26,0x67,0x27,0x27,0x7D}; 1508 { NID_X9_62_characteristic_two_field,20,30,6 },
870static const EC_CURVE_DATA _EC_X9_62_CHAR2_239V2 = { 1509 { 0x2A,0xA6,0x98,0x2F,0xDF,0xA4,0xD6,0x96,0xE6,0x76, /* seed */
871 NID_X9_62_characteristic_two_field, 1510 0x87,0x56,0x15,0x17,0x5D,0x26,0x67,0x27,0x27,0x7D,
872 "800000000000000000000000000000000000000000000000001000000001", 1511
873 "4230017757A767FAE42398569B746325D45313AF0766266479B75654E65F", 1512 0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* p */
874 "5037EA654196CFF0CD82B2C14A2FCF2E3FF8775285B545722F03EACDB74B", 1513 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
875 "28F9D04E900069C8DC47A08534FE76D2B900B7D7EF31F5709F200C4CA205", 1514 0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x01,
876 "5667334C45AFF3B5A03BAD9DD75E2C71A99362567D5453F7FA6E227EC833", 1515
877 "1555555555555555555555555555553C6F2885259C31E3FCDF154624522D", 6, 1516 0x42,0x30,0x01,0x77,0x57,0xA7,0x67,0xFA,0xE4,0x23, /* a */
878 _EC_X9_62_CHAR2_239V2_SEED, 20, 1517 0x98,0x56,0x9B,0x74,0x63,0x25,0xD4,0x53,0x13,0xAF,
879 "X9.62 curve over a 239 bit binary field" 1518 0x07,0x66,0x26,0x64,0x79,0xB7,0x56,0x54,0xE6,0x5F,
1519
1520 0x50,0x37,0xEA,0x65,0x41,0x96,0xCF,0xF0,0xCD,0x82, /* b */
1521 0xB2,0xC1,0x4A,0x2F,0xCF,0x2E,0x3F,0xF8,0x77,0x52,
1522 0x85,0xB5,0x45,0x72,0x2F,0x03,0xEA,0xCD,0xB7,0x4B,
1523
1524 0x28,0xF9,0xD0,0x4E,0x90,0x00,0x69,0xC8,0xDC,0x47, /* x */
1525 0xA0,0x85,0x34,0xFE,0x76,0xD2,0xB9,0x00,0xB7,0xD7,
1526 0xEF,0x31,0xF5,0x70,0x9F,0x20,0x0C,0x4C,0xA2,0x05,
1527
1528 0x56,0x67,0x33,0x4C,0x45,0xAF,0xF3,0xB5,0xA0,0x3B, /* y */
1529 0xAD,0x9D,0xD7,0x5E,0x2C,0x71,0xA9,0x93,0x62,0x56,
1530 0x7D,0x54,0x53,0xF7,0xFA,0x6E,0x22,0x7E,0xC8,0x33,
1531
1532 0x15,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, /* order */
1533 0x55,0x55,0x55,0x55,0x55,0x3C,0x6F,0x28,0x85,0x25,
1534 0x9C,0x31,0xE3,0xFC,0xDF,0x15,0x46,0x24,0x52,0x2D }
880 }; 1535 };
881 1536
882static const unsigned char _EC_X9_62_CHAR2_239V3_SEED[] = { 1537static const struct { EC_CURVE_DATA h; unsigned char data[20+30*6]; }
883 0x9E,0x07,0x6F,0x4D,0x69,0x6E,0x67,0x68,0x75,0x61, 1538 _EC_X9_62_CHAR2_239V3 = {
884 0x51,0x75,0xE1,0x1E,0x9F,0xDD,0x77,0xF9,0x20,0x41}; 1539 { NID_X9_62_characteristic_two_field,20,30,0xA },
885static const EC_CURVE_DATA _EC_X9_62_CHAR2_239V3 = { 1540 { 0x9E,0x07,0x6F,0x4D,0x69,0x6E,0x67,0x68,0x75,0x61, /* seed */
886 NID_X9_62_characteristic_two_field, 1541 0x51,0x75,0xE1,0x1E,0x9F,0xDD,0x77,0xF9,0x20,0x41,
887 "800000000000000000000000000000000000000000000000001000000001", 1542
888 "01238774666A67766D6676F778E676B66999176666E687666D8766C66A9F", 1543 0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* p */
889 "6A941977BA9F6A435199ACFC51067ED587F519C5ECB541B8E44111DE1D40", 1544 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
890 "70F6E9D04D289C4E89913CE3530BFDE903977D42B146D539BF1BDE4E9C92", 1545 0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x01,
891 "2E5A0EAF6E5E1305B9004DCE5C0ED7FE59A35608F33837C816D80B79F461", 1546
892 "0CCCCCCCCCCCCCCCCCCCCCCCCCCCCCAC4912D2D9DF903EF9888B8A0E4CFF", 0xA, 1547 0x01,0x23,0x87,0x74,0x66,0x6A,0x67,0x76,0x6D,0x66, /* a */
893 _EC_X9_62_CHAR2_239V3_SEED, 20, 1548 0x76,0xF7,0x78,0xE6,0x76,0xB6,0x69,0x99,0x17,0x66,
894 "X9.62 curve over a 239 bit binary field" 1549 0x66,0xE6,0x87,0x66,0x6D,0x87,0x66,0xC6,0x6A,0x9F,
1550
1551 0x6A,0x94,0x19,0x77,0xBA,0x9F,0x6A,0x43,0x51,0x99, /* b */
1552 0xAC,0xFC,0x51,0x06,0x7E,0xD5,0x87,0xF5,0x19,0xC5,
1553 0xEC,0xB5,0x41,0xB8,0xE4,0x41,0x11,0xDE,0x1D,0x40,
1554
1555 0x70,0xF6,0xE9,0xD0,0x4D,0x28,0x9C,0x4E,0x89,0x91, /* x */
1556 0x3C,0xE3,0x53,0x0B,0xFD,0xE9,0x03,0x97,0x7D,0x42,
1557 0xB1,0x46,0xD5,0x39,0xBF,0x1B,0xDE,0x4E,0x9C,0x92,
1558
1559 0x2E,0x5A,0x0E,0xAF,0x6E,0x5E,0x13,0x05,0xB9,0x00, /* y */
1560 0x4D,0xCE,0x5C,0x0E,0xD7,0xFE,0x59,0xA3,0x56,0x08,
1561 0xF3,0x38,0x37,0xC8,0x16,0xD8,0x0B,0x79,0xF4,0x61,
1562
1563 0x0C,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC, /* order */
1564 0xCC,0xCC,0xCC,0xCC,0xCC,0xAC,0x49,0x12,0xD2,0xD9,
1565 0xDF,0x90,0x3E,0xF9,0x88,0x8B,0x8A,0x0E,0x4C,0xFF }
895 }; 1566 };
896 1567
897static const EC_CURVE_DATA _EC_X9_62_CHAR2_272W1 = { 1568static const struct { EC_CURVE_DATA h; unsigned char data[0+35*6]; }
898 NID_X9_62_characteristic_two_field, 1569 _EC_X9_62_CHAR2_272W1 = {
899 "010000000000000000000000000000000000000000000000000000010000000000000" 1570 { NID_X9_62_characteristic_two_field,0,35,0xFF06 },
900 "B", 1571 { /* no seed */
901 "91A091F03B5FBA4AB2CCF49C4EDD220FB028712D42BE752B2C40094DBACDB586FB20", 1572 0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* p */
902 "7167EFC92BB2E3CE7C8AAAFF34E12A9C557003D7C73A6FAF003F99F6CC8482E540F7", 1573 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
903 "6108BABB2CEEBCF787058A056CBE0CFE622D7723A289E08A07AE13EF0D10D171DD8D", 1574 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,
904 "10C7695716851EEF6BA7F6872E6142FBD241B830FF5EFCACECCAB05E02005DDE9D23", 1575 0x00,0x00,0x00,0x00,0x0B,
905 "000100FAF51354E0E39E4892DF6E319C72C8161603FA45AA7B998A167B8F1E629521", 1576 0x00,0x91,0xA0,0x91,0xF0,0x3B,0x5F,0xBA,0x4A,0xB2, /* a */
906 0xFF06, 1577 0xCC,0xF4,0x9C,0x4E,0xDD,0x22,0x0F,0xB0,0x28,0x71,
907 NULL, 0, 1578 0x2D,0x42,0xBE,0x75,0x2B,0x2C,0x40,0x09,0x4D,0xBA,
908 "X9.62 curve over a 272 bit binary field" 1579 0xCD,0xB5,0x86,0xFB,0x20,
1580 0x00,0x71,0x67,0xEF,0xC9,0x2B,0xB2,0xE3,0xCE,0x7C, /* b */
1581 0x8A,0xAA,0xFF,0x34,0xE1,0x2A,0x9C,0x55,0x70,0x03,
1582 0xD7,0xC7,0x3A,0x6F,0xAF,0x00,0x3F,0x99,0xF6,0xCC,
1583 0x84,0x82,0xE5,0x40,0xF7,
1584 0x00,0x61,0x08,0xBA,0xBB,0x2C,0xEE,0xBC,0xF7,0x87, /* x */
1585 0x05,0x8A,0x05,0x6C,0xBE,0x0C,0xFE,0x62,0x2D,0x77,
1586 0x23,0xA2,0x89,0xE0,0x8A,0x07,0xAE,0x13,0xEF,0x0D,
1587 0x10,0xD1,0x71,0xDD,0x8D,
1588 0x00,0x10,0xC7,0x69,0x57,0x16,0x85,0x1E,0xEF,0x6B, /* y */
1589 0xA7,0xF6,0x87,0x2E,0x61,0x42,0xFB,0xD2,0x41,0xB8,
1590 0x30,0xFF,0x5E,0xFC,0xAC,0xEC,0xCA,0xB0,0x5E,0x02,
1591 0x00,0x5D,0xDE,0x9D,0x23,
1592 0x00,0x00,0x01,0x00,0xFA,0xF5,0x13,0x54,0xE0,0xE3, /* order */
1593 0x9E,0x48,0x92,0xDF,0x6E,0x31,0x9C,0x72,0xC8,0x16,
1594 0x16,0x03,0xFA,0x45,0xAA,0x7B,0x99,0x8A,0x16,0x7B,
1595 0x8F,0x1E,0x62,0x95,0x21 }
909 }; 1596 };
910 1597
911static const EC_CURVE_DATA _EC_X9_62_CHAR2_304W1 = { 1598static const struct { EC_CURVE_DATA h; unsigned char data[0+39*6]; }
912 NID_X9_62_characteristic_two_field, 1599 _EC_X9_62_CHAR2_304W1 = {
913 "010000000000000000000000000000000000000000000000000000000000000000000" 1600 { NID_X9_62_characteristic_two_field,0,39,0xFE2E },
914 "000000807", 1601 { /* no seed */
915 "FD0D693149A118F651E6DCE6802085377E5F882D1B510B44160074C1288078365A039" 1602 0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* p */
916 "6C8E681", 1603 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
917 "BDDB97E555A50A908E43B01C798EA5DAA6788F1EA2794EFCF57166B8C14039601E558" 1604 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
918 "27340BE", 1605 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x07,
919 "197B07845E9BE2D96ADB0F5F3C7F2CFFBD7A3EB8B6FEC35C7FD67F26DDF6285A644F7" 1606 0x00,0xFD,0x0D,0x69,0x31,0x49,0xA1,0x18,0xF6,0x51, /* a */
920 "40A2614", 1607 0xE6,0xDC,0xE6,0x80,0x20,0x85,0x37,0x7E,0x5F,0x88,
921 "E19FBEB76E0DA171517ECF401B50289BF014103288527A9B416A105E80260B549FDC1" 1608 0x2D,0x1B,0x51,0x0B,0x44,0x16,0x00,0x74,0xC1,0x28,
922 "B92C03B", 1609 0x80,0x78,0x36,0x5A,0x03,0x96,0xC8,0xE6,0x81,
923 "000101D556572AABAC800101D556572AABAC8001022D5C91DD173F8FB561DA6899164" 1610 0x00,0xBD,0xDB,0x97,0xE5,0x55,0xA5,0x0A,0x90,0x8E, /* b */
924 "443051D", 0xFE2E, 1611 0x43,0xB0,0x1C,0x79,0x8E,0xA5,0xDA,0xA6,0x78,0x8F,
925 NULL, 0, 1612 0x1E,0xA2,0x79,0x4E,0xFC,0xF5,0x71,0x66,0xB8,0xC1,
926 "X9.62 curve over a 304 bit binary field" 1613 0x40,0x39,0x60,0x1E,0x55,0x82,0x73,0x40,0xBE,
1614 0x00,0x19,0x7B,0x07,0x84,0x5E,0x9B,0xE2,0xD9,0x6A, /* x */
1615 0xDB,0x0F,0x5F,0x3C,0x7F,0x2C,0xFF,0xBD,0x7A,0x3E,
1616 0xB8,0xB6,0xFE,0xC3,0x5C,0x7F,0xD6,0x7F,0x26,0xDD,
1617 0xF6,0x28,0x5A,0x64,0x4F,0x74,0x0A,0x26,0x14,
1618 0x00,0xE1,0x9F,0xBE,0xB7,0x6E,0x0D,0xA1,0x71,0x51, /* y */
1619 0x7E,0xCF,0x40,0x1B,0x50,0x28,0x9B,0xF0,0x14,0x10,
1620 0x32,0x88,0x52,0x7A,0x9B,0x41,0x6A,0x10,0x5E,0x80,
1621 0x26,0x0B,0x54,0x9F,0xDC,0x1B,0x92,0xC0,0x3B,
1622 0x00,0x00,0x01,0x01,0xD5,0x56,0x57,0x2A,0xAB,0xAC, /* order */
1623 0x80,0x01,0x01,0xD5,0x56,0x57,0x2A,0xAB,0xAC,0x80,
1624 0x01,0x02,0x2D,0x5C,0x91,0xDD,0x17,0x3F,0x8F,0xB5,
1625 0x61,0xDA,0x68,0x99,0x16,0x44,0x43,0x05,0x1D }
927 }; 1626 };
928 1627
929static const unsigned char _EC_X9_62_CHAR2_359V1_SEED[] = { 1628static const struct { EC_CURVE_DATA h; unsigned char data[20+45*6]; }
930 0x2B,0x35,0x49,0x20,0xB7,0x24,0xD6,0x96,0xE6,0x76, 1629 _EC_X9_62_CHAR2_359V1 = {
931 0x87,0x56,0x15,0x17,0x58,0x5B,0xA1,0x33,0x2D,0xC6}; 1630 { NID_X9_62_characteristic_two_field,20,45,0x4C },
932static const EC_CURVE_DATA _EC_X9_62_CHAR2_359V1 = { 1631 { 0x2B,0x35,0x49,0x20,0xB7,0x24,0xD6,0x96,0xE6,0x76, /* seed */
933 NID_X9_62_characteristic_two_field, 1632 0x87,0x56,0x15,0x17,0x58,0x5B,0xA1,0x33,0x2D,0xC6,
934 "800000000000000000000000000000000000000000000000000000000000000000000" 1633
935 "000100000000000000001", 1634 0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* p */
936 "5667676A654B20754F356EA92017D946567C46675556F19556A04616B567D223A5E05" 1635 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
937 "656FB549016A96656A557", 1636 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
938 "2472E2D0197C49363F1FE7F5B6DB075D52B6947D135D8CA445805D39BC34562608968" 1637 0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x00,0x00,
939 "7742B6329E70680231988", 1638 0x00,0x00,0x00,0x00,0x01,
940 "3C258EF3047767E7EDE0F1FDAA79DAEE3841366A132E163ACED4ED2401DF9C6BDCDE9" 1639 0x56,0x67,0x67,0x6A,0x65,0x4B,0x20,0x75,0x4F,0x35, /* a */
941 "8E8E707C07A2239B1B097", 1640 0x6E,0xA9,0x20,0x17,0xD9,0x46,0x56,0x7C,0x46,0x67,
942 "53D7E08529547048121E9C95F3791DD804963948F34FAE7BF44EA82365DC7868FE57E" 1641 0x55,0x56,0xF1,0x95,0x56,0xA0,0x46,0x16,0xB5,0x67,
943 "4AE2DE211305A407104BD", 1642 0xD2,0x23,0xA5,0xE0,0x56,0x56,0xFB,0x54,0x90,0x16,
944 "01AF286BCA1AF286BCA1AF286BCA1AF286BCA1AF286BC9FB8F6B85C556892C20A7EB9" 1643 0xA9,0x66,0x56,0xA5,0x57,
945 "64FE7719E74F490758D3B", 0x4C, 1644 0x24,0x72,0xE2,0xD0,0x19,0x7C,0x49,0x36,0x3F,0x1F, /* b */
946 _EC_X9_62_CHAR2_359V1_SEED, 20, 1645 0xE7,0xF5,0xB6,0xDB,0x07,0x5D,0x52,0xB6,0x94,0x7D,
947 "X9.62 curve over a 359 bit binary field" 1646 0x13,0x5D,0x8C,0xA4,0x45,0x80,0x5D,0x39,0xBC,0x34,
1647 0x56,0x26,0x08,0x96,0x87,0x74,0x2B,0x63,0x29,0xE7,
1648 0x06,0x80,0x23,0x19,0x88,
1649 0x3C,0x25,0x8E,0xF3,0x04,0x77,0x67,0xE7,0xED,0xE0, /* x */
1650 0xF1,0xFD,0xAA,0x79,0xDA,0xEE,0x38,0x41,0x36,0x6A,
1651 0x13,0x2E,0x16,0x3A,0xCE,0xD4,0xED,0x24,0x01,0xDF,
1652 0x9C,0x6B,0xDC,0xDE,0x98,0xE8,0xE7,0x07,0xC0,0x7A,
1653 0x22,0x39,0xB1,0xB0,0x97,
1654 0x53,0xD7,0xE0,0x85,0x29,0x54,0x70,0x48,0x12,0x1E, /* y */
1655 0x9C,0x95,0xF3,0x79,0x1D,0xD8,0x04,0x96,0x39,0x48,
1656 0xF3,0x4F,0xAE,0x7B,0xF4,0x4E,0xA8,0x23,0x65,0xDC,
1657 0x78,0x68,0xFE,0x57,0xE4,0xAE,0x2D,0xE2,0x11,0x30,
1658 0x5A,0x40,0x71,0x04,0xBD,
1659 0x01,0xAF,0x28,0x6B,0xCA,0x1A,0xF2,0x86,0xBC,0xA1, /* order */
1660 0xAF,0x28,0x6B,0xCA,0x1A,0xF2,0x86,0xBC,0xA1,0xAF,
1661 0x28,0x6B,0xC9,0xFB,0x8F,0x6B,0x85,0xC5,0x56,0x89,
1662 0x2C,0x20,0xA7,0xEB,0x96,0x4F,0xE7,0x71,0x9E,0x74,
1663 0xF4,0x90,0x75,0x8D,0x3B }
948 }; 1664 };
949 1665
950static const EC_CURVE_DATA _EC_X9_62_CHAR2_368W1 = { 1666static const struct { EC_CURVE_DATA h; unsigned char data[0+47*6]; }
951 NID_X9_62_characteristic_two_field, 1667 _EC_X9_62_CHAR2_368W1 = {
952 "010000000000000000000000000000000000000000000000000000000000000000000" 1668 { NID_X9_62_characteristic_two_field,0,47,0xFF70 },
953 "0002000000000000000000007", 1669 { /* no seed */
954 "E0D2EE25095206F5E2A4F9ED229F1F256E79A0E2B455970D8D0D865BD94778C576D62" 1670 0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* p */
955 "F0AB7519CCD2A1A906AE30D", 1671 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
956 "FC1217D4320A90452C760A58EDCD30C8DD069B3C34453837A34ED50CB54917E1C2112" 1672 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
957 "D84D164F444F8F74786046A", 1673 0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x00,
958 "1085E2755381DCCCE3C1557AFA10C2F0C0C2825646C5B34A394CBCFA8BC16B22E7E78" 1674 0x00,0x00,0x00,0x00,0x00,0x00,0x07,
959 "9E927BE216F02E1FB136A5F", 1675 0x00,0xE0,0xD2,0xEE,0x25,0x09,0x52,0x06,0xF5,0xE2, /* a */
960 "7B3EB1BDDCBA62D5D8B2059B525797FC73822C59059C623A45FF3843CEE8F87CD1855" 1676 0xA4,0xF9,0xED,0x22,0x9F,0x1F,0x25,0x6E,0x79,0xA0,
961 "ADAA81E2A0750B80FDA2310", 1677 0xE2,0xB4,0x55,0x97,0x0D,0x8D,0x0D,0x86,0x5B,0xD9,
962 "00010090512DA9AF72B08349D98A5DD4C7B0532ECA51CE03E2D10F3B7AC579BD87E90" 1678 0x47,0x78,0xC5,0x76,0xD6,0x2F,0x0A,0xB7,0x51,0x9C,
963 "9AE40A6F131E9CFCE5BD967", 0xFF70, 1679 0xCD,0x2A,0x1A,0x90,0x6A,0xE3,0x0D,
964 NULL, 0, 1680 0x00,0xFC,0x12,0x17,0xD4,0x32,0x0A,0x90,0x45,0x2C, /* b */
965 "X9.62 curve over a 368 bit binary field" 1681 0x76,0x0A,0x58,0xED,0xCD,0x30,0xC8,0xDD,0x06,0x9B,
1682 0x3C,0x34,0x45,0x38,0x37,0xA3,0x4E,0xD5,0x0C,0xB5,
1683 0x49,0x17,0xE1,0xC2,0x11,0x2D,0x84,0xD1,0x64,0xF4,
1684 0x44,0xF8,0xF7,0x47,0x86,0x04,0x6A,
1685 0x00,0x10,0x85,0xE2,0x75,0x53,0x81,0xDC,0xCC,0xE3, /* x */
1686 0xC1,0x55,0x7A,0xFA,0x10,0xC2,0xF0,0xC0,0xC2,0x82,
1687 0x56,0x46,0xC5,0xB3,0x4A,0x39,0x4C,0xBC,0xFA,0x8B,
1688 0xC1,0x6B,0x22,0xE7,0xE7,0x89,0xE9,0x27,0xBE,0x21,
1689 0x6F,0x02,0xE1,0xFB,0x13,0x6A,0x5F,
1690 0x00,0x7B,0x3E,0xB1,0xBD,0xDC,0xBA,0x62,0xD5,0xD8, /* y */
1691 0xB2,0x05,0x9B,0x52,0x57,0x97,0xFC,0x73,0x82,0x2C,
1692 0x59,0x05,0x9C,0x62,0x3A,0x45,0xFF,0x38,0x43,0xCE,
1693 0xE8,0xF8,0x7C,0xD1,0x85,0x5A,0xDA,0xA8,0x1E,0x2A,
1694 0x07,0x50,0xB8,0x0F,0xDA,0x23,0x10,
1695 0x00,0x00,0x01,0x00,0x90,0x51,0x2D,0xA9,0xAF,0x72, /* order */
1696 0xB0,0x83,0x49,0xD9,0x8A,0x5D,0xD4,0xC7,0xB0,0x53,
1697 0x2E,0xCA,0x51,0xCE,0x03,0xE2,0xD1,0x0F,0x3B,0x7A,
1698 0xC5,0x79,0xBD,0x87,0xE9,0x09,0xAE,0x40,0xA6,0xF1,
1699 0x31,0xE9,0xCF,0xCE,0x5B,0xD9,0x67 }
966 }; 1700 };
967 1701
968static const EC_CURVE_DATA _EC_X9_62_CHAR2_431R1 = { 1702static const struct { EC_CURVE_DATA h; unsigned char data[0+54*6]; }
969 NID_X9_62_characteristic_two_field, 1703 _EC_X9_62_CHAR2_431R1 = {
970 "800000000000000000000000000000000000000000000000000000000000000000000" 1704 { NID_X9_62_characteristic_two_field,0,54,0x2760 },
971 "000000001000000000000000000000000000001", 1705 { /* no seed */
972 "1A827EF00DD6FC0E234CAF046C6A5D8A85395B236CC4AD2CF32A0CADBDC9DDF620B0E" 1706 0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* p */
973 "B9906D0957F6C6FEACD615468DF104DE296CD8F", 1707 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
974 "10D9B4A3D9047D8B154359ABFB1B7F5485B04CEB868237DDC9DEDA982A679A5A919B6" 1708 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
975 "26D4E50A8DD731B107A9962381FB5D807BF2618", 1709 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,
976 "120FC05D3C67A99DE161D2F4092622FECA701BE4F50F4758714E8A87BBF2A658EF8C2" 1710 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
977 "1E7C5EFE965361F6C2999C0C247B0DBD70CE6B7", 1711 0x00,0x00,0x00,0x01,
978 "20D0AF8903A96F8D5FA2C255745D3C451B302C9346D9B7E485E7BCE41F6B591F3E8F6" 1712 0x1A,0x82,0x7E,0xF0,0x0D,0xD6,0xFC,0x0E,0x23,0x4C, /* a */
979 "ADDCBB0BC4C2F947A7DE1A89B625D6A598B3760", 1713 0xAF,0x04,0x6C,0x6A,0x5D,0x8A,0x85,0x39,0x5B,0x23,
980 "0340340340340340340340340340340340340340340340340340340323C313FAB5058" 1714 0x6C,0xC4,0xAD,0x2C,0xF3,0x2A,0x0C,0xAD,0xBD,0xC9,
981 "9703B5EC68D3587FEC60D161CC149C1AD4A91", 0x2760, 1715 0xDD,0xF6,0x20,0xB0,0xEB,0x99,0x06,0xD0,0x95,0x7F,
982 NULL, 0, 1716 0x6C,0x6F,0xEA,0xCD,0x61,0x54,0x68,0xDF,0x10,0x4D,
983 "X9.62 curve over a 431 bit binary field" 1717 0xE2,0x96,0xCD,0x8F,
1718 0x10,0xD9,0xB4,0xA3,0xD9,0x04,0x7D,0x8B,0x15,0x43, /* b */
1719 0x59,0xAB,0xFB,0x1B,0x7F,0x54,0x85,0xB0,0x4C,0xEB,
1720 0x86,0x82,0x37,0xDD,0xC9,0xDE,0xDA,0x98,0x2A,0x67,
1721 0x9A,0x5A,0x91,0x9B,0x62,0x6D,0x4E,0x50,0xA8,0xDD,
1722 0x73,0x1B,0x10,0x7A,0x99,0x62,0x38,0x1F,0xB5,0xD8,
1723 0x07,0xBF,0x26,0x18,
1724 0x12,0x0F,0xC0,0x5D,0x3C,0x67,0xA9,0x9D,0xE1,0x61, /* x */
1725 0xD2,0xF4,0x09,0x26,0x22,0xFE,0xCA,0x70,0x1B,0xE4,
1726 0xF5,0x0F,0x47,0x58,0x71,0x4E,0x8A,0x87,0xBB,0xF2,
1727 0xA6,0x58,0xEF,0x8C,0x21,0xE7,0xC5,0xEF,0xE9,0x65,
1728 0x36,0x1F,0x6C,0x29,0x99,0xC0,0xC2,0x47,0xB0,0xDB,
1729 0xD7,0x0C,0xE6,0xB7,
1730 0x20,0xD0,0xAF,0x89,0x03,0xA9,0x6F,0x8D,0x5F,0xA2, /* y */
1731 0xC2,0x55,0x74,0x5D,0x3C,0x45,0x1B,0x30,0x2C,0x93,
1732 0x46,0xD9,0xB7,0xE4,0x85,0xE7,0xBC,0xE4,0x1F,0x6B,
1733 0x59,0x1F,0x3E,0x8F,0x6A,0xDD,0xCB,0xB0,0xBC,0x4C,
1734 0x2F,0x94,0x7A,0x7D,0xE1,0xA8,0x9B,0x62,0x5D,0x6A,
1735 0x59,0x8B,0x37,0x60,
1736 0x00,0x03,0x40,0x34,0x03,0x40,0x34,0x03,0x40,0x34, /* order */
1737 0x03,0x40,0x34,0x03,0x40,0x34,0x03,0x40,0x34,0x03,
1738 0x40,0x34,0x03,0x40,0x34,0x03,0x40,0x34,0x03,0x23,
1739 0xC3,0x13,0xFA,0xB5,0x05,0x89,0x70,0x3B,0x5E,0xC6,
1740 0x8D,0x35,0x87,0xFE,0xC6,0x0D,0x16,0x1C,0xC1,0x49,
1741 0xC1,0xAD,0x4A,0x91 }
984 }; 1742 };
985 1743
986static const EC_CURVE_DATA _EC_WTLS_1 = { 1744static const struct { EC_CURVE_DATA h; unsigned char data[0+15*6]; }
987 NID_X9_62_characteristic_two_field, 1745 _EC_WTLS_1 = {
988 "020000000000000000000000000201", 1746 { NID_X9_62_characteristic_two_field,0,15,2 },
989 "1", 1747 { /* no seed */
990 "1", 1748 0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* p */
991 "01667979A40BA497E5D5C270780617", 1749 0x00,0x00,0x00,0x02,0x01,
992 "00F44B4AF1ECC2630E08785CEBCC15", 1750 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* a */
993 "00FFFFFFFFFFFFFFFDBF91AF6DEA73", 2, 1751 0x00,0x00,0x00,0x00,0x01,
994 NULL, 0, 1752 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* b */
995 "WTLS curve over a 113 bit binary field" 1753 0x00,0x00,0x00,0x00,0x01,
1754 0x01,0x66,0x79,0x79,0xA4,0x0B,0xA4,0x97,0xE5,0xD5, /* x */
1755 0xC2,0x70,0x78,0x06,0x17,
1756 0x00,0xF4,0x4B,0x4A,0xF1,0xEC,0xC2,0x63,0x0E,0x08, /* y */
1757 0x78,0x5C,0xEB,0xCC,0x15,
1758 0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFD,0xBF, /* order */
1759 0x91,0xAF,0x6D,0xEA,0x73 }
996 }; 1760 };
997 1761
998/* IPSec curves */ 1762/* IPSec curves */
@@ -1001,17 +1765,27 @@ static const EC_CURVE_DATA _EC_WTLS_1 = {
1001 * As the group order is not a prime this curve is not suitable 1765 * As the group order is not a prime this curve is not suitable
1002 * for ECDSA. 1766 * for ECDSA.
1003 */ 1767 */
1004static const EC_CURVE_DATA _EC_IPSEC_155_ID3 = { 1768static const struct { EC_CURVE_DATA h; unsigned char data[0+20*6]; }
1005 NID_X9_62_characteristic_two_field, 1769 _EC_IPSEC_155_ID3 = {
1006 "0800000000000000000000004000000000000001", 1770 { NID_X9_62_characteristic_two_field,0,20,3 },
1007 "0", 1771 { /* no seed */
1008 "07338f", 1772 0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* p */
1009 "7b", 1773 0x00,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x01,
1010 "1c8", 1774
1011 "2AAAAAAAAAAAAAAAAAAC7F3C7881BD0868FA86C",3, 1775 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* a */
1012 NULL, 0, 1776 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1013 "\n\tIPSec/IKE/Oakley curve #3 over a 155 bit binary field.\n" 1777
1014 "\tNot suitable for ECDSA.\n\tQuestionable extension field!" 1778 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* b */
1779 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x33,0x8f,
1780
1781 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* x */
1782 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7b,
1783
1784 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* y */
1785 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0xc8,
1786
1787 0x02,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA, /* order */
1788 0xC7,0xF3,0xC7,0x88,0x1B,0xD0,0x86,0x8F,0xA8,0x6C }
1015 }; 1789 };
1016 1790
1017/* NOTE: The of curves over a extension field of non prime degree 1791/* NOTE: The of curves over a extension field of non prime degree
@@ -1019,106 +1793,118 @@ static const EC_CURVE_DATA _EC_IPSEC_155_ID3 = {
1019 * As the group order is not a prime this curve is not suitable 1793 * As the group order is not a prime this curve is not suitable
1020 * for ECDSA. 1794 * for ECDSA.
1021 */ 1795 */
1022static const EC_CURVE_DATA _EC_IPSEC_185_ID4 = { 1796static const struct { EC_CURVE_DATA h; unsigned char data[0+24*6]; }
1023 NID_X9_62_characteristic_two_field, 1797 _EC_IPSEC_185_ID4 = {
1024 "020000000000000000000000000000200000000000000001", 1798 { NID_X9_62_characteristic_two_field,0,24,2 },
1025 "0", 1799 { /* no seed */
1026 "1ee9", 1800 0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* p */
1027 "18", 1801 0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x00,
1028 "0d", 1802 0x00,0x00,0x00,0x01,
1029 "FFFFFFFFFFFFFFFFFFFFFFEDF97C44DB9F2420BAFCA75E",2, 1803 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* a */
1030 NULL, 0, 1804 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1031 "\n\tIPSec/IKE/Oakley curve #4 over a 185 bit binary field.\n" 1805 0x00,0x00,0x00,0x00,
1032 "\tNot suitable for ECDSA.\n\tQuestionable extension field!" 1806 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* b */
1807 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1808 0x00,0x00,0x1e,0xe9,
1809 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* x */
1810 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1811 0x00,0x00,0x00,0x18,
1812 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* y */
1813 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1814 0x00,0x00,0x00,0x0d,
1815 0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* order */
1816 0xFF,0xFF,0xED,0xF9,0x7C,0x44,0xDB,0x9F,0x24,0x20,
1817 0xBA,0xFC,0xA7,0x5E }
1033 }; 1818 };
1034 1819
1035typedef struct _ec_list_element_st { 1820typedef struct _ec_list_element_st {
1036 int nid; 1821 int nid;
1037 const EC_CURVE_DATA *data; 1822 const EC_CURVE_DATA *data;
1823 const char *comment;
1038 } ec_list_element; 1824 } ec_list_element;
1039 1825
1040static const ec_list_element curve_list[] = { 1826static const ec_list_element curve_list[] = {
1041 /* prime field curves */ 1827 /* prime field curves */
1042 /* secg curves */ 1828 /* secg curves */
1043 { NID_secp112r1, &_EC_SECG_PRIME_112R1}, 1829 { NID_secp112r1, &_EC_SECG_PRIME_112R1.h, "SECG/WTLS curve over a 112 bit prime field"},
1044 { NID_secp112r2, &_EC_SECG_PRIME_112R2}, 1830 { NID_secp112r2, &_EC_SECG_PRIME_112R2.h, "SECG curve over a 112 bit prime field"},
1045 { NID_secp128r1, &_EC_SECG_PRIME_128R1}, 1831 { NID_secp128r1, &_EC_SECG_PRIME_128R1.h, "SECG curve over a 128 bit prime field"},
1046 { NID_secp128r2, &_EC_SECG_PRIME_128R2}, 1832 { NID_secp128r2, &_EC_SECG_PRIME_128R2.h, "SECG curve over a 128 bit prime field"},
1047 { NID_secp160k1, &_EC_SECG_PRIME_160K1}, 1833 { NID_secp160k1, &_EC_SECG_PRIME_160K1.h, "SECG curve over a 160 bit prime field"},
1048 { NID_secp160r1, &_EC_SECG_PRIME_160R1}, 1834 { NID_secp160r1, &_EC_SECG_PRIME_160R1.h, "SECG curve over a 160 bit prime field"},
1049 { NID_secp160r2, &_EC_SECG_PRIME_160R2}, 1835 { NID_secp160r2, &_EC_SECG_PRIME_160R2.h, "SECG/WTLS curve over a 160 bit prime field"},
1050 /* SECG secp192r1 is the same as X9.62 prime192v1 and hence omitted */ 1836 /* SECG secp192r1 is the same as X9.62 prime192v1 and hence omitted */
1051 { NID_secp192k1, &_EC_SECG_PRIME_192K1}, 1837 { NID_secp192k1, &_EC_SECG_PRIME_192K1.h, "SECG curve over a 192 bit prime field"},
1052 { NID_secp224k1, &_EC_SECG_PRIME_224K1}, 1838 { NID_secp224k1, &_EC_SECG_PRIME_224K1.h, "SECG curve over a 224 bit prime field"},
1053 { NID_secp224r1, &_EC_NIST_PRIME_224}, 1839 { NID_secp224r1, &_EC_NIST_PRIME_224.h, "NIST/SECG curve over a 224 bit prime field"},
1054 { NID_secp256k1, &_EC_SECG_PRIME_256K1}, 1840 { NID_secp256k1, &_EC_SECG_PRIME_256K1.h, "SECG curve over a 256 bit prime field"},
1055 /* SECG secp256r1 is the same as X9.62 prime256v1 and hence omitted */ 1841 /* SECG secp256r1 is the same as X9.62 prime256v1 and hence omitted */
1056 { NID_secp384r1, &_EC_NIST_PRIME_384}, 1842 { NID_secp384r1, &_EC_NIST_PRIME_384.h, "NIST/SECG curve over a 384 bit prime field"},
1057 { NID_secp521r1, &_EC_NIST_PRIME_521}, 1843 { NID_secp521r1, &_EC_NIST_PRIME_521.h, "NIST/SECG curve over a 521 bit prime field"},
1058 /* X9.62 curves */ 1844 /* X9.62 curves */
1059 { NID_X9_62_prime192v1, &_EC_NIST_PRIME_192}, 1845 { NID_X9_62_prime192v1, &_EC_NIST_PRIME_192.h, "NIST/X9.62/SECG curve over a 192 bit prime field"},
1060 { NID_X9_62_prime192v2, &_EC_X9_62_PRIME_192V2}, 1846 { NID_X9_62_prime192v2, &_EC_X9_62_PRIME_192V2.h, "X9.62 curve over a 192 bit prime field"},
1061 { NID_X9_62_prime192v3, &_EC_X9_62_PRIME_192V3}, 1847 { NID_X9_62_prime192v3, &_EC_X9_62_PRIME_192V3.h, "X9.62 curve over a 192 bit prime field"},
1062 { NID_X9_62_prime239v1, &_EC_X9_62_PRIME_239V1}, 1848 { NID_X9_62_prime239v1, &_EC_X9_62_PRIME_239V1.h, "X9.62 curve over a 239 bit prime field"},
1063 { NID_X9_62_prime239v2, &_EC_X9_62_PRIME_239V2}, 1849 { NID_X9_62_prime239v2, &_EC_X9_62_PRIME_239V2.h, "X9.62 curve over a 239 bit prime field"},
1064 { NID_X9_62_prime239v3, &_EC_X9_62_PRIME_239V3}, 1850 { NID_X9_62_prime239v3, &_EC_X9_62_PRIME_239V3.h, "X9.62 curve over a 239 bit prime field"},
1065 { NID_X9_62_prime256v1, &_EC_X9_62_PRIME_256V1}, 1851 { NID_X9_62_prime256v1, &_EC_X9_62_PRIME_256V1.h, "X9.62/SECG curve over a 256 bit prime field"},
1066 /* characteristic two field curves */ 1852 /* characteristic two field curves */
1067 /* NIST/SECG curves */ 1853 /* NIST/SECG curves */
1068 { NID_sect113r1, &_EC_SECG_CHAR2_113R1}, 1854 { NID_sect113r1, &_EC_SECG_CHAR2_113R1.h, "SECG curve over a 113 bit binary field"},
1069 { NID_sect113r2, &_EC_SECG_CHAR2_113R2}, 1855 { NID_sect113r2, &_EC_SECG_CHAR2_113R2.h, "SECG curve over a 113 bit binary field"},
1070 { NID_sect131r1, &_EC_SECG_CHAR2_131R1}, 1856 { NID_sect131r1, &_EC_SECG_CHAR2_131R1.h, "SECG/WTLS curve over a 131 bit binary field"},
1071 { NID_sect131r2, &_EC_SECG_CHAR2_131R2}, 1857 { NID_sect131r2, &_EC_SECG_CHAR2_131R2.h, "SECG curve over a 131 bit binary field"},
1072 { NID_sect163k1, &_EC_NIST_CHAR2_163K }, 1858 { NID_sect163k1, &_EC_NIST_CHAR2_163K.h, "NIST/SECG/WTLS curve over a 163 bit binary field" },
1073 { NID_sect163r1, &_EC_SECG_CHAR2_163R1}, 1859 { NID_sect163r1, &_EC_SECG_CHAR2_163R1.h, "SECG curve over a 163 bit binary field"},
1074 { NID_sect163r2, &_EC_NIST_CHAR2_163B }, 1860 { NID_sect163r2, &_EC_NIST_CHAR2_163B.h, "NIST/SECG curve over a 163 bit binary field" },
1075 { NID_sect193r1, &_EC_SECG_CHAR2_193R1}, 1861 { NID_sect193r1, &_EC_SECG_CHAR2_193R1.h, "SECG curve over a 193 bit binary field"},
1076 { NID_sect193r2, &_EC_SECG_CHAR2_193R2}, 1862 { NID_sect193r2, &_EC_SECG_CHAR2_193R2.h, "SECG curve over a 193 bit binary field"},
1077 { NID_sect233k1, &_EC_NIST_CHAR2_233K }, 1863 { NID_sect233k1, &_EC_NIST_CHAR2_233K.h, "NIST/SECG/WTLS curve over a 233 bit binary field" },
1078 { NID_sect233r1, &_EC_NIST_CHAR2_233B }, 1864 { NID_sect233r1, &_EC_NIST_CHAR2_233B.h, "NIST/SECG/WTLS curve over a 233 bit binary field" },
1079 { NID_sect239k1, &_EC_SECG_CHAR2_239K1}, 1865 { NID_sect239k1, &_EC_SECG_CHAR2_239K1.h, "SECG curve over a 239 bit binary field"},
1080 { NID_sect283k1, &_EC_NIST_CHAR2_283K }, 1866 { NID_sect283k1, &_EC_NIST_CHAR2_283K.h, "NIST/SECG curve over a 283 bit binary field" },
1081 { NID_sect283r1, &_EC_NIST_CHAR2_283B }, 1867 { NID_sect283r1, &_EC_NIST_CHAR2_283B.h, "NIST/SECG curve over a 283 bit binary field" },
1082 { NID_sect409k1, &_EC_NIST_CHAR2_409K }, 1868 { NID_sect409k1, &_EC_NIST_CHAR2_409K.h, "NIST/SECG curve over a 409 bit binary field" },
1083 { NID_sect409r1, &_EC_NIST_CHAR2_409B }, 1869 { NID_sect409r1, &_EC_NIST_CHAR2_409B.h, "NIST/SECG curve over a 409 bit binary field" },
1084 { NID_sect571k1, &_EC_NIST_CHAR2_571K }, 1870 { NID_sect571k1, &_EC_NIST_CHAR2_571K.h, "NIST/SECG curve over a 571 bit binary field" },
1085 { NID_sect571r1, &_EC_NIST_CHAR2_571B }, 1871 { NID_sect571r1, &_EC_NIST_CHAR2_571B.h, "NIST/SECG curve over a 571 bit binary field" },
1086 /* X9.62 curves */ 1872 /* X9.62 curves */
1087 { NID_X9_62_c2pnb163v1, &_EC_X9_62_CHAR2_163V1}, 1873 { NID_X9_62_c2pnb163v1, &_EC_X9_62_CHAR2_163V1.h, "X9.62 curve over a 163 bit binary field"},
1088 { NID_X9_62_c2pnb163v2, &_EC_X9_62_CHAR2_163V2}, 1874 { NID_X9_62_c2pnb163v2, &_EC_X9_62_CHAR2_163V2.h, "X9.62 curve over a 163 bit binary field"},
1089 { NID_X9_62_c2pnb163v3, &_EC_X9_62_CHAR2_163V3}, 1875 { NID_X9_62_c2pnb163v3, &_EC_X9_62_CHAR2_163V3.h, "X9.62 curve over a 163 bit binary field"},
1090 { NID_X9_62_c2pnb176v1, &_EC_X9_62_CHAR2_176V1}, 1876 { NID_X9_62_c2pnb176v1, &_EC_X9_62_CHAR2_176V1.h, "X9.62 curve over a 176 bit binary field"},
1091 { NID_X9_62_c2tnb191v1, &_EC_X9_62_CHAR2_191V1}, 1877 { NID_X9_62_c2tnb191v1, &_EC_X9_62_CHAR2_191V1.h, "X9.62 curve over a 191 bit binary field"},
1092 { NID_X9_62_c2tnb191v2, &_EC_X9_62_CHAR2_191V2}, 1878 { NID_X9_62_c2tnb191v2, &_EC_X9_62_CHAR2_191V2.h, "X9.62 curve over a 191 bit binary field"},
1093 { NID_X9_62_c2tnb191v3, &_EC_X9_62_CHAR2_191V3}, 1879 { NID_X9_62_c2tnb191v3, &_EC_X9_62_CHAR2_191V3.h, "X9.62 curve over a 191 bit binary field"},
1094 { NID_X9_62_c2pnb208w1, &_EC_X9_62_CHAR2_208W1}, 1880 { NID_X9_62_c2pnb208w1, &_EC_X9_62_CHAR2_208W1.h, "X9.62 curve over a 208 bit binary field"},
1095 { NID_X9_62_c2tnb239v1, &_EC_X9_62_CHAR2_239V1}, 1881 { NID_X9_62_c2tnb239v1, &_EC_X9_62_CHAR2_239V1.h, "X9.62 curve over a 239 bit binary field"},
1096 { NID_X9_62_c2tnb239v2, &_EC_X9_62_CHAR2_239V2}, 1882 { NID_X9_62_c2tnb239v2, &_EC_X9_62_CHAR2_239V2.h, "X9.62 curve over a 239 bit binary field"},
1097 { NID_X9_62_c2tnb239v3, &_EC_X9_62_CHAR2_239V3}, 1883 { NID_X9_62_c2tnb239v3, &_EC_X9_62_CHAR2_239V3.h, "X9.62 curve over a 239 bit binary field"},
1098 { NID_X9_62_c2pnb272w1, &_EC_X9_62_CHAR2_272W1}, 1884 { NID_X9_62_c2pnb272w1, &_EC_X9_62_CHAR2_272W1.h, "X9.62 curve over a 272 bit binary field"},
1099 { NID_X9_62_c2pnb304w1, &_EC_X9_62_CHAR2_304W1}, 1885 { NID_X9_62_c2pnb304w1, &_EC_X9_62_CHAR2_304W1.h, "X9.62 curve over a 304 bit binary field"},
1100 { NID_X9_62_c2tnb359v1, &_EC_X9_62_CHAR2_359V1}, 1886 { NID_X9_62_c2tnb359v1, &_EC_X9_62_CHAR2_359V1.h, "X9.62 curve over a 359 bit binary field"},
1101 { NID_X9_62_c2pnb368w1, &_EC_X9_62_CHAR2_368W1}, 1887 { NID_X9_62_c2pnb368w1, &_EC_X9_62_CHAR2_368W1.h, "X9.62 curve over a 368 bit binary field"},
1102 { NID_X9_62_c2tnb431r1, &_EC_X9_62_CHAR2_431R1}, 1888 { NID_X9_62_c2tnb431r1, &_EC_X9_62_CHAR2_431R1.h, "X9.62 curve over a 431 bit binary field"},
1103 /* the WAP/WTLS curves 1889 /* the WAP/WTLS curves
1104 * [unlike SECG, spec has its own OIDs for curves from X9.62] */ 1890 * [unlike SECG, spec has its own OIDs for curves from X9.62] */
1105 { NID_wap_wsg_idm_ecid_wtls1, &_EC_WTLS_1}, 1891 { NID_wap_wsg_idm_ecid_wtls1, &_EC_WTLS_1.h, "WTLS curve over a 113 bit binary field"},
1106 { NID_wap_wsg_idm_ecid_wtls3, &_EC_NIST_CHAR2_163K}, 1892 { NID_wap_wsg_idm_ecid_wtls3, &_EC_NIST_CHAR2_163K.h, "NIST/SECG/WTLS curve over a 163 bit binary field"},
1107 { NID_wap_wsg_idm_ecid_wtls4, &_EC_SECG_CHAR2_113R1}, 1893 { NID_wap_wsg_idm_ecid_wtls4, &_EC_SECG_CHAR2_113R1.h, "SECG curve over a 113 bit binary field"},
1108 { NID_wap_wsg_idm_ecid_wtls5, &_EC_X9_62_CHAR2_163V1}, 1894 { NID_wap_wsg_idm_ecid_wtls5, &_EC_X9_62_CHAR2_163V1.h, "X9.62 curve over a 163 bit binary field"},
1109 { NID_wap_wsg_idm_ecid_wtls6, &_EC_SECG_PRIME_112R1}, 1895 { NID_wap_wsg_idm_ecid_wtls6, &_EC_SECG_PRIME_112R1.h, "SECG/WTLS curve over a 112 bit prime field"},
1110 { NID_wap_wsg_idm_ecid_wtls7, &_EC_SECG_PRIME_160R2}, 1896 { NID_wap_wsg_idm_ecid_wtls7, &_EC_SECG_PRIME_160R2.h, "SECG/WTLS curve over a 160 bit prime field"},
1111 { NID_wap_wsg_idm_ecid_wtls8, &_EC_WTLS_8}, 1897 { NID_wap_wsg_idm_ecid_wtls8, &_EC_WTLS_8.h, "WTLS curve over a 112 bit prime field"},
1112 { NID_wap_wsg_idm_ecid_wtls9, &_EC_WTLS_9 }, 1898 { NID_wap_wsg_idm_ecid_wtls9, &_EC_WTLS_9.h, "WTLS curve over a 160 bit prime field" },
1113 { NID_wap_wsg_idm_ecid_wtls10, &_EC_NIST_CHAR2_233K}, 1899 { NID_wap_wsg_idm_ecid_wtls10, &_EC_NIST_CHAR2_233K.h, "NIST/SECG/WTLS curve over a 233 bit binary field"},
1114 { NID_wap_wsg_idm_ecid_wtls11, &_EC_NIST_CHAR2_233B}, 1900 { NID_wap_wsg_idm_ecid_wtls11, &_EC_NIST_CHAR2_233B.h, "NIST/SECG/WTLS curve over a 233 bit binary field"},
1115 { NID_wap_wsg_idm_ecid_wtls12, &_EC_WTLS_12}, 1901 { NID_wap_wsg_idm_ecid_wtls12, &_EC_WTLS_12.h, "WTLS curvs over a 224 bit prime field"},
1116 /* IPSec curves */ 1902 /* IPSec curves */
1117 { NID_ipsec3, &_EC_IPSEC_155_ID3}, 1903 { NID_ipsec3, &_EC_IPSEC_155_ID3.h, "\n\tIPSec/IKE/Oakley curve #3 over a 155 bit binary field.\n""\tNot suitable for ECDSA.\n\tQuestionable extension field!"},
1118 { NID_ipsec4, &_EC_IPSEC_185_ID4}, 1904 { NID_ipsec4, &_EC_IPSEC_185_ID4.h, "\n\tIPSec/IKE/Oakley curve #4 over a 185 bit binary field.\n""\tNot suitable for ECDSA.\n\tQuestionable extension field!"},
1119}; 1905};
1120 1906
1121static size_t curve_list_length = sizeof(curve_list)/sizeof(ec_list_element); 1907#define curve_list_length (sizeof(curve_list)/sizeof(ec_list_element))
1122 1908
1123static EC_GROUP *ec_group_new_from_data(const EC_CURVE_DATA *data) 1909static EC_GROUP *ec_group_new_from_data(const EC_CURVE_DATA *data)
1124 { 1910 {
@@ -1127,22 +1913,23 @@ static EC_GROUP *ec_group_new_from_data(const EC_CURVE_DATA *data)
1127 BN_CTX *ctx=NULL; 1913 BN_CTX *ctx=NULL;
1128 BIGNUM *p=NULL, *a=NULL, *b=NULL, *x=NULL, *y=NULL, *order=NULL; 1914 BIGNUM *p=NULL, *a=NULL, *b=NULL, *x=NULL, *y=NULL, *order=NULL;
1129 int ok=0; 1915 int ok=0;
1916 int seed_len,param_len;
1917 const unsigned char *params;
1130 1918
1131 if ((ctx = BN_CTX_new()) == NULL) 1919 if ((ctx = BN_CTX_new()) == NULL)
1132 { 1920 {
1133 ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_MALLOC_FAILURE); 1921 ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_MALLOC_FAILURE);
1134 goto err; 1922 goto err;
1135 } 1923 }
1136 if ((p = BN_new()) == NULL || (a = BN_new()) == NULL || 1924
1137 (b = BN_new()) == NULL || (x = BN_new()) == NULL || 1925 seed_len = data->seed_len;
1138 (y = BN_new()) == NULL || (order = BN_new()) == NULL) 1926 param_len = data->param_len;
1139 { 1927 params = (const unsigned char *)(data+1); /* skip header */
1140 ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_MALLOC_FAILURE); 1928 params += seed_len; /* skip seed */
1141 goto err; 1929
1142 } 1930 if (!(p = BN_bin2bn(params+0*param_len, param_len, NULL))
1143 1931 || !(a = BN_bin2bn(params+1*param_len, param_len, NULL))
1144 if (!BN_hex2bn(&p, data->p) || !BN_hex2bn(&a, data->a) 1932 || !(b = BN_bin2bn(params+2*param_len, param_len, NULL)))
1145 || !BN_hex2bn(&b, data->b))
1146 { 1933 {
1147 ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_BN_LIB); 1934 ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_BN_LIB);
1148 goto err; 1935 goto err;
@@ -1156,8 +1943,8 @@ static EC_GROUP *ec_group_new_from_data(const EC_CURVE_DATA *data)
1156 goto err; 1943 goto err;
1157 } 1944 }
1158 } 1945 }
1159 else 1946 else /* field_type == NID_X9_62_characteristic_two_field */
1160 { /* field_type == NID_X9_62_characteristic_two_field */ 1947 {
1161 if ((group = EC_GROUP_new_curve_GF2m(p, a, b, ctx)) == NULL) 1948 if ((group = EC_GROUP_new_curve_GF2m(p, a, b, ctx)) == NULL)
1162 { 1949 {
1163 ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB); 1950 ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB);
@@ -1171,7 +1958,8 @@ static EC_GROUP *ec_group_new_from_data(const EC_CURVE_DATA *data)
1171 goto err; 1958 goto err;
1172 } 1959 }
1173 1960
1174 if (!BN_hex2bn(&x, data->x) || !BN_hex2bn(&y, data->y)) 1961 if (!(x = BN_bin2bn(params+3*param_len, param_len, NULL))
1962 || !(y = BN_bin2bn(params+4*param_len, param_len, NULL)))
1175 { 1963 {
1176 ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_BN_LIB); 1964 ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_BN_LIB);
1177 goto err; 1965 goto err;
@@ -1181,7 +1969,8 @@ static EC_GROUP *ec_group_new_from_data(const EC_CURVE_DATA *data)
1181 ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB); 1969 ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB);
1182 goto err; 1970 goto err;
1183 } 1971 }
1184 if (!BN_hex2bn(&order, data->order) || !BN_set_word(x, data->cofactor)) 1972 if (!(order = BN_bin2bn(params+5*param_len, param_len, NULL))
1973 || !BN_set_word(x, (BN_ULONG)data->cofactor))
1185 { 1974 {
1186 ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_BN_LIB); 1975 ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_BN_LIB);
1187 goto err; 1976 goto err;
@@ -1191,9 +1980,9 @@ static EC_GROUP *ec_group_new_from_data(const EC_CURVE_DATA *data)
1191 ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB); 1980 ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB);
1192 goto err; 1981 goto err;
1193 } 1982 }
1194 if (data->seed) 1983 if (seed_len)
1195 { 1984 {
1196 if (!EC_GROUP_set_seed(group, data->seed, data->seed_len)) 1985 if (!EC_GROUP_set_seed(group, params-seed_len, seed_len))
1197 { 1986 {
1198 ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB); 1987 ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB);
1199 goto err; 1988 goto err;
@@ -1263,7 +2052,7 @@ size_t EC_get_builtin_curves(EC_builtin_curve *r, size_t nitems)
1263 for (i = 0; i < min; i++) 2052 for (i = 0; i < min; i++)
1264 { 2053 {
1265 r[i].nid = curve_list[i].nid; 2054 r[i].nid = curve_list[i].nid;
1266 r[i].comment = curve_list[i].data->comment; 2055 r[i].comment = curve_list[i].comment;
1267 } 2056 }
1268 2057
1269 return curve_list_length; 2058 return curve_list_length;
diff --git a/src/lib/libcrypto/ec/ec_err.c b/src/lib/libcrypto/ec/ec_err.c
index d04c895560..84b4833371 100644
--- a/src/lib/libcrypto/ec/ec_err.c
+++ b/src/lib/libcrypto/ec/ec_err.c
@@ -74,6 +74,14 @@ static ERR_STRING_DATA EC_str_functs[]=
74{ERR_FUNC(EC_F_D2I_ECPARAMETERS), "d2i_ECParameters"}, 74{ERR_FUNC(EC_F_D2I_ECPARAMETERS), "d2i_ECParameters"},
75{ERR_FUNC(EC_F_D2I_ECPKPARAMETERS), "d2i_ECPKParameters"}, 75{ERR_FUNC(EC_F_D2I_ECPKPARAMETERS), "d2i_ECPKParameters"},
76{ERR_FUNC(EC_F_D2I_ECPRIVATEKEY), "d2i_ECPrivateKey"}, 76{ERR_FUNC(EC_F_D2I_ECPRIVATEKEY), "d2i_ECPrivateKey"},
77{ERR_FUNC(EC_F_DO_EC_KEY_PRINT), "DO_EC_KEY_PRINT"},
78{ERR_FUNC(EC_F_ECKEY_PARAM2TYPE), "ECKEY_PARAM2TYPE"},
79{ERR_FUNC(EC_F_ECKEY_PARAM_DECODE), "ECKEY_PARAM_DECODE"},
80{ERR_FUNC(EC_F_ECKEY_PRIV_DECODE), "ECKEY_PRIV_DECODE"},
81{ERR_FUNC(EC_F_ECKEY_PRIV_ENCODE), "ECKEY_PRIV_ENCODE"},
82{ERR_FUNC(EC_F_ECKEY_PUB_DECODE), "ECKEY_PUB_DECODE"},
83{ERR_FUNC(EC_F_ECKEY_PUB_ENCODE), "ECKEY_PUB_ENCODE"},
84{ERR_FUNC(EC_F_ECKEY_TYPE2PARAM), "ECKEY_TYPE2PARAM"},
77{ERR_FUNC(EC_F_ECPARAMETERS_PRINT), "ECParameters_print"}, 85{ERR_FUNC(EC_F_ECPARAMETERS_PRINT), "ECParameters_print"},
78{ERR_FUNC(EC_F_ECPARAMETERS_PRINT_FP), "ECParameters_print_fp"}, 86{ERR_FUNC(EC_F_ECPARAMETERS_PRINT_FP), "ECParameters_print_fp"},
79{ERR_FUNC(EC_F_ECPKPARAMETERS_PRINT), "ECPKParameters_print"}, 87{ERR_FUNC(EC_F_ECPKPARAMETERS_PRINT), "ECPKParameters_print"},
@@ -147,7 +155,6 @@ static ERR_STRING_DATA EC_str_functs[]=
147{ERR_FUNC(EC_F_EC_KEY_PRINT), "EC_KEY_print"}, 155{ERR_FUNC(EC_F_EC_KEY_PRINT), "EC_KEY_print"},
148{ERR_FUNC(EC_F_EC_KEY_PRINT_FP), "EC_KEY_print_fp"}, 156{ERR_FUNC(EC_F_EC_KEY_PRINT_FP), "EC_KEY_print_fp"},
149{ERR_FUNC(EC_F_EC_POINTS_MAKE_AFFINE), "EC_POINTs_make_affine"}, 157{ERR_FUNC(EC_F_EC_POINTS_MAKE_AFFINE), "EC_POINTs_make_affine"},
150{ERR_FUNC(EC_F_EC_POINTS_MUL), "EC_POINTs_mul"},
151{ERR_FUNC(EC_F_EC_POINT_ADD), "EC_POINT_add"}, 158{ERR_FUNC(EC_F_EC_POINT_ADD), "EC_POINT_add"},
152{ERR_FUNC(EC_F_EC_POINT_CMP), "EC_POINT_cmp"}, 159{ERR_FUNC(EC_F_EC_POINT_CMP), "EC_POINT_cmp"},
153{ERR_FUNC(EC_F_EC_POINT_COPY), "EC_POINT_copy"}, 160{ERR_FUNC(EC_F_EC_POINT_COPY), "EC_POINT_copy"},
@@ -178,6 +185,13 @@ static ERR_STRING_DATA EC_str_functs[]=
178{ERR_FUNC(EC_F_I2D_ECPRIVATEKEY), "i2d_ECPrivateKey"}, 185{ERR_FUNC(EC_F_I2D_ECPRIVATEKEY), "i2d_ECPrivateKey"},
179{ERR_FUNC(EC_F_I2O_ECPUBLICKEY), "i2o_ECPublicKey"}, 186{ERR_FUNC(EC_F_I2O_ECPUBLICKEY), "i2o_ECPublicKey"},
180{ERR_FUNC(EC_F_O2I_ECPUBLICKEY), "o2i_ECPublicKey"}, 187{ERR_FUNC(EC_F_O2I_ECPUBLICKEY), "o2i_ECPublicKey"},
188{ERR_FUNC(EC_F_OLD_EC_PRIV_DECODE), "OLD_EC_PRIV_DECODE"},
189{ERR_FUNC(EC_F_PKEY_EC_CTRL), "PKEY_EC_CTRL"},
190{ERR_FUNC(EC_F_PKEY_EC_CTRL_STR), "PKEY_EC_CTRL_STR"},
191{ERR_FUNC(EC_F_PKEY_EC_DERIVE), "PKEY_EC_DERIVE"},
192{ERR_FUNC(EC_F_PKEY_EC_KEYGEN), "PKEY_EC_KEYGEN"},
193{ERR_FUNC(EC_F_PKEY_EC_PARAMGEN), "PKEY_EC_PARAMGEN"},
194{ERR_FUNC(EC_F_PKEY_EC_SIGN), "PKEY_EC_SIGN"},
181{0,NULL} 195{0,NULL}
182 }; 196 };
183 197
@@ -187,6 +201,7 @@ static ERR_STRING_DATA EC_str_reasons[]=
187{ERR_REASON(EC_R_ASN1_UNKNOWN_FIELD) ,"asn1 unknown field"}, 201{ERR_REASON(EC_R_ASN1_UNKNOWN_FIELD) ,"asn1 unknown field"},
188{ERR_REASON(EC_R_BUFFER_TOO_SMALL) ,"buffer too small"}, 202{ERR_REASON(EC_R_BUFFER_TOO_SMALL) ,"buffer too small"},
189{ERR_REASON(EC_R_D2I_ECPKPARAMETERS_FAILURE),"d2i ecpkparameters failure"}, 203{ERR_REASON(EC_R_D2I_ECPKPARAMETERS_FAILURE),"d2i ecpkparameters failure"},
204{ERR_REASON(EC_R_DECODE_ERROR) ,"decode error"},
190{ERR_REASON(EC_R_DISCRIMINANT_IS_ZERO) ,"discriminant is zero"}, 205{ERR_REASON(EC_R_DISCRIMINANT_IS_ZERO) ,"discriminant is zero"},
191{ERR_REASON(EC_R_EC_GROUP_NEW_BY_NAME_FAILURE),"ec group new by name failure"}, 206{ERR_REASON(EC_R_EC_GROUP_NEW_BY_NAME_FAILURE),"ec group new by name failure"},
192{ERR_REASON(EC_R_FIELD_TOO_LARGE) ,"field too large"}, 207{ERR_REASON(EC_R_FIELD_TOO_LARGE) ,"field too large"},
@@ -196,6 +211,8 @@ static ERR_STRING_DATA EC_str_reasons[]=
196{ERR_REASON(EC_R_INVALID_ARGUMENT) ,"invalid argument"}, 211{ERR_REASON(EC_R_INVALID_ARGUMENT) ,"invalid argument"},
197{ERR_REASON(EC_R_INVALID_COMPRESSED_POINT),"invalid compressed point"}, 212{ERR_REASON(EC_R_INVALID_COMPRESSED_POINT),"invalid compressed point"},
198{ERR_REASON(EC_R_INVALID_COMPRESSION_BIT),"invalid compression bit"}, 213{ERR_REASON(EC_R_INVALID_COMPRESSION_BIT),"invalid compression bit"},
214{ERR_REASON(EC_R_INVALID_CURVE) ,"invalid curve"},
215{ERR_REASON(EC_R_INVALID_DIGEST_TYPE) ,"invalid digest type"},
199{ERR_REASON(EC_R_INVALID_ENCODING) ,"invalid encoding"}, 216{ERR_REASON(EC_R_INVALID_ENCODING) ,"invalid encoding"},
200{ERR_REASON(EC_R_INVALID_FIELD) ,"invalid field"}, 217{ERR_REASON(EC_R_INVALID_FIELD) ,"invalid field"},
201{ERR_REASON(EC_R_INVALID_FORM) ,"invalid form"}, 218{ERR_REASON(EC_R_INVALID_FORM) ,"invalid form"},
@@ -203,6 +220,7 @@ static ERR_STRING_DATA EC_str_reasons[]=
203{ERR_REASON(EC_R_INVALID_PENTANOMIAL_BASIS),"invalid pentanomial basis"}, 220{ERR_REASON(EC_R_INVALID_PENTANOMIAL_BASIS),"invalid pentanomial basis"},
204{ERR_REASON(EC_R_INVALID_PRIVATE_KEY) ,"invalid private key"}, 221{ERR_REASON(EC_R_INVALID_PRIVATE_KEY) ,"invalid private key"},
205{ERR_REASON(EC_R_INVALID_TRINOMIAL_BASIS),"invalid trinomial basis"}, 222{ERR_REASON(EC_R_INVALID_TRINOMIAL_BASIS),"invalid trinomial basis"},
223{ERR_REASON(EC_R_KEYS_NOT_SET) ,"keys not set"},
206{ERR_REASON(EC_R_MISSING_PARAMETERS) ,"missing parameters"}, 224{ERR_REASON(EC_R_MISSING_PARAMETERS) ,"missing parameters"},
207{ERR_REASON(EC_R_MISSING_PRIVATE_KEY) ,"missing private key"}, 225{ERR_REASON(EC_R_MISSING_PRIVATE_KEY) ,"missing private key"},
208{ERR_REASON(EC_R_NOT_A_NIST_PRIME) ,"not a NIST prime"}, 226{ERR_REASON(EC_R_NOT_A_NIST_PRIME) ,"not a NIST prime"},
@@ -210,6 +228,7 @@ static ERR_STRING_DATA EC_str_reasons[]=
210{ERR_REASON(EC_R_NOT_IMPLEMENTED) ,"not implemented"}, 228{ERR_REASON(EC_R_NOT_IMPLEMENTED) ,"not implemented"},
211{ERR_REASON(EC_R_NOT_INITIALIZED) ,"not initialized"}, 229{ERR_REASON(EC_R_NOT_INITIALIZED) ,"not initialized"},
212{ERR_REASON(EC_R_NO_FIELD_MOD) ,"no field mod"}, 230{ERR_REASON(EC_R_NO_FIELD_MOD) ,"no field mod"},
231{ERR_REASON(EC_R_NO_PARAMETERS_SET) ,"no parameters set"},
213{ERR_REASON(EC_R_PASSED_NULL_PARAMETER) ,"passed null parameter"}, 232{ERR_REASON(EC_R_PASSED_NULL_PARAMETER) ,"passed null parameter"},
214{ERR_REASON(EC_R_PKPARAMETERS2GROUP_FAILURE),"pkparameters2group failure"}, 233{ERR_REASON(EC_R_PKPARAMETERS2GROUP_FAILURE),"pkparameters2group failure"},
215{ERR_REASON(EC_R_POINT_AT_INFINITY) ,"point at infinity"}, 234{ERR_REASON(EC_R_POINT_AT_INFINITY) ,"point at infinity"},
diff --git a/src/lib/libcrypto/ec/ec_lcl.h b/src/lib/libcrypto/ec/ec_lcl.h
index fdd7aa2755..3e2c34b0bc 100644
--- a/src/lib/libcrypto/ec/ec_lcl.h
+++ b/src/lib/libcrypto/ec/ec_lcl.h
@@ -205,11 +205,14 @@ struct ec_group_st {
205 * irreducible polynomial defining the field. 205 * irreducible polynomial defining the field.
206 */ 206 */
207 207
208 unsigned int poly[5]; /* Field specification for curves over GF(2^m). 208 int poly[6]; /* Field specification for curves over GF(2^m).
209 * The irreducible f(t) is then of the form: 209 * The irreducible f(t) is then of the form:
210 * t^poly[0] + t^poly[1] + ... + t^poly[k] 210 * t^poly[0] + t^poly[1] + ... + t^poly[k]
211 * where m = poly[0] > poly[1] > ... > poly[k] = 0. 211 * where m = poly[0] > poly[1] > ... > poly[k] = 0.
212 */ 212 * The array is terminated with poly[k+1]=-1.
213 * All elliptic curve irreducibles have at most 5
214 * non-zero terms.
215 */
213 216
214 BIGNUM a, b; /* Curve coefficients. 217 BIGNUM a, b; /* Curve coefficients.
215 * (Here the assumption is that BIGNUMs can be used 218 * (Here the assumption is that BIGNUMs can be used
diff --git a/src/lib/libcrypto/ec/ec_lib.c b/src/lib/libcrypto/ec/ec_lib.c
index 5af84376c6..dd7da0fcf9 100644
--- a/src/lib/libcrypto/ec/ec_lib.c
+++ b/src/lib/libcrypto/ec/ec_lib.c
@@ -79,7 +79,7 @@ EC_GROUP *EC_GROUP_new(const EC_METHOD *meth)
79 79
80 if (meth == NULL) 80 if (meth == NULL)
81 { 81 {
82 ECerr(EC_F_EC_GROUP_NEW, ERR_R_PASSED_NULL_PARAMETER); 82 ECerr(EC_F_EC_GROUP_NEW, EC_R_SLOT_FULL);
83 return NULL; 83 return NULL;
84 } 84 }
85 if (meth->group_init == 0) 85 if (meth->group_init == 0)
@@ -740,7 +740,7 @@ void EC_POINT_clear_free(EC_POINT *point)
740 740
741 if (point->meth->point_clear_finish != 0) 741 if (point->meth->point_clear_finish != 0)
742 point->meth->point_clear_finish(point); 742 point->meth->point_clear_finish(point);
743 else if (point->meth != NULL && point->meth->point_finish != 0) 743 else if (point->meth->point_finish != 0)
744 point->meth->point_finish(point); 744 point->meth->point_finish(point);
745 OPENSSL_cleanse(point, sizeof *point); 745 OPENSSL_cleanse(point, sizeof *point);
746 OPENSSL_free(point); 746 OPENSSL_free(point);
diff --git a/src/lib/libcrypto/ec/ec_mult.c b/src/lib/libcrypto/ec/ec_mult.c
index 2ba173ef36..f05df5332e 100644
--- a/src/lib/libcrypto/ec/ec_mult.c
+++ b/src/lib/libcrypto/ec/ec_mult.c
@@ -224,6 +224,12 @@ static signed char *compute_wNAF(const BIGNUM *scalar, int w, size_t *ret_len)
224 sign = -1; 224 sign = -1;
225 } 225 }
226 226
227 if (scalar->d == NULL || scalar->top == 0)
228 {
229 ECerr(EC_F_COMPUTE_WNAF, ERR_R_INTERNAL_ERROR);
230 goto err;
231 }
232
227 len = BN_num_bits(scalar); 233 len = BN_num_bits(scalar);
228 r = OPENSSL_malloc(len + 1); /* modified wNAF may be one digit longer than binary representation 234 r = OPENSSL_malloc(len + 1); /* modified wNAF may be one digit longer than binary representation
229 * (*ret_len will be set to the actual length, i.e. at most 235 * (*ret_len will be set to the actual length, i.e. at most
@@ -233,12 +239,6 @@ static signed char *compute_wNAF(const BIGNUM *scalar, int w, size_t *ret_len)
233 ECerr(EC_F_COMPUTE_WNAF, ERR_R_MALLOC_FAILURE); 239 ECerr(EC_F_COMPUTE_WNAF, ERR_R_MALLOC_FAILURE);
234 goto err; 240 goto err;
235 } 241 }
236
237 if (scalar->d == NULL || scalar->top == 0)
238 {
239 ECerr(EC_F_COMPUTE_WNAF, ERR_R_INTERNAL_ERROR);
240 goto err;
241 }
242 window_val = scalar->d[0] & mask; 242 window_val = scalar->d[0] & mask;
243 j = 0; 243 j = 0;
244 while ((window_val != 0) || (j + w + 1 < len)) /* if j+w+1 >= len, window_val will not increase */ 244 while ((window_val != 0) || (j + w + 1 < len)) /* if j+w+1 >= len, window_val will not increase */
@@ -419,7 +419,7 @@ int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
419 if (numblocks > pre_comp->numblocks) 419 if (numblocks > pre_comp->numblocks)
420 numblocks = pre_comp->numblocks; 420 numblocks = pre_comp->numblocks;
421 421
422 pre_points_per_block = 1u << (pre_comp->w - 1); 422 pre_points_per_block = (size_t)1 << (pre_comp->w - 1);
423 423
424 /* check that pre_comp looks sane */ 424 /* check that pre_comp looks sane */
425 if (pre_comp->num != (pre_comp->numblocks * pre_points_per_block)) 425 if (pre_comp->num != (pre_comp->numblocks * pre_points_per_block))
@@ -461,7 +461,7 @@ int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
461 461
462 bits = i < num ? BN_num_bits(scalars[i]) : BN_num_bits(scalar); 462 bits = i < num ? BN_num_bits(scalars[i]) : BN_num_bits(scalar);
463 wsize[i] = EC_window_bits_for_scalar_size(bits); 463 wsize[i] = EC_window_bits_for_scalar_size(bits);
464 num_val += 1u << (wsize[i] - 1); 464 num_val += (size_t)1 << (wsize[i] - 1);
465 wNAF[i + 1] = NULL; /* make sure we always have a pivot */ 465 wNAF[i + 1] = NULL; /* make sure we always have a pivot */
466 wNAF[i] = compute_wNAF((i < num ? scalars[i] : scalar), wsize[i], &wNAF_len[i]); 466 wNAF[i] = compute_wNAF((i < num ? scalars[i] : scalar), wsize[i], &wNAF_len[i]);
467 if (wNAF[i] == NULL) 467 if (wNAF[i] == NULL)
@@ -600,7 +600,7 @@ int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
600 for (i = 0; i < num + num_scalar; i++) 600 for (i = 0; i < num + num_scalar; i++)
601 { 601 {
602 val_sub[i] = v; 602 val_sub[i] = v;
603 for (j = 0; j < (1u << (wsize[i] - 1)); j++) 603 for (j = 0; j < ((size_t)1 << (wsize[i] - 1)); j++)
604 { 604 {
605 *v = EC_POINT_new(group); 605 *v = EC_POINT_new(group);
606 if (*v == NULL) goto err; 606 if (*v == NULL) goto err;
@@ -636,7 +636,7 @@ int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
636 if (wsize[i] > 1) 636 if (wsize[i] > 1)
637 { 637 {
638 if (!EC_POINT_dbl(group, tmp, val_sub[i][0], ctx)) goto err; 638 if (!EC_POINT_dbl(group, tmp, val_sub[i][0], ctx)) goto err;
639 for (j = 1; j < (1u << (wsize[i] - 1)); j++) 639 for (j = 1; j < ((size_t)1 << (wsize[i] - 1)); j++)
640 { 640 {
641 if (!EC_POINT_add(group, val_sub[i][j], val_sub[i][j - 1], tmp, ctx)) goto err; 641 if (!EC_POINT_add(group, val_sub[i][j], val_sub[i][j - 1], tmp, ctx)) goto err;
642 } 642 }
@@ -820,7 +820,7 @@ int ec_wNAF_precompute_mult(EC_GROUP *group, BN_CTX *ctx)
820 820
821 numblocks = (bits + blocksize - 1) / blocksize; /* max. number of blocks to use for wNAF splitting */ 821 numblocks = (bits + blocksize - 1) / blocksize; /* max. number of blocks to use for wNAF splitting */
822 822
823 pre_points_per_block = 1u << (w - 1); 823 pre_points_per_block = (size_t)1 << (w - 1);
824 num = pre_points_per_block * numblocks; /* number of points to compute and store */ 824 num = pre_points_per_block * numblocks; /* number of points to compute and store */
825 825
826 points = OPENSSL_malloc(sizeof (EC_POINT*)*(num + 1)); 826 points = OPENSSL_malloc(sizeof (EC_POINT*)*(num + 1));
diff --git a/src/lib/libcrypto/ec/ec_pmeth.c b/src/lib/libcrypto/ec/ec_pmeth.c
new file mode 100644
index 0000000000..f433076ca1
--- /dev/null
+++ b/src/lib/libcrypto/ec/ec_pmeth.c
@@ -0,0 +1,340 @@
1/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
2 * project 2006.
3 */
4/* ====================================================================
5 * Copyright (c) 2006 The OpenSSL Project. All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 *
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 *
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in
16 * the documentation and/or other materials provided with the
17 * distribution.
18 *
19 * 3. All advertising materials mentioning features or use of this
20 * software must display the following acknowledgment:
21 * "This product includes software developed by the OpenSSL Project
22 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
23 *
24 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
25 * endorse or promote products derived from this software without
26 * prior written permission. For written permission, please contact
27 * licensing@OpenSSL.org.
28 *
29 * 5. Products derived from this software may not be called "OpenSSL"
30 * nor may "OpenSSL" appear in their names without prior written
31 * permission of the OpenSSL Project.
32 *
33 * 6. Redistributions of any form whatsoever must retain the following
34 * acknowledgment:
35 * "This product includes software developed by the OpenSSL Project
36 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
37 *
38 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
39 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
40 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
41 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
42 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
43 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
44 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
45 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
46 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
47 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
48 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
49 * OF THE POSSIBILITY OF SUCH DAMAGE.
50 * ====================================================================
51 *
52 * This product includes cryptographic software written by Eric Young
53 * (eay@cryptsoft.com). This product includes software written by Tim
54 * Hudson (tjh@cryptsoft.com).
55 *
56 */
57
58#include <stdio.h>
59#include "cryptlib.h"
60#include <openssl/asn1t.h>
61#include <openssl/x509.h>
62#include <openssl/ec.h>
63#include <openssl/ecdsa.h>
64#include <openssl/evp.h>
65#include "evp_locl.h"
66
67/* EC pkey context structure */
68
69typedef struct
70 {
71 /* Key and paramgen group */
72 EC_GROUP *gen_group;
73 /* message digest */
74 const EVP_MD *md;
75 } EC_PKEY_CTX;
76
77static int pkey_ec_init(EVP_PKEY_CTX *ctx)
78 {
79 EC_PKEY_CTX *dctx;
80 dctx = OPENSSL_malloc(sizeof(EC_PKEY_CTX));
81 if (!dctx)
82 return 0;
83 dctx->gen_group = NULL;
84 dctx->md = NULL;
85
86 ctx->data = dctx;
87
88 return 1;
89 }
90
91static int pkey_ec_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src)
92 {
93 EC_PKEY_CTX *dctx, *sctx;
94 if (!pkey_ec_init(dst))
95 return 0;
96 sctx = src->data;
97 dctx = dst->data;
98 if (sctx->gen_group)
99 {
100 dctx->gen_group = EC_GROUP_dup(sctx->gen_group);
101 if (!dctx->gen_group)
102 return 0;
103 }
104 dctx->md = sctx->md;
105 return 1;
106 }
107
108static void pkey_ec_cleanup(EVP_PKEY_CTX *ctx)
109 {
110 EC_PKEY_CTX *dctx = ctx->data;
111 if (dctx)
112 {
113 if (dctx->gen_group)
114 EC_GROUP_free(dctx->gen_group);
115 OPENSSL_free(dctx);
116 }
117 }
118
119static int pkey_ec_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen,
120 const unsigned char *tbs, size_t tbslen)
121 {
122 int ret, type;
123 unsigned int sltmp;
124 EC_PKEY_CTX *dctx = ctx->data;
125 EC_KEY *ec = ctx->pkey->pkey.ec;
126
127 if (!sig)
128 {
129 *siglen = ECDSA_size(ec);
130 return 1;
131 }
132 else if(*siglen < (size_t)ECDSA_size(ec))
133 {
134 ECerr(EC_F_PKEY_EC_SIGN, EC_R_BUFFER_TOO_SMALL);
135 return 0;
136 }
137
138 if (dctx->md)
139 type = EVP_MD_type(dctx->md);
140 else
141 type = NID_sha1;
142
143
144 ret = ECDSA_sign(type, tbs, tbslen, sig, &sltmp, ec);
145
146 if (ret <= 0)
147 return ret;
148 *siglen = (size_t)sltmp;
149 return 1;
150 }
151
152static int pkey_ec_verify(EVP_PKEY_CTX *ctx,
153 const unsigned char *sig, size_t siglen,
154 const unsigned char *tbs, size_t tbslen)
155 {
156 int ret, type;
157 EC_PKEY_CTX *dctx = ctx->data;
158 EC_KEY *ec = ctx->pkey->pkey.ec;
159
160 if (dctx->md)
161 type = EVP_MD_type(dctx->md);
162 else
163 type = NID_sha1;
164
165 ret = ECDSA_verify(type, tbs, tbslen, sig, siglen, ec);
166
167 return ret;
168 }
169
170static int pkey_ec_derive(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen)
171 {
172 int ret;
173 size_t outlen;
174 const EC_POINT *pubkey = NULL;
175 if (!ctx->pkey || !ctx->peerkey)
176 {
177 ECerr(EC_F_PKEY_EC_DERIVE, EC_R_KEYS_NOT_SET);
178 return 0;
179 }
180
181 if (!key)
182 {
183 const EC_GROUP *group;
184 group = EC_KEY_get0_group(ctx->pkey->pkey.ec);
185 *keylen = (EC_GROUP_get_degree(group) + 7)/8;
186 return 1;
187 }
188
189 pubkey = EC_KEY_get0_public_key(ctx->peerkey->pkey.ec);
190
191 /* NB: unlike PKS#3 DH, if *outlen is less than maximum size this is
192 * not an error, the result is truncated.
193 */
194
195 outlen = *keylen;
196
197 ret = ECDH_compute_key(key, outlen, pubkey, ctx->pkey->pkey.ec, 0);
198 if (ret < 0)
199 return ret;
200 *keylen = ret;
201 return 1;
202 }
203
204static int pkey_ec_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
205 {
206 EC_PKEY_CTX *dctx = ctx->data;
207 EC_GROUP *group;
208 switch (type)
209 {
210 case EVP_PKEY_CTRL_EC_PARAMGEN_CURVE_NID:
211 group = EC_GROUP_new_by_curve_name(p1);
212 if (group == NULL)
213 {
214 ECerr(EC_F_PKEY_EC_CTRL, EC_R_INVALID_CURVE);
215 return 0;
216 }
217 if (dctx->gen_group)
218 EC_GROUP_free(dctx->gen_group);
219 dctx->gen_group = group;
220 return 1;
221
222 case EVP_PKEY_CTRL_MD:
223 if (EVP_MD_type((const EVP_MD *)p2) != NID_sha1 &&
224 EVP_MD_type((const EVP_MD *)p2) != NID_sha224 &&
225 EVP_MD_type((const EVP_MD *)p2) != NID_sha256 &&
226 EVP_MD_type((const EVP_MD *)p2) != NID_sha384 &&
227 EVP_MD_type((const EVP_MD *)p2) != NID_sha512)
228 {
229 ECerr(EC_F_PKEY_EC_CTRL, EC_R_INVALID_DIGEST_TYPE);
230 return 0;
231 }
232 dctx->md = p2;
233 return 1;
234
235 case EVP_PKEY_CTRL_PEER_KEY:
236 /* Default behaviour is OK */
237 case EVP_PKEY_CTRL_DIGESTINIT:
238 case EVP_PKEY_CTRL_PKCS7_SIGN:
239 case EVP_PKEY_CTRL_CMS_SIGN:
240 return 1;
241
242 default:
243 return -2;
244
245 }
246 }
247
248static int pkey_ec_ctrl_str(EVP_PKEY_CTX *ctx,
249 const char *type, const char *value)
250 {
251 if (!strcmp(type, "ec_paramgen_curve"))
252 {
253 int nid;
254 nid = OBJ_sn2nid(value);
255 if (nid == NID_undef)
256 nid = OBJ_ln2nid(value);
257 if (nid == NID_undef)
258 {
259 ECerr(EC_F_PKEY_EC_CTRL_STR, EC_R_INVALID_CURVE);
260 return 0;
261 }
262 return EVP_PKEY_CTX_set_ec_paramgen_curve_nid(ctx, nid);
263 }
264 return -2;
265 }
266
267static int pkey_ec_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
268 {
269 EC_KEY *ec = NULL;
270 EC_PKEY_CTX *dctx = ctx->data;
271 int ret = 0;
272 if (dctx->gen_group == NULL)
273 {
274 ECerr(EC_F_PKEY_EC_PARAMGEN, EC_R_NO_PARAMETERS_SET);
275 return 0;
276 }
277 ec = EC_KEY_new();
278 if (!ec)
279 return 0;
280 ret = EC_KEY_set_group(ec, dctx->gen_group);
281 if (ret)
282 EVP_PKEY_assign_EC_KEY(pkey, ec);
283 else
284 EC_KEY_free(ec);
285 return ret;
286 }
287
288static int pkey_ec_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
289 {
290 EC_KEY *ec = NULL;
291 if (ctx->pkey == NULL)
292 {
293 ECerr(EC_F_PKEY_EC_KEYGEN, EC_R_NO_PARAMETERS_SET);
294 return 0;
295 }
296 ec = EC_KEY_new();
297 if (!ec)
298 return 0;
299 EVP_PKEY_assign_EC_KEY(pkey, ec);
300 /* Note: if error return, pkey is freed by parent routine */
301 if (!EVP_PKEY_copy_parameters(pkey, ctx->pkey))
302 return 0;
303 return EC_KEY_generate_key(pkey->pkey.ec);
304 }
305
306const EVP_PKEY_METHOD ec_pkey_meth =
307 {
308 EVP_PKEY_EC,
309 0,
310 pkey_ec_init,
311 pkey_ec_copy,
312 pkey_ec_cleanup,
313
314 0,
315 pkey_ec_paramgen,
316
317 0,
318 pkey_ec_keygen,
319
320 0,
321 pkey_ec_sign,
322
323 0,
324 pkey_ec_verify,
325
326 0,0,
327
328 0,0,0,0,
329
330 0,0,
331
332 0,0,
333
334 0,
335 pkey_ec_derive,
336
337 pkey_ec_ctrl,
338 pkey_ec_ctrl_str
339
340 };
diff --git a/src/lib/libcrypto/ec/eck_prn.c b/src/lib/libcrypto/ec/eck_prn.c
new file mode 100644
index 0000000000..7d3e175ae7
--- /dev/null
+++ b/src/lib/libcrypto/ec/eck_prn.c
@@ -0,0 +1,391 @@
1/* crypto/ec/eck_prn.c */
2/*
3 * Written by Nils Larsch for the OpenSSL project.
4 */
5/* ====================================================================
6 * Copyright (c) 1998-2005 The OpenSSL Project. All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 *
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 *
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in
17 * the documentation and/or other materials provided with the
18 * distribution.
19 *
20 * 3. All advertising materials mentioning features or use of this
21 * software must display the following acknowledgment:
22 * "This product includes software developed by the OpenSSL Project
23 * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
24 *
25 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
26 * endorse or promote products derived from this software without
27 * prior written permission. For written permission, please contact
28 * openssl-core@openssl.org.
29 *
30 * 5. Products derived from this software may not be called "OpenSSL"
31 * nor may "OpenSSL" appear in their names without prior written
32 * permission of the OpenSSL Project.
33 *
34 * 6. Redistributions of any form whatsoever must retain the following
35 * acknowledgment:
36 * "This product includes software developed by the OpenSSL Project
37 * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
38 *
39 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
40 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
43 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
50 * OF THE POSSIBILITY OF SUCH DAMAGE.
51 * ====================================================================
52 *
53 * This product includes cryptographic software written by Eric Young
54 * (eay@cryptsoft.com). This product includes software written by Tim
55 * Hudson (tjh@cryptsoft.com).
56 *
57 */
58/* ====================================================================
59 * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
60 * Portions originally developed by SUN MICROSYSTEMS, INC., and
61 * contributed to the OpenSSL project.
62 */
63
64#include <stdio.h>
65#include "cryptlib.h"
66#include <openssl/evp.h>
67#include <openssl/ec.h>
68#include <openssl/bn.h>
69
70#ifndef OPENSSL_NO_FP_API
71int ECPKParameters_print_fp(FILE *fp, const EC_GROUP *x, int off)
72 {
73 BIO *b;
74 int ret;
75
76 if ((b=BIO_new(BIO_s_file())) == NULL)
77 {
78 ECerr(EC_F_ECPKPARAMETERS_PRINT_FP,ERR_R_BUF_LIB);
79 return(0);
80 }
81 BIO_set_fp(b, fp, BIO_NOCLOSE);
82 ret = ECPKParameters_print(b, x, off);
83 BIO_free(b);
84 return(ret);
85 }
86
87int EC_KEY_print_fp(FILE *fp, const EC_KEY *x, int off)
88 {
89 BIO *b;
90 int ret;
91
92 if ((b=BIO_new(BIO_s_file())) == NULL)
93 {
94 ECerr(EC_F_EC_KEY_PRINT_FP, ERR_R_BIO_LIB);
95 return(0);
96 }
97 BIO_set_fp(b, fp, BIO_NOCLOSE);
98 ret = EC_KEY_print(b, x, off);
99 BIO_free(b);
100 return(ret);
101 }
102
103int ECParameters_print_fp(FILE *fp, const EC_KEY *x)
104 {
105 BIO *b;
106 int ret;
107
108 if ((b=BIO_new(BIO_s_file())) == NULL)
109 {
110 ECerr(EC_F_ECPARAMETERS_PRINT_FP, ERR_R_BIO_LIB);
111 return(0);
112 }
113 BIO_set_fp(b, fp, BIO_NOCLOSE);
114 ret = ECParameters_print(b, x);
115 BIO_free(b);
116 return(ret);
117 }
118#endif
119
120int EC_KEY_print(BIO *bp, const EC_KEY *x, int off)
121 {
122 EVP_PKEY *pk;
123 int ret;
124 pk = EVP_PKEY_new();
125 if (!pk || !EVP_PKEY_set1_EC_KEY(pk, (EC_KEY *)x))
126 return 0;
127 ret = EVP_PKEY_print_private(bp, pk, off, NULL);
128 EVP_PKEY_free(pk);
129 return ret;
130 }
131
132int ECParameters_print(BIO *bp, const EC_KEY *x)
133 {
134 EVP_PKEY *pk;
135 int ret;
136 pk = EVP_PKEY_new();
137 if (!pk || !EVP_PKEY_set1_EC_KEY(pk, (EC_KEY *)x))
138 return 0;
139 ret = EVP_PKEY_print_params(bp, pk, 4, NULL);
140 EVP_PKEY_free(pk);
141 return ret;
142 }
143
144static int print_bin(BIO *fp, const char *str, const unsigned char *num,
145 size_t len, int off);
146
147int ECPKParameters_print(BIO *bp, const EC_GROUP *x, int off)
148 {
149 unsigned char *buffer=NULL;
150 size_t buf_len=0, i;
151 int ret=0, reason=ERR_R_BIO_LIB;
152 BN_CTX *ctx=NULL;
153 const EC_POINT *point=NULL;
154 BIGNUM *p=NULL, *a=NULL, *b=NULL, *gen=NULL,
155 *order=NULL, *cofactor=NULL;
156 const unsigned char *seed;
157 size_t seed_len=0;
158
159 static const char *gen_compressed = "Generator (compressed):";
160 static const char *gen_uncompressed = "Generator (uncompressed):";
161 static const char *gen_hybrid = "Generator (hybrid):";
162
163 if (!x)
164 {
165 reason = ERR_R_PASSED_NULL_PARAMETER;
166 goto err;
167 }
168
169 ctx = BN_CTX_new();
170 if (ctx == NULL)
171 {
172 reason = ERR_R_MALLOC_FAILURE;
173 goto err;
174 }
175
176 if (EC_GROUP_get_asn1_flag(x))
177 {
178 /* the curve parameter are given by an asn1 OID */
179 int nid;
180
181 if (!BIO_indent(bp, off, 128))
182 goto err;
183
184 nid = EC_GROUP_get_curve_name(x);
185 if (nid == 0)
186 goto err;
187
188 if (BIO_printf(bp, "ASN1 OID: %s", OBJ_nid2sn(nid)) <= 0)
189 goto err;
190 if (BIO_printf(bp, "\n") <= 0)
191 goto err;
192 }
193 else
194 {
195 /* explicit parameters */
196 int is_char_two = 0;
197 point_conversion_form_t form;
198 int tmp_nid = EC_METHOD_get_field_type(EC_GROUP_method_of(x));
199
200 if (tmp_nid == NID_X9_62_characteristic_two_field)
201 is_char_two = 1;
202
203 if ((p = BN_new()) == NULL || (a = BN_new()) == NULL ||
204 (b = BN_new()) == NULL || (order = BN_new()) == NULL ||
205 (cofactor = BN_new()) == NULL)
206 {
207 reason = ERR_R_MALLOC_FAILURE;
208 goto err;
209 }
210
211 if (is_char_two)
212 {
213 if (!EC_GROUP_get_curve_GF2m(x, p, a, b, ctx))
214 {
215 reason = ERR_R_EC_LIB;
216 goto err;
217 }
218 }
219 else /* prime field */
220 {
221 if (!EC_GROUP_get_curve_GFp(x, p, a, b, ctx))
222 {
223 reason = ERR_R_EC_LIB;
224 goto err;
225 }
226 }
227
228 if ((point = EC_GROUP_get0_generator(x)) == NULL)
229 {
230 reason = ERR_R_EC_LIB;
231 goto err;
232 }
233 if (!EC_GROUP_get_order(x, order, NULL) ||
234 !EC_GROUP_get_cofactor(x, cofactor, NULL))
235 {
236 reason = ERR_R_EC_LIB;
237 goto err;
238 }
239
240 form = EC_GROUP_get_point_conversion_form(x);
241
242 if ((gen = EC_POINT_point2bn(x, point,
243 form, NULL, ctx)) == NULL)
244 {
245 reason = ERR_R_EC_LIB;
246 goto err;
247 }
248
249 buf_len = (size_t)BN_num_bytes(p);
250 if (buf_len < (i = (size_t)BN_num_bytes(a)))
251 buf_len = i;
252 if (buf_len < (i = (size_t)BN_num_bytes(b)))
253 buf_len = i;
254 if (buf_len < (i = (size_t)BN_num_bytes(gen)))
255 buf_len = i;
256 if (buf_len < (i = (size_t)BN_num_bytes(order)))
257 buf_len = i;
258 if (buf_len < (i = (size_t)BN_num_bytes(cofactor)))
259 buf_len = i;
260
261 if ((seed = EC_GROUP_get0_seed(x)) != NULL)
262 seed_len = EC_GROUP_get_seed_len(x);
263
264 buf_len += 10;
265 if ((buffer = OPENSSL_malloc(buf_len)) == NULL)
266 {
267 reason = ERR_R_MALLOC_FAILURE;
268 goto err;
269 }
270
271 if (!BIO_indent(bp, off, 128))
272 goto err;
273
274 /* print the 'short name' of the field type */
275 if (BIO_printf(bp, "Field Type: %s\n", OBJ_nid2sn(tmp_nid))
276 <= 0)
277 goto err;
278
279 if (is_char_two)
280 {
281 /* print the 'short name' of the base type OID */
282 int basis_type = EC_GROUP_get_basis_type(x);
283 if (basis_type == 0)
284 goto err;
285
286 if (!BIO_indent(bp, off, 128))
287 goto err;
288
289 if (BIO_printf(bp, "Basis Type: %s\n",
290 OBJ_nid2sn(basis_type)) <= 0)
291 goto err;
292
293 /* print the polynomial */
294 if ((p != NULL) && !ASN1_bn_print(bp, "Polynomial:", p, buffer,
295 off))
296 goto err;
297 }
298 else
299 {
300 if ((p != NULL) && !ASN1_bn_print(bp, "Prime:", p, buffer,off))
301 goto err;
302 }
303 if ((a != NULL) && !ASN1_bn_print(bp, "A: ", a, buffer, off))
304 goto err;
305 if ((b != NULL) && !ASN1_bn_print(bp, "B: ", b, buffer, off))
306 goto err;
307 if (form == POINT_CONVERSION_COMPRESSED)
308 {
309 if ((gen != NULL) && !ASN1_bn_print(bp, gen_compressed, gen,
310 buffer, off))
311 goto err;
312 }
313 else if (form == POINT_CONVERSION_UNCOMPRESSED)
314 {
315 if ((gen != NULL) && !ASN1_bn_print(bp, gen_uncompressed, gen,
316 buffer, off))
317 goto err;
318 }
319 else /* form == POINT_CONVERSION_HYBRID */
320 {
321 if ((gen != NULL) && !ASN1_bn_print(bp, gen_hybrid, gen,
322 buffer, off))
323 goto err;
324 }
325 if ((order != NULL) && !ASN1_bn_print(bp, "Order: ", order,
326 buffer, off)) goto err;
327 if ((cofactor != NULL) && !ASN1_bn_print(bp, "Cofactor: ", cofactor,
328 buffer, off)) goto err;
329 if (seed && !print_bin(bp, "Seed:", seed, seed_len, off))
330 goto err;
331 }
332 ret=1;
333err:
334 if (!ret)
335 ECerr(EC_F_ECPKPARAMETERS_PRINT, reason);
336 if (p)
337 BN_free(p);
338 if (a)
339 BN_free(a);
340 if (b)
341 BN_free(b);
342 if (gen)
343 BN_free(gen);
344 if (order)
345 BN_free(order);
346 if (cofactor)
347 BN_free(cofactor);
348 if (ctx)
349 BN_CTX_free(ctx);
350 if (buffer != NULL)
351 OPENSSL_free(buffer);
352 return(ret);
353 }
354
355static int print_bin(BIO *fp, const char *name, const unsigned char *buf,
356 size_t len, int off)
357 {
358 size_t i;
359 char str[128];
360
361 if (buf == NULL)
362 return 1;
363 if (off)
364 {
365 if (off > 128)
366 off=128;
367 memset(str,' ',off);
368 if (BIO_write(fp, str, off) <= 0)
369 return 0;
370 }
371
372 if (BIO_printf(fp,"%s", name) <= 0)
373 return 0;
374
375 for (i=0; i<len; i++)
376 {
377 if ((i%15) == 0)
378 {
379 str[0]='\n';
380 memset(&(str[1]),' ',off+4);
381 if (BIO_write(fp, str, off+1+4) <= 0)
382 return 0;
383 }
384 if (BIO_printf(fp,"%02x%s",buf[i],((i+1) == len)?"":":") <= 0)
385 return 0;
386 }
387 if (BIO_write(fp,"\n",1) <= 0)
388 return 0;
389
390 return 1;
391 }
diff --git a/src/lib/libcrypto/ec/ecp_nist.c b/src/lib/libcrypto/ec/ecp_nist.c
index 71893d5eab..2a5682ea41 100644
--- a/src/lib/libcrypto/ec/ecp_nist.c
+++ b/src/lib/libcrypto/ec/ecp_nist.c
@@ -112,10 +112,6 @@ const EC_METHOD *EC_GFp_nist_method(void)
112 return &ret; 112 return &ret;
113 } 113 }
114 114
115#if BN_BITS2 == 64
116#define NO_32_BIT_TYPE
117#endif
118
119int ec_GFp_nist_group_copy(EC_GROUP *dest, const EC_GROUP *src) 115int ec_GFp_nist_group_copy(EC_GROUP *dest, const EC_GROUP *src)
120 { 116 {
121 dest->field_mod_func = src->field_mod_func; 117 dest->field_mod_func = src->field_mod_func;
@@ -139,34 +135,12 @@ int ec_GFp_nist_group_set_curve(EC_GROUP *group, const BIGNUM *p,
139 if (BN_ucmp(BN_get0_nist_prime_192(), p) == 0) 135 if (BN_ucmp(BN_get0_nist_prime_192(), p) == 0)
140 group->field_mod_func = BN_nist_mod_192; 136 group->field_mod_func = BN_nist_mod_192;
141 else if (BN_ucmp(BN_get0_nist_prime_224(), p) == 0) 137 else if (BN_ucmp(BN_get0_nist_prime_224(), p) == 0)
142 {
143#ifndef NO_32_BIT_TYPE
144 group->field_mod_func = BN_nist_mod_224; 138 group->field_mod_func = BN_nist_mod_224;
145#else
146 ECerr(EC_F_EC_GFP_NIST_GROUP_SET_CURVE, EC_R_NOT_A_SUPPORTED_NIST_PRIME);
147 goto err;
148#endif
149 }
150 else if (BN_ucmp(BN_get0_nist_prime_256(), p) == 0) 139 else if (BN_ucmp(BN_get0_nist_prime_256(), p) == 0)
151 {
152#ifndef NO_32_BIT_TYPE
153 group->field_mod_func = BN_nist_mod_256; 140 group->field_mod_func = BN_nist_mod_256;
154#else
155 ECerr(EC_F_EC_GFP_NIST_GROUP_SET_CURVE, EC_R_NOT_A_SUPPORTED_NIST_PRIME);
156 goto err;
157#endif
158 }
159 else if (BN_ucmp(BN_get0_nist_prime_384(), p) == 0) 141 else if (BN_ucmp(BN_get0_nist_prime_384(), p) == 0)
160 {
161#ifndef NO_32_BIT_TYPE
162 group->field_mod_func = BN_nist_mod_384; 142 group->field_mod_func = BN_nist_mod_384;
163#else
164 ECerr(EC_F_EC_GFP_NIST_GROUP_SET_CURVE, EC_R_NOT_A_SUPPORTED_NIST_PRIME);
165 goto err;
166#endif
167 }
168 else if (BN_ucmp(BN_get0_nist_prime_521(), p) == 0) 143 else if (BN_ucmp(BN_get0_nist_prime_521(), p) == 0)
169 /* this one works in the NO_32_BIT_TYPE case */
170 group->field_mod_func = BN_nist_mod_521; 144 group->field_mod_func = BN_nist_mod_521;
171 else 145 else
172 { 146 {
diff --git a/src/lib/libcrypto/ecdh/ech_err.c b/src/lib/libcrypto/ecdh/ech_err.c
index 4d2ede75bd..6f4b0c9953 100644
--- a/src/lib/libcrypto/ecdh/ech_err.c
+++ b/src/lib/libcrypto/ecdh/ech_err.c
@@ -1,6 +1,6 @@
1/* crypto/ecdh/ech_err.c */ 1/* crypto/ecdh/ech_err.c */
2/* ==================================================================== 2/* ====================================================================
3 * Copyright (c) 1999-2005 The OpenSSL Project. All rights reserved. 3 * Copyright (c) 1999-2006 The OpenSSL Project. All rights reserved.
4 * 4 *
5 * Redistribution and use in source and binary forms, with or without 5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions 6 * modification, are permitted provided that the following conditions
@@ -71,7 +71,7 @@
71static ERR_STRING_DATA ECDH_str_functs[]= 71static ERR_STRING_DATA ECDH_str_functs[]=
72 { 72 {
73{ERR_FUNC(ECDH_F_ECDH_COMPUTE_KEY), "ECDH_compute_key"}, 73{ERR_FUNC(ECDH_F_ECDH_COMPUTE_KEY), "ECDH_compute_key"},
74{ERR_FUNC(ECDH_F_ECDH_DATA_NEW_METHOD), "ECDH_DATA_NEW_METHOD"}, 74{ERR_FUNC(ECDH_F_ECDH_DATA_NEW_METHOD), "ECDH_DATA_new_method"},
75{0,NULL} 75{0,NULL}
76 }; 76 };
77 77
diff --git a/src/lib/libcrypto/ecdsa/ecdsa.h b/src/lib/libcrypto/ecdsa/ecdsa.h
index f20c8ee738..e61c539812 100644
--- a/src/lib/libcrypto/ecdsa/ecdsa.h
+++ b/src/lib/libcrypto/ecdsa/ecdsa.h
@@ -4,7 +4,7 @@
4 * \author Written by Nils Larsch for the OpenSSL project 4 * \author Written by Nils Larsch for the OpenSSL project
5 */ 5 */
6/* ==================================================================== 6/* ====================================================================
7 * Copyright (c) 2000-2003 The OpenSSL Project. All rights reserved. 7 * Copyright (c) 2000-2005 The OpenSSL Project. All rights reserved.
8 * 8 *
9 * Redistribution and use in source and binary forms, with or without 9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions 10 * modification, are permitted provided that the following conditions
@@ -81,156 +81,143 @@ typedef struct ECDSA_SIG_st
81 BIGNUM *s; 81 BIGNUM *s;
82 } ECDSA_SIG; 82 } ECDSA_SIG;
83 83
84/** ECDSA_SIG *ECDSA_SIG_new(void) 84/** Allocates and initialize a ECDSA_SIG structure
85 * allocates and initialize a ECDSA_SIG structure 85 * \return pointer to a ECDSA_SIG structure or NULL if an error occurred
86 * \return pointer to a ECDSA_SIG structure or NULL if an error occurred
87 */ 86 */
88ECDSA_SIG *ECDSA_SIG_new(void); 87ECDSA_SIG *ECDSA_SIG_new(void);
89 88
90/** ECDSA_SIG_free 89/** frees a ECDSA_SIG structure
91 * frees a ECDSA_SIG structure 90 * \param sig pointer to the ECDSA_SIG structure
92 * \param a pointer to the ECDSA_SIG structure
93 */ 91 */
94void ECDSA_SIG_free(ECDSA_SIG *a); 92void ECDSA_SIG_free(ECDSA_SIG *sig);
95 93
96/** i2d_ECDSA_SIG 94/** DER encode content of ECDSA_SIG object (note: this function modifies *pp
97 * DER encode content of ECDSA_SIG object (note: this function modifies *pp 95 * (*pp += length of the DER encoded signature)).
98 * (*pp += length of the DER encoded signature)). 96 * \param sig pointer to the ECDSA_SIG object
99 * \param a pointer to the ECDSA_SIG object 97 * \param pp pointer to a unsigned char pointer for the output or NULL
100 * \param pp pointer to a unsigned char pointer for the output or NULL 98 * \return the length of the DER encoded ECDSA_SIG object or 0
101 * \return the length of the DER encoded ECDSA_SIG object or 0
102 */ 99 */
103int i2d_ECDSA_SIG(const ECDSA_SIG *a, unsigned char **pp); 100int i2d_ECDSA_SIG(const ECDSA_SIG *sig, unsigned char **pp);
104 101
105/** d2i_ECDSA_SIG 102/** Decodes a DER encoded ECDSA signature (note: this function changes *pp
106 * decodes a DER encoded ECDSA signature (note: this function changes *pp 103 * (*pp += len)).
107 * (*pp += len)). 104 * \param sig pointer to ECDSA_SIG pointer (may be NULL)
108 * \param v pointer to ECDSA_SIG pointer (may be NULL) 105 * \param pp memory buffer with the DER encoded signature
109 * \param pp buffer with the DER encoded signature 106 * \param len length of the buffer
110 * \param len bufferlength 107 * \return pointer to the decoded ECDSA_SIG structure (or NULL)
111 * \return pointer to the decoded ECDSA_SIG structure (or NULL)
112 */ 108 */
113ECDSA_SIG *d2i_ECDSA_SIG(ECDSA_SIG **v, const unsigned char **pp, long len); 109ECDSA_SIG *d2i_ECDSA_SIG(ECDSA_SIG **sig, const unsigned char **pp, long len);
114 110
115/** ECDSA_do_sign 111/** Computes the ECDSA signature of the given hash value using
116 * computes the ECDSA signature of the given hash value using 112 * the supplied private key and returns the created signature.
117 * the supplied private key and returns the created signature. 113 * \param dgst pointer to the hash value
118 * \param dgst pointer to the hash value 114 * \param dgst_len length of the hash value
119 * \param dgst_len length of the hash value 115 * \param eckey EC_KEY object containing a private EC key
120 * \param eckey pointer to the EC_KEY object containing a private EC key 116 * \return pointer to a ECDSA_SIG structure or NULL if an error occurred
121 * \return pointer to a ECDSA_SIG structure or NULL
122 */ 117 */
123ECDSA_SIG *ECDSA_do_sign(const unsigned char *dgst,int dgst_len,EC_KEY *eckey); 118ECDSA_SIG *ECDSA_do_sign(const unsigned char *dgst,int dgst_len,EC_KEY *eckey);
124 119
125/** ECDSA_do_sign_ex 120/** Computes ECDSA signature of a given hash value using the supplied
126 * computes ECDSA signature of a given hash value using the supplied 121 * private key (note: sig must point to ECDSA_size(eckey) bytes of memory).
127 * private key (note: sig must point to ECDSA_size(eckey) bytes of memory). 122 * \param dgst pointer to the hash value to sign
128 * \param dgst pointer to the hash value to sign 123 * \param dgstlen length of the hash value
129 * \param dgstlen length of the hash value 124 * \param kinv BIGNUM with a pre-computed inverse k (optional)
130 * \param kinv optional pointer to a pre-computed inverse k 125 * \param rp BIGNUM with a pre-computed rp value (optioanl),
131 * \param rp optional pointer to the pre-computed rp value (see 126 * see ECDSA_sign_setup
132 * ECDSA_sign_setup 127 * \param eckey EC_KEY object containing a private EC key
133 * \param eckey pointer to the EC_KEY object containing a private EC key 128 * \return pointer to a ECDSA_SIG structure or NULL if an error occurred
134 * \return pointer to a ECDSA_SIG structure or NULL
135 */ 129 */
136ECDSA_SIG *ECDSA_do_sign_ex(const unsigned char *dgst, int dgstlen, 130ECDSA_SIG *ECDSA_do_sign_ex(const unsigned char *dgst, int dgstlen,
137 const BIGNUM *kinv, const BIGNUM *rp, EC_KEY *eckey); 131 const BIGNUM *kinv, const BIGNUM *rp, EC_KEY *eckey);
138 132
139/** ECDSA_do_verify 133/** Verifies that the supplied signature is a valid ECDSA
140 * verifies that the supplied signature is a valid ECDSA 134 * signature of the supplied hash value using the supplied public key.
141 * signature of the supplied hash value using the supplied public key. 135 * \param dgst pointer to the hash value
142 * \param dgst pointer to the hash value 136 * \param dgst_len length of the hash value
143 * \param dgst_len length of the hash value 137 * \param sig ECDSA_SIG structure
144 * \param sig pointer to the ECDSA_SIG structure 138 * \param eckey EC_KEY object containing a public EC key
145 * \param eckey pointer to the EC_KEY object containing a public EC key 139 * \return 1 if the signature is valid, 0 if the signature is invalid
146 * \return 1 if the signature is valid, 0 if the signature is invalid and -1 on error 140 * and -1 on error
147 */ 141 */
148int ECDSA_do_verify(const unsigned char *dgst, int dgst_len, 142int ECDSA_do_verify(const unsigned char *dgst, int dgst_len,
149 const ECDSA_SIG *sig, EC_KEY* eckey); 143 const ECDSA_SIG *sig, EC_KEY* eckey);
150 144
151const ECDSA_METHOD *ECDSA_OpenSSL(void); 145const ECDSA_METHOD *ECDSA_OpenSSL(void);
152 146
153/** ECDSA_set_default_method 147/** Sets the default ECDSA method
154 * sets the default ECDSA method 148 * \param meth new default ECDSA_METHOD
155 * \param meth the new default ECDSA_METHOD
156 */ 149 */
157void ECDSA_set_default_method(const ECDSA_METHOD *meth); 150void ECDSA_set_default_method(const ECDSA_METHOD *meth);
158 151
159/** ECDSA_get_default_method 152/** Returns the default ECDSA method
160 * returns the default ECDSA method 153 * \return pointer to ECDSA_METHOD structure containing the default method
161 * \return pointer to ECDSA_METHOD structure containing the default method
162 */ 154 */
163const ECDSA_METHOD *ECDSA_get_default_method(void); 155const ECDSA_METHOD *ECDSA_get_default_method(void);
164 156
165/** ECDSA_set_method 157/** Sets method to be used for the ECDSA operations
166 * sets method to be used for the ECDSA operations 158 * \param eckey EC_KEY object
167 * \param eckey pointer to the EC_KEY object 159 * \param meth new method
168 * \param meth pointer to the new method 160 * \return 1 on success and 0 otherwise
169 * \return 1 on success and 0 otherwise
170 */ 161 */
171int ECDSA_set_method(EC_KEY *eckey, const ECDSA_METHOD *meth); 162int ECDSA_set_method(EC_KEY *eckey, const ECDSA_METHOD *meth);
172 163
173/** ECDSA_size 164/** Returns the maximum length of the DER encoded signature
174 * returns the maximum length of the DER encoded signature 165 * \param eckey EC_KEY object
175 * \param eckey pointer to a EC_KEY object 166 * \return numbers of bytes required for the DER encoded signature
176 * \return numbers of bytes required for the DER encoded signature
177 */ 167 */
178int ECDSA_size(const EC_KEY *eckey); 168int ECDSA_size(const EC_KEY *eckey);
179 169
180/** ECDSA_sign_setup 170/** Precompute parts of the signing operation
181 * precompute parts of the signing operation. 171 * \param eckey EC_KEY object containing a private EC key
182 * \param eckey pointer to the EC_KEY object containing a private EC key 172 * \param ctx BN_CTX object (optional)
183 * \param ctx pointer to a BN_CTX object (may be NULL) 173 * \param kinv BIGNUM pointer for the inverse of k
184 * \param kinv pointer to a BIGNUM pointer for the inverse of k 174 * \param rp BIGNUM pointer for x coordinate of k * generator
185 * \param rp pointer to a BIGNUM pointer for x coordinate of k * generator 175 * \return 1 on success and 0 otherwise
186 * \return 1 on success and 0 otherwise
187 */ 176 */
188int ECDSA_sign_setup(EC_KEY *eckey, BN_CTX *ctx, BIGNUM **kinv, 177int ECDSA_sign_setup(EC_KEY *eckey, BN_CTX *ctx, BIGNUM **kinv,
189 BIGNUM **rp); 178 BIGNUM **rp);
190 179
191/** ECDSA_sign 180/** Computes ECDSA signature of a given hash value using the supplied
192 * computes ECDSA signature of a given hash value using the supplied 181 * private key (note: sig must point to ECDSA_size(eckey) bytes of memory).
193 * private key (note: sig must point to ECDSA_size(eckey) bytes of memory). 182 * \param type this parameter is ignored
194 * \param type this parameter is ignored 183 * \param dgst pointer to the hash value to sign
195 * \param dgst pointer to the hash value to sign 184 * \param dgstlen length of the hash value
196 * \param dgstlen length of the hash value 185 * \param sig memory for the DER encoded created signature
197 * \param sig buffer to hold the DER encoded signature 186 * \param siglen pointer to the length of the returned signature
198 * \param siglen pointer to the length of the returned signature 187 * \param eckey EC_KEY object containing a private EC key
199 * \param eckey pointer to the EC_KEY object containing a private EC key 188 * \return 1 on success and 0 otherwise
200 * \return 1 on success and 0 otherwise
201 */ 189 */
202int ECDSA_sign(int type, const unsigned char *dgst, int dgstlen, 190int ECDSA_sign(int type, const unsigned char *dgst, int dgstlen,
203 unsigned char *sig, unsigned int *siglen, EC_KEY *eckey); 191 unsigned char *sig, unsigned int *siglen, EC_KEY *eckey);
204 192
205 193
206/** ECDSA_sign_ex 194/** Computes ECDSA signature of a given hash value using the supplied
207 * computes ECDSA signature of a given hash value using the supplied 195 * private key (note: sig must point to ECDSA_size(eckey) bytes of memory).
208 * private key (note: sig must point to ECDSA_size(eckey) bytes of memory). 196 * \param type this parameter is ignored
209 * \param type this parameter is ignored 197 * \param dgst pointer to the hash value to sign
210 * \param dgst pointer to the hash value to sign 198 * \param dgstlen length of the hash value
211 * \param dgstlen length of the hash value 199 * \param sig buffer to hold the DER encoded signature
212 * \param sig buffer to hold the DER encoded signature 200 * \param siglen pointer to the length of the returned signature
213 * \param siglen pointer to the length of the returned signature 201 * \param kinv BIGNUM with a pre-computed inverse k (optional)
214 * \param kinv optional pointer to a pre-computed inverse k 202 * \param rp BIGNUM with a pre-computed rp value (optioanl),
215 * \param rp optional pointer to the pre-computed rp value (see 203 * see ECDSA_sign_setup
216 * ECDSA_sign_setup 204 * \param eckey EC_KEY object containing a private EC key
217 * \param eckey pointer to the EC_KEY object containing a private EC key 205 * \return 1 on success and 0 otherwise
218 * \return 1 on success and 0 otherwise
219 */ 206 */
220int ECDSA_sign_ex(int type, const unsigned char *dgst, int dgstlen, 207int ECDSA_sign_ex(int type, const unsigned char *dgst, int dgstlen,
221 unsigned char *sig, unsigned int *siglen, const BIGNUM *kinv, 208 unsigned char *sig, unsigned int *siglen, const BIGNUM *kinv,
222 const BIGNUM *rp, EC_KEY *eckey); 209 const BIGNUM *rp, EC_KEY *eckey);
223 210
224/** ECDSA_verify 211/** Verifies that the given signature is valid ECDSA signature
225 * verifies that the given signature is valid ECDSA signature 212 * of the supplied hash value using the specified public key.
226 * of the supplied hash value using the specified public key. 213 * \param type this parameter is ignored
227 * \param type this parameter is ignored 214 * \param dgst pointer to the hash value
228 * \param dgst pointer to the hash value 215 * \param dgstlen length of the hash value
229 * \param dgstlen length of the hash value 216 * \param sig pointer to the DER encoded signature
230 * \param sig pointer to the DER encoded signature 217 * \param siglen length of the DER encoded signature
231 * \param siglen length of the DER encoded signature 218 * \param eckey EC_KEY object containing a public EC key
232 * \param eckey pointer to the EC_KEY object containing a public EC key 219 * \return 1 if the signature is valid, 0 if the signature is invalid
233 * \return 1 if the signature is valid, 0 if the signature is invalid and -1 on error 220 * and -1 on error
234 */ 221 */
235int ECDSA_verify(int type, const unsigned char *dgst, int dgstlen, 222int ECDSA_verify(int type, const unsigned char *dgst, int dgstlen,
236 const unsigned char *sig, int siglen, EC_KEY *eckey); 223 const unsigned char *sig, int siglen, EC_KEY *eckey);
diff --git a/src/lib/libcrypto/ecdsa/ecs_err.c b/src/lib/libcrypto/ecdsa/ecs_err.c
index d2a53730ea..98e38d537f 100644
--- a/src/lib/libcrypto/ecdsa/ecs_err.c
+++ b/src/lib/libcrypto/ecdsa/ecs_err.c
@@ -1,6 +1,6 @@
1/* crypto/ecdsa/ecs_err.c */ 1/* crypto/ecdsa/ecs_err.c */
2/* ==================================================================== 2/* ====================================================================
3 * Copyright (c) 1999-2005 The OpenSSL Project. All rights reserved. 3 * Copyright (c) 1999-2006 The OpenSSL Project. All rights reserved.
4 * 4 *
5 * Redistribution and use in source and binary forms, with or without 5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions 6 * modification, are permitted provided that the following conditions
diff --git a/src/lib/libcrypto/ecdsa/ecs_ossl.c b/src/lib/libcrypto/ecdsa/ecs_ossl.c
index 3ead1af94e..551cf5068f 100644
--- a/src/lib/libcrypto/ecdsa/ecs_ossl.c
+++ b/src/lib/libcrypto/ecdsa/ecs_ossl.c
@@ -212,7 +212,7 @@ err:
212static ECDSA_SIG *ecdsa_do_sign(const unsigned char *dgst, int dgst_len, 212static ECDSA_SIG *ecdsa_do_sign(const unsigned char *dgst, int dgst_len,
213 const BIGNUM *in_kinv, const BIGNUM *in_r, EC_KEY *eckey) 213 const BIGNUM *in_kinv, const BIGNUM *in_r, EC_KEY *eckey)
214{ 214{
215 int ok = 0; 215 int ok = 0, i;
216 BIGNUM *kinv=NULL, *s, *m=NULL,*tmp=NULL,*order=NULL; 216 BIGNUM *kinv=NULL, *s, *m=NULL,*tmp=NULL,*order=NULL;
217 const BIGNUM *ckinv; 217 const BIGNUM *ckinv;
218 BN_CTX *ctx = NULL; 218 BN_CTX *ctx = NULL;
@@ -251,22 +251,19 @@ static ECDSA_SIG *ecdsa_do_sign(const unsigned char *dgst, int dgst_len,
251 ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_EC_LIB); 251 ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_EC_LIB);
252 goto err; 252 goto err;
253 } 253 }
254 if (8 * dgst_len > BN_num_bits(order)) 254 i = BN_num_bits(order);
255 /* Need to truncate digest if it is too long: first truncate whole
256 * bytes.
257 */
258 if (8 * dgst_len > i)
259 dgst_len = (i + 7)/8;
260 if (!BN_bin2bn(dgst, dgst_len, m))
255 { 261 {
256 /* XXX 262 ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB);
257 *
258 * Should provide for optional hash truncation:
259 * Keep the BN_num_bits(order) leftmost bits of dgst
260 * (see March 2006 FIPS 186-3 draft, which has a few
261 * confusing errors in this part though)
262 */
263
264 ECDSAerr(ECDSA_F_ECDSA_DO_SIGN,
265 ECDSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE);
266 goto err; 263 goto err;
267 } 264 }
268 265 /* If still too long truncate remaining bits with a shift */
269 if (!BN_bin2bn(dgst, dgst_len, m)) 266 if ((8 * dgst_len > i) && !BN_rshift(m, m, 8 - (i & 0x7)))
270 { 267 {
271 ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB); 268 ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB);
272 goto err; 269 goto err;
@@ -346,7 +343,7 @@ err:
346static int ecdsa_do_verify(const unsigned char *dgst, int dgst_len, 343static int ecdsa_do_verify(const unsigned char *dgst, int dgst_len,
347 const ECDSA_SIG *sig, EC_KEY *eckey) 344 const ECDSA_SIG *sig, EC_KEY *eckey)
348{ 345{
349 int ret = -1; 346 int ret = -1, i;
350 BN_CTX *ctx; 347 BN_CTX *ctx;
351 BIGNUM *order, *u1, *u2, *m, *X; 348 BIGNUM *order, *u1, *u2, *m, *X;
352 EC_POINT *point = NULL; 349 EC_POINT *point = NULL;
@@ -384,21 +381,6 @@ static int ecdsa_do_verify(const unsigned char *dgst, int dgst_len,
384 ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB); 381 ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB);
385 goto err; 382 goto err;
386 } 383 }
387 if (8 * dgst_len > BN_num_bits(order))
388 {
389 /* XXX
390 *
391 * Should provide for optional hash truncation:
392 * Keep the BN_num_bits(order) leftmost bits of dgst
393 * (see March 2006 FIPS 186-3 draft, which has a few
394 * confusing errors in this part though)
395 */
396
397 ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY,
398 ECDSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE);
399 ret = 0;
400 goto err;
401 }
402 384
403 if (BN_is_zero(sig->r) || BN_is_negative(sig->r) || 385 if (BN_is_zero(sig->r) || BN_is_negative(sig->r) ||
404 BN_ucmp(sig->r, order) >= 0 || BN_is_zero(sig->s) || 386 BN_ucmp(sig->r, order) >= 0 || BN_is_zero(sig->s) ||
@@ -415,11 +397,23 @@ static int ecdsa_do_verify(const unsigned char *dgst, int dgst_len,
415 goto err; 397 goto err;
416 } 398 }
417 /* digest -> m */ 399 /* digest -> m */
400 i = BN_num_bits(order);
401 /* Need to truncate digest if it is too long: first truncate whole
402 * bytes.
403 */
404 if (8 * dgst_len > i)
405 dgst_len = (i + 7)/8;
418 if (!BN_bin2bn(dgst, dgst_len, m)) 406 if (!BN_bin2bn(dgst, dgst_len, m))
419 { 407 {
420 ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB); 408 ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB);
421 goto err; 409 goto err;
422 } 410 }
411 /* If still too long truncate remaining bits with a shift */
412 if ((8 * dgst_len > i) && !BN_rshift(m, m, 8 - (i & 0x7)))
413 {
414 ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB);
415 goto err;
416 }
423 /* u1 = m * tmp mod order */ 417 /* u1 = m * tmp mod order */
424 if (!BN_mod_mul(u1, m, u2, order, ctx)) 418 if (!BN_mod_mul(u1, m, u2, order, ctx))
425 { 419 {
diff --git a/src/lib/libcrypto/ecdsa/ecs_sign.c b/src/lib/libcrypto/ecdsa/ecs_sign.c
index 74b1fe8caf..353d5af514 100644
--- a/src/lib/libcrypto/ecdsa/ecs_sign.c
+++ b/src/lib/libcrypto/ecdsa/ecs_sign.c
@@ -57,6 +57,7 @@
57#ifndef OPENSSL_NO_ENGINE 57#ifndef OPENSSL_NO_ENGINE
58#include <openssl/engine.h> 58#include <openssl/engine.h>
59#endif 59#endif
60#include <openssl/rand.h>
60 61
61ECDSA_SIG *ECDSA_do_sign(const unsigned char *dgst, int dlen, EC_KEY *eckey) 62ECDSA_SIG *ECDSA_do_sign(const unsigned char *dgst, int dlen, EC_KEY *eckey)
62{ 63{
@@ -83,6 +84,7 @@ int ECDSA_sign_ex(int type, const unsigned char *dgst, int dlen, unsigned char
83 EC_KEY *eckey) 84 EC_KEY *eckey)
84{ 85{
85 ECDSA_SIG *s; 86 ECDSA_SIG *s;
87 RAND_seed(dgst, dlen);
86 s = ECDSA_do_sign_ex(dgst, dlen, kinv, r, eckey); 88 s = ECDSA_do_sign_ex(dgst, dlen, kinv, r, eckey);
87 if (s == NULL) 89 if (s == NULL)
88 { 90 {
diff --git a/src/lib/libcrypto/engine/eng_all.c b/src/lib/libcrypto/engine/eng_all.c
index d29cd57dc2..22c120454f 100644
--- a/src/lib/libcrypto/engine/eng_all.c
+++ b/src/lib/libcrypto/engine/eng_all.c
@@ -61,15 +61,15 @@
61 61
62void ENGINE_load_builtin_engines(void) 62void ENGINE_load_builtin_engines(void)
63 { 63 {
64#if 0
64 /* There's no longer any need for an "openssl" ENGINE unless, one day, 65 /* There's no longer any need for an "openssl" ENGINE unless, one day,
65 * it is the *only* way for standard builtin implementations to be be 66 * it is the *only* way for standard builtin implementations to be be
66 * accessed (ie. it would be possible to statically link binaries with 67 * accessed (ie. it would be possible to statically link binaries with
67 * *no* builtin implementations). */ 68 * *no* builtin implementations). */
68#if 0
69 ENGINE_load_openssl(); 69 ENGINE_load_openssl();
70#endif 70#endif
71#if !defined(OPENSSL_NO_HW) && !defined(OPENSSL_NO_HW_PADLOCK) 71#if !defined(OPENSSL_NO_HW) && (defined(__OpenBSD__) || defined(__FreeBSD__) || defined(HAVE_CRYPTODEV))
72 ENGINE_load_padlock(); 72 ENGINE_load_cryptodev();
73#endif 73#endif
74 ENGINE_load_dynamic(); 74 ENGINE_load_dynamic();
75#ifndef OPENSSL_NO_STATIC_ENGINE 75#ifndef OPENSSL_NO_STATIC_ENGINE
@@ -98,14 +98,15 @@ void ENGINE_load_builtin_engines(void)
98#ifndef OPENSSL_NO_HW_UBSEC 98#ifndef OPENSSL_NO_HW_UBSEC
99 ENGINE_load_ubsec(); 99 ENGINE_load_ubsec();
100#endif 100#endif
101#ifndef OPENSSL_NO_HW_PADLOCK
102 ENGINE_load_padlock();
101#endif 103#endif
102#if !defined(OPENSSL_NO_GMP) && !defined(OPENSSL_NO_HW_GMP)
103 ENGINE_load_gmp();
104#endif 104#endif
105#ifndef OPENSSL_NO_GOST
106 ENGINE_load_gost();
105#endif 107#endif
106#ifndef OPENSSL_NO_HW 108#ifndef OPENSSL_NO_GMP
107#if defined(__OpenBSD__) || defined(__FreeBSD__) 109 ENGINE_load_gmp();
108 ENGINE_load_cryptodev();
109#endif 110#endif
110#if defined(OPENSSL_SYS_WIN32) && !defined(OPENSSL_NO_CAPIENG) 111#if defined(OPENSSL_SYS_WIN32) && !defined(OPENSSL_NO_CAPIENG)
111 ENGINE_load_capi(); 112 ENGINE_load_capi();
@@ -113,7 +114,7 @@ void ENGINE_load_builtin_engines(void)
113#endif 114#endif
114 } 115 }
115 116
116#if defined(__OpenBSD__) || defined(__FreeBSD__) 117#if defined(__OpenBSD__) || defined(__FreeBSD__) || defined(HAVE_CRYPTODEV)
117void ENGINE_setup_bsd_cryptodev(void) { 118void ENGINE_setup_bsd_cryptodev(void) {
118 static int bsd_cryptodev_default_loaded = 0; 119 static int bsd_cryptodev_default_loaded = 0;
119 if (!bsd_cryptodev_default_loaded) { 120 if (!bsd_cryptodev_default_loaded) {
diff --git a/src/lib/libcrypto/engine/eng_cnf.c b/src/lib/libcrypto/engine/eng_cnf.c
index 08066cea59..95c4070015 100644
--- a/src/lib/libcrypto/engine/eng_cnf.c
+++ b/src/lib/libcrypto/engine/eng_cnf.c
@@ -95,7 +95,7 @@ static int int_engine_configure(char *name, char *value, const CONF *cnf)
95 int ret = 0; 95 int ret = 0;
96 long do_init = -1; 96 long do_init = -1;
97 STACK_OF(CONF_VALUE) *ecmds; 97 STACK_OF(CONF_VALUE) *ecmds;
98 CONF_VALUE *ecmd; 98 CONF_VALUE *ecmd = NULL;
99 char *ctrlname, *ctrlvalue; 99 char *ctrlname, *ctrlvalue;
100 ENGINE *e = NULL; 100 ENGINE *e = NULL;
101 int soft = 0; 101 int soft = 0;
@@ -157,7 +157,7 @@ static int int_engine_configure(char *name, char *value, const CONF *cnf)
157 return 1; 157 return 1;
158 } 158 }
159 if (!e) 159 if (!e)
160 return 0; 160 goto err;
161 } 161 }
162 /* Allow "EMPTY" to mean no value: this allows a valid 162 /* Allow "EMPTY" to mean no value: this allows a valid
163 * "value" to be passed to ctrls of type NO_INPUT 163 * "value" to be passed to ctrls of type NO_INPUT
@@ -186,16 +186,27 @@ static int int_engine_configure(char *name, char *value, const CONF *cnf)
186 } 186 }
187 else if (!ENGINE_ctrl_cmd_string(e, 187 else if (!ENGINE_ctrl_cmd_string(e,
188 ctrlname, ctrlvalue, 0)) 188 ctrlname, ctrlvalue, 0))
189 return 0; 189 goto err;
190 } 190 }
191 191
192 192
193 193
194 } 194 }
195 if (e && (do_init == -1) && !int_engine_init(e)) 195 if (e && (do_init == -1) && !int_engine_init(e))
196 {
197 ecmd = NULL;
196 goto err; 198 goto err;
199 }
197 ret = 1; 200 ret = 1;
198 err: 201 err:
202 if (ret != 1)
203 {
204 ENGINEerr(ENGINE_F_INT_ENGINE_CONFIGURE, ENGINE_R_ENGINE_CONFIGURATION_ERROR);
205 if (ecmd)
206 ERR_add_error_data(6, "section=", ecmd->section,
207 ", name=", ecmd->name,
208 ", value=", ecmd->value);
209 }
199 if (e) 210 if (e)
200 ENGINE_free(e); 211 ENGINE_free(e);
201 return ret; 212 return ret;
diff --git a/src/lib/libcrypto/engine/eng_ctrl.c b/src/lib/libcrypto/engine/eng_ctrl.c
index 95b6b455aa..5ce25d92ec 100644
--- a/src/lib/libcrypto/engine/eng_ctrl.c
+++ b/src/lib/libcrypto/engine/eng_ctrl.c
@@ -280,7 +280,7 @@ int ENGINE_ctrl_cmd(ENGINE *e, const char *cmd_name,
280 } 280 }
281 /* Force the result of the control command to 0 or 1, for the reasons 281 /* Force the result of the control command to 0 or 1, for the reasons
282 * mentioned before. */ 282 * mentioned before. */
283 if (ENGINE_ctrl(e, num, i, p, f)) 283 if (ENGINE_ctrl(e, num, i, p, f) > 0)
284 return 1; 284 return 1;
285 return 0; 285 return 0;
286 } 286 }
@@ -345,7 +345,7 @@ int ENGINE_ctrl_cmd_string(ENGINE *e, const char *cmd_name, const char *arg,
345 * usage of these commands is consistent across applications and 345 * usage of these commands is consistent across applications and
346 * that certain applications don't understand it one way, and 346 * that certain applications don't understand it one way, and
347 * others another. */ 347 * others another. */
348 if(ENGINE_ctrl(e, num, 0, (void *)arg, NULL)) 348 if(ENGINE_ctrl(e, num, 0, (void *)arg, NULL) > 0)
349 return 1; 349 return 1;
350 return 0; 350 return 0;
351 } 351 }
@@ -360,7 +360,7 @@ int ENGINE_ctrl_cmd_string(ENGINE *e, const char *cmd_name, const char *arg,
360 if(flags & ENGINE_CMD_FLAG_STRING) 360 if(flags & ENGINE_CMD_FLAG_STRING)
361 { 361 {
362 /* Same explanation as above */ 362 /* Same explanation as above */
363 if(ENGINE_ctrl(e, num, 0, (void *)arg, NULL)) 363 if(ENGINE_ctrl(e, num, 0, (void *)arg, NULL) > 0)
364 return 1; 364 return 1;
365 return 0; 365 return 0;
366 } 366 }
@@ -383,7 +383,7 @@ int ENGINE_ctrl_cmd_string(ENGINE *e, const char *cmd_name, const char *arg,
383 } 383 }
384 /* Force the result of the control command to 0 or 1, for the reasons 384 /* Force the result of the control command to 0 or 1, for the reasons
385 * mentioned before. */ 385 * mentioned before. */
386 if(ENGINE_ctrl(e, num, l, NULL, NULL)) 386 if(ENGINE_ctrl(e, num, l, NULL, NULL) > 0)
387 return 1; 387 return 1;
388 return 0; 388 return 0;
389 } 389 }
diff --git a/src/lib/libcrypto/engine/eng_dyn.c b/src/lib/libcrypto/engine/eng_dyn.c
index acb30c34d8..807da7a5eb 100644
--- a/src/lib/libcrypto/engine/eng_dyn.c
+++ b/src/lib/libcrypto/engine/eng_dyn.c
@@ -146,14 +146,14 @@ struct st_dynamic_data_ctx
146 * 'dirs' for loading. Default is to use 'dirs' as a fallback. */ 146 * 'dirs' for loading. Default is to use 'dirs' as a fallback. */
147 int dir_load; 147 int dir_load;
148 /* A stack of directories from which ENGINEs could be loaded */ 148 /* A stack of directories from which ENGINEs could be loaded */
149 STACK *dirs; 149 STACK_OF(OPENSSL_STRING) *dirs;
150 }; 150 };
151 151
152/* This is the "ex_data" index we obtain and reserve for use with our context 152/* This is the "ex_data" index we obtain and reserve for use with our context
153 * structure. */ 153 * structure. */
154static int dynamic_ex_data_idx = -1; 154static int dynamic_ex_data_idx = -1;
155 155
156static void int_free_str(void *s) { OPENSSL_free(s); } 156static void int_free_str(char *s) { OPENSSL_free(s); }
157/* Because our ex_data element may or may not get allocated depending on whether 157/* Because our ex_data element may or may not get allocated depending on whether
158 * a "first-use" occurs before the ENGINE is freed, we have a memory leak 158 * a "first-use" occurs before the ENGINE is freed, we have a memory leak
159 * problem to solve. We can't declare a "new" handler for the ex_data as we 159 * problem to solve. We can't declare a "new" handler for the ex_data as we
@@ -174,7 +174,7 @@ static void dynamic_data_ctx_free_func(void *parent, void *ptr,
174 if(ctx->engine_id) 174 if(ctx->engine_id)
175 OPENSSL_free((void*)ctx->engine_id); 175 OPENSSL_free((void*)ctx->engine_id);
176 if(ctx->dirs) 176 if(ctx->dirs)
177 sk_pop_free(ctx->dirs, int_free_str); 177 sk_OPENSSL_STRING_pop_free(ctx->dirs, int_free_str);
178 OPENSSL_free(ctx); 178 OPENSSL_free(ctx);
179 } 179 }
180 } 180 }
@@ -203,7 +203,7 @@ static int dynamic_set_data_ctx(ENGINE *e, dynamic_data_ctx **ctx)
203 c->DYNAMIC_F1 = "v_check"; 203 c->DYNAMIC_F1 = "v_check";
204 c->DYNAMIC_F2 = "bind_engine"; 204 c->DYNAMIC_F2 = "bind_engine";
205 c->dir_load = 1; 205 c->dir_load = 1;
206 c->dirs = sk_new_null(); 206 c->dirs = sk_OPENSSL_STRING_new_null();
207 if(!c->dirs) 207 if(!c->dirs)
208 { 208 {
209 ENGINEerr(ENGINE_F_DYNAMIC_SET_DATA_CTX,ERR_R_MALLOC_FAILURE); 209 ENGINEerr(ENGINE_F_DYNAMIC_SET_DATA_CTX,ERR_R_MALLOC_FAILURE);
@@ -393,7 +393,7 @@ static int dynamic_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void))
393 ERR_R_MALLOC_FAILURE); 393 ERR_R_MALLOC_FAILURE);
394 return 0; 394 return 0;
395 } 395 }
396 sk_insert(ctx->dirs, tmp_str, -1); 396 sk_OPENSSL_STRING_insert(ctx->dirs, tmp_str, -1);
397 } 397 }
398 return 1; 398 return 1;
399 default: 399 default:
@@ -411,11 +411,11 @@ static int int_load(dynamic_data_ctx *ctx)
411 ctx->DYNAMIC_LIBNAME, NULL, 0)) != NULL) 411 ctx->DYNAMIC_LIBNAME, NULL, 0)) != NULL)
412 return 1; 412 return 1;
413 /* If we're not allowed to use 'dirs' or we have none, fail */ 413 /* If we're not allowed to use 'dirs' or we have none, fail */
414 if(!ctx->dir_load || ((num = sk_num(ctx->dirs)) < 1)) 414 if(!ctx->dir_load || (num = sk_OPENSSL_STRING_num(ctx->dirs)) < 1)
415 return 0; 415 return 0;
416 for(loop = 0; loop < num; loop++) 416 for(loop = 0; loop < num; loop++)
417 { 417 {
418 const char *s = sk_value(ctx->dirs, loop); 418 const char *s = sk_OPENSSL_STRING_value(ctx->dirs, loop);
419 char *merge = DSO_merge(ctx->dynamic_dso, ctx->DYNAMIC_LIBNAME, s); 419 char *merge = DSO_merge(ctx->dynamic_dso, ctx->DYNAMIC_LIBNAME, s);
420 if(!merge) 420 if(!merge)
421 return 0; 421 return 0;
diff --git a/src/lib/libcrypto/engine/eng_err.c b/src/lib/libcrypto/engine/eng_err.c
index 574ffbb5c0..81c70acfa8 100644
--- a/src/lib/libcrypto/engine/eng_err.c
+++ b/src/lib/libcrypto/engine/eng_err.c
@@ -1,6 +1,6 @@
1/* crypto/engine/eng_err.c */ 1/* crypto/engine/eng_err.c */
2/* ==================================================================== 2/* ====================================================================
3 * Copyright (c) 1999-2008 The OpenSSL Project. All rights reserved. 3 * Copyright (c) 1999-2010 The OpenSSL Project. All rights reserved.
4 * 4 *
5 * Redistribution and use in source and binary forms, with or without 5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions 6 * modification, are permitted provided that the following conditions
@@ -86,6 +86,8 @@ static ERR_STRING_DATA ENGINE_str_functs[]=
86{ERR_FUNC(ENGINE_F_ENGINE_GET_DEFAULT_TYPE), "ENGINE_GET_DEFAULT_TYPE"}, 86{ERR_FUNC(ENGINE_F_ENGINE_GET_DEFAULT_TYPE), "ENGINE_GET_DEFAULT_TYPE"},
87{ERR_FUNC(ENGINE_F_ENGINE_GET_DIGEST), "ENGINE_get_digest"}, 87{ERR_FUNC(ENGINE_F_ENGINE_GET_DIGEST), "ENGINE_get_digest"},
88{ERR_FUNC(ENGINE_F_ENGINE_GET_NEXT), "ENGINE_get_next"}, 88{ERR_FUNC(ENGINE_F_ENGINE_GET_NEXT), "ENGINE_get_next"},
89{ERR_FUNC(ENGINE_F_ENGINE_GET_PKEY_ASN1_METH), "ENGINE_get_pkey_asn1_meth"},
90{ERR_FUNC(ENGINE_F_ENGINE_GET_PKEY_METH), "ENGINE_get_pkey_meth"},
89{ERR_FUNC(ENGINE_F_ENGINE_GET_PREV), "ENGINE_get_prev"}, 91{ERR_FUNC(ENGINE_F_ENGINE_GET_PREV), "ENGINE_get_prev"},
90{ERR_FUNC(ENGINE_F_ENGINE_INIT), "ENGINE_init"}, 92{ERR_FUNC(ENGINE_F_ENGINE_INIT), "ENGINE_init"},
91{ERR_FUNC(ENGINE_F_ENGINE_LIST_ADD), "ENGINE_LIST_ADD"}, 93{ERR_FUNC(ENGINE_F_ENGINE_LIST_ADD), "ENGINE_LIST_ADD"},
@@ -124,6 +126,7 @@ static ERR_STRING_DATA ENGINE_str_reasons[]=
124{ERR_REASON(ENGINE_R_DSO_FAILURE) ,"DSO failure"}, 126{ERR_REASON(ENGINE_R_DSO_FAILURE) ,"DSO failure"},
125{ERR_REASON(ENGINE_R_DSO_NOT_FOUND) ,"dso not found"}, 127{ERR_REASON(ENGINE_R_DSO_NOT_FOUND) ,"dso not found"},
126{ERR_REASON(ENGINE_R_ENGINES_SECTION_ERROR),"engines section error"}, 128{ERR_REASON(ENGINE_R_ENGINES_SECTION_ERROR),"engines section error"},
129{ERR_REASON(ENGINE_R_ENGINE_CONFIGURATION_ERROR),"engine configuration error"},
127{ERR_REASON(ENGINE_R_ENGINE_IS_NOT_IN_LIST),"engine is not in the list"}, 130{ERR_REASON(ENGINE_R_ENGINE_IS_NOT_IN_LIST),"engine is not in the list"},
128{ERR_REASON(ENGINE_R_ENGINE_SECTION_ERROR),"engine section error"}, 131{ERR_REASON(ENGINE_R_ENGINE_SECTION_ERROR),"engine section error"},
129{ERR_REASON(ENGINE_R_FAILED_LOADING_PRIVATE_KEY),"failed loading private key"}, 132{ERR_REASON(ENGINE_R_FAILED_LOADING_PRIVATE_KEY),"failed loading private key"},
@@ -150,6 +153,7 @@ static ERR_STRING_DATA ENGINE_str_reasons[]=
150{ERR_REASON(ENGINE_R_RSA_NOT_IMPLEMENTED),"rsa not implemented"}, 153{ERR_REASON(ENGINE_R_RSA_NOT_IMPLEMENTED),"rsa not implemented"},
151{ERR_REASON(ENGINE_R_UNIMPLEMENTED_CIPHER),"unimplemented cipher"}, 154{ERR_REASON(ENGINE_R_UNIMPLEMENTED_CIPHER),"unimplemented cipher"},
152{ERR_REASON(ENGINE_R_UNIMPLEMENTED_DIGEST),"unimplemented digest"}, 155{ERR_REASON(ENGINE_R_UNIMPLEMENTED_DIGEST),"unimplemented digest"},
156{ERR_REASON(ENGINE_R_UNIMPLEMENTED_PUBLIC_KEY_METHOD),"unimplemented public key method"},
153{ERR_REASON(ENGINE_R_VERSION_INCOMPATIBILITY),"version incompatibility"}, 157{ERR_REASON(ENGINE_R_VERSION_INCOMPATIBILITY),"version incompatibility"},
154{0,NULL} 158{0,NULL}
155 }; 159 };
diff --git a/src/lib/libcrypto/engine/eng_fat.c b/src/lib/libcrypto/engine/eng_fat.c
index 27c1662f62..db66e62350 100644
--- a/src/lib/libcrypto/engine/eng_fat.c
+++ b/src/lib/libcrypto/engine/eng_fat.c
@@ -89,6 +89,12 @@ int ENGINE_set_default(ENGINE *e, unsigned int flags)
89#endif 89#endif
90 if((flags & ENGINE_METHOD_RAND) && !ENGINE_set_default_RAND(e)) 90 if((flags & ENGINE_METHOD_RAND) && !ENGINE_set_default_RAND(e))
91 return 0; 91 return 0;
92 if((flags & ENGINE_METHOD_PKEY_METHS)
93 && !ENGINE_set_default_pkey_meths(e))
94 return 0;
95 if((flags & ENGINE_METHOD_PKEY_ASN1_METHS)
96 && !ENGINE_set_default_pkey_asn1_meths(e))
97 return 0;
92 return 1; 98 return 1;
93 } 99 }
94 100
@@ -115,6 +121,13 @@ static int int_def_cb(const char *alg, int len, void *arg)
115 *pflags |= ENGINE_METHOD_CIPHERS; 121 *pflags |= ENGINE_METHOD_CIPHERS;
116 else if (!strncmp(alg, "DIGESTS", len)) 122 else if (!strncmp(alg, "DIGESTS", len))
117 *pflags |= ENGINE_METHOD_DIGESTS; 123 *pflags |= ENGINE_METHOD_DIGESTS;
124 else if (!strncmp(alg, "PKEY", len))
125 *pflags |=
126 ENGINE_METHOD_PKEY_METHS|ENGINE_METHOD_PKEY_ASN1_METHS;
127 else if (!strncmp(alg, "PKEY_CRYPTO", len))
128 *pflags |= ENGINE_METHOD_PKEY_METHS;
129 else if (!strncmp(alg, "PKEY_ASN1", len))
130 *pflags |= ENGINE_METHOD_PKEY_ASN1_METHS;
118 else 131 else
119 return 0; 132 return 0;
120 return 1; 133 return 1;
@@ -154,6 +167,7 @@ int ENGINE_register_complete(ENGINE *e)
154 ENGINE_register_ECDSA(e); 167 ENGINE_register_ECDSA(e);
155#endif 168#endif
156 ENGINE_register_RAND(e); 169 ENGINE_register_RAND(e);
170 ENGINE_register_pkey_meths(e);
157 return 1; 171 return 1;
158 } 172 }
159 173
diff --git a/src/lib/libcrypto/engine/eng_int.h b/src/lib/libcrypto/engine/eng_int.h
index a66f107a44..451ef8feb8 100644
--- a/src/lib/libcrypto/engine/eng_int.h
+++ b/src/lib/libcrypto/engine/eng_int.h
@@ -127,6 +127,8 @@ ENGINE *engine_table_select(ENGINE_TABLE **table, int nid);
127ENGINE *engine_table_select_tmp(ENGINE_TABLE **table, int nid, const char *f, int l); 127ENGINE *engine_table_select_tmp(ENGINE_TABLE **table, int nid, const char *f, int l);
128#define engine_table_select(t,n) engine_table_select_tmp(t,n,__FILE__,__LINE__) 128#define engine_table_select(t,n) engine_table_select_tmp(t,n,__FILE__,__LINE__)
129#endif 129#endif
130typedef void (engine_table_doall_cb)(int nid, STACK_OF(ENGINE) *sk, ENGINE *def, void *arg);
131void engine_table_doall(ENGINE_TABLE *table, engine_table_doall_cb *cb, void *arg);
130 132
131/* Internal versions of API functions that have control over locking. These are 133/* Internal versions of API functions that have control over locking. These are
132 * used between C files when functionality needs to be shared but the caller may 134 * used between C files when functionality needs to be shared but the caller may
@@ -143,6 +145,11 @@ void engine_set_all_null(ENGINE *e);
143/* NB: Bitwise OR-able values for the "flags" variable in ENGINE are now exposed 145/* NB: Bitwise OR-able values for the "flags" variable in ENGINE are now exposed
144 * in engine.h. */ 146 * in engine.h. */
145 147
148/* Free up dynamically allocated public key methods associated with ENGINE */
149
150void engine_pkey_meths_free(ENGINE *e);
151void engine_pkey_asn1_meths_free(ENGINE *e);
152
146/* This is a structure for storing implementations of various crypto 153/* This is a structure for storing implementations of various crypto
147 * algorithms and functions. */ 154 * algorithms and functions. */
148struct engine_st 155struct engine_st
@@ -160,7 +167,10 @@ struct engine_st
160 ENGINE_CIPHERS_PTR ciphers; 167 ENGINE_CIPHERS_PTR ciphers;
161 /* Digest handling is via this callback */ 168 /* Digest handling is via this callback */
162 ENGINE_DIGESTS_PTR digests; 169 ENGINE_DIGESTS_PTR digests;
163 170 /* Public key handling via this callback */
171 ENGINE_PKEY_METHS_PTR pkey_meths;
172 /* ASN1 public key handling via this callback */
173 ENGINE_PKEY_ASN1_METHS_PTR pkey_asn1_meths;
164 174
165 ENGINE_GEN_INT_FUNC_PTR destroy; 175 ENGINE_GEN_INT_FUNC_PTR destroy;
166 176
diff --git a/src/lib/libcrypto/engine/eng_lib.c b/src/lib/libcrypto/engine/eng_lib.c
index 5815b867f4..18a6664645 100644
--- a/src/lib/libcrypto/engine/eng_lib.c
+++ b/src/lib/libcrypto/engine/eng_lib.c
@@ -125,6 +125,9 @@ int engine_free_util(ENGINE *e, int locked)
125 abort(); 125 abort();
126 } 126 }
127#endif 127#endif
128 /* Free up any dynamically allocated public key methods */
129 engine_pkey_meths_free(e);
130 engine_pkey_asn1_meths_free(e);
128 /* Give the ENGINE a chance to do any structural cleanup corresponding 131 /* Give the ENGINE a chance to do any structural cleanup corresponding
129 * to allocation it did in its constructor (eg. unload error strings) */ 132 * to allocation it did in its constructor (eg. unload error strings) */
130 if(e->destroy) 133 if(e->destroy)
diff --git a/src/lib/libcrypto/engine/eng_list.c b/src/lib/libcrypto/engine/eng_list.c
index bd511944ba..27846edb1e 100644
--- a/src/lib/libcrypto/engine/eng_list.c
+++ b/src/lib/libcrypto/engine/eng_list.c
@@ -336,6 +336,7 @@ static void engine_cpy(ENGINE *dest, const ENGINE *src)
336 dest->store_meth = src->store_meth; 336 dest->store_meth = src->store_meth;
337 dest->ciphers = src->ciphers; 337 dest->ciphers = src->ciphers;
338 dest->digests = src->digests; 338 dest->digests = src->digests;
339 dest->pkey_meths = src->pkey_meths;
339 dest->destroy = src->destroy; 340 dest->destroy = src->destroy;
340 dest->init = src->init; 341 dest->init = src->init;
341 dest->finish = src->finish; 342 dest->finish = src->finish;
@@ -412,6 +413,7 @@ ENGINE *ENGINE_by_id(const char *id)
412 return iterator; 413 return iterator;
413 } 414 }
414notfound: 415notfound:
416 ENGINE_free(iterator);
415 ENGINEerr(ENGINE_F_ENGINE_BY_ID,ENGINE_R_NO_SUCH_ENGINE); 417 ENGINEerr(ENGINE_F_ENGINE_BY_ID,ENGINE_R_NO_SUCH_ENGINE);
416 ERR_add_error_data(2, "id=", id); 418 ERR_add_error_data(2, "id=", id);
417 return NULL; 419 return NULL;
diff --git a/src/lib/libcrypto/engine/eng_openssl.c b/src/lib/libcrypto/engine/eng_openssl.c
index 7c139ae2ef..9abb95cc22 100644
--- a/src/lib/libcrypto/engine/eng_openssl.c
+++ b/src/lib/libcrypto/engine/eng_openssl.c
@@ -238,7 +238,7 @@ static int test_rc4_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
238 return 1; 238 return 1;
239 } 239 }
240static int test_rc4_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, 240static int test_rc4_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
241 const unsigned char *in, unsigned int inl) 241 const unsigned char *in, size_t inl)
242 { 242 {
243#ifdef TEST_ENG_OPENSSL_RC4_P_CIPHER 243#ifdef TEST_ENG_OPENSSL_RC4_P_CIPHER
244 fprintf(stderr, "(TEST_ENG_OPENSSL_RC4) test_cipher() called\n"); 244 fprintf(stderr, "(TEST_ENG_OPENSSL_RC4) test_cipher() called\n");
diff --git a/src/lib/libcrypto/engine/eng_table.c b/src/lib/libcrypto/engine/eng_table.c
index 8879a267d1..4fde948185 100644
--- a/src/lib/libcrypto/engine/eng_table.c
+++ b/src/lib/libcrypto/engine/eng_table.c
@@ -70,12 +70,22 @@ typedef struct st_engine_pile
70 int uptodate; 70 int uptodate;
71 } ENGINE_PILE; 71 } ENGINE_PILE;
72 72
73DECLARE_LHASH_OF(ENGINE_PILE);
74
73/* The type exposed in eng_int.h */ 75/* The type exposed in eng_int.h */
74struct st_engine_table 76struct st_engine_table
75 { 77 {
76 LHASH piles; 78 LHASH_OF(ENGINE_PILE) piles;
77 }; /* ENGINE_TABLE */ 79 }; /* ENGINE_TABLE */
78 80
81
82typedef struct st_engine_pile_doall
83 {
84 engine_table_doall_cb *cb;
85 void *arg;
86 } ENGINE_PILE_DOALL;
87
88
79/* Global flags (ENGINE_TABLE_FLAG_***). */ 89/* Global flags (ENGINE_TABLE_FLAG_***). */
80static unsigned int table_flags = 0; 90static unsigned int table_flags = 0;
81 91
@@ -84,6 +94,7 @@ unsigned int ENGINE_get_table_flags(void)
84 { 94 {
85 return table_flags; 95 return table_flags;
86 } 96 }
97
87void ENGINE_set_table_flags(unsigned int flags) 98void ENGINE_set_table_flags(unsigned int flags)
88 { 99 {
89 table_flags = flags; 100 table_flags = flags;
@@ -94,19 +105,21 @@ static unsigned long engine_pile_hash(const ENGINE_PILE *c)
94 { 105 {
95 return c->nid; 106 return c->nid;
96 } 107 }
108
97static int engine_pile_cmp(const ENGINE_PILE *a, const ENGINE_PILE *b) 109static int engine_pile_cmp(const ENGINE_PILE *a, const ENGINE_PILE *b)
98 { 110 {
99 return a->nid - b->nid; 111 return a->nid - b->nid;
100 } 112 }
101static IMPLEMENT_LHASH_HASH_FN(engine_pile_hash, const ENGINE_PILE *) 113static IMPLEMENT_LHASH_HASH_FN(engine_pile, ENGINE_PILE)
102static IMPLEMENT_LHASH_COMP_FN(engine_pile_cmp, const ENGINE_PILE *) 114static IMPLEMENT_LHASH_COMP_FN(engine_pile, ENGINE_PILE)
115
103static int int_table_check(ENGINE_TABLE **t, int create) 116static int int_table_check(ENGINE_TABLE **t, int create)
104 { 117 {
105 LHASH *lh; 118 LHASH_OF(ENGINE_PILE) *lh;
119
106 if(*t) return 1; 120 if(*t) return 1;
107 if(!create) return 0; 121 if(!create) return 0;
108 if((lh = lh_new(LHASH_HASH_FN(engine_pile_hash), 122 if((lh = lh_ENGINE_PILE_new()) == NULL)
109 LHASH_COMP_FN(engine_pile_cmp))) == NULL)
110 return 0; 123 return 0;
111 *t = (ENGINE_TABLE *)lh; 124 *t = (ENGINE_TABLE *)lh;
112 return 1; 125 return 1;
@@ -130,7 +143,7 @@ int engine_table_register(ENGINE_TABLE **table, ENGINE_CLEANUP_CB *cleanup,
130 while(num_nids--) 143 while(num_nids--)
131 { 144 {
132 tmplate.nid = *nids; 145 tmplate.nid = *nids;
133 fnd = lh_retrieve(&(*table)->piles, &tmplate); 146 fnd = lh_ENGINE_PILE_retrieve(&(*table)->piles, &tmplate);
134 if(!fnd) 147 if(!fnd)
135 { 148 {
136 fnd = OPENSSL_malloc(sizeof(ENGINE_PILE)); 149 fnd = OPENSSL_malloc(sizeof(ENGINE_PILE));
@@ -144,7 +157,7 @@ int engine_table_register(ENGINE_TABLE **table, ENGINE_CLEANUP_CB *cleanup,
144 goto end; 157 goto end;
145 } 158 }
146 fnd->funct = NULL; 159 fnd->funct = NULL;
147 lh_insert(&(*table)->piles, fnd); 160 (void)lh_ENGINE_PILE_insert(&(*table)->piles, fnd);
148 } 161 }
149 /* A registration shouldn't add duplciate entries */ 162 /* A registration shouldn't add duplciate entries */
150 (void)sk_ENGINE_delete_ptr(fnd->sk, e); 163 (void)sk_ENGINE_delete_ptr(fnd->sk, e);
@@ -173,7 +186,7 @@ end:
173 CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); 186 CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
174 return ret; 187 return ret;
175 } 188 }
176static void int_unregister_cb(ENGINE_PILE *pile, ENGINE *e) 189static void int_unregister_cb_doall_arg(ENGINE_PILE *pile, ENGINE *e)
177 { 190 {
178 int n; 191 int n;
179 /* Iterate the 'c->sk' stack removing any occurance of 'e' */ 192 /* Iterate the 'c->sk' stack removing any occurance of 'e' */
@@ -188,31 +201,35 @@ static void int_unregister_cb(ENGINE_PILE *pile, ENGINE *e)
188 pile->funct = NULL; 201 pile->funct = NULL;
189 } 202 }
190 } 203 }
191static IMPLEMENT_LHASH_DOALL_ARG_FN(int_unregister_cb,ENGINE_PILE *,ENGINE *) 204static IMPLEMENT_LHASH_DOALL_ARG_FN(int_unregister_cb, ENGINE_PILE, ENGINE)
205
192void engine_table_unregister(ENGINE_TABLE **table, ENGINE *e) 206void engine_table_unregister(ENGINE_TABLE **table, ENGINE *e)
193 { 207 {
194 CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); 208 CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
195 if(int_table_check(table, 0)) 209 if(int_table_check(table, 0))
196 lh_doall_arg(&(*table)->piles, 210 lh_ENGINE_PILE_doall_arg(&(*table)->piles,
197 LHASH_DOALL_ARG_FN(int_unregister_cb), e); 211 LHASH_DOALL_ARG_FN(int_unregister_cb),
212 ENGINE, e);
198 CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); 213 CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
199 } 214 }
200 215
201static void int_cleanup_cb(ENGINE_PILE *p) 216static void int_cleanup_cb_doall(ENGINE_PILE *p)
202 { 217 {
203 sk_ENGINE_free(p->sk); 218 sk_ENGINE_free(p->sk);
204 if(p->funct) 219 if(p->funct)
205 engine_unlocked_finish(p->funct, 0); 220 engine_unlocked_finish(p->funct, 0);
206 OPENSSL_free(p); 221 OPENSSL_free(p);
207 } 222 }
208static IMPLEMENT_LHASH_DOALL_FN(int_cleanup_cb,ENGINE_PILE *) 223static IMPLEMENT_LHASH_DOALL_FN(int_cleanup_cb, ENGINE_PILE)
224
209void engine_table_cleanup(ENGINE_TABLE **table) 225void engine_table_cleanup(ENGINE_TABLE **table)
210 { 226 {
211 CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); 227 CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
212 if(*table) 228 if(*table)
213 { 229 {
214 lh_doall(&(*table)->piles, LHASH_DOALL_FN(int_cleanup_cb)); 230 lh_ENGINE_PILE_doall(&(*table)->piles,
215 lh_free(&(*table)->piles); 231 LHASH_DOALL_FN(int_cleanup_cb));
232 lh_ENGINE_PILE_free(&(*table)->piles);
216 *table = NULL; 233 *table = NULL;
217 } 234 }
218 CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); 235 CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
@@ -237,12 +254,13 @@ ENGINE *engine_table_select_tmp(ENGINE_TABLE **table, int nid, const char *f, in
237#endif 254#endif
238 return NULL; 255 return NULL;
239 } 256 }
257 ERR_set_mark();
240 CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); 258 CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
241 /* Check again inside the lock otherwise we could race against cleanup 259 /* Check again inside the lock otherwise we could race against cleanup
242 * operations. But don't worry about a fprintf(stderr). */ 260 * operations. But don't worry about a fprintf(stderr). */
243 if(!int_table_check(table, 0)) goto end; 261 if(!int_table_check(table, 0)) goto end;
244 tmplate.nid = nid; 262 tmplate.nid = nid;
245 fnd = lh_retrieve(&(*table)->piles, &tmplate); 263 fnd = lh_ENGINE_PILE_retrieve(&(*table)->piles, &tmplate);
246 if(!fnd) goto end; 264 if(!fnd) goto end;
247 if(fnd->funct && engine_unlocked_init(fnd->funct)) 265 if(fnd->funct && engine_unlocked_init(fnd->funct))
248 { 266 {
@@ -310,6 +328,24 @@ end:
310 CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); 328 CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
311 /* Whatever happened, any failed init()s are not failures in this 329 /* Whatever happened, any failed init()s are not failures in this
312 * context, so clear our error state. */ 330 * context, so clear our error state. */
313 ERR_clear_error(); 331 ERR_pop_to_mark();
314 return ret; 332 return ret;
315 } 333 }
334
335/* Table enumeration */
336
337static void int_cb_doall_arg(ENGINE_PILE *pile, ENGINE_PILE_DOALL *dall)
338 {
339 dall->cb(pile->nid, pile->sk, pile->funct, dall->arg);
340 }
341static IMPLEMENT_LHASH_DOALL_ARG_FN(int_cb, ENGINE_PILE,ENGINE_PILE_DOALL)
342
343void engine_table_doall(ENGINE_TABLE *table, engine_table_doall_cb *cb,
344 void *arg)
345 {
346 ENGINE_PILE_DOALL dall;
347 dall.cb = cb;
348 dall.arg = arg;
349 lh_ENGINE_PILE_doall_arg(&table->piles, LHASH_DOALL_ARG_FN(int_cb),
350 ENGINE_PILE_DOALL, &dall);
351 }
diff --git a/src/lib/libcrypto/engine/engine.h b/src/lib/libcrypto/engine/engine.h
index f503595ece..7fbd95f634 100644
--- a/src/lib/libcrypto/engine/engine.h
+++ b/src/lib/libcrypto/engine/engine.h
@@ -88,16 +88,15 @@
88#include <openssl/ecdsa.h> 88#include <openssl/ecdsa.h>
89#endif 89#endif
90#include <openssl/rand.h> 90#include <openssl/rand.h>
91#include <openssl/store.h>
92#include <openssl/ui.h> 91#include <openssl/ui.h>
93#include <openssl/err.h> 92#include <openssl/err.h>
94#endif 93#endif
95 94
96#include <openssl/x509.h>
97
98#include <openssl/ossl_typ.h> 95#include <openssl/ossl_typ.h>
99#include <openssl/symhacks.h> 96#include <openssl/symhacks.h>
100 97
98#include <openssl/x509.h>
99
101#ifdef __cplusplus 100#ifdef __cplusplus
102extern "C" { 101extern "C" {
103#endif 102#endif
@@ -113,6 +112,8 @@ extern "C" {
113#define ENGINE_METHOD_CIPHERS (unsigned int)0x0040 112#define ENGINE_METHOD_CIPHERS (unsigned int)0x0040
114#define ENGINE_METHOD_DIGESTS (unsigned int)0x0080 113#define ENGINE_METHOD_DIGESTS (unsigned int)0x0080
115#define ENGINE_METHOD_STORE (unsigned int)0x0100 114#define ENGINE_METHOD_STORE (unsigned int)0x0100
115#define ENGINE_METHOD_PKEY_METHS (unsigned int)0x0200
116#define ENGINE_METHOD_PKEY_ASN1_METHS (unsigned int)0x0400
116/* Obvious all-or-nothing cases. */ 117/* Obvious all-or-nothing cases. */
117#define ENGINE_METHOD_ALL (unsigned int)0xFFFF 118#define ENGINE_METHOD_ALL (unsigned int)0xFFFF
118#define ENGINE_METHOD_NONE (unsigned int)0x0000 119#define ENGINE_METHOD_NONE (unsigned int)0x0000
@@ -297,7 +298,8 @@ typedef int (*ENGINE_SSL_CLIENT_CERT_PTR)(ENGINE *, SSL *ssl,
297 * parameter is non-NULL it is set to the size of the returned array. */ 298 * parameter is non-NULL it is set to the size of the returned array. */
298typedef int (*ENGINE_CIPHERS_PTR)(ENGINE *, const EVP_CIPHER **, const int **, int); 299typedef int (*ENGINE_CIPHERS_PTR)(ENGINE *, const EVP_CIPHER **, const int **, int);
299typedef int (*ENGINE_DIGESTS_PTR)(ENGINE *, const EVP_MD **, const int **, int); 300typedef int (*ENGINE_DIGESTS_PTR)(ENGINE *, const EVP_MD **, const int **, int);
300 301typedef int (*ENGINE_PKEY_METHS_PTR)(ENGINE *, EVP_PKEY_METHOD **, const int **, int);
302typedef int (*ENGINE_PKEY_ASN1_METHS_PTR)(ENGINE *, EVP_PKEY_ASN1_METHOD **, const int **, int);
301/* STRUCTURE functions ... all of these functions deal with pointers to ENGINE 303/* STRUCTURE functions ... all of these functions deal with pointers to ENGINE
302 * structures where the pointers have a "structural reference". This means that 304 * structures where the pointers have a "structural reference". This means that
303 * their reference is to allowed access to the structure but it does not imply 305 * their reference is to allowed access to the structure but it does not imply
@@ -329,19 +331,20 @@ void ENGINE_load_aep(void);
329void ENGINE_load_atalla(void); 331void ENGINE_load_atalla(void);
330void ENGINE_load_chil(void); 332void ENGINE_load_chil(void);
331void ENGINE_load_cswift(void); 333void ENGINE_load_cswift(void);
332#ifndef OPENSSL_NO_GMP
333void ENGINE_load_gmp(void);
334#endif
335void ENGINE_load_nuron(void); 334void ENGINE_load_nuron(void);
336void ENGINE_load_sureware(void); 335void ENGINE_load_sureware(void);
337void ENGINE_load_ubsec(void); 336void ENGINE_load_ubsec(void);
338#endif
339void ENGINE_load_cryptodev(void);
340void ENGINE_load_padlock(void); 337void ENGINE_load_padlock(void);
341void ENGINE_load_builtin_engines(void);
342#ifndef OPENSSL_NO_CAPIENG
343void ENGINE_load_capi(void); 338void ENGINE_load_capi(void);
339#ifndef OPENSSL_NO_GMP
340void ENGINE_load_gmp(void);
341#endif
342#ifndef OPENSSL_NO_GOST
343void ENGINE_load_gost(void);
344#endif
344#endif 345#endif
346void ENGINE_load_cryptodev(void);
347void ENGINE_load_builtin_engines(void);
345 348
346/* Get and set global flags (ENGINE_TABLE_FLAG_***) for the implementation 349/* Get and set global flags (ENGINE_TABLE_FLAG_***) for the implementation
347 * "registry" handling. */ 350 * "registry" handling. */
@@ -392,6 +395,14 @@ int ENGINE_register_digests(ENGINE *e);
392void ENGINE_unregister_digests(ENGINE *e); 395void ENGINE_unregister_digests(ENGINE *e);
393void ENGINE_register_all_digests(void); 396void ENGINE_register_all_digests(void);
394 397
398int ENGINE_register_pkey_meths(ENGINE *e);
399void ENGINE_unregister_pkey_meths(ENGINE *e);
400void ENGINE_register_all_pkey_meths(void);
401
402int ENGINE_register_pkey_asn1_meths(ENGINE *e);
403void ENGINE_unregister_pkey_asn1_meths(ENGINE *e);
404void ENGINE_register_all_pkey_asn1_meths(void);
405
395/* These functions register all support from the above categories. Note, use of 406/* These functions register all support from the above categories. Note, use of
396 * these functions can result in static linkage of code your application may not 407 * these functions can result in static linkage of code your application may not
397 * need. If you only need a subset of functionality, consider using more 408 * need. If you only need a subset of functionality, consider using more
@@ -471,6 +482,8 @@ int ENGINE_set_load_ssl_client_cert_function(ENGINE *e,
471 ENGINE_SSL_CLIENT_CERT_PTR loadssl_f); 482 ENGINE_SSL_CLIENT_CERT_PTR loadssl_f);
472int ENGINE_set_ciphers(ENGINE *e, ENGINE_CIPHERS_PTR f); 483int ENGINE_set_ciphers(ENGINE *e, ENGINE_CIPHERS_PTR f);
473int ENGINE_set_digests(ENGINE *e, ENGINE_DIGESTS_PTR f); 484int ENGINE_set_digests(ENGINE *e, ENGINE_DIGESTS_PTR f);
485int ENGINE_set_pkey_meths(ENGINE *e, ENGINE_PKEY_METHS_PTR f);
486int ENGINE_set_pkey_asn1_meths(ENGINE *e, ENGINE_PKEY_ASN1_METHS_PTR f);
474int ENGINE_set_flags(ENGINE *e, int flags); 487int ENGINE_set_flags(ENGINE *e, int flags);
475int ENGINE_set_cmd_defns(ENGINE *e, const ENGINE_CMD_DEFN *defns); 488int ENGINE_set_cmd_defns(ENGINE *e, const ENGINE_CMD_DEFN *defns);
476/* These functions allow control over any per-structure ENGINE data. */ 489/* These functions allow control over any per-structure ENGINE data. */
@@ -507,8 +520,16 @@ ENGINE_LOAD_KEY_PTR ENGINE_get_load_pubkey_function(const ENGINE *e);
507ENGINE_SSL_CLIENT_CERT_PTR ENGINE_get_ssl_client_cert_function(const ENGINE *e); 520ENGINE_SSL_CLIENT_CERT_PTR ENGINE_get_ssl_client_cert_function(const ENGINE *e);
508ENGINE_CIPHERS_PTR ENGINE_get_ciphers(const ENGINE *e); 521ENGINE_CIPHERS_PTR ENGINE_get_ciphers(const ENGINE *e);
509ENGINE_DIGESTS_PTR ENGINE_get_digests(const ENGINE *e); 522ENGINE_DIGESTS_PTR ENGINE_get_digests(const ENGINE *e);
523ENGINE_PKEY_METHS_PTR ENGINE_get_pkey_meths(const ENGINE *e);
524ENGINE_PKEY_ASN1_METHS_PTR ENGINE_get_pkey_asn1_meths(const ENGINE *e);
510const EVP_CIPHER *ENGINE_get_cipher(ENGINE *e, int nid); 525const EVP_CIPHER *ENGINE_get_cipher(ENGINE *e, int nid);
511const EVP_MD *ENGINE_get_digest(ENGINE *e, int nid); 526const EVP_MD *ENGINE_get_digest(ENGINE *e, int nid);
527const EVP_PKEY_METHOD *ENGINE_get_pkey_meth(ENGINE *e, int nid);
528const EVP_PKEY_ASN1_METHOD *ENGINE_get_pkey_asn1_meth(ENGINE *e, int nid);
529const EVP_PKEY_ASN1_METHOD *ENGINE_get_pkey_asn1_meth_str(ENGINE *e,
530 const char *str, int len);
531const EVP_PKEY_ASN1_METHOD *ENGINE_pkey_asn1_find_str(ENGINE **pe,
532 const char *str, int len);
512const ENGINE_CMD_DEFN *ENGINE_get_cmd_defns(const ENGINE *e); 533const ENGINE_CMD_DEFN *ENGINE_get_cmd_defns(const ENGINE *e);
513int ENGINE_get_flags(const ENGINE *e); 534int ENGINE_get_flags(const ENGINE *e);
514 535
@@ -560,6 +581,8 @@ ENGINE *ENGINE_get_default_RAND(void);
560 * ciphering or digesting corresponding to "nid". */ 581 * ciphering or digesting corresponding to "nid". */
561ENGINE *ENGINE_get_cipher_engine(int nid); 582ENGINE *ENGINE_get_cipher_engine(int nid);
562ENGINE *ENGINE_get_digest_engine(int nid); 583ENGINE *ENGINE_get_digest_engine(int nid);
584ENGINE *ENGINE_get_pkey_meth_engine(int nid);
585ENGINE *ENGINE_get_pkey_asn1_meth_engine(int nid);
563 586
564/* This sets a new default ENGINE structure for performing RSA 587/* This sets a new default ENGINE structure for performing RSA
565 * operations. If the result is non-zero (success) then the ENGINE 588 * operations. If the result is non-zero (success) then the ENGINE
@@ -575,6 +598,8 @@ int ENGINE_set_default_DH(ENGINE *e);
575int ENGINE_set_default_RAND(ENGINE *e); 598int ENGINE_set_default_RAND(ENGINE *e);
576int ENGINE_set_default_ciphers(ENGINE *e); 599int ENGINE_set_default_ciphers(ENGINE *e);
577int ENGINE_set_default_digests(ENGINE *e); 600int ENGINE_set_default_digests(ENGINE *e);
601int ENGINE_set_default_pkey_meths(ENGINE *e);
602int ENGINE_set_default_pkey_asn1_meths(ENGINE *e);
578 603
579/* The combination "set" - the flags are bitwise "OR"d from the 604/* The combination "set" - the flags are bitwise "OR"d from the
580 * ENGINE_METHOD_*** defines above. As with the "ENGINE_register_complete()" 605 * ENGINE_METHOD_*** defines above. As with the "ENGINE_register_complete()"
@@ -703,7 +728,7 @@ typedef int (*dynamic_bind_engine)(ENGINE *e, const char *id,
703 * values. */ 728 * values. */
704void *ENGINE_get_static_state(void); 729void *ENGINE_get_static_state(void);
705 730
706#if defined(__OpenBSD__) || defined(__FreeBSD__) 731#if defined(__OpenBSD__) || defined(__FreeBSD__) || defined(HAVE_CRYPTODEV)
707void ENGINE_setup_bsd_cryptodev(void); 732void ENGINE_setup_bsd_cryptodev(void);
708#endif 733#endif
709 734
@@ -732,13 +757,15 @@ void ERR_load_ENGINE_strings(void);
732#define ENGINE_F_ENGINE_GET_DEFAULT_TYPE 177 757#define ENGINE_F_ENGINE_GET_DEFAULT_TYPE 177
733#define ENGINE_F_ENGINE_GET_DIGEST 186 758#define ENGINE_F_ENGINE_GET_DIGEST 186
734#define ENGINE_F_ENGINE_GET_NEXT 115 759#define ENGINE_F_ENGINE_GET_NEXT 115
760#define ENGINE_F_ENGINE_GET_PKEY_ASN1_METH 193
761#define ENGINE_F_ENGINE_GET_PKEY_METH 192
735#define ENGINE_F_ENGINE_GET_PREV 116 762#define ENGINE_F_ENGINE_GET_PREV 116
736#define ENGINE_F_ENGINE_INIT 119 763#define ENGINE_F_ENGINE_INIT 119
737#define ENGINE_F_ENGINE_LIST_ADD 120 764#define ENGINE_F_ENGINE_LIST_ADD 120
738#define ENGINE_F_ENGINE_LIST_REMOVE 121 765#define ENGINE_F_ENGINE_LIST_REMOVE 121
739#define ENGINE_F_ENGINE_LOAD_PRIVATE_KEY 150 766#define ENGINE_F_ENGINE_LOAD_PRIVATE_KEY 150
740#define ENGINE_F_ENGINE_LOAD_PUBLIC_KEY 151 767#define ENGINE_F_ENGINE_LOAD_PUBLIC_KEY 151
741#define ENGINE_F_ENGINE_LOAD_SSL_CLIENT_CERT 192 768#define ENGINE_F_ENGINE_LOAD_SSL_CLIENT_CERT 194
742#define ENGINE_F_ENGINE_NEW 122 769#define ENGINE_F_ENGINE_NEW 122
743#define ENGINE_F_ENGINE_REMOVE 123 770#define ENGINE_F_ENGINE_REMOVE 123
744#define ENGINE_F_ENGINE_SET_DEFAULT_STRING 189 771#define ENGINE_F_ENGINE_SET_DEFAULT_STRING 189
@@ -767,6 +794,7 @@ void ERR_load_ENGINE_strings(void);
767#define ENGINE_R_DSO_FAILURE 104 794#define ENGINE_R_DSO_FAILURE 104
768#define ENGINE_R_DSO_NOT_FOUND 132 795#define ENGINE_R_DSO_NOT_FOUND 132
769#define ENGINE_R_ENGINES_SECTION_ERROR 148 796#define ENGINE_R_ENGINES_SECTION_ERROR 148
797#define ENGINE_R_ENGINE_CONFIGURATION_ERROR 102
770#define ENGINE_R_ENGINE_IS_NOT_IN_LIST 105 798#define ENGINE_R_ENGINE_IS_NOT_IN_LIST 105
771#define ENGINE_R_ENGINE_SECTION_ERROR 149 799#define ENGINE_R_ENGINE_SECTION_ERROR 149
772#define ENGINE_R_FAILED_LOADING_PRIVATE_KEY 128 800#define ENGINE_R_FAILED_LOADING_PRIVATE_KEY 128
@@ -793,6 +821,7 @@ void ERR_load_ENGINE_strings(void);
793#define ENGINE_R_RSA_NOT_IMPLEMENTED 141 821#define ENGINE_R_RSA_NOT_IMPLEMENTED 141
794#define ENGINE_R_UNIMPLEMENTED_CIPHER 146 822#define ENGINE_R_UNIMPLEMENTED_CIPHER 146
795#define ENGINE_R_UNIMPLEMENTED_DIGEST 147 823#define ENGINE_R_UNIMPLEMENTED_DIGEST 147
824#define ENGINE_R_UNIMPLEMENTED_PUBLIC_KEY_METHOD 101
796#define ENGINE_R_VERSION_INCOMPATIBILITY 145 825#define ENGINE_R_VERSION_INCOMPATIBILITY 145
797 826
798#ifdef __cplusplus 827#ifdef __cplusplus
diff --git a/src/lib/libcrypto/engine/tb_asnmth.c b/src/lib/libcrypto/engine/tb_asnmth.c
new file mode 100644
index 0000000000..75090339f7
--- /dev/null
+++ b/src/lib/libcrypto/engine/tb_asnmth.c
@@ -0,0 +1,246 @@
1/* ====================================================================
2 * Copyright (c) 2006 The OpenSSL Project. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 *
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in
13 * the documentation and/or other materials provided with the
14 * distribution.
15 *
16 * 3. All advertising materials mentioning features or use of this
17 * software must display the following acknowledgment:
18 * "This product includes software developed by the OpenSSL Project
19 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
20 *
21 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
22 * endorse or promote products derived from this software without
23 * prior written permission. For written permission, please contact
24 * licensing@OpenSSL.org.
25 *
26 * 5. Products derived from this software may not be called "OpenSSL"
27 * nor may "OpenSSL" appear in their names without prior written
28 * permission of the OpenSSL Project.
29 *
30 * 6. Redistributions of any form whatsoever must retain the following
31 * acknowledgment:
32 * "This product includes software developed by the OpenSSL Project
33 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
34 *
35 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
36 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
37 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
38 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
39 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
40 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
41 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
42 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
43 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
44 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
45 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
46 * OF THE POSSIBILITY OF SUCH DAMAGE.
47 * ====================================================================
48 *
49 * This product includes cryptographic software written by Eric Young
50 * (eay@cryptsoft.com). This product includes software written by Tim
51 * Hudson (tjh@cryptsoft.com).
52 *
53 */
54
55#include "eng_int.h"
56#include "asn1_locl.h"
57#include <openssl/evp.h>
58
59/* If this symbol is defined then ENGINE_get_pkey_asn1_meth_engine(), the
60 * function that is used by EVP to hook in pkey_asn1_meth code and cache
61 * defaults (etc), will display brief debugging summaries to stderr with the
62 * 'nid'. */
63/* #define ENGINE_PKEY_ASN1_METH_DEBUG */
64
65static ENGINE_TABLE *pkey_asn1_meth_table = NULL;
66
67void ENGINE_unregister_pkey_asn1_meths(ENGINE *e)
68 {
69 engine_table_unregister(&pkey_asn1_meth_table, e);
70 }
71
72static void engine_unregister_all_pkey_asn1_meths(void)
73 {
74 engine_table_cleanup(&pkey_asn1_meth_table);
75 }
76
77int ENGINE_register_pkey_asn1_meths(ENGINE *e)
78 {
79 if(e->pkey_asn1_meths)
80 {
81 const int *nids;
82 int num_nids = e->pkey_asn1_meths(e, NULL, &nids, 0);
83 if(num_nids > 0)
84 return engine_table_register(&pkey_asn1_meth_table,
85 engine_unregister_all_pkey_asn1_meths, e, nids,
86 num_nids, 0);
87 }
88 return 1;
89 }
90
91void ENGINE_register_all_pkey_asn1_meths(void)
92 {
93 ENGINE *e;
94
95 for(e=ENGINE_get_first() ; e ; e=ENGINE_get_next(e))
96 ENGINE_register_pkey_asn1_meths(e);
97 }
98
99int ENGINE_set_default_pkey_asn1_meths(ENGINE *e)
100 {
101 if(e->pkey_asn1_meths)
102 {
103 const int *nids;
104 int num_nids = e->pkey_asn1_meths(e, NULL, &nids, 0);
105 if(num_nids > 0)
106 return engine_table_register(&pkey_asn1_meth_table,
107 engine_unregister_all_pkey_asn1_meths, e, nids,
108 num_nids, 1);
109 }
110 return 1;
111 }
112
113/* Exposed API function to get a functional reference from the implementation
114 * table (ie. try to get a functional reference from the tabled structural
115 * references) for a given pkey_asn1_meth 'nid' */
116ENGINE *ENGINE_get_pkey_asn1_meth_engine(int nid)
117 {
118 return engine_table_select(&pkey_asn1_meth_table, nid);
119 }
120
121/* Obtains a pkey_asn1_meth implementation from an ENGINE functional reference */
122const EVP_PKEY_ASN1_METHOD *ENGINE_get_pkey_asn1_meth(ENGINE *e, int nid)
123 {
124 EVP_PKEY_ASN1_METHOD *ret;
125 ENGINE_PKEY_ASN1_METHS_PTR fn = ENGINE_get_pkey_asn1_meths(e);
126 if(!fn || !fn(e, &ret, NULL, nid))
127 {
128 ENGINEerr(ENGINE_F_ENGINE_GET_PKEY_ASN1_METH,
129 ENGINE_R_UNIMPLEMENTED_PUBLIC_KEY_METHOD);
130 return NULL;
131 }
132 return ret;
133 }
134
135/* Gets the pkey_asn1_meth callback from an ENGINE structure */
136ENGINE_PKEY_ASN1_METHS_PTR ENGINE_get_pkey_asn1_meths(const ENGINE *e)
137 {
138 return e->pkey_asn1_meths;
139 }
140
141/* Sets the pkey_asn1_meth callback in an ENGINE structure */
142int ENGINE_set_pkey_asn1_meths(ENGINE *e, ENGINE_PKEY_ASN1_METHS_PTR f)
143 {
144 e->pkey_asn1_meths = f;
145 return 1;
146 }
147
148/* Internal function to free up EVP_PKEY_ASN1_METHOD structures before an
149 * ENGINE is destroyed
150 */
151
152void engine_pkey_asn1_meths_free(ENGINE *e)
153 {
154 int i;
155 EVP_PKEY_ASN1_METHOD *pkm;
156 if (e->pkey_asn1_meths)
157 {
158 const int *pknids;
159 int npknids;
160 npknids = e->pkey_asn1_meths(e, NULL, &pknids, 0);
161 for (i = 0; i < npknids; i++)
162 {
163 if (e->pkey_asn1_meths(e, &pkm, NULL, pknids[i]))
164 {
165 EVP_PKEY_asn1_free(pkm);
166 }
167 }
168 }
169 }
170
171/* Find a method based on a string. This does a linear search through
172 * all implemented algorithms. This is OK in practice because only
173 * a small number of algorithms are likely to be implemented in an engine
174 * and it is not used for speed critical operations.
175 */
176
177const EVP_PKEY_ASN1_METHOD *ENGINE_get_pkey_asn1_meth_str(ENGINE *e,
178 const char *str, int len)
179 {
180 int i, nidcount;
181 const int *nids;
182 EVP_PKEY_ASN1_METHOD *ameth;
183 if (!e->pkey_asn1_meths)
184 return NULL;
185 if (len == -1)
186 len = strlen(str);
187 nidcount = e->pkey_asn1_meths(e, NULL, &nids, 0);
188 for (i = 0; i < nidcount; i++)
189 {
190 e->pkey_asn1_meths(e, &ameth, NULL, nids[i]);
191 if (((int)strlen(ameth->pem_str) == len) &&
192 !strncasecmp(ameth->pem_str, str, len))
193 return ameth;
194 }
195 return NULL;
196 }
197
198typedef struct
199 {
200 ENGINE *e;
201 const EVP_PKEY_ASN1_METHOD *ameth;
202 const char *str;
203 int len;
204 } ENGINE_FIND_STR;
205
206static void look_str_cb(int nid, STACK_OF(ENGINE) *sk, ENGINE *def, void *arg)
207 {
208 ENGINE_FIND_STR *lk = arg;
209 int i;
210 if (lk->ameth)
211 return;
212 for (i = 0; i < sk_ENGINE_num(sk); i++)
213 {
214 ENGINE *e = sk_ENGINE_value(sk, i);
215 EVP_PKEY_ASN1_METHOD *ameth;
216 e->pkey_asn1_meths(e, &ameth, NULL, nid);
217 if (((int)strlen(ameth->pem_str) == lk->len) &&
218 !strncasecmp(ameth->pem_str, lk->str, lk->len))
219 {
220 lk->e = e;
221 lk->ameth = ameth;
222 return;
223 }
224 }
225 }
226
227const EVP_PKEY_ASN1_METHOD *ENGINE_pkey_asn1_find_str(ENGINE **pe,
228 const char *str, int len)
229 {
230 ENGINE_FIND_STR fstr;
231 fstr.e = NULL;
232 fstr.ameth = NULL;
233 fstr.str = str;
234 fstr.len = len;
235 CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
236 engine_table_doall(pkey_asn1_meth_table, look_str_cb, &fstr);
237 /* If found obtain a structural reference to engine */
238 if (fstr.e)
239 {
240 fstr.e->struct_ref++;
241 engine_ref_debug(fstr.e, 0, 1)
242 }
243 *pe = fstr.e;
244 CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
245 return fstr.ameth;
246 }
diff --git a/src/lib/libcrypto/engine/tb_pkmeth.c b/src/lib/libcrypto/engine/tb_pkmeth.c
new file mode 100644
index 0000000000..1cdb967f25
--- /dev/null
+++ b/src/lib/libcrypto/engine/tb_pkmeth.c
@@ -0,0 +1,167 @@
1/* ====================================================================
2 * Copyright (c) 2006 The OpenSSL Project. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 *
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in
13 * the documentation and/or other materials provided with the
14 * distribution.
15 *
16 * 3. All advertising materials mentioning features or use of this
17 * software must display the following acknowledgment:
18 * "This product includes software developed by the OpenSSL Project
19 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
20 *
21 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
22 * endorse or promote products derived from this software without
23 * prior written permission. For written permission, please contact
24 * licensing@OpenSSL.org.
25 *
26 * 5. Products derived from this software may not be called "OpenSSL"
27 * nor may "OpenSSL" appear in their names without prior written
28 * permission of the OpenSSL Project.
29 *
30 * 6. Redistributions of any form whatsoever must retain the following
31 * acknowledgment:
32 * "This product includes software developed by the OpenSSL Project
33 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
34 *
35 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
36 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
37 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
38 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
39 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
40 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
41 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
42 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
43 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
44 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
45 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
46 * OF THE POSSIBILITY OF SUCH DAMAGE.
47 * ====================================================================
48 *
49 * This product includes cryptographic software written by Eric Young
50 * (eay@cryptsoft.com). This product includes software written by Tim
51 * Hudson (tjh@cryptsoft.com).
52 *
53 */
54
55#include "eng_int.h"
56#include <openssl/evp.h>
57
58/* If this symbol is defined then ENGINE_get_pkey_meth_engine(), the function
59 * that is used by EVP to hook in pkey_meth code and cache defaults (etc), will
60 * display brief debugging summaries to stderr with the 'nid'. */
61/* #define ENGINE_PKEY_METH_DEBUG */
62
63static ENGINE_TABLE *pkey_meth_table = NULL;
64
65void ENGINE_unregister_pkey_meths(ENGINE *e)
66 {
67 engine_table_unregister(&pkey_meth_table, e);
68 }
69
70static void engine_unregister_all_pkey_meths(void)
71 {
72 engine_table_cleanup(&pkey_meth_table);
73 }
74
75int ENGINE_register_pkey_meths(ENGINE *e)
76 {
77 if(e->pkey_meths)
78 {
79 const int *nids;
80 int num_nids = e->pkey_meths(e, NULL, &nids, 0);
81 if(num_nids > 0)
82 return engine_table_register(&pkey_meth_table,
83 engine_unregister_all_pkey_meths, e, nids,
84 num_nids, 0);
85 }
86 return 1;
87 }
88
89void ENGINE_register_all_pkey_meths()
90 {
91 ENGINE *e;
92
93 for(e=ENGINE_get_first() ; e ; e=ENGINE_get_next(e))
94 ENGINE_register_pkey_meths(e);
95 }
96
97int ENGINE_set_default_pkey_meths(ENGINE *e)
98 {
99 if(e->pkey_meths)
100 {
101 const int *nids;
102 int num_nids = e->pkey_meths(e, NULL, &nids, 0);
103 if(num_nids > 0)
104 return engine_table_register(&pkey_meth_table,
105 engine_unregister_all_pkey_meths, e, nids,
106 num_nids, 1);
107 }
108 return 1;
109 }
110
111/* Exposed API function to get a functional reference from the implementation
112 * table (ie. try to get a functional reference from the tabled structural
113 * references) for a given pkey_meth 'nid' */
114ENGINE *ENGINE_get_pkey_meth_engine(int nid)
115 {
116 return engine_table_select(&pkey_meth_table, nid);
117 }
118
119/* Obtains a pkey_meth implementation from an ENGINE functional reference */
120const EVP_PKEY_METHOD *ENGINE_get_pkey_meth(ENGINE *e, int nid)
121 {
122 EVP_PKEY_METHOD *ret;
123 ENGINE_PKEY_METHS_PTR fn = ENGINE_get_pkey_meths(e);
124 if(!fn || !fn(e, &ret, NULL, nid))
125 {
126 ENGINEerr(ENGINE_F_ENGINE_GET_PKEY_METH,
127 ENGINE_R_UNIMPLEMENTED_PUBLIC_KEY_METHOD);
128 return NULL;
129 }
130 return ret;
131 }
132
133/* Gets the pkey_meth callback from an ENGINE structure */
134ENGINE_PKEY_METHS_PTR ENGINE_get_pkey_meths(const ENGINE *e)
135 {
136 return e->pkey_meths;
137 }
138
139/* Sets the pkey_meth callback in an ENGINE structure */
140int ENGINE_set_pkey_meths(ENGINE *e, ENGINE_PKEY_METHS_PTR f)
141 {
142 e->pkey_meths = f;
143 return 1;
144 }
145
146/* Internal function to free up EVP_PKEY_METHOD structures before an
147 * ENGINE is destroyed
148 */
149
150void engine_pkey_meths_free(ENGINE *e)
151 {
152 int i;
153 EVP_PKEY_METHOD *pkm;
154 if (e->pkey_meths)
155 {
156 const int *pknids;
157 int npknids;
158 npknids = e->pkey_meths(e, NULL, &pknids, 0);
159 for (i = 0; i < npknids; i++)
160 {
161 if (e->pkey_meths(e, &pkm, NULL, pknids[i]))
162 {
163 EVP_PKEY_meth_free(pkm);
164 }
165 }
166 }
167 }
diff --git a/src/lib/libcrypto/err/err.c b/src/lib/libcrypto/err/err.c
index 292404a2fb..69713a6e2f 100644
--- a/src/lib/libcrypto/err/err.c
+++ b/src/lib/libcrypto/err/err.c
@@ -56,7 +56,7 @@
56 * [including the GNU Public Licence.] 56 * [including the GNU Public Licence.]
57 */ 57 */
58/* ==================================================================== 58/* ====================================================================
59 * Copyright (c) 1998-2001 The OpenSSL Project. All rights reserved. 59 * Copyright (c) 1998-2006 The OpenSSL Project. All rights reserved.
60 * 60 *
61 * Redistribution and use in source and binary forms, with or without 61 * Redistribution and use in source and binary forms, with or without
62 * modification, are permitted provided that the following conditions 62 * modification, are permitted provided that the following conditions
@@ -119,9 +119,507 @@
119#include <openssl/bio.h> 119#include <openssl/bio.h>
120#include <openssl/err.h> 120#include <openssl/err.h>
121 121
122static unsigned long get_error_values(int inc,int top, 122DECLARE_LHASH_OF(ERR_STRING_DATA);
123 const char **file,int *line, 123DECLARE_LHASH_OF(ERR_STATE);
124 const char **data,int *flags); 124
125static void err_load_strings(int lib, ERR_STRING_DATA *str);
126
127static void ERR_STATE_free(ERR_STATE *s);
128#ifndef OPENSSL_NO_ERR
129static ERR_STRING_DATA ERR_str_libraries[]=
130 {
131{ERR_PACK(ERR_LIB_NONE,0,0) ,"unknown library"},
132{ERR_PACK(ERR_LIB_SYS,0,0) ,"system library"},
133{ERR_PACK(ERR_LIB_BN,0,0) ,"bignum routines"},
134{ERR_PACK(ERR_LIB_RSA,0,0) ,"rsa routines"},
135{ERR_PACK(ERR_LIB_DH,0,0) ,"Diffie-Hellman routines"},
136{ERR_PACK(ERR_LIB_EVP,0,0) ,"digital envelope routines"},
137{ERR_PACK(ERR_LIB_BUF,0,0) ,"memory buffer routines"},
138{ERR_PACK(ERR_LIB_OBJ,0,0) ,"object identifier routines"},
139{ERR_PACK(ERR_LIB_PEM,0,0) ,"PEM routines"},
140{ERR_PACK(ERR_LIB_DSA,0,0) ,"dsa routines"},
141{ERR_PACK(ERR_LIB_X509,0,0) ,"x509 certificate routines"},
142{ERR_PACK(ERR_LIB_ASN1,0,0) ,"asn1 encoding routines"},
143{ERR_PACK(ERR_LIB_CONF,0,0) ,"configuration file routines"},
144{ERR_PACK(ERR_LIB_CRYPTO,0,0) ,"common libcrypto routines"},
145{ERR_PACK(ERR_LIB_EC,0,0) ,"elliptic curve routines"},
146{ERR_PACK(ERR_LIB_SSL,0,0) ,"SSL routines"},
147{ERR_PACK(ERR_LIB_BIO,0,0) ,"BIO routines"},
148{ERR_PACK(ERR_LIB_PKCS7,0,0) ,"PKCS7 routines"},
149{ERR_PACK(ERR_LIB_X509V3,0,0) ,"X509 V3 routines"},
150{ERR_PACK(ERR_LIB_PKCS12,0,0) ,"PKCS12 routines"},
151{ERR_PACK(ERR_LIB_RAND,0,0) ,"random number generator"},
152{ERR_PACK(ERR_LIB_DSO,0,0) ,"DSO support routines"},
153{ERR_PACK(ERR_LIB_TS,0,0) ,"time stamp routines"},
154{ERR_PACK(ERR_LIB_ENGINE,0,0) ,"engine routines"},
155{ERR_PACK(ERR_LIB_OCSP,0,0) ,"OCSP routines"},
156{ERR_PACK(ERR_LIB_FIPS,0,0) ,"FIPS routines"},
157{ERR_PACK(ERR_LIB_CMS,0,0) ,"CMS routines"},
158{ERR_PACK(ERR_LIB_HMAC,0,0) ,"HMAC routines"},
159{0,NULL},
160 };
161
162static ERR_STRING_DATA ERR_str_functs[]=
163 {
164 {ERR_PACK(0,SYS_F_FOPEN,0), "fopen"},
165 {ERR_PACK(0,SYS_F_CONNECT,0), "connect"},
166 {ERR_PACK(0,SYS_F_GETSERVBYNAME,0), "getservbyname"},
167 {ERR_PACK(0,SYS_F_SOCKET,0), "socket"},
168 {ERR_PACK(0,SYS_F_IOCTLSOCKET,0), "ioctlsocket"},
169 {ERR_PACK(0,SYS_F_BIND,0), "bind"},
170 {ERR_PACK(0,SYS_F_LISTEN,0), "listen"},
171 {ERR_PACK(0,SYS_F_ACCEPT,0), "accept"},
172#ifdef OPENSSL_SYS_WINDOWS
173 {ERR_PACK(0,SYS_F_WSASTARTUP,0), "WSAstartup"},
174#endif
175 {ERR_PACK(0,SYS_F_OPENDIR,0), "opendir"},
176 {ERR_PACK(0,SYS_F_FREAD,0), "fread"},
177 {0,NULL},
178 };
179
180static ERR_STRING_DATA ERR_str_reasons[]=
181 {
182{ERR_R_SYS_LIB ,"system lib"},
183{ERR_R_BN_LIB ,"BN lib"},
184{ERR_R_RSA_LIB ,"RSA lib"},
185{ERR_R_DH_LIB ,"DH lib"},
186{ERR_R_EVP_LIB ,"EVP lib"},
187{ERR_R_BUF_LIB ,"BUF lib"},
188{ERR_R_OBJ_LIB ,"OBJ lib"},
189{ERR_R_PEM_LIB ,"PEM lib"},
190{ERR_R_DSA_LIB ,"DSA lib"},
191{ERR_R_X509_LIB ,"X509 lib"},
192{ERR_R_ASN1_LIB ,"ASN1 lib"},
193{ERR_R_CONF_LIB ,"CONF lib"},
194{ERR_R_CRYPTO_LIB ,"CRYPTO lib"},
195{ERR_R_EC_LIB ,"EC lib"},
196{ERR_R_SSL_LIB ,"SSL lib"},
197{ERR_R_BIO_LIB ,"BIO lib"},
198{ERR_R_PKCS7_LIB ,"PKCS7 lib"},
199{ERR_R_X509V3_LIB ,"X509V3 lib"},
200{ERR_R_PKCS12_LIB ,"PKCS12 lib"},
201{ERR_R_RAND_LIB ,"RAND lib"},
202{ERR_R_DSO_LIB ,"DSO lib"},
203{ERR_R_ENGINE_LIB ,"ENGINE lib"},
204{ERR_R_OCSP_LIB ,"OCSP lib"},
205{ERR_R_TS_LIB ,"TS lib"},
206
207{ERR_R_NESTED_ASN1_ERROR ,"nested asn1 error"},
208{ERR_R_BAD_ASN1_OBJECT_HEADER ,"bad asn1 object header"},
209{ERR_R_BAD_GET_ASN1_OBJECT_CALL ,"bad get asn1 object call"},
210{ERR_R_EXPECTING_AN_ASN1_SEQUENCE ,"expecting an asn1 sequence"},
211{ERR_R_ASN1_LENGTH_MISMATCH ,"asn1 length mismatch"},
212{ERR_R_MISSING_ASN1_EOS ,"missing asn1 eos"},
213
214{ERR_R_FATAL ,"fatal"},
215{ERR_R_MALLOC_FAILURE ,"malloc failure"},
216{ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED ,"called a function you should not call"},
217{ERR_R_PASSED_NULL_PARAMETER ,"passed a null parameter"},
218{ERR_R_INTERNAL_ERROR ,"internal error"},
219{ERR_R_DISABLED ,"called a function that was disabled at compile-time"},
220
221{0,NULL},
222 };
223#endif
224
225
226/* Define the predeclared (but externally opaque) "ERR_FNS" type */
227struct st_ERR_FNS
228 {
229 /* Works on the "error_hash" string table */
230 LHASH_OF(ERR_STRING_DATA) *(*cb_err_get)(int create);
231 void (*cb_err_del)(void);
232 ERR_STRING_DATA *(*cb_err_get_item)(const ERR_STRING_DATA *);
233 ERR_STRING_DATA *(*cb_err_set_item)(ERR_STRING_DATA *);
234 ERR_STRING_DATA *(*cb_err_del_item)(ERR_STRING_DATA *);
235 /* Works on the "thread_hash" error-state table */
236 LHASH_OF(ERR_STATE) *(*cb_thread_get)(int create);
237 void (*cb_thread_release)(LHASH_OF(ERR_STATE) **hash);
238 ERR_STATE *(*cb_thread_get_item)(const ERR_STATE *);
239 ERR_STATE *(*cb_thread_set_item)(ERR_STATE *);
240 void (*cb_thread_del_item)(const ERR_STATE *);
241 /* Returns the next available error "library" numbers */
242 int (*cb_get_next_lib)(void);
243 };
244
245/* Predeclarations of the "err_defaults" functions */
246static LHASH_OF(ERR_STRING_DATA) *int_err_get(int create);
247static void int_err_del(void);
248static ERR_STRING_DATA *int_err_get_item(const ERR_STRING_DATA *);
249static ERR_STRING_DATA *int_err_set_item(ERR_STRING_DATA *);
250static ERR_STRING_DATA *int_err_del_item(ERR_STRING_DATA *);
251static LHASH_OF(ERR_STATE) *int_thread_get(int create);
252static void int_thread_release(LHASH_OF(ERR_STATE) **hash);
253static ERR_STATE *int_thread_get_item(const ERR_STATE *);
254static ERR_STATE *int_thread_set_item(ERR_STATE *);
255static void int_thread_del_item(const ERR_STATE *);
256static int int_err_get_next_lib(void);
257/* The static ERR_FNS table using these defaults functions */
258static const ERR_FNS err_defaults =
259 {
260 int_err_get,
261 int_err_del,
262 int_err_get_item,
263 int_err_set_item,
264 int_err_del_item,
265 int_thread_get,
266 int_thread_release,
267 int_thread_get_item,
268 int_thread_set_item,
269 int_thread_del_item,
270 int_err_get_next_lib
271 };
272
273/* The replacable table of ERR_FNS functions we use at run-time */
274static const ERR_FNS *err_fns = NULL;
275
276/* Eg. rather than using "err_get()", use "ERRFN(err_get)()". */
277#define ERRFN(a) err_fns->cb_##a
278
279/* The internal state used by "err_defaults" - as such, the setting, reading,
280 * creating, and deleting of this data should only be permitted via the
281 * "err_defaults" functions. This way, a linked module can completely defer all
282 * ERR state operation (together with requisite locking) to the implementations
283 * and state in the loading application. */
284static LHASH_OF(ERR_STRING_DATA) *int_error_hash = NULL;
285static LHASH_OF(ERR_STATE) *int_thread_hash = NULL;
286static int int_thread_hash_references = 0;
287static int int_err_library_number= ERR_LIB_USER;
288
289/* Internal function that checks whether "err_fns" is set and if not, sets it to
290 * the defaults. */
291static void err_fns_check(void)
292 {
293 if (err_fns) return;
294
295 CRYPTO_w_lock(CRYPTO_LOCK_ERR);
296 if (!err_fns)
297 err_fns = &err_defaults;
298 CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
299 }
300
301/* API functions to get or set the underlying ERR functions. */
302
303const ERR_FNS *ERR_get_implementation(void)
304 {
305 err_fns_check();
306 return err_fns;
307 }
308
309int ERR_set_implementation(const ERR_FNS *fns)
310 {
311 int ret = 0;
312
313 CRYPTO_w_lock(CRYPTO_LOCK_ERR);
314 /* It's too late if 'err_fns' is non-NULL. BTW: not much point setting
315 * an error is there?! */
316 if (!err_fns)
317 {
318 err_fns = fns;
319 ret = 1;
320 }
321 CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
322 return ret;
323 }
324
325/* These are the callbacks provided to "lh_new()" when creating the LHASH tables
326 * internal to the "err_defaults" implementation. */
327
328static unsigned long get_error_values(int inc,int top,const char **file,int *line,
329 const char **data,int *flags);
330
331/* The internal functions used in the "err_defaults" implementation */
332
333static unsigned long err_string_data_hash(const ERR_STRING_DATA *a)
334 {
335 unsigned long ret,l;
336
337 l=a->error;
338 ret=l^ERR_GET_LIB(l)^ERR_GET_FUNC(l);
339 return(ret^ret%19*13);
340 }
341static IMPLEMENT_LHASH_HASH_FN(err_string_data, ERR_STRING_DATA)
342
343static int err_string_data_cmp(const ERR_STRING_DATA *a,
344 const ERR_STRING_DATA *b)
345 {
346 return (int)(a->error - b->error);
347 }
348static IMPLEMENT_LHASH_COMP_FN(err_string_data, ERR_STRING_DATA)
349
350static LHASH_OF(ERR_STRING_DATA) *int_err_get(int create)
351 {
352 LHASH_OF(ERR_STRING_DATA) *ret = NULL;
353
354 CRYPTO_w_lock(CRYPTO_LOCK_ERR);
355 if (!int_error_hash && create)
356 {
357 CRYPTO_push_info("int_err_get (err.c)");
358 int_error_hash = lh_ERR_STRING_DATA_new();
359 CRYPTO_pop_info();
360 }
361 if (int_error_hash)
362 ret = int_error_hash;
363 CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
364
365 return ret;
366 }
367
368static void int_err_del(void)
369 {
370 CRYPTO_w_lock(CRYPTO_LOCK_ERR);
371 if (int_error_hash)
372 {
373 lh_ERR_STRING_DATA_free(int_error_hash);
374 int_error_hash = NULL;
375 }
376 CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
377 }
378
379static ERR_STRING_DATA *int_err_get_item(const ERR_STRING_DATA *d)
380 {
381 ERR_STRING_DATA *p;
382 LHASH_OF(ERR_STRING_DATA) *hash;
383
384 err_fns_check();
385 hash = ERRFN(err_get)(0);
386 if (!hash)
387 return NULL;
388
389 CRYPTO_r_lock(CRYPTO_LOCK_ERR);
390 p = lh_ERR_STRING_DATA_retrieve(hash, d);
391 CRYPTO_r_unlock(CRYPTO_LOCK_ERR);
392
393 return p;
394 }
395
396static ERR_STRING_DATA *int_err_set_item(ERR_STRING_DATA *d)
397 {
398 ERR_STRING_DATA *p;
399 LHASH_OF(ERR_STRING_DATA) *hash;
400
401 err_fns_check();
402 hash = ERRFN(err_get)(1);
403 if (!hash)
404 return NULL;
405
406 CRYPTO_w_lock(CRYPTO_LOCK_ERR);
407 p = lh_ERR_STRING_DATA_insert(hash, d);
408 CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
409
410 return p;
411 }
412
413static ERR_STRING_DATA *int_err_del_item(ERR_STRING_DATA *d)
414 {
415 ERR_STRING_DATA *p;
416 LHASH_OF(ERR_STRING_DATA) *hash;
417
418 err_fns_check();
419 hash = ERRFN(err_get)(0);
420 if (!hash)
421 return NULL;
422
423 CRYPTO_w_lock(CRYPTO_LOCK_ERR);
424 p = lh_ERR_STRING_DATA_delete(hash, d);
425 CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
426
427 return p;
428 }
429
430static unsigned long err_state_hash(const ERR_STATE *a)
431 {
432 return CRYPTO_THREADID_hash(&a->tid) * 13;
433 }
434static IMPLEMENT_LHASH_HASH_FN(err_state, ERR_STATE)
435
436static int err_state_cmp(const ERR_STATE *a, const ERR_STATE *b)
437 {
438 return CRYPTO_THREADID_cmp(&a->tid, &b->tid);
439 }
440static IMPLEMENT_LHASH_COMP_FN(err_state, ERR_STATE)
441
442static LHASH_OF(ERR_STATE) *int_thread_get(int create)
443 {
444 LHASH_OF(ERR_STATE) *ret = NULL;
445
446 CRYPTO_w_lock(CRYPTO_LOCK_ERR);
447 if (!int_thread_hash && create)
448 {
449 CRYPTO_push_info("int_thread_get (err.c)");
450 int_thread_hash = lh_ERR_STATE_new();
451 CRYPTO_pop_info();
452 }
453 if (int_thread_hash)
454 {
455 int_thread_hash_references++;
456 ret = int_thread_hash;
457 }
458 CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
459 return ret;
460 }
461
462static void int_thread_release(LHASH_OF(ERR_STATE) **hash)
463 {
464 int i;
465
466 if (hash == NULL || *hash == NULL)
467 return;
468
469 i = CRYPTO_add(&int_thread_hash_references, -1, CRYPTO_LOCK_ERR);
470
471#ifdef REF_PRINT
472 fprintf(stderr,"%4d:%s\n",int_thread_hash_references,"ERR");
473#endif
474 if (i > 0) return;
475#ifdef REF_CHECK
476 if (i < 0)
477 {
478 fprintf(stderr,"int_thread_release, bad reference count\n");
479 abort(); /* ok */
480 }
481#endif
482 *hash = NULL;
483 }
484
485static ERR_STATE *int_thread_get_item(const ERR_STATE *d)
486 {
487 ERR_STATE *p;
488 LHASH_OF(ERR_STATE) *hash;
489
490 err_fns_check();
491 hash = ERRFN(thread_get)(0);
492 if (!hash)
493 return NULL;
494
495 CRYPTO_r_lock(CRYPTO_LOCK_ERR);
496 p = lh_ERR_STATE_retrieve(hash, d);
497 CRYPTO_r_unlock(CRYPTO_LOCK_ERR);
498
499 ERRFN(thread_release)(&hash);
500 return p;
501 }
502
503static ERR_STATE *int_thread_set_item(ERR_STATE *d)
504 {
505 ERR_STATE *p;
506 LHASH_OF(ERR_STATE) *hash;
507
508 err_fns_check();
509 hash = ERRFN(thread_get)(1);
510 if (!hash)
511 return NULL;
512
513 CRYPTO_w_lock(CRYPTO_LOCK_ERR);
514 p = lh_ERR_STATE_insert(hash, d);
515 CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
516
517 ERRFN(thread_release)(&hash);
518 return p;
519 }
520
521static void int_thread_del_item(const ERR_STATE *d)
522 {
523 ERR_STATE *p;
524 LHASH_OF(ERR_STATE) *hash;
525
526 err_fns_check();
527 hash = ERRFN(thread_get)(0);
528 if (!hash)
529 return;
530
531 CRYPTO_w_lock(CRYPTO_LOCK_ERR);
532 p = lh_ERR_STATE_delete(hash, d);
533 /* make sure we don't leak memory */
534 if (int_thread_hash_references == 1
535 && int_thread_hash && lh_ERR_STATE_num_items(int_thread_hash) == 0)
536 {
537 lh_ERR_STATE_free(int_thread_hash);
538 int_thread_hash = NULL;
539 }
540 CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
541
542 ERRFN(thread_release)(&hash);
543 if (p)
544 ERR_STATE_free(p);
545 }
546
547static int int_err_get_next_lib(void)
548 {
549 int ret;
550
551 CRYPTO_w_lock(CRYPTO_LOCK_ERR);
552 ret = int_err_library_number++;
553 CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
554
555 return ret;
556 }
557
558
559#ifndef OPENSSL_NO_ERR
560#define NUM_SYS_STR_REASONS 127
561#define LEN_SYS_STR_REASON 32
562
563static ERR_STRING_DATA SYS_str_reasons[NUM_SYS_STR_REASONS + 1];
564/* SYS_str_reasons is filled with copies of strerror() results at
565 * initialization.
566 * 'errno' values up to 127 should cover all usual errors,
567 * others will be displayed numerically by ERR_error_string.
568 * It is crucial that we have something for each reason code
569 * that occurs in ERR_str_reasons, or bogus reason strings
570 * will be returned for SYSerr(), which always gets an errno
571 * value and never one of those 'standard' reason codes. */
572
573static void build_SYS_str_reasons(void)
574 {
575 /* OPENSSL_malloc cannot be used here, use static storage instead */
576 static char strerror_tab[NUM_SYS_STR_REASONS][LEN_SYS_STR_REASON];
577 int i;
578 static int init = 1;
579
580 CRYPTO_r_lock(CRYPTO_LOCK_ERR);
581 if (!init)
582 {
583 CRYPTO_r_unlock(CRYPTO_LOCK_ERR);
584 return;
585 }
586
587 CRYPTO_r_unlock(CRYPTO_LOCK_ERR);
588 CRYPTO_w_lock(CRYPTO_LOCK_ERR);
589 if (!init)
590 {
591 CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
592 return;
593 }
594
595 for (i = 1; i <= NUM_SYS_STR_REASONS; i++)
596 {
597 ERR_STRING_DATA *str = &SYS_str_reasons[i - 1];
598
599 str->error = (unsigned long)i;
600 if (str->string == NULL)
601 {
602 char (*dest)[LEN_SYS_STR_REASON] = &(strerror_tab[i - 1]);
603 char *src = strerror(i);
604 if (src != NULL)
605 {
606 strncpy(*dest, src, sizeof *dest);
607 (*dest)[sizeof *dest - 1] = '\0';
608 str->string = *dest;
609 }
610 }
611 if (str->string == NULL)
612 str->string = "unknown";
613 }
614
615 /* Now we still have SYS_str_reasons[NUM_SYS_STR_REASONS] = {0, NULL},
616 * as required by ERR_load_strings. */
617
618 init = 0;
619
620 CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
621 }
622#endif
125 623
126#define err_clear_data(p,i) \ 624#define err_clear_data(p,i) \
127 do { \ 625 do { \
@@ -143,6 +641,68 @@ static unsigned long get_error_values(int inc,int top,
143 (p)->err_line[i]= -1; \ 641 (p)->err_line[i]= -1; \
144 } while(0) 642 } while(0)
145 643
644static void ERR_STATE_free(ERR_STATE *s)
645 {
646 int i;
647
648 if (s == NULL)
649 return;
650
651 for (i=0; i<ERR_NUM_ERRORS; i++)
652 {
653 err_clear_data(s,i);
654 }
655 OPENSSL_free(s);
656 }
657
658void ERR_load_ERR_strings(void)
659 {
660 err_fns_check();
661#ifndef OPENSSL_NO_ERR
662 err_load_strings(0,ERR_str_libraries);
663 err_load_strings(0,ERR_str_reasons);
664 err_load_strings(ERR_LIB_SYS,ERR_str_functs);
665 build_SYS_str_reasons();
666 err_load_strings(ERR_LIB_SYS,SYS_str_reasons);
667#endif
668 }
669
670static void err_load_strings(int lib, ERR_STRING_DATA *str)
671 {
672 while (str->error)
673 {
674 if (lib)
675 str->error|=ERR_PACK(lib,0,0);
676 ERRFN(err_set_item)(str);
677 str++;
678 }
679 }
680
681void ERR_load_strings(int lib, ERR_STRING_DATA *str)
682 {
683 ERR_load_ERR_strings();
684 err_load_strings(lib, str);
685 }
686
687void ERR_unload_strings(int lib, ERR_STRING_DATA *str)
688 {
689 while (str->error)
690 {
691 if (lib)
692 str->error|=ERR_PACK(lib,0,0);
693 ERRFN(err_del_item)(str);
694 str++;
695 }
696 }
697
698void ERR_free_strings(void)
699 {
700 err_fns_check();
701 ERRFN(err_del)();
702 }
703
704/********************************************************/
705
146void ERR_put_error(int lib, int func, int reason, const char *file, 706void ERR_put_error(int lib, int func, int reason, const char *file,
147 int line) 707 int line)
148 { 708 {
@@ -297,6 +857,196 @@ static unsigned long get_error_values(int inc, int top, const char **file, int *
297 return ret; 857 return ret;
298 } 858 }
299 859
860void ERR_error_string_n(unsigned long e, char *buf, size_t len)
861 {
862 char lsbuf[64], fsbuf[64], rsbuf[64];
863 const char *ls,*fs,*rs;
864 unsigned long l,f,r;
865
866 l=ERR_GET_LIB(e);
867 f=ERR_GET_FUNC(e);
868 r=ERR_GET_REASON(e);
869
870 ls=ERR_lib_error_string(e);
871 fs=ERR_func_error_string(e);
872 rs=ERR_reason_error_string(e);
873
874 if (ls == NULL)
875 BIO_snprintf(lsbuf, sizeof(lsbuf), "lib(%lu)", l);
876 if (fs == NULL)
877 BIO_snprintf(fsbuf, sizeof(fsbuf), "func(%lu)", f);
878 if (rs == NULL)
879 BIO_snprintf(rsbuf, sizeof(rsbuf), "reason(%lu)", r);
880
881 BIO_snprintf(buf, len,"error:%08lX:%s:%s:%s", e, ls?ls:lsbuf,
882 fs?fs:fsbuf, rs?rs:rsbuf);
883 if (strlen(buf) == len-1)
884 {
885 /* output may be truncated; make sure we always have 5
886 * colon-separated fields, i.e. 4 colons ... */
887#define NUM_COLONS 4
888 if (len > NUM_COLONS) /* ... if possible */
889 {
890 int i;
891 char *s = buf;
892
893 for (i = 0; i < NUM_COLONS; i++)
894 {
895 char *colon = strchr(s, ':');
896 if (colon == NULL || colon > &buf[len-1] - NUM_COLONS + i)
897 {
898 /* set colon no. i at last possible position
899 * (buf[len-1] is the terminating 0)*/
900 colon = &buf[len-1] - NUM_COLONS + i;
901 *colon = ':';
902 }
903 s = colon + 1;
904 }
905 }
906 }
907 }
908
909/* BAD for multi-threading: uses a local buffer if ret == NULL */
910/* ERR_error_string_n should be used instead for ret != NULL
911 * as ERR_error_string cannot know how large the buffer is */
912char *ERR_error_string(unsigned long e, char *ret)
913 {
914 static char buf[256];
915
916 if (ret == NULL) ret=buf;
917 ERR_error_string_n(e, ret, 256);
918
919 return ret;
920 }
921
922LHASH_OF(ERR_STRING_DATA) *ERR_get_string_table(void)
923 {
924 err_fns_check();
925 return ERRFN(err_get)(0);
926 }
927
928LHASH_OF(ERR_STATE) *ERR_get_err_state_table(void)
929 {
930 err_fns_check();
931 return ERRFN(thread_get)(0);
932 }
933
934void ERR_release_err_state_table(LHASH_OF(ERR_STATE) **hash)
935 {
936 err_fns_check();
937 ERRFN(thread_release)(hash);
938 }
939
940const char *ERR_lib_error_string(unsigned long e)
941 {
942 ERR_STRING_DATA d,*p;
943 unsigned long l;
944
945 err_fns_check();
946 l=ERR_GET_LIB(e);
947 d.error=ERR_PACK(l,0,0);
948 p=ERRFN(err_get_item)(&d);
949 return((p == NULL)?NULL:p->string);
950 }
951
952const char *ERR_func_error_string(unsigned long e)
953 {
954 ERR_STRING_DATA d,*p;
955 unsigned long l,f;
956
957 err_fns_check();
958 l=ERR_GET_LIB(e);
959 f=ERR_GET_FUNC(e);
960 d.error=ERR_PACK(l,f,0);
961 p=ERRFN(err_get_item)(&d);
962 return((p == NULL)?NULL:p->string);
963 }
964
965const char *ERR_reason_error_string(unsigned long e)
966 {
967 ERR_STRING_DATA d,*p=NULL;
968 unsigned long l,r;
969
970 err_fns_check();
971 l=ERR_GET_LIB(e);
972 r=ERR_GET_REASON(e);
973 d.error=ERR_PACK(l,0,r);
974 p=ERRFN(err_get_item)(&d);
975 if (!p)
976 {
977 d.error=ERR_PACK(0,0,r);
978 p=ERRFN(err_get_item)(&d);
979 }
980 return((p == NULL)?NULL:p->string);
981 }
982
983void ERR_remove_thread_state(const CRYPTO_THREADID *id)
984 {
985 ERR_STATE tmp;
986
987 if (id)
988 CRYPTO_THREADID_cpy(&tmp.tid, id);
989 else
990 CRYPTO_THREADID_current(&tmp.tid);
991 err_fns_check();
992 /* thread_del_item automatically destroys the LHASH if the number of
993 * items reaches zero. */
994 ERRFN(thread_del_item)(&tmp);
995 }
996
997#ifndef OPENSSL_NO_DEPRECATED
998void ERR_remove_state(unsigned long pid)
999 {
1000 ERR_remove_thread_state(NULL);
1001 }
1002#endif
1003
1004ERR_STATE *ERR_get_state(void)
1005 {
1006 static ERR_STATE fallback;
1007 ERR_STATE *ret,tmp,*tmpp=NULL;
1008 int i;
1009 CRYPTO_THREADID tid;
1010
1011 err_fns_check();
1012 CRYPTO_THREADID_current(&tid);
1013 CRYPTO_THREADID_cpy(&tmp.tid, &tid);
1014 ret=ERRFN(thread_get_item)(&tmp);
1015
1016 /* ret == the error state, if NULL, make a new one */
1017 if (ret == NULL)
1018 {
1019 ret=(ERR_STATE *)OPENSSL_malloc(sizeof(ERR_STATE));
1020 if (ret == NULL) return(&fallback);
1021 CRYPTO_THREADID_cpy(&ret->tid, &tid);
1022 ret->top=0;
1023 ret->bottom=0;
1024 for (i=0; i<ERR_NUM_ERRORS; i++)
1025 {
1026 ret->err_data[i]=NULL;
1027 ret->err_data_flags[i]=0;
1028 }
1029 tmpp = ERRFN(thread_set_item)(ret);
1030 /* To check if insertion failed, do a get. */
1031 if (ERRFN(thread_get_item)(ret) != ret)
1032 {
1033 ERR_STATE_free(ret); /* could not insert it */
1034 return(&fallback);
1035 }
1036 /* If a race occured in this function and we came second, tmpp
1037 * is the first one that we just replaced. */
1038 if (tmpp)
1039 ERR_STATE_free(tmpp);
1040 }
1041 return ret;
1042 }
1043
1044int ERR_get_next_error_library(void)
1045 {
1046 err_fns_check();
1047 return ERRFN(get_next_lib)();
1048 }
1049
300void ERR_set_error_data(char *data, int flags) 1050void ERR_set_error_data(char *data, int flags)
301 { 1051 {
302 ERR_STATE *es; 1052 ERR_STATE *es;
@@ -383,34 +1133,3 @@ int ERR_pop_to_mark(void)
383 es->err_flags[es->top]&=~ERR_FLAG_MARK; 1133 es->err_flags[es->top]&=~ERR_FLAG_MARK;
384 return 1; 1134 return 1;
385 } 1135 }
386
387#ifdef OPENSSL_FIPS
388
389static ERR_STATE *fget_state(void)
390 {
391 static ERR_STATE fstate;
392 return &fstate;
393 }
394
395ERR_STATE *(*get_state_func)(void) = fget_state;
396void (*remove_state_func)(unsigned long pid);
397
398ERR_STATE *ERR_get_state(void)
399 {
400 return get_state_func();
401 }
402
403void int_ERR_set_state_func(ERR_STATE *(*get_func)(void),
404 void (*remove_func)(unsigned long pid))
405 {
406 get_state_func = get_func;
407 remove_state_func = remove_func;
408 }
409
410void ERR_remove_state(unsigned long pid)
411 {
412 if (remove_state_func)
413 remove_state_func(pid);
414 }
415
416#endif
diff --git a/src/lib/libcrypto/err/err.h b/src/lib/libcrypto/err/err.h
index dcac415231..b9f8c16d47 100644
--- a/src/lib/libcrypto/err/err.h
+++ b/src/lib/libcrypto/err/err.h
@@ -55,6 +55,59 @@
55 * copied and put under another distribution licence 55 * copied and put under another distribution licence
56 * [including the GNU Public Licence.] 56 * [including the GNU Public Licence.]
57 */ 57 */
58/* ====================================================================
59 * Copyright (c) 1998-2006 The OpenSSL Project. All rights reserved.
60 *
61 * Redistribution and use in source and binary forms, with or without
62 * modification, are permitted provided that the following conditions
63 * are met:
64 *
65 * 1. Redistributions of source code must retain the above copyright
66 * notice, this list of conditions and the following disclaimer.
67 *
68 * 2. Redistributions in binary form must reproduce the above copyright
69 * notice, this list of conditions and the following disclaimer in
70 * the documentation and/or other materials provided with the
71 * distribution.
72 *
73 * 3. All advertising materials mentioning features or use of this
74 * software must display the following acknowledgment:
75 * "This product includes software developed by the OpenSSL Project
76 * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
77 *
78 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
79 * endorse or promote products derived from this software without
80 * prior written permission. For written permission, please contact
81 * openssl-core@openssl.org.
82 *
83 * 5. Products derived from this software may not be called "OpenSSL"
84 * nor may "OpenSSL" appear in their names without prior written
85 * permission of the OpenSSL Project.
86 *
87 * 6. Redistributions of any form whatsoever must retain the following
88 * acknowledgment:
89 * "This product includes software developed by the OpenSSL Project
90 * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
91 *
92 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
93 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
94 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
95 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
96 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
97 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
98 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
99 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
100 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
101 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
102 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
103 * OF THE POSSIBILITY OF SUCH DAMAGE.
104 * ====================================================================
105 *
106 * This product includes cryptographic software written by Eric Young
107 * (eay@cryptsoft.com). This product includes software written by Tim
108 * Hudson (tjh@cryptsoft.com).
109 *
110 */
58 111
59#ifndef HEADER_ERR_H 112#ifndef HEADER_ERR_H
60#define HEADER_ERR_H 113#define HEADER_ERR_H
@@ -94,7 +147,7 @@ extern "C" {
94#define ERR_NUM_ERRORS 16 147#define ERR_NUM_ERRORS 16
95typedef struct err_state_st 148typedef struct err_state_st
96 { 149 {
97 unsigned long pid; 150 CRYPTO_THREADID tid;
98 int err_flags[ERR_NUM_ERRORS]; 151 int err_flags[ERR_NUM_ERRORS];
99 unsigned long err_buffer[ERR_NUM_ERRORS]; 152 unsigned long err_buffer[ERR_NUM_ERRORS];
100 char *err_data[ERR_NUM_ERRORS]; 153 char *err_data[ERR_NUM_ERRORS];
@@ -142,7 +195,9 @@ typedef struct err_state_st
142#define ERR_LIB_STORE 44 195#define ERR_LIB_STORE 44
143#define ERR_LIB_FIPS 45 196#define ERR_LIB_FIPS 45
144#define ERR_LIB_CMS 46 197#define ERR_LIB_CMS 46
145#define ERR_LIB_JPAKE 47 198#define ERR_LIB_TS 47
199#define ERR_LIB_HMAC 48
200#define ERR_LIB_JPAKE 49
146 201
147#define ERR_LIB_USER 128 202#define ERR_LIB_USER 128
148 203
@@ -176,6 +231,8 @@ typedef struct err_state_st
176#define STOREerr(f,r) ERR_PUT_error(ERR_LIB_STORE,(f),(r),__FILE__,__LINE__) 231#define STOREerr(f,r) ERR_PUT_error(ERR_LIB_STORE,(f),(r),__FILE__,__LINE__)
177#define FIPSerr(f,r) ERR_PUT_error(ERR_LIB_FIPS,(f),(r),__FILE__,__LINE__) 232#define FIPSerr(f,r) ERR_PUT_error(ERR_LIB_FIPS,(f),(r),__FILE__,__LINE__)
178#define CMSerr(f,r) ERR_PUT_error(ERR_LIB_CMS,(f),(r),__FILE__,__LINE__) 233#define CMSerr(f,r) ERR_PUT_error(ERR_LIB_CMS,(f),(r),__FILE__,__LINE__)
234#define TSerr(f,r) ERR_PUT_error(ERR_LIB_TS,(f),(r),__FILE__,__LINE__)
235#define HMACerr(f,r) ERR_PUT_error(ERR_LIB_HMAC,(f),(r),__FILE__,__LINE__)
179#define JPAKEerr(f,r) ERR_PUT_error(ERR_LIB_JPAKE,(f),(r),__FILE__,__LINE__) 236#define JPAKEerr(f,r) ERR_PUT_error(ERR_LIB_JPAKE,(f),(r),__FILE__,__LINE__)
180 237
181/* Borland C seems too stupid to be able to shift and do longs in 238/* Borland C seems too stupid to be able to shift and do longs in
@@ -232,6 +289,7 @@ typedef struct err_state_st
232#define ERR_R_ECDSA_LIB ERR_LIB_ECDSA /* 42 */ 289#define ERR_R_ECDSA_LIB ERR_LIB_ECDSA /* 42 */
233#define ERR_R_ECDH_LIB ERR_LIB_ECDH /* 43 */ 290#define ERR_R_ECDH_LIB ERR_LIB_ECDH /* 43 */
234#define ERR_R_STORE_LIB ERR_LIB_STORE /* 44 */ 291#define ERR_R_STORE_LIB ERR_LIB_STORE /* 44 */
292#define ERR_R_TS_LIB ERR_LIB_TS /* 45 */
235 293
236#define ERR_R_NESTED_ASN1_ERROR 58 294#define ERR_R_NESTED_ASN1_ERROR 58
237#define ERR_R_BAD_ASN1_OBJECT_HEADER 59 295#define ERR_R_BAD_ASN1_OBJECT_HEADER 59
@@ -294,13 +352,16 @@ void ERR_load_ERR_strings(void);
294void ERR_load_crypto_strings(void); 352void ERR_load_crypto_strings(void);
295void ERR_free_strings(void); 353void ERR_free_strings(void);
296 354
355void ERR_remove_thread_state(const CRYPTO_THREADID *tid);
356#ifndef OPENSSL_NO_DEPRECATED
297void ERR_remove_state(unsigned long pid); /* if zero we look it up */ 357void ERR_remove_state(unsigned long pid); /* if zero we look it up */
358#endif
298ERR_STATE *ERR_get_state(void); 359ERR_STATE *ERR_get_state(void);
299 360
300#ifndef OPENSSL_NO_LHASH 361#ifndef OPENSSL_NO_LHASH
301LHASH *ERR_get_string_table(void); 362LHASH_OF(ERR_STRING_DATA) *ERR_get_string_table(void);
302LHASH *ERR_get_err_state_table(void); 363LHASH_OF(ERR_STATE) *ERR_get_err_state_table(void);
303void ERR_release_err_state_table(LHASH **hash); 364void ERR_release_err_state_table(LHASH_OF(ERR_STATE) **hash);
304#endif 365#endif
305 366
306int ERR_get_next_error_library(void); 367int ERR_get_next_error_library(void);
@@ -308,12 +369,6 @@ int ERR_get_next_error_library(void);
308int ERR_set_mark(void); 369int ERR_set_mark(void);
309int ERR_pop_to_mark(void); 370int ERR_pop_to_mark(void);
310 371
311#ifdef OPENSSL_FIPS
312void int_ERR_set_state_func(ERR_STATE *(*get_func)(void),
313 void (*remove_func)(unsigned long pid));
314void int_ERR_lib_init(void);
315#endif
316
317/* Already defined in ossl_typ.h */ 372/* Already defined in ossl_typ.h */
318/* typedef struct st_ERR_FNS ERR_FNS; */ 373/* typedef struct st_ERR_FNS ERR_FNS; */
319/* An application can use this function and provide the return value to loaded 374/* 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 f21a5276ed..fc049e8e88 100644
--- a/src/lib/libcrypto/err/err_all.c
+++ b/src/lib/libcrypto/err/err_all.c
@@ -64,6 +64,7 @@
64#endif 64#endif
65#include <openssl/buffer.h> 65#include <openssl/buffer.h>
66#include <openssl/bio.h> 66#include <openssl/bio.h>
67#include <openssl/comp.h>
67#ifndef OPENSSL_NO_RSA 68#ifndef OPENSSL_NO_RSA
68#include <openssl/rsa.h> 69#include <openssl/rsa.h>
69#endif 70#endif
@@ -94,16 +95,14 @@
94#include <openssl/ui.h> 95#include <openssl/ui.h>
95#include <openssl/ocsp.h> 96#include <openssl/ocsp.h>
96#include <openssl/err.h> 97#include <openssl/err.h>
97#ifdef OPENSSL_FIPS 98#include <openssl/ts.h>
98#include <openssl/fips.h>
99#endif
100
101#ifndef OPENSSL_NO_CMS 99#ifndef OPENSSL_NO_CMS
102#include <openssl/cms.h> 100#include <openssl/cms.h>
103#endif 101#endif
104#ifndef OPENSSL_NO_JPAKE 102#ifndef OPENSSL_NO_JPAKE
105#include <openssl/jpake.h> 103#include <openssl/jpake.h>
106#endif 104#endif
105#include <openssl/comp.h>
107 106
108void ERR_load_crypto_strings(void) 107void ERR_load_crypto_strings(void)
109 { 108 {
@@ -127,6 +126,7 @@ void ERR_load_crypto_strings(void)
127 ERR_load_ASN1_strings(); 126 ERR_load_ASN1_strings();
128 ERR_load_CONF_strings(); 127 ERR_load_CONF_strings();
129 ERR_load_CRYPTO_strings(); 128 ERR_load_CRYPTO_strings();
129 ERR_load_COMP_strings();
130#ifndef OPENSSL_NO_EC 130#ifndef OPENSSL_NO_EC
131 ERR_load_EC_strings(); 131 ERR_load_EC_strings();
132#endif 132#endif
@@ -143,19 +143,18 @@ void ERR_load_crypto_strings(void)
143 ERR_load_PKCS12_strings(); 143 ERR_load_PKCS12_strings();
144 ERR_load_RAND_strings(); 144 ERR_load_RAND_strings();
145 ERR_load_DSO_strings(); 145 ERR_load_DSO_strings();
146 ERR_load_TS_strings();
146#ifndef OPENSSL_NO_ENGINE 147#ifndef OPENSSL_NO_ENGINE
147 ERR_load_ENGINE_strings(); 148 ERR_load_ENGINE_strings();
148#endif 149#endif
149 ERR_load_OCSP_strings(); 150 ERR_load_OCSP_strings();
150 ERR_load_UI_strings(); 151 ERR_load_UI_strings();
151#ifdef OPENSSL_FIPS
152 ERR_load_FIPS_strings();
153#endif
154#ifndef OPENSSL_NO_CMS 152#ifndef OPENSSL_NO_CMS
155 ERR_load_CMS_strings(); 153 ERR_load_CMS_strings();
156#endif 154#endif
157#ifndef OPENSSL_NO_JPAKE 155#ifndef OPENSSL_NO_JPAKE
158 ERR_load_JPAKE_strings(); 156 ERR_load_JPAKE_strings();
159#endif 157#endif
158 ERR_load_COMP_strings();
160#endif 159#endif
161 } 160 }
diff --git a/src/lib/libcrypto/err/err_prn.c b/src/lib/libcrypto/err/err_prn.c
index 4cdf342fa6..a0168ac8ed 100644
--- a/src/lib/libcrypto/err/err_prn.c
+++ b/src/lib/libcrypto/err/err_prn.c
@@ -72,21 +72,29 @@ void ERR_print_errors_cb(int (*cb)(const char *str, size_t len, void *u),
72 const char *file,*data; 72 const char *file,*data;
73 int line,flags; 73 int line,flags;
74 unsigned long es; 74 unsigned long es;
75 CRYPTO_THREADID cur;
75 76
76 es=CRYPTO_thread_id(); 77 CRYPTO_THREADID_current(&cur);
78 es=CRYPTO_THREADID_hash(&cur);
77 while ((l=ERR_get_error_line_data(&file,&line,&data,&flags)) != 0) 79 while ((l=ERR_get_error_line_data(&file,&line,&data,&flags)) != 0)
78 { 80 {
79 ERR_error_string_n(l, buf, sizeof buf); 81 ERR_error_string_n(l, buf, sizeof buf);
80 BIO_snprintf(buf2, sizeof(buf2), "%lu:%s:%s:%d:%s\n", es, buf, 82 BIO_snprintf(buf2, sizeof(buf2), "%lu:%s:%s:%d:%s\n", es, buf,
81 file, line, (flags & ERR_TXT_STRING) ? data : ""); 83 file, line, (flags & ERR_TXT_STRING) ? data : "");
82 cb(buf2, strlen(buf2), u); 84 if (cb(buf2, strlen(buf2), u) <= 0)
85 break; /* abort outputting the error report */
83 } 86 }
84 } 87 }
85 88
86#ifndef OPENSSL_NO_FP_API 89#ifndef OPENSSL_NO_FP_API
87static int print_fp(const char *str, size_t len, void *fp) 90static int print_fp(const char *str, size_t len, void *fp)
88 { 91 {
89 return fwrite(str, 1, len, fp); 92 BIO bio;
93
94 BIO_set(&bio,BIO_s_file());
95 BIO_set_fp(&bio,fp,BIO_NOCLOSE);
96
97 return BIO_printf(&bio, "%s", str);
90 } 98 }
91void ERR_print_errors_fp(FILE *fp) 99void ERR_print_errors_fp(FILE *fp)
92 { 100 {
@@ -94,64 +102,13 @@ void ERR_print_errors_fp(FILE *fp)
94 } 102 }
95#endif 103#endif
96 104
97void ERR_error_string_n(unsigned long e, char *buf, size_t len) 105static int print_bio(const char *str, size_t len, void *bp)
98 { 106 {
99 char lsbuf[64], fsbuf[64], rsbuf[64]; 107 return BIO_write((BIO *)bp, str, len);
100 const char *ls,*fs,*rs;
101 unsigned long l,f,r;
102
103 l=ERR_GET_LIB(e);
104 f=ERR_GET_FUNC(e);
105 r=ERR_GET_REASON(e);
106
107 ls=ERR_lib_error_string(e);
108 fs=ERR_func_error_string(e);
109 rs=ERR_reason_error_string(e);
110
111 if (ls == NULL)
112 BIO_snprintf(lsbuf, sizeof(lsbuf), "lib(%lu)", l);
113 if (fs == NULL)
114 BIO_snprintf(fsbuf, sizeof(fsbuf), "func(%lu)", f);
115 if (rs == NULL)
116 BIO_snprintf(rsbuf, sizeof(rsbuf), "reason(%lu)", r);
117
118 BIO_snprintf(buf, len,"error:%08lX:%s:%s:%s", e, ls?ls:lsbuf,
119 fs?fs:fsbuf, rs?rs:rsbuf);
120 if (strlen(buf) == len-1)
121 {
122 /* output may be truncated; make sure we always have 5
123 * colon-separated fields, i.e. 4 colons ... */
124#define NUM_COLONS 4
125 if (len > NUM_COLONS) /* ... if possible */
126 {
127 int i;
128 char *s = buf;
129
130 for (i = 0; i < NUM_COLONS; i++)
131 {
132 char *colon = strchr(s, ':');
133 if (colon == NULL || colon > &buf[len-1] - NUM_COLONS + i)
134 {
135 /* set colon no. i at last possible position
136 * (buf[len-1] is the terminating 0)*/
137 colon = &buf[len-1] - NUM_COLONS + i;
138 *colon = ':';
139 }
140 s = colon + 1;
141 }
142 }
143 }
144 } 108 }
145 109void ERR_print_errors(BIO *bp)
146/* BAD for multi-threading: uses a local buffer if ret == NULL */
147/* ERR_error_string_n should be used instead for ret != NULL
148 * as ERR_error_string cannot know how large the buffer is */
149char *ERR_error_string(unsigned long e, char *ret)
150 { 110 {
151 static char buf[256]; 111 ERR_print_errors_cb(print_bio, bp);
152
153 if (ret == NULL) ret=buf;
154 ERR_error_string_n(e, ret, 256);
155
156 return ret;
157 } 112 }
113
114
diff --git a/src/lib/libcrypto/err/openssl.ec b/src/lib/libcrypto/err/openssl.ec
index 868826624d..e0554b4342 100644
--- a/src/lib/libcrypto/err/openssl.ec
+++ b/src/lib/libcrypto/err/openssl.ec
@@ -31,13 +31,15 @@ L COMP crypto/comp/comp.h crypto/comp/comp_err.c
31L ECDSA crypto/ecdsa/ecdsa.h crypto/ecdsa/ecs_err.c 31L ECDSA crypto/ecdsa/ecdsa.h crypto/ecdsa/ecs_err.c
32L ECDH crypto/ecdh/ecdh.h crypto/ecdh/ech_err.c 32L ECDH crypto/ecdh/ecdh.h crypto/ecdh/ech_err.c
33L STORE crypto/store/store.h crypto/store/str_err.c 33L STORE crypto/store/store.h crypto/store/str_err.c
34L FIPS fips/fips.h crypto/fips_err.h 34L TS crypto/ts/ts.h crypto/ts/ts_err.c
35L HMAC crypto/hmac/hmac.h crypto/hmac/hmac_err.c
35L CMS crypto/cms/cms.h crypto/cms/cms_err.c 36L CMS crypto/cms/cms.h crypto/cms/cms_err.c
36L JPAKE crypto/jpake/jpake.h crypto/jpake/jpake_err.c 37L JPAKE crypto/jpake/jpake.h crypto/jpake/jpake_err.c
37 38
38# additional header files to be scanned for function names 39# additional header files to be scanned for function names
39L NONE crypto/x509/x509_vfy.h NONE 40L NONE crypto/x509/x509_vfy.h NONE
40L NONE crypto/ec/ec_lcl.h NONE 41L NONE crypto/ec/ec_lcl.h NONE
42L NONE crypto/asn1/asn_lcl.h NONE
41L NONE crypto/cms/cms_lcl.h NONE 43L NONE crypto/cms/cms_lcl.h NONE
42 44
43 45
@@ -71,6 +73,11 @@ R SSL_R_TLSV1_ALERT_INSUFFICIENT_SECURITY 1071
71R SSL_R_TLSV1_ALERT_INTERNAL_ERROR 1080 73R SSL_R_TLSV1_ALERT_INTERNAL_ERROR 1080
72R SSL_R_TLSV1_ALERT_USER_CANCELLED 1090 74R SSL_R_TLSV1_ALERT_USER_CANCELLED 1090
73R SSL_R_TLSV1_ALERT_NO_RENEGOTIATION 1100 75R SSL_R_TLSV1_ALERT_NO_RENEGOTIATION 1100
76R SSL_R_TLSV1_UNSUPPORTED_EXTENSION 1110
77R SSL_R_TLSV1_CERTIFICATE_UNOBTAINABLE 1111
78R SSL_R_TLSV1_UNRECOGNIZED_NAME 1112
79R SSL_R_TLSV1_BAD_CERTIFICATE_STATUS_RESPONSE 1113
80R SSL_R_TLSV1_BAD_CERTIFICATE_HASH_VALUE 1114
74 81
75R RSAREF_R_CONTENT_ENCODING 0x0400 82R RSAREF_R_CONTENT_ENCODING 0x0400
76R RSAREF_R_DATA 0x0401 83R RSAREF_R_DATA 0x0401
diff --git a/src/lib/libcrypto/evp/bio_b64.c b/src/lib/libcrypto/evp/bio_b64.c
index fa5cbc7eb1..72a2a67277 100644
--- a/src/lib/libcrypto/evp/bio_b64.c
+++ b/src/lib/libcrypto/evp/bio_b64.c
@@ -64,7 +64,7 @@
64 64
65static int b64_write(BIO *h, const char *buf, int num); 65static int b64_write(BIO *h, const char *buf, int num);
66static int b64_read(BIO *h, char *buf, int size); 66static int b64_read(BIO *h, char *buf, int size);
67/*static int b64_puts(BIO *h, const char *str); */ 67static int b64_puts(BIO *h, const char *str);
68/*static int b64_gets(BIO *h, char *str, int size); */ 68/*static int b64_gets(BIO *h, char *str, int size); */
69static long b64_ctrl(BIO *h, int cmd, long arg1, void *arg2); 69static long b64_ctrl(BIO *h, int cmd, long arg1, void *arg2);
70static int b64_new(BIO *h); 70static int b64_new(BIO *h);
@@ -96,7 +96,7 @@ static BIO_METHOD methods_b64=
96 BIO_TYPE_BASE64,"base64 encoding", 96 BIO_TYPE_BASE64,"base64 encoding",
97 b64_write, 97 b64_write,
98 b64_read, 98 b64_read,
99 NULL, /* b64_puts, */ 99 b64_puts,
100 NULL, /* b64_gets, */ 100 NULL, /* b64_gets, */
101 b64_ctrl, 101 b64_ctrl,
102 b64_new, 102 b64_new,
@@ -127,6 +127,7 @@ static int b64_new(BIO *bi)
127 bi->init=1; 127 bi->init=1;
128 bi->ptr=(char *)ctx; 128 bi->ptr=(char *)ctx;
129 bi->flags=0; 129 bi->flags=0;
130 bi->num = 0;
130 return(1); 131 return(1);
131 } 132 }
132 133
@@ -151,6 +152,8 @@ static int b64_read(BIO *b, char *out, int outl)
151 152
152 if ((ctx == NULL) || (b->next_bio == NULL)) return(0); 153 if ((ctx == NULL) || (b->next_bio == NULL)) return(0);
153 154
155 BIO_clear_retry_flags(b);
156
154 if (ctx->encode != B64_DECODE) 157 if (ctx->encode != B64_DECODE)
155 { 158 {
156 ctx->encode=B64_DECODE; 159 ctx->encode=B64_DECODE;
@@ -163,6 +166,7 @@ static int b64_read(BIO *b, char *out, int outl)
163 /* First check if there are bytes decoded/encoded */ 166 /* First check if there are bytes decoded/encoded */
164 if (ctx->buf_len > 0) 167 if (ctx->buf_len > 0)
165 { 168 {
169 OPENSSL_assert(ctx->buf_len >= ctx->buf_off);
166 i=ctx->buf_len-ctx->buf_off; 170 i=ctx->buf_len-ctx->buf_off;
167 if (i > outl) i=outl; 171 if (i > outl) i=outl;
168 OPENSSL_assert(ctx->buf_off+i < (int)sizeof(ctx->buf)); 172 OPENSSL_assert(ctx->buf_off+i < (int)sizeof(ctx->buf));
@@ -184,7 +188,6 @@ static int b64_read(BIO *b, char *out, int outl)
184 ret_code=0; 188 ret_code=0;
185 while (outl > 0) 189 while (outl > 0)
186 { 190 {
187
188 if (ctx->cont <= 0) 191 if (ctx->cont <= 0)
189 break; 192 break;
190 193
@@ -195,7 +198,7 @@ static int b64_read(BIO *b, char *out, int outl)
195 { 198 {
196 ret_code=i; 199 ret_code=i;
197 200
198 /* Should be continue next time we are called? */ 201 /* Should we continue next time we are called? */
199 if (!BIO_should_retry(b->next_bio)) 202 if (!BIO_should_retry(b->next_bio))
200 { 203 {
201 ctx->cont=i; 204 ctx->cont=i;
@@ -285,19 +288,27 @@ static int b64_read(BIO *b, char *out, int outl)
285 continue; 288 continue;
286 } 289 }
287 else 290 else
291 {
288 ctx->tmp_len=0; 292 ctx->tmp_len=0;
289 } 293 }
290 /* If buffer isn't full and we can retry then 294 }
291 * restart to read in more data.
292 */
293 else if ((i < B64_BLOCK_SIZE) && (ctx->cont > 0)) 295 else if ((i < B64_BLOCK_SIZE) && (ctx->cont > 0))
296 {
297 /* If buffer isn't full and we can retry then
298 * restart to read in more data.
299 */
294 continue; 300 continue;
301 }
295 302
296 if (BIO_get_flags(b) & BIO_FLAGS_BASE64_NO_NL) 303 if (BIO_get_flags(b) & BIO_FLAGS_BASE64_NO_NL)
297 { 304 {
298 int z,jj; 305 int z,jj;
299 306
307#if 0
300 jj=(i>>2)<<2; 308 jj=(i>>2)<<2;
309#else
310 jj = i & ~3; /* process per 4 */
311#endif
301 z=EVP_DecodeBlock((unsigned char *)ctx->buf, 312 z=EVP_DecodeBlock((unsigned char *)ctx->buf,
302 (unsigned char *)ctx->tmp,jj); 313 (unsigned char *)ctx->tmp,jj);
303 if (jj > 2) 314 if (jj > 2)
@@ -313,18 +324,15 @@ static int b64_read(BIO *b, char *out, int outl)
313 * number consumed */ 324 * number consumed */
314 if (jj != i) 325 if (jj != i)
315 { 326 {
316 memcpy((unsigned char *)ctx->tmp, 327 memmove(ctx->tmp, &ctx->tmp[jj], i-jj);
317 (unsigned char *)&(ctx->tmp[jj]),i-jj);
318 ctx->tmp_len=i-jj; 328 ctx->tmp_len=i-jj;
319 } 329 }
320 ctx->buf_len=0; 330 ctx->buf_len=0;
321 if (z > 0) 331 if (z > 0)
322 { 332 {
323 ctx->buf_len=z; 333 ctx->buf_len=z;
324 i=1;
325 } 334 }
326 else 335 i=z;
327 i=z;
328 } 336 }
329 else 337 else
330 { 338 {
@@ -357,14 +365,16 @@ static int b64_read(BIO *b, char *out, int outl)
357 outl-=i; 365 outl-=i;
358 out+=i; 366 out+=i;
359 } 367 }
360 BIO_clear_retry_flags(b); 368 /* BIO_clear_retry_flags(b); */
361 BIO_copy_next_retry(b); 369 BIO_copy_next_retry(b);
362 return((ret == 0)?ret_code:ret); 370 return((ret == 0)?ret_code:ret);
363 } 371 }
364 372
365static int b64_write(BIO *b, const char *in, int inl) 373static int b64_write(BIO *b, const char *in, int inl)
366 { 374 {
367 int ret=inl,n,i; 375 int ret=0;
376 int n;
377 int i;
368 BIO_B64_CTX *ctx; 378 BIO_B64_CTX *ctx;
369 379
370 ctx=(BIO_B64_CTX *)b->ptr; 380 ctx=(BIO_B64_CTX *)b->ptr;
@@ -379,6 +389,9 @@ static int b64_write(BIO *b, const char *in, int inl)
379 EVP_EncodeInit(&(ctx->base64)); 389 EVP_EncodeInit(&(ctx->base64));
380 } 390 }
381 391
392 OPENSSL_assert(ctx->buf_off < (int)sizeof(ctx->buf));
393 OPENSSL_assert(ctx->buf_len <= (int)sizeof(ctx->buf));
394 OPENSSL_assert(ctx->buf_len >= ctx->buf_off);
382 n=ctx->buf_len-ctx->buf_off; 395 n=ctx->buf_len-ctx->buf_off;
383 while (n > 0) 396 while (n > 0)
384 { 397 {
@@ -388,7 +401,10 @@ static int b64_write(BIO *b, const char *in, int inl)
388 BIO_copy_next_retry(b); 401 BIO_copy_next_retry(b);
389 return(i); 402 return(i);
390 } 403 }
404 OPENSSL_assert(i <= n);
391 ctx->buf_off+=i; 405 ctx->buf_off+=i;
406 OPENSSL_assert(ctx->buf_off <= (int)sizeof(ctx->buf));
407 OPENSSL_assert(ctx->buf_len >= ctx->buf_off);
392 n-=i; 408 n-=i;
393 } 409 }
394 /* at this point all pending data has been written */ 410 /* at this point all pending data has been written */
@@ -405,18 +421,19 @@ static int b64_write(BIO *b, const char *in, int inl)
405 { 421 {
406 if (ctx->tmp_len > 0) 422 if (ctx->tmp_len > 0)
407 { 423 {
424 OPENSSL_assert(ctx->tmp_len <= 3);
408 n=3-ctx->tmp_len; 425 n=3-ctx->tmp_len;
409 /* There's a teoretical possibility for this */ 426 /* There's a theoretical possibility for this */
410 if (n > inl) 427 if (n > inl)
411 n=inl; 428 n=inl;
412 memcpy(&(ctx->tmp[ctx->tmp_len]),in,n); 429 memcpy(&(ctx->tmp[ctx->tmp_len]),in,n);
413 ctx->tmp_len+=n; 430 ctx->tmp_len+=n;
431 ret += n;
414 if (ctx->tmp_len < 3) 432 if (ctx->tmp_len < 3)
415 break; 433 break;
416 ctx->buf_len=EVP_EncodeBlock( 434 ctx->buf_len=EVP_EncodeBlock((unsigned char *)ctx->buf,(unsigned char *)ctx->tmp,ctx->tmp_len);
417 (unsigned char *)ctx->buf, 435 OPENSSL_assert(ctx->buf_len <= (int)sizeof(ctx->buf));
418 (unsigned char *)ctx->tmp, 436 OPENSSL_assert(ctx->buf_len >= ctx->buf_off);
419 ctx->tmp_len);
420 /* Since we're now done using the temporary 437 /* Since we're now done using the temporary
421 buffer, the length should be 0'd */ 438 buffer, the length should be 0'd */
422 ctx->tmp_len=0; 439 ctx->tmp_len=0;
@@ -425,14 +442,16 @@ static int b64_write(BIO *b, const char *in, int inl)
425 { 442 {
426 if (n < 3) 443 if (n < 3)
427 { 444 {
428 memcpy(&(ctx->tmp[0]),in,n); 445 memcpy(ctx->tmp,in,n);
429 ctx->tmp_len=n; 446 ctx->tmp_len=n;
447 ret += n;
430 break; 448 break;
431 } 449 }
432 n-=n%3; 450 n-=n%3;
433 ctx->buf_len=EVP_EncodeBlock( 451 ctx->buf_len=EVP_EncodeBlock((unsigned char *)ctx->buf,(const unsigned char *)in,n);
434 (unsigned char *)ctx->buf, 452 OPENSSL_assert(ctx->buf_len <= (int)sizeof(ctx->buf));
435 (unsigned char *)in,n); 453 OPENSSL_assert(ctx->buf_len >= ctx->buf_off);
454 ret += n;
436 } 455 }
437 } 456 }
438 else 457 else
@@ -440,6 +459,9 @@ static int b64_write(BIO *b, const char *in, int inl)
440 EVP_EncodeUpdate(&(ctx->base64), 459 EVP_EncodeUpdate(&(ctx->base64),
441 (unsigned char *)ctx->buf,&ctx->buf_len, 460 (unsigned char *)ctx->buf,&ctx->buf_len,
442 (unsigned char *)in,n); 461 (unsigned char *)in,n);
462 OPENSSL_assert(ctx->buf_len <= (int)sizeof(ctx->buf));
463 OPENSSL_assert(ctx->buf_len >= ctx->buf_off);
464 ret += n;
443 } 465 }
444 inl-=n; 466 inl-=n;
445 in+=n; 467 in+=n;
@@ -454,8 +476,11 @@ static int b64_write(BIO *b, const char *in, int inl)
454 BIO_copy_next_retry(b); 476 BIO_copy_next_retry(b);
455 return((ret == 0)?i:ret); 477 return((ret == 0)?i:ret);
456 } 478 }
479 OPENSSL_assert(i <= n);
457 n-=i; 480 n-=i;
458 ctx->buf_off+=i; 481 ctx->buf_off+=i;
482 OPENSSL_assert(ctx->buf_off <= (int)sizeof(ctx->buf));
483 OPENSSL_assert(ctx->buf_len >= ctx->buf_off);
459 } 484 }
460 ctx->buf_len=0; 485 ctx->buf_len=0;
461 ctx->buf_off=0; 486 ctx->buf_off=0;
@@ -486,6 +511,7 @@ static long b64_ctrl(BIO *b, int cmd, long num, void *ptr)
486 ret=BIO_ctrl(b->next_bio,cmd,num,ptr); 511 ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
487 break; 512 break;
488 case BIO_CTRL_WPENDING: /* More to write in buffer */ 513 case BIO_CTRL_WPENDING: /* More to write in buffer */
514 OPENSSL_assert(ctx->buf_len >= ctx->buf_off);
489 ret=ctx->buf_len-ctx->buf_off; 515 ret=ctx->buf_len-ctx->buf_off;
490 if ((ret == 0) && (ctx->encode != B64_NONE) 516 if ((ret == 0) && (ctx->encode != B64_NONE)
491 && (ctx->base64.num != 0)) 517 && (ctx->base64.num != 0))
@@ -494,6 +520,7 @@ static long b64_ctrl(BIO *b, int cmd, long num, void *ptr)
494 ret=BIO_ctrl(b->next_bio,cmd,num,ptr); 520 ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
495 break; 521 break;
496 case BIO_CTRL_PENDING: /* More to read in buffer */ 522 case BIO_CTRL_PENDING: /* More to read in buffer */
523 OPENSSL_assert(ctx->buf_len >= ctx->buf_off);
497 ret=ctx->buf_len-ctx->buf_off; 524 ret=ctx->buf_len-ctx->buf_off;
498 if (ret <= 0) 525 if (ret <= 0)
499 ret=BIO_ctrl(b->next_bio,cmd,num,ptr); 526 ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
@@ -565,3 +592,7 @@ static long b64_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp)
565 return(ret); 592 return(ret);
566 } 593 }
567 594
595static int b64_puts(BIO *b, const char *str)
596 {
597 return b64_write(b,str,strlen(str));
598 }
diff --git a/src/lib/libcrypto/evp/bio_enc.c b/src/lib/libcrypto/evp/bio_enc.c
index f6ac94c6e1..b6efb5fbc4 100644
--- a/src/lib/libcrypto/evp/bio_enc.c
+++ b/src/lib/libcrypto/evp/bio_enc.c
@@ -361,8 +361,10 @@ again:
361 case BIO_CTRL_DUP: 361 case BIO_CTRL_DUP:
362 dbio=(BIO *)ptr; 362 dbio=(BIO *)ptr;
363 dctx=(BIO_ENC_CTX *)dbio->ptr; 363 dctx=(BIO_ENC_CTX *)dbio->ptr;
364 memcpy(&(dctx->cipher),&(ctx->cipher),sizeof(ctx->cipher)); 364 EVP_CIPHER_CTX_init(&dctx->cipher);
365 dbio->init=1; 365 ret = EVP_CIPHER_CTX_copy(&dctx->cipher,&ctx->cipher);
366 if (ret)
367 dbio->init=1;
366 break; 368 break;
367 default: 369 default:
368 ret=BIO_ctrl(b->next_bio,cmd,num,ptr); 370 ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
diff --git a/src/lib/libcrypto/evp/bio_md.c b/src/lib/libcrypto/evp/bio_md.c
index ed5c1135fd..9841e32e1a 100644
--- a/src/lib/libcrypto/evp/bio_md.c
+++ b/src/lib/libcrypto/evp/bio_md.c
@@ -130,8 +130,8 @@ static int md_read(BIO *b, char *out, int outl)
130 { 130 {
131 if (ret > 0) 131 if (ret > 0)
132 { 132 {
133 EVP_DigestUpdate(ctx,(unsigned char *)out, 133 if (EVP_DigestUpdate(ctx,(unsigned char *)out,
134 (unsigned int)ret); 134 (unsigned int)ret)<=0) return (-1);
135 } 135 }
136 } 136 }
137 BIO_clear_retry_flags(b); 137 BIO_clear_retry_flags(b);
@@ -157,8 +157,11 @@ static int md_write(BIO *b, const char *in, int inl)
157 (unsigned int)ret); 157 (unsigned int)ret);
158 } 158 }
159 } 159 }
160 BIO_clear_retry_flags(b); 160 if(b->next_bio != NULL)
161 BIO_copy_next_retry(b); 161 {
162 BIO_clear_retry_flags(b);
163 BIO_copy_next_retry(b);
164 }
162 return(ret); 165 return(ret);
163 } 166 }
164 167
@@ -194,6 +197,7 @@ static long md_ctrl(BIO *b, int cmd, long num, void *ptr)
194 case BIO_C_GET_MD_CTX: 197 case BIO_C_GET_MD_CTX:
195 pctx=ptr; 198 pctx=ptr;
196 *pctx=ctx; 199 *pctx=ctx;
200 b->init = 1;
197 break; 201 break;
198 case BIO_C_SET_MD_CTX: 202 case BIO_C_SET_MD_CTX:
199 if (b->init) 203 if (b->init)
@@ -249,7 +253,9 @@ static int md_gets(BIO *bp, char *buf, int size)
249 ctx=bp->ptr; 253 ctx=bp->ptr;
250 if (size < ctx->digest->md_size) 254 if (size < ctx->digest->md_size)
251 return(0); 255 return(0);
252 EVP_DigestFinal_ex(ctx,(unsigned char *)buf,&ret); 256 if (EVP_DigestFinal_ex(ctx,(unsigned char *)buf,&ret)<=0)
257 return -1;
258
253 return((int)ret); 259 return((int)ret);
254 } 260 }
255 261
diff --git a/src/lib/libcrypto/evp/c_all.c b/src/lib/libcrypto/evp/c_all.c
index a5da52e62d..766c4cecdf 100644
--- a/src/lib/libcrypto/evp/c_all.c
+++ b/src/lib/libcrypto/evp/c_all.c
@@ -83,7 +83,7 @@ void OPENSSL_add_all_algorithms_noconf(void)
83 OpenSSL_add_all_ciphers(); 83 OpenSSL_add_all_ciphers();
84 OpenSSL_add_all_digests(); 84 OpenSSL_add_all_digests();
85#ifndef OPENSSL_NO_ENGINE 85#ifndef OPENSSL_NO_ENGINE
86# if defined(__OpenBSD__) || defined(__FreeBSD__) 86# if defined(__OpenBSD__) || defined(__FreeBSD__) || defined(HAVE_CRYPTODEV)
87 ENGINE_setup_bsd_cryptodev(); 87 ENGINE_setup_bsd_cryptodev();
88# endif 88# endif
89#endif 89#endif
diff --git a/src/lib/libcrypto/evp/digest.c b/src/lib/libcrypto/evp/digest.c
index 3bc2d1295c..982ba2b136 100644
--- a/src/lib/libcrypto/evp/digest.c
+++ b/src/lib/libcrypto/evp/digest.c
@@ -116,7 +116,6 @@
116#ifndef OPENSSL_NO_ENGINE 116#ifndef OPENSSL_NO_ENGINE
117#include <openssl/engine.h> 117#include <openssl/engine.h>
118#endif 118#endif
119#include "evp_locl.h"
120 119
121void EVP_MD_CTX_init(EVP_MD_CTX *ctx) 120void EVP_MD_CTX_init(EVP_MD_CTX *ctx)
122 { 121 {
@@ -127,7 +126,8 @@ EVP_MD_CTX *EVP_MD_CTX_create(void)
127 { 126 {
128 EVP_MD_CTX *ctx=OPENSSL_malloc(sizeof *ctx); 127 EVP_MD_CTX *ctx=OPENSSL_malloc(sizeof *ctx);
129 128
130 EVP_MD_CTX_init(ctx); 129 if (ctx)
130 EVP_MD_CTX_init(ctx);
131 131
132 return ctx; 132 return ctx;
133 } 133 }
@@ -138,77 +138,18 @@ int EVP_DigestInit(EVP_MD_CTX *ctx, const EVP_MD *type)
138 return EVP_DigestInit_ex(ctx, type, NULL); 138 return EVP_DigestInit_ex(ctx, type, NULL);
139 } 139 }
140 140
141#ifdef OPENSSL_FIPS 141int EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *impl)
142
143/* The purpose of these is to trap programs that attempt to use non FIPS
144 * algorithms in FIPS mode and ignore the errors.
145 */
146
147static int bad_init(EVP_MD_CTX *ctx)
148 { FIPS_ERROR_IGNORED("Digest init"); return 0;}
149
150static int bad_update(EVP_MD_CTX *ctx,const void *data,size_t count)
151 { FIPS_ERROR_IGNORED("Digest update"); return 0;}
152
153static int bad_final(EVP_MD_CTX *ctx,unsigned char *md)
154 { FIPS_ERROR_IGNORED("Digest Final"); return 0;}
155
156static const EVP_MD bad_md =
157 { 142 {
158 0, 143 EVP_MD_CTX_clear_flags(ctx,EVP_MD_CTX_FLAG_CLEANED);
159 0,
160 0,
161 0,
162 bad_init,
163 bad_update,
164 bad_final,
165 NULL,
166 NULL,
167 NULL,
168 0,
169 {0,0,0,0},
170 };
171
172#endif
173
174#ifndef OPENSSL_NO_ENGINE 144#ifndef OPENSSL_NO_ENGINE
175 145 /* Whether it's nice or not, "Inits" can be used on "Final"'d contexts
176#ifdef OPENSSL_FIPS 146 * so this context may already have an ENGINE! Try to avoid releasing
177 147 * the previous handle, re-querying for an ENGINE, and having a
178static int do_engine_null(ENGINE *impl) { return 0;} 148 * reinitialisation, when it may all be unecessary. */
179static int do_evp_md_engine_null(EVP_MD_CTX *ctx, 149 if (ctx->engine && ctx->digest && (!type ||
180 const EVP_MD **ptype, ENGINE *impl) 150 (type && (type->type == ctx->digest->type))))
181 { return 1; } 151 goto skip_to_init;
182 152 if (type)
183static int (*do_engine_init)(ENGINE *impl)
184 = do_engine_null;
185
186static int (*do_engine_finish)(ENGINE *impl)
187 = do_engine_null;
188
189static int (*do_evp_md_engine)
190 (EVP_MD_CTX *ctx, const EVP_MD **ptype, ENGINE *impl)
191 = do_evp_md_engine_null;
192
193void int_EVP_MD_set_engine_callbacks(
194 int (*eng_md_init)(ENGINE *impl),
195 int (*eng_md_fin)(ENGINE *impl),
196 int (*eng_md_evp)
197 (EVP_MD_CTX *ctx, const EVP_MD **ptype, ENGINE *impl))
198 {
199 do_engine_init = eng_md_init;
200 do_engine_finish = eng_md_fin;
201 do_evp_md_engine = eng_md_evp;
202 }
203
204#else
205
206#define do_engine_init ENGINE_init
207#define do_engine_finish ENGINE_finish
208
209static int do_evp_md_engine(EVP_MD_CTX *ctx, const EVP_MD **ptype, ENGINE *impl)
210 {
211 if (*ptype)
212 { 153 {
213 /* Ensure an ENGINE left lying around from last time is cleared 154 /* Ensure an ENGINE left lying around from last time is cleared
214 * (the previous check attempted to avoid this if the same 155 * (the previous check attempted to avoid this if the same
@@ -219,25 +160,26 @@ static int do_evp_md_engine(EVP_MD_CTX *ctx, const EVP_MD **ptype, ENGINE *impl)
219 { 160 {
220 if (!ENGINE_init(impl)) 161 if (!ENGINE_init(impl))
221 { 162 {
222 EVPerr(EVP_F_DO_EVP_MD_ENGINE,EVP_R_INITIALIZATION_ERROR); 163 EVPerr(EVP_F_EVP_DIGESTINIT_EX,EVP_R_INITIALIZATION_ERROR);
223 return 0; 164 return 0;
224 } 165 }
225 } 166 }
226 else 167 else
227 /* Ask if an ENGINE is reserved for this job */ 168 /* Ask if an ENGINE is reserved for this job */
228 impl = ENGINE_get_digest_engine((*ptype)->type); 169 impl = ENGINE_get_digest_engine(type->type);
229 if(impl) 170 if(impl)
230 { 171 {
231 /* There's an ENGINE for this job ... (apparently) */ 172 /* There's an ENGINE for this job ... (apparently) */
232 const EVP_MD *d = ENGINE_get_digest(impl, (*ptype)->type); 173 const EVP_MD *d = ENGINE_get_digest(impl, type->type);
233 if(!d) 174 if(!d)
234 { 175 {
235 /* Same comment from evp_enc.c */ 176 /* Same comment from evp_enc.c */
236 EVPerr(EVP_F_DO_EVP_MD_ENGINE,EVP_R_INITIALIZATION_ERROR); 177 EVPerr(EVP_F_EVP_DIGESTINIT_EX,EVP_R_INITIALIZATION_ERROR);
178 ENGINE_finish(impl);
237 return 0; 179 return 0;
238 } 180 }
239 /* We'll use the ENGINE's private digest definition */ 181 /* We'll use the ENGINE's private digest definition */
240 *ptype = d; 182 type = d;
241 /* Store the ENGINE functional reference so we know 183 /* Store the ENGINE functional reference so we know
242 * 'type' came from an ENGINE and we need to release 184 * 'type' came from an ENGINE and we need to release
243 * it when done. */ 185 * it when done. */
@@ -249,71 +191,46 @@ static int do_evp_md_engine(EVP_MD_CTX *ctx, const EVP_MD **ptype, ENGINE *impl)
249 else 191 else
250 if(!ctx->digest) 192 if(!ctx->digest)
251 { 193 {
252 EVPerr(EVP_F_DO_EVP_MD_ENGINE,EVP_R_NO_DIGEST_SET); 194 EVPerr(EVP_F_EVP_DIGESTINIT_EX,EVP_R_NO_DIGEST_SET);
253 return 0; 195 return 0;
254 } 196 }
255 return 1;
256 }
257
258#endif
259
260#endif
261
262int EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *impl)
263 {
264 M_EVP_MD_CTX_clear_flags(ctx,EVP_MD_CTX_FLAG_CLEANED);
265#ifdef OPENSSL_FIPS
266 if(FIPS_selftest_failed())
267 {
268 FIPSerr(FIPS_F_EVP_DIGESTINIT_EX,FIPS_R_FIPS_SELFTEST_FAILED);
269 ctx->digest = &bad_md;
270 return 0;
271 }
272#endif
273#ifndef OPENSSL_NO_ENGINE
274 /* Whether it's nice or not, "Inits" can be used on "Final"'d contexts
275 * so this context may already have an ENGINE! Try to avoid releasing
276 * the previous handle, re-querying for an ENGINE, and having a
277 * reinitialisation, when it may all be unecessary. */
278 if (ctx->engine && ctx->digest && (!type ||
279 (type && (type->type == ctx->digest->type))))
280 goto skip_to_init;
281 if (!do_evp_md_engine(ctx, &type, impl))
282 return 0;
283#endif 197#endif
284 if (ctx->digest != type) 198 if (ctx->digest != type)
285 { 199 {
286#ifdef OPENSSL_FIPS 200 if (ctx->digest && ctx->digest->ctx_size)
287 if (FIPS_mode()) 201 OPENSSL_free(ctx->md_data);
202 ctx->digest=type;
203 if (!(ctx->flags & EVP_MD_CTX_FLAG_NO_INIT) && type->ctx_size)
288 { 204 {
289 if (!(type->flags & EVP_MD_FLAG_FIPS) 205 ctx->update = type->update;
290 && !(ctx->flags & EVP_MD_CTX_FLAG_NON_FIPS_ALLOW)) 206 ctx->md_data=OPENSSL_malloc(type->ctx_size);
207 if (ctx->md_data == NULL)
291 { 208 {
292 EVPerr(EVP_F_EVP_DIGESTINIT_EX, EVP_R_DISABLED_FOR_FIPS); 209 EVPerr(EVP_F_EVP_DIGESTINIT_EX,
293 ctx->digest = &bad_md; 210 ERR_R_MALLOC_FAILURE);
294 return 0; 211 return 0;
295 } 212 }
296 } 213 }
297#endif
298 if (ctx->digest && ctx->digest->ctx_size)
299 OPENSSL_free(ctx->md_data);
300 ctx->digest=type;
301 if (type->ctx_size)
302 ctx->md_data=OPENSSL_malloc(type->ctx_size);
303 } 214 }
304#ifndef OPENSSL_NO_ENGINE 215#ifndef OPENSSL_NO_ENGINE
305 skip_to_init: 216skip_to_init:
306#endif 217#endif
218 if (ctx->pctx)
219 {
220 int r;
221 r = EVP_PKEY_CTX_ctrl(ctx->pctx, -1, EVP_PKEY_OP_TYPE_SIG,
222 EVP_PKEY_CTRL_DIGESTINIT, 0, ctx);
223 if (r <= 0 && (r != -2))
224 return 0;
225 }
226 if (ctx->flags & EVP_MD_CTX_FLAG_NO_INIT)
227 return 1;
307 return ctx->digest->init(ctx); 228 return ctx->digest->init(ctx);
308 } 229 }
309 230
310int EVP_DigestUpdate(EVP_MD_CTX *ctx, const void *data, 231int EVP_DigestUpdate(EVP_MD_CTX *ctx, const void *data, size_t count)
311 size_t count)
312 { 232 {
313#ifdef OPENSSL_FIPS 233 return ctx->update(ctx,data,count);
314 FIPS_selftest_check();
315#endif
316 return ctx->digest->update(ctx,data,count);
317 } 234 }
318 235
319/* The caller can assume that this removes any secret data from the context */ 236/* The caller can assume that this removes any secret data from the context */
@@ -329,9 +246,6 @@ int EVP_DigestFinal(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *size)
329int EVP_DigestFinal_ex(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *size) 246int EVP_DigestFinal_ex(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *size)
330 { 247 {
331 int ret; 248 int ret;
332#ifdef OPENSSL_FIPS
333 FIPS_selftest_check();
334#endif
335 249
336 OPENSSL_assert(ctx->digest->md_size <= EVP_MAX_MD_SIZE); 250 OPENSSL_assert(ctx->digest->md_size <= EVP_MAX_MD_SIZE);
337 ret=ctx->digest->final(ctx,md); 251 ret=ctx->digest->final(ctx,md);
@@ -340,7 +254,7 @@ int EVP_DigestFinal_ex(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *size)
340 if (ctx->digest->cleanup) 254 if (ctx->digest->cleanup)
341 { 255 {
342 ctx->digest->cleanup(ctx); 256 ctx->digest->cleanup(ctx);
343 M_EVP_MD_CTX_set_flags(ctx,EVP_MD_CTX_FLAG_CLEANED); 257 EVP_MD_CTX_set_flags(ctx,EVP_MD_CTX_FLAG_CLEANED);
344 } 258 }
345 memset(ctx->md_data,0,ctx->digest->ctx_size); 259 memset(ctx->md_data,0,ctx->digest->ctx_size);
346 return ret; 260 return ret;
@@ -362,7 +276,7 @@ int EVP_MD_CTX_copy_ex(EVP_MD_CTX *out, const EVP_MD_CTX *in)
362 } 276 }
363#ifndef OPENSSL_NO_ENGINE 277#ifndef OPENSSL_NO_ENGINE
364 /* Make sure it's safe to copy a digest context using an ENGINE */ 278 /* Make sure it's safe to copy a digest context using an ENGINE */
365 if (in->engine && !do_engine_init(in->engine)) 279 if (in->engine && !ENGINE_init(in->engine))
366 { 280 {
367 EVPerr(EVP_F_EVP_MD_CTX_COPY_EX,ERR_R_ENGINE_LIB); 281 EVPerr(EVP_F_EVP_MD_CTX_COPY_EX,ERR_R_ENGINE_LIB);
368 return 0; 282 return 0;
@@ -372,19 +286,40 @@ int EVP_MD_CTX_copy_ex(EVP_MD_CTX *out, const EVP_MD_CTX *in)
372 if (out->digest == in->digest) 286 if (out->digest == in->digest)
373 { 287 {
374 tmp_buf = out->md_data; 288 tmp_buf = out->md_data;
375 M_EVP_MD_CTX_set_flags(out,EVP_MD_CTX_FLAG_REUSE); 289 EVP_MD_CTX_set_flags(out,EVP_MD_CTX_FLAG_REUSE);
376 } 290 }
377 else tmp_buf = NULL; 291 else tmp_buf = NULL;
378 EVP_MD_CTX_cleanup(out); 292 EVP_MD_CTX_cleanup(out);
379 memcpy(out,in,sizeof *out); 293 memcpy(out,in,sizeof *out);
380 294
381 if (out->digest->ctx_size) 295 if (in->md_data && out->digest->ctx_size)
382 { 296 {
383 if (tmp_buf) out->md_data = tmp_buf; 297 if (tmp_buf)
384 else out->md_data=OPENSSL_malloc(out->digest->ctx_size); 298 out->md_data = tmp_buf;
299 else
300 {
301 out->md_data=OPENSSL_malloc(out->digest->ctx_size);
302 if (!out->md_data)
303 {
304 EVPerr(EVP_F_EVP_MD_CTX_COPY_EX,ERR_R_MALLOC_FAILURE);
305 return 0;
306 }
307 }
385 memcpy(out->md_data,in->md_data,out->digest->ctx_size); 308 memcpy(out->md_data,in->md_data,out->digest->ctx_size);
386 } 309 }
387 310
311 out->update = in->update;
312
313 if (in->pctx)
314 {
315 out->pctx = EVP_PKEY_CTX_dup(in->pctx);
316 if (!out->pctx)
317 {
318 EVP_MD_CTX_cleanup(out);
319 return 0;
320 }
321 }
322
388 if (out->digest->copy) 323 if (out->digest->copy)
389 return out->digest->copy(out,in); 324 return out->digest->copy(out,in);
390 325
@@ -398,7 +333,7 @@ int EVP_Digest(const void *data, size_t count,
398 int ret; 333 int ret;
399 334
400 EVP_MD_CTX_init(&ctx); 335 EVP_MD_CTX_init(&ctx);
401 M_EVP_MD_CTX_set_flags(&ctx,EVP_MD_CTX_FLAG_ONESHOT); 336 EVP_MD_CTX_set_flags(&ctx,EVP_MD_CTX_FLAG_ONESHOT);
402 ret=EVP_DigestInit_ex(&ctx, type, impl) 337 ret=EVP_DigestInit_ex(&ctx, type, impl)
403 && EVP_DigestUpdate(&ctx, data, count) 338 && EVP_DigestUpdate(&ctx, data, count)
404 && EVP_DigestFinal_ex(&ctx, md, size); 339 && EVP_DigestFinal_ex(&ctx, md, size);
@@ -420,19 +355,21 @@ int EVP_MD_CTX_cleanup(EVP_MD_CTX *ctx)
420 * because sometimes only copies of the context are ever finalised. 355 * because sometimes only copies of the context are ever finalised.
421 */ 356 */
422 if (ctx->digest && ctx->digest->cleanup 357 if (ctx->digest && ctx->digest->cleanup
423 && !M_EVP_MD_CTX_test_flags(ctx,EVP_MD_CTX_FLAG_CLEANED)) 358 && !EVP_MD_CTX_test_flags(ctx,EVP_MD_CTX_FLAG_CLEANED))
424 ctx->digest->cleanup(ctx); 359 ctx->digest->cleanup(ctx);
425 if (ctx->digest && ctx->digest->ctx_size && ctx->md_data 360 if (ctx->digest && ctx->digest->ctx_size && ctx->md_data
426 && !M_EVP_MD_CTX_test_flags(ctx, EVP_MD_CTX_FLAG_REUSE)) 361 && !EVP_MD_CTX_test_flags(ctx, EVP_MD_CTX_FLAG_REUSE))
427 { 362 {
428 OPENSSL_cleanse(ctx->md_data,ctx->digest->ctx_size); 363 OPENSSL_cleanse(ctx->md_data,ctx->digest->ctx_size);
429 OPENSSL_free(ctx->md_data); 364 OPENSSL_free(ctx->md_data);
430 } 365 }
366 if (ctx->pctx)
367 EVP_PKEY_CTX_free(ctx->pctx);
431#ifndef OPENSSL_NO_ENGINE 368#ifndef OPENSSL_NO_ENGINE
432 if(ctx->engine) 369 if(ctx->engine)
433 /* The EVP_MD we used belongs to an ENGINE, release the 370 /* The EVP_MD we used belongs to an ENGINE, release the
434 * functional reference we held for this reason. */ 371 * functional reference we held for this reason. */
435 do_engine_finish(ctx->engine); 372 ENGINE_finish(ctx->engine);
436#endif 373#endif
437 memset(ctx,'\0',sizeof *ctx); 374 memset(ctx,'\0',sizeof *ctx);
438 375
diff --git a/src/lib/libcrypto/evp/e_aes.c b/src/lib/libcrypto/evp/e_aes.c
index c9a5ee8d75..bd6c0a3a62 100644
--- a/src/lib/libcrypto/evp/e_aes.c
+++ b/src/lib/libcrypto/evp/e_aes.c
@@ -69,29 +69,32 @@ typedef struct
69 69
70IMPLEMENT_BLOCK_CIPHER(aes_128, ks, AES, EVP_AES_KEY, 70IMPLEMENT_BLOCK_CIPHER(aes_128, ks, AES, EVP_AES_KEY,
71 NID_aes_128, 16, 16, 16, 128, 71 NID_aes_128, 16, 16, 16, 128,
72 EVP_CIPH_FLAG_FIPS|EVP_CIPH_FLAG_DEFAULT_ASN1, 72 0, aes_init_key, NULL,
73 aes_init_key, 73 EVP_CIPHER_set_asn1_iv,
74 NULL, NULL, NULL, NULL) 74 EVP_CIPHER_get_asn1_iv,
75 NULL)
75IMPLEMENT_BLOCK_CIPHER(aes_192, ks, AES, EVP_AES_KEY, 76IMPLEMENT_BLOCK_CIPHER(aes_192, ks, AES, EVP_AES_KEY,
76 NID_aes_192, 16, 24, 16, 128, 77 NID_aes_192, 16, 24, 16, 128,
77 EVP_CIPH_FLAG_FIPS|EVP_CIPH_FLAG_DEFAULT_ASN1, 78 0, aes_init_key, NULL,
78 aes_init_key, 79 EVP_CIPHER_set_asn1_iv,
79 NULL, NULL, NULL, NULL) 80 EVP_CIPHER_get_asn1_iv,
81 NULL)
80IMPLEMENT_BLOCK_CIPHER(aes_256, ks, AES, EVP_AES_KEY, 82IMPLEMENT_BLOCK_CIPHER(aes_256, ks, AES, EVP_AES_KEY,
81 NID_aes_256, 16, 32, 16, 128, 83 NID_aes_256, 16, 32, 16, 128,
82 EVP_CIPH_FLAG_FIPS|EVP_CIPH_FLAG_DEFAULT_ASN1, 84 0, aes_init_key, NULL,
83 aes_init_key, 85 EVP_CIPHER_set_asn1_iv,
84 NULL, NULL, NULL, NULL) 86 EVP_CIPHER_get_asn1_iv,
87 NULL)
85 88
86#define IMPLEMENT_AES_CFBR(ksize,cbits,flags) IMPLEMENT_CFBR(aes,AES,EVP_AES_KEY,ks,ksize,cbits,16,flags) 89#define IMPLEMENT_AES_CFBR(ksize,cbits) IMPLEMENT_CFBR(aes,AES,EVP_AES_KEY,ks,ksize,cbits,16)
87 90
88IMPLEMENT_AES_CFBR(128,1,EVP_CIPH_FLAG_FIPS) 91IMPLEMENT_AES_CFBR(128,1)
89IMPLEMENT_AES_CFBR(192,1,EVP_CIPH_FLAG_FIPS) 92IMPLEMENT_AES_CFBR(192,1)
90IMPLEMENT_AES_CFBR(256,1,EVP_CIPH_FLAG_FIPS) 93IMPLEMENT_AES_CFBR(256,1)
91 94
92IMPLEMENT_AES_CFBR(128,8,EVP_CIPH_FLAG_FIPS) 95IMPLEMENT_AES_CFBR(128,8)
93IMPLEMENT_AES_CFBR(192,8,EVP_CIPH_FLAG_FIPS) 96IMPLEMENT_AES_CFBR(192,8)
94IMPLEMENT_AES_CFBR(256,8,EVP_CIPH_FLAG_FIPS) 97IMPLEMENT_AES_CFBR(256,8)
95 98
96static int aes_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, 99static int aes_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
97 const unsigned char *iv, int enc) 100 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 365d397164..a7b40d1c60 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,
93 EVP_CIPHER_get_asn1_iv, 93 EVP_CIPHER_get_asn1_iv,
94 NULL) 94 NULL)
95 95
96#define IMPLEMENT_CAMELLIA_CFBR(ksize,cbits) IMPLEMENT_CFBR(camellia,Camellia,EVP_CAMELLIA_KEY,ks,ksize,cbits,16,0) 96#define IMPLEMENT_CAMELLIA_CFBR(ksize,cbits) IMPLEMENT_CFBR(camellia,Camellia,EVP_CAMELLIA_KEY,ks,ksize,cbits,16)
97 97
98IMPLEMENT_CAMELLIA_CFBR(128,1) 98IMPLEMENT_CAMELLIA_CFBR(128,1)
99IMPLEMENT_CAMELLIA_CFBR(192,1) 99IMPLEMENT_CAMELLIA_CFBR(192,1)
diff --git a/src/lib/libcrypto/evp/e_des.c b/src/lib/libcrypto/evp/e_des.c
index 04376df232..ca009f2c52 100644
--- a/src/lib/libcrypto/evp/e_des.c
+++ b/src/lib/libcrypto/evp/e_des.c
@@ -72,7 +72,7 @@ static int des_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr);
72/* Because of various casts and different names can't use IMPLEMENT_BLOCK_CIPHER */ 72/* Because of various casts and different names can't use IMPLEMENT_BLOCK_CIPHER */
73 73
74static int des_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, 74static int des_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
75 const unsigned char *in, unsigned int inl) 75 const unsigned char *in, size_t inl)
76{ 76{
77 BLOCK_CIPHER_ecb_loop() 77 BLOCK_CIPHER_ecb_loop()
78 DES_ecb_encrypt((DES_cblock *)(in + i), (DES_cblock *)(out + i), ctx->cipher_data, ctx->encrypt); 78 DES_ecb_encrypt((DES_cblock *)(in + i), (DES_cblock *)(out + i), ctx->cipher_data, ctx->encrypt);
@@ -80,24 +80,52 @@ static int des_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
80} 80}
81 81
82static int des_ofb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, 82static int des_ofb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
83 const unsigned char *in, unsigned int inl) 83 const unsigned char *in, size_t inl)
84{ 84{
85 DES_ofb64_encrypt(in, out, (long)inl, ctx->cipher_data, (DES_cblock *)ctx->iv, &ctx->num); 85 while(inl>=EVP_MAXCHUNK)
86 {
87 DES_ofb64_encrypt(in, out, (long)EVP_MAXCHUNK, ctx->cipher_data,
88 (DES_cblock *)ctx->iv, &ctx->num);
89 inl-=EVP_MAXCHUNK;
90 in +=EVP_MAXCHUNK;
91 out+=EVP_MAXCHUNK;
92 }
93 if (inl)
94 DES_ofb64_encrypt(in, out, (long)inl, ctx->cipher_data,
95 (DES_cblock *)ctx->iv, &ctx->num);
86 return 1; 96 return 1;
87} 97}
88 98
89static int des_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, 99static int des_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
90 const unsigned char *in, unsigned int inl) 100 const unsigned char *in, size_t inl)
91{ 101{
92 DES_ncbc_encrypt(in, out, (long)inl, ctx->cipher_data, 102 while(inl>=EVP_MAXCHUNK)
93 (DES_cblock *)ctx->iv, ctx->encrypt); 103 {
104 DES_ncbc_encrypt(in, out, (long)EVP_MAXCHUNK, ctx->cipher_data,
105 (DES_cblock *)ctx->iv, ctx->encrypt);
106 inl-=EVP_MAXCHUNK;
107 in +=EVP_MAXCHUNK;
108 out+=EVP_MAXCHUNK;
109 }
110 if (inl)
111 DES_ncbc_encrypt(in, out, (long)inl, ctx->cipher_data,
112 (DES_cblock *)ctx->iv, ctx->encrypt);
94 return 1; 113 return 1;
95} 114}
96 115
97static int des_cfb64_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, 116static int des_cfb64_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
98 const unsigned char *in, unsigned int inl) 117 const unsigned char *in, size_t inl)
99{ 118{
100 DES_cfb64_encrypt(in, out, (long)inl, ctx->cipher_data, 119 while(inl>=EVP_MAXCHUNK)
120 {
121 DES_cfb64_encrypt(in,out, (long)EVP_MAXCHUNK, ctx->cipher_data,
122 (DES_cblock *)ctx->iv, &ctx->num, ctx->encrypt);
123 inl-=EVP_MAXCHUNK;
124 in +=EVP_MAXCHUNK;
125 out+=EVP_MAXCHUNK;
126 }
127 if (inl)
128 DES_cfb64_encrypt(in, out, (long)inl, ctx->cipher_data,
101 (DES_cblock *)ctx->iv, &ctx->num, ctx->encrypt); 129 (DES_cblock *)ctx->iv, &ctx->num, ctx->encrypt);
102 return 1; 130 return 1;
103} 131}
@@ -105,45 +133,62 @@ static int des_cfb64_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
105/* Although we have a CFB-r implementation for DES, it doesn't pack the right 133/* Although we have a CFB-r implementation for DES, it doesn't pack the right
106 way, so wrap it here */ 134 way, so wrap it here */
107static int des_cfb1_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, 135static int des_cfb1_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
108 const unsigned char *in, unsigned int inl) 136 const unsigned char *in, size_t inl)
109 { 137 {
110 unsigned int n; 138 size_t n,chunk=EVP_MAXCHUNK/8;
111 unsigned char c[1],d[1]; 139 unsigned char c[1],d[1];
112 140
113 for(n=0 ; n < inl ; ++n) 141 if (inl<chunk) chunk=inl;
142
143 while (inl && inl>=chunk)
114 { 144 {
115 c[0]=(in[n/8]&(1 << (7-n%8))) ? 0x80 : 0; 145 for(n=0 ; n < chunk*8; ++n)
116 DES_cfb_encrypt(c,d,1,1,ctx->cipher_data,(DES_cblock *)ctx->iv, 146 {
147 c[0]=(in[n/8]&(1 << (7-n%8))) ? 0x80 : 0;
148 DES_cfb_encrypt(c,d,1,1,ctx->cipher_data,(DES_cblock *)ctx->iv,
117 ctx->encrypt); 149 ctx->encrypt);
118 out[n/8]=(out[n/8]&~(0x80 >> (n%8)))|((d[0]&0x80) >> (n%8)); 150 out[n/8]=(out[n/8]&~(0x80 >> (unsigned int)(n%8))) |
151 ((d[0]&0x80) >> (unsigned int)(n%8));
152 }
153 inl-=chunk;
154 in +=chunk;
155 out+=chunk;
156 if (inl<chunk) chunk=inl;
119 } 157 }
158
120 return 1; 159 return 1;
121 } 160 }
122 161
123static int des_cfb8_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, 162static int des_cfb8_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
124 const unsigned char *in, unsigned int inl) 163 const unsigned char *in, size_t inl)
125 { 164 {
126 DES_cfb_encrypt(in,out,8,inl,ctx->cipher_data,(DES_cblock *)ctx->iv, 165 while (inl>=EVP_MAXCHUNK)
127 ctx->encrypt); 166 {
167 DES_cfb_encrypt(in,out,8,(long)EVP_MAXCHUNK,ctx->cipher_data,
168 (DES_cblock *)ctx->iv,ctx->encrypt);
169 inl-=EVP_MAXCHUNK;
170 in +=EVP_MAXCHUNK;
171 out+=EVP_MAXCHUNK;
172 }
173 if (inl)
174 DES_cfb_encrypt(in,out,8,(long)inl,ctx->cipher_data,
175 (DES_cblock *)ctx->iv,ctx->encrypt);
128 return 1; 176 return 1;
129 } 177 }
130 178
131BLOCK_CIPHER_defs(des, DES_key_schedule, NID_des, 8, 8, 8, 64, 179BLOCK_CIPHER_defs(des, DES_key_schedule, NID_des, 8, 8, 8, 64,
132 EVP_CIPH_RAND_KEY, 180 EVP_CIPH_RAND_KEY, des_init_key, NULL,
133 des_init_key, NULL,
134 EVP_CIPHER_set_asn1_iv, 181 EVP_CIPHER_set_asn1_iv,
135 EVP_CIPHER_get_asn1_iv, 182 EVP_CIPHER_get_asn1_iv,
136 des_ctrl) 183 des_ctrl)
137 184
138BLOCK_CIPHER_def_cfb(des,DES_key_schedule,NID_des,8,8,1, 185BLOCK_CIPHER_def_cfb(des,DES_key_schedule,NID_des,8,8,1,
139 EVP_CIPH_RAND_KEY, 186 EVP_CIPH_RAND_KEY, des_init_key,NULL,
140 des_init_key, NULL,
141 EVP_CIPHER_set_asn1_iv, 187 EVP_CIPHER_set_asn1_iv,
142 EVP_CIPHER_get_asn1_iv,des_ctrl) 188 EVP_CIPHER_get_asn1_iv,des_ctrl)
143 189
144BLOCK_CIPHER_def_cfb(des,DES_key_schedule,NID_des,8,8,8, 190BLOCK_CIPHER_def_cfb(des,DES_key_schedule,NID_des,8,8,8,
145 EVP_CIPH_RAND_KEY, 191 EVP_CIPH_RAND_KEY,des_init_key,NULL,
146 des_init_key,NULL,
147 EVP_CIPHER_set_asn1_iv, 192 EVP_CIPHER_set_asn1_iv,
148 EVP_CIPHER_get_asn1_iv,des_ctrl) 193 EVP_CIPHER_get_asn1_iv,des_ctrl)
149 194
diff --git a/src/lib/libcrypto/evp/e_des3.c b/src/lib/libcrypto/evp/e_des3.c
index f910af19b1..3232cfe024 100644
--- a/src/lib/libcrypto/evp/e_des3.c
+++ b/src/lib/libcrypto/evp/e_des3.c
@@ -85,7 +85,7 @@ typedef struct
85/* Because of various casts and different args can't use IMPLEMENT_BLOCK_CIPHER */ 85/* Because of various casts and different args can't use IMPLEMENT_BLOCK_CIPHER */
86 86
87static int des_ede_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, 87static int des_ede_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
88 const unsigned char *in, unsigned int inl) 88 const unsigned char *in, size_t inl)
89{ 89{
90 BLOCK_CIPHER_ecb_loop() 90 BLOCK_CIPHER_ecb_loop()
91 DES_ecb3_encrypt((const_DES_cblock *)(in + i), 91 DES_ecb3_encrypt((const_DES_cblock *)(in + i),
@@ -97,48 +97,80 @@ static int des_ede_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
97} 97}
98 98
99static int des_ede_ofb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, 99static int des_ede_ofb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
100 const unsigned char *in, unsigned int inl) 100 const unsigned char *in, size_t inl)
101{ 101{
102 DES_ede3_ofb64_encrypt(in, out, (long)inl, 102 if (inl>=EVP_MAXCHUNK)
103 {
104 DES_ede3_ofb64_encrypt(in, out, (long)EVP_MAXCHUNK,
103 &data(ctx)->ks1, &data(ctx)->ks2, &data(ctx)->ks3, 105 &data(ctx)->ks1, &data(ctx)->ks2, &data(ctx)->ks3,
104 (DES_cblock *)ctx->iv, &ctx->num); 106 (DES_cblock *)ctx->iv, &ctx->num);
107 inl-=EVP_MAXCHUNK;
108 in +=EVP_MAXCHUNK;
109 out+=EVP_MAXCHUNK;
110 }
111 if (inl)
112 DES_ede3_ofb64_encrypt(in, out, (long)inl,
113 &data(ctx)->ks1, &data(ctx)->ks2, &data(ctx)->ks3,
114 (DES_cblock *)ctx->iv, &ctx->num);
115
105 return 1; 116 return 1;
106} 117}
107 118
108static int des_ede_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, 119static int des_ede_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
109 const unsigned char *in, unsigned int inl) 120 const unsigned char *in, size_t inl)
110{ 121{
111#ifdef KSSL_DEBUG 122#ifdef KSSL_DEBUG
112 { 123 {
113 int i; 124 int i;
114 printf("des_ede_cbc_cipher(ctx=%lx, buflen=%d)\n", (unsigned long)ctx, ctx->buf_len); 125 char *cp;
126 printf("des_ede_cbc_cipher(ctx=%lx, buflen=%d)\n", ctx, ctx->buf_len);
115 printf("\t iv= "); 127 printf("\t iv= ");
116 for(i=0;i<8;i++) 128 for(i=0;i<8;i++)
117 printf("%02X",ctx->iv[i]); 129 printf("%02X",ctx->iv[i]);
118 printf("\n"); 130 printf("\n");
119 } 131 }
120#endif /* KSSL_DEBUG */ 132#endif /* KSSL_DEBUG */
121 DES_ede3_cbc_encrypt(in, out, (long)inl, 133 if (inl>=EVP_MAXCHUNK)
134 {
135 DES_ede3_cbc_encrypt(in, out, (long)EVP_MAXCHUNK,
122 &data(ctx)->ks1, &data(ctx)->ks2, &data(ctx)->ks3, 136 &data(ctx)->ks1, &data(ctx)->ks2, &data(ctx)->ks3,
123 (DES_cblock *)ctx->iv, ctx->encrypt); 137 (DES_cblock *)ctx->iv, ctx->encrypt);
138 inl-=EVP_MAXCHUNK;
139 in +=EVP_MAXCHUNK;
140 out+=EVP_MAXCHUNK;
141 }
142 if (inl)
143 DES_ede3_cbc_encrypt(in, out, (long)inl,
144 &data(ctx)->ks1, &data(ctx)->ks2, &data(ctx)->ks3,
145 (DES_cblock *)ctx->iv, ctx->encrypt);
124 return 1; 146 return 1;
125} 147}
126 148
127static int des_ede_cfb64_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, 149static int des_ede_cfb64_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
128 const unsigned char *in, unsigned int inl) 150 const unsigned char *in, size_t inl)
129{ 151{
130 DES_ede3_cfb64_encrypt(in, out, (long)inl, 152 if (inl>=EVP_MAXCHUNK)
153 {
154 DES_ede3_cfb64_encrypt(in, out, (long)EVP_MAXCHUNK,
131 &data(ctx)->ks1, &data(ctx)->ks2, &data(ctx)->ks3, 155 &data(ctx)->ks1, &data(ctx)->ks2, &data(ctx)->ks3,
132 (DES_cblock *)ctx->iv, &ctx->num, ctx->encrypt); 156 (DES_cblock *)ctx->iv, &ctx->num, ctx->encrypt);
157 inl-=EVP_MAXCHUNK;
158 in +=EVP_MAXCHUNK;
159 out+=EVP_MAXCHUNK;
160 }
161 if (inl)
162 DES_ede3_cfb64_encrypt(in, out, (long)inl,
163 &data(ctx)->ks1, &data(ctx)->ks2, &data(ctx)->ks3,
164 (DES_cblock *)ctx->iv, &ctx->num, ctx->encrypt);
133 return 1; 165 return 1;
134} 166}
135 167
136/* Although we have a CFB-r implementation for 3-DES, it doesn't pack the right 168/* Although we have a CFB-r implementation for 3-DES, it doesn't pack the right
137 way, so wrap it here */ 169 way, so wrap it here */
138static int des_ede3_cfb1_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, 170static int des_ede3_cfb1_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
139 const unsigned char *in, unsigned int inl) 171 const unsigned char *in, size_t inl)
140 { 172 {
141 unsigned int n; 173 size_t n;
142 unsigned char c[1],d[1]; 174 unsigned char c[1],d[1];
143 175
144 for(n=0 ; n < inl ; ++n) 176 for(n=0 ; n < inl ; ++n)
@@ -147,25 +179,36 @@ static int des_ede3_cfb1_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
147 DES_ede3_cfb_encrypt(c,d,1,1, 179 DES_ede3_cfb_encrypt(c,d,1,1,
148 &data(ctx)->ks1,&data(ctx)->ks2,&data(ctx)->ks3, 180 &data(ctx)->ks1,&data(ctx)->ks2,&data(ctx)->ks3,
149 (DES_cblock *)ctx->iv,ctx->encrypt); 181 (DES_cblock *)ctx->iv,ctx->encrypt);
150 out[n/8]=(out[n/8]&~(0x80 >> (n%8)))|((d[0]&0x80) >> (n%8)); 182 out[n/8]=(out[n/8]&~(0x80 >> (unsigned int)(n%8))) |
183 ((d[0]&0x80) >> (unsigned int)(n%8));
151 } 184 }
152 185
153 return 1; 186 return 1;
154 } 187 }
155 188
156static int des_ede3_cfb8_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, 189static int des_ede3_cfb8_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
157 const unsigned char *in, unsigned int inl) 190 const unsigned char *in, size_t inl)
158 { 191 {
159 DES_ede3_cfb_encrypt(in,out,8,inl, 192 while (inl>=EVP_MAXCHUNK)
193 {
194 DES_ede3_cfb_encrypt(in,out,8,(long)EVP_MAXCHUNK,
160 &data(ctx)->ks1,&data(ctx)->ks2,&data(ctx)->ks3, 195 &data(ctx)->ks1,&data(ctx)->ks2,&data(ctx)->ks3,
161 (DES_cblock *)ctx->iv,ctx->encrypt); 196 (DES_cblock *)ctx->iv,ctx->encrypt);
197 inl-=EVP_MAXCHUNK;
198 in +=EVP_MAXCHUNK;
199 out+=EVP_MAXCHUNK;
200 }
201 if (inl)
202 DES_ede3_cfb_encrypt(in,out,8,(long)inl,
203 &data(ctx)->ks1,&data(ctx)->ks2,&data(ctx)->ks3,
204 (DES_cblock *)ctx->iv,ctx->encrypt);
162 return 1; 205 return 1;
163 } 206 }
164 207
165BLOCK_CIPHER_defs(des_ede, DES_EDE_KEY, NID_des_ede, 8, 16, 8, 64, 208BLOCK_CIPHER_defs(des_ede, DES_EDE_KEY, NID_des_ede, 8, 16, 8, 64,
166 EVP_CIPH_RAND_KEY|EVP_CIPH_FLAG_FIPS|EVP_CIPH_FLAG_DEFAULT_ASN1, 209 EVP_CIPH_RAND_KEY, des_ede_init_key, NULL,
167 des_ede_init_key, 210 EVP_CIPHER_set_asn1_iv,
168 NULL, NULL, NULL, 211 EVP_CIPHER_get_asn1_iv,
169 des3_ctrl) 212 des3_ctrl)
170 213
171#define des_ede3_cfb64_cipher des_ede_cfb64_cipher 214#define des_ede3_cfb64_cipher des_ede_cfb64_cipher
@@ -174,21 +217,21 @@ BLOCK_CIPHER_defs(des_ede, DES_EDE_KEY, NID_des_ede, 8, 16, 8, 64,
174#define des_ede3_ecb_cipher des_ede_ecb_cipher 217#define des_ede3_ecb_cipher des_ede_ecb_cipher
175 218
176BLOCK_CIPHER_defs(des_ede3, DES_EDE_KEY, NID_des_ede3, 8, 24, 8, 64, 219BLOCK_CIPHER_defs(des_ede3, DES_EDE_KEY, NID_des_ede3, 8, 24, 8, 64,
177 EVP_CIPH_RAND_KEY|EVP_CIPH_FLAG_FIPS|EVP_CIPH_FLAG_DEFAULT_ASN1, 220 EVP_CIPH_RAND_KEY, des_ede3_init_key, NULL,
178 des_ede3_init_key, 221 EVP_CIPHER_set_asn1_iv,
179 NULL, NULL, NULL, 222 EVP_CIPHER_get_asn1_iv,
180 des3_ctrl) 223 des3_ctrl)
181 224
182BLOCK_CIPHER_def_cfb(des_ede3,DES_EDE_KEY,NID_des_ede3,24,8,1, 225BLOCK_CIPHER_def_cfb(des_ede3,DES_EDE_KEY,NID_des_ede3,24,8,1,
183 EVP_CIPH_RAND_KEY|EVP_CIPH_FLAG_FIPS|EVP_CIPH_FLAG_DEFAULT_ASN1, 226 EVP_CIPH_RAND_KEY, des_ede3_init_key,NULL,
184 des_ede3_init_key, 227 EVP_CIPHER_set_asn1_iv,
185 NULL, NULL, NULL, 228 EVP_CIPHER_get_asn1_iv,
186 des3_ctrl) 229 des3_ctrl)
187 230
188BLOCK_CIPHER_def_cfb(des_ede3,DES_EDE_KEY,NID_des_ede3,24,8,8, 231BLOCK_CIPHER_def_cfb(des_ede3,DES_EDE_KEY,NID_des_ede3,24,8,8,
189 EVP_CIPH_RAND_KEY|EVP_CIPH_FLAG_FIPS|EVP_CIPH_FLAG_DEFAULT_ASN1, 232 EVP_CIPH_RAND_KEY, des_ede3_init_key,NULL,
190 des_ede3_init_key, 233 EVP_CIPHER_set_asn1_iv,
191 NULL, NULL, NULL, 234 EVP_CIPHER_get_asn1_iv,
192 des3_ctrl) 235 des3_ctrl)
193 236
194static int des_ede_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, 237static int des_ede_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
@@ -215,7 +258,7 @@ static int des_ede3_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
215#ifdef KSSL_DEBUG 258#ifdef KSSL_DEBUG
216 { 259 {
217 int i; 260 int i;
218 printf("des_ede3_init_key(ctx=%lx)\n", (unsigned long)ctx); 261 printf("des_ede3_init_key(ctx=%lx)\n", ctx);
219 printf("\tKEY= "); 262 printf("\tKEY= ");
220 for(i=0;i<24;i++) printf("%02X",key[i]); printf("\n"); 263 for(i=0;i<24;i++) printf("%02X",key[i]); printf("\n");
221 printf("\t IV= "); 264 printf("\t IV= ");
diff --git a/src/lib/libcrypto/evp/e_idea.c b/src/lib/libcrypto/evp/e_idea.c
index 48c33a774a..806b080360 100644
--- a/src/lib/libcrypto/evp/e_idea.c
+++ b/src/lib/libcrypto/evp/e_idea.c
@@ -73,7 +73,7 @@ static int idea_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
73 */ 73 */
74 74
75static int idea_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, 75static int idea_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
76 const unsigned char *in, unsigned int inl) 76 const unsigned char *in, size_t inl)
77{ 77{
78 BLOCK_CIPHER_ecb_loop() 78 BLOCK_CIPHER_ecb_loop()
79 idea_ecb_encrypt(in + i, out + i, ctx->cipher_data); 79 idea_ecb_encrypt(in + i, out + i, ctx->cipher_data);
diff --git a/src/lib/libcrypto/evp/e_null.c b/src/lib/libcrypto/evp/e_null.c
index 0872d733e4..7cf50e1416 100644
--- a/src/lib/libcrypto/evp/e_null.c
+++ b/src/lib/libcrypto/evp/e_null.c
@@ -64,12 +64,12 @@
64static int null_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, 64static int null_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
65 const unsigned char *iv,int enc); 65 const unsigned char *iv,int enc);
66static int null_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, 66static int null_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
67 const unsigned char *in, unsigned int inl); 67 const unsigned char *in, size_t inl);
68static const EVP_CIPHER n_cipher= 68static const EVP_CIPHER n_cipher=
69 { 69 {
70 NID_undef, 70 NID_undef,
71 1,0,0, 71 1,0,0,
72 EVP_CIPH_FLAG_FIPS, 72 0,
73 null_init_key, 73 null_init_key,
74 null_cipher, 74 null_cipher,
75 NULL, 75 NULL,
@@ -93,10 +93,10 @@ static int null_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
93 } 93 }
94 94
95static int null_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, 95static int null_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
96 const unsigned char *in, unsigned int inl) 96 const unsigned char *in, size_t inl)
97 { 97 {
98 if (in != out) 98 if (in != out)
99 memcpy((char *)out,(const char *)in,(size_t)inl); 99 memcpy((char *)out,(const char *)in,inl);
100 return 1; 100 return 1;
101 } 101 }
102 102
diff --git a/src/lib/libcrypto/evp/e_rc2.c b/src/lib/libcrypto/evp/e_rc2.c
index d37726ffae..f78d781129 100644
--- a/src/lib/libcrypto/evp/e_rc2.c
+++ b/src/lib/libcrypto/evp/e_rc2.c
@@ -223,6 +223,11 @@ static int rc2_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr)
223 return 1; 223 return 1;
224 } 224 }
225 return 0; 225 return 0;
226#ifdef PBE_PRF_TEST
227 case EVP_CTRL_PBE_PRF_NID:
228 *(int *)ptr = NID_hmacWithMD5;
229 return 1;
230#endif
226 231
227 default: 232 default:
228 return -1; 233 return -1;
diff --git a/src/lib/libcrypto/evp/e_rc4.c b/src/lib/libcrypto/evp/e_rc4.c
index 55baad7446..8b5175e0fd 100644
--- a/src/lib/libcrypto/evp/e_rc4.c
+++ b/src/lib/libcrypto/evp/e_rc4.c
@@ -64,7 +64,6 @@
64#include <openssl/evp.h> 64#include <openssl/evp.h>
65#include <openssl/objects.h> 65#include <openssl/objects.h>
66#include <openssl/rc4.h> 66#include <openssl/rc4.h>
67#include "evp_locl.h"
68 67
69/* FIXME: surely this is available elsewhere? */ 68/* FIXME: surely this is available elsewhere? */
70#define EVP_RC4_KEY_SIZE 16 69#define EVP_RC4_KEY_SIZE 16
@@ -79,7 +78,7 @@ typedef struct
79static int rc4_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, 78static int rc4_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
80 const unsigned char *iv,int enc); 79 const unsigned char *iv,int enc);
81static int rc4_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, 80static int rc4_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
82 const unsigned char *in, unsigned int inl); 81 const unsigned char *in, size_t inl);
83static const EVP_CIPHER r4_cipher= 82static const EVP_CIPHER r4_cipher=
84 { 83 {
85 NID_rc4, 84 NID_rc4,
@@ -129,7 +128,7 @@ static int rc4_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
129 } 128 }
130 129
131static int rc4_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, 130static int rc4_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
132 const unsigned char *in, unsigned int inl) 131 const unsigned char *in, size_t inl)
133 { 132 {
134 RC4(&data(ctx)->ks,inl,in,out); 133 RC4(&data(ctx)->ks,inl,in,out);
135 return 1; 134 return 1;
diff --git a/src/lib/libcrypto/evp/e_xcbc_d.c b/src/lib/libcrypto/evp/e_xcbc_d.c
index 8832da2433..250e88c8c5 100644
--- a/src/lib/libcrypto/evp/e_xcbc_d.c
+++ b/src/lib/libcrypto/evp/e_xcbc_d.c
@@ -63,12 +63,13 @@
63 63
64#include <openssl/evp.h> 64#include <openssl/evp.h>
65#include <openssl/objects.h> 65#include <openssl/objects.h>
66#include "evp_locl.h"
66#include <openssl/des.h> 67#include <openssl/des.h>
67 68
68static int desx_cbc_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, 69static int desx_cbc_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
69 const unsigned char *iv,int enc); 70 const unsigned char *iv,int enc);
70static int desx_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, 71static int desx_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
71 const unsigned char *in, unsigned int inl); 72 const unsigned char *in, size_t inl);
72 73
73 74
74typedef struct 75typedef struct
@@ -113,13 +114,25 @@ static int desx_cbc_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
113 } 114 }
114 115
115static int desx_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, 116static int desx_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
116 const unsigned char *in, unsigned int inl) 117 const unsigned char *in, size_t inl)
117 { 118 {
118 DES_xcbc_encrypt(in,out,inl,&data(ctx)->ks, 119 while (inl>=EVP_MAXCHUNK)
120 {
121 DES_xcbc_encrypt(in,out,(long)EVP_MAXCHUNK,&data(ctx)->ks,
119 (DES_cblock *)&(ctx->iv[0]), 122 (DES_cblock *)&(ctx->iv[0]),
120 &data(ctx)->inw, 123 &data(ctx)->inw,
121 &data(ctx)->outw, 124 &data(ctx)->outw,
122 ctx->encrypt); 125 ctx->encrypt);
126 inl-=EVP_MAXCHUNK;
127 in +=EVP_MAXCHUNK;
128 out+=EVP_MAXCHUNK;
129 }
130 if (inl)
131 DES_xcbc_encrypt(in,out,(long)inl,&data(ctx)->ks,
132 (DES_cblock *)&(ctx->iv[0]),
133 &data(ctx)->inw,
134 &data(ctx)->outw,
135 ctx->encrypt);
123 return 1; 136 return 1;
124 } 137 }
125#endif 138#endif
diff --git a/src/lib/libcrypto/evp/encode.c b/src/lib/libcrypto/evp/encode.c
index 5921f0d710..b42c747249 100644
--- a/src/lib/libcrypto/evp/encode.c
+++ b/src/lib/libcrypto/evp/encode.c
@@ -85,7 +85,7 @@
85#define CHUNKS_PER_LINE (64/4) 85#define CHUNKS_PER_LINE (64/4)
86#define CHAR_PER_LINE (64+1) 86#define CHAR_PER_LINE (64+1)
87 87
88static unsigned char data_bin2ascii[65]="ABCDEFGHIJKLMNOPQRSTUVWXYZ\ 88static const unsigned char data_bin2ascii[65]="ABCDEFGHIJKLMNOPQRSTUVWXYZ\
89abcdefghijklmnopqrstuvwxyz0123456789+/"; 89abcdefghijklmnopqrstuvwxyz0123456789+/";
90 90
91/* 0xF0 is a EOLN 91/* 0xF0 is a EOLN
@@ -102,7 +102,7 @@ abcdefghijklmnopqrstuvwxyz0123456789+/";
102#define B64_ERROR 0xFF 102#define B64_ERROR 0xFF
103#define B64_NOT_BASE64(a) (((a)|0x13) == 0xF3) 103#define B64_NOT_BASE64(a) (((a)|0x13) == 0xF3)
104 104
105static unsigned char data_ascii2bin[128]={ 105static const unsigned char data_ascii2bin[128]={
106 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 106 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
107 0xFF,0xE0,0xF0,0xFF,0xFF,0xF1,0xFF,0xFF, 107 0xFF,0xE0,0xF0,0xFF,0xFF,0xF1,0xFF,0xFF,
108 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 108 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
diff --git a/src/lib/libcrypto/evp/evp.h b/src/lib/libcrypto/evp/evp.h
index 79c097181f..9f9795e2d9 100644
--- a/src/lib/libcrypto/evp/evp.h
+++ b/src/lib/libcrypto/evp/evp.h
@@ -75,10 +75,6 @@
75#include <openssl/bio.h> 75#include <openssl/bio.h>
76#endif 76#endif
77 77
78#ifdef OPENSSL_FIPS
79#include <openssl/fips.h>
80#endif
81
82/* 78/*
83#define EVP_RC2_KEY_SIZE 16 79#define EVP_RC2_KEY_SIZE 16
84#define EVP_RC4_KEY_SIZE 16 80#define EVP_RC4_KEY_SIZE 16
@@ -119,6 +115,7 @@
119#define EVP_PKEY_DSA4 NID_dsaWithSHA1_2 115#define EVP_PKEY_DSA4 NID_dsaWithSHA1_2
120#define EVP_PKEY_DH NID_dhKeyAgreement 116#define EVP_PKEY_DH NID_dhKeyAgreement
121#define EVP_PKEY_EC NID_X9_62_id_ecPublicKey 117#define EVP_PKEY_EC NID_X9_62_id_ecPublicKey
118#define EVP_PKEY_HMAC NID_hmac
122 119
123#ifdef __cplusplus 120#ifdef __cplusplus
124extern "C" { 121extern "C" {
@@ -132,6 +129,8 @@ struct evp_pkey_st
132 int type; 129 int type;
133 int save_type; 130 int save_type;
134 int references; 131 int references;
132 const EVP_PKEY_ASN1_METHOD *ameth;
133 ENGINE *engine;
135 union { 134 union {
136 char *ptr; 135 char *ptr;
137#ifndef OPENSSL_NO_RSA 136#ifndef OPENSSL_NO_RSA
@@ -156,73 +155,6 @@ struct evp_pkey_st
156#define EVP_PKEY_MO_ENCRYPT 0x0004 155#define EVP_PKEY_MO_ENCRYPT 0x0004
157#define EVP_PKEY_MO_DECRYPT 0x0008 156#define EVP_PKEY_MO_DECRYPT 0x0008
158 157
159#if 0
160/* This structure is required to tie the message digest and signing together.
161 * The lookup can be done by md/pkey_method, oid, oid/pkey_method, or
162 * oid, md and pkey.
163 * This is required because for various smart-card perform the digest and
164 * signing/verification on-board. To handle this case, the specific
165 * EVP_MD and EVP_PKEY_METHODs need to be closely associated.
166 * When a PKEY is created, it will have a EVP_PKEY_METHOD associated with it.
167 * This can either be software or a token to provide the required low level
168 * routines.
169 */
170typedef struct evp_pkey_md_st
171 {
172 int oid;
173 EVP_MD *md;
174 EVP_PKEY_METHOD *pkey;
175 } EVP_PKEY_MD;
176
177#define EVP_rsa_md2() \
178 EVP_PKEY_MD_add(NID_md2WithRSAEncryption,\
179 EVP_rsa_pkcs1(),EVP_md2())
180#define EVP_rsa_md5() \
181 EVP_PKEY_MD_add(NID_md5WithRSAEncryption,\
182 EVP_rsa_pkcs1(),EVP_md5())
183#define EVP_rsa_sha0() \
184 EVP_PKEY_MD_add(NID_shaWithRSAEncryption,\
185 EVP_rsa_pkcs1(),EVP_sha())
186#define EVP_rsa_sha1() \
187 EVP_PKEY_MD_add(NID_sha1WithRSAEncryption,\
188 EVP_rsa_pkcs1(),EVP_sha1())
189#define EVP_rsa_ripemd160() \
190 EVP_PKEY_MD_add(NID_ripemd160WithRSA,\
191 EVP_rsa_pkcs1(),EVP_ripemd160())
192#define EVP_rsa_mdc2() \
193 EVP_PKEY_MD_add(NID_mdc2WithRSA,\
194 EVP_rsa_octet_string(),EVP_mdc2())
195#define EVP_dsa_sha() \
196 EVP_PKEY_MD_add(NID_dsaWithSHA,\
197 EVP_dsa(),EVP_sha())
198#define EVP_dsa_sha1() \
199 EVP_PKEY_MD_add(NID_dsaWithSHA1,\
200 EVP_dsa(),EVP_sha1())
201
202typedef struct evp_pkey_method_st
203 {
204 char *name;
205 int flags;
206 int type; /* RSA, DSA, an SSLeay specific constant */
207 int oid; /* For the pub-key type */
208 int encrypt_oid; /* pub/priv key encryption */
209
210 int (*sign)();
211 int (*verify)();
212 struct {
213 int (*set)(); /* get and/or set the underlying type */
214 int (*get)();
215 int (*encrypt)();
216 int (*decrypt)();
217 int (*i2d)();
218 int (*d2i)();
219 int (*dup)();
220 } pub,priv;
221 int (*set_asn1_parameters)();
222 int (*get_asn1_parameters)();
223 } EVP_PKEY_METHOD;
224#endif
225
226#ifndef EVP_MD 158#ifndef EVP_MD
227struct env_md_st 159struct env_md_st
228 { 160 {
@@ -245,6 +177,8 @@ struct env_md_st
245 int required_pkey_type[5]; /*EVP_PKEY_xxx */ 177 int required_pkey_type[5]; /*EVP_PKEY_xxx */
246 int block_size; 178 int block_size;
247 int ctx_size; /* how big does the ctx->md_data need to be */ 179 int ctx_size; /* how big does the ctx->md_data need to be */
180 /* control function */
181 int (*md_ctrl)(EVP_MD_CTX *ctx, int cmd, int p1, void *p2);
248 } /* EVP_MD */; 182 } /* EVP_MD */;
249 183
250typedef int evp_sign_method(int type,const unsigned char *m, 184typedef int evp_sign_method(int type,const unsigned char *m,
@@ -254,18 +188,42 @@ typedef int evp_verify_method(int type,const unsigned char *m,
254 unsigned int m_length,const unsigned char *sigbuf, 188 unsigned int m_length,const unsigned char *sigbuf,
255 unsigned int siglen, void *key); 189 unsigned int siglen, void *key);
256 190
257typedef struct
258 {
259 EVP_MD_CTX *mctx;
260 void *key;
261 } EVP_MD_SVCTX;
262
263#define EVP_MD_FLAG_ONESHOT 0x0001 /* digest can only handle a single 191#define EVP_MD_FLAG_ONESHOT 0x0001 /* digest can only handle a single
264 * block */ 192 * block */
265 193
266#define EVP_MD_FLAG_FIPS 0x0400 /* Note if suitable for use in FIPS mode */ 194#define EVP_MD_FLAG_PKEY_DIGEST 0x0002 /* digest is a "clone" digest used
195 * which is a copy of an existing
196 * one for a specific public key type.
197 * EVP_dss1() etc */
198
199/* Digest uses EVP_PKEY_METHOD for signing instead of MD specific signing */
200
201#define EVP_MD_FLAG_PKEY_METHOD_SIGNATURE 0x0004
202
203/* DigestAlgorithmIdentifier flags... */
204
205#define EVP_MD_FLAG_DIGALGID_MASK 0x0018
267 206
268#define EVP_MD_FLAG_SVCTX 0x0800 /* pass EVP_MD_SVCTX to sign/verify */ 207/* NULL or absent parameter accepted. Use NULL */
208
209#define EVP_MD_FLAG_DIGALGID_NULL 0x0000
210
211/* NULL or absent parameter accepted. Use NULL for PKCS#1 otherwise absent */
212
213#define EVP_MD_FLAG_DIGALGID_ABSENT 0x0008
214
215/* Custom handling via ctrl */
216
217#define EVP_MD_FLAG_DIGALGID_CUSTOM 0x0018
218
219/* Digest ctrls */
220
221#define EVP_MD_CTRL_DIGALGID 0x1
222#define EVP_MD_CTRL_MICALG 0x2
223
224/* Minimum Algorithm specific ctrl value */
225
226#define EVP_MD_CTRL_ALG_CTRL 0x1000
269 227
270#define EVP_PKEY_NULL_method NULL,NULL,{0,0,0,0} 228#define EVP_PKEY_NULL_method NULL,NULL,{0,0,0,0}
271 229
@@ -307,6 +265,10 @@ struct env_md_ctx_st
307 ENGINE *engine; /* functional reference if 'digest' is ENGINE-provided */ 265 ENGINE *engine; /* functional reference if 'digest' is ENGINE-provided */
308 unsigned long flags; 266 unsigned long flags;
309 void *md_data; 267 void *md_data;
268 /* Public key context for sign/verify */
269 EVP_PKEY_CTX *pctx;
270 /* Update function: usually copied from EVP_MD */
271 int (*update)(EVP_MD_CTX *ctx,const void *data,size_t count);
310 } /* EVP_MD_CTX */; 272 } /* EVP_MD_CTX */;
311 273
312/* values for EVP_MD_CTX flags */ 274/* values for EVP_MD_CTX flags */
@@ -317,17 +279,23 @@ struct env_md_ctx_st
317 * cleaned */ 279 * cleaned */
318#define EVP_MD_CTX_FLAG_REUSE 0x0004 /* Don't free up ctx->md_data 280#define EVP_MD_CTX_FLAG_REUSE 0x0004 /* Don't free up ctx->md_data
319 * in EVP_MD_CTX_cleanup */ 281 * in EVP_MD_CTX_cleanup */
282/* FIPS and pad options are ignored in 1.0.0, definitions are here
283 * so we don't accidentally reuse the values for other purposes.
284 */
285
320#define EVP_MD_CTX_FLAG_NON_FIPS_ALLOW 0x0008 /* Allow use of non FIPS digest 286#define EVP_MD_CTX_FLAG_NON_FIPS_ALLOW 0x0008 /* Allow use of non FIPS digest
321 * in FIPS mode */ 287 * in FIPS mode */
322 288
289/* The following PAD options are also currently ignored in 1.0.0, digest
290 * parameters are handled through EVP_DigestSign*() and EVP_DigestVerify*()
291 * instead.
292 */
323#define EVP_MD_CTX_FLAG_PAD_MASK 0xF0 /* RSA mode to use */ 293#define EVP_MD_CTX_FLAG_PAD_MASK 0xF0 /* RSA mode to use */
324#define EVP_MD_CTX_FLAG_PAD_PKCS1 0x00 /* PKCS#1 v1.5 mode */ 294#define EVP_MD_CTX_FLAG_PAD_PKCS1 0x00 /* PKCS#1 v1.5 mode */
325#define EVP_MD_CTX_FLAG_PAD_X931 0x10 /* X9.31 mode */ 295#define EVP_MD_CTX_FLAG_PAD_X931 0x10 /* X9.31 mode */
326#define EVP_MD_CTX_FLAG_PAD_PSS 0x20 /* PSS mode */ 296#define EVP_MD_CTX_FLAG_PAD_PSS 0x20 /* PSS mode */
327#define M_EVP_MD_CTX_FLAG_PSS_SALT(ctx) \ 297
328 ((ctx->flags>>16) &0xFFFF) /* seed length */ 298#define EVP_MD_CTX_FLAG_NO_INIT 0x0100 /* Don't initialize md_data */
329#define EVP_MD_CTX_FLAG_PSS_MDLEN 0xFFFF /* salt len same as digest */
330#define EVP_MD_CTX_FLAG_PSS_MREC 0xFFFE /* salt max or auto recovered */
331 299
332struct evp_cipher_st 300struct evp_cipher_st
333 { 301 {
@@ -339,7 +307,7 @@ struct evp_cipher_st
339 int (*init)(EVP_CIPHER_CTX *ctx, const unsigned char *key, 307 int (*init)(EVP_CIPHER_CTX *ctx, const unsigned char *key,
340 const unsigned char *iv, int enc); /* init key */ 308 const unsigned char *iv, int enc); /* init key */
341 int (*do_cipher)(EVP_CIPHER_CTX *ctx, unsigned char *out, 309 int (*do_cipher)(EVP_CIPHER_CTX *ctx, unsigned char *out,
342 const unsigned char *in, unsigned int inl);/* encrypt/decrypt data */ 310 const unsigned char *in, size_t inl);/* encrypt/decrypt data */
343 int (*cleanup)(EVP_CIPHER_CTX *); /* cleanup ctx */ 311 int (*cleanup)(EVP_CIPHER_CTX *); /* cleanup ctx */
344 int ctx_size; /* how big ctx->cipher_data needs to be */ 312 int ctx_size; /* how big ctx->cipher_data needs to be */
345 int (*set_asn1_parameters)(EVP_CIPHER_CTX *, ASN1_TYPE *); /* Populate a ASN1_TYPE with parameters */ 313 int (*set_asn1_parameters)(EVP_CIPHER_CTX *, ASN1_TYPE *); /* Populate a ASN1_TYPE with parameters */
@@ -357,7 +325,7 @@ struct evp_cipher_st
357#define EVP_CIPH_CBC_MODE 0x2 325#define EVP_CIPH_CBC_MODE 0x2
358#define EVP_CIPH_CFB_MODE 0x3 326#define EVP_CIPH_CFB_MODE 0x3
359#define EVP_CIPH_OFB_MODE 0x4 327#define EVP_CIPH_OFB_MODE 0x4
360#define EVP_CIPH_MODE 0x7 328#define EVP_CIPH_MODE 0xF0007
361/* Set if variable length cipher */ 329/* Set if variable length cipher */
362#define EVP_CIPH_VARIABLE_LENGTH 0x8 330#define EVP_CIPH_VARIABLE_LENGTH 0x8
363/* Set if the iv handling should be done by the cipher itself */ 331/* Set if the iv handling should be done by the cipher itself */
@@ -372,10 +340,8 @@ struct evp_cipher_st
372#define EVP_CIPH_NO_PADDING 0x100 340#define EVP_CIPH_NO_PADDING 0x100
373/* cipher handles random key generation */ 341/* cipher handles random key generation */
374#define EVP_CIPH_RAND_KEY 0x200 342#define EVP_CIPH_RAND_KEY 0x200
375/* Note if suitable for use in FIPS mode */ 343/* cipher has its own additional copying logic */
376#define EVP_CIPH_FLAG_FIPS 0x400 344#define EVP_CIPH_CUSTOM_COPY 0x400
377/* Allow non FIPS cipher in FIPS mode */
378#define EVP_CIPH_FLAG_NON_FIPS_ALLOW 0x800
379/* Allow use default ASN1 get/set iv */ 345/* Allow use default ASN1 get/set iv */
380#define EVP_CIPH_FLAG_DEFAULT_ASN1 0x1000 346#define EVP_CIPH_FLAG_DEFAULT_ASN1 0x1000
381/* Buffer length in bits not bytes: CFB1 mode only */ 347/* Buffer length in bits not bytes: CFB1 mode only */
@@ -390,6 +356,8 @@ struct evp_cipher_st
390#define EVP_CTRL_GET_RC5_ROUNDS 0x4 356#define EVP_CTRL_GET_RC5_ROUNDS 0x4
391#define EVP_CTRL_SET_RC5_ROUNDS 0x5 357#define EVP_CTRL_SET_RC5_ROUNDS 0x5
392#define EVP_CTRL_RAND_KEY 0x6 358#define EVP_CTRL_RAND_KEY 0x6
359#define EVP_CTRL_PBE_PRF_NID 0x7
360#define EVP_CTRL_COPY 0x8
393 361
394typedef struct evp_cipher_info_st 362typedef struct evp_cipher_info_st
395 { 363 {
@@ -462,26 +430,15 @@ typedef int (EVP_PBE_KEYGEN)(EVP_CIPHER_CTX *ctx, const char *pass, int passlen,
462#define EVP_get_cipherbynid(a) EVP_get_cipherbyname(OBJ_nid2sn(a)) 430#define EVP_get_cipherbynid(a) EVP_get_cipherbyname(OBJ_nid2sn(a))
463#define EVP_get_cipherbyobj(a) EVP_get_cipherbynid(OBJ_obj2nid(a)) 431#define EVP_get_cipherbyobj(a) EVP_get_cipherbynid(OBJ_obj2nid(a))
464 432
465/* Macros to reduce FIPS dependencies: do NOT use in applications */
466#define M_EVP_MD_size(e) ((e)->md_size)
467#define M_EVP_MD_block_size(e) ((e)->block_size)
468#define M_EVP_MD_CTX_set_flags(ctx,flgs) ((ctx)->flags|=(flgs))
469#define M_EVP_MD_CTX_clear_flags(ctx,flgs) ((ctx)->flags&=~(flgs))
470#define M_EVP_MD_CTX_test_flags(ctx,flgs) ((ctx)->flags&(flgs))
471#define M_EVP_MD_type(e) ((e)->type)
472#define M_EVP_MD_CTX_type(e) M_EVP_MD_type(M_EVP_MD_CTX_md(e))
473#define M_EVP_MD_CTX_md(e) ((e)->digest)
474
475#define M_EVP_CIPHER_CTX_set_flags(ctx,flgs) ((ctx)->flags|=(flgs))
476
477int EVP_MD_type(const EVP_MD *md); 433int EVP_MD_type(const EVP_MD *md);
478#define EVP_MD_nid(e) EVP_MD_type(e) 434#define EVP_MD_nid(e) EVP_MD_type(e)
479#define EVP_MD_name(e) OBJ_nid2sn(EVP_MD_nid(e)) 435#define EVP_MD_name(e) OBJ_nid2sn(EVP_MD_nid(e))
480int EVP_MD_pkey_type(const EVP_MD *md); 436int EVP_MD_pkey_type(const EVP_MD *md);
481int EVP_MD_size(const EVP_MD *md); 437int EVP_MD_size(const EVP_MD *md);
482int EVP_MD_block_size(const EVP_MD *md); 438int EVP_MD_block_size(const EVP_MD *md);
439unsigned long EVP_MD_flags(const EVP_MD *md);
483 440
484const EVP_MD * EVP_MD_CTX_md(const EVP_MD_CTX *ctx); 441const EVP_MD *EVP_MD_CTX_md(const EVP_MD_CTX *ctx);
485#define EVP_MD_CTX_size(e) EVP_MD_size(EVP_MD_CTX_md(e)) 442#define EVP_MD_CTX_size(e) EVP_MD_size(EVP_MD_CTX_md(e))
486#define EVP_MD_CTX_block_size(e) EVP_MD_block_size(EVP_MD_CTX_md(e)) 443#define EVP_MD_CTX_block_size(e) EVP_MD_block_size(EVP_MD_CTX_md(e))
487#define EVP_MD_CTX_type(e) EVP_MD_type(EVP_MD_CTX_md(e)) 444#define EVP_MD_CTX_type(e) EVP_MD_type(EVP_MD_CTX_md(e))
@@ -499,6 +456,7 @@ int EVP_CIPHER_CTX_nid(const EVP_CIPHER_CTX *ctx);
499int EVP_CIPHER_CTX_block_size(const EVP_CIPHER_CTX *ctx); 456int EVP_CIPHER_CTX_block_size(const EVP_CIPHER_CTX *ctx);
500int EVP_CIPHER_CTX_key_length(const EVP_CIPHER_CTX *ctx); 457int EVP_CIPHER_CTX_key_length(const EVP_CIPHER_CTX *ctx);
501int EVP_CIPHER_CTX_iv_length(const EVP_CIPHER_CTX *ctx); 458int EVP_CIPHER_CTX_iv_length(const EVP_CIPHER_CTX *ctx);
459int EVP_CIPHER_CTX_copy(EVP_CIPHER_CTX *out, const EVP_CIPHER_CTX *in);
502void * EVP_CIPHER_CTX_get_app_data(const EVP_CIPHER_CTX *ctx); 460void * EVP_CIPHER_CTX_get_app_data(const EVP_CIPHER_CTX *ctx);
503void EVP_CIPHER_CTX_set_app_data(EVP_CIPHER_CTX *ctx, void *data); 461void EVP_CIPHER_CTX_set_app_data(EVP_CIPHER_CTX *ctx, void *data);
504#define EVP_CIPHER_CTX_type(c) EVP_CIPHER_type(EVP_CIPHER_CTX_cipher(c)) 462#define EVP_CIPHER_CTX_type(c) EVP_CIPHER_type(EVP_CIPHER_CTX_cipher(c))
@@ -516,6 +474,8 @@ unsigned long EVP_CIPHER_CTX_flags(const EVP_CIPHER_CTX *ctx);
516#define EVP_VerifyUpdate(a,b,c) EVP_DigestUpdate(a,b,c) 474#define EVP_VerifyUpdate(a,b,c) EVP_DigestUpdate(a,b,c)
517#define EVP_OpenUpdate(a,b,c,d,e) EVP_DecryptUpdate(a,b,c,d,e) 475#define EVP_OpenUpdate(a,b,c,d,e) EVP_DecryptUpdate(a,b,c,d,e)
518#define EVP_SealUpdate(a,b,c,d,e) EVP_EncryptUpdate(a,b,c,d,e) 476#define EVP_SealUpdate(a,b,c,d,e) EVP_EncryptUpdate(a,b,c,d,e)
477#define EVP_DigestSignUpdate(a,b,c) EVP_DigestUpdate(a,b,c)
478#define EVP_DigestVerifyUpdate(a,b,c) EVP_DigestUpdate(a,b,c)
519 479
520#ifdef CONST_STRICT 480#ifdef CONST_STRICT
521void BIO_set_md(BIO *,const EVP_MD *md); 481void BIO_set_md(BIO *,const EVP_MD *md);
@@ -562,6 +522,7 @@ int EVP_DigestInit(EVP_MD_CTX *ctx, const EVP_MD *type);
562int EVP_DigestFinal(EVP_MD_CTX *ctx,unsigned char *md,unsigned int *s); 522int EVP_DigestFinal(EVP_MD_CTX *ctx,unsigned char *md,unsigned int *s);
563 523
564int EVP_read_pw_string(char *buf,int length,const char *prompt,int verify); 524int EVP_read_pw_string(char *buf,int length,const char *prompt,int verify);
525int EVP_read_pw_string_min(char *buf,int minlen,int maxlen,const char *prompt,int verify);
565void EVP_set_pw_prompt(const char *prompt); 526void EVP_set_pw_prompt(const char *prompt);
566char * EVP_get_pw_prompt(void); 527char * EVP_get_pw_prompt(void);
567 528
@@ -608,6 +569,16 @@ int EVP_SignFinal(EVP_MD_CTX *ctx,unsigned char *md,unsigned int *s,
608int EVP_VerifyFinal(EVP_MD_CTX *ctx,const unsigned char *sigbuf, 569int EVP_VerifyFinal(EVP_MD_CTX *ctx,const unsigned char *sigbuf,
609 unsigned int siglen,EVP_PKEY *pkey); 570 unsigned int siglen,EVP_PKEY *pkey);
610 571
572int EVP_DigestSignInit(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx,
573 const EVP_MD *type, ENGINE *e, EVP_PKEY *pkey);
574int EVP_DigestSignFinal(EVP_MD_CTX *ctx,
575 unsigned char *sigret, size_t *siglen);
576
577int EVP_DigestVerifyInit(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx,
578 const EVP_MD *type, ENGINE *e, EVP_PKEY *pkey);
579int EVP_DigestVerifyFinal(EVP_MD_CTX *ctx,
580 unsigned char *sig, size_t siglen);
581
611int EVP_OpenInit(EVP_CIPHER_CTX *ctx,const EVP_CIPHER *type, 582int EVP_OpenInit(EVP_CIPHER_CTX *ctx,const EVP_CIPHER *type,
612 const unsigned char *ek, int ekl, const unsigned char *iv, 583 const unsigned char *ek, int ekl, const unsigned char *iv,
613 EVP_PKEY *priv); 584 EVP_PKEY *priv);
@@ -680,6 +651,9 @@ const EVP_MD *EVP_mdc2(void);
680#ifndef OPENSSL_NO_RIPEMD 651#ifndef OPENSSL_NO_RIPEMD
681const EVP_MD *EVP_ripemd160(void); 652const EVP_MD *EVP_ripemd160(void);
682#endif 653#endif
654#ifndef OPENSSL_NO_WHIRLPOOL
655const EVP_MD *EVP_whirlpool(void);
656#endif
683const EVP_CIPHER *EVP_enc_null(void); /* does nothing :-) */ 657const EVP_CIPHER *EVP_enc_null(void); /* does nothing :-) */
684#ifndef OPENSSL_NO_DES 658#ifndef OPENSSL_NO_DES
685const EVP_CIPHER *EVP_des_ecb(void); 659const EVP_CIPHER *EVP_des_ecb(void);
@@ -847,16 +821,31 @@ const EVP_CIPHER *EVP_get_cipherbyname(const char *name);
847const EVP_MD *EVP_get_digestbyname(const char *name); 821const EVP_MD *EVP_get_digestbyname(const char *name);
848void EVP_cleanup(void); 822void EVP_cleanup(void);
849 823
850int EVP_PKEY_decrypt(unsigned char *dec_key, 824void EVP_CIPHER_do_all(void (*fn)(const EVP_CIPHER *ciph,
825 const char *from, const char *to, void *x), void *arg);
826void EVP_CIPHER_do_all_sorted(void (*fn)(const EVP_CIPHER *ciph,
827 const char *from, const char *to, void *x), void *arg);
828
829void EVP_MD_do_all(void (*fn)(const EVP_MD *ciph,
830 const char *from, const char *to, void *x), void *arg);
831void EVP_MD_do_all_sorted(void (*fn)(const EVP_MD *ciph,
832 const char *from, const char *to, void *x), void *arg);
833
834int EVP_PKEY_decrypt_old(unsigned char *dec_key,
851 const unsigned char *enc_key,int enc_key_len, 835 const unsigned char *enc_key,int enc_key_len,
852 EVP_PKEY *private_key); 836 EVP_PKEY *private_key);
853int EVP_PKEY_encrypt(unsigned char *enc_key, 837int EVP_PKEY_encrypt_old(unsigned char *enc_key,
854 const unsigned char *key,int key_len, 838 const unsigned char *key,int key_len,
855 EVP_PKEY *pub_key); 839 EVP_PKEY *pub_key);
856int EVP_PKEY_type(int type); 840int EVP_PKEY_type(int type);
841int EVP_PKEY_id(const EVP_PKEY *pkey);
842int EVP_PKEY_base_id(const EVP_PKEY *pkey);
857int EVP_PKEY_bits(EVP_PKEY *pkey); 843int EVP_PKEY_bits(EVP_PKEY *pkey);
858int EVP_PKEY_size(EVP_PKEY *pkey); 844int EVP_PKEY_size(EVP_PKEY *pkey);
859int EVP_PKEY_assign(EVP_PKEY *pkey,int type,char *key); 845int EVP_PKEY_set_type(EVP_PKEY *pkey,int type);
846int EVP_PKEY_set_type_str(EVP_PKEY *pkey, const char *str, int len);
847int EVP_PKEY_assign(EVP_PKEY *pkey,int type,void *key);
848void * EVP_PKEY_get0(EVP_PKEY *pkey);
860 849
861#ifndef OPENSSL_NO_RSA 850#ifndef OPENSSL_NO_RSA
862struct rsa_st; 851struct rsa_st;
@@ -899,6 +888,15 @@ int EVP_PKEY_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b);
899 888
900int EVP_PKEY_cmp(const EVP_PKEY *a, const EVP_PKEY *b); 889int EVP_PKEY_cmp(const EVP_PKEY *a, const EVP_PKEY *b);
901 890
891int EVP_PKEY_print_public(BIO *out, const EVP_PKEY *pkey,
892 int indent, ASN1_PCTX *pctx);
893int EVP_PKEY_print_private(BIO *out, const EVP_PKEY *pkey,
894 int indent, ASN1_PCTX *pctx);
895int EVP_PKEY_print_params(BIO *out, const EVP_PKEY *pkey,
896 int indent, ASN1_PCTX *pctx);
897
898int EVP_PKEY_get_default_digest_nid(EVP_PKEY *pkey, int *pnid);
899
902int EVP_CIPHER_type(const EVP_CIPHER *ctx); 900int EVP_CIPHER_type(const EVP_CIPHER *ctx);
903 901
904/* calls methods */ 902/* calls methods */
@@ -916,6 +914,10 @@ int PKCS5_PBE_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, int passlen,
916int PKCS5_PBKDF2_HMAC_SHA1(const char *pass, int passlen, 914int PKCS5_PBKDF2_HMAC_SHA1(const char *pass, int passlen,
917 const unsigned char *salt, int saltlen, int iter, 915 const unsigned char *salt, int saltlen, int iter,
918 int keylen, unsigned char *out); 916 int keylen, unsigned char *out);
917int PKCS5_PBKDF2_HMAC(const char *pass, int passlen,
918 const unsigned char *salt, int saltlen, int iter,
919 const EVP_MD *digest,
920 int keylen, unsigned char *out);
919int PKCS5_v2_PBE_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, int passlen, 921int PKCS5_v2_PBE_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, int passlen,
920 ASN1_TYPE *param, const EVP_CIPHER *cipher, const EVP_MD *md, 922 ASN1_TYPE *param, const EVP_CIPHER *cipher, const EVP_MD *md,
921 int en_de); 923 int en_de);
@@ -924,27 +926,260 @@ void PKCS5_PBE_add(void);
924 926
925int EVP_PBE_CipherInit (ASN1_OBJECT *pbe_obj, const char *pass, int passlen, 927int EVP_PBE_CipherInit (ASN1_OBJECT *pbe_obj, const char *pass, int passlen,
926 ASN1_TYPE *param, EVP_CIPHER_CTX *ctx, int en_de); 928 ASN1_TYPE *param, EVP_CIPHER_CTX *ctx, int en_de);
929
930/* PBE type */
931
932/* Can appear as the outermost AlgorithmIdentifier */
933#define EVP_PBE_TYPE_OUTER 0x0
934/* Is an PRF type OID */
935#define EVP_PBE_TYPE_PRF 0x1
936
937int EVP_PBE_alg_add_type(int pbe_type, int pbe_nid, int cipher_nid, int md_nid,
938 EVP_PBE_KEYGEN *keygen);
927int EVP_PBE_alg_add(int nid, const EVP_CIPHER *cipher, const EVP_MD *md, 939int EVP_PBE_alg_add(int nid, const EVP_CIPHER *cipher, const EVP_MD *md,
928 EVP_PBE_KEYGEN *keygen); 940 EVP_PBE_KEYGEN *keygen);
941int EVP_PBE_find(int type, int pbe_nid,
942 int *pcnid, int *pmnid, EVP_PBE_KEYGEN **pkeygen);
929void EVP_PBE_cleanup(void); 943void EVP_PBE_cleanup(void);
930 944
931#ifdef OPENSSL_FIPS 945#define ASN1_PKEY_ALIAS 0x1
932#ifndef OPENSSL_NO_ENGINE 946#define ASN1_PKEY_DYNAMIC 0x2
933void int_EVP_MD_set_engine_callbacks( 947#define ASN1_PKEY_SIGPARAM_NULL 0x4
934 int (*eng_md_init)(ENGINE *impl), 948
935 int (*eng_md_fin)(ENGINE *impl), 949#define ASN1_PKEY_CTRL_PKCS7_SIGN 0x1
936 int (*eng_md_evp) 950#define ASN1_PKEY_CTRL_PKCS7_ENCRYPT 0x2
937 (EVP_MD_CTX *ctx, const EVP_MD **ptype, ENGINE *impl)); 951#define ASN1_PKEY_CTRL_DEFAULT_MD_NID 0x3
938void int_EVP_MD_init_engine_callbacks(void); 952#define ASN1_PKEY_CTRL_CMS_SIGN 0x5
939void int_EVP_CIPHER_set_engine_callbacks( 953#define ASN1_PKEY_CTRL_CMS_ENVELOPE 0x7
940 int (*eng_ciph_fin)(ENGINE *impl), 954
941 int (*eng_ciph_evp) 955int EVP_PKEY_asn1_get_count(void);
942 (EVP_CIPHER_CTX *ctx, const EVP_CIPHER **pciph, ENGINE *impl)); 956const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_get0(int idx);
943void int_EVP_CIPHER_init_engine_callbacks(void); 957const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_find(ENGINE **pe, int type);
944#endif 958const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_find_str(ENGINE **pe,
945#endif 959 const char *str, int len);
960int EVP_PKEY_asn1_add0(const EVP_PKEY_ASN1_METHOD *ameth);
961int EVP_PKEY_asn1_add_alias(int to, int from);
962int EVP_PKEY_asn1_get0_info(int *ppkey_id, int *pkey_base_id, int *ppkey_flags,
963 const char **pinfo, const char **ppem_str,
964 const EVP_PKEY_ASN1_METHOD *ameth);
965
966const EVP_PKEY_ASN1_METHOD* EVP_PKEY_get0_asn1(EVP_PKEY *pkey);
967EVP_PKEY_ASN1_METHOD* EVP_PKEY_asn1_new(int id, int flags,
968 const char *pem_str, const char *info);
969void EVP_PKEY_asn1_copy(EVP_PKEY_ASN1_METHOD *dst,
970 const EVP_PKEY_ASN1_METHOD *src);
971void EVP_PKEY_asn1_free(EVP_PKEY_ASN1_METHOD *ameth);
972void EVP_PKEY_asn1_set_public(EVP_PKEY_ASN1_METHOD *ameth,
973 int (*pub_decode)(EVP_PKEY *pk, X509_PUBKEY *pub),
974 int (*pub_encode)(X509_PUBKEY *pub, const EVP_PKEY *pk),
975 int (*pub_cmp)(const EVP_PKEY *a, const EVP_PKEY *b),
976 int (*pub_print)(BIO *out, const EVP_PKEY *pkey, int indent,
977 ASN1_PCTX *pctx),
978 int (*pkey_size)(const EVP_PKEY *pk),
979 int (*pkey_bits)(const EVP_PKEY *pk));
980void EVP_PKEY_asn1_set_private(EVP_PKEY_ASN1_METHOD *ameth,
981 int (*priv_decode)(EVP_PKEY *pk, PKCS8_PRIV_KEY_INFO *p8inf),
982 int (*priv_encode)(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pk),
983 int (*priv_print)(BIO *out, const EVP_PKEY *pkey, int indent,
984 ASN1_PCTX *pctx));
985void EVP_PKEY_asn1_set_param(EVP_PKEY_ASN1_METHOD *ameth,
986 int (*param_decode)(EVP_PKEY *pkey,
987 const unsigned char **pder, int derlen),
988 int (*param_encode)(const EVP_PKEY *pkey, unsigned char **pder),
989 int (*param_missing)(const EVP_PKEY *pk),
990 int (*param_copy)(EVP_PKEY *to, const EVP_PKEY *from),
991 int (*param_cmp)(const EVP_PKEY *a, const EVP_PKEY *b),
992 int (*param_print)(BIO *out, const EVP_PKEY *pkey, int indent,
993 ASN1_PCTX *pctx));
994
995void EVP_PKEY_asn1_set_free(EVP_PKEY_ASN1_METHOD *ameth,
996 void (*pkey_free)(EVP_PKEY *pkey));
997void EVP_PKEY_asn1_set_ctrl(EVP_PKEY_ASN1_METHOD *ameth,
998 int (*pkey_ctrl)(EVP_PKEY *pkey, int op,
999 long arg1, void *arg2));
1000
1001
1002#define EVP_PKEY_OP_UNDEFINED 0
1003#define EVP_PKEY_OP_PARAMGEN (1<<1)
1004#define EVP_PKEY_OP_KEYGEN (1<<2)
1005#define EVP_PKEY_OP_SIGN (1<<3)
1006#define EVP_PKEY_OP_VERIFY (1<<4)
1007#define EVP_PKEY_OP_VERIFYRECOVER (1<<5)
1008#define EVP_PKEY_OP_SIGNCTX (1<<6)
1009#define EVP_PKEY_OP_VERIFYCTX (1<<7)
1010#define EVP_PKEY_OP_ENCRYPT (1<<8)
1011#define EVP_PKEY_OP_DECRYPT (1<<9)
1012#define EVP_PKEY_OP_DERIVE (1<<10)
1013
1014#define EVP_PKEY_OP_TYPE_SIG \
1015 (EVP_PKEY_OP_SIGN | EVP_PKEY_OP_VERIFY | EVP_PKEY_OP_VERIFYRECOVER \
1016 | EVP_PKEY_OP_SIGNCTX | EVP_PKEY_OP_VERIFYCTX)
1017
1018#define EVP_PKEY_OP_TYPE_CRYPT \
1019 (EVP_PKEY_OP_ENCRYPT | EVP_PKEY_OP_DECRYPT)
1020
1021#define EVP_PKEY_OP_TYPE_NOGEN \
1022 (EVP_PKEY_OP_SIG | EVP_PKEY_OP_CRYPT | EVP_PKEY_OP_DERIVE)
1023
1024#define EVP_PKEY_OP_TYPE_GEN \
1025 (EVP_PKEY_OP_PARAMGEN | EVP_PKEY_OP_KEYGEN)
1026
1027#define EVP_PKEY_CTX_set_signature_md(ctx, md) \
1028 EVP_PKEY_CTX_ctrl(ctx, -1, EVP_PKEY_OP_TYPE_SIG, \
1029 EVP_PKEY_CTRL_MD, 0, (void *)md)
1030
1031#define EVP_PKEY_CTRL_MD 1
1032#define EVP_PKEY_CTRL_PEER_KEY 2
1033
1034#define EVP_PKEY_CTRL_PKCS7_ENCRYPT 3
1035#define EVP_PKEY_CTRL_PKCS7_DECRYPT 4
1036
1037#define EVP_PKEY_CTRL_PKCS7_SIGN 5
1038
1039#define EVP_PKEY_CTRL_SET_MAC_KEY 6
1040
1041#define EVP_PKEY_CTRL_DIGESTINIT 7
1042
1043/* Used by GOST key encryption in TLS */
1044#define EVP_PKEY_CTRL_SET_IV 8
1045
1046#define EVP_PKEY_CTRL_CMS_ENCRYPT 9
1047#define EVP_PKEY_CTRL_CMS_DECRYPT 10
1048#define EVP_PKEY_CTRL_CMS_SIGN 11
1049
1050#define EVP_PKEY_ALG_CTRL 0x1000
1051
1052
1053#define EVP_PKEY_FLAG_AUTOARGLEN 2
1054
1055const EVP_PKEY_METHOD *EVP_PKEY_meth_find(int type);
1056EVP_PKEY_METHOD* EVP_PKEY_meth_new(int id, int flags);
1057void EVP_PKEY_meth_free(EVP_PKEY_METHOD *pmeth);
1058int EVP_PKEY_meth_add0(const EVP_PKEY_METHOD *pmeth);
1059
1060EVP_PKEY_CTX *EVP_PKEY_CTX_new(EVP_PKEY *pkey, ENGINE *e);
1061EVP_PKEY_CTX *EVP_PKEY_CTX_new_id(int id, ENGINE *e);
1062EVP_PKEY_CTX *EVP_PKEY_CTX_dup(EVP_PKEY_CTX *ctx);
1063void EVP_PKEY_CTX_free(EVP_PKEY_CTX *ctx);
1064
1065int EVP_PKEY_CTX_ctrl(EVP_PKEY_CTX *ctx, int keytype, int optype,
1066 int cmd, int p1, void *p2);
1067int EVP_PKEY_CTX_ctrl_str(EVP_PKEY_CTX *ctx, const char *type,
1068 const char *value);
1069
1070int EVP_PKEY_CTX_get_operation(EVP_PKEY_CTX *ctx);
1071void EVP_PKEY_CTX_set0_keygen_info(EVP_PKEY_CTX *ctx, int *dat, int datlen);
1072
1073EVP_PKEY *EVP_PKEY_new_mac_key(int type, ENGINE *e,
1074 unsigned char *key, int keylen);
1075
1076void EVP_PKEY_CTX_set_data(EVP_PKEY_CTX *ctx, void *data);
1077void *EVP_PKEY_CTX_get_data(EVP_PKEY_CTX *ctx);
1078EVP_PKEY *EVP_PKEY_CTX_get0_pkey(EVP_PKEY_CTX *ctx);
1079
1080EVP_PKEY *EVP_PKEY_CTX_get0_peerkey(EVP_PKEY_CTX *ctx);
1081
1082void EVP_PKEY_CTX_set_app_data(EVP_PKEY_CTX *ctx, void *data);
1083void *EVP_PKEY_CTX_get_app_data(EVP_PKEY_CTX *ctx);
1084
1085int EVP_PKEY_sign_init(EVP_PKEY_CTX *ctx);
1086int EVP_PKEY_sign(EVP_PKEY_CTX *ctx,
1087 unsigned char *sig, size_t *siglen,
1088 const unsigned char *tbs, size_t tbslen);
1089int EVP_PKEY_verify_init(EVP_PKEY_CTX *ctx);
1090int EVP_PKEY_verify(EVP_PKEY_CTX *ctx,
1091 const unsigned char *sig, size_t siglen,
1092 const unsigned char *tbs, size_t tbslen);
1093int EVP_PKEY_verify_recover_init(EVP_PKEY_CTX *ctx);
1094int EVP_PKEY_verify_recover(EVP_PKEY_CTX *ctx,
1095 unsigned char *rout, size_t *routlen,
1096 const unsigned char *sig, size_t siglen);
1097int EVP_PKEY_encrypt_init(EVP_PKEY_CTX *ctx);
1098int EVP_PKEY_encrypt(EVP_PKEY_CTX *ctx,
1099 unsigned char *out, size_t *outlen,
1100 const unsigned char *in, size_t inlen);
1101int EVP_PKEY_decrypt_init(EVP_PKEY_CTX *ctx);
1102int EVP_PKEY_decrypt(EVP_PKEY_CTX *ctx,
1103 unsigned char *out, size_t *outlen,
1104 const unsigned char *in, size_t inlen);
1105
1106int EVP_PKEY_derive_init(EVP_PKEY_CTX *ctx);
1107int EVP_PKEY_derive_set_peer(EVP_PKEY_CTX *ctx, EVP_PKEY *peer);
1108int EVP_PKEY_derive(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen);
1109
1110typedef int EVP_PKEY_gen_cb(EVP_PKEY_CTX *ctx);
1111
1112int EVP_PKEY_paramgen_init(EVP_PKEY_CTX *ctx);
1113int EVP_PKEY_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey);
1114int EVP_PKEY_keygen_init(EVP_PKEY_CTX *ctx);
1115int EVP_PKEY_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey);
1116
1117void EVP_PKEY_CTX_set_cb(EVP_PKEY_CTX *ctx, EVP_PKEY_gen_cb *cb);
1118EVP_PKEY_gen_cb *EVP_PKEY_CTX_get_cb(EVP_PKEY_CTX *ctx);
1119
1120int EVP_PKEY_CTX_get_keygen_info(EVP_PKEY_CTX *ctx, int idx);
1121
1122void EVP_PKEY_meth_set_init(EVP_PKEY_METHOD *pmeth,
1123 int (*init)(EVP_PKEY_CTX *ctx));
1124
1125void EVP_PKEY_meth_set_copy(EVP_PKEY_METHOD *pmeth,
1126 int (*copy)(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src));
1127
1128void EVP_PKEY_meth_set_cleanup(EVP_PKEY_METHOD *pmeth,
1129 void (*cleanup)(EVP_PKEY_CTX *ctx));
1130
1131void EVP_PKEY_meth_set_paramgen(EVP_PKEY_METHOD *pmeth,
1132 int (*paramgen_init)(EVP_PKEY_CTX *ctx),
1133 int (*paramgen)(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey));
1134
1135void EVP_PKEY_meth_set_keygen(EVP_PKEY_METHOD *pmeth,
1136 int (*keygen_init)(EVP_PKEY_CTX *ctx),
1137 int (*keygen)(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey));
946 1138
947void EVP_add_alg_module(void); 1139void EVP_PKEY_meth_set_sign(EVP_PKEY_METHOD *pmeth,
1140 int (*sign_init)(EVP_PKEY_CTX *ctx),
1141 int (*sign)(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen,
1142 const unsigned char *tbs, size_t tbslen));
1143
1144void EVP_PKEY_meth_set_verify(EVP_PKEY_METHOD *pmeth,
1145 int (*verify_init)(EVP_PKEY_CTX *ctx),
1146 int (*verify)(EVP_PKEY_CTX *ctx, const unsigned char *sig, size_t siglen,
1147 const unsigned char *tbs, size_t tbslen));
1148
1149void EVP_PKEY_meth_set_verify_recover(EVP_PKEY_METHOD *pmeth,
1150 int (*verify_recover_init)(EVP_PKEY_CTX *ctx),
1151 int (*verify_recover)(EVP_PKEY_CTX *ctx,
1152 unsigned char *sig, size_t *siglen,
1153 const unsigned char *tbs, size_t tbslen));
1154
1155void EVP_PKEY_meth_set_signctx(EVP_PKEY_METHOD *pmeth,
1156 int (*signctx_init)(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx),
1157 int (*signctx)(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen,
1158 EVP_MD_CTX *mctx));
1159
1160void EVP_PKEY_meth_set_verifyctx(EVP_PKEY_METHOD *pmeth,
1161 int (*verifyctx_init)(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx),
1162 int (*verifyctx)(EVP_PKEY_CTX *ctx, const unsigned char *sig,int siglen,
1163 EVP_MD_CTX *mctx));
1164
1165void EVP_PKEY_meth_set_encrypt(EVP_PKEY_METHOD *pmeth,
1166 int (*encrypt_init)(EVP_PKEY_CTX *ctx),
1167 int (*encryptfn)(EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen,
1168 const unsigned char *in, size_t inlen));
1169
1170void EVP_PKEY_meth_set_decrypt(EVP_PKEY_METHOD *pmeth,
1171 int (*decrypt_init)(EVP_PKEY_CTX *ctx),
1172 int (*decrypt)(EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen,
1173 const unsigned char *in, size_t inlen));
1174
1175void EVP_PKEY_meth_set_derive(EVP_PKEY_METHOD *pmeth,
1176 int (*derive_init)(EVP_PKEY_CTX *ctx),
1177 int (*derive)(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen));
1178
1179void EVP_PKEY_meth_set_ctrl(EVP_PKEY_METHOD *pmeth,
1180 int (*ctrl)(EVP_PKEY_CTX *ctx, int type, int p1, void *p2),
1181 int (*ctrl_str)(EVP_PKEY_CTX *ctx,
1182 const char *type, const char *value));
948 1183
949/* BEGIN ERROR CODES */ 1184/* BEGIN ERROR CODES */
950/* The following lines are auto generated by the script mkerr.pl. Any changes 1185/* The following lines are auto generated by the script mkerr.pl. Any changes
@@ -956,46 +1191,66 @@ void ERR_load_EVP_strings(void);
956 1191
957/* Function codes. */ 1192/* Function codes. */
958#define EVP_F_AES_INIT_KEY 133 1193#define EVP_F_AES_INIT_KEY 133
959#define EVP_F_ALG_MODULE_INIT 138
960#define EVP_F_CAMELLIA_INIT_KEY 159 1194#define EVP_F_CAMELLIA_INIT_KEY 159
961#define EVP_F_D2I_PKEY 100 1195#define EVP_F_D2I_PKEY 100
962#define EVP_F_DO_EVP_ENC_ENGINE 140 1196#define EVP_F_DO_SIGVER_INIT 161
963#define EVP_F_DO_EVP_ENC_ENGINE_FULL 141
964#define EVP_F_DO_EVP_MD_ENGINE 139
965#define EVP_F_DO_EVP_MD_ENGINE_FULL 142
966#define EVP_F_DSAPKEY2PKCS8 134 1197#define EVP_F_DSAPKEY2PKCS8 134
967#define EVP_F_DSA_PKEY2PKCS8 135 1198#define EVP_F_DSA_PKEY2PKCS8 135
968#define EVP_F_ECDSA_PKEY2PKCS8 129 1199#define EVP_F_ECDSA_PKEY2PKCS8 129
969#define EVP_F_ECKEY_PKEY2PKCS8 132 1200#define EVP_F_ECKEY_PKEY2PKCS8 132
970#define EVP_F_EVP_CIPHERINIT 137
971#define EVP_F_EVP_CIPHERINIT_EX 123 1201#define EVP_F_EVP_CIPHERINIT_EX 123
1202#define EVP_F_EVP_CIPHER_CTX_COPY 163
972#define EVP_F_EVP_CIPHER_CTX_CTRL 124 1203#define EVP_F_EVP_CIPHER_CTX_CTRL 124
973#define EVP_F_EVP_CIPHER_CTX_SET_KEY_LENGTH 122 1204#define EVP_F_EVP_CIPHER_CTX_SET_KEY_LENGTH 122
974#define EVP_F_EVP_DECRYPTFINAL_EX 101 1205#define EVP_F_EVP_DECRYPTFINAL_EX 101
975#define EVP_F_EVP_DIGESTINIT 136
976#define EVP_F_EVP_DIGESTINIT_EX 128 1206#define EVP_F_EVP_DIGESTINIT_EX 128
977#define EVP_F_EVP_ENCRYPTFINAL_EX 127 1207#define EVP_F_EVP_ENCRYPTFINAL_EX 127
978#define EVP_F_EVP_MD_CTX_COPY_EX 110 1208#define EVP_F_EVP_MD_CTX_COPY_EX 110
1209#define EVP_F_EVP_MD_SIZE 162
979#define EVP_F_EVP_OPENINIT 102 1210#define EVP_F_EVP_OPENINIT 102
980#define EVP_F_EVP_PBE_ALG_ADD 115 1211#define EVP_F_EVP_PBE_ALG_ADD 115
1212#define EVP_F_EVP_PBE_ALG_ADD_TYPE 160
981#define EVP_F_EVP_PBE_CIPHERINIT 116 1213#define EVP_F_EVP_PBE_CIPHERINIT 116
982#define EVP_F_EVP_PKCS82PKEY 111 1214#define EVP_F_EVP_PKCS82PKEY 111
1215#define EVP_F_EVP_PKCS82PKEY_BROKEN 136
983#define EVP_F_EVP_PKEY2PKCS8_BROKEN 113 1216#define EVP_F_EVP_PKEY2PKCS8_BROKEN 113
984#define EVP_F_EVP_PKEY_COPY_PARAMETERS 103 1217#define EVP_F_EVP_PKEY_COPY_PARAMETERS 103
1218#define EVP_F_EVP_PKEY_CTX_CTRL 137
1219#define EVP_F_EVP_PKEY_CTX_CTRL_STR 150
1220#define EVP_F_EVP_PKEY_CTX_DUP 156
985#define EVP_F_EVP_PKEY_DECRYPT 104 1221#define EVP_F_EVP_PKEY_DECRYPT 104
1222#define EVP_F_EVP_PKEY_DECRYPT_INIT 138
1223#define EVP_F_EVP_PKEY_DECRYPT_OLD 151
1224#define EVP_F_EVP_PKEY_DERIVE 153
1225#define EVP_F_EVP_PKEY_DERIVE_INIT 154
1226#define EVP_F_EVP_PKEY_DERIVE_SET_PEER 155
986#define EVP_F_EVP_PKEY_ENCRYPT 105 1227#define EVP_F_EVP_PKEY_ENCRYPT 105
1228#define EVP_F_EVP_PKEY_ENCRYPT_INIT 139
1229#define EVP_F_EVP_PKEY_ENCRYPT_OLD 152
987#define EVP_F_EVP_PKEY_GET1_DH 119 1230#define EVP_F_EVP_PKEY_GET1_DH 119
988#define EVP_F_EVP_PKEY_GET1_DSA 120 1231#define EVP_F_EVP_PKEY_GET1_DSA 120
989#define EVP_F_EVP_PKEY_GET1_ECDSA 130 1232#define EVP_F_EVP_PKEY_GET1_ECDSA 130
990#define EVP_F_EVP_PKEY_GET1_EC_KEY 131 1233#define EVP_F_EVP_PKEY_GET1_EC_KEY 131
991#define EVP_F_EVP_PKEY_GET1_RSA 121 1234#define EVP_F_EVP_PKEY_GET1_RSA 121
1235#define EVP_F_EVP_PKEY_KEYGEN 146
1236#define EVP_F_EVP_PKEY_KEYGEN_INIT 147
992#define EVP_F_EVP_PKEY_NEW 106 1237#define EVP_F_EVP_PKEY_NEW 106
1238#define EVP_F_EVP_PKEY_PARAMGEN 148
1239#define EVP_F_EVP_PKEY_PARAMGEN_INIT 149
1240#define EVP_F_EVP_PKEY_SIGN 140
1241#define EVP_F_EVP_PKEY_SIGN_INIT 141
1242#define EVP_F_EVP_PKEY_VERIFY 142
1243#define EVP_F_EVP_PKEY_VERIFY_INIT 143
1244#define EVP_F_EVP_PKEY_VERIFY_RECOVER 144
1245#define EVP_F_EVP_PKEY_VERIFY_RECOVER_INIT 145
993#define EVP_F_EVP_RIJNDAEL 126 1246#define EVP_F_EVP_RIJNDAEL 126
994#define EVP_F_EVP_SIGNFINAL 107 1247#define EVP_F_EVP_SIGNFINAL 107
995#define EVP_F_EVP_VERIFYFINAL 108 1248#define EVP_F_EVP_VERIFYFINAL 108
1249#define EVP_F_INT_CTX_NEW 157
996#define EVP_F_PKCS5_PBE_KEYIVGEN 117 1250#define EVP_F_PKCS5_PBE_KEYIVGEN 117
997#define EVP_F_PKCS5_V2_PBE_KEYIVGEN 118 1251#define EVP_F_PKCS5_V2_PBE_KEYIVGEN 118
998#define EVP_F_PKCS8_SET_BROKEN 112 1252#define EVP_F_PKCS8_SET_BROKEN 112
1253#define EVP_F_PKEY_SET_TYPE 158
999#define EVP_F_RC2_MAGIC_TO_METH 109 1254#define EVP_F_RC2_MAGIC_TO_METH 109
1000#define EVP_F_RC5_CTRL 125 1255#define EVP_F_RC5_CTRL 125
1001 1256
@@ -1007,41 +1262,52 @@ void ERR_load_EVP_strings(void);
1007#define EVP_R_BAD_KEY_LENGTH 137 1262#define EVP_R_BAD_KEY_LENGTH 137
1008#define EVP_R_BN_DECODE_ERROR 112 1263#define EVP_R_BN_DECODE_ERROR 112
1009#define EVP_R_BN_PUBKEY_ERROR 113 1264#define EVP_R_BN_PUBKEY_ERROR 113
1265#define EVP_R_BUFFER_TOO_SMALL 155
1010#define EVP_R_CAMELLIA_KEY_SETUP_FAILED 157 1266#define EVP_R_CAMELLIA_KEY_SETUP_FAILED 157
1011#define EVP_R_CIPHER_PARAMETER_ERROR 122 1267#define EVP_R_CIPHER_PARAMETER_ERROR 122
1268#define EVP_R_COMMAND_NOT_SUPPORTED 147
1012#define EVP_R_CTRL_NOT_IMPLEMENTED 132 1269#define EVP_R_CTRL_NOT_IMPLEMENTED 132
1013#define EVP_R_CTRL_OPERATION_NOT_IMPLEMENTED 133 1270#define EVP_R_CTRL_OPERATION_NOT_IMPLEMENTED 133
1014#define EVP_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH 138 1271#define EVP_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH 138
1015#define EVP_R_DECODE_ERROR 114 1272#define EVP_R_DECODE_ERROR 114
1016#define EVP_R_DIFFERENT_KEY_TYPES 101 1273#define EVP_R_DIFFERENT_KEY_TYPES 101
1017#define EVP_R_DISABLED_FOR_FIPS 144 1274#define EVP_R_DIFFERENT_PARAMETERS 153
1018#define EVP_R_ENCODE_ERROR 115 1275#define EVP_R_ENCODE_ERROR 115
1019#define EVP_R_ERROR_LOADING_SECTION 145
1020#define EVP_R_ERROR_SETTING_FIPS_MODE 146
1021#define EVP_R_EVP_PBE_CIPHERINIT_ERROR 119 1276#define EVP_R_EVP_PBE_CIPHERINIT_ERROR 119
1022#define EVP_R_EXPECTING_AN_RSA_KEY 127 1277#define EVP_R_EXPECTING_AN_RSA_KEY 127
1023#define EVP_R_EXPECTING_A_DH_KEY 128 1278#define EVP_R_EXPECTING_A_DH_KEY 128
1024#define EVP_R_EXPECTING_A_DSA_KEY 129 1279#define EVP_R_EXPECTING_A_DSA_KEY 129
1025#define EVP_R_EXPECTING_A_ECDSA_KEY 141 1280#define EVP_R_EXPECTING_A_ECDSA_KEY 141
1026#define EVP_R_EXPECTING_A_EC_KEY 142 1281#define EVP_R_EXPECTING_A_EC_KEY 142
1027#define EVP_R_FIPS_MODE_NOT_SUPPORTED 147
1028#define EVP_R_INITIALIZATION_ERROR 134 1282#define EVP_R_INITIALIZATION_ERROR 134
1029#define EVP_R_INPUT_NOT_INITIALIZED 111 1283#define EVP_R_INPUT_NOT_INITIALIZED 111
1030#define EVP_R_INVALID_FIPS_MODE 148 1284#define EVP_R_INVALID_DIGEST 152
1031#define EVP_R_INVALID_KEY_LENGTH 130 1285#define EVP_R_INVALID_KEY_LENGTH 130
1286#define EVP_R_INVALID_OPERATION 148
1032#define EVP_R_IV_TOO_LARGE 102 1287#define EVP_R_IV_TOO_LARGE 102
1033#define EVP_R_KEYGEN_FAILURE 120 1288#define EVP_R_KEYGEN_FAILURE 120
1289#define EVP_R_MESSAGE_DIGEST_IS_NULL 159
1290#define EVP_R_METHOD_NOT_SUPPORTED 144
1034#define EVP_R_MISSING_PARAMETERS 103 1291#define EVP_R_MISSING_PARAMETERS 103
1035#define EVP_R_NO_CIPHER_SET 131 1292#define EVP_R_NO_CIPHER_SET 131
1293#define EVP_R_NO_DEFAULT_DIGEST 158
1036#define EVP_R_NO_DIGEST_SET 139 1294#define EVP_R_NO_DIGEST_SET 139
1037#define EVP_R_NO_DSA_PARAMETERS 116 1295#define EVP_R_NO_DSA_PARAMETERS 116
1296#define EVP_R_NO_KEY_SET 154
1297#define EVP_R_NO_OPERATION_SET 149
1038#define EVP_R_NO_SIGN_FUNCTION_CONFIGURED 104 1298#define EVP_R_NO_SIGN_FUNCTION_CONFIGURED 104
1039#define EVP_R_NO_VERIFY_FUNCTION_CONFIGURED 105 1299#define EVP_R_NO_VERIFY_FUNCTION_CONFIGURED 105
1300#define EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE 150
1301#define EVP_R_OPERATON_NOT_INITIALIZED 151
1040#define EVP_R_PKCS8_UNKNOWN_BROKEN_TYPE 117 1302#define EVP_R_PKCS8_UNKNOWN_BROKEN_TYPE 117
1303#define EVP_R_PRIVATE_KEY_DECODE_ERROR 145
1304#define EVP_R_PRIVATE_KEY_ENCODE_ERROR 146
1041#define EVP_R_PUBLIC_KEY_NOT_RSA 106 1305#define EVP_R_PUBLIC_KEY_NOT_RSA 106
1042#define EVP_R_UNKNOWN_OPTION 149 1306#define EVP_R_UNKNOWN_CIPHER 160
1307#define EVP_R_UNKNOWN_DIGEST 161
1043#define EVP_R_UNKNOWN_PBE_ALGORITHM 121 1308#define EVP_R_UNKNOWN_PBE_ALGORITHM 121
1044#define EVP_R_UNSUPORTED_NUMBER_OF_ROUNDS 135 1309#define EVP_R_UNSUPORTED_NUMBER_OF_ROUNDS 135
1310#define EVP_R_UNSUPPORTED_ALGORITHM 156
1045#define EVP_R_UNSUPPORTED_CIPHER 107 1311#define EVP_R_UNSUPPORTED_CIPHER 107
1046#define EVP_R_UNSUPPORTED_KEYLENGTH 123 1312#define EVP_R_UNSUPPORTED_KEYLENGTH 123
1047#define EVP_R_UNSUPPORTED_KEY_DERIVATION_FUNCTION 124 1313#define EVP_R_UNSUPPORTED_KEY_DERIVATION_FUNCTION 124
@@ -1051,7 +1317,6 @@ void ERR_load_EVP_strings(void);
1051#define EVP_R_UNSUPPORTED_SALT_TYPE 126 1317#define EVP_R_UNSUPPORTED_SALT_TYPE 126
1052#define EVP_R_WRONG_FINAL_BLOCK_LENGTH 109 1318#define EVP_R_WRONG_FINAL_BLOCK_LENGTH 109
1053#define EVP_R_WRONG_PUBLIC_KEY_TYPE 110 1319#define EVP_R_WRONG_PUBLIC_KEY_TYPE 110
1054#define EVP_R_SEED_KEY_SETUP_FAILED 162
1055 1320
1056#ifdef __cplusplus 1321#ifdef __cplusplus
1057} 1322}
diff --git a/src/lib/libcrypto/evp/evp_enc.c b/src/lib/libcrypto/evp/evp_enc.c
index 30e0ca4d9f..bead6a2170 100644
--- a/src/lib/libcrypto/evp/evp_enc.c
+++ b/src/lib/libcrypto/evp/evp_enc.c
@@ -66,16 +66,14 @@
66#endif 66#endif
67#include "evp_locl.h" 67#include "evp_locl.h"
68 68
69#ifdef OPENSSL_FIPS
70 #define M_do_cipher(ctx, out, in, inl) \
71 EVP_Cipher(ctx,out,in,inl)
72#else
73 #define M_do_cipher(ctx, out, in, inl) \
74 ctx->cipher->do_cipher(ctx,out,in,inl)
75#endif
76
77const char EVP_version[]="EVP" OPENSSL_VERSION_PTEXT; 69const char EVP_version[]="EVP" OPENSSL_VERSION_PTEXT;
78 70
71void EVP_CIPHER_CTX_init(EVP_CIPHER_CTX *ctx)
72 {
73 memset(ctx,0,sizeof(EVP_CIPHER_CTX));
74 /* ctx->cipher=NULL; */
75 }
76
79EVP_CIPHER_CTX *EVP_CIPHER_CTX_new(void) 77EVP_CIPHER_CTX *EVP_CIPHER_CTX_new(void)
80 { 78 {
81 EVP_CIPHER_CTX *ctx=OPENSSL_malloc(sizeof *ctx); 79 EVP_CIPHER_CTX *ctx=OPENSSL_malloc(sizeof *ctx);
@@ -92,6 +90,144 @@ int EVP_CipherInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher,
92 return EVP_CipherInit_ex(ctx,cipher,NULL,key,iv,enc); 90 return EVP_CipherInit_ex(ctx,cipher,NULL,key,iv,enc);
93 } 91 }
94 92
93int EVP_CipherInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, ENGINE *impl,
94 const unsigned char *key, const unsigned char *iv, int enc)
95 {
96 if (enc == -1)
97 enc = ctx->encrypt;
98 else
99 {
100 if (enc)
101 enc = 1;
102 ctx->encrypt = enc;
103 }
104#ifndef OPENSSL_NO_ENGINE
105 /* Whether it's nice or not, "Inits" can be used on "Final"'d contexts
106 * so this context may already have an ENGINE! Try to avoid releasing
107 * the previous handle, re-querying for an ENGINE, and having a
108 * reinitialisation, when it may all be unecessary. */
109 if (ctx->engine && ctx->cipher && (!cipher ||
110 (cipher && (cipher->nid == ctx->cipher->nid))))
111 goto skip_to_init;
112#endif
113 if (cipher)
114 {
115 /* Ensure a context left lying around from last time is cleared
116 * (the previous check attempted to avoid this if the same
117 * ENGINE and EVP_CIPHER could be used). */
118 EVP_CIPHER_CTX_cleanup(ctx);
119
120 /* Restore encrypt field: it is zeroed by cleanup */
121 ctx->encrypt = enc;
122#ifndef OPENSSL_NO_ENGINE
123 if(impl)
124 {
125 if (!ENGINE_init(impl))
126 {
127 EVPerr(EVP_F_EVP_CIPHERINIT_EX, EVP_R_INITIALIZATION_ERROR);
128 return 0;
129 }
130 }
131 else
132 /* Ask if an ENGINE is reserved for this job */
133 impl = ENGINE_get_cipher_engine(cipher->nid);
134 if(impl)
135 {
136 /* There's an ENGINE for this job ... (apparently) */
137 const EVP_CIPHER *c = ENGINE_get_cipher(impl, cipher->nid);
138 if(!c)
139 {
140 /* One positive side-effect of US's export
141 * control history, is that we should at least
142 * be able to avoid using US mispellings of
143 * "initialisation"? */
144 EVPerr(EVP_F_EVP_CIPHERINIT_EX, EVP_R_INITIALIZATION_ERROR);
145 return 0;
146 }
147 /* We'll use the ENGINE's private cipher definition */
148 cipher = c;
149 /* Store the ENGINE functional reference so we know
150 * 'cipher' came from an ENGINE and we need to release
151 * it when done. */
152 ctx->engine = impl;
153 }
154 else
155 ctx->engine = NULL;
156#endif
157
158 ctx->cipher=cipher;
159 if (ctx->cipher->ctx_size)
160 {
161 ctx->cipher_data=OPENSSL_malloc(ctx->cipher->ctx_size);
162 if (!ctx->cipher_data)
163 {
164 EVPerr(EVP_F_EVP_CIPHERINIT_EX, ERR_R_MALLOC_FAILURE);
165 return 0;
166 }
167 }
168 else
169 {
170 ctx->cipher_data = NULL;
171 }
172 ctx->key_len = cipher->key_len;
173 ctx->flags = 0;
174 if(ctx->cipher->flags & EVP_CIPH_CTRL_INIT)
175 {
176 if(!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_INIT, 0, NULL))
177 {
178 EVPerr(EVP_F_EVP_CIPHERINIT_EX, EVP_R_INITIALIZATION_ERROR);
179 return 0;
180 }
181 }
182 }
183 else if(!ctx->cipher)
184 {
185 EVPerr(EVP_F_EVP_CIPHERINIT_EX, EVP_R_NO_CIPHER_SET);
186 return 0;
187 }
188#ifndef OPENSSL_NO_ENGINE
189skip_to_init:
190#endif
191 /* we assume block size is a power of 2 in *cryptUpdate */
192 OPENSSL_assert(ctx->cipher->block_size == 1
193 || ctx->cipher->block_size == 8
194 || ctx->cipher->block_size == 16);
195
196 if(!(EVP_CIPHER_CTX_flags(ctx) & EVP_CIPH_CUSTOM_IV)) {
197 switch(EVP_CIPHER_CTX_mode(ctx)) {
198
199 case EVP_CIPH_STREAM_CIPHER:
200 case EVP_CIPH_ECB_MODE:
201 break;
202
203 case EVP_CIPH_CFB_MODE:
204 case EVP_CIPH_OFB_MODE:
205
206 ctx->num = 0;
207
208 case EVP_CIPH_CBC_MODE:
209
210 OPENSSL_assert(EVP_CIPHER_CTX_iv_length(ctx) <=
211 (int)sizeof(ctx->iv));
212 if(iv) memcpy(ctx->oiv, iv, EVP_CIPHER_CTX_iv_length(ctx));
213 memcpy(ctx->iv, ctx->oiv, EVP_CIPHER_CTX_iv_length(ctx));
214 break;
215
216 default:
217 return 0;
218 break;
219 }
220 }
221
222 if(key || (ctx->cipher->flags & EVP_CIPH_ALWAYS_CALL_INIT)) {
223 if(!ctx->cipher->init(ctx,key,iv,enc)) return 0;
224 }
225 ctx->buf_len=0;
226 ctx->final_used=0;
227 ctx->block_mask=ctx->cipher->block_size-1;
228 return 1;
229 }
230
95int EVP_CipherUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl, 231int EVP_CipherUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl,
96 const unsigned char *in, int inl) 232 const unsigned char *in, int inl)
97 { 233 {
@@ -151,7 +287,7 @@ int EVP_EncryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl,
151 287
152 if(ctx->buf_len == 0 && (inl&(ctx->block_mask)) == 0) 288 if(ctx->buf_len == 0 && (inl&(ctx->block_mask)) == 0)
153 { 289 {
154 if(M_do_cipher(ctx,out,in,inl)) 290 if(ctx->cipher->do_cipher(ctx,out,in,inl))
155 { 291 {
156 *outl=inl; 292 *outl=inl;
157 return 1; 293 return 1;
@@ -178,7 +314,7 @@ int EVP_EncryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl,
178 { 314 {
179 j=bl-i; 315 j=bl-i;
180 memcpy(&(ctx->buf[i]),in,j); 316 memcpy(&(ctx->buf[i]),in,j);
181 if(!M_do_cipher(ctx,out,ctx->buf,bl)) return 0; 317 if(!ctx->cipher->do_cipher(ctx,out,ctx->buf,bl)) return 0;
182 inl-=j; 318 inl-=j;
183 in+=j; 319 in+=j;
184 out+=bl; 320 out+=bl;
@@ -191,7 +327,7 @@ int EVP_EncryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl,
191 inl-=i; 327 inl-=i;
192 if (inl > 0) 328 if (inl > 0)
193 { 329 {
194 if(!M_do_cipher(ctx,out,in,inl)) return 0; 330 if(!ctx->cipher->do_cipher(ctx,out,in,inl)) return 0;
195 *outl+=inl; 331 *outl+=inl;
196 } 332 }
197 333
@@ -235,7 +371,7 @@ int EVP_EncryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
235 n=b-bl; 371 n=b-bl;
236 for (i=bl; i<b; i++) 372 for (i=bl; i<b; i++)
237 ctx->buf[i]=n; 373 ctx->buf[i]=n;
238 ret=M_do_cipher(ctx,out,ctx->buf,b); 374 ret=ctx->cipher->do_cipher(ctx,out,ctx->buf,b);
239 375
240 376
241 if(ret) 377 if(ret)
@@ -357,6 +493,28 @@ void EVP_CIPHER_CTX_free(EVP_CIPHER_CTX *ctx)
357 } 493 }
358 } 494 }
359 495
496int EVP_CIPHER_CTX_cleanup(EVP_CIPHER_CTX *c)
497 {
498 if (c->cipher != NULL)
499 {
500 if(c->cipher->cleanup && !c->cipher->cleanup(c))
501 return 0;
502 /* Cleanse cipher context data */
503 if (c->cipher_data)
504 OPENSSL_cleanse(c->cipher_data, c->cipher->ctx_size);
505 }
506 if (c->cipher_data)
507 OPENSSL_free(c->cipher_data);
508#ifndef OPENSSL_NO_ENGINE
509 if (c->engine)
510 /* The EVP_CIPHER we used belongs to an ENGINE, release the
511 * functional reference we held for this reason. */
512 ENGINE_finish(c->engine);
513#endif
514 memset(c,0,sizeof(EVP_CIPHER_CTX));
515 return 1;
516 }
517
360int EVP_CIPHER_CTX_set_key_length(EVP_CIPHER_CTX *c, int keylen) 518int EVP_CIPHER_CTX_set_key_length(EVP_CIPHER_CTX *c, int keylen)
361 { 519 {
362 if(c->cipher->flags & EVP_CIPH_CUSTOM_KEY_LENGTH) 520 if(c->cipher->flags & EVP_CIPH_CUSTOM_KEY_LENGTH)
@@ -378,6 +536,27 @@ int EVP_CIPHER_CTX_set_padding(EVP_CIPHER_CTX *ctx, int pad)
378 return 1; 536 return 1;
379 } 537 }
380 538
539int EVP_CIPHER_CTX_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr)
540{
541 int ret;
542 if(!ctx->cipher) {
543 EVPerr(EVP_F_EVP_CIPHER_CTX_CTRL, EVP_R_NO_CIPHER_SET);
544 return 0;
545 }
546
547 if(!ctx->cipher->ctrl) {
548 EVPerr(EVP_F_EVP_CIPHER_CTX_CTRL, EVP_R_CTRL_NOT_IMPLEMENTED);
549 return 0;
550 }
551
552 ret = ctx->cipher->ctrl(ctx, type, arg, ptr);
553 if(ret == -1) {
554 EVPerr(EVP_F_EVP_CIPHER_CTX_CTRL, EVP_R_CTRL_OPERATION_NOT_IMPLEMENTED);
555 return 0;
556 }
557 return ret;
558}
559
381int EVP_CIPHER_CTX_rand_key(EVP_CIPHER_CTX *ctx, unsigned char *key) 560int EVP_CIPHER_CTX_rand_key(EVP_CIPHER_CTX *ctx, unsigned char *key)
382 { 561 {
383 if (ctx->cipher->flags & EVP_CIPH_RAND_KEY) 562 if (ctx->cipher->flags & EVP_CIPH_RAND_KEY)
@@ -387,54 +566,38 @@ int EVP_CIPHER_CTX_rand_key(EVP_CIPHER_CTX *ctx, unsigned char *key)
387 return 1; 566 return 1;
388 } 567 }
389 568
390#ifndef OPENSSL_NO_ENGINE 569int EVP_CIPHER_CTX_copy(EVP_CIPHER_CTX *out, const EVP_CIPHER_CTX *in)
391
392#ifdef OPENSSL_FIPS
393
394static int do_evp_enc_engine_full(EVP_CIPHER_CTX *ctx, const EVP_CIPHER **pcipher, ENGINE *impl)
395 { 570 {
396 if(impl) 571 if ((in == NULL) || (in->cipher == NULL))
397 { 572 {
398 if (!ENGINE_init(impl)) 573 EVPerr(EVP_F_EVP_CIPHER_CTX_COPY,EVP_R_INPUT_NOT_INITIALIZED);
399 { 574 return 0;
400 EVPerr(EVP_F_DO_EVP_ENC_ENGINE_FULL, EVP_R_INITIALIZATION_ERROR);
401 return 0;
402 }
403 } 575 }
404 else 576#ifndef OPENSSL_NO_ENGINE
405 /* Ask if an ENGINE is reserved for this job */ 577 /* Make sure it's safe to copy a cipher context using an ENGINE */
406 impl = ENGINE_get_cipher_engine((*pcipher)->nid); 578 if (in->engine && !ENGINE_init(in->engine))
407 if(impl) 579 {
580 EVPerr(EVP_F_EVP_CIPHER_CTX_COPY,ERR_R_ENGINE_LIB);
581 return 0;
582 }
583#endif
584
585 EVP_CIPHER_CTX_cleanup(out);
586 memcpy(out,in,sizeof *out);
587
588 if (in->cipher_data && in->cipher->ctx_size)
408 { 589 {
409 /* There's an ENGINE for this job ... (apparently) */ 590 out->cipher_data=OPENSSL_malloc(in->cipher->ctx_size);
410 const EVP_CIPHER *c = ENGINE_get_cipher(impl, (*pcipher)->nid); 591 if (!out->cipher_data)
411 if(!c)
412 { 592 {
413 /* One positive side-effect of US's export 593 EVPerr(EVP_F_EVP_CIPHER_CTX_COPY,ERR_R_MALLOC_FAILURE);
414 * control history, is that we should at least
415 * be able to avoid using US mispellings of
416 * "initialisation"? */
417 EVPerr(EVP_F_DO_EVP_ENC_ENGINE_FULL, EVP_R_INITIALIZATION_ERROR);
418 return 0; 594 return 0;
419 } 595 }
420 /* We'll use the ENGINE's private cipher definition */ 596 memcpy(out->cipher_data,in->cipher_data,in->cipher->ctx_size);
421 *pcipher = c;
422 /* Store the ENGINE functional reference so we know
423 * 'cipher' came from an ENGINE and we need to release
424 * it when done. */
425 ctx->engine = impl;
426 } 597 }
427 else
428 ctx->engine = NULL;
429 return 1;
430 }
431 598
432void int_EVP_CIPHER_init_engine_callbacks(void) 599 if (in->cipher->flags & EVP_CIPH_CUSTOM_COPY)
433 { 600 return in->cipher->ctrl((EVP_CIPHER_CTX *)in, EVP_CTRL_COPY, 0, out);
434 int_EVP_CIPHER_set_engine_callbacks( 601 return 1;
435 ENGINE_finish, do_evp_enc_engine_full);
436 } 602 }
437 603
438#endif
439
440#endif
diff --git a/src/lib/libcrypto/evp/evp_err.c b/src/lib/libcrypto/evp/evp_err.c
index b5b900d4fe..d8bfec0959 100644
--- a/src/lib/libcrypto/evp/evp_err.c
+++ b/src/lib/libcrypto/evp/evp_err.c
@@ -1,6 +1,6 @@
1/* crypto/evp/evp_err.c */ 1/* crypto/evp/evp_err.c */
2/* ==================================================================== 2/* ====================================================================
3 * Copyright (c) 1999-2007 The OpenSSL Project. All rights reserved. 3 * Copyright (c) 1999-2008 The OpenSSL Project. All rights reserved.
4 * 4 *
5 * Redistribution and use in source and binary forms, with or without 5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions 6 * modification, are permitted provided that the following conditions
@@ -71,46 +71,66 @@
71static ERR_STRING_DATA EVP_str_functs[]= 71static ERR_STRING_DATA EVP_str_functs[]=
72 { 72 {
73{ERR_FUNC(EVP_F_AES_INIT_KEY), "AES_INIT_KEY"}, 73{ERR_FUNC(EVP_F_AES_INIT_KEY), "AES_INIT_KEY"},
74{ERR_FUNC(EVP_F_ALG_MODULE_INIT), "ALG_MODULE_INIT"},
75{ERR_FUNC(EVP_F_CAMELLIA_INIT_KEY), "CAMELLIA_INIT_KEY"}, 74{ERR_FUNC(EVP_F_CAMELLIA_INIT_KEY), "CAMELLIA_INIT_KEY"},
76{ERR_FUNC(EVP_F_D2I_PKEY), "D2I_PKEY"}, 75{ERR_FUNC(EVP_F_D2I_PKEY), "D2I_PKEY"},
77{ERR_FUNC(EVP_F_DO_EVP_ENC_ENGINE), "DO_EVP_ENC_ENGINE"}, 76{ERR_FUNC(EVP_F_DO_SIGVER_INIT), "DO_SIGVER_INIT"},
78{ERR_FUNC(EVP_F_DO_EVP_ENC_ENGINE_FULL), "DO_EVP_ENC_ENGINE_FULL"},
79{ERR_FUNC(EVP_F_DO_EVP_MD_ENGINE), "DO_EVP_MD_ENGINE"},
80{ERR_FUNC(EVP_F_DO_EVP_MD_ENGINE_FULL), "DO_EVP_MD_ENGINE_FULL"},
81{ERR_FUNC(EVP_F_DSAPKEY2PKCS8), "DSAPKEY2PKCS8"}, 77{ERR_FUNC(EVP_F_DSAPKEY2PKCS8), "DSAPKEY2PKCS8"},
82{ERR_FUNC(EVP_F_DSA_PKEY2PKCS8), "DSA_PKEY2PKCS8"}, 78{ERR_FUNC(EVP_F_DSA_PKEY2PKCS8), "DSA_PKEY2PKCS8"},
83{ERR_FUNC(EVP_F_ECDSA_PKEY2PKCS8), "ECDSA_PKEY2PKCS8"}, 79{ERR_FUNC(EVP_F_ECDSA_PKEY2PKCS8), "ECDSA_PKEY2PKCS8"},
84{ERR_FUNC(EVP_F_ECKEY_PKEY2PKCS8), "ECKEY_PKEY2PKCS8"}, 80{ERR_FUNC(EVP_F_ECKEY_PKEY2PKCS8), "ECKEY_PKEY2PKCS8"},
85{ERR_FUNC(EVP_F_EVP_CIPHERINIT), "EVP_CipherInit"},
86{ERR_FUNC(EVP_F_EVP_CIPHERINIT_EX), "EVP_CipherInit_ex"}, 81{ERR_FUNC(EVP_F_EVP_CIPHERINIT_EX), "EVP_CipherInit_ex"},
82{ERR_FUNC(EVP_F_EVP_CIPHER_CTX_COPY), "EVP_CIPHER_CTX_copy"},
87{ERR_FUNC(EVP_F_EVP_CIPHER_CTX_CTRL), "EVP_CIPHER_CTX_ctrl"}, 83{ERR_FUNC(EVP_F_EVP_CIPHER_CTX_CTRL), "EVP_CIPHER_CTX_ctrl"},
88{ERR_FUNC(EVP_F_EVP_CIPHER_CTX_SET_KEY_LENGTH), "EVP_CIPHER_CTX_set_key_length"}, 84{ERR_FUNC(EVP_F_EVP_CIPHER_CTX_SET_KEY_LENGTH), "EVP_CIPHER_CTX_set_key_length"},
89{ERR_FUNC(EVP_F_EVP_DECRYPTFINAL_EX), "EVP_DecryptFinal_ex"}, 85{ERR_FUNC(EVP_F_EVP_DECRYPTFINAL_EX), "EVP_DecryptFinal_ex"},
90{ERR_FUNC(EVP_F_EVP_DIGESTINIT), "EVP_DigestInit"},
91{ERR_FUNC(EVP_F_EVP_DIGESTINIT_EX), "EVP_DigestInit_ex"}, 86{ERR_FUNC(EVP_F_EVP_DIGESTINIT_EX), "EVP_DigestInit_ex"},
92{ERR_FUNC(EVP_F_EVP_ENCRYPTFINAL_EX), "EVP_EncryptFinal_ex"}, 87{ERR_FUNC(EVP_F_EVP_ENCRYPTFINAL_EX), "EVP_EncryptFinal_ex"},
93{ERR_FUNC(EVP_F_EVP_MD_CTX_COPY_EX), "EVP_MD_CTX_copy_ex"}, 88{ERR_FUNC(EVP_F_EVP_MD_CTX_COPY_EX), "EVP_MD_CTX_copy_ex"},
89{ERR_FUNC(EVP_F_EVP_MD_SIZE), "EVP_MD_SIZE"},
94{ERR_FUNC(EVP_F_EVP_OPENINIT), "EVP_OpenInit"}, 90{ERR_FUNC(EVP_F_EVP_OPENINIT), "EVP_OpenInit"},
95{ERR_FUNC(EVP_F_EVP_PBE_ALG_ADD), "EVP_PBE_alg_add"}, 91{ERR_FUNC(EVP_F_EVP_PBE_ALG_ADD), "EVP_PBE_alg_add"},
92{ERR_FUNC(EVP_F_EVP_PBE_ALG_ADD_TYPE), "EVP_PBE_alg_add_type"},
96{ERR_FUNC(EVP_F_EVP_PBE_CIPHERINIT), "EVP_PBE_CipherInit"}, 93{ERR_FUNC(EVP_F_EVP_PBE_CIPHERINIT), "EVP_PBE_CipherInit"},
97{ERR_FUNC(EVP_F_EVP_PKCS82PKEY), "EVP_PKCS82PKEY"}, 94{ERR_FUNC(EVP_F_EVP_PKCS82PKEY), "EVP_PKCS82PKEY"},
95{ERR_FUNC(EVP_F_EVP_PKCS82PKEY_BROKEN), "EVP_PKCS82PKEY_BROKEN"},
98{ERR_FUNC(EVP_F_EVP_PKEY2PKCS8_BROKEN), "EVP_PKEY2PKCS8_broken"}, 96{ERR_FUNC(EVP_F_EVP_PKEY2PKCS8_BROKEN), "EVP_PKEY2PKCS8_broken"},
99{ERR_FUNC(EVP_F_EVP_PKEY_COPY_PARAMETERS), "EVP_PKEY_copy_parameters"}, 97{ERR_FUNC(EVP_F_EVP_PKEY_COPY_PARAMETERS), "EVP_PKEY_copy_parameters"},
98{ERR_FUNC(EVP_F_EVP_PKEY_CTX_CTRL), "EVP_PKEY_CTX_ctrl"},
99{ERR_FUNC(EVP_F_EVP_PKEY_CTX_CTRL_STR), "EVP_PKEY_CTX_ctrl_str"},
100{ERR_FUNC(EVP_F_EVP_PKEY_CTX_DUP), "EVP_PKEY_CTX_dup"},
100{ERR_FUNC(EVP_F_EVP_PKEY_DECRYPT), "EVP_PKEY_decrypt"}, 101{ERR_FUNC(EVP_F_EVP_PKEY_DECRYPT), "EVP_PKEY_decrypt"},
102{ERR_FUNC(EVP_F_EVP_PKEY_DECRYPT_INIT), "EVP_PKEY_decrypt_init"},
103{ERR_FUNC(EVP_F_EVP_PKEY_DECRYPT_OLD), "EVP_PKEY_decrypt_old"},
104{ERR_FUNC(EVP_F_EVP_PKEY_DERIVE), "EVP_PKEY_derive"},
105{ERR_FUNC(EVP_F_EVP_PKEY_DERIVE_INIT), "EVP_PKEY_derive_init"},
106{ERR_FUNC(EVP_F_EVP_PKEY_DERIVE_SET_PEER), "EVP_PKEY_derive_set_peer"},
101{ERR_FUNC(EVP_F_EVP_PKEY_ENCRYPT), "EVP_PKEY_encrypt"}, 107{ERR_FUNC(EVP_F_EVP_PKEY_ENCRYPT), "EVP_PKEY_encrypt"},
108{ERR_FUNC(EVP_F_EVP_PKEY_ENCRYPT_INIT), "EVP_PKEY_encrypt_init"},
109{ERR_FUNC(EVP_F_EVP_PKEY_ENCRYPT_OLD), "EVP_PKEY_encrypt_old"},
102{ERR_FUNC(EVP_F_EVP_PKEY_GET1_DH), "EVP_PKEY_get1_DH"}, 110{ERR_FUNC(EVP_F_EVP_PKEY_GET1_DH), "EVP_PKEY_get1_DH"},
103{ERR_FUNC(EVP_F_EVP_PKEY_GET1_DSA), "EVP_PKEY_get1_DSA"}, 111{ERR_FUNC(EVP_F_EVP_PKEY_GET1_DSA), "EVP_PKEY_get1_DSA"},
104{ERR_FUNC(EVP_F_EVP_PKEY_GET1_ECDSA), "EVP_PKEY_GET1_ECDSA"}, 112{ERR_FUNC(EVP_F_EVP_PKEY_GET1_ECDSA), "EVP_PKEY_GET1_ECDSA"},
105{ERR_FUNC(EVP_F_EVP_PKEY_GET1_EC_KEY), "EVP_PKEY_get1_EC_KEY"}, 113{ERR_FUNC(EVP_F_EVP_PKEY_GET1_EC_KEY), "EVP_PKEY_get1_EC_KEY"},
106{ERR_FUNC(EVP_F_EVP_PKEY_GET1_RSA), "EVP_PKEY_get1_RSA"}, 114{ERR_FUNC(EVP_F_EVP_PKEY_GET1_RSA), "EVP_PKEY_get1_RSA"},
115{ERR_FUNC(EVP_F_EVP_PKEY_KEYGEN), "EVP_PKEY_keygen"},
116{ERR_FUNC(EVP_F_EVP_PKEY_KEYGEN_INIT), "EVP_PKEY_keygen_init"},
107{ERR_FUNC(EVP_F_EVP_PKEY_NEW), "EVP_PKEY_new"}, 117{ERR_FUNC(EVP_F_EVP_PKEY_NEW), "EVP_PKEY_new"},
118{ERR_FUNC(EVP_F_EVP_PKEY_PARAMGEN), "EVP_PKEY_paramgen"},
119{ERR_FUNC(EVP_F_EVP_PKEY_PARAMGEN_INIT), "EVP_PKEY_paramgen_init"},
120{ERR_FUNC(EVP_F_EVP_PKEY_SIGN), "EVP_PKEY_sign"},
121{ERR_FUNC(EVP_F_EVP_PKEY_SIGN_INIT), "EVP_PKEY_sign_init"},
122{ERR_FUNC(EVP_F_EVP_PKEY_VERIFY), "EVP_PKEY_verify"},
123{ERR_FUNC(EVP_F_EVP_PKEY_VERIFY_INIT), "EVP_PKEY_verify_init"},
124{ERR_FUNC(EVP_F_EVP_PKEY_VERIFY_RECOVER), "EVP_PKEY_verify_recover"},
125{ERR_FUNC(EVP_F_EVP_PKEY_VERIFY_RECOVER_INIT), "EVP_PKEY_verify_recover_init"},
108{ERR_FUNC(EVP_F_EVP_RIJNDAEL), "EVP_RIJNDAEL"}, 126{ERR_FUNC(EVP_F_EVP_RIJNDAEL), "EVP_RIJNDAEL"},
109{ERR_FUNC(EVP_F_EVP_SIGNFINAL), "EVP_SignFinal"}, 127{ERR_FUNC(EVP_F_EVP_SIGNFINAL), "EVP_SignFinal"},
110{ERR_FUNC(EVP_F_EVP_VERIFYFINAL), "EVP_VerifyFinal"}, 128{ERR_FUNC(EVP_F_EVP_VERIFYFINAL), "EVP_VerifyFinal"},
129{ERR_FUNC(EVP_F_INT_CTX_NEW), "INT_CTX_NEW"},
111{ERR_FUNC(EVP_F_PKCS5_PBE_KEYIVGEN), "PKCS5_PBE_keyivgen"}, 130{ERR_FUNC(EVP_F_PKCS5_PBE_KEYIVGEN), "PKCS5_PBE_keyivgen"},
112{ERR_FUNC(EVP_F_PKCS5_V2_PBE_KEYIVGEN), "PKCS5_v2_PBE_keyivgen"}, 131{ERR_FUNC(EVP_F_PKCS5_V2_PBE_KEYIVGEN), "PKCS5_v2_PBE_keyivgen"},
113{ERR_FUNC(EVP_F_PKCS8_SET_BROKEN), "PKCS8_set_broken"}, 132{ERR_FUNC(EVP_F_PKCS8_SET_BROKEN), "PKCS8_set_broken"},
133{ERR_FUNC(EVP_F_PKEY_SET_TYPE), "PKEY_SET_TYPE"},
114{ERR_FUNC(EVP_F_RC2_MAGIC_TO_METH), "RC2_MAGIC_TO_METH"}, 134{ERR_FUNC(EVP_F_RC2_MAGIC_TO_METH), "RC2_MAGIC_TO_METH"},
115{ERR_FUNC(EVP_F_RC5_CTRL), "RC5_CTRL"}, 135{ERR_FUNC(EVP_F_RC5_CTRL), "RC5_CTRL"},
116{0,NULL} 136{0,NULL}
@@ -125,42 +145,52 @@ static ERR_STRING_DATA EVP_str_reasons[]=
125{ERR_REASON(EVP_R_BAD_KEY_LENGTH) ,"bad key length"}, 145{ERR_REASON(EVP_R_BAD_KEY_LENGTH) ,"bad key length"},
126{ERR_REASON(EVP_R_BN_DECODE_ERROR) ,"bn decode error"}, 146{ERR_REASON(EVP_R_BN_DECODE_ERROR) ,"bn decode error"},
127{ERR_REASON(EVP_R_BN_PUBKEY_ERROR) ,"bn pubkey error"}, 147{ERR_REASON(EVP_R_BN_PUBKEY_ERROR) ,"bn pubkey error"},
148{ERR_REASON(EVP_R_BUFFER_TOO_SMALL) ,"buffer too small"},
128{ERR_REASON(EVP_R_CAMELLIA_KEY_SETUP_FAILED),"camellia key setup failed"}, 149{ERR_REASON(EVP_R_CAMELLIA_KEY_SETUP_FAILED),"camellia key setup failed"},
129{ERR_REASON(EVP_R_CIPHER_PARAMETER_ERROR),"cipher parameter error"}, 150{ERR_REASON(EVP_R_CIPHER_PARAMETER_ERROR),"cipher parameter error"},
151{ERR_REASON(EVP_R_COMMAND_NOT_SUPPORTED) ,"command not supported"},
130{ERR_REASON(EVP_R_CTRL_NOT_IMPLEMENTED) ,"ctrl not implemented"}, 152{ERR_REASON(EVP_R_CTRL_NOT_IMPLEMENTED) ,"ctrl not implemented"},
131{ERR_REASON(EVP_R_CTRL_OPERATION_NOT_IMPLEMENTED),"ctrl operation not implemented"}, 153{ERR_REASON(EVP_R_CTRL_OPERATION_NOT_IMPLEMENTED),"ctrl operation not implemented"},
132{ERR_REASON(EVP_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH),"data not multiple of block length"}, 154{ERR_REASON(EVP_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH),"data not multiple of block length"},
133{ERR_REASON(EVP_R_DECODE_ERROR) ,"decode error"}, 155{ERR_REASON(EVP_R_DECODE_ERROR) ,"decode error"},
134{ERR_REASON(EVP_R_DIFFERENT_KEY_TYPES) ,"different key types"}, 156{ERR_REASON(EVP_R_DIFFERENT_KEY_TYPES) ,"different key types"},
135{ERR_REASON(EVP_R_DISABLED_FOR_FIPS) ,"disabled for fips"}, 157{ERR_REASON(EVP_R_DIFFERENT_PARAMETERS) ,"different parameters"},
136{ERR_REASON(EVP_R_ENCODE_ERROR) ,"encode error"}, 158{ERR_REASON(EVP_R_ENCODE_ERROR) ,"encode error"},
137{ERR_REASON(EVP_R_ERROR_LOADING_SECTION) ,"error loading section"},
138{ERR_REASON(EVP_R_ERROR_SETTING_FIPS_MODE),"error setting fips mode"},
139{ERR_REASON(EVP_R_EVP_PBE_CIPHERINIT_ERROR),"evp pbe cipherinit error"}, 159{ERR_REASON(EVP_R_EVP_PBE_CIPHERINIT_ERROR),"evp pbe cipherinit error"},
140{ERR_REASON(EVP_R_EXPECTING_AN_RSA_KEY) ,"expecting an rsa key"}, 160{ERR_REASON(EVP_R_EXPECTING_AN_RSA_KEY) ,"expecting an rsa key"},
141{ERR_REASON(EVP_R_EXPECTING_A_DH_KEY) ,"expecting a dh key"}, 161{ERR_REASON(EVP_R_EXPECTING_A_DH_KEY) ,"expecting a dh key"},
142{ERR_REASON(EVP_R_EXPECTING_A_DSA_KEY) ,"expecting a dsa key"}, 162{ERR_REASON(EVP_R_EXPECTING_A_DSA_KEY) ,"expecting a dsa key"},
143{ERR_REASON(EVP_R_EXPECTING_A_ECDSA_KEY) ,"expecting a ecdsa key"}, 163{ERR_REASON(EVP_R_EXPECTING_A_ECDSA_KEY) ,"expecting a ecdsa key"},
144{ERR_REASON(EVP_R_EXPECTING_A_EC_KEY) ,"expecting a ec key"}, 164{ERR_REASON(EVP_R_EXPECTING_A_EC_KEY) ,"expecting a ec key"},
145{ERR_REASON(EVP_R_FIPS_MODE_NOT_SUPPORTED),"fips mode not supported"},
146{ERR_REASON(EVP_R_INITIALIZATION_ERROR) ,"initialization error"}, 165{ERR_REASON(EVP_R_INITIALIZATION_ERROR) ,"initialization error"},
147{ERR_REASON(EVP_R_INPUT_NOT_INITIALIZED) ,"input not initialized"}, 166{ERR_REASON(EVP_R_INPUT_NOT_INITIALIZED) ,"input not initialized"},
148{ERR_REASON(EVP_R_INVALID_FIPS_MODE) ,"invalid fips mode"}, 167{ERR_REASON(EVP_R_INVALID_DIGEST) ,"invalid digest"},
149{ERR_REASON(EVP_R_INVALID_KEY_LENGTH) ,"invalid key length"}, 168{ERR_REASON(EVP_R_INVALID_KEY_LENGTH) ,"invalid key length"},
169{ERR_REASON(EVP_R_INVALID_OPERATION) ,"invalid operation"},
150{ERR_REASON(EVP_R_IV_TOO_LARGE) ,"iv too large"}, 170{ERR_REASON(EVP_R_IV_TOO_LARGE) ,"iv too large"},
151{ERR_REASON(EVP_R_KEYGEN_FAILURE) ,"keygen failure"}, 171{ERR_REASON(EVP_R_KEYGEN_FAILURE) ,"keygen failure"},
172{ERR_REASON(EVP_R_MESSAGE_DIGEST_IS_NULL),"message digest is null"},
173{ERR_REASON(EVP_R_METHOD_NOT_SUPPORTED) ,"method not supported"},
152{ERR_REASON(EVP_R_MISSING_PARAMETERS) ,"missing parameters"}, 174{ERR_REASON(EVP_R_MISSING_PARAMETERS) ,"missing parameters"},
153{ERR_REASON(EVP_R_NO_CIPHER_SET) ,"no cipher set"}, 175{ERR_REASON(EVP_R_NO_CIPHER_SET) ,"no cipher set"},
176{ERR_REASON(EVP_R_NO_DEFAULT_DIGEST) ,"no default digest"},
154{ERR_REASON(EVP_R_NO_DIGEST_SET) ,"no digest set"}, 177{ERR_REASON(EVP_R_NO_DIGEST_SET) ,"no digest set"},
155{ERR_REASON(EVP_R_NO_DSA_PARAMETERS) ,"no dsa parameters"}, 178{ERR_REASON(EVP_R_NO_DSA_PARAMETERS) ,"no dsa parameters"},
179{ERR_REASON(EVP_R_NO_KEY_SET) ,"no key set"},
180{ERR_REASON(EVP_R_NO_OPERATION_SET) ,"no operation set"},
156{ERR_REASON(EVP_R_NO_SIGN_FUNCTION_CONFIGURED),"no sign function configured"}, 181{ERR_REASON(EVP_R_NO_SIGN_FUNCTION_CONFIGURED),"no sign function configured"},
157{ERR_REASON(EVP_R_NO_VERIFY_FUNCTION_CONFIGURED),"no verify function configured"}, 182{ERR_REASON(EVP_R_NO_VERIFY_FUNCTION_CONFIGURED),"no verify function configured"},
183{ERR_REASON(EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE),"operation not supported for this keytype"},
184{ERR_REASON(EVP_R_OPERATON_NOT_INITIALIZED),"operaton not initialized"},
158{ERR_REASON(EVP_R_PKCS8_UNKNOWN_BROKEN_TYPE),"pkcs8 unknown broken type"}, 185{ERR_REASON(EVP_R_PKCS8_UNKNOWN_BROKEN_TYPE),"pkcs8 unknown broken type"},
186{ERR_REASON(EVP_R_PRIVATE_KEY_DECODE_ERROR),"private key decode error"},
187{ERR_REASON(EVP_R_PRIVATE_KEY_ENCODE_ERROR),"private key encode error"},
159{ERR_REASON(EVP_R_PUBLIC_KEY_NOT_RSA) ,"public key not rsa"}, 188{ERR_REASON(EVP_R_PUBLIC_KEY_NOT_RSA) ,"public key not rsa"},
160{ERR_REASON(EVP_R_SEED_KEY_SETUP_FAILED) ,"seed key setup failed"}, 189{ERR_REASON(EVP_R_UNKNOWN_CIPHER) ,"unknown cipher"},
161{ERR_REASON(EVP_R_UNKNOWN_OPTION) ,"unknown option"}, 190{ERR_REASON(EVP_R_UNKNOWN_DIGEST) ,"unknown digest"},
162{ERR_REASON(EVP_R_UNKNOWN_PBE_ALGORITHM) ,"unknown pbe algorithm"}, 191{ERR_REASON(EVP_R_UNKNOWN_PBE_ALGORITHM) ,"unknown pbe algorithm"},
163{ERR_REASON(EVP_R_UNSUPORTED_NUMBER_OF_ROUNDS),"unsuported number of rounds"}, 192{ERR_REASON(EVP_R_UNSUPORTED_NUMBER_OF_ROUNDS),"unsuported number of rounds"},
193{ERR_REASON(EVP_R_UNSUPPORTED_ALGORITHM) ,"unsupported algorithm"},
164{ERR_REASON(EVP_R_UNSUPPORTED_CIPHER) ,"unsupported cipher"}, 194{ERR_REASON(EVP_R_UNSUPPORTED_CIPHER) ,"unsupported cipher"},
165{ERR_REASON(EVP_R_UNSUPPORTED_KEYLENGTH) ,"unsupported keylength"}, 195{ERR_REASON(EVP_R_UNSUPPORTED_KEYLENGTH) ,"unsupported keylength"},
166{ERR_REASON(EVP_R_UNSUPPORTED_KEY_DERIVATION_FUNCTION),"unsupported key derivation function"}, 196{ERR_REASON(EVP_R_UNSUPPORTED_KEY_DERIVATION_FUNCTION),"unsupported key derivation function"},
diff --git a/src/lib/libcrypto/evp/evp_key.c b/src/lib/libcrypto/evp/evp_key.c
index 361ea69ab6..839d6a3a16 100644
--- a/src/lib/libcrypto/evp/evp_key.c
+++ b/src/lib/libcrypto/evp/evp_key.c
@@ -90,6 +90,11 @@ char *EVP_get_pw_prompt(void)
90 * this function will fail */ 90 * this function will fail */
91int EVP_read_pw_string(char *buf, int len, const char *prompt, int verify) 91int EVP_read_pw_string(char *buf, int len, const char *prompt, int verify)
92 { 92 {
93 return EVP_read_pw_string_min(buf, 0, len, prompt, verify);
94 }
95
96int EVP_read_pw_string_min(char *buf, int min, int len, const char *prompt, int verify)
97 {
93 int ret; 98 int ret;
94 char buff[BUFSIZ]; 99 char buff[BUFSIZ];
95 UI *ui; 100 UI *ui;
@@ -97,10 +102,10 @@ int EVP_read_pw_string(char *buf, int len, const char *prompt, int verify)
97 if ((prompt == NULL) && (prompt_string[0] != '\0')) 102 if ((prompt == NULL) && (prompt_string[0] != '\0'))
98 prompt=prompt_string; 103 prompt=prompt_string;
99 ui = UI_new(); 104 ui = UI_new();
100 UI_add_input_string(ui,prompt,0,buf,0,(len>=BUFSIZ)?BUFSIZ-1:len); 105 UI_add_input_string(ui,prompt,0,buf,min,(len>=BUFSIZ)?BUFSIZ-1:len);
101 if (verify) 106 if (verify)
102 UI_add_verify_string(ui,prompt,0, 107 UI_add_verify_string(ui,prompt,0,
103 buff,0,(len>=BUFSIZ)?BUFSIZ-1:len,buf); 108 buff,min,(len>=BUFSIZ)?BUFSIZ-1:len,buf);
104 ret = UI_process(ui); 109 ret = UI_process(ui);
105 UI_free(ui); 110 UI_free(ui);
106 OPENSSL_cleanse(buff,BUFSIZ); 111 OPENSSL_cleanse(buff,BUFSIZ);
diff --git a/src/lib/libcrypto/evp/evp_lib.c b/src/lib/libcrypto/evp/evp_lib.c
index 174cf6c594..40951a04f0 100644
--- a/src/lib/libcrypto/evp/evp_lib.c
+++ b/src/lib/libcrypto/evp/evp_lib.c
@@ -67,8 +67,6 @@ int EVP_CIPHER_param_to_asn1(EVP_CIPHER_CTX *c, ASN1_TYPE *type)
67 67
68 if (c->cipher->set_asn1_parameters != NULL) 68 if (c->cipher->set_asn1_parameters != NULL)
69 ret=c->cipher->set_asn1_parameters(c,type); 69 ret=c->cipher->set_asn1_parameters(c,type);
70 else if (c->cipher->flags & EVP_CIPH_FLAG_DEFAULT_ASN1)
71 ret=EVP_CIPHER_set_asn1_iv(c, type);
72 else 70 else
73 ret=-1; 71 ret=-1;
74 return(ret); 72 return(ret);
@@ -80,8 +78,6 @@ int EVP_CIPHER_asn1_to_param(EVP_CIPHER_CTX *c, ASN1_TYPE *type)
80 78
81 if (c->cipher->get_asn1_parameters != NULL) 79 if (c->cipher->get_asn1_parameters != NULL)
82 ret=c->cipher->get_asn1_parameters(c,type); 80 ret=c->cipher->get_asn1_parameters(c,type);
83 else if (c->cipher->flags & EVP_CIPH_FLAG_DEFAULT_ASN1)
84 ret=EVP_CIPHER_get_asn1_iv(c, type);
85 else 81 else
86 ret=-1; 82 ret=-1;
87 return(ret); 83 return(ret);
@@ -163,6 +159,12 @@ int EVP_CIPHER_type(const EVP_CIPHER *ctx)
163 159
164 return NID_des_cfb64; 160 return NID_des_cfb64;
165 161
162 case NID_des_ede3_cfb64:
163 case NID_des_ede3_cfb8:
164 case NID_des_ede3_cfb1:
165
166 return NID_des_cfb64;
167
166 default: 168 default:
167 /* Check it has an OID and it is valid */ 169 /* Check it has an OID and it is valid */
168 otmp = OBJ_nid2obj(nid); 170 otmp = OBJ_nid2obj(nid);
@@ -182,6 +184,11 @@ int EVP_CIPHER_CTX_block_size(const EVP_CIPHER_CTX *ctx)
182 return ctx->cipher->block_size; 184 return ctx->cipher->block_size;
183 } 185 }
184 186
187int EVP_Cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, unsigned int inl)
188 {
189 return ctx->cipher->do_cipher(ctx,out,in,inl);
190 }
191
185const EVP_CIPHER *EVP_CIPHER_CTX_cipher(const EVP_CIPHER_CTX *ctx) 192const EVP_CIPHER *EVP_CIPHER_CTX_cipher(const EVP_CIPHER_CTX *ctx)
186 { 193 {
187 return ctx->cipher; 194 return ctx->cipher;
@@ -192,6 +199,11 @@ unsigned long EVP_CIPHER_flags(const EVP_CIPHER *cipher)
192 return cipher->flags; 199 return cipher->flags;
193 } 200 }
194 201
202unsigned long EVP_CIPHER_CTX_flags(const EVP_CIPHER_CTX *ctx)
203 {
204 return ctx->cipher->flags;
205 }
206
195void *EVP_CIPHER_CTX_get_app_data(const EVP_CIPHER_CTX *ctx) 207void *EVP_CIPHER_CTX_get_app_data(const EVP_CIPHER_CTX *ctx)
196 { 208 {
197 return ctx->app_data; 209 return ctx->app_data;
@@ -207,6 +219,11 @@ int EVP_CIPHER_iv_length(const EVP_CIPHER *cipher)
207 return cipher->iv_len; 219 return cipher->iv_len;
208 } 220 }
209 221
222int EVP_CIPHER_CTX_iv_length(const EVP_CIPHER_CTX *ctx)
223 {
224 return ctx->cipher->iv_len;
225 }
226
210int EVP_CIPHER_key_length(const EVP_CIPHER *cipher) 227int EVP_CIPHER_key_length(const EVP_CIPHER *cipher)
211 { 228 {
212 return cipher->key_len; 229 return cipher->key_len;
@@ -217,6 +234,11 @@ int EVP_CIPHER_CTX_key_length(const EVP_CIPHER_CTX *ctx)
217 return ctx->key_len; 234 return ctx->key_len;
218 } 235 }
219 236
237int EVP_CIPHER_nid(const EVP_CIPHER *cipher)
238 {
239 return cipher->nid;
240 }
241
220int EVP_CIPHER_CTX_nid(const EVP_CIPHER_CTX *ctx) 242int EVP_CIPHER_CTX_nid(const EVP_CIPHER_CTX *ctx)
221 { 243 {
222 return ctx->cipher->nid; 244 return ctx->cipher->nid;
@@ -239,11 +261,23 @@ int EVP_MD_pkey_type(const EVP_MD *md)
239 261
240int EVP_MD_size(const EVP_MD *md) 262int EVP_MD_size(const EVP_MD *md)
241 { 263 {
264 if (!md)
265 {
266 EVPerr(EVP_F_EVP_MD_SIZE, EVP_R_MESSAGE_DIGEST_IS_NULL);
267 return -1;
268 }
242 return md->md_size; 269 return md->md_size;
243 } 270 }
244 271
245const EVP_MD * EVP_MD_CTX_md(const EVP_MD_CTX *ctx) 272unsigned long EVP_MD_flags(const EVP_MD *md)
273 {
274 return md->flags;
275 }
276
277const EVP_MD *EVP_MD_CTX_md(const EVP_MD_CTX *ctx)
246 { 278 {
279 if (!ctx)
280 return NULL;
247 return ctx->digest; 281 return ctx->digest;
248 } 282 }
249 283
diff --git a/src/lib/libcrypto/evp/evp_locl.h b/src/lib/libcrypto/evp/evp_locl.h
index eabcc96f30..292d74c188 100644
--- a/src/lib/libcrypto/evp/evp_locl.h
+++ b/src/lib/libcrypto/evp/evp_locl.h
@@ -61,38 +61,66 @@
61/* Wrapper functions for each cipher mode */ 61/* Wrapper functions for each cipher mode */
62 62
63#define BLOCK_CIPHER_ecb_loop() \ 63#define BLOCK_CIPHER_ecb_loop() \
64 unsigned int i, bl; \ 64 size_t i, bl; \
65 bl = ctx->cipher->block_size;\ 65 bl = ctx->cipher->block_size;\
66 if(inl < bl) return 1;\ 66 if(inl < bl) return 1;\
67 inl -= bl; \ 67 inl -= bl; \
68 for(i=0; i <= inl; i+=bl) 68 for(i=0; i <= inl; i+=bl)
69 69
70#define BLOCK_CIPHER_func_ecb(cname, cprefix, kstruct, ksched) \ 70#define BLOCK_CIPHER_func_ecb(cname, cprefix, kstruct, ksched) \
71static int cname##_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, unsigned int inl) \ 71static int cname##_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t inl) \
72{\ 72{\
73 BLOCK_CIPHER_ecb_loop() \ 73 BLOCK_CIPHER_ecb_loop() \
74 cprefix##_ecb_encrypt(in + i, out + i, &((kstruct *)ctx->cipher_data)->ksched, ctx->encrypt);\ 74 cprefix##_ecb_encrypt(in + i, out + i, &((kstruct *)ctx->cipher_data)->ksched, ctx->encrypt);\
75 return 1;\ 75 return 1;\
76} 76}
77 77
78#define EVP_MAXCHUNK ((size_t)1<<(sizeof(long)*8-2))
79
78#define BLOCK_CIPHER_func_ofb(cname, cprefix, cbits, kstruct, ksched) \ 80#define BLOCK_CIPHER_func_ofb(cname, cprefix, cbits, kstruct, ksched) \
79static int cname##_ofb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, unsigned int inl) \ 81static int cname##_ofb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t inl) \
80{\ 82{\
81 cprefix##_ofb##cbits##_encrypt(in, out, (long)inl, &((kstruct *)ctx->cipher_data)->ksched, ctx->iv, &ctx->num);\ 83 while(inl>=EVP_MAXCHUNK)\
84 {\
85 cprefix##_ofb##cbits##_encrypt(in, out, (long)EVP_MAXCHUNK, &((kstruct *)ctx->cipher_data)->ksched, ctx->iv, &ctx->num);\
86 inl-=EVP_MAXCHUNK;\
87 in +=EVP_MAXCHUNK;\
88 out+=EVP_MAXCHUNK;\
89 }\
90 if (inl)\
91 cprefix##_ofb##cbits##_encrypt(in, out, (long)inl, &((kstruct *)ctx->cipher_data)->ksched, ctx->iv, &ctx->num);\
82 return 1;\ 92 return 1;\
83} 93}
84 94
85#define BLOCK_CIPHER_func_cbc(cname, cprefix, kstruct, ksched) \ 95#define BLOCK_CIPHER_func_cbc(cname, cprefix, kstruct, ksched) \
86static int cname##_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, unsigned int inl) \ 96static int cname##_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t inl) \
87{\ 97{\
88 cprefix##_cbc_encrypt(in, out, (long)inl, &((kstruct *)ctx->cipher_data)->ksched, ctx->iv, ctx->encrypt);\ 98 while(inl>=EVP_MAXCHUNK) \
99 {\
100 cprefix##_cbc_encrypt(in, out, (long)EVP_MAXCHUNK, &((kstruct *)ctx->cipher_data)->ksched, ctx->iv, ctx->encrypt);\
101 inl-=EVP_MAXCHUNK;\
102 in +=EVP_MAXCHUNK;\
103 out+=EVP_MAXCHUNK;\
104 }\
105 if (inl)\
106 cprefix##_cbc_encrypt(in, out, (long)inl, &((kstruct *)ctx->cipher_data)->ksched, ctx->iv, ctx->encrypt);\
89 return 1;\ 107 return 1;\
90} 108}
91 109
92#define BLOCK_CIPHER_func_cfb(cname, cprefix, cbits, kstruct, ksched) \ 110#define BLOCK_CIPHER_func_cfb(cname, cprefix, cbits, kstruct, ksched) \
93static int cname##_cfb##cbits##_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, unsigned int inl) \ 111static int cname##_cfb##cbits##_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t inl) \
94{\ 112{\
95 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);\ 113 size_t chunk=EVP_MAXCHUNK;\
114 if (cbits==1) chunk>>=3;\
115 if (inl<chunk) chunk=inl;\
116 while(inl && inl>=chunk)\
117 {\
118 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);\
119 inl-=chunk;\
120 in +=chunk;\
121 out+=chunk;\
122 if(inl<chunk) chunk=inl;\
123 }\
96 return 1;\ 124 return 1;\
97} 125}
98 126
@@ -139,10 +167,10 @@ BLOCK_CIPHER_def1(cname, ofb##cbits, ofb, OFB, kstruct, nid, 1, \
139 get_asn1, ctrl) 167 get_asn1, ctrl)
140 168
141#define BLOCK_CIPHER_def_ecb(cname, kstruct, nid, block_size, key_len, \ 169#define BLOCK_CIPHER_def_ecb(cname, kstruct, nid, block_size, key_len, \
142 iv_len, flags, init_key, cleanup, set_asn1, \ 170 flags, init_key, cleanup, set_asn1, \
143 get_asn1, ctrl) \ 171 get_asn1, ctrl) \
144BLOCK_CIPHER_def1(cname, ecb, ecb, ECB, kstruct, nid, block_size, key_len, \ 172BLOCK_CIPHER_def1(cname, ecb, ecb, ECB, kstruct, nid, block_size, key_len, \
145 iv_len, flags, init_key, cleanup, set_asn1, get_asn1, ctrl) 173 0, flags, init_key, cleanup, set_asn1, get_asn1, ctrl)
146 174
147#define BLOCK_CIPHER_defs(cname, kstruct, \ 175#define BLOCK_CIPHER_defs(cname, kstruct, \
148 nid, block_size, key_len, iv_len, cbits, flags, \ 176 nid, block_size, key_len, iv_len, cbits, flags, \
@@ -153,7 +181,7 @@ BLOCK_CIPHER_def_cfb(cname, kstruct, nid, key_len, iv_len, cbits, \
153 flags, init_key, cleanup, set_asn1, get_asn1, ctrl) \ 181 flags, init_key, cleanup, set_asn1, get_asn1, ctrl) \
154BLOCK_CIPHER_def_ofb(cname, kstruct, nid, key_len, iv_len, cbits, \ 182BLOCK_CIPHER_def_ofb(cname, kstruct, nid, key_len, iv_len, cbits, \
155 flags, init_key, cleanup, set_asn1, get_asn1, ctrl) \ 183 flags, init_key, cleanup, set_asn1, get_asn1, ctrl) \
156BLOCK_CIPHER_def_ecb(cname, kstruct, nid, block_size, key_len, iv_len, flags, \ 184BLOCK_CIPHER_def_ecb(cname, kstruct, nid, block_size, key_len, flags, \
157 init_key, cleanup, set_asn1, get_asn1, ctrl) 185 init_key, cleanup, set_asn1, get_asn1, ctrl)
158 186
159 187
@@ -226,27 +254,92 @@ const EVP_CIPHER *EVP_##cname##_ecb(void) { return &cname##_ecb; }
226 254
227#define EVP_C_DATA(kstruct, ctx) ((kstruct *)(ctx)->cipher_data) 255#define EVP_C_DATA(kstruct, ctx) ((kstruct *)(ctx)->cipher_data)
228 256
229#define IMPLEMENT_CFBR(cipher,cprefix,kstruct,ksched,keysize,cbits,iv_len,fl) \ 257#define IMPLEMENT_CFBR(cipher,cprefix,kstruct,ksched,keysize,cbits,iv_len) \
230 BLOCK_CIPHER_func_cfb(cipher##_##keysize,cprefix,cbits,kstruct,ksched) \ 258 BLOCK_CIPHER_func_cfb(cipher##_##keysize,cprefix,cbits,kstruct,ksched) \
231 BLOCK_CIPHER_def_cfb(cipher##_##keysize,kstruct, \ 259 BLOCK_CIPHER_def_cfb(cipher##_##keysize,kstruct, \
232 NID_##cipher##_##keysize, keysize/8, iv_len, cbits, \ 260 NID_##cipher##_##keysize, keysize/8, iv_len, cbits, \
233 (fl)|EVP_CIPH_FLAG_DEFAULT_ASN1, \ 261 0, cipher##_init_key, NULL, \
234 cipher##_init_key, NULL, NULL, NULL, NULL) 262 EVP_CIPHER_set_asn1_iv, \
235 263 EVP_CIPHER_get_asn1_iv, \
236#ifdef OPENSSL_FIPS 264 NULL)
237#define RC2_set_key private_RC2_set_key 265
238#define RC4_set_key private_RC4_set_key 266struct evp_pkey_ctx_st
239#define CAST_set_key private_CAST_set_key 267 {
240#define RC5_32_set_key private_RC5_32_set_key 268 /* Method associated with this operation */
241#define BF_set_key private_BF_set_key 269 const EVP_PKEY_METHOD *pmeth;
242#define Camellia_set_key private_Camellia_set_key 270 /* Engine that implements this method or NULL if builtin */
243#define idea_set_encrypt_key private_idea_set_encrypt_key 271 ENGINE *engine;
244 272 /* Key: may be NULL */
245#define MD5_Init private_MD5_Init 273 EVP_PKEY *pkey;
246#define MD4_Init private_MD4_Init 274 /* Peer key for key agreement, may be NULL */
247#define MD2_Init private_MD2_Init 275 EVP_PKEY *peerkey;
248#define MDC2_Init private_MDC2_Init 276 /* Actual operation */
249#define SHA_Init private_SHA_Init 277 int operation;
250 278 /* Algorithm specific data */
251#endif 279 void *data;
280 /* Application specific data */
281 void *app_data;
282 /* Keygen callback */
283 EVP_PKEY_gen_cb *pkey_gencb;
284 /* implementation specific keygen data */
285 int *keygen_info;
286 int keygen_info_count;
287 } /* EVP_PKEY_CTX */;
288
289#define EVP_PKEY_FLAG_DYNAMIC 1
290
291struct evp_pkey_method_st
292 {
293 int pkey_id;
294 int flags;
295
296 int (*init)(EVP_PKEY_CTX *ctx);
297 int (*copy)(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src);
298 void (*cleanup)(EVP_PKEY_CTX *ctx);
299
300 int (*paramgen_init)(EVP_PKEY_CTX *ctx);
301 int (*paramgen)(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey);
302
303 int (*keygen_init)(EVP_PKEY_CTX *ctx);
304 int (*keygen)(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey);
305
306 int (*sign_init)(EVP_PKEY_CTX *ctx);
307 int (*sign)(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen,
308 const unsigned char *tbs, size_t tbslen);
309
310 int (*verify_init)(EVP_PKEY_CTX *ctx);
311 int (*verify)(EVP_PKEY_CTX *ctx,
312 const unsigned char *sig, size_t siglen,
313 const unsigned char *tbs, size_t tbslen);
314
315 int (*verify_recover_init)(EVP_PKEY_CTX *ctx);
316 int (*verify_recover)(EVP_PKEY_CTX *ctx,
317 unsigned char *rout, size_t *routlen,
318 const unsigned char *sig, size_t siglen);
319
320 int (*signctx_init)(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx);
321 int (*signctx)(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen,
322 EVP_MD_CTX *mctx);
323
324 int (*verifyctx_init)(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx);
325 int (*verifyctx)(EVP_PKEY_CTX *ctx, const unsigned char *sig,int siglen,
326 EVP_MD_CTX *mctx);
327
328 int (*encrypt_init)(EVP_PKEY_CTX *ctx);
329 int (*encrypt)(EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen,
330 const unsigned char *in, size_t inlen);
331
332 int (*decrypt_init)(EVP_PKEY_CTX *ctx);
333 int (*decrypt)(EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen,
334 const unsigned char *in, size_t inlen);
335
336 int (*derive_init)(EVP_PKEY_CTX *ctx);
337 int (*derive)(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen);
338
339 int (*ctrl)(EVP_PKEY_CTX *ctx, int type, int p1, void *p2);
340 int (*ctrl_str)(EVP_PKEY_CTX *ctx, const char *type, const char *value);
341
342
343 } /* EVP_PKEY_METHOD */;
252 344
345void evp_pkey_set_cb_translate(BN_GENCB *cb, EVP_PKEY_CTX *ctx);
diff --git a/src/lib/libcrypto/evp/evp_pbe.c b/src/lib/libcrypto/evp/evp_pbe.c
index 5e830be65f..c9d932d205 100644
--- a/src/lib/libcrypto/evp/evp_pbe.c
+++ b/src/lib/libcrypto/evp/evp_pbe.c
@@ -3,7 +3,7 @@
3 * project 1999. 3 * project 1999.
4 */ 4 */
5/* ==================================================================== 5/* ====================================================================
6 * Copyright (c) 1999 The OpenSSL Project. All rights reserved. 6 * Copyright (c) 1999-2006 The OpenSSL Project. All rights reserved.
7 * 7 *
8 * Redistribution and use in source and binary forms, with or without 8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions 9 * modification, are permitted provided that the following conditions
@@ -59,79 +59,253 @@
59#include <stdio.h> 59#include <stdio.h>
60#include "cryptlib.h" 60#include "cryptlib.h"
61#include <openssl/evp.h> 61#include <openssl/evp.h>
62#include <openssl/pkcs12.h>
62#include <openssl/x509.h> 63#include <openssl/x509.h>
63 64
64/* Password based encryption (PBE) functions */ 65/* Password based encryption (PBE) functions */
65 66
66static STACK *pbe_algs; 67DECLARE_STACK_OF(EVP_PBE_CTL)
68static STACK_OF(EVP_PBE_CTL) *pbe_algs;
67 69
68/* Setup a cipher context from a PBE algorithm */ 70/* Setup a cipher context from a PBE algorithm */
69 71
70typedef struct { 72typedef struct
71int pbe_nid; 73 {
72const EVP_CIPHER *cipher; 74 int pbe_type;
73const EVP_MD *md; 75 int pbe_nid;
74EVP_PBE_KEYGEN *keygen; 76 int cipher_nid;
75} EVP_PBE_CTL; 77 int md_nid;
78 EVP_PBE_KEYGEN *keygen;
79 } EVP_PBE_CTL;
76 80
77int EVP_PBE_CipherInit(ASN1_OBJECT *pbe_obj, const char *pass, int passlen, 81static const EVP_PBE_CTL builtin_pbe[] =
78 ASN1_TYPE *param, EVP_CIPHER_CTX *ctx, int en_de) 82 {
79{ 83 {EVP_PBE_TYPE_OUTER, NID_pbeWithMD2AndDES_CBC,
84 NID_des_cbc, NID_md2, PKCS5_PBE_keyivgen},
85 {EVP_PBE_TYPE_OUTER, NID_pbeWithMD5AndDES_CBC,
86 NID_des_cbc, NID_md5, PKCS5_PBE_keyivgen},
87 {EVP_PBE_TYPE_OUTER, NID_pbeWithSHA1AndRC2_CBC,
88 NID_rc2_64_cbc, NID_sha1, PKCS5_PBE_keyivgen},
80 89
81 EVP_PBE_CTL *pbetmp, pbelu; 90 {EVP_PBE_TYPE_OUTER, NID_pbe_WithSHA1And128BitRC4,
82 int i; 91 NID_rc4, NID_sha1, PKCS12_PBE_keyivgen},
83 pbelu.pbe_nid = OBJ_obj2nid(pbe_obj); 92 {EVP_PBE_TYPE_OUTER, NID_pbe_WithSHA1And40BitRC4,
84 if (pbelu.pbe_nid != NID_undef) i = sk_find(pbe_algs, (char *)&pbelu); 93 NID_rc4_40, NID_sha1, PKCS12_PBE_keyivgen},
85 else i = -1; 94 {EVP_PBE_TYPE_OUTER, NID_pbe_WithSHA1And3_Key_TripleDES_CBC,
95 NID_des_ede3_cbc, NID_sha1, PKCS12_PBE_keyivgen},
96 {EVP_PBE_TYPE_OUTER, NID_pbe_WithSHA1And2_Key_TripleDES_CBC,
97 NID_des_ede_cbc, NID_sha1, PKCS12_PBE_keyivgen},
98 {EVP_PBE_TYPE_OUTER, NID_pbe_WithSHA1And128BitRC2_CBC,
99 NID_rc2_cbc, NID_sha1, PKCS12_PBE_keyivgen},
100 {EVP_PBE_TYPE_OUTER, NID_pbe_WithSHA1And40BitRC2_CBC,
101 NID_rc2_40_cbc, NID_sha1, PKCS12_PBE_keyivgen},
102
103#ifndef OPENSSL_NO_HMAC
104 {EVP_PBE_TYPE_OUTER, NID_pbes2, -1, -1, PKCS5_v2_PBE_keyivgen},
105#endif
106 {EVP_PBE_TYPE_OUTER, NID_pbeWithMD2AndRC2_CBC,
107 NID_rc2_64_cbc, NID_md2, PKCS5_PBE_keyivgen},
108 {EVP_PBE_TYPE_OUTER, NID_pbeWithMD5AndRC2_CBC,
109 NID_rc2_64_cbc, NID_md5, PKCS5_PBE_keyivgen},
110 {EVP_PBE_TYPE_OUTER, NID_pbeWithSHA1AndDES_CBC,
111 NID_des_cbc, NID_sha1, PKCS5_PBE_keyivgen},
112
113
114 {EVP_PBE_TYPE_PRF, NID_hmacWithSHA1, -1, NID_sha1, 0},
115 {EVP_PBE_TYPE_PRF, NID_hmacWithMD5, -1, NID_md5, 0},
116 {EVP_PBE_TYPE_PRF, NID_hmacWithSHA224, -1, NID_sha224, 0},
117 {EVP_PBE_TYPE_PRF, NID_hmacWithSHA256, -1, NID_sha256, 0},
118 {EVP_PBE_TYPE_PRF, NID_hmacWithSHA384, -1, NID_sha384, 0},
119 {EVP_PBE_TYPE_PRF, NID_hmacWithSHA512, -1, NID_sha512, 0},
120 {EVP_PBE_TYPE_PRF, NID_id_HMACGostR3411_94, -1, NID_id_GostR3411_94, 0},
121 };
122
123#ifdef TEST
124int main(int argc, char **argv)
125 {
126 int i, nid_md, nid_cipher;
127 EVP_PBE_CTL *tpbe, *tpbe2;
128 /*OpenSSL_add_all_algorithms();*/
129
130 for (i = 0; i < sizeof(builtin_pbe)/sizeof(EVP_PBE_CTL); i++)
131 {
132 tpbe = builtin_pbe + i;
133 fprintf(stderr, "%d %d %s ", tpbe->pbe_type, tpbe->pbe_nid,
134 OBJ_nid2sn(tpbe->pbe_nid));
135 if (EVP_PBE_find(tpbe->pbe_type, tpbe->pbe_nid,
136 &nid_cipher ,&nid_md,0))
137 fprintf(stderr, "Found %s %s\n",
138 OBJ_nid2sn(nid_cipher),
139 OBJ_nid2sn(nid_md));
140 else
141 fprintf(stderr, "Find ERROR!!\n");
142 }
143
144 return 0;
145 }
146#endif
147
148
149
150int EVP_PBE_CipherInit(ASN1_OBJECT *pbe_obj, const char *pass, int passlen,
151 ASN1_TYPE *param, EVP_CIPHER_CTX *ctx, int en_de)
152 {
153 const EVP_CIPHER *cipher;
154 const EVP_MD *md;
155 int cipher_nid, md_nid;
156 EVP_PBE_KEYGEN *keygen;
86 157
87 if (i == -1) { 158 if (!EVP_PBE_find(EVP_PBE_TYPE_OUTER, OBJ_obj2nid(pbe_obj),
159 &cipher_nid, &md_nid, &keygen))
160 {
88 char obj_tmp[80]; 161 char obj_tmp[80];
89 EVPerr(EVP_F_EVP_PBE_CIPHERINIT,EVP_R_UNKNOWN_PBE_ALGORITHM); 162 EVPerr(EVP_F_EVP_PBE_CIPHERINIT,EVP_R_UNKNOWN_PBE_ALGORITHM);
90 if (!pbe_obj) BUF_strlcpy (obj_tmp, "NULL", sizeof obj_tmp); 163 if (!pbe_obj) BUF_strlcpy (obj_tmp, "NULL", sizeof obj_tmp);
91 else i2t_ASN1_OBJECT(obj_tmp, sizeof obj_tmp, pbe_obj); 164 else i2t_ASN1_OBJECT(obj_tmp, sizeof obj_tmp, pbe_obj);
92 ERR_add_error_data(2, "TYPE=", obj_tmp); 165 ERR_add_error_data(2, "TYPE=", obj_tmp);
93 return 0; 166 return 0;
94 } 167 }
95 if(!pass) passlen = 0; 168
96 else if (passlen == -1) passlen = strlen(pass); 169 if(!pass)
97 pbetmp = (EVP_PBE_CTL *)sk_value (pbe_algs, i); 170 passlen = 0;
98 i = (*pbetmp->keygen)(ctx, pass, passlen, param, pbetmp->cipher, 171 else if (passlen == -1)
99 pbetmp->md, en_de); 172 passlen = strlen(pass);
100 if (!i) { 173
174 if (cipher_nid == -1)
175 cipher = NULL;
176 else
177 {
178 cipher = EVP_get_cipherbynid(cipher_nid);
179 if (!cipher)
180 {
181 EVPerr(EVP_F_EVP_PBE_CIPHERINIT,EVP_R_UNKNOWN_CIPHER);
182 return 0;
183 }
184 }
185
186 if (md_nid == -1)
187 md = NULL;
188 else
189 {
190 md = EVP_get_digestbynid(md_nid);
191 if (!md)
192 {
193 EVPerr(EVP_F_EVP_PBE_CIPHERINIT,EVP_R_UNKNOWN_DIGEST);
194 return 0;
195 }
196 }
197
198 if (!keygen(ctx, pass, passlen, param, cipher, md, en_de))
199 {
101 EVPerr(EVP_F_EVP_PBE_CIPHERINIT,EVP_R_KEYGEN_FAILURE); 200 EVPerr(EVP_F_EVP_PBE_CIPHERINIT,EVP_R_KEYGEN_FAILURE);
102 return 0; 201 return 0;
103 } 202 }
104 return 1; 203 return 1;
105} 204}
106 205
107static int pbe_cmp(const char * const *a, const char * const *b) 206DECLARE_OBJ_BSEARCH_CMP_FN(EVP_PBE_CTL, EVP_PBE_CTL, pbe2);
108{ 207
109 const EVP_PBE_CTL * const *pbe1 = (const EVP_PBE_CTL * const *) a, 208static int pbe2_cmp(const EVP_PBE_CTL *pbe1, const EVP_PBE_CTL *pbe2)
110 * const *pbe2 = (const EVP_PBE_CTL * const *)b; 209 {
111 return ((*pbe1)->pbe_nid - (*pbe2)->pbe_nid); 210 int ret = pbe1->pbe_type - pbe2->pbe_type;
112} 211 if (ret)
212 return ret;
213 else
214 return pbe1->pbe_nid - pbe2->pbe_nid;
215 }
216
217IMPLEMENT_OBJ_BSEARCH_CMP_FN(EVP_PBE_CTL, EVP_PBE_CTL, pbe2);
218
219static int pbe_cmp(const EVP_PBE_CTL * const *a, const EVP_PBE_CTL * const *b)
220 {
221 int ret = (*a)->pbe_type - (*b)->pbe_type;
222 if (ret)
223 return ret;
224 else
225 return (*a)->pbe_nid - (*b)->pbe_nid;
226 }
113 227
114/* Add a PBE algorithm */ 228/* Add a PBE algorithm */
115 229
116int EVP_PBE_alg_add(int nid, const EVP_CIPHER *cipher, const EVP_MD *md, 230int EVP_PBE_alg_add_type(int pbe_type, int pbe_nid, int cipher_nid, int md_nid,
117 EVP_PBE_KEYGEN *keygen) 231 EVP_PBE_KEYGEN *keygen)
118{ 232 {
119 EVP_PBE_CTL *pbe_tmp; 233 EVP_PBE_CTL *pbe_tmp;
120 if (!pbe_algs) pbe_algs = sk_new(pbe_cmp); 234 if (!pbe_algs)
121 if (!(pbe_tmp = (EVP_PBE_CTL*) OPENSSL_malloc (sizeof(EVP_PBE_CTL)))) { 235 pbe_algs = sk_EVP_PBE_CTL_new(pbe_cmp);
122 EVPerr(EVP_F_EVP_PBE_ALG_ADD,ERR_R_MALLOC_FAILURE); 236 if (!(pbe_tmp = (EVP_PBE_CTL*) OPENSSL_malloc (sizeof(EVP_PBE_CTL))))
237 {
238 EVPerr(EVP_F_EVP_PBE_ALG_ADD_TYPE,ERR_R_MALLOC_FAILURE);
123 return 0; 239 return 0;
124 } 240 }
125 pbe_tmp->pbe_nid = nid; 241 pbe_tmp->pbe_type = pbe_type;
126 pbe_tmp->cipher = cipher; 242 pbe_tmp->pbe_nid = pbe_nid;
127 pbe_tmp->md = md; 243 pbe_tmp->cipher_nid = cipher_nid;
244 pbe_tmp->md_nid = md_nid;
128 pbe_tmp->keygen = keygen; 245 pbe_tmp->keygen = keygen;
129 sk_push (pbe_algs, (char *)pbe_tmp); 246
247
248 sk_EVP_PBE_CTL_push (pbe_algs, pbe_tmp);
130 return 1; 249 return 1;
131} 250 }
251
252int EVP_PBE_alg_add(int nid, const EVP_CIPHER *cipher, const EVP_MD *md,
253 EVP_PBE_KEYGEN *keygen)
254 {
255 int cipher_nid, md_nid;
256 if (cipher)
257 cipher_nid = EVP_CIPHER_type(cipher);
258 else
259 cipher_nid = -1;
260 if (md)
261 md_nid = EVP_MD_type(md);
262 else
263 md_nid = -1;
264
265 return EVP_PBE_alg_add_type(EVP_PBE_TYPE_OUTER, nid,
266 cipher_nid, md_nid, keygen);
267 }
268
269int EVP_PBE_find(int type, int pbe_nid,
270 int *pcnid, int *pmnid, EVP_PBE_KEYGEN **pkeygen)
271 {
272 EVP_PBE_CTL *pbetmp = NULL, pbelu;
273 int i;
274 if (pbe_nid == NID_undef)
275 return 0;
276
277 pbelu.pbe_type = type;
278 pbelu.pbe_nid = pbe_nid;
279
280 if (pbe_algs)
281 {
282 i = sk_EVP_PBE_CTL_find(pbe_algs, &pbelu);
283 if (i != -1)
284 pbetmp = sk_EVP_PBE_CTL_value (pbe_algs, i);
285 }
286 if (pbetmp == NULL)
287 {
288 pbetmp = OBJ_bsearch_pbe2(&pbelu, builtin_pbe,
289 sizeof(builtin_pbe)/sizeof(EVP_PBE_CTL));
290 }
291 if (pbetmp == NULL)
292 return 0;
293 if (pcnid)
294 *pcnid = pbetmp->cipher_nid;
295 if (pmnid)
296 *pmnid = pbetmp->md_nid;
297 if (pkeygen)
298 *pkeygen = pbetmp->keygen;
299 return 1;
300 }
301
302static void free_evp_pbe_ctl(EVP_PBE_CTL *pbe)
303 {
304 OPENSSL_freeFunc(pbe);
305 }
132 306
133void EVP_PBE_cleanup(void) 307void EVP_PBE_cleanup(void)
134{ 308 {
135 sk_pop_free(pbe_algs, OPENSSL_freeFunc); 309 sk_EVP_PBE_CTL_pop_free(pbe_algs, free_evp_pbe_ctl);
136 pbe_algs = NULL; 310 pbe_algs = NULL;
137} 311 }
diff --git a/src/lib/libcrypto/evp/evp_pkey.c b/src/lib/libcrypto/evp/evp_pkey.c
index 10d9e9e772..ceebf69284 100644
--- a/src/lib/libcrypto/evp/evp_pkey.c
+++ b/src/lib/libcrypto/evp/evp_pkey.c
@@ -3,7 +3,7 @@
3 * project 1999. 3 * project 1999.
4 */ 4 */
5/* ==================================================================== 5/* ====================================================================
6 * Copyright (c) 1999-2002 The OpenSSL Project. All rights reserved. 6 * Copyright (c) 1999-2005 The OpenSSL Project. All rights reserved.
7 * 7 *
8 * Redistribution and use in source and binary forms, with or without 8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions 9 * modification, are permitted provided that the following conditions
@@ -61,287 +61,52 @@
61#include "cryptlib.h" 61#include "cryptlib.h"
62#include <openssl/x509.h> 62#include <openssl/x509.h>
63#include <openssl/rand.h> 63#include <openssl/rand.h>
64#ifndef OPENSSL_NO_RSA 64#include "asn1_locl.h"
65#include <openssl/rsa.h>
66#endif
67#ifndef OPENSSL_NO_DSA
68#include <openssl/dsa.h>
69#endif
70#include <openssl/bn.h>
71
72#ifndef OPENSSL_NO_DSA
73static int dsa_pkey2pkcs8(PKCS8_PRIV_KEY_INFO *p8inf, EVP_PKEY *pkey);
74#endif
75#ifndef OPENSSL_NO_EC
76static int eckey_pkey2pkcs8(PKCS8_PRIV_KEY_INFO *p8inf, EVP_PKEY *pkey);
77#endif
78 65
79/* Extract a private key from a PKCS8 structure */ 66/* Extract a private key from a PKCS8 structure */
80 67
81EVP_PKEY *EVP_PKCS82PKEY(PKCS8_PRIV_KEY_INFO *p8) 68EVP_PKEY *EVP_PKCS82PKEY(PKCS8_PRIV_KEY_INFO *p8)
82{ 69{
83 EVP_PKEY *pkey = NULL; 70 EVP_PKEY *pkey = NULL;
84#ifndef OPENSSL_NO_RSA 71 ASN1_OBJECT *algoid;
85 RSA *rsa = NULL;
86#endif
87#ifndef OPENSSL_NO_DSA
88 DSA *dsa = NULL;
89 ASN1_TYPE *t1, *t2;
90 ASN1_INTEGER *privkey;
91 STACK_OF(ASN1_TYPE) *ndsa = NULL;
92#endif
93#ifndef OPENSSL_NO_EC
94 EC_KEY *eckey = NULL;
95 const unsigned char *p_tmp;
96#endif
97#if !defined(OPENSSL_NO_DSA) || !defined(OPENSSL_NO_EC)
98 ASN1_TYPE *param = NULL;
99 BN_CTX *ctx = NULL;
100 int plen;
101#endif
102 X509_ALGOR *a;
103 const unsigned char *p;
104 const unsigned char *cp;
105 int pkeylen;
106 int nid;
107 char obj_tmp[80]; 72 char obj_tmp[80];
108 73
109 if(p8->pkey->type == V_ASN1_OCTET_STRING) { 74 if (!PKCS8_pkey_get0(&algoid, NULL, NULL, NULL, p8))
110 p8->broken = PKCS8_OK; 75 return NULL;
111 p = p8->pkey->value.octet_string->data; 76
112 pkeylen = p8->pkey->value.octet_string->length;
113 } else {
114 p8->broken = PKCS8_NO_OCTET;
115 p = p8->pkey->value.sequence->data;
116 pkeylen = p8->pkey->value.sequence->length;
117 }
118 if (!(pkey = EVP_PKEY_new())) { 77 if (!(pkey = EVP_PKEY_new())) {
119 EVPerr(EVP_F_EVP_PKCS82PKEY,ERR_R_MALLOC_FAILURE); 78 EVPerr(EVP_F_EVP_PKCS82PKEY,ERR_R_MALLOC_FAILURE);
120 return NULL; 79 return NULL;
121 } 80 }
122 a = p8->pkeyalg;
123 nid = OBJ_obj2nid(a->algorithm);
124 switch(nid)
125 {
126#ifndef OPENSSL_NO_RSA
127 case NID_rsaEncryption:
128 cp = p;
129 if (!(rsa = d2i_RSAPrivateKey (NULL,&cp, pkeylen))) {
130 EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR);
131 return NULL;
132 }
133 EVP_PKEY_assign_RSA (pkey, rsa);
134 break;
135#endif
136#ifndef OPENSSL_NO_DSA
137 case NID_dsa:
138 /* PKCS#8 DSA is weird: you just get a private key integer
139 * and parameters in the AlgorithmIdentifier the pubkey must
140 * be recalculated.
141 */
142
143 /* Check for broken DSA PKCS#8, UGH! */
144 if(*p == (V_ASN1_SEQUENCE|V_ASN1_CONSTRUCTED)) {
145 if(!(ndsa = ASN1_seq_unpack_ASN1_TYPE(p, pkeylen,
146 d2i_ASN1_TYPE,
147 ASN1_TYPE_free))) {
148 EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR);
149 goto dsaerr;
150 }
151 if(sk_ASN1_TYPE_num(ndsa) != 2 ) {
152 EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR);
153 goto dsaerr;
154 }
155 /* Handle Two broken types:
156 * SEQUENCE {parameters, priv_key}
157 * SEQUENCE {pub_key, priv_key}
158 */
159
160 t1 = sk_ASN1_TYPE_value(ndsa, 0);
161 t2 = sk_ASN1_TYPE_value(ndsa, 1);
162 if(t1->type == V_ASN1_SEQUENCE) {
163 p8->broken = PKCS8_EMBEDDED_PARAM;
164 param = t1;
165 } else if(a->parameter->type == V_ASN1_SEQUENCE) {
166 p8->broken = PKCS8_NS_DB;
167 param = a->parameter;
168 } else {
169 EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR);
170 goto dsaerr;
171 }
172
173 if(t2->type != V_ASN1_INTEGER) {
174 EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR);
175 goto dsaerr;
176 }
177 privkey = t2->value.integer;
178 } else {
179 if (!(privkey=d2i_ASN1_INTEGER (NULL, &p, pkeylen))) {
180 EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR);
181 goto dsaerr;
182 }
183 param = p8->pkeyalg->parameter;
184 }
185 if (!param || (param->type != V_ASN1_SEQUENCE)) {
186 EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR);
187 goto dsaerr;
188 }
189 cp = p = param->value.sequence->data;
190 plen = param->value.sequence->length;
191 if (!(dsa = d2i_DSAparams (NULL, &cp, plen))) {
192 EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR);
193 goto dsaerr;
194 }
195 /* We have parameters now set private key */
196 if (!(dsa->priv_key = ASN1_INTEGER_to_BN(privkey, NULL))) {
197 EVPerr(EVP_F_EVP_PKCS82PKEY,EVP_R_BN_DECODE_ERROR);
198 goto dsaerr;
199 }
200 /* Calculate public key (ouch!) */
201 if (!(dsa->pub_key = BN_new())) {
202 EVPerr(EVP_F_EVP_PKCS82PKEY,ERR_R_MALLOC_FAILURE);
203 goto dsaerr;
204 }
205 if (!(ctx = BN_CTX_new())) {
206 EVPerr(EVP_F_EVP_PKCS82PKEY,ERR_R_MALLOC_FAILURE);
207 goto dsaerr;
208 }
209
210 if (!BN_mod_exp(dsa->pub_key, dsa->g,
211 dsa->priv_key, dsa->p, ctx)) {
212
213 EVPerr(EVP_F_EVP_PKCS82PKEY,EVP_R_BN_PUBKEY_ERROR);
214 goto dsaerr;
215 }
216 81
217 EVP_PKEY_assign_DSA(pkey, dsa); 82 if (!EVP_PKEY_set_type(pkey, OBJ_obj2nid(algoid)))
218 BN_CTX_free (ctx);
219 if(ndsa) sk_ASN1_TYPE_pop_free(ndsa, ASN1_TYPE_free);
220 else ASN1_INTEGER_free(privkey);
221 break;
222 dsaerr:
223 BN_CTX_free (ctx);
224 sk_ASN1_TYPE_pop_free(ndsa, ASN1_TYPE_free);
225 DSA_free(dsa);
226 EVP_PKEY_free(pkey);
227 return NULL;
228 break;
229#endif
230#ifndef OPENSSL_NO_EC
231 case NID_X9_62_id_ecPublicKey:
232 p_tmp = p;
233 /* extract the ec parameters */
234 param = p8->pkeyalg->parameter;
235
236 if (!param || ((param->type != V_ASN1_SEQUENCE) &&
237 (param->type != V_ASN1_OBJECT)))
238 { 83 {
239 EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR); 84 EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_UNSUPPORTED_PRIVATE_KEY_ALGORITHM);
240 goto ecerr; 85 i2t_ASN1_OBJECT(obj_tmp, 80, algoid);
86 ERR_add_error_data(2, "TYPE=", obj_tmp);
87 goto error;
241 } 88 }
242 89
243 if (param->type == V_ASN1_SEQUENCE) 90 if (pkey->ameth->priv_decode)
244 { 91 {
245 cp = p = param->value.sequence->data; 92 if (!pkey->ameth->priv_decode(pkey, p8))
246 plen = param->value.sequence->length;
247
248 if (!(eckey = d2i_ECParameters(NULL, &cp, plen)))
249 { 93 {
250 EVPerr(EVP_F_EVP_PKCS82PKEY, 94 EVPerr(EVP_F_EVP_PKCS82PKEY,
251 EVP_R_DECODE_ERROR); 95 EVP_R_PRIVATE_KEY_DECODE_ERROR);
252 goto ecerr; 96 goto error;
253 } 97 }
254 } 98 }
255 else 99 else
256 { 100 {
257 EC_GROUP *group; 101 EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_METHOD_NOT_SUPPORTED);
258 cp = p = param->value.object->data; 102 goto error;
259 plen = param->value.object->length;
260
261 /* type == V_ASN1_OBJECT => the parameters are given
262 * by an asn1 OID
263 */
264 if ((eckey = EC_KEY_new()) == NULL)
265 {
266 EVPerr(EVP_F_EVP_PKCS82PKEY,
267 ERR_R_MALLOC_FAILURE);
268 goto ecerr;
269 }
270 group = EC_GROUP_new_by_curve_name(OBJ_obj2nid(a->parameter->value.object));
271 if (group == NULL)
272 goto ecerr;
273 EC_GROUP_set_asn1_flag(group, OPENSSL_EC_NAMED_CURVE);
274 if (EC_KEY_set_group(eckey, group) == 0)
275 goto ecerr;
276 EC_GROUP_free(group);
277 }
278
279 /* We have parameters now set private key */
280 if (!d2i_ECPrivateKey(&eckey, &p_tmp, pkeylen))
281 {
282 EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR);
283 goto ecerr;
284 }
285
286 /* calculate public key (if necessary) */
287 if (EC_KEY_get0_public_key(eckey) == NULL)
288 {
289 const BIGNUM *priv_key;
290 const EC_GROUP *group;
291 EC_POINT *pub_key;
292 /* the public key was not included in the SEC1 private
293 * key => calculate the public key */
294 group = EC_KEY_get0_group(eckey);
295 pub_key = EC_POINT_new(group);
296 if (pub_key == NULL)
297 {
298 EVPerr(EVP_F_EVP_PKCS82PKEY, ERR_R_EC_LIB);
299 goto ecerr;
300 }
301 if (!EC_POINT_copy(pub_key, EC_GROUP_get0_generator(group)))
302 {
303 EC_POINT_free(pub_key);
304 EVPerr(EVP_F_EVP_PKCS82PKEY, ERR_R_EC_LIB);
305 goto ecerr;
306 }
307 priv_key = EC_KEY_get0_private_key(eckey);
308 if (!EC_POINT_mul(group, pub_key, priv_key, NULL, NULL, ctx))
309 {
310 EC_POINT_free(pub_key);
311 EVPerr(EVP_F_EVP_PKCS82PKEY, ERR_R_EC_LIB);
312 goto ecerr;
313 }
314 if (EC_KEY_set_public_key(eckey, pub_key) == 0)
315 {
316 EC_POINT_free(pub_key);
317 EVPerr(EVP_F_EVP_PKCS82PKEY, ERR_R_EC_LIB);
318 goto ecerr;
319 }
320 EC_POINT_free(pub_key);
321 } 103 }
322 104
323 EVP_PKEY_assign_EC_KEY(pkey, eckey);
324 if (ctx)
325 BN_CTX_free(ctx);
326 break;
327ecerr:
328 if (ctx)
329 BN_CTX_free(ctx);
330 if (eckey)
331 EC_KEY_free(eckey);
332 if (pkey)
333 EVP_PKEY_free(pkey);
334 return NULL;
335#endif
336 default:
337 EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_UNSUPPORTED_PRIVATE_KEY_ALGORITHM);
338 if (!a->algorithm) BUF_strlcpy (obj_tmp, "NULL", sizeof obj_tmp);
339 else i2t_ASN1_OBJECT(obj_tmp, 80, a->algorithm);
340 ERR_add_error_data(2, "TYPE=", obj_tmp);
341 EVP_PKEY_free (pkey);
342 return NULL;
343 }
344 return pkey; 105 return pkey;
106
107 error:
108 EVP_PKEY_free (pkey);
109 return NULL;
345} 110}
346 111
347PKCS8_PRIV_KEY_INFO *EVP_PKEY2PKCS8(EVP_PKEY *pkey) 112PKCS8_PRIV_KEY_INFO *EVP_PKEY2PKCS8(EVP_PKEY *pkey)
@@ -360,59 +125,37 @@ PKCS8_PRIV_KEY_INFO *EVP_PKEY2PKCS8_broken(EVP_PKEY *pkey, int broken)
360 return NULL; 125 return NULL;
361 } 126 }
362 p8->broken = broken; 127 p8->broken = broken;
363 if (!ASN1_INTEGER_set(p8->version, 0)) {
364 EVPerr(EVP_F_EVP_PKEY2PKCS8_BROKEN,ERR_R_MALLOC_FAILURE);
365 PKCS8_PRIV_KEY_INFO_free (p8);
366 return NULL;
367 }
368 if (!(p8->pkeyalg->parameter = ASN1_TYPE_new ())) {
369 EVPerr(EVP_F_EVP_PKEY2PKCS8_BROKEN,ERR_R_MALLOC_FAILURE);
370 PKCS8_PRIV_KEY_INFO_free (p8);
371 return NULL;
372 }
373 p8->pkey->type = V_ASN1_OCTET_STRING;
374 switch (EVP_PKEY_type(pkey->type)) {
375#ifndef OPENSSL_NO_RSA
376 case EVP_PKEY_RSA:
377 128
378 if(p8->broken == PKCS8_NO_OCTET) p8->pkey->type = V_ASN1_SEQUENCE; 129 if (pkey->ameth)
379 130 {
380 p8->pkeyalg->algorithm = OBJ_nid2obj(NID_rsaEncryption); 131 if (pkey->ameth->priv_encode)
381 p8->pkeyalg->parameter->type = V_ASN1_NULL; 132 {
382 if (!ASN1_pack_string_of (EVP_PKEY,pkey, i2d_PrivateKey, 133 if (!pkey->ameth->priv_encode(p8, pkey))
383 &p8->pkey->value.octet_string)) { 134 {
384 EVPerr(EVP_F_EVP_PKEY2PKCS8_BROKEN,ERR_R_MALLOC_FAILURE); 135 EVPerr(EVP_F_EVP_PKEY2PKCS8_BROKEN,
385 PKCS8_PRIV_KEY_INFO_free (p8); 136 EVP_R_PRIVATE_KEY_ENCODE_ERROR);
386 return NULL; 137 goto error;
387 } 138 }
388 break; 139 }
389#endif 140 else
390#ifndef OPENSSL_NO_DSA 141 {
391 case EVP_PKEY_DSA: 142 EVPerr(EVP_F_EVP_PKEY2PKCS8_BROKEN,
392 if(!dsa_pkey2pkcs8(p8, pkey)) { 143 EVP_R_METHOD_NOT_SUPPORTED);
393 PKCS8_PRIV_KEY_INFO_free (p8); 144 goto error;
394 return NULL; 145 }
395 } 146 }
396 147 else
397 break;
398#endif
399#ifndef OPENSSL_NO_EC
400 case EVP_PKEY_EC:
401 if (!eckey_pkey2pkcs8(p8, pkey))
402 { 148 {
403 PKCS8_PRIV_KEY_INFO_free(p8); 149 EVPerr(EVP_F_EVP_PKEY2PKCS8_BROKEN,
404 return(NULL); 150 EVP_R_UNSUPPORTED_PRIVATE_KEY_ALGORITHM);
151 goto error;
405 } 152 }
406 break;
407#endif
408 default:
409 EVPerr(EVP_F_EVP_PKEY2PKCS8_BROKEN, EVP_R_UNSUPPORTED_PRIVATE_KEY_ALGORITHM);
410 PKCS8_PRIV_KEY_INFO_free (p8);
411 return NULL;
412 }
413 RAND_add(p8->pkey->value.octet_string->data, 153 RAND_add(p8->pkey->value.octet_string->data,
414 p8->pkey->value.octet_string->length, 0.0); 154 p8->pkey->value.octet_string->length, 0.0);
415 return p8; 155 return p8;
156 error:
157 PKCS8_PRIV_KEY_INFO_free(p8);
158 return NULL;
416} 159}
417 160
418PKCS8_PRIV_KEY_INFO *PKCS8_set_broken(PKCS8_PRIV_KEY_INFO *p8, int broken) 161PKCS8_PRIV_KEY_INFO *PKCS8_set_broken(PKCS8_PRIV_KEY_INFO *p8, int broken)
@@ -436,301 +179,6 @@ PKCS8_PRIV_KEY_INFO *PKCS8_set_broken(PKCS8_PRIV_KEY_INFO *p8, int broken)
436 } 179 }
437} 180}
438 181
439#ifndef OPENSSL_NO_DSA
440static int dsa_pkey2pkcs8(PKCS8_PRIV_KEY_INFO *p8, EVP_PKEY *pkey)
441{
442 ASN1_STRING *params = NULL;
443 ASN1_INTEGER *prkey = NULL;
444 ASN1_TYPE *ttmp = NULL;
445 STACK_OF(ASN1_TYPE) *ndsa = NULL;
446 unsigned char *p = NULL, *q;
447 int len;
448
449 p8->pkeyalg->algorithm = OBJ_nid2obj(NID_dsa);
450 len = i2d_DSAparams (pkey->pkey.dsa, NULL);
451 if (!(p = OPENSSL_malloc(len))) {
452 EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
453 goto err;
454 }
455 q = p;
456 i2d_DSAparams (pkey->pkey.dsa, &q);
457 if (!(params = ASN1_STRING_new())) {
458 EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
459 goto err;
460 }
461 if (!ASN1_STRING_set(params, p, len)) {
462 EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
463 goto err;
464 }
465 OPENSSL_free(p);
466 p = NULL;
467 /* Get private key into integer */
468 if (!(prkey = BN_to_ASN1_INTEGER (pkey->pkey.dsa->priv_key, NULL))) {
469 EVPerr(EVP_F_DSA_PKEY2PKCS8,EVP_R_ENCODE_ERROR);
470 goto err;
471 }
472
473 switch(p8->broken) {
474
475 case PKCS8_OK:
476 case PKCS8_NO_OCTET:
477
478 if (!ASN1_pack_string_of(ASN1_INTEGER,prkey, i2d_ASN1_INTEGER,
479 &p8->pkey->value.octet_string)) {
480 EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
481 goto err;
482 }
483
484 M_ASN1_INTEGER_free (prkey);
485 prkey = NULL;
486 p8->pkeyalg->parameter->value.sequence = params;
487 params = NULL;
488 p8->pkeyalg->parameter->type = V_ASN1_SEQUENCE;
489
490 break;
491
492 case PKCS8_NS_DB:
493
494 p8->pkeyalg->parameter->value.sequence = params;
495 params = NULL;
496 p8->pkeyalg->parameter->type = V_ASN1_SEQUENCE;
497 if (!(ndsa = sk_ASN1_TYPE_new_null())) {
498 EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
499 goto err;
500 }
501 if (!(ttmp = ASN1_TYPE_new())) {
502 EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
503 goto err;
504 }
505 if (!(ttmp->value.integer =
506 BN_to_ASN1_INTEGER(pkey->pkey.dsa->pub_key, NULL))) {
507 EVPerr(EVP_F_DSA_PKEY2PKCS8,EVP_R_ENCODE_ERROR);
508 goto err;
509 }
510 ttmp->type = V_ASN1_INTEGER;
511 if (!sk_ASN1_TYPE_push(ndsa, ttmp)) {
512 EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
513 goto err;
514 }
515
516 if (!(ttmp = ASN1_TYPE_new())) {
517 EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
518 goto err;
519 }
520 ttmp->value.integer = prkey;
521 prkey = NULL;
522 ttmp->type = V_ASN1_INTEGER;
523 if (!sk_ASN1_TYPE_push(ndsa, ttmp)) {
524 EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
525 goto err;
526 }
527 ttmp = NULL;
528
529 if (!(p8->pkey->value.octet_string = ASN1_OCTET_STRING_new())) {
530 EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
531 goto err;
532 }
533
534 if (!ASN1_seq_pack_ASN1_TYPE(ndsa, i2d_ASN1_TYPE,
535 &p8->pkey->value.octet_string->data,
536 &p8->pkey->value.octet_string->length)) {
537
538 EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
539 goto err;
540 }
541 sk_ASN1_TYPE_pop_free(ndsa, ASN1_TYPE_free);
542 break;
543
544 case PKCS8_EMBEDDED_PARAM:
545
546 p8->pkeyalg->parameter->type = V_ASN1_NULL;
547 if (!(ndsa = sk_ASN1_TYPE_new_null())) {
548 EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
549 goto err;
550 }
551 if (!(ttmp = ASN1_TYPE_new())) {
552 EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
553 goto err;
554 }
555 ttmp->value.sequence = params;
556 params = NULL;
557 ttmp->type = V_ASN1_SEQUENCE;
558 if (!sk_ASN1_TYPE_push(ndsa, ttmp)) {
559 EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
560 goto err;
561 }
562
563 if (!(ttmp = ASN1_TYPE_new())) {
564 EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
565 goto err;
566 }
567 ttmp->value.integer = prkey;
568 prkey = NULL;
569 ttmp->type = V_ASN1_INTEGER;
570 if (!sk_ASN1_TYPE_push(ndsa, ttmp)) {
571 EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
572 goto err;
573 }
574 ttmp = NULL;
575
576 if (!(p8->pkey->value.octet_string = ASN1_OCTET_STRING_new())) {
577 EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
578 goto err;
579 }
580
581 if (!ASN1_seq_pack_ASN1_TYPE(ndsa, i2d_ASN1_TYPE,
582 &p8->pkey->value.octet_string->data,
583 &p8->pkey->value.octet_string->length)) {
584
585 EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
586 goto err;
587 }
588 sk_ASN1_TYPE_pop_free(ndsa, ASN1_TYPE_free);
589 break;
590 }
591 return 1;
592err:
593 if (p != NULL) OPENSSL_free(p);
594 if (params != NULL) ASN1_STRING_free(params);
595 if (prkey != NULL) M_ASN1_INTEGER_free(prkey);
596 if (ttmp != NULL) ASN1_TYPE_free(ttmp);
597 if (ndsa != NULL) sk_ASN1_TYPE_pop_free(ndsa, ASN1_TYPE_free);
598 return 0;
599}
600#endif
601
602#ifndef OPENSSL_NO_EC
603static int eckey_pkey2pkcs8(PKCS8_PRIV_KEY_INFO *p8, EVP_PKEY *pkey)
604{
605 EC_KEY *ec_key;
606 const EC_GROUP *group;
607 unsigned char *p, *pp;
608 int nid, i, ret = 0;
609 unsigned int tmp_flags, old_flags;
610
611 ec_key = pkey->pkey.ec;
612 if (ec_key == NULL || (group = EC_KEY_get0_group(ec_key)) == NULL)
613 {
614 EVPerr(EVP_F_ECKEY_PKEY2PKCS8, EVP_R_MISSING_PARAMETERS);
615 return 0;
616 }
617
618 /* set the ec parameters OID */
619 if (p8->pkeyalg->algorithm)
620 ASN1_OBJECT_free(p8->pkeyalg->algorithm);
621
622 p8->pkeyalg->algorithm = OBJ_nid2obj(NID_X9_62_id_ecPublicKey);
623
624 /* set the ec parameters */
625
626 if (p8->pkeyalg->parameter)
627 {
628 ASN1_TYPE_free(p8->pkeyalg->parameter);
629 p8->pkeyalg->parameter = NULL;
630 }
631
632 if ((p8->pkeyalg->parameter = ASN1_TYPE_new()) == NULL)
633 {
634 EVPerr(EVP_F_ECKEY_PKEY2PKCS8, ERR_R_MALLOC_FAILURE);
635 return 0;
636 }
637
638 if (EC_GROUP_get_asn1_flag(group)
639 && (nid = EC_GROUP_get_curve_name(group)))
640 {
641 /* we have a 'named curve' => just set the OID */
642 p8->pkeyalg->parameter->type = V_ASN1_OBJECT;
643 p8->pkeyalg->parameter->value.object = OBJ_nid2obj(nid);
644 }
645 else /* explicit parameters */
646 {
647 if ((i = i2d_ECParameters(ec_key, NULL)) == 0)
648 {
649 EVPerr(EVP_F_ECKEY_PKEY2PKCS8, ERR_R_EC_LIB);
650 return 0;
651 }
652 if ((p = (unsigned char *) OPENSSL_malloc(i)) == NULL)
653 {
654 EVPerr(EVP_F_ECKEY_PKEY2PKCS8, ERR_R_MALLOC_FAILURE);
655 return 0;
656 }
657 pp = p;
658 if (!i2d_ECParameters(ec_key, &pp))
659 {
660 EVPerr(EVP_F_ECKEY_PKEY2PKCS8, ERR_R_EC_LIB);
661 OPENSSL_free(p);
662 return 0;
663 }
664 p8->pkeyalg->parameter->type = V_ASN1_SEQUENCE;
665 if ((p8->pkeyalg->parameter->value.sequence
666 = ASN1_STRING_new()) == NULL)
667 {
668 EVPerr(EVP_F_ECKEY_PKEY2PKCS8, ERR_R_ASN1_LIB);
669 OPENSSL_free(p);
670 return 0;
671 }
672 ASN1_STRING_set(p8->pkeyalg->parameter->value.sequence, p, i);
673 OPENSSL_free(p);
674 }
675
676 /* set the private key */
677
678 /* do not include the parameters in the SEC1 private key
679 * see PKCS#11 12.11 */
680 old_flags = EC_KEY_get_enc_flags(pkey->pkey.ec);
681 tmp_flags = old_flags | EC_PKEY_NO_PARAMETERS;
682 EC_KEY_set_enc_flags(pkey->pkey.ec, tmp_flags);
683 i = i2d_ECPrivateKey(pkey->pkey.ec, NULL);
684 if (!i)
685 {
686 EC_KEY_set_enc_flags(pkey->pkey.ec, old_flags);
687 EVPerr(EVP_F_ECKEY_PKEY2PKCS8, ERR_R_EC_LIB);
688 return 0;
689 }
690 p = (unsigned char *) OPENSSL_malloc(i);
691 if (!p)
692 {
693 EC_KEY_set_enc_flags(pkey->pkey.ec, old_flags);
694 EVPerr(EVP_F_ECKEY_PKEY2PKCS8, ERR_R_MALLOC_FAILURE);
695 return 0;
696 }
697 pp = p;
698 if (!i2d_ECPrivateKey(pkey->pkey.ec, &pp))
699 {
700 EC_KEY_set_enc_flags(pkey->pkey.ec, old_flags);
701 EVPerr(EVP_F_ECKEY_PKEY2PKCS8, ERR_R_EC_LIB);
702 OPENSSL_free(p);
703 return 0;
704 }
705 /* restore old encoding flags */
706 EC_KEY_set_enc_flags(pkey->pkey.ec, old_flags);
707
708 switch(p8->broken) {
709
710 case PKCS8_OK:
711 p8->pkey->value.octet_string = ASN1_OCTET_STRING_new();
712 if (!p8->pkey->value.octet_string ||
713 !M_ASN1_OCTET_STRING_set(p8->pkey->value.octet_string,
714 (const void *)p, i))
715
716 {
717 EVPerr(EVP_F_ECKEY_PKEY2PKCS8, ERR_R_MALLOC_FAILURE);
718 }
719 else
720 ret = 1;
721 break;
722 case PKCS8_NO_OCTET: /* RSA specific */
723 case PKCS8_NS_DB: /* DSA specific */
724 case PKCS8_EMBEDDED_PARAM: /* DSA specific */
725 default:
726 EVPerr(EVP_F_ECKEY_PKEY2PKCS8,EVP_R_ENCODE_ERROR);
727 }
728 OPENSSL_cleanse(p, (size_t)i);
729 OPENSSL_free(p);
730 return ret;
731}
732#endif
733
734/* EVP_PKEY attribute functions */ 182/* EVP_PKEY attribute functions */
735 183
736int EVP_PKEY_get_attr_count(const EVP_PKEY *key) 184int EVP_PKEY_get_attr_count(const EVP_PKEY *key)
diff --git a/src/lib/libcrypto/evp/m_dss.c b/src/lib/libcrypto/evp/m_dss.c
index 6b0c0aa7a3..48c2689504 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=
81 NID_dsaWithSHA, 81 NID_dsaWithSHA,
82 NID_dsaWithSHA, 82 NID_dsaWithSHA,
83 SHA_DIGEST_LENGTH, 83 SHA_DIGEST_LENGTH,
84 EVP_MD_FLAG_FIPS, 84 EVP_MD_FLAG_PKEY_DIGEST,
85 init, 85 init,
86 update, 86 update,
87 final, 87 final,
diff --git a/src/lib/libcrypto/evp/m_dss1.c b/src/lib/libcrypto/evp/m_dss1.c
index da8babc147..4f03fb70e0 100644
--- a/src/lib/libcrypto/evp/m_dss1.c
+++ b/src/lib/libcrypto/evp/m_dss1.c
@@ -68,8 +68,6 @@
68#include <openssl/dsa.h> 68#include <openssl/dsa.h>
69#endif 69#endif
70 70
71#ifndef OPENSSL_FIPS
72
73static int init(EVP_MD_CTX *ctx) 71static int init(EVP_MD_CTX *ctx)
74 { return SHA1_Init(ctx->md_data); } 72 { return SHA1_Init(ctx->md_data); }
75 73
@@ -84,7 +82,7 @@ static const EVP_MD dss1_md=
84 NID_dsa, 82 NID_dsa,
85 NID_dsaWithSHA1, 83 NID_dsaWithSHA1,
86 SHA_DIGEST_LENGTH, 84 SHA_DIGEST_LENGTH,
87 0, 85 EVP_MD_FLAG_PKEY_DIGEST,
88 init, 86 init,
89 update, 87 update,
90 final, 88 final,
@@ -100,4 +98,3 @@ const EVP_MD *EVP_dss1(void)
100 return(&dss1_md); 98 return(&dss1_md);
101 } 99 }
102#endif 100#endif
103#endif
diff --git a/src/lib/libcrypto/evp/m_ecdsa.c b/src/lib/libcrypto/evp/m_ecdsa.c
index fad270faca..8d87a49ebe 100644
--- a/src/lib/libcrypto/evp/m_ecdsa.c
+++ b/src/lib/libcrypto/evp/m_ecdsa.c
@@ -130,7 +130,7 @@ static const EVP_MD ecdsa_md=
130 NID_ecdsa_with_SHA1, 130 NID_ecdsa_with_SHA1,
131 NID_ecdsa_with_SHA1, 131 NID_ecdsa_with_SHA1,
132 SHA_DIGEST_LENGTH, 132 SHA_DIGEST_LENGTH,
133 0, 133 EVP_MD_FLAG_PKEY_DIGEST,
134 init, 134 init,
135 update, 135 update,
136 final, 136 final,
diff --git a/src/lib/libcrypto/evp/m_md4.c b/src/lib/libcrypto/evp/m_md4.c
index 5cd2ab5ade..1e0b7c5b42 100644
--- a/src/lib/libcrypto/evp/m_md4.c
+++ b/src/lib/libcrypto/evp/m_md4.c
@@ -58,7 +58,6 @@
58 58
59#include <stdio.h> 59#include <stdio.h>
60#include "cryptlib.h" 60#include "cryptlib.h"
61#include "evp_locl.h"
62 61
63#ifndef OPENSSL_NO_MD4 62#ifndef OPENSSL_NO_MD4
64 63
diff --git a/src/lib/libcrypto/evp/m_md5.c b/src/lib/libcrypto/evp/m_md5.c
index 6455829671..63c142119e 100644
--- a/src/lib/libcrypto/evp/m_md5.c
+++ b/src/lib/libcrypto/evp/m_md5.c
@@ -62,7 +62,6 @@
62#ifndef OPENSSL_NO_MD5 62#ifndef OPENSSL_NO_MD5
63 63
64#include <openssl/evp.h> 64#include <openssl/evp.h>
65#include "evp_locl.h"
66#include <openssl/objects.h> 65#include <openssl/objects.h>
67#include <openssl/x509.h> 66#include <openssl/x509.h>
68#include <openssl/md5.h> 67#include <openssl/md5.h>
diff --git a/src/lib/libcrypto/evp/m_sha1.c b/src/lib/libcrypto/evp/m_sha1.c
index 471ec30be0..9a2790fdea 100644
--- a/src/lib/libcrypto/evp/m_sha1.c
+++ b/src/lib/libcrypto/evp/m_sha1.c
@@ -68,8 +68,6 @@
68#include <openssl/rsa.h> 68#include <openssl/rsa.h>
69#endif 69#endif
70 70
71#ifndef OPENSSL_FIPS
72
73static int init(EVP_MD_CTX *ctx) 71static int init(EVP_MD_CTX *ctx)
74 { return SHA1_Init(ctx->md_data); } 72 { return SHA1_Init(ctx->md_data); }
75 73
@@ -84,7 +82,7 @@ static const EVP_MD sha1_md=
84 NID_sha1, 82 NID_sha1,
85 NID_sha1WithRSAEncryption, 83 NID_sha1WithRSAEncryption,
86 SHA_DIGEST_LENGTH, 84 SHA_DIGEST_LENGTH,
87 0, 85 EVP_MD_FLAG_PKEY_METHOD_SIGNATURE|EVP_MD_FLAG_DIGALGID_ABSENT,
88 init, 86 init,
89 update, 87 update,
90 final, 88 final,
@@ -99,6 +97,7 @@ const EVP_MD *EVP_sha1(void)
99 { 97 {
100 return(&sha1_md); 98 return(&sha1_md);
101 } 99 }
100#endif
102 101
103#ifndef OPENSSL_NO_SHA256 102#ifndef OPENSSL_NO_SHA256
104static int init224(EVP_MD_CTX *ctx) 103static int init224(EVP_MD_CTX *ctx)
@@ -120,7 +119,7 @@ static const EVP_MD sha224_md=
120 NID_sha224, 119 NID_sha224,
121 NID_sha224WithRSAEncryption, 120 NID_sha224WithRSAEncryption,
122 SHA224_DIGEST_LENGTH, 121 SHA224_DIGEST_LENGTH,
123 0, 122 EVP_MD_FLAG_PKEY_METHOD_SIGNATURE|EVP_MD_FLAG_DIGALGID_ABSENT,
124 init224, 123 init224,
125 update256, 124 update256,
126 final256, 125 final256,
@@ -139,7 +138,7 @@ static const EVP_MD sha256_md=
139 NID_sha256, 138 NID_sha256,
140 NID_sha256WithRSAEncryption, 139 NID_sha256WithRSAEncryption,
141 SHA256_DIGEST_LENGTH, 140 SHA256_DIGEST_LENGTH,
142 0, 141 EVP_MD_FLAG_PKEY_METHOD_SIGNATURE|EVP_MD_FLAG_DIGALGID_ABSENT,
143 init256, 142 init256,
144 update256, 143 update256,
145 final256, 144 final256,
@@ -170,7 +169,7 @@ static const EVP_MD sha384_md=
170 NID_sha384, 169 NID_sha384,
171 NID_sha384WithRSAEncryption, 170 NID_sha384WithRSAEncryption,
172 SHA384_DIGEST_LENGTH, 171 SHA384_DIGEST_LENGTH,
173 0, 172 EVP_MD_FLAG_PKEY_METHOD_SIGNATURE|EVP_MD_FLAG_DIGALGID_ABSENT,
174 init384, 173 init384,
175 update512, 174 update512,
176 final512, 175 final512,
@@ -189,7 +188,7 @@ static const EVP_MD sha512_md=
189 NID_sha512, 188 NID_sha512,
190 NID_sha512WithRSAEncryption, 189 NID_sha512WithRSAEncryption,
191 SHA512_DIGEST_LENGTH, 190 SHA512_DIGEST_LENGTH,
192 0, 191 EVP_MD_FLAG_PKEY_METHOD_SIGNATURE|EVP_MD_FLAG_DIGALGID_ABSENT,
193 init512, 192 init512,
194 update512, 193 update512,
195 final512, 194 final512,
@@ -203,7 +202,3 @@ static const EVP_MD sha512_md=
203const EVP_MD *EVP_sha512(void) 202const EVP_MD *EVP_sha512(void)
204 { return(&sha512_md); } 203 { return(&sha512_md); }
205#endif /* ifndef OPENSSL_NO_SHA512 */ 204#endif /* ifndef OPENSSL_NO_SHA512 */
206
207#endif
208
209#endif
diff --git a/src/lib/libcrypto/evp/m_sigver.c b/src/lib/libcrypto/evp/m_sigver.c
new file mode 100644
index 0000000000..f0b7f95059
--- /dev/null
+++ b/src/lib/libcrypto/evp/m_sigver.c
@@ -0,0 +1,200 @@
1/* m_sigver.c */
2/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
3 * project 2006.
4 */
5/* ====================================================================
6 * Copyright (c) 2006,2007 The OpenSSL Project. All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 *
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 *
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in
17 * the documentation and/or other materials provided with the
18 * distribution.
19 *
20 * 3. All advertising materials mentioning features or use of this
21 * software must display the following acknowledgment:
22 * "This product includes software developed by the OpenSSL Project
23 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
24 *
25 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
26 * endorse or promote products derived from this software without
27 * prior written permission. For written permission, please contact
28 * licensing@OpenSSL.org.
29 *
30 * 5. Products derived from this software may not be called "OpenSSL"
31 * nor may "OpenSSL" appear in their names without prior written
32 * permission of the OpenSSL Project.
33 *
34 * 6. Redistributions of any form whatsoever must retain the following
35 * acknowledgment:
36 * "This product includes software developed by the OpenSSL Project
37 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
38 *
39 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
40 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
43 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
50 * OF THE POSSIBILITY OF SUCH DAMAGE.
51 * ====================================================================
52 *
53 * This product includes cryptographic software written by Eric Young
54 * (eay@cryptsoft.com). This product includes software written by Tim
55 * Hudson (tjh@cryptsoft.com).
56 *
57 */
58
59#include <stdio.h>
60#include "cryptlib.h"
61#include <openssl/evp.h>
62#include <openssl/objects.h>
63#include <openssl/x509.h>
64#include "evp_locl.h"
65
66static int do_sigver_init(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx,
67 const EVP_MD *type, ENGINE *e, EVP_PKEY *pkey,
68 int ver)
69 {
70 if (ctx->pctx == NULL)
71 ctx->pctx = EVP_PKEY_CTX_new(pkey, e);
72 if (ctx->pctx == NULL)
73 return 0;
74
75 if (type == NULL)
76 {
77 int def_nid;
78 if (EVP_PKEY_get_default_digest_nid(pkey, &def_nid) > 0)
79 type = EVP_get_digestbynid(def_nid);
80 }
81
82 if (type == NULL)
83 {
84 EVPerr(EVP_F_DO_SIGVER_INIT, EVP_R_NO_DEFAULT_DIGEST);
85 return 0;
86 }
87
88 if (ver)
89 {
90 if (ctx->pctx->pmeth->verifyctx_init)
91 {
92 if (ctx->pctx->pmeth->verifyctx_init(ctx->pctx, ctx) <=0)
93 return 0;
94 ctx->pctx->operation = EVP_PKEY_OP_VERIFYCTX;
95 }
96 else if (EVP_PKEY_verify_init(ctx->pctx) <= 0)
97 return 0;
98 }
99 else
100 {
101 if (ctx->pctx->pmeth->signctx_init)
102 {
103 if (ctx->pctx->pmeth->signctx_init(ctx->pctx, ctx) <= 0)
104 return 0;
105 ctx->pctx->operation = EVP_PKEY_OP_SIGNCTX;
106 }
107 else if (EVP_PKEY_sign_init(ctx->pctx) <= 0)
108 return 0;
109 }
110 if (EVP_PKEY_CTX_set_signature_md(ctx->pctx, type) <= 0)
111 return 0;
112 if (pctx)
113 *pctx = ctx->pctx;
114 if (!EVP_DigestInit_ex(ctx, type, e))
115 return 0;
116 return 1;
117 }
118
119int EVP_DigestSignInit(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx,
120 const EVP_MD *type, ENGINE *e, EVP_PKEY *pkey)
121 {
122 return do_sigver_init(ctx, pctx, type, e, pkey, 0);
123 }
124
125int EVP_DigestVerifyInit(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx,
126 const EVP_MD *type, ENGINE *e, EVP_PKEY *pkey)
127 {
128 return do_sigver_init(ctx, pctx, type, e, pkey, 1);
129 }
130
131int EVP_DigestSignFinal(EVP_MD_CTX *ctx, unsigned char *sigret, size_t *siglen)
132 {
133 int sctx, r = 0;
134 if (ctx->pctx->pmeth->signctx)
135 sctx = 1;
136 else
137 sctx = 0;
138 if (sigret)
139 {
140 MS_STATIC EVP_MD_CTX tmp_ctx;
141 unsigned char md[EVP_MAX_MD_SIZE];
142 unsigned int mdlen;
143 EVP_MD_CTX_init(&tmp_ctx);
144 if (!EVP_MD_CTX_copy_ex(&tmp_ctx,ctx))
145 return 0;
146 if (sctx)
147 r = tmp_ctx.pctx->pmeth->signctx(tmp_ctx.pctx,
148 sigret, siglen, &tmp_ctx);
149 else
150 r = EVP_DigestFinal_ex(&tmp_ctx,md,&mdlen);
151 EVP_MD_CTX_cleanup(&tmp_ctx);
152 if (sctx || !r)
153 return r;
154 if (EVP_PKEY_sign(ctx->pctx, sigret, siglen, md, mdlen) <= 0)
155 return 0;
156 }
157 else
158 {
159 if (sctx)
160 {
161 if (ctx->pctx->pmeth->signctx(ctx->pctx, sigret, siglen, ctx) <= 0)
162 return 0;
163 }
164 else
165 {
166 int s = EVP_MD_size(ctx->digest);
167 if (s < 0 || EVP_PKEY_sign(ctx->pctx, sigret, siglen, NULL, s) <= 0)
168 return 0;
169 }
170 }
171 return 1;
172 }
173
174int EVP_DigestVerifyFinal(EVP_MD_CTX *ctx, unsigned char *sig, size_t siglen)
175 {
176 MS_STATIC EVP_MD_CTX tmp_ctx;
177 unsigned char md[EVP_MAX_MD_SIZE];
178 int r;
179 unsigned int mdlen;
180 int vctx;
181
182 if (ctx->pctx->pmeth->verifyctx)
183 vctx = 1;
184 else
185 vctx = 0;
186 EVP_MD_CTX_init(&tmp_ctx);
187 if (!EVP_MD_CTX_copy_ex(&tmp_ctx,ctx))
188 return -1;
189 if (vctx)
190 {
191 r = tmp_ctx.pctx->pmeth->verifyctx(tmp_ctx.pctx,
192 sig, siglen, &tmp_ctx);
193 }
194 else
195 r = EVP_DigestFinal_ex(&tmp_ctx,md,&mdlen);
196 EVP_MD_CTX_cleanup(&tmp_ctx);
197 if (vctx || !r)
198 return r;
199 return EVP_PKEY_verify(ctx->pctx, sig, siglen, md, mdlen);
200 }
diff --git a/src/lib/libcrypto/evp/m_wp.c b/src/lib/libcrypto/evp/m_wp.c
new file mode 100644
index 0000000000..1ce47c040b
--- /dev/null
+++ b/src/lib/libcrypto/evp/m_wp.c
@@ -0,0 +1,42 @@
1/* crypto/evp/m_wp.c */
2
3#include <stdio.h>
4#include "cryptlib.h"
5
6#ifndef OPENSSL_NO_WHIRLPOOL
7
8#include <openssl/evp.h>
9#include <openssl/objects.h>
10#include <openssl/x509.h>
11#include <openssl/whrlpool.h>
12
13static int init(EVP_MD_CTX *ctx)
14 { return WHIRLPOOL_Init(ctx->md_data); }
15
16static int update(EVP_MD_CTX *ctx,const void *data,size_t count)
17 { return WHIRLPOOL_Update(ctx->md_data,data,count); }
18
19static int final(EVP_MD_CTX *ctx,unsigned char *md)
20 { return WHIRLPOOL_Final(md,ctx->md_data); }
21
22static const EVP_MD whirlpool_md=
23 {
24 NID_whirlpool,
25 0,
26 WHIRLPOOL_DIGEST_LENGTH,
27 0,
28 init,
29 update,
30 final,
31 NULL,
32 NULL,
33 EVP_PKEY_NULL_method,
34 WHIRLPOOL_BBLOCK/8,
35 sizeof(EVP_MD *)+sizeof(WHIRLPOOL_CTX),
36 };
37
38const EVP_MD *EVP_whirlpool(void)
39 {
40 return(&whirlpool_md);
41 }
42#endif
diff --git a/src/lib/libcrypto/evp/names.c b/src/lib/libcrypto/evp/names.c
index e2e04c3570..f2869f5c78 100644
--- a/src/lib/libcrypto/evp/names.c
+++ b/src/lib/libcrypto/evp/names.c
@@ -66,35 +66,32 @@ int EVP_add_cipher(const EVP_CIPHER *c)
66 { 66 {
67 int r; 67 int r;
68 68
69#ifdef OPENSSL_FIPS
70 OPENSSL_init();
71#endif
72
73 r=OBJ_NAME_add(OBJ_nid2sn(c->nid),OBJ_NAME_TYPE_CIPHER_METH,(const char *)c); 69 r=OBJ_NAME_add(OBJ_nid2sn(c->nid),OBJ_NAME_TYPE_CIPHER_METH,(const char *)c);
74 if (r == 0) return(0); 70 if (r == 0) return(0);
71 check_defer(c->nid);
75 r=OBJ_NAME_add(OBJ_nid2ln(c->nid),OBJ_NAME_TYPE_CIPHER_METH,(const char *)c); 72 r=OBJ_NAME_add(OBJ_nid2ln(c->nid),OBJ_NAME_TYPE_CIPHER_METH,(const char *)c);
76 return(r); 73 return(r);
77 } 74 }
78 75
76
79int EVP_add_digest(const EVP_MD *md) 77int EVP_add_digest(const EVP_MD *md)
80 { 78 {
81 int r; 79 int r;
82 const char *name; 80 const char *name;
83 81
84#ifdef OPENSSL_FIPS
85 OPENSSL_init();
86#endif
87 name=OBJ_nid2sn(md->type); 82 name=OBJ_nid2sn(md->type);
88 r=OBJ_NAME_add(name,OBJ_NAME_TYPE_MD_METH,(const char *)md); 83 r=OBJ_NAME_add(name,OBJ_NAME_TYPE_MD_METH,(const char *)md);
89 if (r == 0) return(0); 84 if (r == 0) return(0);
85 check_defer(md->type);
90 r=OBJ_NAME_add(OBJ_nid2ln(md->type),OBJ_NAME_TYPE_MD_METH,(const char *)md); 86 r=OBJ_NAME_add(OBJ_nid2ln(md->type),OBJ_NAME_TYPE_MD_METH,(const char *)md);
91 if (r == 0) return(0); 87 if (r == 0) return(0);
92 88
93 if (md->type != md->pkey_type) 89 if (md->pkey_type && md->type != md->pkey_type)
94 { 90 {
95 r=OBJ_NAME_add(OBJ_nid2sn(md->pkey_type), 91 r=OBJ_NAME_add(OBJ_nid2sn(md->pkey_type),
96 OBJ_NAME_TYPE_MD_METH|OBJ_NAME_ALIAS,name); 92 OBJ_NAME_TYPE_MD_METH|OBJ_NAME_ALIAS,name);
97 if (r == 0) return(0); 93 if (r == 0) return(0);
94 check_defer(md->pkey_type);
98 r=OBJ_NAME_add(OBJ_nid2ln(md->pkey_type), 95 r=OBJ_NAME_add(OBJ_nid2ln(md->pkey_type),
99 OBJ_NAME_TYPE_MD_METH|OBJ_NAME_ALIAS,name); 96 OBJ_NAME_TYPE_MD_METH|OBJ_NAME_ALIAS,name);
100 } 97 }
@@ -127,4 +124,78 @@ void EVP_cleanup(void)
127 OBJ_NAME_cleanup(-1); 124 OBJ_NAME_cleanup(-1);
128 125
129 EVP_PBE_cleanup(); 126 EVP_PBE_cleanup();
127 if (obj_cleanup_defer == 2)
128 {
129 obj_cleanup_defer = 0;
130 OBJ_cleanup();
131 }
132 OBJ_sigid_free();
133 }
134
135struct doall_cipher
136 {
137 void *arg;
138 void (*fn)(const EVP_CIPHER *ciph,
139 const char *from, const char *to, void *arg);
140 };
141
142static void do_all_cipher_fn(const OBJ_NAME *nm, void *arg)
143 {
144 struct doall_cipher *dc = arg;
145 if (nm->alias)
146 dc->fn(NULL, nm->name, nm->data, dc->arg);
147 else
148 dc->fn((const EVP_CIPHER *)nm->data, nm->name, NULL, dc->arg);
149 }
150
151void EVP_CIPHER_do_all(void (*fn)(const EVP_CIPHER *ciph,
152 const char *from, const char *to, void *x), void *arg)
153 {
154 struct doall_cipher dc;
155 dc.fn = fn;
156 dc.arg = arg;
157 OBJ_NAME_do_all(OBJ_NAME_TYPE_CIPHER_METH, do_all_cipher_fn, &dc);
158 }
159
160void EVP_CIPHER_do_all_sorted(void (*fn)(const EVP_CIPHER *ciph,
161 const char *from, const char *to, void *x), void *arg)
162 {
163 struct doall_cipher dc;
164 dc.fn = fn;
165 dc.arg = arg;
166 OBJ_NAME_do_all_sorted(OBJ_NAME_TYPE_CIPHER_METH, do_all_cipher_fn,&dc);
167 }
168
169struct doall_md
170 {
171 void *arg;
172 void (*fn)(const EVP_MD *ciph,
173 const char *from, const char *to, void *arg);
174 };
175
176static void do_all_md_fn(const OBJ_NAME *nm, void *arg)
177 {
178 struct doall_md *dc = arg;
179 if (nm->alias)
180 dc->fn(NULL, nm->name, nm->data, dc->arg);
181 else
182 dc->fn((const EVP_MD *)nm->data, nm->name, NULL, dc->arg);
183 }
184
185void EVP_MD_do_all(void (*fn)(const EVP_MD *md,
186 const char *from, const char *to, void *x), void *arg)
187 {
188 struct doall_md dc;
189 dc.fn = fn;
190 dc.arg = arg;
191 OBJ_NAME_do_all(OBJ_NAME_TYPE_MD_METH, do_all_md_fn, &dc);
192 }
193
194void EVP_MD_do_all_sorted(void (*fn)(const EVP_MD *md,
195 const char *from, const char *to, void *x), void *arg)
196 {
197 struct doall_md dc;
198 dc.fn = fn;
199 dc.arg = arg;
200 OBJ_NAME_do_all_sorted(OBJ_NAME_TYPE_MD_METH, do_all_md_fn, &dc);
130 } 201 }
diff --git a/src/lib/libcrypto/evp/p5_crpt.c b/src/lib/libcrypto/evp/p5_crpt.c
index 2a265fdee2..7ecfa8dad9 100644
--- a/src/lib/libcrypto/evp/p5_crpt.c
+++ b/src/lib/libcrypto/evp/p5_crpt.c
@@ -62,42 +62,11 @@
62#include <openssl/x509.h> 62#include <openssl/x509.h>
63#include <openssl/evp.h> 63#include <openssl/evp.h>
64 64
65/* PKCS#5 v1.5 compatible PBE functions: see PKCS#5 v2.0 for more info. 65/* Doesn't do anything now: Builtin PBE algorithms in static table.
66 */ 66 */
67 67
68void PKCS5_PBE_add(void) 68void PKCS5_PBE_add(void)
69{ 69{
70#ifndef OPENSSL_NO_DES
71# ifndef OPENSSL_NO_MD5
72EVP_PBE_alg_add(NID_pbeWithMD5AndDES_CBC, EVP_des_cbc(), EVP_md5(),
73 PKCS5_PBE_keyivgen);
74# endif
75# ifndef OPENSSL_NO_MD2
76EVP_PBE_alg_add(NID_pbeWithMD2AndDES_CBC, EVP_des_cbc(), EVP_md2(),
77 PKCS5_PBE_keyivgen);
78# endif
79# ifndef OPENSSL_NO_SHA
80EVP_PBE_alg_add(NID_pbeWithSHA1AndDES_CBC, EVP_des_cbc(), EVP_sha1(),
81 PKCS5_PBE_keyivgen);
82# endif
83#endif
84#ifndef OPENSSL_NO_RC2
85# ifndef OPENSSL_NO_MD5
86EVP_PBE_alg_add(NID_pbeWithMD5AndRC2_CBC, EVP_rc2_64_cbc(), EVP_md5(),
87 PKCS5_PBE_keyivgen);
88# endif
89# ifndef OPENSSL_NO_MD2
90EVP_PBE_alg_add(NID_pbeWithMD2AndRC2_CBC, EVP_rc2_64_cbc(), EVP_md2(),
91 PKCS5_PBE_keyivgen);
92# endif
93# ifndef OPENSSL_NO_SHA
94EVP_PBE_alg_add(NID_pbeWithSHA1AndRC2_CBC, EVP_rc2_64_cbc(), EVP_sha1(),
95 PKCS5_PBE_keyivgen);
96# endif
97#endif
98#ifndef OPENSSL_NO_HMAC
99EVP_PBE_alg_add(NID_pbes2, NULL, NULL, PKCS5_v2_PBE_keyivgen);
100#endif
101} 70}
102 71
103int PKCS5_PBE_keyivgen(EVP_CIPHER_CTX *cctx, const char *pass, int passlen, 72int PKCS5_PBE_keyivgen(EVP_CIPHER_CTX *cctx, const char *pass, int passlen,
@@ -112,6 +81,7 @@ int PKCS5_PBE_keyivgen(EVP_CIPHER_CTX *cctx, const char *pass, int passlen,
112 int saltlen, iter; 81 int saltlen, iter;
113 unsigned char *salt; 82 unsigned char *salt;
114 const unsigned char *pbuf; 83 const unsigned char *pbuf;
84 int mdsize;
115 85
116 /* Extract useful info from parameter */ 86 /* Extract useful info from parameter */
117 if (param == NULL || param->type != V_ASN1_SEQUENCE || 87 if (param == NULL || param->type != V_ASN1_SEQUENCE ||
@@ -140,9 +110,12 @@ int PKCS5_PBE_keyivgen(EVP_CIPHER_CTX *cctx, const char *pass, int passlen,
140 EVP_DigestUpdate(&ctx, salt, saltlen); 110 EVP_DigestUpdate(&ctx, salt, saltlen);
141 PBEPARAM_free(pbe); 111 PBEPARAM_free(pbe);
142 EVP_DigestFinal_ex(&ctx, md_tmp, NULL); 112 EVP_DigestFinal_ex(&ctx, md_tmp, NULL);
113 mdsize = EVP_MD_size(md);
114 if (mdsize < 0)
115 return 0;
143 for (i = 1; i < iter; i++) { 116 for (i = 1; i < iter; i++) {
144 EVP_DigestInit_ex(&ctx, md, NULL); 117 EVP_DigestInit_ex(&ctx, md, NULL);
145 EVP_DigestUpdate(&ctx, md_tmp, EVP_MD_size(md)); 118 EVP_DigestUpdate(&ctx, md_tmp, mdsize);
146 EVP_DigestFinal_ex (&ctx, md_tmp, NULL); 119 EVP_DigestFinal_ex (&ctx, md_tmp, NULL);
147 } 120 }
148 EVP_MD_CTX_cleanup(&ctx); 121 EVP_MD_CTX_cleanup(&ctx);
diff --git a/src/lib/libcrypto/evp/p5_crpt2.c b/src/lib/libcrypto/evp/p5_crpt2.c
index 6bec77baf9..334379f310 100644
--- a/src/lib/libcrypto/evp/p5_crpt2.c
+++ b/src/lib/libcrypto/evp/p5_crpt2.c
@@ -3,7 +3,7 @@
3 * project 1999. 3 * project 1999.
4 */ 4 */
5/* ==================================================================== 5/* ====================================================================
6 * Copyright (c) 1999 The OpenSSL Project. All rights reserved. 6 * Copyright (c) 1999-2006 The OpenSSL Project. All rights reserved.
7 * 7 *
8 * Redistribution and use in source and binary forms, with or without 8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions 9 * modification, are permitted provided that the following conditions
@@ -71,28 +71,38 @@
71#endif 71#endif
72 72
73/* This is an implementation of PKCS#5 v2.0 password based encryption key 73/* This is an implementation of PKCS#5 v2.0 password based encryption key
74 * derivation function PBKDF2 using the only currently defined function HMAC 74 * derivation function PBKDF2.
75 * with SHA1. Verified against test vectors posted by Peter Gutmann 75 * SHA1 version verified against test vectors posted by Peter Gutmann
76 * <pgut001@cs.auckland.ac.nz> to the PKCS-TNG <pkcs-tng@rsa.com> mailing list. 76 * <pgut001@cs.auckland.ac.nz> to the PKCS-TNG <pkcs-tng@rsa.com> mailing list.
77 */ 77 */
78 78
79int PKCS5_PBKDF2_HMAC_SHA1(const char *pass, int passlen, 79int PKCS5_PBKDF2_HMAC(const char *pass, int passlen,
80 const unsigned char *salt, int saltlen, int iter, 80 const unsigned char *salt, int saltlen, int iter,
81 const EVP_MD *digest,
81 int keylen, unsigned char *out) 82 int keylen, unsigned char *out)
82{ 83 {
83 unsigned char digtmp[SHA_DIGEST_LENGTH], *p, itmp[4]; 84 unsigned char digtmp[EVP_MAX_MD_SIZE], *p, itmp[4];
84 int cplen, j, k, tkeylen; 85 int cplen, j, k, tkeylen, mdlen;
85 unsigned long i = 1; 86 unsigned long i = 1;
86 HMAC_CTX hctx; 87 HMAC_CTX hctx;
87 88
89 mdlen = EVP_MD_size(digest);
90 if (mdlen < 0)
91 return 0;
92
88 HMAC_CTX_init(&hctx); 93 HMAC_CTX_init(&hctx);
89 p = out; 94 p = out;
90 tkeylen = keylen; 95 tkeylen = keylen;
91 if(!pass) passlen = 0; 96 if(!pass)
92 else if(passlen == -1) passlen = strlen(pass); 97 passlen = 0;
93 while(tkeylen) { 98 else if(passlen == -1)
94 if(tkeylen > SHA_DIGEST_LENGTH) cplen = SHA_DIGEST_LENGTH; 99 passlen = strlen(pass);
95 else cplen = tkeylen; 100 while(tkeylen)
101 {
102 if(tkeylen > mdlen)
103 cplen = mdlen;
104 else
105 cplen = tkeylen;
96 /* We are unlikely to ever use more than 256 blocks (5120 bits!) 106 /* We are unlikely to ever use more than 256 blocks (5120 bits!)
97 * but just in case... 107 * but just in case...
98 */ 108 */
@@ -100,20 +110,22 @@ int PKCS5_PBKDF2_HMAC_SHA1(const char *pass, int passlen,
100 itmp[1] = (unsigned char)((i >> 16) & 0xff); 110 itmp[1] = (unsigned char)((i >> 16) & 0xff);
101 itmp[2] = (unsigned char)((i >> 8) & 0xff); 111 itmp[2] = (unsigned char)((i >> 8) & 0xff);
102 itmp[3] = (unsigned char)(i & 0xff); 112 itmp[3] = (unsigned char)(i & 0xff);
103 HMAC_Init_ex(&hctx, pass, passlen, EVP_sha1(), NULL); 113 HMAC_Init_ex(&hctx, pass, passlen, digest, NULL);
104 HMAC_Update(&hctx, salt, saltlen); 114 HMAC_Update(&hctx, salt, saltlen);
105 HMAC_Update(&hctx, itmp, 4); 115 HMAC_Update(&hctx, itmp, 4);
106 HMAC_Final(&hctx, digtmp, NULL); 116 HMAC_Final(&hctx, digtmp, NULL);
107 memcpy(p, digtmp, cplen); 117 memcpy(p, digtmp, cplen);
108 for(j = 1; j < iter; j++) { 118 for(j = 1; j < iter; j++)
109 HMAC(EVP_sha1(), pass, passlen, 119 {
110 digtmp, SHA_DIGEST_LENGTH, digtmp, NULL); 120 HMAC(digest, pass, passlen,
111 for(k = 0; k < cplen; k++) p[k] ^= digtmp[k]; 121 digtmp, mdlen, digtmp, NULL);
112 } 122 for(k = 0; k < cplen; k++)
123 p[k] ^= digtmp[k];
124 }
113 tkeylen-= cplen; 125 tkeylen-= cplen;
114 i++; 126 i++;
115 p+= cplen; 127 p+= cplen;
116 } 128 }
117 HMAC_CTX_cleanup(&hctx); 129 HMAC_CTX_cleanup(&hctx);
118#ifdef DEBUG_PKCS5V2 130#ifdef DEBUG_PKCS5V2
119 fprintf(stderr, "Password:\n"); 131 fprintf(stderr, "Password:\n");
@@ -125,7 +137,15 @@ int PKCS5_PBKDF2_HMAC_SHA1(const char *pass, int passlen,
125 h__dump (out, keylen); 137 h__dump (out, keylen);
126#endif 138#endif
127 return 1; 139 return 1;
128} 140 }
141
142int PKCS5_PBKDF2_HMAC_SHA1(const char *pass, int passlen,
143 const unsigned char *salt, int saltlen, int iter,
144 int keylen, unsigned char *out)
145 {
146 return PKCS5_PBKDF2_HMAC(pass, passlen, salt, saltlen, iter, EVP_sha1(),
147 keylen, out);
148 }
129 149
130#ifdef DO_TEST 150#ifdef DO_TEST
131main() 151main()
@@ -155,6 +175,8 @@ int PKCS5_v2_PBE_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, int passlen,
155 PBE2PARAM *pbe2 = NULL; 175 PBE2PARAM *pbe2 = NULL;
156 const EVP_CIPHER *cipher; 176 const EVP_CIPHER *cipher;
157 PBKDF2PARAM *kdf = NULL; 177 PBKDF2PARAM *kdf = NULL;
178 const EVP_MD *prfmd;
179 int prf_nid, hmac_md_nid;
158 180
159 if (param == NULL || param->type != V_ASN1_SEQUENCE || 181 if (param == NULL || param->type != V_ASN1_SEQUENCE ||
160 param->value.sequence == NULL) { 182 param->value.sequence == NULL) {
@@ -180,8 +202,7 @@ int PKCS5_v2_PBE_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, int passlen,
180 /* lets see if we recognise the encryption algorithm. 202 /* lets see if we recognise the encryption algorithm.
181 */ 203 */
182 204
183 cipher = EVP_get_cipherbyname( 205 cipher = EVP_get_cipherbyobj(pbe2->encryption->algorithm);
184 OBJ_nid2sn(OBJ_obj2nid(pbe2->encryption->algorithm)));
185 206
186 if(!cipher) { 207 if(!cipher) {
187 EVPerr(EVP_F_PKCS5_V2_PBE_KEYIVGEN, 208 EVPerr(EVP_F_PKCS5_V2_PBE_KEYIVGEN,
@@ -226,10 +247,23 @@ int PKCS5_v2_PBE_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, int passlen,
226 goto err; 247 goto err;
227 } 248 }
228 249
229 if(kdf->prf && (OBJ_obj2nid(kdf->prf->algorithm) != NID_hmacWithSHA1)) { 250 if (kdf->prf)
251 prf_nid = OBJ_obj2nid(kdf->prf->algorithm);
252 else
253 prf_nid = NID_hmacWithSHA1;
254
255 if (!EVP_PBE_find(EVP_PBE_TYPE_PRF, prf_nid, NULL, &hmac_md_nid, 0))
256 {
230 EVPerr(EVP_F_PKCS5_V2_PBE_KEYIVGEN, EVP_R_UNSUPPORTED_PRF); 257 EVPerr(EVP_F_PKCS5_V2_PBE_KEYIVGEN, EVP_R_UNSUPPORTED_PRF);
231 goto err; 258 goto err;
232 } 259 }
260
261 prfmd = EVP_get_digestbynid(hmac_md_nid);
262 if (prfmd == NULL)
263 {
264 EVPerr(EVP_F_PKCS5_V2_PBE_KEYIVGEN, EVP_R_UNSUPPORTED_PRF);
265 goto err;
266 }
233 267
234 if(kdf->salt->type != V_ASN1_OCTET_STRING) { 268 if(kdf->salt->type != V_ASN1_OCTET_STRING) {
235 EVPerr(EVP_F_PKCS5_V2_PBE_KEYIVGEN, 269 EVPerr(EVP_F_PKCS5_V2_PBE_KEYIVGEN,
@@ -241,7 +275,9 @@ int PKCS5_v2_PBE_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, int passlen,
241 salt = kdf->salt->value.octet_string->data; 275 salt = kdf->salt->value.octet_string->data;
242 saltlen = kdf->salt->value.octet_string->length; 276 saltlen = kdf->salt->value.octet_string->length;
243 iter = ASN1_INTEGER_get(kdf->iter); 277 iter = ASN1_INTEGER_get(kdf->iter);
244 PKCS5_PBKDF2_HMAC_SHA1(pass, passlen, salt, saltlen, iter, keylen, key); 278 if(!PKCS5_PBKDF2_HMAC(pass, passlen, salt, saltlen, iter, prfmd,
279 keylen, key))
280 goto err;
245 EVP_CipherInit_ex(ctx, NULL, NULL, key, NULL, en_de); 281 EVP_CipherInit_ex(ctx, NULL, NULL, key, NULL, en_de);
246 OPENSSL_cleanse(key, keylen); 282 OPENSSL_cleanse(key, keylen);
247 PBKDF2PARAM_free(kdf); 283 PBKDF2PARAM_free(kdf);
diff --git a/src/lib/libcrypto/evp/p_dec.c b/src/lib/libcrypto/evp/p_dec.c
index f64901f653..4201dcbad9 100644
--- a/src/lib/libcrypto/evp/p_dec.c
+++ b/src/lib/libcrypto/evp/p_dec.c
@@ -66,7 +66,7 @@
66#include <openssl/objects.h> 66#include <openssl/objects.h>
67#include <openssl/x509.h> 67#include <openssl/x509.h>
68 68
69int EVP_PKEY_decrypt(unsigned char *key, const unsigned char *ek, int ekl, 69int EVP_PKEY_decrypt_old(unsigned char *key, const unsigned char *ek, int ekl,
70 EVP_PKEY *priv) 70 EVP_PKEY *priv)
71 { 71 {
72 int ret= -1; 72 int ret= -1;
@@ -75,7 +75,7 @@ int EVP_PKEY_decrypt(unsigned char *key, const unsigned char *ek, int ekl,
75 if (priv->type != EVP_PKEY_RSA) 75 if (priv->type != EVP_PKEY_RSA)
76 { 76 {
77#endif 77#endif
78 EVPerr(EVP_F_EVP_PKEY_DECRYPT,EVP_R_PUBLIC_KEY_NOT_RSA); 78 EVPerr(EVP_F_EVP_PKEY_DECRYPT_OLD,EVP_R_PUBLIC_KEY_NOT_RSA);
79#ifndef OPENSSL_NO_RSA 79#ifndef OPENSSL_NO_RSA
80 goto err; 80 goto err;
81 } 81 }
diff --git a/src/lib/libcrypto/evp/p_enc.c b/src/lib/libcrypto/evp/p_enc.c
index c2dfdc52ad..b5a3a84c41 100644
--- a/src/lib/libcrypto/evp/p_enc.c
+++ b/src/lib/libcrypto/evp/p_enc.c
@@ -66,7 +66,7 @@
66#include <openssl/objects.h> 66#include <openssl/objects.h>
67#include <openssl/x509.h> 67#include <openssl/x509.h>
68 68
69int EVP_PKEY_encrypt(unsigned char *ek, const unsigned char *key, int key_len, 69int EVP_PKEY_encrypt_old(unsigned char *ek, const unsigned char *key, int key_len,
70 EVP_PKEY *pubk) 70 EVP_PKEY *pubk)
71 { 71 {
72 int ret=0; 72 int ret=0;
@@ -75,7 +75,7 @@ int EVP_PKEY_encrypt(unsigned char *ek, const unsigned char *key, int key_len,
75 if (pubk->type != EVP_PKEY_RSA) 75 if (pubk->type != EVP_PKEY_RSA)
76 { 76 {
77#endif 77#endif
78 EVPerr(EVP_F_EVP_PKEY_ENCRYPT,EVP_R_PUBLIC_KEY_NOT_RSA); 78 EVPerr(EVP_F_EVP_PKEY_ENCRYPT_OLD,EVP_R_PUBLIC_KEY_NOT_RSA);
79#ifndef OPENSSL_NO_RSA 79#ifndef OPENSSL_NO_RSA
80 goto err; 80 goto err;
81 } 81 }
diff --git a/src/lib/libcrypto/evp/p_lib.c b/src/lib/libcrypto/evp/p_lib.c
index 22155ecf62..1916c61699 100644
--- a/src/lib/libcrypto/evp/p_lib.c
+++ b/src/lib/libcrypto/evp/p_lib.c
@@ -74,66 +74,26 @@
74#include <openssl/dh.h> 74#include <openssl/dh.h>
75#endif 75#endif
76 76
77#ifndef OPENSSL_NO_ENGINE
78#include <openssl/engine.h>
79#endif
80
81#include "asn1_locl.h"
82
77static void EVP_PKEY_free_it(EVP_PKEY *x); 83static void EVP_PKEY_free_it(EVP_PKEY *x);
78 84
79int EVP_PKEY_bits(EVP_PKEY *pkey) 85int EVP_PKEY_bits(EVP_PKEY *pkey)
80 { 86 {
81 if (0) 87 if (pkey && pkey->ameth && pkey->ameth->pkey_bits)
82 return 0; 88 return pkey->ameth->pkey_bits(pkey);
83#ifndef OPENSSL_NO_RSA 89 return 0;
84 else if (pkey->type == EVP_PKEY_RSA)
85 return(BN_num_bits(pkey->pkey.rsa->n));
86#endif
87#ifndef OPENSSL_NO_DSA
88 else if (pkey->type == EVP_PKEY_DSA)
89 return(BN_num_bits(pkey->pkey.dsa->p));
90#endif
91#ifndef OPENSSL_NO_EC
92 else if (pkey->type == EVP_PKEY_EC)
93 {
94 BIGNUM *order = BN_new();
95 const EC_GROUP *group;
96 int ret;
97
98 if (!order)
99 {
100 ERR_clear_error();
101 return 0;
102 }
103 group = EC_KEY_get0_group(pkey->pkey.ec);
104 if (!EC_GROUP_get_order(group, order, NULL))
105 {
106 ERR_clear_error();
107 return 0;
108 }
109
110 ret = BN_num_bits(order);
111 BN_free(order);
112 return ret;
113 }
114#endif
115 return(0);
116 } 90 }
117 91
118int EVP_PKEY_size(EVP_PKEY *pkey) 92int EVP_PKEY_size(EVP_PKEY *pkey)
119 { 93 {
120 if (pkey == NULL) 94 if (pkey && pkey->ameth && pkey->ameth->pkey_size)
121 return(0); 95 return pkey->ameth->pkey_size(pkey);
122#ifndef OPENSSL_NO_RSA 96 return 0;
123 if (pkey->type == EVP_PKEY_RSA)
124 return(RSA_size(pkey->pkey.rsa));
125 else
126#endif
127#ifndef OPENSSL_NO_DSA
128 if (pkey->type == EVP_PKEY_DSA)
129 return(DSA_size(pkey->pkey.dsa));
130#endif
131#ifndef OPENSSL_NO_ECDSA
132 if (pkey->type == EVP_PKEY_EC)
133 return(ECDSA_size(pkey->pkey.ec));
134#endif
135
136 return(0);
137 } 97 }
138 98
139int EVP_PKEY_save_parameters(EVP_PKEY *pkey, int mode) 99int EVP_PKEY_save_parameters(EVP_PKEY *pkey, int mode)
@@ -174,88 +134,26 @@ int EVP_PKEY_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from)
174 EVPerr(EVP_F_EVP_PKEY_COPY_PARAMETERS,EVP_R_MISSING_PARAMETERS); 134 EVPerr(EVP_F_EVP_PKEY_COPY_PARAMETERS,EVP_R_MISSING_PARAMETERS);
175 goto err; 135 goto err;
176 } 136 }
177#ifndef OPENSSL_NO_DSA 137 if (from->ameth && from->ameth->param_copy)
178 if (to->type == EVP_PKEY_DSA) 138 return from->ameth->param_copy(to, from);
179 {
180 BIGNUM *a;
181
182 if ((a=BN_dup(from->pkey.dsa->p)) == NULL) goto err;
183 if (to->pkey.dsa->p != NULL) BN_free(to->pkey.dsa->p);
184 to->pkey.dsa->p=a;
185
186 if ((a=BN_dup(from->pkey.dsa->q)) == NULL) goto err;
187 if (to->pkey.dsa->q != NULL) BN_free(to->pkey.dsa->q);
188 to->pkey.dsa->q=a;
189
190 if ((a=BN_dup(from->pkey.dsa->g)) == NULL) goto err;
191 if (to->pkey.dsa->g != NULL) BN_free(to->pkey.dsa->g);
192 to->pkey.dsa->g=a;
193 }
194#endif
195#ifndef OPENSSL_NO_EC
196 if (to->type == EVP_PKEY_EC)
197 {
198 EC_GROUP *group = EC_GROUP_dup(EC_KEY_get0_group(from->pkey.ec));
199 if (group == NULL)
200 goto err;
201 if (EC_KEY_set_group(to->pkey.ec, group) == 0)
202 goto err;
203 EC_GROUP_free(group);
204 }
205#endif
206 return(1);
207err: 139err:
208 return(0); 140 return 0;
209 } 141 }
210 142
211int EVP_PKEY_missing_parameters(const EVP_PKEY *pkey) 143int EVP_PKEY_missing_parameters(const EVP_PKEY *pkey)
212 { 144 {
213#ifndef OPENSSL_NO_DSA 145 if (pkey->ameth && pkey->ameth->param_missing)
214 if (pkey->type == EVP_PKEY_DSA) 146 return pkey->ameth->param_missing(pkey);
215 { 147 return 0;
216 DSA *dsa;
217
218 dsa=pkey->pkey.dsa;
219 if ((dsa->p == NULL) || (dsa->q == NULL) || (dsa->g == NULL))
220 return(1);
221 }
222#endif
223#ifndef OPENSSL_NO_EC
224 if (pkey->type == EVP_PKEY_EC)
225 {
226 if (EC_KEY_get0_group(pkey->pkey.ec) == NULL)
227 return(1);
228 }
229#endif
230
231 return(0);
232 } 148 }
233 149
234int EVP_PKEY_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b) 150int EVP_PKEY_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b)
235 { 151 {
236#ifndef OPENSSL_NO_DSA 152 if (a->type != b->type)
237 if ((a->type == EVP_PKEY_DSA) && (b->type == EVP_PKEY_DSA)) 153 return -1;
238 { 154 if (a->ameth && a->ameth->param_cmp)
239 if ( BN_cmp(a->pkey.dsa->p,b->pkey.dsa->p) || 155 return a->ameth->param_cmp(a, b);
240 BN_cmp(a->pkey.dsa->q,b->pkey.dsa->q) || 156 return -2;
241 BN_cmp(a->pkey.dsa->g,b->pkey.dsa->g))
242 return(0);
243 else
244 return(1);
245 }
246#endif
247#ifndef OPENSSL_NO_EC
248 if (a->type == EVP_PKEY_EC && b->type == EVP_PKEY_EC)
249 {
250 const EC_GROUP *group_a = EC_KEY_get0_group(a->pkey.ec),
251 *group_b = EC_KEY_get0_group(b->pkey.ec);
252 if (EC_GROUP_cmp(group_a, group_b, NULL))
253 return 0;
254 else
255 return 1;
256 }
257#endif
258 return(-1);
259 } 157 }
260 158
261int EVP_PKEY_cmp(const EVP_PKEY *a, const EVP_PKEY *b) 159int EVP_PKEY_cmp(const EVP_PKEY *a, const EVP_PKEY *b)
@@ -263,51 +161,22 @@ int EVP_PKEY_cmp(const EVP_PKEY *a, const EVP_PKEY *b)
263 if (a->type != b->type) 161 if (a->type != b->type)
264 return -1; 162 return -1;
265 163
266 if (EVP_PKEY_cmp_parameters(a, b) == 0) 164 if (a->ameth)
267 return 0;
268
269 switch (a->type)
270 { 165 {
271#ifndef OPENSSL_NO_RSA 166 int ret;
272 case EVP_PKEY_RSA: 167 /* Compare parameters if the algorithm has them */
273 if (BN_cmp(b->pkey.rsa->n,a->pkey.rsa->n) != 0 168 if (a->ameth->param_cmp)
274 || BN_cmp(b->pkey.rsa->e,a->pkey.rsa->e) != 0)
275 return 0;
276 break;
277#endif
278#ifndef OPENSSL_NO_DSA
279 case EVP_PKEY_DSA:
280 if (BN_cmp(b->pkey.dsa->pub_key,a->pkey.dsa->pub_key) != 0)
281 return 0;
282 break;
283#endif
284#ifndef OPENSSL_NO_EC
285 case EVP_PKEY_EC:
286 {
287 int r;
288 const EC_GROUP *group = EC_KEY_get0_group(b->pkey.ec);
289 const EC_POINT *pa = EC_KEY_get0_public_key(a->pkey.ec),
290 *pb = EC_KEY_get0_public_key(b->pkey.ec);
291 r = EC_POINT_cmp(group, pa, pb, NULL);
292 if (r != 0)
293 { 169 {
294 if (r == 1) 170 ret = a->ameth->param_cmp(a, b);
295 return 0; 171 if (ret <= 0)
296 else 172 return ret;
297 return -2;
298 } 173 }
299 } 174
300 break; 175 if (a->ameth->pub_cmp)
301#endif 176 return a->ameth->pub_cmp(a, b);
302#ifndef OPENSSL_NO_DH
303 case EVP_PKEY_DH:
304 return -2;
305#endif
306 default:
307 return -2;
308 } 177 }
309 178
310 return 1; 179 return -2;
311 } 180 }
312 181
313EVP_PKEY *EVP_PKEY_new(void) 182EVP_PKEY *EVP_PKEY_new(void)
@@ -321,22 +190,87 @@ EVP_PKEY *EVP_PKEY_new(void)
321 return(NULL); 190 return(NULL);
322 } 191 }
323 ret->type=EVP_PKEY_NONE; 192 ret->type=EVP_PKEY_NONE;
193 ret->save_type=EVP_PKEY_NONE;
324 ret->references=1; 194 ret->references=1;
195 ret->ameth=NULL;
196 ret->engine=NULL;
325 ret->pkey.ptr=NULL; 197 ret->pkey.ptr=NULL;
326 ret->attributes=NULL; 198 ret->attributes=NULL;
327 ret->save_parameters=1; 199 ret->save_parameters=1;
328 return(ret); 200 return(ret);
329 } 201 }
330 202
331int EVP_PKEY_assign(EVP_PKEY *pkey, int type, char *key) 203/* Setup a public key ASN1 method and ENGINE from a NID or a string.
204 * If pkey is NULL just return 1 or 0 if the algorithm exists.
205 */
206
207static int pkey_set_type(EVP_PKEY *pkey, int type, const char *str, int len)
332 { 208 {
333 if (pkey == NULL) return(0); 209 const EVP_PKEY_ASN1_METHOD *ameth;
334 if (pkey->pkey.ptr != NULL) 210 ENGINE *e = NULL;
335 EVP_PKEY_free_it(pkey); 211 if (pkey)
336 pkey->type=EVP_PKEY_type(type); 212 {
337 pkey->save_type=type; 213 if (pkey->pkey.ptr)
214 EVP_PKEY_free_it(pkey);
215 /* If key type matches and a method exists then this
216 * lookup has succeeded once so just indicate success.
217 */
218 if ((type == pkey->save_type) && pkey->ameth)
219 return 1;
220#ifndef OPENSSL_NO_ENGINE
221 /* If we have an ENGINE release it */
222 if (pkey->engine)
223 {
224 ENGINE_finish(pkey->engine);
225 pkey->engine = NULL;
226 }
227#endif
228 }
229 if (str)
230 ameth = EVP_PKEY_asn1_find_str(&e, str, len);
231 else
232 ameth = EVP_PKEY_asn1_find(&e, type);
233#ifndef OPENSSL_NO_ENGINE
234 if (!pkey && e)
235 ENGINE_finish(e);
236#endif
237 if (!ameth)
238 {
239 EVPerr(EVP_F_PKEY_SET_TYPE, EVP_R_UNSUPPORTED_ALGORITHM);
240 return 0;
241 }
242 if (pkey)
243 {
244 pkey->ameth = ameth;
245 pkey->engine = e;
246
247 pkey->type = pkey->ameth->pkey_id;
248 pkey->save_type=type;
249 }
250 return 1;
251 }
252
253int EVP_PKEY_set_type(EVP_PKEY *pkey, int type)
254 {
255 return pkey_set_type(pkey, type, NULL, -1);
256 }
257
258int EVP_PKEY_set_type_str(EVP_PKEY *pkey, const char *str, int len)
259 {
260 return pkey_set_type(pkey, EVP_PKEY_NONE, str, len);
261 }
262
263int EVP_PKEY_assign(EVP_PKEY *pkey, int type, void *key)
264 {
265 if (!EVP_PKEY_set_type(pkey, type))
266 return 0;
338 pkey->pkey.ptr=key; 267 pkey->pkey.ptr=key;
339 return(key != NULL); 268 return (key != NULL);
269 }
270
271void *EVP_PKEY_get0(EVP_PKEY *pkey)
272 {
273 return pkey->pkey.ptr;
340 } 274 }
341 275
342#ifndef OPENSSL_NO_RSA 276#ifndef OPENSSL_NO_RSA
@@ -425,24 +359,29 @@ DH *EVP_PKEY_get1_DH(EVP_PKEY *pkey)
425 359
426int EVP_PKEY_type(int type) 360int EVP_PKEY_type(int type)
427 { 361 {
428 switch (type) 362 int ret;
429 { 363 const EVP_PKEY_ASN1_METHOD *ameth;
430 case EVP_PKEY_RSA: 364 ENGINE *e;
431 case EVP_PKEY_RSA2: 365 ameth = EVP_PKEY_asn1_find(&e, type);
432 return(EVP_PKEY_RSA); 366 if (ameth)
433 case EVP_PKEY_DSA: 367 ret = ameth->pkey_id;
434 case EVP_PKEY_DSA1: 368 else
435 case EVP_PKEY_DSA2: 369 ret = NID_undef;
436 case EVP_PKEY_DSA3: 370#ifndef OPENSSL_NO_ENGINE
437 case EVP_PKEY_DSA4: 371 if (e)
438 return(EVP_PKEY_DSA); 372 ENGINE_finish(e);
439 case EVP_PKEY_DH: 373#endif
440 return(EVP_PKEY_DH); 374 return ret;
441 case EVP_PKEY_EC: 375 }
442 return(EVP_PKEY_EC); 376
443 default: 377int EVP_PKEY_id(const EVP_PKEY *pkey)
444 return(NID_undef); 378 {
445 } 379 return pkey->type;
380 }
381
382int EVP_PKEY_base_id(const EVP_PKEY *pkey)
383 {
384 return EVP_PKEY_type(pkey->type);
446 } 385 }
447 386
448void EVP_PKEY_free(EVP_PKEY *x) 387void EVP_PKEY_free(EVP_PKEY *x)
@@ -471,32 +410,57 @@ void EVP_PKEY_free(EVP_PKEY *x)
471 410
472static void EVP_PKEY_free_it(EVP_PKEY *x) 411static void EVP_PKEY_free_it(EVP_PKEY *x)
473 { 412 {
474 switch (x->type) 413 if (x->ameth && x->ameth->pkey_free)
414 x->ameth->pkey_free(x);
415#ifndef OPENSSL_NO_ENGINE
416 if (x->engine)
475 { 417 {
476#ifndef OPENSSL_NO_RSA 418 ENGINE_finish(x->engine);
477 case EVP_PKEY_RSA: 419 x->engine = NULL;
478 case EVP_PKEY_RSA2:
479 RSA_free(x->pkey.rsa);
480 break;
481#endif
482#ifndef OPENSSL_NO_DSA
483 case EVP_PKEY_DSA:
484 case EVP_PKEY_DSA2:
485 case EVP_PKEY_DSA3:
486 case EVP_PKEY_DSA4:
487 DSA_free(x->pkey.dsa);
488 break;
489#endif
490#ifndef OPENSSL_NO_EC
491 case EVP_PKEY_EC:
492 EC_KEY_free(x->pkey.ec);
493 break;
494#endif
495#ifndef OPENSSL_NO_DH
496 case EVP_PKEY_DH:
497 DH_free(x->pkey.dh);
498 break;
499#endif
500 } 420 }
421#endif
422 }
423
424static int unsup_alg(BIO *out, const EVP_PKEY *pkey, int indent,
425 const char *kstr)
426 {
427 BIO_indent(out, indent, 128);
428 BIO_printf(out, "%s algorithm \"%s\" unsupported\n",
429 kstr, OBJ_nid2ln(pkey->type));
430 return 1;
431 }
432
433int EVP_PKEY_print_public(BIO *out, const EVP_PKEY *pkey,
434 int indent, ASN1_PCTX *pctx)
435 {
436 if (pkey->ameth && pkey->ameth->pub_print)
437 return pkey->ameth->pub_print(out, pkey, indent, pctx);
438
439 return unsup_alg(out, pkey, indent, "Public Key");
440 }
441
442int EVP_PKEY_print_private(BIO *out, const EVP_PKEY *pkey,
443 int indent, ASN1_PCTX *pctx)
444 {
445 if (pkey->ameth && pkey->ameth->priv_print)
446 return pkey->ameth->priv_print(out, pkey, indent, pctx);
447
448 return unsup_alg(out, pkey, indent, "Private Key");
449 }
450
451int EVP_PKEY_print_params(BIO *out, const EVP_PKEY *pkey,
452 int indent, ASN1_PCTX *pctx)
453 {
454 if (pkey->ameth && pkey->ameth->param_print)
455 return pkey->ameth->param_print(out, pkey, indent, pctx);
456 return unsup_alg(out, pkey, indent, "Parameters");
457 }
458
459int EVP_PKEY_get_default_digest_nid(EVP_PKEY *pkey, int *pnid)
460 {
461 if (!pkey->ameth || !pkey->ameth->pkey_ctrl)
462 return -2;
463 return pkey->ameth->pkey_ctrl(pkey, ASN1_PKEY_CTRL_DEFAULT_MD_NID,
464 0, pnid);
501 } 465 }
502 466
diff --git a/src/lib/libcrypto/evp/p_open.c b/src/lib/libcrypto/evp/p_open.c
index 9935206d0f..53a59a295c 100644
--- a/src/lib/libcrypto/evp/p_open.c
+++ b/src/lib/libcrypto/evp/p_open.c
@@ -95,7 +95,7 @@ int EVP_OpenInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *type,
95 goto err; 95 goto err;
96 } 96 }
97 97
98 i=EVP_PKEY_decrypt(key,ek,ekl,priv); 98 i=EVP_PKEY_decrypt_old(key,ek,ekl,priv);
99 if ((i <= 0) || !EVP_CIPHER_CTX_set_key_length(ctx, i)) 99 if ((i <= 0) || !EVP_CIPHER_CTX_set_key_length(ctx, i))
100 { 100 {
101 /* ERROR */ 101 /* ERROR */
diff --git a/src/lib/libcrypto/evp/p_seal.c b/src/lib/libcrypto/evp/p_seal.c
index 8cc8fcb0bd..d8324526e7 100644
--- a/src/lib/libcrypto/evp/p_seal.c
+++ b/src/lib/libcrypto/evp/p_seal.c
@@ -87,7 +87,7 @@ int EVP_SealInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *type, unsigned char **ek
87 87
88 for (i=0; i<npubk; i++) 88 for (i=0; i<npubk; i++)
89 { 89 {
90 ekl[i]=EVP_PKEY_encrypt(ek[i],key,EVP_CIPHER_CTX_key_length(ctx), 90 ekl[i]=EVP_PKEY_encrypt_old(ek[i],key,EVP_CIPHER_CTX_key_length(ctx),
91 pubk[i]); 91 pubk[i]);
92 if (ekl[i] <= 0) return(-1); 92 if (ekl[i] <= 0) return(-1);
93 } 93 }
diff --git a/src/lib/libcrypto/evp/p_sign.c b/src/lib/libcrypto/evp/p_sign.c
index bf41a0db68..8df6d48a7e 100644
--- a/src/lib/libcrypto/evp/p_sign.c
+++ b/src/lib/libcrypto/evp/p_sign.c
@@ -84,6 +84,32 @@ int EVP_SignFinal(EVP_MD_CTX *ctx, unsigned char *sigret, unsigned int *siglen,
84 MS_STATIC EVP_MD_CTX tmp_ctx; 84 MS_STATIC EVP_MD_CTX tmp_ctx;
85 85
86 *siglen=0; 86 *siglen=0;
87 EVP_MD_CTX_init(&tmp_ctx);
88 EVP_MD_CTX_copy_ex(&tmp_ctx,ctx);
89 EVP_DigestFinal_ex(&tmp_ctx,&(m[0]),&m_len);
90 EVP_MD_CTX_cleanup(&tmp_ctx);
91
92 if (ctx->digest->flags & EVP_MD_FLAG_PKEY_METHOD_SIGNATURE)
93 {
94 EVP_PKEY_CTX *pkctx = NULL;
95 size_t sltmp = (size_t)EVP_PKEY_size(pkey);
96 i = 0;
97 pkctx = EVP_PKEY_CTX_new(pkey, NULL);
98 if (!pkctx)
99 goto err;
100 if (EVP_PKEY_sign_init(pkctx) <= 0)
101 goto err;
102 if (EVP_PKEY_CTX_set_signature_md(pkctx, ctx->digest) <= 0)
103 goto err;
104 if (EVP_PKEY_sign(pkctx, sigret, &sltmp, m, m_len) <= 0)
105 goto err;
106 *siglen = sltmp;
107 i = 1;
108 err:
109 EVP_PKEY_CTX_free(pkctx);
110 return i;
111 }
112
87 for (i=0; i<4; i++) 113 for (i=0; i<4; i++)
88 { 114 {
89 v=ctx->digest->required_pkey_type[i]; 115 v=ctx->digest->required_pkey_type[i];
@@ -99,28 +125,13 @@ int EVP_SignFinal(EVP_MD_CTX *ctx, unsigned char *sigret, unsigned int *siglen,
99 EVPerr(EVP_F_EVP_SIGNFINAL,EVP_R_WRONG_PUBLIC_KEY_TYPE); 125 EVPerr(EVP_F_EVP_SIGNFINAL,EVP_R_WRONG_PUBLIC_KEY_TYPE);
100 return(0); 126 return(0);
101 } 127 }
128
102 if (ctx->digest->sign == NULL) 129 if (ctx->digest->sign == NULL)
103 { 130 {
104 EVPerr(EVP_F_EVP_SIGNFINAL,EVP_R_NO_SIGN_FUNCTION_CONFIGURED); 131 EVPerr(EVP_F_EVP_SIGNFINAL,EVP_R_NO_SIGN_FUNCTION_CONFIGURED);
105 return(0); 132 return(0);
106 } 133 }
107 EVP_MD_CTX_init(&tmp_ctx); 134 return(ctx->digest->sign(ctx->digest->type,m,m_len,sigret,siglen,
108 EVP_MD_CTX_copy_ex(&tmp_ctx,ctx); 135 pkey->pkey.ptr));
109 if (ctx->digest->flags & EVP_MD_FLAG_SVCTX)
110 {
111 EVP_MD_SVCTX sctmp;
112 sctmp.mctx = &tmp_ctx;
113 sctmp.key = pkey->pkey.ptr;
114 i = ctx->digest->sign(ctx->digest->type,
115 NULL, -1, sigret, siglen, &sctmp);
116 }
117 else
118 {
119 EVP_DigestFinal_ex(&tmp_ctx,&(m[0]),&m_len);
120 i = ctx->digest->sign(ctx->digest->type,m,m_len,sigret,siglen,
121 pkey->pkey.ptr);
122 }
123 EVP_MD_CTX_cleanup(&tmp_ctx);
124 return i;
125 } 136 }
126 137
diff --git a/src/lib/libcrypto/evp/p_verify.c b/src/lib/libcrypto/evp/p_verify.c
index 2d46dffe7e..8db46412f3 100644
--- a/src/lib/libcrypto/evp/p_verify.c
+++ b/src/lib/libcrypto/evp/p_verify.c
@@ -70,6 +70,28 @@ int EVP_VerifyFinal(EVP_MD_CTX *ctx, const unsigned char *sigbuf,
70 int i,ok=0,v; 70 int i,ok=0,v;
71 MS_STATIC EVP_MD_CTX tmp_ctx; 71 MS_STATIC EVP_MD_CTX tmp_ctx;
72 72
73 EVP_MD_CTX_init(&tmp_ctx);
74 EVP_MD_CTX_copy_ex(&tmp_ctx,ctx);
75 EVP_DigestFinal_ex(&tmp_ctx,&(m[0]),&m_len);
76 EVP_MD_CTX_cleanup(&tmp_ctx);
77
78 if (ctx->digest->flags & EVP_MD_FLAG_PKEY_METHOD_SIGNATURE)
79 {
80 EVP_PKEY_CTX *pkctx = NULL;
81 i = -1;
82 pkctx = EVP_PKEY_CTX_new(pkey, NULL);
83 if (!pkctx)
84 goto err;
85 if (EVP_PKEY_verify_init(pkctx) <= 0)
86 goto err;
87 if (EVP_PKEY_CTX_set_signature_md(pkctx, ctx->digest) <= 0)
88 goto err;
89 i = EVP_PKEY_verify(pkctx, sigbuf, siglen, m, m_len);
90 err:
91 EVP_PKEY_CTX_free(pkctx);
92 return i;
93 }
94
73 for (i=0; i<4; i++) 95 for (i=0; i<4; i++)
74 { 96 {
75 v=ctx->digest->required_pkey_type[i]; 97 v=ctx->digest->required_pkey_type[i];
@@ -85,29 +107,13 @@ int EVP_VerifyFinal(EVP_MD_CTX *ctx, const unsigned char *sigbuf,
85 EVPerr(EVP_F_EVP_VERIFYFINAL,EVP_R_WRONG_PUBLIC_KEY_TYPE); 107 EVPerr(EVP_F_EVP_VERIFYFINAL,EVP_R_WRONG_PUBLIC_KEY_TYPE);
86 return(-1); 108 return(-1);
87 } 109 }
88 if (ctx->digest->verify == NULL) 110 if (ctx->digest->verify == NULL)
89 { 111 {
90 EVPerr(EVP_F_EVP_VERIFYFINAL,EVP_R_NO_VERIFY_FUNCTION_CONFIGURED); 112 EVPerr(EVP_F_EVP_VERIFYFINAL,EVP_R_NO_VERIFY_FUNCTION_CONFIGURED);
91 return(0); 113 return(0);
92 } 114 }
93 115
94 EVP_MD_CTX_init(&tmp_ctx); 116 return(ctx->digest->verify(ctx->digest->type,m,m_len,
95 EVP_MD_CTX_copy_ex(&tmp_ctx,ctx); 117 sigbuf,siglen,pkey->pkey.ptr));
96 if (ctx->digest->flags & EVP_MD_FLAG_SVCTX)
97 {
98 EVP_MD_SVCTX sctmp;
99 sctmp.mctx = &tmp_ctx;
100 sctmp.key = pkey->pkey.ptr;
101 i = ctx->digest->verify(ctx->digest->type,
102 NULL, -1, sigbuf, siglen, &sctmp);
103 }
104 else
105 {
106 EVP_DigestFinal_ex(&tmp_ctx,&(m[0]),&m_len);
107 i = ctx->digest->verify(ctx->digest->type,m,m_len,
108 sigbuf,siglen,pkey->pkey.ptr);
109 }
110 EVP_MD_CTX_cleanup(&tmp_ctx);
111 return i;
112 } 118 }
113 119
diff --git a/src/lib/libcrypto/evp/pmeth_fn.c b/src/lib/libcrypto/evp/pmeth_fn.c
new file mode 100644
index 0000000000..c4676f2f8d
--- /dev/null
+++ b/src/lib/libcrypto/evp/pmeth_fn.c
@@ -0,0 +1,368 @@
1/* pmeth_fn.c */
2/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
3 * project 2006.
4 */
5/* ====================================================================
6 * Copyright (c) 2006 The OpenSSL Project. All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 *
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 *
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in
17 * the documentation and/or other materials provided with the
18 * distribution.
19 *
20 * 3. All advertising materials mentioning features or use of this
21 * software must display the following acknowledgment:
22 * "This product includes software developed by the OpenSSL Project
23 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
24 *
25 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
26 * endorse or promote products derived from this software without
27 * prior written permission. For written permission, please contact
28 * licensing@OpenSSL.org.
29 *
30 * 5. Products derived from this software may not be called "OpenSSL"
31 * nor may "OpenSSL" appear in their names without prior written
32 * permission of the OpenSSL Project.
33 *
34 * 6. Redistributions of any form whatsoever must retain the following
35 * acknowledgment:
36 * "This product includes software developed by the OpenSSL Project
37 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
38 *
39 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
40 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
43 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
50 * OF THE POSSIBILITY OF SUCH DAMAGE.
51 * ====================================================================
52 *
53 * This product includes cryptographic software written by Eric Young
54 * (eay@cryptsoft.com). This product includes software written by Tim
55 * Hudson (tjh@cryptsoft.com).
56 *
57 */
58
59#include <stdio.h>
60#include <stdlib.h>
61#include "cryptlib.h"
62#include <openssl/objects.h>
63#include <openssl/evp.h>
64#include "evp_locl.h"
65
66#define M_check_autoarg(ctx, arg, arglen, err) \
67 if (ctx->pmeth->flags & EVP_PKEY_FLAG_AUTOARGLEN) \
68 { \
69 size_t pksize = (size_t)EVP_PKEY_size(ctx->pkey); \
70 if (!arg) \
71 { \
72 *arglen = pksize; \
73 return 1; \
74 } \
75 else if (*arglen < pksize) \
76 { \
77 EVPerr(err, EVP_R_BUFFER_TOO_SMALL); /*ckerr_ignore*/\
78 return 0; \
79 } \
80 }
81
82int EVP_PKEY_sign_init(EVP_PKEY_CTX *ctx)
83 {
84 int ret;
85 if (!ctx || !ctx->pmeth || !ctx->pmeth->sign)
86 {
87 EVPerr(EVP_F_EVP_PKEY_SIGN_INIT,
88 EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
89 return -2;
90 }
91 ctx->operation = EVP_PKEY_OP_SIGN;
92 if (!ctx->pmeth->sign_init)
93 return 1;
94 ret = ctx->pmeth->sign_init(ctx);
95 if (ret <= 0)
96 ctx->operation = EVP_PKEY_OP_UNDEFINED;
97 return ret;
98 }
99
100int EVP_PKEY_sign(EVP_PKEY_CTX *ctx,
101 unsigned char *sig, size_t *siglen,
102 const unsigned char *tbs, size_t tbslen)
103 {
104 if (!ctx || !ctx->pmeth || !ctx->pmeth->sign)
105 {
106 EVPerr(EVP_F_EVP_PKEY_SIGN,
107 EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
108 return -2;
109 }
110 if (ctx->operation != EVP_PKEY_OP_SIGN)
111 {
112 EVPerr(EVP_F_EVP_PKEY_SIGN, EVP_R_OPERATON_NOT_INITIALIZED);
113 return -1;
114 }
115 M_check_autoarg(ctx, sig, siglen, EVP_F_EVP_PKEY_SIGN)
116 return ctx->pmeth->sign(ctx, sig, siglen, tbs, tbslen);
117 }
118
119int EVP_PKEY_verify_init(EVP_PKEY_CTX *ctx)
120 {
121 int ret;
122 if (!ctx || !ctx->pmeth || !ctx->pmeth->verify)
123 {
124 EVPerr(EVP_F_EVP_PKEY_VERIFY_INIT,
125 EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
126 return -2;
127 }
128 ctx->operation = EVP_PKEY_OP_VERIFY;
129 if (!ctx->pmeth->verify_init)
130 return 1;
131 ret = ctx->pmeth->verify_init(ctx);
132 if (ret <= 0)
133 ctx->operation = EVP_PKEY_OP_UNDEFINED;
134 return ret;
135 }
136
137int EVP_PKEY_verify(EVP_PKEY_CTX *ctx,
138 const unsigned char *sig, size_t siglen,
139 const unsigned char *tbs, size_t tbslen)
140 {
141 if (!ctx || !ctx->pmeth || !ctx->pmeth->verify)
142 {
143 EVPerr(EVP_F_EVP_PKEY_VERIFY,
144 EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
145 return -2;
146 }
147 if (ctx->operation != EVP_PKEY_OP_VERIFY)
148 {
149 EVPerr(EVP_F_EVP_PKEY_VERIFY, EVP_R_OPERATON_NOT_INITIALIZED);
150 return -1;
151 }
152 return ctx->pmeth->verify(ctx, sig, siglen, tbs, tbslen);
153 }
154
155int EVP_PKEY_verify_recover_init(EVP_PKEY_CTX *ctx)
156 {
157 int ret;
158 if (!ctx || !ctx->pmeth || !ctx->pmeth->verify_recover)
159 {
160 EVPerr(EVP_F_EVP_PKEY_VERIFY_RECOVER_INIT,
161 EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
162 return -2;
163 }
164 ctx->operation = EVP_PKEY_OP_VERIFYRECOVER;
165 if (!ctx->pmeth->verify_recover_init)
166 return 1;
167 ret = ctx->pmeth->verify_recover_init(ctx);
168 if (ret <= 0)
169 ctx->operation = EVP_PKEY_OP_UNDEFINED;
170 return ret;
171 }
172
173int EVP_PKEY_verify_recover(EVP_PKEY_CTX *ctx,
174 unsigned char *rout, size_t *routlen,
175 const unsigned char *sig, size_t siglen)
176 {
177 if (!ctx || !ctx->pmeth || !ctx->pmeth->verify_recover)
178 {
179 EVPerr(EVP_F_EVP_PKEY_VERIFY_RECOVER,
180 EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
181 return -2;
182 }
183 if (ctx->operation != EVP_PKEY_OP_VERIFYRECOVER)
184 {
185 EVPerr(EVP_F_EVP_PKEY_VERIFY_RECOVER, EVP_R_OPERATON_NOT_INITIALIZED);
186 return -1;
187 }
188 M_check_autoarg(ctx, rout, routlen, EVP_F_EVP_PKEY_VERIFY_RECOVER)
189 return ctx->pmeth->verify_recover(ctx, rout, routlen, sig, siglen);
190 }
191
192int EVP_PKEY_encrypt_init(EVP_PKEY_CTX *ctx)
193 {
194 int ret;
195 if (!ctx || !ctx->pmeth || !ctx->pmeth->encrypt)
196 {
197 EVPerr(EVP_F_EVP_PKEY_ENCRYPT_INIT,
198 EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
199 return -2;
200 }
201 ctx->operation = EVP_PKEY_OP_ENCRYPT;
202 if (!ctx->pmeth->encrypt_init)
203 return 1;
204 ret = ctx->pmeth->encrypt_init(ctx);
205 if (ret <= 0)
206 ctx->operation = EVP_PKEY_OP_UNDEFINED;
207 return ret;
208 }
209
210int EVP_PKEY_encrypt(EVP_PKEY_CTX *ctx,
211 unsigned char *out, size_t *outlen,
212 const unsigned char *in, size_t inlen)
213 {
214 if (!ctx || !ctx->pmeth || !ctx->pmeth->encrypt)
215 {
216 EVPerr(EVP_F_EVP_PKEY_ENCRYPT,
217 EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
218 return -2;
219 }
220 if (ctx->operation != EVP_PKEY_OP_ENCRYPT)
221 {
222 EVPerr(EVP_F_EVP_PKEY_ENCRYPT, EVP_R_OPERATON_NOT_INITIALIZED);
223 return -1;
224 }
225 M_check_autoarg(ctx, out, outlen, EVP_F_EVP_PKEY_ENCRYPT)
226 return ctx->pmeth->encrypt(ctx, out, outlen, in, inlen);
227 }
228
229int EVP_PKEY_decrypt_init(EVP_PKEY_CTX *ctx)
230 {
231 int ret;
232 if (!ctx || !ctx->pmeth || !ctx->pmeth->decrypt)
233 {
234 EVPerr(EVP_F_EVP_PKEY_DECRYPT_INIT,
235 EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
236 return -2;
237 }
238 ctx->operation = EVP_PKEY_OP_DECRYPT;
239 if (!ctx->pmeth->decrypt_init)
240 return 1;
241 ret = ctx->pmeth->decrypt_init(ctx);
242 if (ret <= 0)
243 ctx->operation = EVP_PKEY_OP_UNDEFINED;
244 return ret;
245 }
246
247int EVP_PKEY_decrypt(EVP_PKEY_CTX *ctx,
248 unsigned char *out, size_t *outlen,
249 const unsigned char *in, size_t inlen)
250 {
251 if (!ctx || !ctx->pmeth || !ctx->pmeth->decrypt)
252 {
253 EVPerr(EVP_F_EVP_PKEY_DECRYPT,
254 EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
255 return -2;
256 }
257 if (ctx->operation != EVP_PKEY_OP_DECRYPT)
258 {
259 EVPerr(EVP_F_EVP_PKEY_DECRYPT, EVP_R_OPERATON_NOT_INITIALIZED);
260 return -1;
261 }
262 M_check_autoarg(ctx, out, outlen, EVP_F_EVP_PKEY_DECRYPT)
263 return ctx->pmeth->decrypt(ctx, out, outlen, in, inlen);
264 }
265
266
267int EVP_PKEY_derive_init(EVP_PKEY_CTX *ctx)
268 {
269 int ret;
270 if (!ctx || !ctx->pmeth || !ctx->pmeth->derive)
271 {
272 EVPerr(EVP_F_EVP_PKEY_DERIVE_INIT,
273 EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
274 return -2;
275 }
276 ctx->operation = EVP_PKEY_OP_DERIVE;
277 if (!ctx->pmeth->derive_init)
278 return 1;
279 ret = ctx->pmeth->derive_init(ctx);
280 if (ret <= 0)
281 ctx->operation = EVP_PKEY_OP_UNDEFINED;
282 return ret;
283 }
284
285int EVP_PKEY_derive_set_peer(EVP_PKEY_CTX *ctx, EVP_PKEY *peer)
286 {
287 int ret;
288 if (!ctx || !ctx->pmeth || !(ctx->pmeth->derive||ctx->pmeth->encrypt||ctx->pmeth->decrypt) || !ctx->pmeth->ctrl)
289 {
290 EVPerr(EVP_F_EVP_PKEY_DERIVE_SET_PEER,
291 EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
292 return -2;
293 }
294 if (ctx->operation != EVP_PKEY_OP_DERIVE && ctx->operation != EVP_PKEY_OP_ENCRYPT && ctx->operation != EVP_PKEY_OP_DECRYPT)
295 {
296 EVPerr(EVP_F_EVP_PKEY_DERIVE_SET_PEER,
297 EVP_R_OPERATON_NOT_INITIALIZED);
298 return -1;
299 }
300
301 ret = ctx->pmeth->ctrl(ctx, EVP_PKEY_CTRL_PEER_KEY, 0, peer);
302
303 if (ret <= 0)
304 return ret;
305
306 if (ret == 2)
307 return 1;
308
309 if (!ctx->pkey)
310 {
311 EVPerr(EVP_F_EVP_PKEY_DERIVE_SET_PEER, EVP_R_NO_KEY_SET);
312 return -1;
313 }
314
315 if (ctx->pkey->type != peer->type)
316 {
317 EVPerr(EVP_F_EVP_PKEY_DERIVE_SET_PEER,
318 EVP_R_DIFFERENT_KEY_TYPES);
319 return -1;
320 }
321
322 /* ran@cryptocom.ru: For clarity. The error is if parameters in peer are
323 * present (!missing) but don't match. EVP_PKEY_cmp_parameters may return
324 * 1 (match), 0 (don't match) and -2 (comparison is not defined). -1
325 * (different key types) is impossible here because it is checked earlier.
326 * -2 is OK for us here, as well as 1, so we can check for 0 only. */
327 if (!EVP_PKEY_missing_parameters(peer) &&
328 !EVP_PKEY_cmp_parameters(ctx->pkey, peer))
329 {
330 EVPerr(EVP_F_EVP_PKEY_DERIVE_SET_PEER,
331 EVP_R_DIFFERENT_PARAMETERS);
332 return -1;
333 }
334
335 if (ctx->peerkey)
336 EVP_PKEY_free(ctx->peerkey);
337 ctx->peerkey = peer;
338
339 ret = ctx->pmeth->ctrl(ctx, EVP_PKEY_CTRL_PEER_KEY, 1, peer);
340
341 if (ret <= 0)
342 {
343 ctx->peerkey = NULL;
344 return ret;
345 }
346
347 CRYPTO_add(&peer->references,1,CRYPTO_LOCK_EVP_PKEY);
348 return 1;
349 }
350
351
352int EVP_PKEY_derive(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *pkeylen)
353 {
354 if (!ctx || !ctx->pmeth || !ctx->pmeth->derive)
355 {
356 EVPerr(EVP_F_EVP_PKEY_DERIVE,
357 EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
358 return -2;
359 }
360 if (ctx->operation != EVP_PKEY_OP_DERIVE)
361 {
362 EVPerr(EVP_F_EVP_PKEY_DERIVE, EVP_R_OPERATON_NOT_INITIALIZED);
363 return -1;
364 }
365 M_check_autoarg(ctx, key, pkeylen, EVP_F_EVP_PKEY_DERIVE)
366 return ctx->pmeth->derive(ctx, key, pkeylen);
367 }
368
diff --git a/src/lib/libcrypto/evp/pmeth_gn.c b/src/lib/libcrypto/evp/pmeth_gn.c
new file mode 100644
index 0000000000..5d74161a09
--- /dev/null
+++ b/src/lib/libcrypto/evp/pmeth_gn.c
@@ -0,0 +1,220 @@
1/* pmeth_gn.c */
2/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
3 * project 2006.
4 */
5/* ====================================================================
6 * Copyright (c) 2006 The OpenSSL Project. All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 *
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 *
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in
17 * the documentation and/or other materials provided with the
18 * distribution.
19 *
20 * 3. All advertising materials mentioning features or use of this
21 * software must display the following acknowledgment:
22 * "This product includes software developed by the OpenSSL Project
23 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
24 *
25 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
26 * endorse or promote products derived from this software without
27 * prior written permission. For written permission, please contact
28 * licensing@OpenSSL.org.
29 *
30 * 5. Products derived from this software may not be called "OpenSSL"
31 * nor may "OpenSSL" appear in their names without prior written
32 * permission of the OpenSSL Project.
33 *
34 * 6. Redistributions of any form whatsoever must retain the following
35 * acknowledgment:
36 * "This product includes software developed by the OpenSSL Project
37 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
38 *
39 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
40 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
43 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
50 * OF THE POSSIBILITY OF SUCH DAMAGE.
51 * ====================================================================
52 *
53 * This product includes cryptographic software written by Eric Young
54 * (eay@cryptsoft.com). This product includes software written by Tim
55 * Hudson (tjh@cryptsoft.com).
56 *
57 */
58
59#include <stdio.h>
60#include <stdlib.h>
61#include "cryptlib.h"
62#include <openssl/objects.h>
63#include <openssl/evp.h>
64#include <openssl/bn.h>
65#include "evp_locl.h"
66
67int EVP_PKEY_paramgen_init(EVP_PKEY_CTX *ctx)
68 {
69 int ret;
70 if (!ctx || !ctx->pmeth || !ctx->pmeth->paramgen)
71 {
72 EVPerr(EVP_F_EVP_PKEY_PARAMGEN_INIT,
73 EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
74 return -2;
75 }
76 ctx->operation = EVP_PKEY_OP_PARAMGEN;
77 if (!ctx->pmeth->paramgen_init)
78 return 1;
79 ret = ctx->pmeth->paramgen_init(ctx);
80 if (ret <= 0)
81 ctx->operation = EVP_PKEY_OP_UNDEFINED;
82 return ret;
83 }
84
85int EVP_PKEY_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey)
86 {
87 int ret;
88 if (!ctx || !ctx->pmeth || !ctx->pmeth->paramgen)
89 {
90 EVPerr(EVP_F_EVP_PKEY_PARAMGEN,
91 EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
92 return -2;
93 }
94
95 if (ctx->operation != EVP_PKEY_OP_PARAMGEN)
96 {
97 EVPerr(EVP_F_EVP_PKEY_PARAMGEN, EVP_R_OPERATON_NOT_INITIALIZED);
98 return -1;
99 }
100
101 if (!ppkey)
102 return -1;
103
104 if (!*ppkey)
105 *ppkey = EVP_PKEY_new();
106
107 ret = ctx->pmeth->paramgen(ctx, *ppkey);
108 if (ret <= 0)
109 {
110 EVP_PKEY_free(*ppkey);
111 *ppkey = NULL;
112 }
113 return ret;
114 }
115
116int EVP_PKEY_keygen_init(EVP_PKEY_CTX *ctx)
117 {
118 int ret;
119 if (!ctx || !ctx->pmeth || !ctx->pmeth->keygen)
120 {
121 EVPerr(EVP_F_EVP_PKEY_KEYGEN_INIT,
122 EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
123 return -2;
124 }
125 ctx->operation = EVP_PKEY_OP_KEYGEN;
126 if (!ctx->pmeth->keygen_init)
127 return 1;
128 ret = ctx->pmeth->keygen_init(ctx);
129 if (ret <= 0)
130 ctx->operation = EVP_PKEY_OP_UNDEFINED;
131 return ret;
132 }
133
134int EVP_PKEY_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey)
135 {
136 int ret;
137
138 if (!ctx || !ctx->pmeth || !ctx->pmeth->keygen)
139 {
140 EVPerr(EVP_F_EVP_PKEY_KEYGEN,
141 EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
142 return -2;
143 }
144 if (ctx->operation != EVP_PKEY_OP_KEYGEN)
145 {
146 EVPerr(EVP_F_EVP_PKEY_KEYGEN, EVP_R_OPERATON_NOT_INITIALIZED);
147 return -1;
148 }
149
150 if (!ppkey)
151 return -1;
152
153 if (!*ppkey)
154 *ppkey = EVP_PKEY_new();
155
156 ret = ctx->pmeth->keygen(ctx, *ppkey);
157 if (ret <= 0)
158 {
159 EVP_PKEY_free(*ppkey);
160 *ppkey = NULL;
161 }
162 return ret;
163 }
164
165void EVP_PKEY_CTX_set_cb(EVP_PKEY_CTX *ctx, EVP_PKEY_gen_cb *cb)
166 {
167 ctx->pkey_gencb = cb;
168 }
169
170EVP_PKEY_gen_cb *EVP_PKEY_CTX_get_cb(EVP_PKEY_CTX *ctx)
171 {
172 return ctx->pkey_gencb;
173 }
174
175/* "translation callback" to call EVP_PKEY_CTX callbacks using BN_GENCB
176 * style callbacks.
177 */
178
179static int trans_cb(int a, int b, BN_GENCB *gcb)
180 {
181 EVP_PKEY_CTX *ctx = gcb->arg;
182 ctx->keygen_info[0] = a;
183 ctx->keygen_info[1] = b;
184 return ctx->pkey_gencb(ctx);
185 }
186
187void evp_pkey_set_cb_translate(BN_GENCB *cb, EVP_PKEY_CTX *ctx)
188 {
189 BN_GENCB_set(cb, trans_cb, ctx)
190 }
191
192int EVP_PKEY_CTX_get_keygen_info(EVP_PKEY_CTX *ctx, int idx)
193 {
194 if (idx == -1)
195 return ctx->keygen_info_count;
196 if (idx < 0 || idx > ctx->keygen_info_count)
197 return 0;
198 return ctx->keygen_info[idx];
199 }
200
201EVP_PKEY *EVP_PKEY_new_mac_key(int type, ENGINE *e,
202 unsigned char *key, int keylen)
203 {
204 EVP_PKEY_CTX *mac_ctx = NULL;
205 EVP_PKEY *mac_key = NULL;
206 mac_ctx = EVP_PKEY_CTX_new_id(type, e);
207 if (!mac_ctx)
208 return NULL;
209 if (EVP_PKEY_keygen_init(mac_ctx) <= 0)
210 goto merr;
211 if (EVP_PKEY_CTX_ctrl(mac_ctx, -1, EVP_PKEY_OP_KEYGEN,
212 EVP_PKEY_CTRL_SET_MAC_KEY, keylen, key) <= 0)
213 goto merr;
214 if (EVP_PKEY_keygen(mac_ctx, &mac_key) <= 0)
215 goto merr;
216 merr:
217 if (mac_ctx)
218 EVP_PKEY_CTX_free(mac_ctx);
219 return mac_key;
220 }
diff --git a/src/lib/libcrypto/evp/pmeth_lib.c b/src/lib/libcrypto/evp/pmeth_lib.c
new file mode 100644
index 0000000000..b2d8de3a8d
--- /dev/null
+++ b/src/lib/libcrypto/evp/pmeth_lib.c
@@ -0,0 +1,538 @@
1/* pmeth_lib.c */
2/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
3 * project 2006.
4 */
5/* ====================================================================
6 * Copyright (c) 2006 The OpenSSL Project. All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 *
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 *
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in
17 * the documentation and/or other materials provided with the
18 * distribution.
19 *
20 * 3. All advertising materials mentioning features or use of this
21 * software must display the following acknowledgment:
22 * "This product includes software developed by the OpenSSL Project
23 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
24 *
25 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
26 * endorse or promote products derived from this software without
27 * prior written permission. For written permission, please contact
28 * licensing@OpenSSL.org.
29 *
30 * 5. Products derived from this software may not be called "OpenSSL"
31 * nor may "OpenSSL" appear in their names without prior written
32 * permission of the OpenSSL Project.
33 *
34 * 6. Redistributions of any form whatsoever must retain the following
35 * acknowledgment:
36 * "This product includes software developed by the OpenSSL Project
37 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
38 *
39 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
40 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
43 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
50 * OF THE POSSIBILITY OF SUCH DAMAGE.
51 * ====================================================================
52 *
53 * This product includes cryptographic software written by Eric Young
54 * (eay@cryptsoft.com). This product includes software written by Tim
55 * Hudson (tjh@cryptsoft.com).
56 *
57 */
58
59#include <stdio.h>
60#include <stdlib.h>
61#include "cryptlib.h"
62#include <openssl/objects.h>
63#include <openssl/evp.h>
64#ifndef OPENSSL_NO_ENGINE
65#include <openssl/engine.h>
66#endif
67#include "asn1_locl.h"
68#include "evp_locl.h"
69
70typedef int sk_cmp_fn_type(const char * const *a, const char * const *b);
71
72DECLARE_STACK_OF(EVP_PKEY_METHOD)
73STACK_OF(EVP_PKEY_METHOD) *app_pkey_methods = NULL;
74
75extern const EVP_PKEY_METHOD rsa_pkey_meth, dh_pkey_meth, dsa_pkey_meth;
76extern const EVP_PKEY_METHOD ec_pkey_meth, hmac_pkey_meth;
77
78static const EVP_PKEY_METHOD *standard_methods[] =
79 {
80#ifndef OPENSSL_NO_RSA
81 &rsa_pkey_meth,
82#endif
83#ifndef OPENSSL_NO_DH
84 &dh_pkey_meth,
85#endif
86#ifndef OPENSSL_NO_DSA
87 &dsa_pkey_meth,
88#endif
89#ifndef OPENSSL_NO_EC
90 &ec_pkey_meth,
91#endif
92 &hmac_pkey_meth,
93 };
94
95DECLARE_OBJ_BSEARCH_CMP_FN(const EVP_PKEY_METHOD *, const EVP_PKEY_METHOD *,
96 pmeth);
97
98static int pmeth_cmp(const EVP_PKEY_METHOD * const *a,
99 const EVP_PKEY_METHOD * const *b)
100 {
101 return ((*a)->pkey_id - (*b)->pkey_id);
102 }
103
104IMPLEMENT_OBJ_BSEARCH_CMP_FN(const EVP_PKEY_METHOD *, const EVP_PKEY_METHOD *,
105 pmeth);
106
107const EVP_PKEY_METHOD *EVP_PKEY_meth_find(int type)
108 {
109 EVP_PKEY_METHOD tmp;
110 const EVP_PKEY_METHOD *t = &tmp, **ret;
111 tmp.pkey_id = type;
112 if (app_pkey_methods)
113 {
114 int idx;
115 idx = sk_EVP_PKEY_METHOD_find(app_pkey_methods, &tmp);
116 if (idx >= 0)
117 return sk_EVP_PKEY_METHOD_value(app_pkey_methods, idx);
118 }
119 ret = OBJ_bsearch_pmeth(&t, standard_methods,
120 sizeof(standard_methods)/sizeof(EVP_PKEY_METHOD *));
121 if (!ret || !*ret)
122 return NULL;
123 return *ret;
124 }
125
126static EVP_PKEY_CTX *int_ctx_new(EVP_PKEY *pkey, ENGINE *e, int id)
127 {
128 EVP_PKEY_CTX *ret;
129 const EVP_PKEY_METHOD *pmeth;
130 if (id == -1)
131 {
132 if (!pkey || !pkey->ameth)
133 return NULL;
134 id = pkey->ameth->pkey_id;
135 }
136#ifndef OPENSSL_NO_ENGINE
137 /* Try to find an ENGINE which implements this method */
138 if (e)
139 {
140 if (!ENGINE_init(e))
141 {
142 EVPerr(EVP_F_INT_CTX_NEW,ERR_R_ENGINE_LIB);
143 return NULL;
144 }
145 }
146 else
147 e = ENGINE_get_pkey_meth_engine(id);
148
149 /* If an ENGINE handled this method look it up. Othewise
150 * use internal tables.
151 */
152
153 if (e)
154 pmeth = ENGINE_get_pkey_meth(e, id);
155 else
156#endif
157 pmeth = EVP_PKEY_meth_find(id);
158
159 if (pmeth == NULL)
160 {
161 EVPerr(EVP_F_INT_CTX_NEW,EVP_R_UNSUPPORTED_ALGORITHM);
162 return NULL;
163 }
164
165 ret = OPENSSL_malloc(sizeof(EVP_PKEY_CTX));
166 if (!ret)
167 {
168#ifndef OPENSSL_NO_ENGINE
169 if (e)
170 ENGINE_finish(e);
171#endif
172 EVPerr(EVP_F_INT_CTX_NEW,ERR_R_MALLOC_FAILURE);
173 return NULL;
174 }
175 ret->engine = e;
176 ret->pmeth = pmeth;
177 ret->operation = EVP_PKEY_OP_UNDEFINED;
178 ret->pkey = pkey;
179 ret->peerkey = NULL;
180 ret->pkey_gencb = 0;
181 if (pkey)
182 CRYPTO_add(&pkey->references,1,CRYPTO_LOCK_EVP_PKEY);
183 ret->data = NULL;
184
185 if (pmeth->init)
186 {
187 if (pmeth->init(ret) <= 0)
188 {
189 EVP_PKEY_CTX_free(ret);
190 return NULL;
191 }
192 }
193
194 return ret;
195 }
196
197EVP_PKEY_METHOD* EVP_PKEY_meth_new(int id, int flags)
198 {
199 EVP_PKEY_METHOD *pmeth;
200 pmeth = OPENSSL_malloc(sizeof(EVP_PKEY_METHOD));
201 if (!pmeth)
202 return NULL;
203
204 pmeth->pkey_id = id;
205 pmeth->flags = flags | EVP_PKEY_FLAG_DYNAMIC;
206
207 pmeth->init = 0;
208 pmeth->copy = 0;
209 pmeth->cleanup = 0;
210 pmeth->paramgen_init = 0;
211 pmeth->paramgen = 0;
212 pmeth->keygen_init = 0;
213 pmeth->keygen = 0;
214 pmeth->sign_init = 0;
215 pmeth->sign = 0;
216 pmeth->verify_init = 0;
217 pmeth->verify = 0;
218 pmeth->verify_recover_init = 0;
219 pmeth->verify_recover = 0;
220 pmeth->signctx_init = 0;
221 pmeth->signctx = 0;
222 pmeth->verifyctx_init = 0;
223 pmeth->verifyctx = 0;
224 pmeth->encrypt_init = 0;
225 pmeth->encrypt = 0;
226 pmeth->decrypt_init = 0;
227 pmeth->decrypt = 0;
228 pmeth->derive_init = 0;
229 pmeth->derive = 0;
230 pmeth->ctrl = 0;
231 pmeth->ctrl_str = 0;
232
233 return pmeth;
234 }
235
236void EVP_PKEY_meth_free(EVP_PKEY_METHOD *pmeth)
237 {
238 if (pmeth && (pmeth->flags & EVP_PKEY_FLAG_DYNAMIC))
239 OPENSSL_free(pmeth);
240 }
241
242EVP_PKEY_CTX *EVP_PKEY_CTX_new(EVP_PKEY *pkey, ENGINE *e)
243 {
244 return int_ctx_new(pkey, e, -1);
245 }
246
247EVP_PKEY_CTX *EVP_PKEY_CTX_new_id(int id, ENGINE *e)
248 {
249 return int_ctx_new(NULL, e, id);
250 }
251
252EVP_PKEY_CTX *EVP_PKEY_CTX_dup(EVP_PKEY_CTX *pctx)
253 {
254 EVP_PKEY_CTX *rctx;
255 if (!pctx->pmeth || !pctx->pmeth->copy)
256 return NULL;
257#ifndef OPENSSL_NO_ENGINE
258 /* Make sure it's safe to copy a pkey context using an ENGINE */
259 if (pctx->engine && !ENGINE_init(pctx->engine))
260 {
261 EVPerr(EVP_F_EVP_PKEY_CTX_DUP,ERR_R_ENGINE_LIB);
262 return 0;
263 }
264#endif
265 rctx = OPENSSL_malloc(sizeof(EVP_PKEY_CTX));
266 if (!rctx)
267 return NULL;
268
269 rctx->pmeth = pctx->pmeth;
270#ifndef OPENSSL_NO_ENGINE
271 rctx->engine = pctx->engine;
272#endif
273
274 if (pctx->pkey)
275 CRYPTO_add(&pctx->pkey->references,1,CRYPTO_LOCK_EVP_PKEY);
276
277 rctx->pkey = pctx->pkey;
278
279 if (pctx->peerkey)
280 CRYPTO_add(&pctx->peerkey->references,1,CRYPTO_LOCK_EVP_PKEY);
281
282 rctx->peerkey = pctx->peerkey;
283
284 rctx->data = NULL;
285 rctx->app_data = NULL;
286 rctx->operation = pctx->operation;
287
288 if (pctx->pmeth->copy(rctx, pctx) > 0)
289 return rctx;
290
291 EVP_PKEY_CTX_free(rctx);
292 return NULL;
293
294 }
295
296int EVP_PKEY_meth_add0(const EVP_PKEY_METHOD *pmeth)
297 {
298 if (app_pkey_methods == NULL)
299 {
300 app_pkey_methods = sk_EVP_PKEY_METHOD_new(pmeth_cmp);
301 if (!app_pkey_methods)
302 return 0;
303 }
304 if (!sk_EVP_PKEY_METHOD_push(app_pkey_methods, pmeth))
305 return 0;
306 sk_EVP_PKEY_METHOD_sort(app_pkey_methods);
307 return 1;
308 }
309
310void EVP_PKEY_CTX_free(EVP_PKEY_CTX *ctx)
311 {
312 if (ctx == NULL)
313 return;
314 if (ctx->pmeth && ctx->pmeth->cleanup)
315 ctx->pmeth->cleanup(ctx);
316 if (ctx->pkey)
317 EVP_PKEY_free(ctx->pkey);
318 if (ctx->peerkey)
319 EVP_PKEY_free(ctx->peerkey);
320#ifndef OPENSSL_NO_ENGINE
321 if(ctx->engine)
322 /* The EVP_PKEY_CTX we used belongs to an ENGINE, release the
323 * functional reference we held for this reason. */
324 ENGINE_finish(ctx->engine);
325#endif
326 OPENSSL_free(ctx);
327 }
328
329int EVP_PKEY_CTX_ctrl(EVP_PKEY_CTX *ctx, int keytype, int optype,
330 int cmd, int p1, void *p2)
331 {
332 int ret;
333 if (!ctx || !ctx->pmeth || !ctx->pmeth->ctrl)
334 {
335 EVPerr(EVP_F_EVP_PKEY_CTX_CTRL, EVP_R_COMMAND_NOT_SUPPORTED);
336 return -2;
337 }
338 if ((keytype != -1) && (ctx->pmeth->pkey_id != keytype))
339 return -1;
340
341 if (ctx->operation == EVP_PKEY_OP_UNDEFINED)
342 {
343 EVPerr(EVP_F_EVP_PKEY_CTX_CTRL, EVP_R_NO_OPERATION_SET);
344 return -1;
345 }
346
347 if ((optype != -1) && !(ctx->operation & optype))
348 {
349 EVPerr(EVP_F_EVP_PKEY_CTX_CTRL, EVP_R_INVALID_OPERATION);
350 return -1;
351 }
352
353 ret = ctx->pmeth->ctrl(ctx, cmd, p1, p2);
354
355 if (ret == -2)
356 EVPerr(EVP_F_EVP_PKEY_CTX_CTRL, EVP_R_COMMAND_NOT_SUPPORTED);
357
358 return ret;
359
360 }
361
362int EVP_PKEY_CTX_ctrl_str(EVP_PKEY_CTX *ctx,
363 const char *name, const char *value)
364 {
365 if (!ctx || !ctx->pmeth || !ctx->pmeth->ctrl_str)
366 {
367 EVPerr(EVP_F_EVP_PKEY_CTX_CTRL_STR,
368 EVP_R_COMMAND_NOT_SUPPORTED);
369 return -2;
370 }
371 if (!strcmp(name, "digest"))
372 {
373 const EVP_MD *md;
374 if (!value || !(md = EVP_get_digestbyname(value)))
375 {
376 EVPerr(EVP_F_EVP_PKEY_CTX_CTRL_STR,
377 EVP_R_INVALID_DIGEST);
378 return 0;
379 }
380 return EVP_PKEY_CTX_set_signature_md(ctx, md);
381 }
382 return ctx->pmeth->ctrl_str(ctx, name, value);
383 }
384
385int EVP_PKEY_CTX_get_operation(EVP_PKEY_CTX *ctx)
386 {
387 return ctx->operation;
388 }
389
390void EVP_PKEY_CTX_set0_keygen_info(EVP_PKEY_CTX *ctx, int *dat, int datlen)
391 {
392 ctx->keygen_info = dat;
393 ctx->keygen_info_count = datlen;
394 }
395
396void EVP_PKEY_CTX_set_data(EVP_PKEY_CTX *ctx, void *data)
397 {
398 ctx->data = data;
399 }
400
401void *EVP_PKEY_CTX_get_data(EVP_PKEY_CTX *ctx)
402 {
403 return ctx->data;
404 }
405
406EVP_PKEY *EVP_PKEY_CTX_get0_pkey(EVP_PKEY_CTX *ctx)
407 {
408 return ctx->pkey;
409 }
410
411EVP_PKEY *EVP_PKEY_CTX_get0_peerkey(EVP_PKEY_CTX *ctx)
412 {
413 return ctx->peerkey;
414 }
415
416void EVP_PKEY_CTX_set_app_data(EVP_PKEY_CTX *ctx, void *data)
417 {
418 ctx->app_data = data;
419 }
420
421void *EVP_PKEY_CTX_get_app_data(EVP_PKEY_CTX *ctx)
422 {
423 return ctx->app_data;
424 }
425
426void EVP_PKEY_meth_set_init(EVP_PKEY_METHOD *pmeth,
427 int (*init)(EVP_PKEY_CTX *ctx))
428 {
429 pmeth->init = init;
430 }
431
432void EVP_PKEY_meth_set_copy(EVP_PKEY_METHOD *pmeth,
433 int (*copy)(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src))
434 {
435 pmeth->copy = copy;
436 }
437
438void EVP_PKEY_meth_set_cleanup(EVP_PKEY_METHOD *pmeth,
439 void (*cleanup)(EVP_PKEY_CTX *ctx))
440 {
441 pmeth->cleanup = cleanup;
442 }
443
444void EVP_PKEY_meth_set_paramgen(EVP_PKEY_METHOD *pmeth,
445 int (*paramgen_init)(EVP_PKEY_CTX *ctx),
446 int (*paramgen)(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey))
447 {
448 pmeth->paramgen_init = paramgen_init;
449 pmeth->paramgen = paramgen;
450 }
451
452void EVP_PKEY_meth_set_keygen(EVP_PKEY_METHOD *pmeth,
453 int (*keygen_init)(EVP_PKEY_CTX *ctx),
454 int (*keygen)(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey))
455 {
456 pmeth->keygen_init = keygen_init;
457 pmeth->keygen = keygen;
458 }
459
460void EVP_PKEY_meth_set_sign(EVP_PKEY_METHOD *pmeth,
461 int (*sign_init)(EVP_PKEY_CTX *ctx),
462 int (*sign)(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen,
463 const unsigned char *tbs, size_t tbslen))
464 {
465 pmeth->sign_init = sign_init;
466 pmeth->sign = sign;
467 }
468
469void EVP_PKEY_meth_set_verify(EVP_PKEY_METHOD *pmeth,
470 int (*verify_init)(EVP_PKEY_CTX *ctx),
471 int (*verify)(EVP_PKEY_CTX *ctx, const unsigned char *sig, size_t siglen,
472 const unsigned char *tbs, size_t tbslen))
473 {
474 pmeth->verify_init = verify_init;
475 pmeth->verify = verify;
476 }
477
478void EVP_PKEY_meth_set_verify_recover(EVP_PKEY_METHOD *pmeth,
479 int (*verify_recover_init)(EVP_PKEY_CTX *ctx),
480 int (*verify_recover)(EVP_PKEY_CTX *ctx,
481 unsigned char *sig, size_t *siglen,
482 const unsigned char *tbs, size_t tbslen))
483 {
484 pmeth->verify_recover_init = verify_recover_init;
485 pmeth->verify_recover = verify_recover;
486 }
487
488void EVP_PKEY_meth_set_signctx(EVP_PKEY_METHOD *pmeth,
489 int (*signctx_init)(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx),
490 int (*signctx)(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen,
491 EVP_MD_CTX *mctx))
492 {
493 pmeth->signctx_init = signctx_init;
494 pmeth->signctx = signctx;
495 }
496
497void EVP_PKEY_meth_set_verifyctx(EVP_PKEY_METHOD *pmeth,
498 int (*verifyctx_init)(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx),
499 int (*verifyctx)(EVP_PKEY_CTX *ctx, const unsigned char *sig,int siglen,
500 EVP_MD_CTX *mctx))
501 {
502 pmeth->verifyctx_init = verifyctx_init;
503 pmeth->verifyctx = verifyctx;
504 }
505
506void EVP_PKEY_meth_set_encrypt(EVP_PKEY_METHOD *pmeth,
507 int (*encrypt_init)(EVP_PKEY_CTX *ctx),
508 int (*encryptfn)(EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen,
509 const unsigned char *in, size_t inlen))
510 {
511 pmeth->encrypt_init = encrypt_init;
512 pmeth->encrypt = encryptfn;
513 }
514
515void EVP_PKEY_meth_set_decrypt(EVP_PKEY_METHOD *pmeth,
516 int (*decrypt_init)(EVP_PKEY_CTX *ctx),
517 int (*decrypt)(EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen,
518 const unsigned char *in, size_t inlen))
519 {
520 pmeth->decrypt_init = decrypt_init;
521 pmeth->decrypt = decrypt;
522 }
523
524void EVP_PKEY_meth_set_derive(EVP_PKEY_METHOD *pmeth,
525 int (*derive_init)(EVP_PKEY_CTX *ctx),
526 int (*derive)(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen))
527 {
528 pmeth->derive_init = derive_init;
529 pmeth->derive = derive;
530 }
531
532void EVP_PKEY_meth_set_ctrl(EVP_PKEY_METHOD *pmeth,
533 int (*ctrl)(EVP_PKEY_CTX *ctx, int type, int p1, void *p2),
534 int (*ctrl_str)(EVP_PKEY_CTX *ctx, const char *type, const char *value))
535 {
536 pmeth->ctrl = ctrl;
537 pmeth->ctrl_str = ctrl_str;
538 }
diff --git a/src/lib/libcrypto/ex_data.c b/src/lib/libcrypto/ex_data.c
index 3b11e7a556..e2bc8298d0 100644
--- a/src/lib/libcrypto/ex_data.c
+++ b/src/lib/libcrypto/ex_data.c
@@ -245,18 +245,21 @@ typedef struct st_ex_class_item {
245static int ex_class = CRYPTO_EX_INDEX_USER; 245static int ex_class = CRYPTO_EX_INDEX_USER;
246 246
247/* The global hash table of EX_CLASS_ITEM items */ 247/* The global hash table of EX_CLASS_ITEM items */
248static LHASH *ex_data = NULL; 248DECLARE_LHASH_OF(EX_CLASS_ITEM);
249static LHASH_OF(EX_CLASS_ITEM) *ex_data = NULL;
249 250
250/* The callbacks required in the "ex_data" hash table */ 251/* The callbacks required in the "ex_data" hash table */
251static unsigned long ex_hash_cb(const void *a_void) 252static unsigned long ex_class_item_hash(const EX_CLASS_ITEM *a)
252 { 253 {
253 return ((const EX_CLASS_ITEM *)a_void)->class_index; 254 return a->class_index;
254 } 255 }
255static int ex_cmp_cb(const void *a_void, const void *b_void) 256static IMPLEMENT_LHASH_HASH_FN(ex_class_item, EX_CLASS_ITEM)
257
258static int ex_class_item_cmp(const EX_CLASS_ITEM *a, const EX_CLASS_ITEM *b)
256 { 259 {
257 return (((const EX_CLASS_ITEM *)a_void)->class_index - 260 return a->class_index - b->class_index;
258 ((const EX_CLASS_ITEM *)b_void)->class_index);
259 } 261 }
262static IMPLEMENT_LHASH_COMP_FN(ex_class_item, EX_CLASS_ITEM)
260 263
261/* Internal functions used by the "impl_default" implementation to access the 264/* Internal functions used by the "impl_default" implementation to access the
262 * state */ 265 * state */
@@ -265,7 +268,8 @@ static int ex_data_check(void)
265 { 268 {
266 int toret = 1; 269 int toret = 1;
267 CRYPTO_w_lock(CRYPTO_LOCK_EX_DATA); 270 CRYPTO_w_lock(CRYPTO_LOCK_EX_DATA);
268 if(!ex_data && ((ex_data = lh_new(ex_hash_cb, ex_cmp_cb)) == NULL)) 271 if(!ex_data
272 && (ex_data = lh_EX_CLASS_ITEM_new()) == NULL)
269 toret = 0; 273 toret = 0;
270 CRYPTO_w_unlock(CRYPTO_LOCK_EX_DATA); 274 CRYPTO_w_unlock(CRYPTO_LOCK_EX_DATA);
271 return toret; 275 return toret;
@@ -298,7 +302,7 @@ static EX_CLASS_ITEM *def_get_class(int class_index)
298 EX_DATA_CHECK(return NULL;) 302 EX_DATA_CHECK(return NULL;)
299 d.class_index = class_index; 303 d.class_index = class_index;
300 CRYPTO_w_lock(CRYPTO_LOCK_EX_DATA); 304 CRYPTO_w_lock(CRYPTO_LOCK_EX_DATA);
301 p = lh_retrieve(ex_data, &d); 305 p = lh_EX_CLASS_ITEM_retrieve(ex_data, &d);
302 if(!p) 306 if(!p)
303 { 307 {
304 gen = OPENSSL_malloc(sizeof(EX_CLASS_ITEM)); 308 gen = OPENSSL_malloc(sizeof(EX_CLASS_ITEM));
@@ -313,7 +317,7 @@ static EX_CLASS_ITEM *def_get_class(int class_index)
313 { 317 {
314 /* Because we're inside the ex_data lock, the 318 /* Because we're inside the ex_data lock, the
315 * return value from the insert will be NULL */ 319 * return value from the insert will be NULL */
316 lh_insert(ex_data, gen); 320 (void)lh_EX_CLASS_ITEM_insert(ex_data, gen);
317 p = gen; 321 p = gen;
318 } 322 }
319 } 323 }
@@ -375,8 +379,8 @@ static int int_new_class(void)
375static void int_cleanup(void) 379static void int_cleanup(void)
376 { 380 {
377 EX_DATA_CHECK(return;) 381 EX_DATA_CHECK(return;)
378 lh_doall(ex_data, def_cleanup_cb); 382 lh_EX_CLASS_ITEM_doall(ex_data, def_cleanup_cb);
379 lh_free(ex_data); 383 lh_EX_CLASS_ITEM_free(ex_data);
380 ex_data = NULL; 384 ex_data = NULL;
381 impl = NULL; 385 impl = NULL;
382 } 386 }
@@ -452,7 +456,7 @@ static int int_dup_ex_data(int class_index, CRYPTO_EX_DATA *to,
452 return 0; 456 return 0;
453 CRYPTO_r_lock(CRYPTO_LOCK_EX_DATA); 457 CRYPTO_r_lock(CRYPTO_LOCK_EX_DATA);
454 mx = sk_CRYPTO_EX_DATA_FUNCS_num(item->meth); 458 mx = sk_CRYPTO_EX_DATA_FUNCS_num(item->meth);
455 j = sk_num(from->sk); 459 j = sk_void_num(from->sk);
456 if(j < mx) 460 if(j < mx)
457 mx = j; 461 mx = j;
458 if(mx > 0) 462 if(mx > 0)
@@ -523,7 +527,7 @@ skip:
523 OPENSSL_free(storage); 527 OPENSSL_free(storage);
524 if(ad->sk) 528 if(ad->sk)
525 { 529 {
526 sk_free(ad->sk); 530 sk_void_free(ad->sk);
527 ad->sk=NULL; 531 ad->sk=NULL;
528 } 532 }
529 } 533 }
@@ -596,24 +600,24 @@ int CRYPTO_set_ex_data(CRYPTO_EX_DATA *ad, int idx, void *val)
596 600
597 if (ad->sk == NULL) 601 if (ad->sk == NULL)
598 { 602 {
599 if ((ad->sk=sk_new_null()) == NULL) 603 if ((ad->sk=sk_void_new_null()) == NULL)
600 { 604 {
601 CRYPTOerr(CRYPTO_F_CRYPTO_SET_EX_DATA,ERR_R_MALLOC_FAILURE); 605 CRYPTOerr(CRYPTO_F_CRYPTO_SET_EX_DATA,ERR_R_MALLOC_FAILURE);
602 return(0); 606 return(0);
603 } 607 }
604 } 608 }
605 i=sk_num(ad->sk); 609 i=sk_void_num(ad->sk);
606 610
607 while (i <= idx) 611 while (i <= idx)
608 { 612 {
609 if (!sk_push(ad->sk,NULL)) 613 if (!sk_void_push(ad->sk,NULL))
610 { 614 {
611 CRYPTOerr(CRYPTO_F_CRYPTO_SET_EX_DATA,ERR_R_MALLOC_FAILURE); 615 CRYPTOerr(CRYPTO_F_CRYPTO_SET_EX_DATA,ERR_R_MALLOC_FAILURE);
612 return(0); 616 return(0);
613 } 617 }
614 i++; 618 i++;
615 } 619 }
616 sk_set(ad->sk,idx,val); 620 sk_void_set(ad->sk,idx,val);
617 return(1); 621 return(1);
618 } 622 }
619 623
@@ -623,10 +627,10 @@ void *CRYPTO_get_ex_data(const CRYPTO_EX_DATA *ad, int idx)
623 { 627 {
624 if (ad->sk == NULL) 628 if (ad->sk == NULL)
625 return(0); 629 return(0);
626 else if (idx >= sk_num(ad->sk)) 630 else if (idx >= sk_void_num(ad->sk))
627 return(0); 631 return(0);
628 else 632 else
629 return(sk_value(ad->sk,idx)); 633 return(sk_void_value(ad->sk,idx));
630 } 634 }
631 635
632IMPLEMENT_STACK_OF(CRYPTO_EX_DATA_FUNCS) 636IMPLEMENT_STACK_OF(CRYPTO_EX_DATA_FUNCS)
diff --git a/src/lib/libcrypto/hmac/hm_ameth.c b/src/lib/libcrypto/hmac/hm_ameth.c
new file mode 100644
index 0000000000..6d8a89149e
--- /dev/null
+++ b/src/lib/libcrypto/hmac/hm_ameth.c
@@ -0,0 +1,167 @@
1/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
2 * project 2007.
3 */
4/* ====================================================================
5 * Copyright (c) 2007 The OpenSSL Project. All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 *
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 *
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in
16 * the documentation and/or other materials provided with the
17 * distribution.
18 *
19 * 3. All advertising materials mentioning features or use of this
20 * software must display the following acknowledgment:
21 * "This product includes software developed by the OpenSSL Project
22 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
23 *
24 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
25 * endorse or promote products derived from this software without
26 * prior written permission. For written permission, please contact
27 * licensing@OpenSSL.org.
28 *
29 * 5. Products derived from this software may not be called "OpenSSL"
30 * nor may "OpenSSL" appear in their names without prior written
31 * permission of the OpenSSL Project.
32 *
33 * 6. Redistributions of any form whatsoever must retain the following
34 * acknowledgment:
35 * "This product includes software developed by the OpenSSL Project
36 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
37 *
38 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
39 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
40 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
41 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
42 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
43 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
44 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
45 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
46 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
47 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
48 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
49 * OF THE POSSIBILITY OF SUCH DAMAGE.
50 * ====================================================================
51 *
52 * This product includes cryptographic software written by Eric Young
53 * (eay@cryptsoft.com). This product includes software written by Tim
54 * Hudson (tjh@cryptsoft.com).
55 *
56 */
57
58#include <stdio.h>
59#include "cryptlib.h"
60#include <openssl/evp.h>
61#include "asn1_locl.h"
62
63#define HMAC_TEST_PRIVATE_KEY_FORMAT
64
65/* HMAC "ASN1" method. This is just here to indicate the
66 * maximum HMAC output length and to free up an HMAC
67 * key.
68 */
69
70static int hmac_size(const EVP_PKEY *pkey)
71 {
72 return EVP_MAX_MD_SIZE;
73 }
74
75static void hmac_key_free(EVP_PKEY *pkey)
76 {
77 ASN1_OCTET_STRING *os = (ASN1_OCTET_STRING *)pkey->pkey.ptr;
78 if (os)
79 {
80 if (os->data)
81 OPENSSL_cleanse(os->data, os->length);
82 ASN1_OCTET_STRING_free(os);
83 }
84 }
85
86
87static int hmac_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2)
88 {
89 switch (op)
90 {
91 case ASN1_PKEY_CTRL_DEFAULT_MD_NID:
92 *(int *)arg2 = NID_sha1;
93 return 1;
94
95 default:
96 return -2;
97 }
98 }
99
100#ifdef HMAC_TEST_PRIVATE_KEY_FORMAT
101/* A bogus private key format for test purposes. This is simply the
102 * HMAC key with "HMAC PRIVATE KEY" in the headers. When enabled the
103 * genpkey utility can be used to "generate" HMAC keys.
104 */
105
106static int old_hmac_decode(EVP_PKEY *pkey,
107 const unsigned char **pder, int derlen)
108 {
109 ASN1_OCTET_STRING *os;
110 os = ASN1_OCTET_STRING_new();
111 if (!os || !ASN1_OCTET_STRING_set(os, *pder, derlen))
112 return 0;
113 EVP_PKEY_assign(pkey, EVP_PKEY_HMAC, os);
114 return 1;
115 }
116
117static int old_hmac_encode(const EVP_PKEY *pkey, unsigned char **pder)
118 {
119 int inc;
120 ASN1_OCTET_STRING *os = (ASN1_OCTET_STRING *)pkey->pkey.ptr;
121 if (pder)
122 {
123 if (!*pder)
124 {
125 *pder = OPENSSL_malloc(os->length);
126 inc = 0;
127 }
128 else inc = 1;
129
130 memcpy(*pder, os->data, os->length);
131
132 if (inc)
133 *pder += os->length;
134 }
135
136 return os->length;
137 }
138
139#endif
140
141const EVP_PKEY_ASN1_METHOD hmac_asn1_meth =
142 {
143 EVP_PKEY_HMAC,
144 EVP_PKEY_HMAC,
145 0,
146
147 "HMAC",
148 "OpenSSL HMAC method",
149
150 0,0,0,0,
151
152 0,0,0,
153
154 hmac_size,
155 0,
156 0,0,0,0,0,0,
157
158 hmac_key_free,
159 hmac_pkey_ctrl,
160#ifdef HMAC_TEST_PRIVATE_KEY_FORMAT
161 old_hmac_decode,
162 old_hmac_encode
163#else
164 0,0
165#endif
166 };
167
diff --git a/src/lib/libcrypto/hmac/hm_pmeth.c b/src/lib/libcrypto/hmac/hm_pmeth.c
new file mode 100644
index 0000000000..985921ca1a
--- /dev/null
+++ b/src/lib/libcrypto/hmac/hm_pmeth.c
@@ -0,0 +1,265 @@
1/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
2 * project 2007.
3 */
4/* ====================================================================
5 * Copyright (c) 2007 The OpenSSL Project. All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 *
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 *
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in
16 * the documentation and/or other materials provided with the
17 * distribution.
18 *
19 * 3. All advertising materials mentioning features or use of this
20 * software must display the following acknowledgment:
21 * "This product includes software developed by the OpenSSL Project
22 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
23 *
24 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
25 * endorse or promote products derived from this software without
26 * prior written permission. For written permission, please contact
27 * licensing@OpenSSL.org.
28 *
29 * 5. Products derived from this software may not be called "OpenSSL"
30 * nor may "OpenSSL" appear in their names without prior written
31 * permission of the OpenSSL Project.
32 *
33 * 6. Redistributions of any form whatsoever must retain the following
34 * acknowledgment:
35 * "This product includes software developed by the OpenSSL Project
36 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
37 *
38 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
39 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
40 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
41 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
42 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
43 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
44 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
45 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
46 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
47 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
48 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
49 * OF THE POSSIBILITY OF SUCH DAMAGE.
50 * ====================================================================
51 *
52 * This product includes cryptographic software written by Eric Young
53 * (eay@cryptsoft.com). This product includes software written by Tim
54 * Hudson (tjh@cryptsoft.com).
55 *
56 */
57
58#include <stdio.h>
59#include "cryptlib.h"
60#include <openssl/x509.h>
61#include <openssl/x509v3.h>
62#include <openssl/evp.h>
63#include <openssl/hmac.h>
64#include "evp_locl.h"
65
66/* HMAC pkey context structure */
67
68typedef struct
69 {
70 const EVP_MD *md; /* MD for HMAC use */
71 ASN1_OCTET_STRING ktmp; /* Temp storage for key */
72 HMAC_CTX ctx;
73 } HMAC_PKEY_CTX;
74
75static int pkey_hmac_init(EVP_PKEY_CTX *ctx)
76 {
77 HMAC_PKEY_CTX *hctx;
78 hctx = OPENSSL_malloc(sizeof(HMAC_PKEY_CTX));
79 if (!hctx)
80 return 0;
81 hctx->md = NULL;
82 hctx->ktmp.data = NULL;
83 hctx->ktmp.length = 0;
84 hctx->ktmp.flags = 0;
85 hctx->ktmp.type = V_ASN1_OCTET_STRING;
86 HMAC_CTX_init(&hctx->ctx);
87
88 ctx->data = hctx;
89 ctx->keygen_info_count = 0;
90
91 return 1;
92 }
93
94static int pkey_hmac_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src)
95 {
96 HMAC_PKEY_CTX *sctx, *dctx;
97 if (!pkey_hmac_init(dst))
98 return 0;
99 sctx = src->data;
100 dctx = dst->data;
101 dctx->md = sctx->md;
102 HMAC_CTX_init(&dctx->ctx);
103 HMAC_CTX_copy(&dctx->ctx, &sctx->ctx);
104 if (sctx->ktmp.data)
105 {
106 if (!ASN1_OCTET_STRING_set(&dctx->ktmp,
107 sctx->ktmp.data, sctx->ktmp.length))
108 return 0;
109 }
110 return 1;
111 }
112
113static void pkey_hmac_cleanup(EVP_PKEY_CTX *ctx)
114 {
115 HMAC_PKEY_CTX *hctx = ctx->data;
116 HMAC_CTX_cleanup(&hctx->ctx);
117 if (hctx->ktmp.data)
118 {
119 if (hctx->ktmp.length)
120 OPENSSL_cleanse(hctx->ktmp.data, hctx->ktmp.length);
121 OPENSSL_free(hctx->ktmp.data);
122 hctx->ktmp.data = NULL;
123 }
124 OPENSSL_free(hctx);
125 }
126
127static int pkey_hmac_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
128 {
129 ASN1_OCTET_STRING *hkey = NULL;
130 HMAC_PKEY_CTX *hctx = ctx->data;
131 if (!hctx->ktmp.data)
132 return 0;
133 hkey = ASN1_OCTET_STRING_dup(&hctx->ktmp);
134 if (!hkey)
135 return 0;
136 EVP_PKEY_assign(pkey, EVP_PKEY_HMAC, hkey);
137
138 return 1;
139 }
140
141static int int_update(EVP_MD_CTX *ctx,const void *data,size_t count)
142 {
143 HMAC_PKEY_CTX *hctx = ctx->pctx->data;
144 HMAC_Update(&hctx->ctx, data, count);
145 return 1;
146 }
147
148static int hmac_signctx_init(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx)
149 {
150 EVP_MD_CTX_set_flags(mctx, EVP_MD_CTX_FLAG_NO_INIT);
151 mctx->update = int_update;
152 return 1;
153 }
154
155static int hmac_signctx(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen,
156 EVP_MD_CTX *mctx)
157 {
158 unsigned int hlen;
159 HMAC_PKEY_CTX *hctx = ctx->data;
160 int l = EVP_MD_CTX_size(mctx);
161
162 if (l < 0)
163 return 0;
164 *siglen = l;
165 if (!sig)
166 return 1;
167
168 HMAC_Final(&hctx->ctx, sig, &hlen);
169 *siglen = (size_t)hlen;
170 return 1;
171 }
172
173static int pkey_hmac_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
174 {
175 HMAC_PKEY_CTX *hctx = ctx->data;
176 ASN1_OCTET_STRING *key;
177 switch (type)
178 {
179
180 case EVP_PKEY_CTRL_SET_MAC_KEY:
181 if ((!p2 && p1 > 0) || (p1 < -1))
182 return 0;
183 if (!ASN1_OCTET_STRING_set(&hctx->ktmp, p2, p1))
184 return 0;
185 break;
186
187 case EVP_PKEY_CTRL_MD:
188 hctx->md = p2;
189 break;
190
191 case EVP_PKEY_CTRL_DIGESTINIT:
192 key = (ASN1_OCTET_STRING *)ctx->pkey->pkey.ptr;
193 HMAC_Init_ex(&hctx->ctx, key->data, key->length, hctx->md,
194 ctx->engine);
195 break;
196
197 default:
198 return -2;
199
200 }
201 return 1;
202 }
203
204static int pkey_hmac_ctrl_str(EVP_PKEY_CTX *ctx,
205 const char *type, const char *value)
206 {
207 if (!value)
208 {
209 return 0;
210 }
211 if (!strcmp(type, "key"))
212 {
213 void *p = (void *)value;
214 return pkey_hmac_ctrl(ctx, EVP_PKEY_CTRL_SET_MAC_KEY,
215 -1, p);
216 }
217 if (!strcmp(type, "hexkey"))
218 {
219 unsigned char *key;
220 int r;
221 long keylen;
222 key = string_to_hex(value, &keylen);
223 if (!key)
224 return 0;
225 r = pkey_hmac_ctrl(ctx, EVP_PKEY_CTRL_SET_MAC_KEY, keylen, key);
226 OPENSSL_free(key);
227 return r;
228 }
229 return -2;
230 }
231
232const EVP_PKEY_METHOD hmac_pkey_meth =
233 {
234 EVP_PKEY_HMAC,
235 0,
236 pkey_hmac_init,
237 pkey_hmac_copy,
238 pkey_hmac_cleanup,
239
240 0, 0,
241
242 0,
243 pkey_hmac_keygen,
244
245 0, 0,
246
247 0, 0,
248
249 0,0,
250
251 hmac_signctx_init,
252 hmac_signctx,
253
254 0,0,
255
256 0,0,
257
258 0,0,
259
260 0,0,
261
262 pkey_hmac_ctrl,
263 pkey_hmac_ctrl_str
264
265 };
diff --git a/src/lib/libcrypto/hmac/hmac.c b/src/lib/libcrypto/hmac/hmac.c
index cbc1c76a57..45015fe754 100644
--- a/src/lib/libcrypto/hmac/hmac.c
+++ b/src/lib/libcrypto/hmac/hmac.c
@@ -61,9 +61,7 @@
61#include "cryptlib.h" 61#include "cryptlib.h"
62#include <openssl/hmac.h> 62#include <openssl/hmac.h>
63 63
64#ifndef OPENSSL_FIPS 64int HMAC_Init_ex(HMAC_CTX *ctx, const void *key, int len,
65
66void HMAC_Init_ex(HMAC_CTX *ctx, const void *key, int len,
67 const EVP_MD *md, ENGINE *impl) 65 const EVP_MD *md, ENGINE *impl)
68 { 66 {
69 int i,j,reset=0; 67 int i,j,reset=0;
@@ -84,10 +82,13 @@ void HMAC_Init_ex(HMAC_CTX *ctx, const void *key, int len,
84 OPENSSL_assert(j <= (int)sizeof(ctx->key)); 82 OPENSSL_assert(j <= (int)sizeof(ctx->key));
85 if (j < len) 83 if (j < len)
86 { 84 {
87 EVP_DigestInit_ex(&ctx->md_ctx,md, impl); 85 if (!EVP_DigestInit_ex(&ctx->md_ctx,md, impl))
88 EVP_DigestUpdate(&ctx->md_ctx,key,len); 86 goto err;
89 EVP_DigestFinal_ex(&(ctx->md_ctx),ctx->key, 87 if (!EVP_DigestUpdate(&ctx->md_ctx,key,len))
90 &ctx->key_length); 88 goto err;
89 if (!EVP_DigestFinal_ex(&(ctx->md_ctx),ctx->key,
90 &ctx->key_length))
91 goto err;
91 } 92 }
92 else 93 else
93 { 94 {
@@ -104,31 +105,38 @@ void HMAC_Init_ex(HMAC_CTX *ctx, const void *key, int len,
104 { 105 {
105 for (i=0; i<HMAC_MAX_MD_CBLOCK; i++) 106 for (i=0; i<HMAC_MAX_MD_CBLOCK; i++)
106 pad[i]=0x36^ctx->key[i]; 107 pad[i]=0x36^ctx->key[i];
107 EVP_DigestInit_ex(&ctx->i_ctx,md, impl); 108 if (!EVP_DigestInit_ex(&ctx->i_ctx,md, impl))
108 EVP_DigestUpdate(&ctx->i_ctx,pad,EVP_MD_block_size(md)); 109 goto err;
110 if (!EVP_DigestUpdate(&ctx->i_ctx,pad,EVP_MD_block_size(md)))
111 goto err;
109 112
110 for (i=0; i<HMAC_MAX_MD_CBLOCK; i++) 113 for (i=0; i<HMAC_MAX_MD_CBLOCK; i++)
111 pad[i]=0x5c^ctx->key[i]; 114 pad[i]=0x5c^ctx->key[i];
112 EVP_DigestInit_ex(&ctx->o_ctx,md, impl); 115 if (!EVP_DigestInit_ex(&ctx->o_ctx,md, impl))
113 EVP_DigestUpdate(&ctx->o_ctx,pad,EVP_MD_block_size(md)); 116 goto err;
117 if (!EVP_DigestUpdate(&ctx->o_ctx,pad,EVP_MD_block_size(md)))
118 goto err;
114 } 119 }
115 EVP_MD_CTX_copy_ex(&ctx->md_ctx,&ctx->i_ctx); 120 if (!EVP_MD_CTX_copy_ex(&ctx->md_ctx,&ctx->i_ctx))
121 goto err;
122 return 1;
123 err:
124 return 0;
116 } 125 }
117 126
118void HMAC_Init(HMAC_CTX *ctx, const void *key, int len, 127int HMAC_Init(HMAC_CTX *ctx, const void *key, int len, const EVP_MD *md)
119 const EVP_MD *md)
120 { 128 {
121 if(key && md) 129 if(key && md)
122 HMAC_CTX_init(ctx); 130 HMAC_CTX_init(ctx);
123 HMAC_Init_ex(ctx,key,len,md, NULL); 131 return HMAC_Init_ex(ctx,key,len,md, NULL);
124 } 132 }
125 133
126void HMAC_Update(HMAC_CTX *ctx, const unsigned char *data, size_t len) 134int HMAC_Update(HMAC_CTX *ctx, const unsigned char *data, size_t len)
127 { 135 {
128 EVP_DigestUpdate(&ctx->md_ctx,data,len); 136 return EVP_DigestUpdate(&ctx->md_ctx,data,len);
129 } 137 }
130 138
131void HMAC_Final(HMAC_CTX *ctx, unsigned char *md, unsigned int *len) 139int HMAC_Final(HMAC_CTX *ctx, unsigned char *md, unsigned int *len)
132 { 140 {
133 int j; 141 int j;
134 unsigned int i; 142 unsigned int i;
@@ -136,10 +144,17 @@ void HMAC_Final(HMAC_CTX *ctx, unsigned char *md, unsigned int *len)
136 144
137 j=EVP_MD_block_size(ctx->md); 145 j=EVP_MD_block_size(ctx->md);
138 146
139 EVP_DigestFinal_ex(&ctx->md_ctx,buf,&i); 147 if (!EVP_DigestFinal_ex(&ctx->md_ctx,buf,&i))
140 EVP_MD_CTX_copy_ex(&ctx->md_ctx,&ctx->o_ctx); 148 goto err;
141 EVP_DigestUpdate(&ctx->md_ctx,buf,i); 149 if (!EVP_MD_CTX_copy_ex(&ctx->md_ctx,&ctx->o_ctx))
142 EVP_DigestFinal_ex(&ctx->md_ctx,md,len); 150 goto err;
151 if (!EVP_DigestUpdate(&ctx->md_ctx,buf,i))
152 goto err;
153 if (!EVP_DigestFinal_ex(&ctx->md_ctx,md,len))
154 goto err;
155 return 1;
156 err:
157 return 0;
143 } 158 }
144 159
145void HMAC_CTX_init(HMAC_CTX *ctx) 160void HMAC_CTX_init(HMAC_CTX *ctx)
@@ -149,6 +164,22 @@ void HMAC_CTX_init(HMAC_CTX *ctx)
149 EVP_MD_CTX_init(&ctx->md_ctx); 164 EVP_MD_CTX_init(&ctx->md_ctx);
150 } 165 }
151 166
167int HMAC_CTX_copy(HMAC_CTX *dctx, HMAC_CTX *sctx)
168 {
169 if (!EVP_MD_CTX_copy(&dctx->i_ctx, &sctx->i_ctx))
170 goto err;
171 if (!EVP_MD_CTX_copy(&dctx->o_ctx, &sctx->o_ctx))
172 goto err;
173 if (!EVP_MD_CTX_copy(&dctx->md_ctx, &sctx->md_ctx))
174 goto err;
175 memcpy(dctx->key, sctx->key, HMAC_MAX_MD_CBLOCK);
176 dctx->key_length = sctx->key_length;
177 dctx->md = sctx->md;
178 return 1;
179 err:
180 return 0;
181 }
182
152void HMAC_CTX_cleanup(HMAC_CTX *ctx) 183void HMAC_CTX_cleanup(HMAC_CTX *ctx)
153 { 184 {
154 EVP_MD_CTX_cleanup(&ctx->i_ctx); 185 EVP_MD_CTX_cleanup(&ctx->i_ctx);
@@ -166,11 +197,16 @@ unsigned char *HMAC(const EVP_MD *evp_md, const void *key, int key_len,
166 197
167 if (md == NULL) md=m; 198 if (md == NULL) md=m;
168 HMAC_CTX_init(&c); 199 HMAC_CTX_init(&c);
169 HMAC_Init(&c,key,key_len,evp_md); 200 if (!HMAC_Init(&c,key,key_len,evp_md))
170 HMAC_Update(&c,d,n); 201 goto err;
171 HMAC_Final(&c,md,md_len); 202 if (!HMAC_Update(&c,d,n))
203 goto err;
204 if (!HMAC_Final(&c,md,md_len))
205 goto err;
172 HMAC_CTX_cleanup(&c); 206 HMAC_CTX_cleanup(&c);
173 return(md); 207 return md;
208 err:
209 return NULL;
174 } 210 }
175 211
176void HMAC_CTX_set_flags(HMAC_CTX *ctx, unsigned long flags) 212void HMAC_CTX_set_flags(HMAC_CTX *ctx, unsigned long flags)
@@ -179,5 +215,3 @@ void HMAC_CTX_set_flags(HMAC_CTX *ctx, unsigned long flags)
179 EVP_MD_CTX_set_flags(&ctx->o_ctx, flags); 215 EVP_MD_CTX_set_flags(&ctx->o_ctx, flags);
180 EVP_MD_CTX_set_flags(&ctx->md_ctx, flags); 216 EVP_MD_CTX_set_flags(&ctx->md_ctx, flags);
181 } 217 }
182
183#endif
diff --git a/src/lib/libcrypto/hmac/hmac.h b/src/lib/libcrypto/hmac/hmac.h
index fc38ffb52b..1be0022190 100644
--- a/src/lib/libcrypto/hmac/hmac.h
+++ b/src/lib/libcrypto/hmac/hmac.h
@@ -90,15 +90,16 @@ void HMAC_CTX_cleanup(HMAC_CTX *ctx);
90 90
91#define HMAC_cleanup(ctx) HMAC_CTX_cleanup(ctx) /* deprecated */ 91#define HMAC_cleanup(ctx) HMAC_CTX_cleanup(ctx) /* deprecated */
92 92
93void HMAC_Init(HMAC_CTX *ctx, const void *key, int len, 93int HMAC_Init(HMAC_CTX *ctx, const void *key, int len,
94 const EVP_MD *md); /* deprecated */ 94 const EVP_MD *md); /* deprecated */
95void HMAC_Init_ex(HMAC_CTX *ctx, const void *key, int len, 95int HMAC_Init_ex(HMAC_CTX *ctx, const void *key, int len,
96 const EVP_MD *md, ENGINE *impl); 96 const EVP_MD *md, ENGINE *impl);
97void HMAC_Update(HMAC_CTX *ctx, const unsigned char *data, size_t len); 97int HMAC_Update(HMAC_CTX *ctx, const unsigned char *data, size_t len);
98void HMAC_Final(HMAC_CTX *ctx, unsigned char *md, unsigned int *len); 98int HMAC_Final(HMAC_CTX *ctx, unsigned char *md, unsigned int *len);
99unsigned char *HMAC(const EVP_MD *evp_md, const void *key, int key_len, 99unsigned char *HMAC(const EVP_MD *evp_md, const void *key, int key_len,
100 const unsigned char *d, size_t n, unsigned char *md, 100 const unsigned char *d, size_t n, unsigned char *md,
101 unsigned int *md_len); 101 unsigned int *md_len);
102int HMAC_CTX_copy(HMAC_CTX *dctx, HMAC_CTX *sctx);
102 103
103void HMAC_CTX_set_flags(HMAC_CTX *ctx, unsigned long flags); 104void HMAC_CTX_set_flags(HMAC_CTX *ctx, unsigned long flags);
104 105
diff --git a/src/lib/libcrypto/ia64cpuid.S b/src/lib/libcrypto/ia64cpuid.S
index 04fbb3439e..d705fff7ee 100644
--- a/src/lib/libcrypto/ia64cpuid.S
+++ b/src/lib/libcrypto/ia64cpuid.S
@@ -1,6 +1,13 @@
1// Works on all IA-64 platforms: Linux, HP-UX, Win64i... 1// Works on all IA-64 platforms: Linux, HP-UX, Win64i...
2// On Win64i compile with ias.exe. 2// On Win64i compile with ias.exe.
3.text 3.text
4
5.global OPENSSL_cpuid_setup#
6.proc OPENSSL_cpuid_setup#
7OPENSSL_cpuid_setup:
8{ .mib; br.ret.sptk.many b0 };;
9.endp OPENSSL_cpuid_setup#
10
4.global OPENSSL_rdtsc# 11.global OPENSSL_rdtsc#
5.proc OPENSSL_rdtsc# 12.proc OPENSSL_rdtsc#
6OPENSSL_rdtsc: 13OPENSSL_rdtsc:
@@ -119,3 +126,42 @@ OPENSSL_wipe_cpu:
119 mov ar.lc=r3 126 mov ar.lc=r3
120 br.ret.sptk b0 };; 127 br.ret.sptk b0 };;
121.endp OPENSSL_wipe_cpu# 128.endp OPENSSL_wipe_cpu#
129
130.global OPENSSL_cleanse#
131.proc OPENSSL_cleanse#
132OPENSSL_cleanse:
133{ .mib; cmp.eq p6,p0=0,r33 // len==0
134#if defined(_HPUX_SOURCE) && !defined(_LP64)
135 addp4 r32=0,r32
136#endif
137(p6) br.ret.spnt b0 };;
138{ .mib; and r2=7,r32
139 cmp.leu p6,p0=15,r33 // len>=15
140(p6) br.cond.dptk .Lot };;
141
142.Little:
143{ .mib; st1 [r32]=r0,1
144 cmp.ltu p6,p7=1,r33 } // len>1
145{ .mbb; add r33=-1,r33 // len--
146(p6) br.cond.dptk .Little
147(p7) br.ret.sptk.many b0 };;
148
149.Lot:
150{ .mib; cmp.eq p6,p0=0,r2
151(p6) br.cond.dptk .Laligned };;
152{ .mmi; st1 [r32]=r0,1;;
153 and r2=7,r32 }
154{ .mib; add r33=-1,r33
155 br .Lot };;
156
157.Laligned:
158{ .mmi; st8 [r32]=r0,8
159 and r2=-8,r33 // len&~7
160 add r33=-8,r33 };; // len-=8
161{ .mib; cmp.ltu p6,p0=8,r2 // ((len+8)&~7)>8
162(p6) br.cond.dptk .Laligned };;
163
164{ .mbb; cmp.eq p6,p7=r0,r33
165(p7) br.cond.dpnt .Little
166(p6) br.ret.sptk.many b0 };;
167.endp OPENSSL_cleanse#
diff --git a/src/lib/libcrypto/idea/idea.h b/src/lib/libcrypto/idea/idea.h
index a137d4cbce..5782e54b0f 100644
--- a/src/lib/libcrypto/idea/idea.h
+++ b/src/lib/libcrypto/idea/idea.h
@@ -83,11 +83,8 @@ typedef struct idea_key_st
83const char *idea_options(void); 83const char *idea_options(void);
84void idea_ecb_encrypt(const unsigned char *in, unsigned char *out, 84void idea_ecb_encrypt(const unsigned char *in, unsigned char *out,
85 IDEA_KEY_SCHEDULE *ks); 85 IDEA_KEY_SCHEDULE *ks);
86#ifdef OPENSSL_FIPS
87void private_idea_set_encrypt_key(const unsigned char *key, IDEA_KEY_SCHEDULE *ks);
88#endif
89void idea_set_encrypt_key(const unsigned char *key, IDEA_KEY_SCHEDULE *ks); 86void idea_set_encrypt_key(const unsigned char *key, IDEA_KEY_SCHEDULE *ks);
90void idea_set_decrypt_key(const IDEA_KEY_SCHEDULE *ek, IDEA_KEY_SCHEDULE *dk); 87void idea_set_decrypt_key(IDEA_KEY_SCHEDULE *ek, IDEA_KEY_SCHEDULE *dk);
91void idea_cbc_encrypt(const unsigned char *in, unsigned char *out, 88void idea_cbc_encrypt(const unsigned char *in, unsigned char *out,
92 long length, IDEA_KEY_SCHEDULE *ks, unsigned char *iv,int enc); 89 long length, IDEA_KEY_SCHEDULE *ks, unsigned char *iv,int enc);
93void idea_cfb64_encrypt(const unsigned char *in, unsigned char *out, 90void idea_cfb64_encrypt(const unsigned char *in, unsigned char *out,
diff --git a/src/lib/libcrypto/lhash/lh_stats.c b/src/lib/libcrypto/lhash/lh_stats.c
index 5aa7766aa6..815615e338 100644
--- a/src/lib/libcrypto/lhash/lh_stats.c
+++ b/src/lib/libcrypto/lhash/lh_stats.c
@@ -139,7 +139,7 @@ void lh_node_usage_stats(LHASH *lh, FILE *out)
139#else 139#else
140 140
141#ifndef OPENSSL_NO_FP_API 141#ifndef OPENSSL_NO_FP_API
142void lh_stats(const LHASH *lh, FILE *fp) 142void lh_stats(const _LHASH *lh, FILE *fp)
143 { 143 {
144 BIO *bp; 144 BIO *bp;
145 145
@@ -151,7 +151,7 @@ void lh_stats(const LHASH *lh, FILE *fp)
151end:; 151end:;
152 } 152 }
153 153
154void lh_node_stats(const LHASH *lh, FILE *fp) 154void lh_node_stats(const _LHASH *lh, FILE *fp)
155 { 155 {
156 BIO *bp; 156 BIO *bp;
157 157
@@ -163,7 +163,7 @@ void lh_node_stats(const LHASH *lh, FILE *fp)
163end:; 163end:;
164 } 164 }
165 165
166void lh_node_usage_stats(const LHASH *lh, FILE *fp) 166void lh_node_usage_stats(const _LHASH *lh, FILE *fp)
167 { 167 {
168 BIO *bp; 168 BIO *bp;
169 169
@@ -177,7 +177,7 @@ end:;
177 177
178#endif 178#endif
179 179
180void lh_stats_bio(const LHASH *lh, BIO *out) 180void lh_stats_bio(const _LHASH *lh, BIO *out)
181 { 181 {
182 BIO_printf(out,"num_items = %lu\n",lh->num_items); 182 BIO_printf(out,"num_items = %lu\n",lh->num_items);
183 BIO_printf(out,"num_nodes = %u\n",lh->num_nodes); 183 BIO_printf(out,"num_nodes = %u\n",lh->num_nodes);
@@ -205,7 +205,7 @@ void lh_stats_bio(const LHASH *lh, BIO *out)
205#endif 205#endif
206 } 206 }
207 207
208void lh_node_stats_bio(const LHASH *lh, BIO *out) 208void lh_node_stats_bio(const _LHASH *lh, BIO *out)
209 { 209 {
210 LHASH_NODE *n; 210 LHASH_NODE *n;
211 unsigned int i,num; 211 unsigned int i,num;
@@ -218,7 +218,7 @@ void lh_node_stats_bio(const LHASH *lh, BIO *out)
218 } 218 }
219 } 219 }
220 220
221void lh_node_usage_stats_bio(const LHASH *lh, BIO *out) 221void lh_node_usage_stats_bio(const _LHASH *lh, BIO *out)
222 { 222 {
223 LHASH_NODE *n; 223 LHASH_NODE *n;
224 unsigned long num; 224 unsigned long num;
diff --git a/src/lib/libcrypto/lhash/lhash.c b/src/lib/libcrypto/lhash/lhash.c
index 04ea80203c..47f748081b 100644
--- a/src/lib/libcrypto/lhash/lhash.c
+++ b/src/lib/libcrypto/lhash/lhash.c
@@ -107,18 +107,18 @@ const char lh_version[]="lhash" OPENSSL_VERSION_PTEXT;
107#define UP_LOAD (2*LH_LOAD_MULT) /* load times 256 (default 2) */ 107#define UP_LOAD (2*LH_LOAD_MULT) /* load times 256 (default 2) */
108#define DOWN_LOAD (LH_LOAD_MULT) /* load times 256 (default 1) */ 108#define DOWN_LOAD (LH_LOAD_MULT) /* load times 256 (default 1) */
109 109
110static void expand(LHASH *lh); 110static void expand(_LHASH *lh);
111static void contract(LHASH *lh); 111static void contract(_LHASH *lh);
112static LHASH_NODE **getrn(LHASH *lh, const void *data, unsigned long *rhash); 112static LHASH_NODE **getrn(_LHASH *lh, const void *data, unsigned long *rhash);
113 113
114LHASH *lh_new(LHASH_HASH_FN_TYPE h, LHASH_COMP_FN_TYPE c) 114_LHASH *lh_new(LHASH_HASH_FN_TYPE h, LHASH_COMP_FN_TYPE c)
115 { 115 {
116 LHASH *ret; 116 _LHASH *ret;
117 int i; 117 int i;
118 118
119 if ((ret=(LHASH *)OPENSSL_malloc(sizeof(LHASH))) == NULL) 119 if ((ret=OPENSSL_malloc(sizeof(_LHASH))) == NULL)
120 goto err0; 120 goto err0;
121 if ((ret->b=(LHASH_NODE **)OPENSSL_malloc(sizeof(LHASH_NODE *)*MIN_NODES)) == NULL) 121 if ((ret->b=OPENSSL_malloc(sizeof(LHASH_NODE *)*MIN_NODES)) == NULL)
122 goto err1; 122 goto err1;
123 for (i=0; i<MIN_NODES; i++) 123 for (i=0; i<MIN_NODES; i++)
124 ret->b[i]=NULL; 124 ret->b[i]=NULL;
@@ -154,7 +154,7 @@ err0:
154 return(NULL); 154 return(NULL);
155 } 155 }
156 156
157void lh_free(LHASH *lh) 157void lh_free(_LHASH *lh)
158 { 158 {
159 unsigned int i; 159 unsigned int i;
160 LHASH_NODE *n,*nn; 160 LHASH_NODE *n,*nn;
@@ -176,7 +176,7 @@ void lh_free(LHASH *lh)
176 OPENSSL_free(lh); 176 OPENSSL_free(lh);
177 } 177 }
178 178
179void *lh_insert(LHASH *lh, void *data) 179void *lh_insert(_LHASH *lh, void *data)
180 { 180 {
181 unsigned long hash; 181 unsigned long hash;
182 LHASH_NODE *nn,**rn; 182 LHASH_NODE *nn,**rn;
@@ -214,7 +214,7 @@ void *lh_insert(LHASH *lh, void *data)
214 return(ret); 214 return(ret);
215 } 215 }
216 216
217void *lh_delete(LHASH *lh, const void *data) 217void *lh_delete(_LHASH *lh, const void *data)
218 { 218 {
219 unsigned long hash; 219 unsigned long hash;
220 LHASH_NODE *nn,**rn; 220 LHASH_NODE *nn,**rn;
@@ -245,7 +245,7 @@ void *lh_delete(LHASH *lh, const void *data)
245 return(ret); 245 return(ret);
246 } 246 }
247 247
248void *lh_retrieve(LHASH *lh, const void *data) 248void *lh_retrieve(_LHASH *lh, const void *data)
249 { 249 {
250 unsigned long hash; 250 unsigned long hash;
251 LHASH_NODE **rn; 251 LHASH_NODE **rn;
@@ -267,12 +267,15 @@ void *lh_retrieve(LHASH *lh, const void *data)
267 return(ret); 267 return(ret);
268 } 268 }
269 269
270static void doall_util_fn(LHASH *lh, int use_arg, LHASH_DOALL_FN_TYPE func, 270static void doall_util_fn(_LHASH *lh, int use_arg, LHASH_DOALL_FN_TYPE func,
271 LHASH_DOALL_ARG_FN_TYPE func_arg, void *arg) 271 LHASH_DOALL_ARG_FN_TYPE func_arg, void *arg)
272 { 272 {
273 int i; 273 int i;
274 LHASH_NODE *a,*n; 274 LHASH_NODE *a,*n;
275 275
276 if (lh == NULL)
277 return;
278
276 /* reverse the order so we search from 'top to bottom' 279 /* reverse the order so we search from 'top to bottom'
277 * We were having memory leaks otherwise */ 280 * We were having memory leaks otherwise */
278 for (i=lh->num_nodes-1; i>=0; i--) 281 for (i=lh->num_nodes-1; i>=0; i--)
@@ -282,6 +285,8 @@ static void doall_util_fn(LHASH *lh, int use_arg, LHASH_DOALL_FN_TYPE func,
282 { 285 {
283 /* 28/05/91 - eay - n added so items can be deleted 286 /* 28/05/91 - eay - n added so items can be deleted
284 * via lh_doall */ 287 * via lh_doall */
288 /* 22/05/08 - ben - eh? since a is not passed,
289 * this should not be needed */
285 n=a->next; 290 n=a->next;
286 if(use_arg) 291 if(use_arg)
287 func_arg(a->data,arg); 292 func_arg(a->data,arg);
@@ -292,17 +297,17 @@ static void doall_util_fn(LHASH *lh, int use_arg, LHASH_DOALL_FN_TYPE func,
292 } 297 }
293 } 298 }
294 299
295void lh_doall(LHASH *lh, LHASH_DOALL_FN_TYPE func) 300void lh_doall(_LHASH *lh, LHASH_DOALL_FN_TYPE func)
296 { 301 {
297 doall_util_fn(lh, 0, func, (LHASH_DOALL_ARG_FN_TYPE)0, NULL); 302 doall_util_fn(lh, 0, func, (LHASH_DOALL_ARG_FN_TYPE)0, NULL);
298 } 303 }
299 304
300void lh_doall_arg(LHASH *lh, LHASH_DOALL_ARG_FN_TYPE func, void *arg) 305void lh_doall_arg(_LHASH *lh, LHASH_DOALL_ARG_FN_TYPE func, void *arg)
301 { 306 {
302 doall_util_fn(lh, 1, (LHASH_DOALL_FN_TYPE)0, func, arg); 307 doall_util_fn(lh, 1, (LHASH_DOALL_FN_TYPE)0, func, arg);
303 } 308 }
304 309
305static void expand(LHASH *lh) 310static void expand(_LHASH *lh)
306 { 311 {
307 LHASH_NODE **n,**n1,**n2,*np; 312 LHASH_NODE **n,**n1,**n2,*np;
308 unsigned int p,i,j; 313 unsigned int p,i,j;
@@ -358,7 +363,7 @@ static void expand(LHASH *lh)
358 } 363 }
359 } 364 }
360 365
361static void contract(LHASH *lh) 366static void contract(_LHASH *lh)
362 { 367 {
363 LHASH_NODE **n,*n1,*np; 368 LHASH_NODE **n,*n1,*np;
364 369
@@ -397,7 +402,7 @@ static void contract(LHASH *lh)
397 } 402 }
398 } 403 }
399 404
400static LHASH_NODE **getrn(LHASH *lh, const void *data, unsigned long *rhash) 405static LHASH_NODE **getrn(_LHASH *lh, const void *data, unsigned long *rhash)
401 { 406 {
402 LHASH_NODE **ret,*n1; 407 LHASH_NODE **ret,*n1;
403 unsigned long hash,nn; 408 unsigned long hash,nn;
@@ -464,7 +469,7 @@ unsigned long lh_strhash(const char *c)
464 return((ret>>16)^ret); 469 return((ret>>16)^ret);
465 } 470 }
466 471
467unsigned long lh_num_items(const LHASH *lh) 472unsigned long lh_num_items(const _LHASH *lh)
468 { 473 {
469 return lh ? lh->num_items : 0; 474 return lh ? lh->num_items : 0;
470 } 475 }
diff --git a/src/lib/libcrypto/lhash/lhash.h b/src/lib/libcrypto/lhash/lhash.h
index d392d0cd80..e7d8763591 100644
--- a/src/lib/libcrypto/lhash/lhash.h
+++ b/src/lib/libcrypto/lhash/lhash.h
@@ -98,42 +98,42 @@ typedef void (*LHASH_DOALL_ARG_FN_TYPE)(void *, void *);
98 * macros if the functions are strictly internal. */ 98 * macros if the functions are strictly internal. */
99 99
100/* First: "hash" functions */ 100/* First: "hash" functions */
101#define DECLARE_LHASH_HASH_FN(f_name,o_type) \ 101#define DECLARE_LHASH_HASH_FN(name, o_type) \
102 unsigned long f_name##_LHASH_HASH(const void *); 102 unsigned long name##_LHASH_HASH(const void *);
103#define IMPLEMENT_LHASH_HASH_FN(f_name,o_type) \ 103#define IMPLEMENT_LHASH_HASH_FN(name, o_type) \
104 unsigned long f_name##_LHASH_HASH(const void *arg) { \ 104 unsigned long name##_LHASH_HASH(const void *arg) { \
105 o_type a = (o_type)arg; \ 105 const o_type *a = arg; \
106 return f_name(a); } 106 return name##_hash(a); }
107#define LHASH_HASH_FN(f_name) f_name##_LHASH_HASH 107#define LHASH_HASH_FN(name) name##_LHASH_HASH
108 108
109/* Second: "compare" functions */ 109/* Second: "compare" functions */
110#define DECLARE_LHASH_COMP_FN(f_name,o_type) \ 110#define DECLARE_LHASH_COMP_FN(name, o_type) \
111 int f_name##_LHASH_COMP(const void *, const void *); 111 int name##_LHASH_COMP(const void *, const void *);
112#define IMPLEMENT_LHASH_COMP_FN(f_name,o_type) \ 112#define IMPLEMENT_LHASH_COMP_FN(name, o_type) \
113 int f_name##_LHASH_COMP(const void *arg1, const void *arg2) { \ 113 int name##_LHASH_COMP(const void *arg1, const void *arg2) { \
114 o_type a = (o_type)arg1; \ 114 const o_type *a = arg1; \
115 o_type b = (o_type)arg2; \ 115 const o_type *b = arg2; \
116 return f_name(a,b); } 116 return name##_cmp(a,b); }
117#define LHASH_COMP_FN(f_name) f_name##_LHASH_COMP 117#define LHASH_COMP_FN(name) name##_LHASH_COMP
118 118
119/* Third: "doall" functions */ 119/* Third: "doall" functions */
120#define DECLARE_LHASH_DOALL_FN(f_name,o_type) \ 120#define DECLARE_LHASH_DOALL_FN(name, o_type) \
121 void f_name##_LHASH_DOALL(void *); 121 void name##_LHASH_DOALL(void *);
122#define IMPLEMENT_LHASH_DOALL_FN(f_name,o_type) \ 122#define IMPLEMENT_LHASH_DOALL_FN(name, o_type) \
123 void f_name##_LHASH_DOALL(void *arg) { \ 123 void name##_LHASH_DOALL(void *arg) { \
124 o_type a = (o_type)arg; \ 124 o_type *a = arg; \
125 f_name(a); } 125 name##_doall(a); }
126#define LHASH_DOALL_FN(f_name) f_name##_LHASH_DOALL 126#define LHASH_DOALL_FN(name) name##_LHASH_DOALL
127 127
128/* Fourth: "doall_arg" functions */ 128/* Fourth: "doall_arg" functions */
129#define DECLARE_LHASH_DOALL_ARG_FN(f_name,o_type,a_type) \ 129#define DECLARE_LHASH_DOALL_ARG_FN(name, o_type, a_type) \
130 void f_name##_LHASH_DOALL_ARG(void *, void *); 130 void name##_LHASH_DOALL_ARG(void *, void *);
131#define IMPLEMENT_LHASH_DOALL_ARG_FN(f_name,o_type,a_type) \ 131#define IMPLEMENT_LHASH_DOALL_ARG_FN(name, o_type, a_type) \
132 void f_name##_LHASH_DOALL_ARG(void *arg1, void *arg2) { \ 132 void name##_LHASH_DOALL_ARG(void *arg1, void *arg2) { \
133 o_type a = (o_type)arg1; \ 133 o_type *a = arg1; \
134 a_type b = (a_type)arg2; \ 134 a_type *b = arg2; \
135 f_name(a,b); } 135 name##_doall_arg(a, b); }
136#define LHASH_DOALL_ARG_FN(f_name) f_name##_LHASH_DOALL_ARG 136#define LHASH_DOALL_ARG_FN(name) name##_LHASH_DOALL_ARG
137 137
138typedef struct lhash_st 138typedef struct lhash_st
139 { 139 {
@@ -163,7 +163,8 @@ typedef struct lhash_st
163 unsigned long num_hash_comps; 163 unsigned long num_hash_comps;
164 164
165 int error; 165 int error;
166 } LHASH; 166 } _LHASH; /* Do not use _LHASH directly, use LHASH_OF
167 * and friends */
167 168
168#define LH_LOAD_MULT 256 169#define LH_LOAD_MULT 256
169 170
@@ -171,27 +172,67 @@ typedef struct lhash_st
171 * in lh_insert(). */ 172 * in lh_insert(). */
172#define lh_error(lh) ((lh)->error) 173#define lh_error(lh) ((lh)->error)
173 174
174LHASH *lh_new(LHASH_HASH_FN_TYPE h, LHASH_COMP_FN_TYPE c); 175_LHASH *lh_new(LHASH_HASH_FN_TYPE h, LHASH_COMP_FN_TYPE c);
175void lh_free(LHASH *lh); 176void lh_free(_LHASH *lh);
176void *lh_insert(LHASH *lh, void *data); 177void *lh_insert(_LHASH *lh, void *data);
177void *lh_delete(LHASH *lh, const void *data); 178void *lh_delete(_LHASH *lh, const void *data);
178void *lh_retrieve(LHASH *lh, const void *data); 179void *lh_retrieve(_LHASH *lh, const void *data);
179void lh_doall(LHASH *lh, LHASH_DOALL_FN_TYPE func); 180void lh_doall(_LHASH *lh, LHASH_DOALL_FN_TYPE func);
180void lh_doall_arg(LHASH *lh, LHASH_DOALL_ARG_FN_TYPE func, void *arg); 181void lh_doall_arg(_LHASH *lh, LHASH_DOALL_ARG_FN_TYPE func, void *arg);
181unsigned long lh_strhash(const char *c); 182unsigned long lh_strhash(const char *c);
182unsigned long lh_num_items(const LHASH *lh); 183unsigned long lh_num_items(const _LHASH *lh);
183 184
184#ifndef OPENSSL_NO_FP_API 185#ifndef OPENSSL_NO_FP_API
185void lh_stats(const LHASH *lh, FILE *out); 186void lh_stats(const _LHASH *lh, FILE *out);
186void lh_node_stats(const LHASH *lh, FILE *out); 187void lh_node_stats(const _LHASH *lh, FILE *out);
187void lh_node_usage_stats(const LHASH *lh, FILE *out); 188void lh_node_usage_stats(const _LHASH *lh, FILE *out);
188#endif 189#endif
189 190
190#ifndef OPENSSL_NO_BIO 191#ifndef OPENSSL_NO_BIO
191void lh_stats_bio(const LHASH *lh, BIO *out); 192void lh_stats_bio(const _LHASH *lh, BIO *out);
192void lh_node_stats_bio(const LHASH *lh, BIO *out); 193void lh_node_stats_bio(const _LHASH *lh, BIO *out);
193void lh_node_usage_stats_bio(const LHASH *lh, BIO *out); 194void lh_node_usage_stats_bio(const _LHASH *lh, BIO *out);
194#endif 195#endif
196
197/* Type checking... */
198
199#define LHASH_OF(type) struct lhash_st_##type
200
201#define DECLARE_LHASH_OF(type) LHASH_OF(type) { int dummy; }
202
203#define CHECKED_LHASH_OF(type,lh) \
204 ((_LHASH *)CHECKED_PTR_OF(LHASH_OF(type),lh))
205
206/* Define wrapper functions. */
207#define LHM_lh_new(type, name) \
208 ((LHASH_OF(type) *)lh_new(LHASH_HASH_FN(name), LHASH_COMP_FN(name)))
209#define LHM_lh_error(type, lh) \
210 lh_error(CHECKED_LHASH_OF(type,lh))
211#define LHM_lh_insert(type, lh, inst) \
212 ((type *)lh_insert(CHECKED_LHASH_OF(type, lh), \
213 CHECKED_PTR_OF(type, inst)))
214#define LHM_lh_retrieve(type, lh, inst) \
215 ((type *)lh_retrieve(CHECKED_LHASH_OF(type, lh), \
216 CHECKED_PTR_OF(type, inst)))
217#define LHM_lh_delete(type, lh, inst) \
218 ((type *)lh_delete(CHECKED_LHASH_OF(type, lh), \
219 CHECKED_PTR_OF(type, inst)))
220#define LHM_lh_doall(type, lh,fn) lh_doall(CHECKED_LHASH_OF(type, lh), fn)
221#define LHM_lh_doall_arg(type, lh, fn, arg_type, arg) \
222 lh_doall_arg(CHECKED_LHASH_OF(type, lh), fn, CHECKED_PTR_OF(arg_type, arg))
223#define LHM_lh_num_items(type, lh) lh_num_items(CHECKED_LHASH_OF(type, lh))
224#define LHM_lh_down_load(type, lh) (CHECKED_LHASH_OF(type, lh)->down_load)
225#define LHM_lh_node_stats_bio(type, lh, out) \
226 lh_node_stats_bio(CHECKED_LHASH_OF(type, lh), out)
227#define LHM_lh_node_usage_stats_bio(type, lh, out) \
228 lh_node_usage_stats_bio(CHECKED_LHASH_OF(type, lh), out)
229#define LHM_lh_stats_bio(type, lh, out) \
230 lh_stats_bio(CHECKED_LHASH_OF(type, lh), out)
231#define LHM_lh_free(type, lh) lh_free(CHECKED_LHASH_OF(type, lh))
232
233DECLARE_LHASH_OF(OPENSSL_STRING);
234DECLARE_LHASH_OF(OPENSSL_CSTRING);
235
195#ifdef __cplusplus 236#ifdef __cplusplus
196} 237}
197#endif 238#endif
diff --git a/src/lib/libcrypto/md32_common.h b/src/lib/libcrypto/md32_common.h
index 61bcd9786f..1cb783944e 100644
--- a/src/lib/libcrypto/md32_common.h
+++ b/src/lib/libcrypto/md32_common.h
@@ -241,11 +241,11 @@
241#ifndef PEDANTIC 241#ifndef PEDANTIC
242# if defined(__GNUC__) && __GNUC__>=2 && !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM) 242# if defined(__GNUC__) && __GNUC__>=2 && !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM)
243# if defined(__s390x__) 243# if defined(__s390x__)
244# define HOST_c2l(c,l) ({ asm ("lrv %0,0(%1)" \ 244# define HOST_c2l(c,l) ({ asm ("lrv %0,%1" \
245 :"=r"(l) : "r"(c)); \ 245 :"=d"(l) :"m"(*(const unsigned int *)(c)));\
246 (c)+=4; (l); }) 246 (c)+=4; (l); })
247# define HOST_l2c(l,c) ({ asm ("strv %0,0(%1)" \ 247# define HOST_l2c(l,c) ({ asm ("strv %1,%0" \
248 : : "r"(l),"r"(c) : "memory"); \ 248 :"=m"(*(unsigned int *)(c)) :"d"(l));\
249 (c)+=4; (l); }) 249 (c)+=4; (l); })
250# endif 250# endif
251# endif 251# endif
@@ -293,7 +293,7 @@ int HASH_UPDATE (HASH_CTX *c, const void *data_, size_t len)
293 * Wei Dai <weidai@eskimo.com> for pointing it out. */ 293 * Wei Dai <weidai@eskimo.com> for pointing it out. */
294 if (l < c->Nl) /* overflow */ 294 if (l < c->Nl) /* overflow */
295 c->Nh++; 295 c->Nh++;
296 c->Nh+=(len>>29); /* might cause compiler warning on 16-bit */ 296 c->Nh+=(HASH_LONG)(len>>29); /* might cause compiler warning on 16-bit */
297 c->Nl=l; 297 c->Nl=l;
298 298
299 n = c->num; 299 n = c->num;
@@ -331,7 +331,7 @@ int HASH_UPDATE (HASH_CTX *c, const void *data_, size_t len)
331 if (len != 0) 331 if (len != 0)
332 { 332 {
333 p = (unsigned char *)c->data; 333 p = (unsigned char *)c->data;
334 c->num = len; 334 c->num = (unsigned int)len;
335 memcpy (p,data,len); 335 memcpy (p,data,len);
336 } 336 }
337 return 1; 337 return 1;
diff --git a/src/lib/libcrypto/md4/md4.h b/src/lib/libcrypto/md4/md4.h
index ba1fe4a6ee..c3ed9b3f75 100644
--- a/src/lib/libcrypto/md4/md4.h
+++ b/src/lib/libcrypto/md4/md4.h
@@ -77,7 +77,7 @@ extern "C" {
77 * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 77 * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
78 */ 78 */
79 79
80#if defined(OPENSSL_SYS_WIN16) || defined(__LP32__) 80#if defined(__LP32__)
81#define MD4_LONG unsigned long 81#define MD4_LONG unsigned long
82#elif defined(OPENSSL_SYS_CRAY) || defined(__ILP64__) 82#elif defined(OPENSSL_SYS_CRAY) || defined(__ILP64__)
83#define MD4_LONG unsigned long 83#define MD4_LONG unsigned long
@@ -105,9 +105,6 @@ typedef struct MD4state_st
105 unsigned int num; 105 unsigned int num;
106 } MD4_CTX; 106 } MD4_CTX;
107 107
108#ifdef OPENSSL_FIPS
109int private_MD4_Init(MD4_CTX *c);
110#endif
111int MD4_Init(MD4_CTX *c); 108int MD4_Init(MD4_CTX *c);
112int MD4_Update(MD4_CTX *c, const void *data, size_t len); 109int MD4_Update(MD4_CTX *c, const void *data, size_t len);
113int MD4_Final(unsigned char *md, MD4_CTX *c); 110int 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 0f5448601d..e0c42e8596 100644
--- a/src/lib/libcrypto/md4/md4_dgst.c
+++ b/src/lib/libcrypto/md4/md4_dgst.c
@@ -59,11 +59,6 @@
59#include <stdio.h> 59#include <stdio.h>
60#include "md4_locl.h" 60#include "md4_locl.h"
61#include <openssl/opensslv.h> 61#include <openssl/opensslv.h>
62#include <openssl/err.h>
63#ifdef OPENSSL_FIPS
64#include <openssl/fips.h>
65#endif
66
67 62
68const char MD4_version[]="MD4" OPENSSL_VERSION_PTEXT; 63const char MD4_version[]="MD4" OPENSSL_VERSION_PTEXT;
69 64
@@ -75,15 +70,13 @@ const char MD4_version[]="MD4" OPENSSL_VERSION_PTEXT;
75#define INIT_DATA_C (unsigned long)0x98badcfeL 70#define INIT_DATA_C (unsigned long)0x98badcfeL
76#define INIT_DATA_D (unsigned long)0x10325476L 71#define INIT_DATA_D (unsigned long)0x10325476L
77 72
78FIPS_NON_FIPS_MD_Init(MD4) 73int MD4_Init(MD4_CTX *c)
79 { 74 {
75 memset (c,0,sizeof(*c));
80 c->A=INIT_DATA_A; 76 c->A=INIT_DATA_A;
81 c->B=INIT_DATA_B; 77 c->B=INIT_DATA_B;
82 c->C=INIT_DATA_C; 78 c->C=INIT_DATA_C;
83 c->D=INIT_DATA_D; 79 c->D=INIT_DATA_D;
84 c->Nl=0;
85 c->Nh=0;
86 c->num=0;
87 return 1; 80 return 1;
88 } 81 }
89 82
diff --git a/src/lib/libcrypto/md5/asm/md5-586.pl b/src/lib/libcrypto/md5/asm/md5-586.pl
index 76ac235f7d..6cb66bb499 100644
--- a/src/lib/libcrypto/md5/asm/md5-586.pl
+++ b/src/lib/libcrypto/md5/asm/md5-586.pl
@@ -7,7 +7,8 @@
7 7
8$normal=0; 8$normal=0;
9 9
10push(@INC,"perlasm","../../perlasm"); 10$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
11push(@INC,"${dir}","${dir}../../perlasm");
11require "x86asm.pl"; 12require "x86asm.pl";
12 13
13&asm_init($ARGV[0],$0); 14&asm_init($ARGV[0],$0);
diff --git a/src/lib/libcrypto/md5/asm/md5-ia64.S b/src/lib/libcrypto/md5/asm/md5-ia64.S
new file mode 100644
index 0000000000..e7de08d46a
--- /dev/null
+++ b/src/lib/libcrypto/md5/asm/md5-ia64.S
@@ -0,0 +1,992 @@
1/* Copyright (c) 2005 Hewlett-Packard Development Company, L.P.
2
3Permission is hereby granted, free of charge, to any person obtaining
4a copy of this software and associated documentation files (the
5"Software"), to deal in the Software without restriction, including
6without limitation the rights to use, copy, modify, merge, publish,
7distribute, sublicense, and/or sell copies of the Software, and to
8permit persons to whom the Software is furnished to do so, subject to
9the following conditions:
10
11The above copyright notice and this permission notice shall be
12included in all copies or substantial portions of the Software.
13
14THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
21
22// Common registers are assigned as follows:
23//
24// COMMON
25//
26// t0 Const Tbl Ptr TPtr
27// t1 Round Constant TRound
28// t4 Block residual LenResid
29// t5 Residual Data DTmp
30//
31// {in,out}0 Block 0 Cycle RotateM0
32// {in,out}1 Block Value 12 M12
33// {in,out}2 Block Value 8 M8
34// {in,out}3 Block Value 4 M4
35// {in,out}4 Block Value 0 M0
36// {in,out}5 Block 1 Cycle RotateM1
37// {in,out}6 Block Value 13 M13
38// {in,out}7 Block Value 9 M9
39// {in,out}8 Block Value 5 M5
40// {in,out}9 Block Value 1 M1
41// {in,out}10 Block 2 Cycle RotateM2
42// {in,out}11 Block Value 14 M14
43// {in,out}12 Block Value 10 M10
44// {in,out}13 Block Value 6 M6
45// {in,out}14 Block Value 2 M2
46// {in,out}15 Block 3 Cycle RotateM3
47// {in,out}16 Block Value 15 M15
48// {in,out}17 Block Value 11 M11
49// {in,out}18 Block Value 7 M7
50// {in,out}19 Block Value 3 M3
51// {in,out}20 Scratch Z
52// {in,out}21 Scratch Y
53// {in,out}22 Scratch X
54// {in,out}23 Scratch W
55// {in,out}24 Digest A A
56// {in,out}25 Digest B B
57// {in,out}26 Digest C C
58// {in,out}27 Digest D D
59// {in,out}28 Active Data Ptr DPtr
60// in28 Dummy Value -
61// out28 Dummy Value -
62// bt0 Coroutine Link QUICK_RTN
63//
64/// These predicates are used for computing the padding block(s) and
65/// are shared between the driver and digest co-routines
66//
67// pt0 Extra Pad Block pExtra
68// pt1 Load next word pLoad
69// pt2 Skip next word pSkip
70// pt3 Search for Pad pNoPad
71// pt4 Pad Word 0 pPad0
72// pt5 Pad Word 1 pPad1
73// pt6 Pad Word 2 pPad2
74// pt7 Pad Word 3 pPad3
75
76#define DTmp r19
77#define LenResid r18
78#define QUICK_RTN b6
79#define TPtr r14
80#define TRound r15
81#define pExtra p6
82#define pLoad p7
83#define pNoPad p9
84#define pPad0 p10
85#define pPad1 p11
86#define pPad2 p12
87#define pPad3 p13
88#define pSkip p8
89
90#define A_ out24
91#define B_ out25
92#define C_ out26
93#define D_ out27
94#define DPtr_ out28
95#define M0_ out4
96#define M1_ out9
97#define M10_ out12
98#define M11_ out17
99#define M12_ out1
100#define M13_ out6
101#define M14_ out11
102#define M15_ out16
103#define M2_ out14
104#define M3_ out19
105#define M4_ out3
106#define M5_ out8
107#define M6_ out13
108#define M7_ out18
109#define M8_ out2
110#define M9_ out7
111#define RotateM0_ out0
112#define RotateM1_ out5
113#define RotateM2_ out10
114#define RotateM3_ out15
115#define W_ out23
116#define X_ out22
117#define Y_ out21
118#define Z_ out20
119
120#define A in24
121#define B in25
122#define C in26
123#define D in27
124#define DPtr in28
125#define M0 in4
126#define M1 in9
127#define M10 in12
128#define M11 in17
129#define M12 in1
130#define M13 in6
131#define M14 in11
132#define M15 in16
133#define M2 in14
134#define M3 in19
135#define M4 in3
136#define M5 in8
137#define M6 in13
138#define M7 in18
139#define M8 in2
140#define M9 in7
141#define RotateM0 in0
142#define RotateM1 in5
143#define RotateM2 in10
144#define RotateM3 in15
145#define W in23
146#define X in22
147#define Y in21
148#define Z in20
149
150/* register stack configuration for md5_block_asm_data_order(): */
151#define MD5_NINP 3
152#define MD5_NLOC 0
153#define MD5_NOUT 29
154#define MD5_NROT 0
155
156/* register stack configuration for helpers: */
157#define _NINPUTS MD5_NOUT
158#define _NLOCALS 0
159#define _NOUTPUT 0
160#define _NROTATE 24 /* this must be <= _NINPUTS */
161
162#if defined(_HPUX_SOURCE) && !defined(_LP64)
163#define ADDP addp4
164#else
165#define ADDP add
166#endif
167
168#if defined(_HPUX_SOURCE) || defined(B_ENDIAN)
169#define HOST_IS_BIG_ENDIAN
170#endif
171
172// Macros for getting the left and right portions of little-endian words
173
174#define GETLW(dst, src, align) dep.z dst = src, 32 - 8 * align, 8 * align
175#define GETRW(dst, src, align) extr.u dst = src, 8 * align, 32 - 8 * align
176
177// MD5 driver
178//
179// Reads an input block, then calls the digest block
180// subroutine and adds the results to the accumulated
181// digest. It allocates 32 outs which the subroutine
182// uses as it's inputs and rotating
183// registers. Initializes the round constant pointer and
184// takes care of saving/restoring ar.lc
185//
186/// INPUT
187//
188// in0 Context Ptr CtxPtr0
189// in1 Input Data Ptr DPtrIn
190// in2 Integral Blocks BlockCount
191// rp Return Address -
192//
193/// CODE
194//
195// v2 Input Align InAlign
196// t0 Shared w/digest -
197// t1 Shared w/digest -
198// t2 Shared w/digest -
199// t3 Shared w/digest -
200// t4 Shared w/digest -
201// t5 Shared w/digest -
202// t6 PFS Save PFSSave
203// t7 ar.lc Save LCSave
204// t8 Saved PR PRSave
205// t9 2nd CtxPtr CtxPtr1
206// t10 Table Base CTable
207// t11 Table[0] CTable0
208// t13 Accumulator A AccumA
209// t14 Accumulator B AccumB
210// t15 Accumulator C AccumC
211// t16 Accumulator D AccumD
212// pt0 Shared w/digest -
213// pt1 Shared w/digest -
214// pt2 Shared w/digest -
215// pt3 Shared w/digest -
216// pt4 Shared w/digest -
217// pt5 Shared w/digest -
218// pt6 Shared w/digest -
219// pt7 Shared w/digest -
220// pt8 Not Aligned pOff
221// pt8 Blocks Left pAgain
222
223#define AccumA r27
224#define AccumB r28
225#define AccumC r29
226#define AccumD r30
227#define CTable r24
228#define CTable0 r25
229#define CtxPtr0 in0
230#define CtxPtr1 r23
231#define DPtrIn in1
232#define BlockCount in2
233#define InAlign r10
234#define LCSave r21
235#define PFSSave r20
236#define PRSave r22
237#define pAgain p63
238#define pOff p63
239
240 .text
241
242/* md5_block_asm_data_order(MD5_CTX *c, const void *data, size_t num)
243
244 where:
245 c: a pointer to a structure of this type:
246
247 typedef struct MD5state_st
248 {
249 MD5_LONG A,B,C,D;
250 MD5_LONG Nl,Nh;
251 MD5_LONG data[MD5_LBLOCK];
252 unsigned int num;
253 }
254 MD5_CTX;
255
256 data: a pointer to the input data (may be misaligned)
257 num: the number of 16-byte blocks to hash (i.e., the length
258 of DATA is 16*NUM.
259
260 */
261
262 .type md5_block_asm_data_order, @function
263 .global md5_block_asm_data_order
264 .align 32
265 .proc md5_block_asm_data_order
266md5_block_asm_data_order:
267.md5_block:
268 .prologue
269{ .mmi
270 .save ar.pfs, PFSSave
271 alloc PFSSave = ar.pfs, MD5_NINP, MD5_NLOC, MD5_NOUT, MD5_NROT
272 ADDP CtxPtr1 = 8, CtxPtr0
273 mov CTable = ip
274}
275{ .mmi
276 ADDP DPtrIn = 0, DPtrIn
277 ADDP CtxPtr0 = 0, CtxPtr0
278 .save ar.lc, LCSave
279 mov LCSave = ar.lc
280}
281;;
282{ .mmi
283 add CTable = .md5_tbl_data_order#-.md5_block#, CTable
284 and InAlign = 0x3, DPtrIn
285}
286
287{ .mmi
288 ld4 AccumA = [CtxPtr0], 4
289 ld4 AccumC = [CtxPtr1], 4
290 .save pr, PRSave
291 mov PRSave = pr
292 .body
293}
294;;
295{ .mmi
296 ld4 AccumB = [CtxPtr0]
297 ld4 AccumD = [CtxPtr1]
298 dep DPtr_ = 0, DPtrIn, 0, 2
299} ;;
300#ifdef HOST_IS_BIG_ENDIAN
301 rum psr.be;; // switch to little-endian
302#endif
303{ .mmb
304 ld4 CTable0 = [CTable], 4
305 cmp.ne pOff, p0 = 0, InAlign
306(pOff) br.cond.spnt.many .md5_unaligned
307} ;;
308
309// The FF load/compute loop rotates values three times, so that
310// loading into M12 here produces the M0 value, M13 -> M1, etc.
311
312.md5_block_loop0:
313{ .mmi
314 ld4 M12_ = [DPtr_], 4
315 mov TPtr = CTable
316 mov TRound = CTable0
317} ;;
318{ .mmi
319 ld4 M13_ = [DPtr_], 4
320 mov A_ = AccumA
321 mov B_ = AccumB
322} ;;
323{ .mmi
324 ld4 M14_ = [DPtr_], 4
325 mov C_ = AccumC
326 mov D_ = AccumD
327} ;;
328{ .mmb
329 ld4 M15_ = [DPtr_], 4
330 add BlockCount = -1, BlockCount
331 br.call.sptk.many QUICK_RTN = md5_digest_block0
332} ;;
333
334// Now, we add the new digest values and do some clean-up
335// before checking if there's another full block to process
336
337{ .mmi
338 add AccumA = AccumA, A_
339 add AccumB = AccumB, B_
340 cmp.ne pAgain, p0 = 0, BlockCount
341}
342{ .mib
343 add AccumC = AccumC, C_
344 add AccumD = AccumD, D_
345(pAgain) br.cond.dptk.many .md5_block_loop0
346} ;;
347
348.md5_exit:
349#ifdef HOST_IS_BIG_ENDIAN
350 sum psr.be;; // switch back to big-endian mode
351#endif
352{ .mmi
353 st4 [CtxPtr0] = AccumB, -4
354 st4 [CtxPtr1] = AccumD, -4
355 mov pr = PRSave, 0x1ffff ;;
356}
357{ .mmi
358 st4 [CtxPtr0] = AccumA
359 st4 [CtxPtr1] = AccumC
360 mov ar.lc = LCSave
361} ;;
362{ .mib
363 mov ar.pfs = PFSSave
364 br.ret.sptk.few rp
365} ;;
366
367#define MD5UNALIGNED(offset) \
368.md5_process##offset: \
369{ .mib ; \
370 nop 0x0 ; \
371 GETRW(DTmp, DTmp, offset) ; \
372} ;; \
373.md5_block_loop##offset: \
374{ .mmi ; \
375 ld4 Y_ = [DPtr_], 4 ; \
376 mov TPtr = CTable ; \
377 mov TRound = CTable0 ; \
378} ;; \
379{ .mmi ; \
380 ld4 M13_ = [DPtr_], 4 ; \
381 mov A_ = AccumA ; \
382 mov B_ = AccumB ; \
383} ;; \
384{ .mii ; \
385 ld4 M14_ = [DPtr_], 4 ; \
386 GETLW(W_, Y_, offset) ; \
387 mov C_ = AccumC ; \
388} \
389{ .mmi ; \
390 mov D_ = AccumD ;; \
391 or M12_ = W_, DTmp ; \
392 GETRW(DTmp, Y_, offset) ; \
393} \
394{ .mib ; \
395 ld4 M15_ = [DPtr_], 4 ; \
396 add BlockCount = -1, BlockCount ; \
397 br.call.sptk.many QUICK_RTN = md5_digest_block##offset; \
398} ;; \
399{ .mmi ; \
400 add AccumA = AccumA, A_ ; \
401 add AccumB = AccumB, B_ ; \
402 cmp.ne pAgain, p0 = 0, BlockCount ; \
403} \
404{ .mib ; \
405 add AccumC = AccumC, C_ ; \
406 add AccumD = AccumD, D_ ; \
407(pAgain) br.cond.dptk.many .md5_block_loop##offset ; \
408} ;; \
409{ .mib ; \
410 nop 0x0 ; \
411 nop 0x0 ; \
412 br.cond.sptk.many .md5_exit ; \
413} ;;
414
415 .align 32
416.md5_unaligned:
417//
418// Because variable shifts are expensive, we special case each of
419// the four alignements. In practice, this won't hurt too much
420// since only one working set of code will be loaded.
421//
422{ .mib
423 ld4 DTmp = [DPtr_], 4
424 cmp.eq pOff, p0 = 1, InAlign
425(pOff) br.cond.dpnt.many .md5_process1
426} ;;
427{ .mib
428 cmp.eq pOff, p0 = 2, InAlign
429 nop 0x0
430(pOff) br.cond.dpnt.many .md5_process2
431} ;;
432 MD5UNALIGNED(3)
433 MD5UNALIGNED(1)
434 MD5UNALIGNED(2)
435
436 .endp md5_block_asm_data_order
437
438
439// MD5 Perform the F function and load
440//
441// Passed the first 4 words (M0 - M3) and initial (A, B, C, D) values,
442// computes the FF() round of functions, then branches to the common
443// digest code to finish up with GG(), HH, and II().
444//
445// INPUT
446//
447// rp Return Address -
448//
449// CODE
450//
451// v0 PFS bit bucket PFS
452// v1 Loop Trip Count LTrip
453// pt0 Load next word pMore
454
455/* For F round: */
456#define LTrip r9
457#define PFS r8
458#define pMore p6
459
460/* For GHI rounds: */
461#define T r9
462#define U r10
463#define V r11
464
465#define COMPUTE(a, b, s, M, R) \
466{ \
467 .mii ; \
468 ld4 TRound = [TPtr], 4 ; \
469 dep.z Y = Z, 32, 32 ;; \
470 shrp Z = Z, Y, 64 - s ; \
471} ;; \
472{ \
473 .mmi ; \
474 add a = Z, b ; \
475 mov R = M ; \
476 nop 0x0 ; \
477} ;;
478
479#define LOOP(a, b, s, M, R, label) \
480{ .mii ; \
481 ld4 TRound = [TPtr], 4 ; \
482 dep.z Y = Z, 32, 32 ;; \
483 shrp Z = Z, Y, 64 - s ; \
484} ;; \
485{ .mib ; \
486 add a = Z, b ; \
487 mov R = M ; \
488 br.ctop.sptk.many label ; \
489} ;;
490
491// G(B, C, D) = (B & D) | (C & ~D)
492
493#define G(a, b, c, d, M) \
494{ .mmi ; \
495 add Z = M, TRound ; \
496 and Y = b, d ; \
497 andcm X = c, d ; \
498} ;; \
499{ .mii ; \
500 add Z = Z, a ; \
501 or Y = Y, X ;; \
502 add Z = Z, Y ; \
503} ;;
504
505// H(B, C, D) = B ^ C ^ D
506
507#define H(a, b, c, d, M) \
508{ .mmi ; \
509 add Z = M, TRound ; \
510 xor Y = b, c ; \
511 nop 0x0 ; \
512} ;; \
513{ .mii ; \
514 add Z = Z, a ; \
515 xor Y = Y, d ;; \
516 add Z = Z, Y ; \
517} ;;
518
519// I(B, C, D) = C ^ (B | ~D)
520//
521// However, since we have an andcm operator, we use the fact that
522//
523// Y ^ Z == ~Y ^ ~Z
524//
525// to rewrite the expression as
526//
527// I(B, C, D) = ~C ^ (~B & D)
528
529#define I(a, b, c, d, M) \
530{ .mmi ; \
531 add Z = M, TRound ; \
532 andcm Y = d, b ; \
533 andcm X = -1, c ; \
534} ;; \
535{ .mii ; \
536 add Z = Z, a ; \
537 xor Y = Y, X ;; \
538 add Z = Z, Y ; \
539} ;;
540
541#define GG4(label) \
542 G(A, B, C, D, M0) \
543 COMPUTE(A, B, 5, M0, RotateM0) \
544 G(D, A, B, C, M1) \
545 COMPUTE(D, A, 9, M1, RotateM1) \
546 G(C, D, A, B, M2) \
547 COMPUTE(C, D, 14, M2, RotateM2) \
548 G(B, C, D, A, M3) \
549 LOOP(B, C, 20, M3, RotateM3, label)
550
551#define HH4(label) \
552 H(A, B, C, D, M0) \
553 COMPUTE(A, B, 4, M0, RotateM0) \
554 H(D, A, B, C, M1) \
555 COMPUTE(D, A, 11, M1, RotateM1) \
556 H(C, D, A, B, M2) \
557 COMPUTE(C, D, 16, M2, RotateM2) \
558 H(B, C, D, A, M3) \
559 LOOP(B, C, 23, M3, RotateM3, label)
560
561#define II4(label) \
562 I(A, B, C, D, M0) \
563 COMPUTE(A, B, 6, M0, RotateM0) \
564 I(D, A, B, C, M1) \
565 COMPUTE(D, A, 10, M1, RotateM1) \
566 I(C, D, A, B, M2) \
567 COMPUTE(C, D, 15, M2, RotateM2) \
568 I(B, C, D, A, M3) \
569 LOOP(B, C, 21, M3, RotateM3, label)
570
571#define FFLOAD(a, b, c, d, M, N, s) \
572{ .mii ; \
573(pMore) ld4 N = [DPtr], 4 ; \
574 add Z = M, TRound ; \
575 and Y = c, b ; \
576} \
577{ .mmi ; \
578 andcm X = d, b ;; \
579 add Z = Z, a ; \
580 or Y = Y, X ; \
581} ;; \
582{ .mii ; \
583 ld4 TRound = [TPtr], 4 ; \
584 add Z = Z, Y ;; \
585 dep.z Y = Z, 32, 32 ; \
586} ;; \
587{ .mii ; \
588 nop 0x0 ; \
589 shrp Z = Z, Y, 64 - s ;; \
590 add a = Z, b ; \
591} ;;
592
593#define FFLOOP(a, b, c, d, M, N, s, dest) \
594{ .mii ; \
595(pMore) ld4 N = [DPtr], 4 ; \
596 add Z = M, TRound ; \
597 and Y = c, b ; \
598} \
599{ .mmi ; \
600 andcm X = d, b ;; \
601 add Z = Z, a ; \
602 or Y = Y, X ; \
603} ;; \
604{ .mii ; \
605 ld4 TRound = [TPtr], 4 ; \
606 add Z = Z, Y ;; \
607 dep.z Y = Z, 32, 32 ; \
608} ;; \
609{ .mii ; \
610 nop 0x0 ; \
611 shrp Z = Z, Y, 64 - s ;; \
612 add a = Z, b ; \
613} \
614{ .mib ; \
615 cmp.ne pMore, p0 = 0, LTrip ; \
616 add LTrip = -1, LTrip ; \
617 br.ctop.dptk.many dest ; \
618} ;;
619
620 .type md5_digest_block0, @function
621 .align 32
622
623 .proc md5_digest_block0
624 .prologue
625md5_digest_block0:
626 .altrp QUICK_RTN
627 .body
628{ .mmi
629 alloc PFS = ar.pfs, _NINPUTS, _NLOCALS, _NOUTPUT, _NROTATE
630 mov LTrip = 2
631 mov ar.lc = 3
632} ;;
633{ .mii
634 cmp.eq pMore, p0 = r0, r0
635 mov ar.ec = 0
636 nop 0x0
637} ;;
638
639.md5_FF_round0:
640 FFLOAD(A, B, C, D, M12, RotateM0, 7)
641 FFLOAD(D, A, B, C, M13, RotateM1, 12)
642 FFLOAD(C, D, A, B, M14, RotateM2, 17)
643 FFLOOP(B, C, D, A, M15, RotateM3, 22, .md5_FF_round0)
644 //
645 // !!! Fall through to md5_digest_GHI
646 //
647 .endp md5_digest_block0
648
649 .type md5_digest_GHI, @function
650 .align 32
651
652 .proc md5_digest_GHI
653 .prologue
654 .regstk _NINPUTS, _NLOCALS, _NOUTPUT, _NROTATE
655md5_digest_GHI:
656 .altrp QUICK_RTN
657 .body
658//
659// The following sequence shuffles the block counstants round for the
660// next round:
661//
662// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
663// 1 6 11 0 5 10 14 4 9 14 3 8 13 2 7 12
664//
665{ .mmi
666 mov Z = M0
667 mov Y = M15
668 mov ar.lc = 3
669}
670{ .mmi
671 mov X = M2
672 mov W = M9
673 mov V = M4
674} ;;
675
676{ .mmi
677 mov M0 = M1
678 mov M15 = M12
679 mov ar.ec = 1
680}
681{ .mmi
682 mov M2 = M11
683 mov M9 = M14
684 mov M4 = M5
685} ;;
686
687{ .mmi
688 mov M1 = M6
689 mov M12 = M13
690 mov U = M3
691}
692{ .mmi
693 mov M11 = M8
694 mov M14 = M7
695 mov M5 = M10
696} ;;
697
698{ .mmi
699 mov M6 = Y
700 mov M13 = X
701 mov M3 = Z
702}
703{ .mmi
704 mov M8 = W
705 mov M7 = V
706 mov M10 = U
707} ;;
708
709.md5_GG_round:
710 GG4(.md5_GG_round)
711
712// The following sequence shuffles the block constants round for the
713// next round:
714//
715// 1 6 11 0 5 10 14 4 9 14 3 8 13 2 7 12
716// 5 8 11 14 1 4 7 10 13 0 3 6 9 12 15 2
717
718{ .mmi
719 mov Z = M0
720 mov Y = M1
721 mov ar.lc = 3
722}
723{ .mmi
724 mov X = M3
725 mov W = M5
726 mov V = M6
727} ;;
728
729{ .mmi
730 mov M0 = M4
731 mov M1 = M11
732 mov ar.ec = 1
733}
734{ .mmi
735 mov M3 = M9
736 mov U = M8
737 mov T = M13
738} ;;
739
740{ .mmi
741 mov M4 = Z
742 mov M11 = Y
743 mov M5 = M7
744}
745{ .mmi
746 mov M6 = M14
747 mov M8 = M12
748 mov M13 = M15
749} ;;
750
751{ .mmi
752 mov M7 = W
753 mov M14 = V
754 nop 0x0
755}
756{ .mmi
757 mov M9 = X
758 mov M12 = U
759 mov M15 = T
760} ;;
761
762.md5_HH_round:
763 HH4(.md5_HH_round)
764
765// The following sequence shuffles the block constants round for the
766// next round:
767//
768// 5 8 11 14 1 4 7 10 13 0 3 6 9 12 15 2
769// 0 7 14 5 12 3 10 1 8 15 6 13 4 11 2 9
770
771{ .mmi
772 mov Z = M0
773 mov Y = M15
774 mov ar.lc = 3
775}
776{ .mmi
777 mov X = M10
778 mov W = M1
779 mov V = M4
780} ;;
781
782{ .mmi
783 mov M0 = M9
784 mov M15 = M12
785 mov ar.ec = 1
786}
787{ .mmi
788 mov M10 = M11
789 mov M1 = M6
790 mov M4 = M13
791} ;;
792
793{ .mmi
794 mov M9 = M14
795 mov M12 = M5
796 mov U = M3
797}
798{ .mmi
799 mov M11 = M8
800 mov M6 = M7
801 mov M13 = M2
802} ;;
803
804{ .mmi
805 mov M14 = Y
806 mov M5 = X
807 mov M3 = Z
808}
809{ .mmi
810 mov M8 = W
811 mov M7 = V
812 mov M2 = U
813} ;;
814
815.md5_II_round:
816 II4(.md5_II_round)
817
818{ .mib
819 nop 0x0
820 nop 0x0
821 br.ret.sptk.many QUICK_RTN
822} ;;
823
824 .endp md5_digest_GHI
825
826#define FFLOADU(a, b, c, d, M, P, N, s, offset) \
827{ .mii ; \
828(pMore) ld4 N = [DPtr], 4 ; \
829 add Z = M, TRound ; \
830 and Y = c, b ; \
831} \
832{ .mmi ; \
833 andcm X = d, b ;; \
834 add Z = Z, a ; \
835 or Y = Y, X ; \
836} ;; \
837{ .mii ; \
838 ld4 TRound = [TPtr], 4 ; \
839 GETLW(W, P, offset) ; \
840 add Z = Z, Y ; \
841} ;; \
842{ .mii ; \
843 or W = W, DTmp ; \
844 dep.z Y = Z, 32, 32 ;; \
845 shrp Z = Z, Y, 64 - s ; \
846} ;; \
847{ .mii ; \
848 add a = Z, b ; \
849 GETRW(DTmp, P, offset) ; \
850 mov P = W ; \
851} ;;
852
853#define FFLOOPU(a, b, c, d, M, P, N, s, offset) \
854{ .mii ; \
855(pMore) ld4 N = [DPtr], 4 ; \
856 add Z = M, TRound ; \
857 and Y = c, b ; \
858} \
859{ .mmi ; \
860 andcm X = d, b ;; \
861 add Z = Z, a ; \
862 or Y = Y, X ; \
863} ;; \
864{ .mii ; \
865 ld4 TRound = [TPtr], 4 ; \
866(pMore) GETLW(W, P, offset) ; \
867 add Z = Z, Y ; \
868} ;; \
869{ .mii ; \
870(pMore) or W = W, DTmp ; \
871 dep.z Y = Z, 32, 32 ;; \
872 shrp Z = Z, Y, 64 - s ; \
873} ;; \
874{ .mii ; \
875 add a = Z, b ; \
876(pMore) GETRW(DTmp, P, offset) ; \
877(pMore) mov P = W ; \
878} \
879{ .mib ; \
880 cmp.ne pMore, p0 = 0, LTrip ; \
881 add LTrip = -1, LTrip ; \
882 br.ctop.sptk.many .md5_FF_round##offset ; \
883} ;;
884
885#define MD5FBLOCK(offset) \
886 .type md5_digest_block##offset, @function ; \
887 \
888 .align 32 ; \
889 .proc md5_digest_block##offset ; \
890 .prologue ; \
891 .altrp QUICK_RTN ; \
892 .body ; \
893md5_digest_block##offset: \
894{ .mmi ; \
895 alloc PFS = ar.pfs, _NINPUTS, _NLOCALS, _NOUTPUT, _NROTATE ; \
896 mov LTrip = 2 ; \
897 mov ar.lc = 3 ; \
898} ;; \
899{ .mii ; \
900 cmp.eq pMore, p0 = r0, r0 ; \
901 mov ar.ec = 0 ; \
902 nop 0x0 ; \
903} ;; \
904 \
905 .pred.rel "mutex", pLoad, pSkip ; \
906.md5_FF_round##offset: \
907 FFLOADU(A, B, C, D, M12, M13, RotateM0, 7, offset) \
908 FFLOADU(D, A, B, C, M13, M14, RotateM1, 12, offset) \
909 FFLOADU(C, D, A, B, M14, M15, RotateM2, 17, offset) \
910 FFLOOPU(B, C, D, A, M15, RotateM0, RotateM3, 22, offset) \
911 \
912{ .mib ; \
913 nop 0x0 ; \
914 nop 0x0 ; \
915 br.cond.sptk.many md5_digest_GHI ; \
916} ;; \
917 .endp md5_digest_block##offset
918
919MD5FBLOCK(1)
920MD5FBLOCK(2)
921MD5FBLOCK(3)
922
923 .align 64
924 .type md5_constants, @object
925md5_constants:
926.md5_tbl_data_order: // To ensure little-endian data
927 // order, code as bytes.
928 data1 0x78, 0xa4, 0x6a, 0xd7 // 0
929 data1 0x56, 0xb7, 0xc7, 0xe8 // 1
930 data1 0xdb, 0x70, 0x20, 0x24 // 2
931 data1 0xee, 0xce, 0xbd, 0xc1 // 3
932 data1 0xaf, 0x0f, 0x7c, 0xf5 // 4
933 data1 0x2a, 0xc6, 0x87, 0x47 // 5
934 data1 0x13, 0x46, 0x30, 0xa8 // 6
935 data1 0x01, 0x95, 0x46, 0xfd // 7
936 data1 0xd8, 0x98, 0x80, 0x69 // 8
937 data1 0xaf, 0xf7, 0x44, 0x8b // 9
938 data1 0xb1, 0x5b, 0xff, 0xff // 10
939 data1 0xbe, 0xd7, 0x5c, 0x89 // 11
940 data1 0x22, 0x11, 0x90, 0x6b // 12
941 data1 0x93, 0x71, 0x98, 0xfd // 13
942 data1 0x8e, 0x43, 0x79, 0xa6 // 14
943 data1 0x21, 0x08, 0xb4, 0x49 // 15
944 data1 0x62, 0x25, 0x1e, 0xf6 // 16
945 data1 0x40, 0xb3, 0x40, 0xc0 // 17
946 data1 0x51, 0x5a, 0x5e, 0x26 // 18
947 data1 0xaa, 0xc7, 0xb6, 0xe9 // 19
948 data1 0x5d, 0x10, 0x2f, 0xd6 // 20
949 data1 0x53, 0x14, 0x44, 0x02 // 21
950 data1 0x81, 0xe6, 0xa1, 0xd8 // 22
951 data1 0xc8, 0xfb, 0xd3, 0xe7 // 23
952 data1 0xe6, 0xcd, 0xe1, 0x21 // 24
953 data1 0xd6, 0x07, 0x37, 0xc3 // 25
954 data1 0x87, 0x0d, 0xd5, 0xf4 // 26
955 data1 0xed, 0x14, 0x5a, 0x45 // 27
956 data1 0x05, 0xe9, 0xe3, 0xa9 // 28
957 data1 0xf8, 0xa3, 0xef, 0xfc // 29
958 data1 0xd9, 0x02, 0x6f, 0x67 // 30
959 data1 0x8a, 0x4c, 0x2a, 0x8d // 31
960 data1 0x42, 0x39, 0xfa, 0xff // 32
961 data1 0x81, 0xf6, 0x71, 0x87 // 33
962 data1 0x22, 0x61, 0x9d, 0x6d // 34
963 data1 0x0c, 0x38, 0xe5, 0xfd // 35
964 data1 0x44, 0xea, 0xbe, 0xa4 // 36
965 data1 0xa9, 0xcf, 0xde, 0x4b // 37
966 data1 0x60, 0x4b, 0xbb, 0xf6 // 38
967 data1 0x70, 0xbc, 0xbf, 0xbe // 39
968 data1 0xc6, 0x7e, 0x9b, 0x28 // 40
969 data1 0xfa, 0x27, 0xa1, 0xea // 41
970 data1 0x85, 0x30, 0xef, 0xd4 // 42
971 data1 0x05, 0x1d, 0x88, 0x04 // 43
972 data1 0x39, 0xd0, 0xd4, 0xd9 // 44
973 data1 0xe5, 0x99, 0xdb, 0xe6 // 45
974 data1 0xf8, 0x7c, 0xa2, 0x1f // 46
975 data1 0x65, 0x56, 0xac, 0xc4 // 47
976 data1 0x44, 0x22, 0x29, 0xf4 // 48
977 data1 0x97, 0xff, 0x2a, 0x43 // 49
978 data1 0xa7, 0x23, 0x94, 0xab // 50
979 data1 0x39, 0xa0, 0x93, 0xfc // 51
980 data1 0xc3, 0x59, 0x5b, 0x65 // 52
981 data1 0x92, 0xcc, 0x0c, 0x8f // 53
982 data1 0x7d, 0xf4, 0xef, 0xff // 54
983 data1 0xd1, 0x5d, 0x84, 0x85 // 55
984 data1 0x4f, 0x7e, 0xa8, 0x6f // 56
985 data1 0xe0, 0xe6, 0x2c, 0xfe // 57
986 data1 0x14, 0x43, 0x01, 0xa3 // 58
987 data1 0xa1, 0x11, 0x08, 0x4e // 59
988 data1 0x82, 0x7e, 0x53, 0xf7 // 60
989 data1 0x35, 0xf2, 0x3a, 0xbd // 61
990 data1 0xbb, 0xd2, 0xd7, 0x2a // 62
991 data1 0x91, 0xd3, 0x86, 0xeb // 63
992.size md5_constants#,64*4
diff --git a/src/lib/libcrypto/md5/asm/md5-x86_64.pl b/src/lib/libcrypto/md5/asm/md5-x86_64.pl
index 9a6fa67224..867885435e 100755
--- a/src/lib/libcrypto/md5/asm/md5-x86_64.pl
+++ b/src/lib/libcrypto/md5/asm/md5-x86_64.pl
@@ -15,7 +15,7 @@ my $code;
15# dst = x + ((dst + F(x,y,z) + X[k] + T_i) <<< s) 15# dst = x + ((dst + F(x,y,z) + X[k] + T_i) <<< s)
16# %r10d = X[k_next] 16# %r10d = X[k_next]
17# %r11d = z' (copy of z for the next step) 17# %r11d = z' (copy of z for the next step)
18# Each round1_step() takes about 5.71 clocks (9 instructions, 1.58 IPC) 18# Each round1_step() takes about 5.3 clocks (9 instructions, 1.7 IPC)
19sub round1_step 19sub round1_step
20{ 20{
21 my ($pos, $dst, $x, $y, $z, $k_next, $T_i, $s) = @_; 21 my ($pos, $dst, $x, $y, $z, $k_next, $T_i, $s) = @_;
@@ -37,22 +37,26 @@ EOF
37# round2_step() does: 37# round2_step() does:
38# dst = x + ((dst + G(x,y,z) + X[k] + T_i) <<< s) 38# dst = x + ((dst + G(x,y,z) + X[k] + T_i) <<< s)
39# %r10d = X[k_next] 39# %r10d = X[k_next]
40# %r11d = y' (copy of y for the next step) 40# %r11d = z' (copy of z for the next step)
41# Each round2_step() takes about 6.22 clocks (9 instructions, 1.45 IPC) 41# %r12d = z' (copy of z for the next step)
42# Each round2_step() takes about 5.4 clocks (11 instructions, 2.0 IPC)
42sub round2_step 43sub round2_step
43{ 44{
44 my ($pos, $dst, $x, $y, $z, $k_next, $T_i, $s) = @_; 45 my ($pos, $dst, $x, $y, $z, $k_next, $T_i, $s) = @_;
45 $code .= " mov 1*4(%rsi), %r10d /* (NEXT STEP) X[1] */\n" if ($pos == -1); 46 $code .= " mov 1*4(%rsi), %r10d /* (NEXT STEP) X[1] */\n" if ($pos == -1);
46 $code .= " mov %ecx, %r11d /* (NEXT STEP) y' = %ecx */\n" if ($pos == -1); 47 $code .= " mov %edx, %r11d /* (NEXT STEP) z' = %edx */\n" if ($pos == -1);
48 $code .= " mov %edx, %r12d /* (NEXT STEP) z' = %edx */\n" if ($pos == -1);
47 $code .= <<EOF; 49 $code .= <<EOF;
48 xor $x, %r11d /* x ^ ... */ 50 not %r11d /* not z */
49 lea $T_i($dst,%r10d),$dst /* Const + dst + ... */ 51 lea $T_i($dst,%r10d),$dst /* Const + dst + ... */
50 and $z, %r11d /* z & ... */ 52 and $x, %r12d /* x & z */
51 xor $y, %r11d /* y ^ ... */ 53 and $y, %r11d /* y & (not z) */
52 mov $k_next*4(%rsi),%r10d /* (NEXT STEP) X[$k_next] */ 54 mov $k_next*4(%rsi),%r10d /* (NEXT STEP) X[$k_next] */
53 add %r11d, $dst /* dst += ... */ 55 or %r11d, %r12d /* (y & (not z)) | (x & z) */
56 mov $y, %r11d /* (NEXT STEP) z' = $y */
57 add %r12d, $dst /* dst += ... */
58 mov $y, %r12d /* (NEXT STEP) z' = $y */
54 rol \$$s, $dst /* dst <<< s */ 59 rol \$$s, $dst /* dst <<< s */
55 mov $x, %r11d /* (NEXT STEP) y' = $x */
56 add $x, $dst /* dst += x */ 60 add $x, $dst /* dst += x */
57EOF 61EOF
58} 62}
@@ -61,7 +65,7 @@ EOF
61# dst = x + ((dst + H(x,y,z) + X[k] + T_i) <<< s) 65# dst = x + ((dst + H(x,y,z) + X[k] + T_i) <<< s)
62# %r10d = X[k_next] 66# %r10d = X[k_next]
63# %r11d = y' (copy of y for the next step) 67# %r11d = y' (copy of y for the next step)
64# Each round3_step() takes about 4.26 clocks (8 instructions, 1.88 IPC) 68# Each round3_step() takes about 4.2 clocks (8 instructions, 1.9 IPC)
65sub round3_step 69sub round3_step
66{ 70{
67 my ($pos, $dst, $x, $y, $z, $k_next, $T_i, $s) = @_; 71 my ($pos, $dst, $x, $y, $z, $k_next, $T_i, $s) = @_;
@@ -83,7 +87,7 @@ EOF
83# dst = x + ((dst + I(x,y,z) + X[k] + T_i) <<< s) 87# dst = x + ((dst + I(x,y,z) + X[k] + T_i) <<< s)
84# %r10d = X[k_next] 88# %r10d = X[k_next]
85# %r11d = not z' (copy of not z for the next step) 89# %r11d = not z' (copy of not z for the next step)
86# Each round4_step() takes about 5.27 clocks (9 instructions, 1.71 IPC) 90# Each round4_step() takes about 5.2 clocks (9 instructions, 1.7 IPC)
87sub round4_step 91sub round4_step
88{ 92{
89 my ($pos, $dst, $x, $y, $z, $k_next, $T_i, $s) = @_; 93 my ($pos, $dst, $x, $y, $z, $k_next, $T_i, $s) = @_;
@@ -104,8 +108,19 @@ sub round4_step
104EOF 108EOF
105} 109}
106 110
107my $output = shift; 111my $flavour = shift;
108open STDOUT,"| $^X ../perlasm/x86_64-xlate.pl $output"; 112my $output = shift;
113if ($flavour =~ /\./) { $output = $flavour; undef $flavour; }
114
115my $win64=0; $win64=1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/);
116
117$0 =~ m/(.*[\/\\])[^\/\\]+$/; my $dir=$1; my $xlate;
118( $xlate="${dir}x86_64-xlate.pl" and -f $xlate ) or
119( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or
120die "can't locate x86_64-xlate.pl";
121
122no warnings qw(uninitialized);
123open STDOUT,"| $^X $xlate $flavour $output";
109 124
110$code .= <<EOF; 125$code .= <<EOF;
111.text 126.text
@@ -116,8 +131,10 @@ $code .= <<EOF;
116md5_block_asm_data_order: 131md5_block_asm_data_order:
117 push %rbp 132 push %rbp
118 push %rbx 133 push %rbx
134 push %r12
119 push %r14 135 push %r14
120 push %r15 136 push %r15
137.Lprologue:
121 138
122 # rdi = arg #1 (ctx, MD5_CTX pointer) 139 # rdi = arg #1 (ctx, MD5_CTX pointer)
123 # rsi = arg #2 (ptr, data pointer) 140 # rsi = arg #2 (ptr, data pointer)
@@ -232,13 +249,120 @@ $code .= <<EOF;
232 mov %ecx, 2*4(%rbp) # ctx->C = C 249 mov %ecx, 2*4(%rbp) # ctx->C = C
233 mov %edx, 3*4(%rbp) # ctx->D = D 250 mov %edx, 3*4(%rbp) # ctx->D = D
234 251
252 mov (%rsp),%r15
253 mov 8(%rsp),%r14
254 mov 16(%rsp),%r12
255 mov 24(%rsp),%rbx
256 mov 32(%rsp),%rbp
257 add \$40,%rsp
258.Lepilogue:
259 ret
260.size md5_block_asm_data_order,.-md5_block_asm_data_order
261EOF
262
263# EXCEPTION_DISPOSITION handler (EXCEPTION_RECORD *rec,ULONG64 frame,
264# CONTEXT *context,DISPATCHER_CONTEXT *disp)
265if ($win64) {
266my $rec="%rcx";
267my $frame="%rdx";
268my $context="%r8";
269my $disp="%r9";
270
271$code.=<<___;
272.extern __imp_RtlVirtualUnwind
273.type se_handler,\@abi-omnipotent
274.align 16
275se_handler:
276 push %rsi
277 push %rdi
278 push %rbx
279 push %rbp
280 push %r12
281 push %r13
282 push %r14
283 push %r15
284 pushfq
285 sub \$64,%rsp
286
287 mov 120($context),%rax # pull context->Rax
288 mov 248($context),%rbx # pull context->Rip
289
290 lea .Lprologue(%rip),%r10
291 cmp %r10,%rbx # context->Rip<.Lprologue
292 jb .Lin_prologue
293
294 mov 152($context),%rax # pull context->Rsp
295
296 lea .Lepilogue(%rip),%r10
297 cmp %r10,%rbx # context->Rip>=.Lepilogue
298 jae .Lin_prologue
299
300 lea 40(%rax),%rax
301
302 mov -8(%rax),%rbp
303 mov -16(%rax),%rbx
304 mov -24(%rax),%r12
305 mov -32(%rax),%r14
306 mov -40(%rax),%r15
307 mov %rbx,144($context) # restore context->Rbx
308 mov %rbp,160($context) # restore context->Rbp
309 mov %r12,216($context) # restore context->R12
310 mov %r14,232($context) # restore context->R14
311 mov %r15,240($context) # restore context->R15
312
313.Lin_prologue:
314 mov 8(%rax),%rdi
315 mov 16(%rax),%rsi
316 mov %rax,152($context) # restore context->Rsp
317 mov %rsi,168($context) # restore context->Rsi
318 mov %rdi,176($context) # restore context->Rdi
319
320 mov 40($disp),%rdi # disp->ContextRecord
321 mov $context,%rsi # context
322 mov \$154,%ecx # sizeof(CONTEXT)
323 .long 0xa548f3fc # cld; rep movsq
324
325 mov $disp,%rsi
326 xor %rcx,%rcx # arg1, UNW_FLAG_NHANDLER
327 mov 8(%rsi),%rdx # arg2, disp->ImageBase
328 mov 0(%rsi),%r8 # arg3, disp->ControlPc
329 mov 16(%rsi),%r9 # arg4, disp->FunctionEntry
330 mov 40(%rsi),%r10 # disp->ContextRecord
331 lea 56(%rsi),%r11 # &disp->HandlerData
332 lea 24(%rsi),%r12 # &disp->EstablisherFrame
333 mov %r10,32(%rsp) # arg5
334 mov %r11,40(%rsp) # arg6
335 mov %r12,48(%rsp) # arg7
336 mov %rcx,56(%rsp) # arg8, (NULL)
337 call *__imp_RtlVirtualUnwind(%rip)
338
339 mov \$1,%eax # ExceptionContinueSearch
340 add \$64,%rsp
341 popfq
235 pop %r15 342 pop %r15
236 pop %r14 343 pop %r14
237 pop %rbx 344 pop %r13
345 pop %r12
238 pop %rbp 346 pop %rbp
347 pop %rbx
348 pop %rdi
349 pop %rsi
239 ret 350 ret
240.size md5_block_asm_data_order,.-md5_block_asm_data_order 351.size se_handler,.-se_handler
241EOF 352
353.section .pdata
354.align 4
355 .rva .LSEH_begin_md5_block_asm_data_order
356 .rva .LSEH_end_md5_block_asm_data_order
357 .rva .LSEH_info_md5_block_asm_data_order
358
359.section .xdata
360.align 8
361.LSEH_info_md5_block_asm_data_order:
362 .byte 9,0,0,0
363 .rva se_handler
364___
365}
242 366
243print $code; 367print $code;
244 368
diff --git a/src/lib/libcrypto/md5/md5.h b/src/lib/libcrypto/md5/md5.h
index 0761f84a27..4cbf84386b 100644
--- a/src/lib/libcrypto/md5/md5.h
+++ b/src/lib/libcrypto/md5/md5.h
@@ -77,7 +77,7 @@ extern "C" {
77 * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 77 * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
78 */ 78 */
79 79
80#if defined(OPENSSL_SYS_WIN16) || defined(__LP32__) 80#if defined(__LP32__)
81#define MD5_LONG unsigned long 81#define MD5_LONG unsigned long
82#elif defined(OPENSSL_SYS_CRAY) || defined(__ILP64__) 82#elif defined(OPENSSL_SYS_CRAY) || defined(__ILP64__)
83#define MD5_LONG unsigned long 83#define MD5_LONG unsigned long
@@ -105,9 +105,6 @@ typedef struct MD5state_st
105 unsigned int num; 105 unsigned int num;
106 } MD5_CTX; 106 } MD5_CTX;
107 107
108#ifdef OPENSSL_FIPS
109int private_MD5_Init(MD5_CTX *c);
110#endif
111int MD5_Init(MD5_CTX *c); 108int MD5_Init(MD5_CTX *c);
112int MD5_Update(MD5_CTX *c, const void *data, size_t len); 109int MD5_Update(MD5_CTX *c, const void *data, size_t len);
113int MD5_Final(unsigned char *md, MD5_CTX *c); 110int 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 47bb9020ee..beace632e3 100644
--- a/src/lib/libcrypto/md5/md5_dgst.c
+++ b/src/lib/libcrypto/md5/md5_dgst.c
@@ -59,11 +59,6 @@
59#include <stdio.h> 59#include <stdio.h>
60#include "md5_locl.h" 60#include "md5_locl.h"
61#include <openssl/opensslv.h> 61#include <openssl/opensslv.h>
62#include <openssl/err.h>
63#ifdef OPENSSL_FIPS
64#include <openssl/fips.h>
65#endif
66
67 62
68const char MD5_version[]="MD5" OPENSSL_VERSION_PTEXT; 63const char MD5_version[]="MD5" OPENSSL_VERSION_PTEXT;
69 64
@@ -75,15 +70,13 @@ const char MD5_version[]="MD5" OPENSSL_VERSION_PTEXT;
75#define INIT_DATA_C (unsigned long)0x98badcfeL 70#define INIT_DATA_C (unsigned long)0x98badcfeL
76#define INIT_DATA_D (unsigned long)0x10325476L 71#define INIT_DATA_D (unsigned long)0x10325476L
77 72
78FIPS_NON_FIPS_MD_Init(MD5) 73int MD5_Init(MD5_CTX *c)
79 { 74 {
75 memset (c,0,sizeof(*c));
80 c->A=INIT_DATA_A; 76 c->A=INIT_DATA_A;
81 c->B=INIT_DATA_B; 77 c->B=INIT_DATA_B;
82 c->C=INIT_DATA_C; 78 c->C=INIT_DATA_C;
83 c->D=INIT_DATA_D; 79 c->D=INIT_DATA_D;
84 c->Nl=0;
85 c->Nh=0;
86 c->num=0;
87 return 1; 80 return 1;
88 } 81 }
89 82
diff --git a/src/lib/libcrypto/md5/md5_locl.h b/src/lib/libcrypto/md5/md5_locl.h
index 84e81b960d..968d577995 100644
--- a/src/lib/libcrypto/md5/md5_locl.h
+++ b/src/lib/libcrypto/md5/md5_locl.h
@@ -69,6 +69,8 @@
69# if defined(__i386) || defined(__i386__) || defined(_M_IX86) || defined(__INTEL__) || \ 69# if defined(__i386) || defined(__i386__) || defined(_M_IX86) || defined(__INTEL__) || \
70 defined(__x86_64) || defined(__x86_64__) || defined(_M_AMD64) || defined(_M_X64) 70 defined(__x86_64) || defined(__x86_64__) || defined(_M_AMD64) || defined(_M_X64)
71# define md5_block_data_order md5_block_asm_data_order 71# define md5_block_data_order md5_block_asm_data_order
72# elif defined(__ia64) || defined(__ia64__) || defined(_M_IA64)
73# define md5_block_data_order md5_block_asm_data_order
72# endif 74# endif
73#endif 75#endif
74 76
diff --git a/src/lib/libcrypto/mem_dbg.c b/src/lib/libcrypto/mem_dbg.c
index dfeb084799..ac793397f1 100644
--- a/src/lib/libcrypto/mem_dbg.c
+++ b/src/lib/libcrypto/mem_dbg.c
@@ -55,6 +55,59 @@
55 * copied and put under another distribution licence 55 * copied and put under another distribution licence
56 * [including the GNU Public Licence.] 56 * [including the GNU Public Licence.]
57 */ 57 */
58/* ====================================================================
59 * Copyright (c) 1998-2006 The OpenSSL Project. All rights reserved.
60 *
61 * Redistribution and use in source and binary forms, with or without
62 * modification, are permitted provided that the following conditions
63 * are met:
64 *
65 * 1. Redistributions of source code must retain the above copyright
66 * notice, this list of conditions and the following disclaimer.
67 *
68 * 2. Redistributions in binary form must reproduce the above copyright
69 * notice, this list of conditions and the following disclaimer in
70 * the documentation and/or other materials provided with the
71 * distribution.
72 *
73 * 3. All advertising materials mentioning features or use of this
74 * software must display the following acknowledgment:
75 * "This product includes software developed by the OpenSSL Project
76 * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
77 *
78 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
79 * endorse or promote products derived from this software without
80 * prior written permission. For written permission, please contact
81 * openssl-core@openssl.org.
82 *
83 * 5. Products derived from this software may not be called "OpenSSL"
84 * nor may "OpenSSL" appear in their names without prior written
85 * permission of the OpenSSL Project.
86 *
87 * 6. Redistributions of any form whatsoever must retain the following
88 * acknowledgment:
89 * "This product includes software developed by the OpenSSL Project
90 * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
91 *
92 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
93 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
94 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
95 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
96 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
97 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
98 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
99 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
100 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
101 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
102 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
103 * OF THE POSSIBILITY OF SUCH DAMAGE.
104 * ====================================================================
105 *
106 * This product includes cryptographic software written by Eric Young
107 * (eay@cryptsoft.com). This product includes software written by Tim
108 * Hudson (tjh@cryptsoft.com).
109 *
110 */
58 111
59#include <stdio.h> 112#include <stdio.h>
60#include <stdlib.h> 113#include <stdlib.h>
@@ -81,8 +134,11 @@ static int mh_mode=CRYPTO_MEM_CHECK_OFF;
81 */ 134 */
82 135
83static unsigned long order = 0; /* number of memory requests */ 136static unsigned long order = 0; /* number of memory requests */
84static LHASH *mh=NULL; /* hash-table of memory requests (address as key); 137
85 * access requires MALLOC2 lock */ 138DECLARE_LHASH_OF(MEM);
139static LHASH_OF(MEM) *mh=NULL; /* hash-table of memory requests
140 * (address as key); access requires
141 * MALLOC2 lock */
86 142
87 143
88typedef struct app_mem_info_st 144typedef struct app_mem_info_st
@@ -93,8 +149,8 @@ typedef struct app_mem_info_st
93 * CRYPTO_pop_info() to pop an entry, 149 * CRYPTO_pop_info() to pop an entry,
94 * CRYPTO_remove_all_info() to pop all entries. 150 * CRYPTO_remove_all_info() to pop all entries.
95 */ 151 */
96 { 152 {
97 unsigned long thread; 153 CRYPTO_THREADID threadid;
98 const char *file; 154 const char *file;
99 int line; 155 int line;
100 const char *info; 156 const char *info;
@@ -104,10 +160,13 @@ typedef struct app_mem_info_st
104 160
105static void app_info_free(APP_INFO *); 161static void app_info_free(APP_INFO *);
106 162
107static LHASH *amih=NULL; /* hash-table with those app_mem_info_st's 163DECLARE_LHASH_OF(APP_INFO);
108 * that are at the top of their thread's stack 164static LHASH_OF(APP_INFO) *amih=NULL; /* hash-table with those
109 * (with `thread' as key); 165 * app_mem_info_st's that are at
110 * access requires MALLOC2 lock */ 166 * the top of their thread's
167 * stack (with `thread' as key);
168 * access requires MALLOC2
169 * lock */
111 170
112typedef struct mem_st 171typedef struct mem_st
113/* memory-block description */ 172/* memory-block description */
@@ -116,7 +175,7 @@ typedef struct mem_st
116 int num; 175 int num;
117 const char *file; 176 const char *file;
118 int line; 177 int line;
119 unsigned long thread; 178 CRYPTO_THREADID threadid;
120 unsigned long order; 179 unsigned long order;
121 time_t time; 180 time_t time;
122 APP_INFO *app_info; 181 APP_INFO *app_info;
@@ -136,11 +195,11 @@ static unsigned int num_disable = 0; /* num_disable > 0
136 * iff 195 * iff
137 * mh_mode == CRYPTO_MEM_CHECK_ON (w/o ..._ENABLE) 196 * mh_mode == CRYPTO_MEM_CHECK_ON (w/o ..._ENABLE)
138 */ 197 */
139static unsigned long disabling_thread = 0; /* Valid iff num_disable > 0. 198
140 * CRYPTO_LOCK_MALLOC2 is locked 199/* Valid iff num_disable > 0. CRYPTO_LOCK_MALLOC2 is locked exactly in this
141 * exactly in this case (by the 200 * case (by the thread named in disabling_thread).
142 * thread named in disabling_thread). 201 */
143 */ 202static CRYPTO_THREADID disabling_threadid;
144 203
145static void app_info_free(APP_INFO *inf) 204static void app_info_free(APP_INFO *inf)
146 { 205 {
@@ -177,7 +236,9 @@ int CRYPTO_mem_ctrl(int mode)
177 case CRYPTO_MEM_CHECK_DISABLE: /* aka MemCheck_off() */ 236 case CRYPTO_MEM_CHECK_DISABLE: /* aka MemCheck_off() */
178 if (mh_mode & CRYPTO_MEM_CHECK_ON) 237 if (mh_mode & CRYPTO_MEM_CHECK_ON)
179 { 238 {
180 if (!num_disable || (disabling_thread != CRYPTO_thread_id())) /* otherwise we already have the MALLOC2 lock */ 239 CRYPTO_THREADID cur;
240 CRYPTO_THREADID_current(&cur);
241 if (!num_disable || CRYPTO_THREADID_cmp(&disabling_threadid, &cur)) /* otherwise we already have the MALLOC2 lock */
181 { 242 {
182 /* Long-time lock CRYPTO_LOCK_MALLOC2 must not be claimed while 243 /* Long-time lock CRYPTO_LOCK_MALLOC2 must not be claimed while
183 * we're holding CRYPTO_LOCK_MALLOC, or we'll deadlock if 244 * we're holding CRYPTO_LOCK_MALLOC, or we'll deadlock if
@@ -195,7 +256,7 @@ int CRYPTO_mem_ctrl(int mode)
195 CRYPTO_w_lock(CRYPTO_LOCK_MALLOC2); 256 CRYPTO_w_lock(CRYPTO_LOCK_MALLOC2);
196 CRYPTO_w_lock(CRYPTO_LOCK_MALLOC); 257 CRYPTO_w_lock(CRYPTO_LOCK_MALLOC);
197 mh_mode &= ~CRYPTO_MEM_CHECK_ENABLE; 258 mh_mode &= ~CRYPTO_MEM_CHECK_ENABLE;
198 disabling_thread=CRYPTO_thread_id(); 259 CRYPTO_THREADID_cpy(&disabling_threadid, &cur);
199 } 260 }
200 num_disable++; 261 num_disable++;
201 } 262 }
@@ -228,10 +289,12 @@ int CRYPTO_is_mem_check_on(void)
228 289
229 if (mh_mode & CRYPTO_MEM_CHECK_ON) 290 if (mh_mode & CRYPTO_MEM_CHECK_ON)
230 { 291 {
292 CRYPTO_THREADID cur;
293 CRYPTO_THREADID_current(&cur);
231 CRYPTO_r_lock(CRYPTO_LOCK_MALLOC); 294 CRYPTO_r_lock(CRYPTO_LOCK_MALLOC);
232 295
233 ret = (mh_mode & CRYPTO_MEM_CHECK_ENABLE) 296 ret = (mh_mode & CRYPTO_MEM_CHECK_ENABLE)
234 || (disabling_thread != CRYPTO_thread_id()); 297 || CRYPTO_THREADID_cmp(&disabling_threadid, &cur);
235 298
236 CRYPTO_r_unlock(CRYPTO_LOCK_MALLOC); 299 CRYPTO_r_unlock(CRYPTO_LOCK_MALLOC);
237 } 300 }
@@ -249,49 +312,49 @@ long CRYPTO_dbg_get_options(void)
249 return options; 312 return options;
250 } 313 }
251 314
252/* static int mem_cmp(MEM *a, MEM *b) */ 315static int mem_cmp(const MEM *a, const MEM *b)
253static int mem_cmp(const void *a_void, const void *b_void)
254 { 316 {
255#ifdef _WIN64 317#ifdef _WIN64
256 const char *a=(const char *)((const MEM *)a_void)->addr, 318 const char *ap=(const char *)a->addr,
257 *b=(const char *)((const MEM *)b_void)->addr; 319 *bp=(const char *)b->addr;
258 if (a==b) return 0; 320 if (ap==bp) return 0;
259 else if (a>b) return 1; 321 else if (ap>bp) return 1;
260 else return -1; 322 else return -1;
261#else 323#else
262 return((const char *)((const MEM *)a_void)->addr 324 return (const char *)a->addr - (const char *)b->addr;
263 - (const char *)((const MEM *)b_void)->addr);
264#endif 325#endif
265 } 326 }
327static IMPLEMENT_LHASH_COMP_FN(mem, MEM)
266 328
267/* static unsigned long mem_hash(MEM *a) */ 329static unsigned long mem_hash(const MEM *a)
268static unsigned long mem_hash(const void *a_void)
269 { 330 {
270 unsigned long ret; 331 unsigned long ret;
271 332
272 ret=(unsigned long)((const MEM *)a_void)->addr; 333 ret=(unsigned long)a->addr;
273 334
274 ret=ret*17851+(ret>>14)*7+(ret>>4)*251; 335 ret=ret*17851+(ret>>14)*7+(ret>>4)*251;
275 return(ret); 336 return(ret);
276 } 337 }
338static IMPLEMENT_LHASH_HASH_FN(mem, MEM)
277 339
278/* static int app_info_cmp(APP_INFO *a, APP_INFO *b) */ 340/* static int app_info_cmp(APP_INFO *a, APP_INFO *b) */
279static int app_info_cmp(const void *a_void, const void *b_void) 341static int app_info_cmp(const void *a_void, const void *b_void)
280 { 342 {
281 return(((const APP_INFO *)a_void)->thread 343 return CRYPTO_THREADID_cmp(&((const APP_INFO *)a_void)->threadid,
282 != ((const APP_INFO *)b_void)->thread); 344 &((const APP_INFO *)b_void)->threadid);
283 } 345 }
346static IMPLEMENT_LHASH_COMP_FN(app_info, APP_INFO)
284 347
285/* static unsigned long app_info_hash(APP_INFO *a) */ 348static unsigned long app_info_hash(const APP_INFO *a)
286static unsigned long app_info_hash(const void *a_void)
287 { 349 {
288 unsigned long ret; 350 unsigned long ret;
289 351
290 ret=(unsigned long)((const APP_INFO *)a_void)->thread; 352 ret = CRYPTO_THREADID_hash(&a->threadid);
291 353 /* This is left in as a "who am I to question legacy?" measure */
292 ret=ret*17851+(ret>>14)*7+(ret>>4)*251; 354 ret=ret*17851+(ret>>14)*7+(ret>>4)*251;
293 return(ret); 355 return(ret);
294 } 356 }
357static IMPLEMENT_LHASH_HASH_FN(app_info, APP_INFO)
295 358
296static APP_INFO *pop_info(void) 359static APP_INFO *pop_info(void)
297 { 360 {
@@ -300,21 +363,22 @@ static APP_INFO *pop_info(void)
300 363
301 if (amih != NULL) 364 if (amih != NULL)
302 { 365 {
303 tmp.thread=CRYPTO_thread_id(); 366 CRYPTO_THREADID_current(&tmp.threadid);
304 if ((ret=(APP_INFO *)lh_delete(amih,&tmp)) != NULL) 367 if ((ret=lh_APP_INFO_delete(amih,&tmp)) != NULL)
305 { 368 {
306 APP_INFO *next=ret->next; 369 APP_INFO *next=ret->next;
307 370
308 if (next != NULL) 371 if (next != NULL)
309 { 372 {
310 next->references++; 373 next->references++;
311 lh_insert(amih,(char *)next); 374 (void)lh_APP_INFO_insert(amih,next);
312 } 375 }
313#ifdef LEVITTE_DEBUG_MEM 376#ifdef LEVITTE_DEBUG_MEM
314 if (ret->thread != tmp.thread) 377 if (CRYPTO_THREADID_cmp(&ret->threadid, &tmp.threadid))
315 { 378 {
316 fprintf(stderr, "pop_info(): deleted info has other thread ID (%lu) than the current thread (%lu)!!!!\n", 379 fprintf(stderr, "pop_info(): deleted info has other thread ID (%lu) than the current thread (%lu)!!!!\n",
317 ret->thread, tmp.thread); 380 CRYPTO_THREADID_hash(&ret->threadid),
381 CRYPTO_THREADID_hash(&tmp.threadid));
318 abort(); 382 abort();
319 } 383 }
320#endif 384#endif
@@ -330,7 +394,7 @@ static APP_INFO *pop_info(void)
330 return(ret); 394 return(ret);
331 } 395 }
332 396
333int CRYPTO_dbg_push_info(const char *info, const char *file, int line) 397int CRYPTO_push_info_(const char *info, const char *file, int line)
334 { 398 {
335 APP_INFO *ami, *amim; 399 APP_INFO *ami, *amim;
336 int ret=0; 400 int ret=0;
@@ -346,7 +410,7 @@ int CRYPTO_dbg_push_info(const char *info, const char *file, int line)
346 } 410 }
347 if (amih == NULL) 411 if (amih == NULL)
348 { 412 {
349 if ((amih=lh_new(app_info_hash, app_info_cmp)) == NULL) 413 if ((amih=lh_APP_INFO_new()) == NULL)
350 { 414 {
351 OPENSSL_free(ami); 415 OPENSSL_free(ami);
352 ret=0; 416 ret=0;
@@ -354,20 +418,21 @@ int CRYPTO_dbg_push_info(const char *info, const char *file, int line)
354 } 418 }
355 } 419 }
356 420
357 ami->thread=CRYPTO_thread_id(); 421 CRYPTO_THREADID_current(&ami->threadid);
358 ami->file=file; 422 ami->file=file;
359 ami->line=line; 423 ami->line=line;
360 ami->info=info; 424 ami->info=info;
361 ami->references=1; 425 ami->references=1;
362 ami->next=NULL; 426 ami->next=NULL;
363 427
364 if ((amim=(APP_INFO *)lh_insert(amih,(char *)ami)) != NULL) 428 if ((amim=lh_APP_INFO_insert(amih,ami)) != NULL)
365 { 429 {
366#ifdef LEVITTE_DEBUG_MEM 430#ifdef LEVITTE_DEBUG_MEM
367 if (ami->thread != amim->thread) 431 if (CRYPTO_THREADID_cmp(&ami->threadid, &amim->threadid))
368 { 432 {
369 fprintf(stderr, "CRYPTO_push_info(): previous info has other thread ID (%lu) than the current thread (%lu)!!!!\n", 433 fprintf(stderr, "CRYPTO_push_info(): previous info has other thread ID (%lu) than the current thread (%lu)!!!!\n",
370 amim->thread, ami->thread); 434 CRYPTO_THREADID_hash(&amim->threadid),
435 CRYPTO_THREADID_hash(&ami->threadid));
371 abort(); 436 abort();
372 } 437 }
373#endif 438#endif
@@ -380,7 +445,7 @@ int CRYPTO_dbg_push_info(const char *info, const char *file, int line)
380 return(ret); 445 return(ret);
381 } 446 }
382 447
383int CRYPTO_dbg_pop_info(void) 448int CRYPTO_pop_info(void)
384 { 449 {
385 int ret=0; 450 int ret=0;
386 451
@@ -395,7 +460,7 @@ int CRYPTO_dbg_pop_info(void)
395 return(ret); 460 return(ret);
396 } 461 }
397 462
398int CRYPTO_dbg_remove_all_info(void) 463int CRYPTO_remove_all_info(void)
399 { 464 {
400 int ret=0; 465 int ret=0;
401 466
@@ -439,7 +504,7 @@ void CRYPTO_dbg_malloc(void *addr, int num, const char *file, int line,
439 } 504 }
440 if (mh == NULL) 505 if (mh == NULL)
441 { 506 {
442 if ((mh=lh_new(mem_hash, mem_cmp)) == NULL) 507 if ((mh=lh_MEM_new()) == NULL)
443 { 508 {
444 OPENSSL_free(addr); 509 OPENSSL_free(addr);
445 OPENSSL_free(m); 510 OPENSSL_free(m);
@@ -453,9 +518,9 @@ void CRYPTO_dbg_malloc(void *addr, int num, const char *file, int line,
453 m->line=line; 518 m->line=line;
454 m->num=num; 519 m->num=num;
455 if (options & V_CRYPTO_MDEBUG_THREAD) 520 if (options & V_CRYPTO_MDEBUG_THREAD)
456 m->thread=CRYPTO_thread_id(); 521 CRYPTO_THREADID_current(&m->threadid);
457 else 522 else
458 m->thread=0; 523 memset(&m->threadid, 0, sizeof(m->threadid));
459 524
460 if (order == break_order_num) 525 if (order == break_order_num)
461 { 526 {
@@ -464,7 +529,7 @@ void CRYPTO_dbg_malloc(void *addr, int num, const char *file, int line,
464 } 529 }
465 m->order=order++; 530 m->order=order++;
466#ifdef LEVITTE_DEBUG_MEM 531#ifdef LEVITTE_DEBUG_MEM
467 fprintf(stderr, "LEVITTE_DEBUG_MEM: [%5d] %c 0x%p (%d)\n", 532 fprintf(stderr, "LEVITTE_DEBUG_MEM: [%5ld] %c 0x%p (%d)\n",
468 m->order, 533 m->order,
469 (before_p & 128) ? '*' : '+', 534 (before_p & 128) ? '*' : '+',
470 m->addr, m->num); 535 m->addr, m->num);
@@ -474,16 +539,16 @@ void CRYPTO_dbg_malloc(void *addr, int num, const char *file, int line,
474 else 539 else
475 m->time=0; 540 m->time=0;
476 541
477 tmp.thread=CRYPTO_thread_id(); 542 CRYPTO_THREADID_current(&tmp.threadid);
478 m->app_info=NULL; 543 m->app_info=NULL;
479 if (amih != NULL 544 if (amih != NULL
480 && (amim=(APP_INFO *)lh_retrieve(amih,(char *)&tmp)) != NULL) 545 && (amim=lh_APP_INFO_retrieve(amih,&tmp)) != NULL)
481 { 546 {
482 m->app_info = amim; 547 m->app_info = amim;
483 amim->references++; 548 amim->references++;
484 } 549 }
485 550
486 if ((mm=(MEM *)lh_insert(mh,(char *)m)) != NULL) 551 if ((mm=lh_MEM_insert(mh, m)) != NULL)
487 { 552 {
488 /* Not good, but don't sweat it */ 553 /* Not good, but don't sweat it */
489 if (mm->app_info != NULL) 554 if (mm->app_info != NULL)
@@ -516,11 +581,11 @@ void CRYPTO_dbg_free(void *addr, int before_p)
516 MemCheck_off(); /* make sure we hold MALLOC2 lock */ 581 MemCheck_off(); /* make sure we hold MALLOC2 lock */
517 582
518 m.addr=addr; 583 m.addr=addr;
519 mp=(MEM *)lh_delete(mh,(char *)&m); 584 mp=lh_MEM_delete(mh,&m);
520 if (mp != NULL) 585 if (mp != NULL)
521 { 586 {
522#ifdef LEVITTE_DEBUG_MEM 587#ifdef LEVITTE_DEBUG_MEM
523 fprintf(stderr, "LEVITTE_DEBUG_MEM: [%5d] - 0x%p (%d)\n", 588 fprintf(stderr, "LEVITTE_DEBUG_MEM: [%5ld] - 0x%p (%d)\n",
524 mp->order, mp->addr, mp->num); 589 mp->order, mp->addr, mp->num);
525#endif 590#endif
526 if (mp->app_info != NULL) 591 if (mp->app_info != NULL)
@@ -566,18 +631,18 @@ void CRYPTO_dbg_realloc(void *addr1, void *addr2, int num,
566 MemCheck_off(); /* make sure we hold MALLOC2 lock */ 631 MemCheck_off(); /* make sure we hold MALLOC2 lock */
567 632
568 m.addr=addr1; 633 m.addr=addr1;
569 mp=(MEM *)lh_delete(mh,(char *)&m); 634 mp=lh_MEM_delete(mh,&m);
570 if (mp != NULL) 635 if (mp != NULL)
571 { 636 {
572#ifdef LEVITTE_DEBUG_MEM 637#ifdef LEVITTE_DEBUG_MEM
573 fprintf(stderr, "LEVITTE_DEBUG_MEM: [%5d] * 0x%p (%d) -> 0x%p (%d)\n", 638 fprintf(stderr, "LEVITTE_DEBUG_MEM: [%5ld] * 0x%p (%d) -> 0x%p (%d)\n",
574 mp->order, 639 mp->order,
575 mp->addr, mp->num, 640 mp->addr, mp->num,
576 addr2, num); 641 addr2, num);
577#endif 642#endif
578 mp->addr=addr2; 643 mp->addr=addr2;
579 mp->num=num; 644 mp->num=num;
580 lh_insert(mh,(char *)mp); 645 (void)lh_MEM_insert(mh,mp);
581 } 646 }
582 647
583 MemCheck_on(); /* release MALLOC2 lock 648 MemCheck_on(); /* release MALLOC2 lock
@@ -596,14 +661,14 @@ typedef struct mem_leak_st
596 long bytes; 661 long bytes;
597 } MEM_LEAK; 662 } MEM_LEAK;
598 663
599static void print_leak(const MEM *m, MEM_LEAK *l) 664static void print_leak_doall_arg(const MEM *m, MEM_LEAK *l)
600 { 665 {
601 char buf[1024]; 666 char buf[1024];
602 char *bufp = buf; 667 char *bufp = buf;
603 APP_INFO *amip; 668 APP_INFO *amip;
604 int ami_cnt; 669 int ami_cnt;
605 struct tm *lcl = NULL; 670 struct tm *lcl = NULL;
606 unsigned long ti; 671 CRYPTO_THREADID ti;
607 672
608#define BUF_REMAIN (sizeof buf - (size_t)(bufp - buf)) 673#define BUF_REMAIN (sizeof buf - (size_t)(bufp - buf))
609 674
@@ -625,7 +690,8 @@ static void print_leak(const MEM *m, MEM_LEAK *l)
625 690
626 if (options & V_CRYPTO_MDEBUG_THREAD) 691 if (options & V_CRYPTO_MDEBUG_THREAD)
627 { 692 {
628 BIO_snprintf(bufp, BUF_REMAIN, "thread=%lu, ", m->thread); 693 BIO_snprintf(bufp, BUF_REMAIN, "thread=%lu, ",
694 CRYPTO_THREADID_hash(&m->threadid));
629 bufp += strlen(bufp); 695 bufp += strlen(bufp);
630 } 696 }
631 697
@@ -642,8 +708,8 @@ static void print_leak(const MEM *m, MEM_LEAK *l)
642 ami_cnt=0; 708 ami_cnt=0;
643 if (!amip) 709 if (!amip)
644 return; 710 return;
645 ti=amip->thread; 711 CRYPTO_THREADID_cpy(&ti, &amip->threadid);
646 712
647 do 713 do
648 { 714 {
649 int buf_len; 715 int buf_len;
@@ -653,7 +719,8 @@ static void print_leak(const MEM *m, MEM_LEAK *l)
653 memset(buf,'>',ami_cnt); 719 memset(buf,'>',ami_cnt);
654 BIO_snprintf(buf + ami_cnt, sizeof buf - ami_cnt, 720 BIO_snprintf(buf + ami_cnt, sizeof buf - ami_cnt,
655 " thread=%lu, file=%s, line=%d, info=\"", 721 " thread=%lu, file=%s, line=%d, info=\"",
656 amip->thread, amip->file, amip->line); 722 CRYPTO_THREADID_hash(&amip->threadid), amip->file,
723 amip->line);
657 buf_len=strlen(buf); 724 buf_len=strlen(buf);
658 info_len=strlen(amip->info); 725 info_len=strlen(amip->info);
659 if (128 - buf_len - 3 < info_len) 726 if (128 - buf_len - 3 < info_len)
@@ -673,8 +740,8 @@ static void print_leak(const MEM *m, MEM_LEAK *l)
673 740
674 amip = amip->next; 741 amip = amip->next;
675 } 742 }
676 while(amip && amip->thread == ti); 743 while(amip && !CRYPTO_THREADID_cmp(&amip->threadid, &ti));
677 744
678#ifdef LEVITTE_DEBUG_MEM 745#ifdef LEVITTE_DEBUG_MEM
679 if (amip) 746 if (amip)
680 { 747 {
@@ -684,7 +751,7 @@ static void print_leak(const MEM *m, MEM_LEAK *l)
684#endif 751#endif
685 } 752 }
686 753
687static IMPLEMENT_LHASH_DOALL_ARG_FN(print_leak, const MEM *, MEM_LEAK *) 754static IMPLEMENT_LHASH_DOALL_ARG_FN(print_leak, const MEM, MEM_LEAK)
688 755
689void CRYPTO_mem_leaks(BIO *b) 756void CRYPTO_mem_leaks(BIO *b)
690 { 757 {
@@ -699,12 +766,15 @@ void CRYPTO_mem_leaks(BIO *b)
699 ml.bytes=0; 766 ml.bytes=0;
700 ml.chunks=0; 767 ml.chunks=0;
701 if (mh != NULL) 768 if (mh != NULL)
702 lh_doall_arg(mh, LHASH_DOALL_ARG_FN(print_leak), 769 lh_MEM_doall_arg(mh, LHASH_DOALL_ARG_FN(print_leak), MEM_LEAK,
703 (char *)&ml); 770 &ml);
704 if (ml.chunks != 0) 771 if (ml.chunks != 0)
705 { 772 {
706 BIO_printf(b,"%ld bytes leaked in %d chunks\n", 773 BIO_printf(b,"%ld bytes leaked in %d chunks\n",
707 ml.bytes,ml.chunks); 774 ml.bytes,ml.chunks);
775#ifdef CRYPTO_MDEBUG_ABORT
776 abort();
777#endif
708 } 778 }
709 else 779 else
710 { 780 {
@@ -717,7 +787,7 @@ void CRYPTO_mem_leaks(BIO *b)
717 * XXX This should be in CRYPTO_mem_leaks_cb, 787 * XXX This should be in CRYPTO_mem_leaks_cb,
718 * and CRYPTO_mem_leaks should be implemented by 788 * and CRYPTO_mem_leaks should be implemented by
719 * using CRYPTO_mem_leaks_cb. 789 * using CRYPTO_mem_leaks_cb.
720 * (Also their should be a variant of lh_doall_arg 790 * (Also there should be a variant of lh_doall_arg
721 * that takes a function pointer instead of a void *; 791 * that takes a function pointer instead of a void *;
722 * this would obviate the ugly and illegal 792 * this would obviate the ugly and illegal
723 * void_fn_to_char kludge in CRYPTO_mem_leaks_cb. 793 * void_fn_to_char kludge in CRYPTO_mem_leaks_cb.
@@ -734,14 +804,14 @@ void CRYPTO_mem_leaks(BIO *b)
734 804
735 if (mh != NULL) 805 if (mh != NULL)
736 { 806 {
737 lh_free(mh); 807 lh_MEM_free(mh);
738 mh = NULL; 808 mh = NULL;
739 } 809 }
740 if (amih != NULL) 810 if (amih != NULL)
741 { 811 {
742 if (lh_num_items(amih) == 0) 812 if (lh_APP_INFO_num_items(amih) == 0)
743 { 813 {
744 lh_free(amih); 814 lh_APP_INFO_free(amih);
745 amih = NULL; 815 amih = NULL;
746 } 816 }
747 } 817 }
@@ -779,39 +849,26 @@ void CRYPTO_mem_leaks_fp(FILE *fp)
779/* NB: The prototypes have been typedef'd to CRYPTO_MEM_LEAK_CB inside crypto.h 849/* NB: The prototypes have been typedef'd to CRYPTO_MEM_LEAK_CB inside crypto.h
780 * If this code is restructured, remove the callback type if it is no longer 850 * If this code is restructured, remove the callback type if it is no longer
781 * needed. -- Geoff Thorpe */ 851 * needed. -- Geoff Thorpe */
782static void cb_leak(const MEM *m, CRYPTO_MEM_LEAK_CB **cb) 852
853/* Can't pass CRYPTO_MEM_LEAK_CB directly to lh_MEM_doall_arg because it
854 * is a function pointer and conversion to void * is prohibited. Instead
855 * pass its address
856 */
857
858typedef CRYPTO_MEM_LEAK_CB *PCRYPTO_MEM_LEAK_CB;
859
860static void cb_leak_doall_arg(const MEM *m, PCRYPTO_MEM_LEAK_CB *cb)
783 { 861 {
784 (**cb)(m->order,m->file,m->line,m->num,m->addr); 862 (*cb)(m->order,m->file,m->line,m->num,m->addr);
785 } 863 }
786 864
787static IMPLEMENT_LHASH_DOALL_ARG_FN(cb_leak, const MEM *, CRYPTO_MEM_LEAK_CB **) 865static IMPLEMENT_LHASH_DOALL_ARG_FN(cb_leak, const MEM, PCRYPTO_MEM_LEAK_CB)
788 866
789void CRYPTO_mem_leaks_cb(CRYPTO_MEM_LEAK_CB *cb) 867void CRYPTO_mem_leaks_cb(CRYPTO_MEM_LEAK_CB *cb)
790 { 868 {
791 if (mh == NULL) return; 869 if (mh == NULL) return;
792 CRYPTO_w_lock(CRYPTO_LOCK_MALLOC2); 870 CRYPTO_w_lock(CRYPTO_LOCK_MALLOC2);
793 lh_doall_arg(mh, LHASH_DOALL_ARG_FN(cb_leak), &cb); 871 lh_MEM_doall_arg(mh, LHASH_DOALL_ARG_FN(cb_leak), PCRYPTO_MEM_LEAK_CB,
872 &cb);
794 CRYPTO_w_unlock(CRYPTO_LOCK_MALLOC2); 873 CRYPTO_w_unlock(CRYPTO_LOCK_MALLOC2);
795 } 874 }
796
797void CRYPTO_malloc_debug_init(void)
798 {
799 CRYPTO_set_mem_debug_functions(
800 CRYPTO_dbg_malloc,
801 CRYPTO_dbg_realloc,
802 CRYPTO_dbg_free,
803 CRYPTO_dbg_set_options,
804 CRYPTO_dbg_get_options);
805 CRYPTO_set_mem_info_functions(
806 CRYPTO_dbg_push_info,
807 CRYPTO_dbg_pop_info,
808 CRYPTO_dbg_remove_all_info);
809 }
810
811char *CRYPTO_strdup(const char *str, const char *file, int line)
812 {
813 char *ret = CRYPTO_malloc(strlen(str)+1, file, line);
814
815 strcpy(ret, str);
816 return ret;
817 }
diff --git a/src/lib/libcrypto/modes/cbc128.c b/src/lib/libcrypto/modes/cbc128.c
new file mode 100644
index 0000000000..8f8bd563b9
--- /dev/null
+++ b/src/lib/libcrypto/modes/cbc128.c
@@ -0,0 +1,206 @@
1/* ====================================================================
2 * Copyright (c) 2008 The OpenSSL Project. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 *
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in
13 * the documentation and/or other materials provided with the
14 * distribution.
15 *
16 * 3. All advertising materials mentioning features or use of this
17 * software must display the following acknowledgment:
18 * "This product includes software developed by the OpenSSL Project
19 * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
20 *
21 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
22 * endorse or promote products derived from this software without
23 * prior written permission. For written permission, please contact
24 * openssl-core@openssl.org.
25 *
26 * 5. Products derived from this software may not be called "OpenSSL"
27 * nor may "OpenSSL" appear in their names without prior written
28 * permission of the OpenSSL Project.
29 *
30 * 6. Redistributions of any form whatsoever must retain the following
31 * acknowledgment:
32 * "This product includes software developed by the OpenSSL Project
33 * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
34 *
35 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
36 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
37 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
38 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
39 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
40 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
41 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
42 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
43 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
44 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
45 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
46 * OF THE POSSIBILITY OF SUCH DAMAGE.
47 * ====================================================================
48 *
49 */
50
51#include "modes.h"
52#include <string.h>
53
54#ifndef MODES_DEBUG
55# ifndef NDEBUG
56# define NDEBUG
57# endif
58#endif
59#include <assert.h>
60
61#define STRICT_ALIGNMENT 1
62#if defined(__i386) || defined(__i386__) || \
63 defined(__x86_64) || defined(__x86_64__) || \
64 defined(_M_IX86) || defined(_M_AMD64) || defined(_M_X64) || \
65 defined(__s390__) || defined(__s390x__)
66# undef STRICT_ALIGNMENT
67# define STRICT_ALIGNMENT 0
68#endif
69
70void CRYPTO_cbc128_encrypt(const unsigned char *in, unsigned char *out,
71 size_t len, const void *key,
72 unsigned char ivec[16], block128_f block)
73{
74 size_t n;
75 const unsigned char *iv = ivec;
76
77 assert(in && out && key && ivec);
78
79#if !defined(OPENSSL_SMALL_FOOTPRINT)
80 if (STRICT_ALIGNMENT &&
81 ((size_t)in|(size_t)out|(size_t)ivec)%sizeof(size_t) != 0) {
82 while (len>=16) {
83 for(n=0; n<16; ++n)
84 out[n] = in[n] ^ iv[n];
85 (*block)(out, out, key);
86 iv = out;
87 len -= 16;
88 in += 16;
89 out += 16;
90 }
91 } else {
92 while (len>=16) {
93 for(n=0; n<16; n+=sizeof(size_t))
94 *(size_t*)(out+n) =
95 *(size_t*)(in+n) ^ *(size_t*)(iv+n);
96 (*block)(out, out, key);
97 iv = out;
98 len -= 16;
99 in += 16;
100 out += 16;
101 }
102 }
103#endif
104 while (len) {
105 for(n=0; n<16 && n<len; ++n)
106 out[n] = in[n] ^ iv[n];
107 for(; n<16; ++n)
108 out[n] = iv[n];
109 (*block)(out, out, key);
110 iv = out;
111 if (len<=16) break;
112 len -= 16;
113 in += 16;
114 out += 16;
115 }
116 memcpy(ivec,iv,16);
117}
118
119void CRYPTO_cbc128_decrypt(const unsigned char *in, unsigned char *out,
120 size_t len, const void *key,
121 unsigned char ivec[16], block128_f block)
122{
123 size_t n;
124 union { size_t align; unsigned char c[16]; } tmp;
125
126 assert(in && out && key && ivec);
127
128#if !defined(OPENSSL_SMALL_FOOTPRINT)
129 if (in != out) {
130 const unsigned char *iv = ivec;
131
132 if (STRICT_ALIGNMENT &&
133 ((size_t)in|(size_t)out|(size_t)ivec)%sizeof(size_t) != 0) {
134 while (len>=16) {
135 (*block)(in, out, key);
136 for(n=0; n<16; ++n)
137 out[n] ^= iv[n];
138 iv = in;
139 len -= 16;
140 in += 16;
141 out += 16;
142 }
143 }
144 else {
145 while (len>=16) {
146 (*block)(in, out, key);
147 for(n=0; n<16; n+=sizeof(size_t))
148 *(size_t *)(out+n) ^= *(size_t *)(iv+n);
149 iv = in;
150 len -= 16;
151 in += 16;
152 out += 16;
153 }
154 }
155 memcpy(ivec,iv,16);
156 } else {
157 if (STRICT_ALIGNMENT &&
158 ((size_t)in|(size_t)out|(size_t)ivec)%sizeof(size_t) != 0) {
159 unsigned char c;
160 while (len>=16) {
161 (*block)(in, tmp.c, key);
162 for(n=0; n<16; ++n) {
163 c = in[n];
164 out[n] = tmp.c[n] ^ ivec[n];
165 ivec[n] = c;
166 }
167 len -= 16;
168 in += 16;
169 out += 16;
170 }
171 }
172 else {
173 size_t c;
174 while (len>=16) {
175 (*block)(in, tmp.c, key);
176 for(n=0; n<16; n+=sizeof(size_t)) {
177 c = *(size_t *)(in+n);
178 *(size_t *)(out+n) =
179 *(size_t *)(tmp.c+n) ^ *(size_t *)(ivec+n);
180 *(size_t *)(ivec+n) = c;
181 }
182 len -= 16;
183 in += 16;
184 out += 16;
185 }
186 }
187 }
188#endif
189 while (len) {
190 unsigned char c;
191 (*block)(in, tmp.c, key);
192 for(n=0; n<16 && n<len; ++n) {
193 c = in[n];
194 out[n] = tmp.c[n] ^ ivec[n];
195 ivec[n] = c;
196 }
197 if (len<=16) {
198 for (; n<16; ++n)
199 ivec[n] = in[n];
200 break;
201 }
202 len -= 16;
203 in += 16;
204 out += 16;
205 }
206}
diff --git a/src/lib/libcrypto/modes/cfb128.c b/src/lib/libcrypto/modes/cfb128.c
new file mode 100644
index 0000000000..e5938c6137
--- /dev/null
+++ b/src/lib/libcrypto/modes/cfb128.c
@@ -0,0 +1,249 @@
1/* ====================================================================
2 * Copyright (c) 2008 The OpenSSL Project. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 *
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in
13 * the documentation and/or other materials provided with the
14 * distribution.
15 *
16 * 3. All advertising materials mentioning features or use of this
17 * software must display the following acknowledgment:
18 * "This product includes software developed by the OpenSSL Project
19 * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
20 *
21 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
22 * endorse or promote products derived from this software without
23 * prior written permission. For written permission, please contact
24 * openssl-core@openssl.org.
25 *
26 * 5. Products derived from this software may not be called "OpenSSL"
27 * nor may "OpenSSL" appear in their names without prior written
28 * permission of the OpenSSL Project.
29 *
30 * 6. Redistributions of any form whatsoever must retain the following
31 * acknowledgment:
32 * "This product includes software developed by the OpenSSL Project
33 * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
34 *
35 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
36 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
37 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
38 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
39 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
40 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
41 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
42 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
43 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
44 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
45 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
46 * OF THE POSSIBILITY OF SUCH DAMAGE.
47 * ====================================================================
48 *
49 */
50
51#include "modes.h"
52#include <string.h>
53
54#ifndef MODES_DEBUG
55# ifndef NDEBUG
56# define NDEBUG
57# endif
58#endif
59#include <assert.h>
60
61#define STRICT_ALIGNMENT
62#if defined(__i386) || defined(__i386__) || \
63 defined(__x86_64) || defined(__x86_64__) || \
64 defined(_M_IX86) || defined(_M_AMD64) || defined(_M_X64) || \
65 defined(__s390__) || defined(__s390x__)
66# undef STRICT_ALIGNMENT
67#endif
68
69/* The input and output encrypted as though 128bit cfb mode is being
70 * used. The extra state information to record how much of the
71 * 128bit block we have used is contained in *num;
72 */
73void CRYPTO_cfb128_encrypt(const unsigned char *in, unsigned char *out,
74 size_t len, const void *key,
75 unsigned char ivec[16], int *num,
76 int enc, block128_f block)
77{
78 unsigned int n;
79 size_t l = 0;
80
81 assert(in && out && key && ivec && num);
82
83 n = *num;
84
85 if (enc) {
86#if !defined(OPENSSL_SMALL_FOOTPRINT)
87 if (16%sizeof(size_t) == 0) do { /* always true actually */
88 while (n && len) {
89 *(out++) = ivec[n] ^= *(in++);
90 --len;
91 n = (n+1) % 16;
92 }
93#if defined(STRICT_ALIGNMENT)
94 if (((size_t)in|(size_t)out|(size_t)ivec)%sizeof(size_t) != 0)
95 break;
96#endif
97 while (len>=16) {
98 (*block)(ivec, ivec, key);
99 for (; n<16; n+=sizeof(size_t)) {
100 *(size_t*)(out+n) =
101 *(size_t*)(ivec+n) ^= *(size_t*)(in+n);
102 }
103 len -= 16;
104 out += 16;
105 in += 16;
106 n = 0;
107 }
108 if (len) {
109 (*block)(ivec, ivec, key);
110 while (len--) {
111 out[n] = ivec[n] ^= in[n];
112 ++n;
113 }
114 }
115 *num = n;
116 return;
117 } while (0);
118 /* the rest would be commonly eliminated by x86* compiler */
119#endif
120 while (l<len) {
121 if (n == 0) {
122 (*block)(ivec, ivec, key);
123 }
124 out[l] = ivec[n] ^= in[l];
125 ++l;
126 n = (n+1) % 16;
127 }
128 *num = n;
129 } else {
130#if !defined(OPENSSL_SMALL_FOOTPRINT)
131 if (16%sizeof(size_t) == 0) do { /* always true actually */
132 while (n && len) {
133 unsigned char c;
134 *(out++) = ivec[n] ^ (c = *(in++)); ivec[n] = c;
135 --len;
136 n = (n+1) % 16;
137 }
138#if defined(STRICT_ALIGNMENT)
139 if (((size_t)in|(size_t)out|(size_t)ivec)%sizeof(size_t) != 0)
140 break;
141#endif
142 while (len>=16) {
143 (*block)(ivec, ivec, key);
144 for (; n<16; n+=sizeof(size_t)) {
145 size_t t = *(size_t*)(in+n);
146 *(size_t*)(out+n) = *(size_t*)(ivec+n) ^ t;
147 *(size_t*)(ivec+n) = t;
148 }
149 len -= 16;
150 out += 16;
151 in += 16;
152 n = 0;
153 }
154 if (len) {
155 (*block)(ivec, ivec, key);
156 while (len--) {
157 unsigned char c;
158 out[n] = ivec[n] ^ (c = in[n]); ivec[n] = c;
159 ++n;
160 }
161 }
162 *num = n;
163 return;
164 } while (0);
165 /* the rest would be commonly eliminated by x86* compiler */
166#endif
167 while (l<len) {
168 unsigned char c;
169 if (n == 0) {
170 (*block)(ivec, ivec, key);
171 }
172 out[l] = ivec[n] ^ (c = in[l]); ivec[n] = c;
173 ++l;
174 n = (n+1) % 16;
175 }
176 *num=n;
177 }
178}
179
180/* This expects a single block of size nbits for both in and out. Note that
181 it corrupts any extra bits in the last byte of out */
182static void cfbr_encrypt_block(const unsigned char *in,unsigned char *out,
183 int nbits,const void *key,
184 unsigned char ivec[16],int enc,
185 block128_f block)
186{
187 int n,rem,num;
188 unsigned char ovec[16*2 + 1]; /* +1 because we dererefence (but don't use) one byte off the end */
189
190 if (nbits<=0 || nbits>128) return;
191
192 /* fill in the first half of the new IV with the current IV */
193 memcpy(ovec,ivec,16);
194 /* construct the new IV */
195 (*block)(ivec,ivec,key);
196 num = (nbits+7)/8;
197 if (enc) /* encrypt the input */
198 for(n=0 ; n < num ; ++n)
199 out[n] = (ovec[16+n] = in[n] ^ ivec[n]);
200 else /* decrypt the input */
201 for(n=0 ; n < num ; ++n)
202 out[n] = (ovec[16+n] = in[n]) ^ ivec[n];
203 /* shift ovec left... */
204 rem = nbits%8;
205 num = nbits/8;
206 if(rem==0)
207 memcpy(ivec,ovec+num,16);
208 else
209 for(n=0 ; n < 16 ; ++n)
210 ivec[n] = ovec[n+num]<<rem | ovec[n+num+1]>>(8-rem);
211
212 /* it is not necessary to cleanse ovec, since the IV is not secret */
213}
214
215/* N.B. This expects the input to be packed, MS bit first */
216void CRYPTO_cfb128_1_encrypt(const unsigned char *in, unsigned char *out,
217 size_t bits, const void *key,
218 unsigned char ivec[16], int *num,
219 int enc, block128_f block)
220{
221 size_t n;
222 unsigned char c[1],d[1];
223
224 assert(in && out && key && ivec && num);
225 assert(*num == 0);
226
227 for(n=0 ; n<bits ; ++n)
228 {
229 c[0]=(in[n/8]&(1 << (7-n%8))) ? 0x80 : 0;
230 cfbr_encrypt_block(c,d,1,key,ivec,enc,block);
231 out[n/8]=(out[n/8]&~(1 << (unsigned int)(7-n%8))) |
232 ((d[0]&0x80) >> (unsigned int)(n%8));
233 }
234}
235
236void CRYPTO_cfb128_8_encrypt(const unsigned char *in, unsigned char *out,
237 size_t length, const void *key,
238 unsigned char ivec[16], int *num,
239 int enc, block128_f block)
240{
241 size_t n;
242
243 assert(in && out && key && ivec && num);
244 assert(*num == 0);
245
246 for(n=0 ; n<length ; ++n)
247 cfbr_encrypt_block(&in[n],&out[n],8,key,ivec,enc,block);
248}
249
diff --git a/src/lib/libcrypto/modes/ctr128.c b/src/lib/libcrypto/modes/ctr128.c
new file mode 100644
index 0000000000..932037f551
--- /dev/null
+++ b/src/lib/libcrypto/modes/ctr128.c
@@ -0,0 +1,184 @@
1/* ====================================================================
2 * Copyright (c) 2008 The OpenSSL Project. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 *
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in
13 * the documentation and/or other materials provided with the
14 * distribution.
15 *
16 * 3. All advertising materials mentioning features or use of this
17 * software must display the following acknowledgment:
18 * "This product includes software developed by the OpenSSL Project
19 * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
20 *
21 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
22 * endorse or promote products derived from this software without
23 * prior written permission. For written permission, please contact
24 * openssl-core@openssl.org.
25 *
26 * 5. Products derived from this software may not be called "OpenSSL"
27 * nor may "OpenSSL" appear in their names without prior written
28 * permission of the OpenSSL Project.
29 *
30 * 6. Redistributions of any form whatsoever must retain the following
31 * acknowledgment:
32 * "This product includes software developed by the OpenSSL Project
33 * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
34 *
35 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
36 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
37 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
38 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
39 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
40 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
41 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
42 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
43 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
44 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
45 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
46 * OF THE POSSIBILITY OF SUCH DAMAGE.
47 * ====================================================================
48 *
49 */
50
51#include "modes.h"
52#include <string.h>
53
54#ifndef MODES_DEBUG
55# ifndef NDEBUG
56# define NDEBUG
57# endif
58#endif
59#include <assert.h>
60
61typedef unsigned int u32;
62typedef unsigned char u8;
63
64#define STRICT_ALIGNMENT
65#if defined(__i386) || defined(__i386__) || \
66 defined(__x86_64) || defined(__x86_64__) || \
67 defined(_M_IX86) || defined(_M_AMD64) || defined(_M_X64) || \
68 defined(__s390__) || defined(__s390x__)
69# undef STRICT_ALIGNMENT
70#endif
71
72/* NOTE: the IV/counter CTR mode is big-endian. The code itself
73 * is endian-neutral. */
74
75/* increment counter (128-bit int) by 1 */
76static void ctr128_inc(unsigned char *counter) {
77 u32 n=16;
78 u8 c;
79
80 do {
81 --n;
82 c = counter[n];
83 ++c;
84 counter[n] = c;
85 if (c) return;
86 } while (n);
87}
88
89#if !defined(OPENSSL_SMALL_FOOTPRINT)
90static void ctr128_inc_aligned(unsigned char *counter) {
91 size_t *data,c,n;
92 const union { long one; char little; } is_endian = {1};
93
94 if (is_endian.little) {
95 ctr128_inc(counter);
96 return;
97 }
98
99 data = (size_t *)counter;
100 n = 16/sizeof(size_t);
101 do {
102 --n;
103 c = data[n];
104 ++c;
105 data[n] = c;
106 if (c) return;
107 } while (n);
108}
109#endif
110
111/* The input encrypted as though 128bit counter mode is being
112 * used. The extra state information to record how much of the
113 * 128bit block we have used is contained in *num, and the
114 * encrypted counter is kept in ecount_buf. Both *num and
115 * ecount_buf must be initialised with zeros before the first
116 * call to CRYPTO_ctr128_encrypt().
117 *
118 * This algorithm assumes that the counter is in the x lower bits
119 * of the IV (ivec), and that the application has full control over
120 * overflow and the rest of the IV. This implementation takes NO
121 * responsability for checking that the counter doesn't overflow
122 * into the rest of the IV when incremented.
123 */
124void CRYPTO_ctr128_encrypt(const unsigned char *in, unsigned char *out,
125 size_t len, const void *key,
126 unsigned char ivec[16], unsigned char ecount_buf[16],
127 unsigned int *num, block128_f block)
128{
129 unsigned int n;
130 size_t l=0;
131
132 assert(in && out && key && ecount_buf && num);
133 assert(*num < 16);
134
135 n = *num;
136
137#if !defined(OPENSSL_SMALL_FOOTPRINT)
138 if (16%sizeof(size_t) == 0) do { /* always true actually */
139 while (n && len) {
140 *(out++) = *(in++) ^ ecount_buf[n];
141 --len;
142 n = (n+1) % 16;
143 }
144
145#if defined(STRICT_ALIGNMENT)
146 if (((size_t)in|(size_t)out|(size_t)ivec)%sizeof(size_t) != 0)
147 break;
148#endif
149 while (len>=16) {
150 (*block)(ivec, ecount_buf, key);
151 ctr128_inc_aligned(ivec);
152 for (; n<16; n+=sizeof(size_t))
153 *(size_t *)(out+n) =
154 *(size_t *)(in+n) ^ *(size_t *)(ecount_buf+n);
155 len -= 16;
156 out += 16;
157 in += 16;
158 n = 0;
159 }
160 if (len) {
161 (*block)(ivec, ecount_buf, key);
162 ctr128_inc_aligned(ivec);
163 while (len--) {
164 out[n] = in[n] ^ ecount_buf[n];
165 ++n;
166 }
167 }
168 *num = n;
169 return;
170 } while(0);
171 /* the rest would be commonly eliminated by x86* compiler */
172#endif
173 while (l<len) {
174 if (n==0) {
175 (*block)(ivec, ecount_buf, key);
176 ctr128_inc(ivec);
177 }
178 out[l] = in[l] ^ ecount_buf[n];
179 ++l;
180 n = (n+1) % 16;
181 }
182
183 *num=n;
184}
diff --git a/src/lib/libcrypto/modes/cts128.c b/src/lib/libcrypto/modes/cts128.c
new file mode 100644
index 0000000000..e0430f9fdc
--- /dev/null
+++ b/src/lib/libcrypto/modes/cts128.c
@@ -0,0 +1,259 @@
1/* ====================================================================
2 * Copyright (c) 2008 The OpenSSL Project. All rights reserved.
3 *
4 * Rights for redistribution and usage in source and binary
5 * forms are granted according to the OpenSSL license.
6 */
7
8#include "modes.h"
9#include <string.h>
10
11#ifndef MODES_DEBUG
12# ifndef NDEBUG
13# define NDEBUG
14# endif
15#endif
16#include <assert.h>
17
18/*
19 * Trouble with Ciphertext Stealing, CTS, mode is that there is no
20 * common official specification, but couple of cipher/application
21 * specific ones: RFC2040 and RFC3962. Then there is 'Proposal to
22 * Extend CBC Mode By "Ciphertext Stealing"' at NIST site, which
23 * deviates from mentioned RFCs. Most notably it allows input to be
24 * of block length and it doesn't flip the order of the last two
25 * blocks. CTS is being discussed even in ECB context, but it's not
26 * adopted for any known application. This implementation complies
27 * with mentioned RFCs and [as such] extends CBC mode.
28 */
29
30size_t CRYPTO_cts128_encrypt_block(const unsigned char *in, unsigned char *out,
31 size_t len, const void *key,
32 unsigned char ivec[16], block128_f block)
33{ size_t residue, n;
34
35 assert (in && out && key && ivec);
36
37 if (len <= 16) return 0;
38
39 if ((residue=len%16) == 0) residue = 16;
40
41 len -= residue;
42
43 CRYPTO_cbc128_encrypt(in,out,len,key,ivec,block);
44
45 in += len;
46 out += len;
47
48 for (n=0; n<residue; ++n)
49 ivec[n] ^= in[n];
50 (*block)(ivec,ivec,key);
51 memcpy(out,out-16,residue);
52 memcpy(out-16,ivec,16);
53
54 return len+residue;
55}
56
57size_t CRYPTO_cts128_encrypt(const unsigned char *in, unsigned char *out,
58 size_t len, const void *key,
59 unsigned char ivec[16], cbc128_f cbc)
60{ size_t residue;
61 union { size_t align; unsigned char c[16]; } tmp;
62
63 assert (in && out && key && ivec);
64
65 if (len <= 16) return 0;
66
67 if ((residue=len%16) == 0) residue = 16;
68
69 len -= residue;
70
71 (*cbc)(in,out,len,key,ivec,1);
72
73 in += len;
74 out += len;
75
76#if defined(CBC_HANDLES_TRUNCATED_IO)
77 memcpy(tmp.c,out-16,16);
78 (*cbc)(in,out-16,residue,key,ivec,1);
79 memcpy(out,tmp.c,residue);
80#else
81 {
82 size_t n;
83 for (n=0; n<16; n+=sizeof(size_t))
84 *(size_t *)(tmp.c+n) = 0;
85 memcpy(tmp.c,in,residue);
86 }
87 memcpy(out,out-16,residue);
88 (*cbc)(tmp.c,out-16,16,key,ivec,1);
89#endif
90 return len+residue;
91}
92
93size_t CRYPTO_cts128_decrypt_block(const unsigned char *in, unsigned char *out,
94 size_t len, const void *key,
95 unsigned char ivec[16], block128_f block)
96{ size_t residue, n;
97 union { size_t align; unsigned char c[32]; } tmp;
98
99 assert (in && out && key && ivec);
100
101 if (len<=16) return 0;
102
103 if ((residue=len%16) == 0) residue = 16;
104
105 len -= 16+residue;
106
107 if (len) {
108 CRYPTO_cbc128_decrypt(in,out,len,key,ivec,block);
109 in += len;
110 out += len;
111 }
112
113 (*block)(in,tmp.c+16,key);
114
115 for (n=0; n<16; n+=sizeof(size_t))
116 *(size_t *)(tmp.c+n) = *(size_t *)(tmp.c+16+n);
117 memcpy(tmp.c,in+16,residue);
118 (*block)(tmp.c,tmp.c,key);
119
120 for(n=0; n<16; ++n) {
121 unsigned char c = in[n];
122 out[n] = tmp.c[n] ^ ivec[n];
123 ivec[n] = c;
124 }
125 for(residue+=16; n<residue; ++n)
126 out[n] = tmp.c[n] ^ in[n];
127
128 return len+residue-16;
129}
130
131size_t CRYPTO_cts128_decrypt(const unsigned char *in, unsigned char *out,
132 size_t len, const void *key,
133 unsigned char ivec[16], cbc128_f cbc)
134{ size_t residue, n;
135 union { size_t align; unsigned char c[32]; } tmp;
136
137 assert (in && out && key && ivec);
138
139 if (len<=16) return 0;
140
141 if ((residue=len%16) == 0) residue = 16;
142
143 len -= 16+residue;
144
145 if (len) {
146 (*cbc)(in,out,len,key,ivec,0);
147 in += len;
148 out += len;
149 }
150
151 for (n=16; n<32; n+=sizeof(size_t))
152 *(size_t *)(tmp.c+n) = 0;
153 /* this places in[16] at &tmp.c[16] and decrypted block at &tmp.c[0] */
154 (*cbc)(in,tmp.c,16,key,tmp.c+16,0);
155
156 memcpy(tmp.c,in+16,residue);
157#if defined(CBC_HANDLES_TRUNCATED_IO)
158 (*cbc)(tmp.c,out,16+residue,key,ivec,0);
159#else
160 (*cbc)(tmp.c,tmp.c,32,key,ivec,0);
161 memcpy(out,tmp.c,16+residue);
162#endif
163 return len+residue;
164}
165
166#if defined(SELFTEST)
167#include <stdio.h>
168#include <openssl/aes.h>
169
170/* test vectors from RFC 3962 */
171static const unsigned char test_key[16] = "chicken teriyaki";
172static const unsigned char test_input[64] =
173 "I would like the" " General Gau's C"
174 "hicken, please, " "and wonton soup.";
175static const unsigned char test_iv[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
176
177static const unsigned char vector_17[17] =
178{0xc6,0x35,0x35,0x68,0xf2,0xbf,0x8c,0xb4, 0xd8,0xa5,0x80,0x36,0x2d,0xa7,0xff,0x7f,
179 0x97};
180static const unsigned char vector_31[31] =
181{0xfc,0x00,0x78,0x3e,0x0e,0xfd,0xb2,0xc1, 0xd4,0x45,0xd4,0xc8,0xef,0xf7,0xed,0x22,
182 0x97,0x68,0x72,0x68,0xd6,0xec,0xcc,0xc0, 0xc0,0x7b,0x25,0xe2,0x5e,0xcf,0xe5};
183static const unsigned char vector_32[32] =
184{0x39,0x31,0x25,0x23,0xa7,0x86,0x62,0xd5, 0xbe,0x7f,0xcb,0xcc,0x98,0xeb,0xf5,0xa8,
185 0x97,0x68,0x72,0x68,0xd6,0xec,0xcc,0xc0, 0xc0,0x7b,0x25,0xe2,0x5e,0xcf,0xe5,0x84};
186static const unsigned char vector_47[47] =
187{0x97,0x68,0x72,0x68,0xd6,0xec,0xcc,0xc0, 0xc0,0x7b,0x25,0xe2,0x5e,0xcf,0xe5,0x84,
188 0xb3,0xff,0xfd,0x94,0x0c,0x16,0xa1,0x8c, 0x1b,0x55,0x49,0xd2,0xf8,0x38,0x02,0x9e,
189 0x39,0x31,0x25,0x23,0xa7,0x86,0x62,0xd5, 0xbe,0x7f,0xcb,0xcc,0x98,0xeb,0xf5};
190static const unsigned char vector_48[48] =
191{0x97,0x68,0x72,0x68,0xd6,0xec,0xcc,0xc0, 0xc0,0x7b,0x25,0xe2,0x5e,0xcf,0xe5,0x84,
192 0x9d,0xad,0x8b,0xbb,0x96,0xc4,0xcd,0xc0, 0x3b,0xc1,0x03,0xe1,0xa1,0x94,0xbb,0xd8,
193 0x39,0x31,0x25,0x23,0xa7,0x86,0x62,0xd5, 0xbe,0x7f,0xcb,0xcc,0x98,0xeb,0xf5,0xa8};
194static const unsigned char vector_64[64] =
195{0x97,0x68,0x72,0x68,0xd6,0xec,0xcc,0xc0, 0xc0,0x7b,0x25,0xe2,0x5e,0xcf,0xe5,0x84,
196 0x39,0x31,0x25,0x23,0xa7,0x86,0x62,0xd5, 0xbe,0x7f,0xcb,0xcc,0x98,0xeb,0xf5,0xa8,
197 0x48,0x07,0xef,0xe8,0x36,0xee,0x89,0xa5, 0x26,0x73,0x0d,0xbc,0x2f,0x7b,0xc8,0x40,
198 0x9d,0xad,0x8b,0xbb,0x96,0xc4,0xcd,0xc0, 0x3b,0xc1,0x03,0xe1,0xa1,0x94,0xbb,0xd8};
199
200static AES_KEY encks, decks;
201
202void test_vector(const unsigned char *vector,size_t len)
203{ unsigned char cleartext[64];
204 unsigned char iv[sizeof(test_iv)];
205 unsigned char ciphertext[64];
206 size_t tail;
207
208 printf("vector_%d\n",len); fflush(stdout);
209
210 if ((tail=len%16) == 0) tail = 16;
211 tail += 16;
212
213 /* test block-based encryption */
214 memcpy(iv,test_iv,sizeof(test_iv));
215 CRYPTO_cts128_encrypt_block(test_input,ciphertext,len,&encks,iv,(block128_f)AES_encrypt);
216 if (memcmp(ciphertext,vector,len))
217 fprintf(stderr,"output_%d mismatch\n",len), exit(1);
218 if (memcmp(iv,vector+len-tail,sizeof(iv)))
219 fprintf(stderr,"iv_%d mismatch\n",len), exit(1);
220
221 /* test block-based decryption */
222 memcpy(iv,test_iv,sizeof(test_iv));
223 CRYPTO_cts128_decrypt_block(ciphertext,cleartext,len,&decks,iv,(block128_f)AES_decrypt);
224 if (memcmp(cleartext,test_input,len))
225 fprintf(stderr,"input_%d mismatch\n",len), exit(2);
226 if (memcmp(iv,vector+len-tail,sizeof(iv)))
227 fprintf(stderr,"iv_%d mismatch\n",len), exit(2);
228
229 /* test streamed encryption */
230 memcpy(iv,test_iv,sizeof(test_iv));
231 CRYPTO_cts128_encrypt(test_input,ciphertext,len,&encks,iv,(cbc128_f)AES_cbc_encrypt);
232 if (memcmp(ciphertext,vector,len))
233 fprintf(stderr,"output_%d mismatch\n",len), exit(3);
234 if (memcmp(iv,vector+len-tail,sizeof(iv)))
235 fprintf(stderr,"iv_%d mismatch\n",len), exit(3);
236
237 /* test streamed decryption */
238 memcpy(iv,test_iv,sizeof(test_iv));
239 CRYPTO_cts128_decrypt(ciphertext,cleartext,len,&decks,iv,(cbc128_f)AES_cbc_encrypt);
240 if (memcmp(cleartext,test_input,len))
241 fprintf(stderr,"input_%d mismatch\n",len), exit(4);
242 if (memcmp(iv,vector+len-tail,sizeof(iv)))
243 fprintf(stderr,"iv_%d mismatch\n",len), exit(4);
244}
245
246main()
247{
248 AES_set_encrypt_key(test_key,128,&encks);
249 AES_set_decrypt_key(test_key,128,&decks);
250
251 test_vector(vector_17,sizeof(vector_17));
252 test_vector(vector_31,sizeof(vector_31));
253 test_vector(vector_32,sizeof(vector_32));
254 test_vector(vector_47,sizeof(vector_47));
255 test_vector(vector_48,sizeof(vector_48));
256 test_vector(vector_64,sizeof(vector_64));
257 exit(0);
258}
259#endif
diff --git a/src/lib/libcrypto/modes/modes.h b/src/lib/libcrypto/modes/modes.h
new file mode 100644
index 0000000000..af8d97d795
--- /dev/null
+++ b/src/lib/libcrypto/modes/modes.h
@@ -0,0 +1,59 @@
1/* ====================================================================
2 * Copyright (c) 2008 The OpenSSL Project. All rights reserved.
3 *
4 * Rights for redistribution and usage in source and binary
5 * forms are granted according to the OpenSSL license.
6 */
7
8#include <stddef.h>
9
10typedef void (*block128_f)(const unsigned char in[16],
11 unsigned char out[16],
12 const void *key);
13
14typedef void (*cbc128_f)(const unsigned char *in, unsigned char *out,
15 size_t len, const void *key,
16 unsigned char ivec[16], int enc);
17
18void CRYPTO_cbc128_encrypt(const unsigned char *in, unsigned char *out,
19 size_t len, const void *key,
20 unsigned char ivec[16], block128_f block);
21void CRYPTO_cbc128_decrypt(const unsigned char *in, unsigned char *out,
22 size_t len, const void *key,
23 unsigned char ivec[16], block128_f block);
24
25void CRYPTO_ctr128_encrypt(const unsigned char *in, unsigned char *out,
26 size_t len, const void *key,
27 unsigned char ivec[16], unsigned char ecount_buf[16],
28 unsigned int *num, block128_f block);
29
30void CRYPTO_ofb128_encrypt(const unsigned char *in, unsigned char *out,
31 size_t len, const void *key,
32 unsigned char ivec[16], int *num,
33 block128_f block);
34
35void CRYPTO_cfb128_encrypt(const unsigned char *in, unsigned char *out,
36 size_t len, const void *key,
37 unsigned char ivec[16], int *num,
38 int enc, block128_f block);
39void CRYPTO_cfb128_8_encrypt(const unsigned char *in, unsigned char *out,
40 size_t length, const void *key,
41 unsigned char ivec[16], int *num,
42 int enc, block128_f block);
43void CRYPTO_cfb128_1_encrypt(const unsigned char *in, unsigned char *out,
44 size_t bits, const void *key,
45 unsigned char ivec[16], int *num,
46 int enc, block128_f block);
47
48size_t CRYPTO_cts128_encrypt_block(const unsigned char *in, unsigned char *out,
49 size_t len, const void *key,
50 unsigned char ivec[16], block128_f block);
51size_t CRYPTO_cts128_encrypt(const unsigned char *in, unsigned char *out,
52 size_t len, const void *key,
53 unsigned char ivec[16], cbc128_f cbc);
54size_t CRYPTO_cts128_decrypt_block(const unsigned char *in, unsigned char *out,
55 size_t len, const void *key,
56 unsigned char ivec[16], block128_f block);
57size_t CRYPTO_cts128_decrypt(const unsigned char *in, unsigned char *out,
58 size_t len, const void *key,
59 unsigned char ivec[16], cbc128_f cbc);
diff --git a/src/lib/libcrypto/modes/ofb128.c b/src/lib/libcrypto/modes/ofb128.c
new file mode 100644
index 0000000000..c732e2ec58
--- /dev/null
+++ b/src/lib/libcrypto/modes/ofb128.c
@@ -0,0 +1,128 @@
1/* ====================================================================
2 * Copyright (c) 2008 The OpenSSL Project. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 *
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in
13 * the documentation and/or other materials provided with the
14 * distribution.
15 *
16 * 3. All advertising materials mentioning features or use of this
17 * software must display the following acknowledgment:
18 * "This product includes software developed by the OpenSSL Project
19 * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
20 *
21 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
22 * endorse or promote products derived from this software without
23 * prior written permission. For written permission, please contact
24 * openssl-core@openssl.org.
25 *
26 * 5. Products derived from this software may not be called "OpenSSL"
27 * nor may "OpenSSL" appear in their names without prior written
28 * permission of the OpenSSL Project.
29 *
30 * 6. Redistributions of any form whatsoever must retain the following
31 * acknowledgment:
32 * "This product includes software developed by the OpenSSL Project
33 * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
34 *
35 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
36 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
37 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
38 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
39 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
40 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
41 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
42 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
43 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
44 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
45 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
46 * OF THE POSSIBILITY OF SUCH DAMAGE.
47 * ====================================================================
48 *
49 */
50
51#include "modes.h"
52#include <string.h>
53
54#ifndef MODES_DEBUG
55# ifndef NDEBUG
56# define NDEBUG
57# endif
58#endif
59#include <assert.h>
60
61#define STRICT_ALIGNMENT
62#if defined(__i386) || defined(__i386__) || \
63 defined(__x86_64) || defined(__x86_64__) || \
64 defined(_M_IX86) || defined(_M_AMD64) || defined(_M_X64) || \
65 defined(__s390__) || defined(__s390x__)
66# undef STRICT_ALIGNMENT
67#endif
68
69/* The input and output encrypted as though 128bit ofb mode is being
70 * used. The extra state information to record how much of the
71 * 128bit block we have used is contained in *num;
72 */
73void CRYPTO_ofb128_encrypt(const unsigned char *in, unsigned char *out,
74 size_t len, const void *key,
75 unsigned char ivec[16], int *num,
76 block128_f block)
77{
78 unsigned int n;
79 size_t l=0;
80
81 assert(in && out && key && ivec && num);
82
83 n = *num;
84
85#if !defined(OPENSSL_SMALL_FOOTPRINT)
86 if (16%sizeof(size_t) == 0) do { /* always true actually */
87 while (n && len) {
88 *(out++) = *(in++) ^ ivec[n];
89 --len;
90 n = (n+1) % 16;
91 }
92#if defined(STRICT_ALIGNMENT)
93 if (((size_t)in|(size_t)out|(size_t)ivec)%sizeof(size_t) != 0)
94 break;
95#endif
96 while (len>=16) {
97 (*block)(ivec, ivec, key);
98 for (; n<16; n+=sizeof(size_t))
99 *(size_t*)(out+n) =
100 *(size_t*)(in+n) ^ *(size_t*)(ivec+n);
101 len -= 16;
102 out += 16;
103 in += 16;
104 n = 0;
105 }
106 if (len) {
107 (*block)(ivec, ivec, key);
108 while (len--) {
109 out[n] = in[n] ^ ivec[n];
110 ++n;
111 }
112 }
113 *num = n;
114 return;
115 } while(0);
116 /* the rest would be commonly eliminated by x86* compiler */
117#endif
118 while (l<len) {
119 if (n==0) {
120 (*block)(ivec, ivec, key);
121 }
122 out[l] = in[l] ^ ivec[n];
123 ++l;
124 n = (n+1) % 16;
125 }
126
127 *num=n;
128}
diff --git a/src/lib/libcrypto/o_str.c b/src/lib/libcrypto/o_str.c
index 59cc25094b..56104a6c34 100644
--- a/src/lib/libcrypto/o_str.c
+++ b/src/lib/libcrypto/o_str.c
@@ -60,7 +60,9 @@
60#include <e_os.h> 60#include <e_os.h>
61#include "o_str.h" 61#include "o_str.h"
62 62
63#if !defined(OPENSSL_IMPLEMENTS_strncasecmp) && !defined(OPENSSL_SYSNAME_WIN32) 63#if !defined(OPENSSL_IMPLEMENTS_strncasecmp) && \
64 !defined(OPENSSL_SYSNAME_WIN32) && \
65 !defined(NETWARE_CLIB)
64# include <strings.h> 66# include <strings.h>
65#endif 67#endif
66 68
diff --git a/src/lib/libcrypto/o_time.c b/src/lib/libcrypto/o_time.c
index e29091d650..eecbdd19f0 100644
--- a/src/lib/libcrypto/o_time.c
+++ b/src/lib/libcrypto/o_time.c
@@ -2,6 +2,9 @@
2/* Written by Richard Levitte (richard@levitte.org) for the OpenSSL 2/* Written by Richard Levitte (richard@levitte.org) for the OpenSSL
3 * project 2001. 3 * project 2001.
4 */ 4 */
5/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
6 * project 2008.
7 */
5/* ==================================================================== 8/* ====================================================================
6 * Copyright (c) 2001 The OpenSSL Project. All rights reserved. 9 * Copyright (c) 2001 The OpenSSL Project. All rights reserved.
7 * 10 *
@@ -73,7 +76,7 @@ struct tm *OPENSSL_gmtime(const time_t *timer, struct tm *result)
73 { 76 {
74 struct tm *ts = NULL; 77 struct tm *ts = NULL;
75 78
76#if defined(OPENSSL_THREADS) && !defined(OPENSSL_SYS_WIN32) && !defined(OPENSSL_SYS_OS2) && !defined(__CYGWIN32__) && (!defined(OPENSSL_SYS_VMS) || defined(gmtime_r)) && !defined(OPENSSL_SYS_MACOSX) && !defined(OPENSSL_SYS_SUNOS) 79#if defined(OPENSSL_THREADS) && !defined(OPENSSL_SYS_WIN32) && !defined(OPENSSL_SYS_OS2) && (!defined(OPENSSL_SYS_VMS) || defined(gmtime_r)) && !defined(OPENSSL_SYS_MACOSX) && !defined(OPENSSL_SYS_SUNOS)
77 /* should return &data, but doesn't on some systems, 80 /* should return &data, but doesn't on some systems,
78 so we don't even look at the return value */ 81 so we don't even look at the return value */
79 gmtime_r(timer,result); 82 gmtime_r(timer,result);
@@ -214,4 +217,150 @@ struct tm *OPENSSL_gmtime(const time_t *timer, struct tm *result)
214 } 217 }
215#endif 218#endif
216 return ts; 219 return ts;
217 } 220 }
221
222/* Take a tm structure and add an offset to it. This avoids any OS issues
223 * with restricted date types and overflows which cause the year 2038
224 * problem.
225 */
226
227#define SECS_PER_DAY (24 * 60 * 60)
228
229static long date_to_julian(int y, int m, int d);
230static void julian_to_date(long jd, int *y, int *m, int *d);
231
232int OPENSSL_gmtime_adj(struct tm *tm, int off_day, long offset_sec)
233 {
234 int offset_hms, offset_day;
235 long time_jd;
236 int time_year, time_month, time_day;
237 /* split offset into days and day seconds */
238 offset_day = offset_sec / SECS_PER_DAY;
239 /* Avoid sign issues with % operator */
240 offset_hms = offset_sec - (offset_day * SECS_PER_DAY);
241 offset_day += off_day;
242 /* Add current time seconds to offset */
243 offset_hms += tm->tm_hour * 3600 + tm->tm_min * 60 + tm->tm_sec;
244 /* Adjust day seconds if overflow */
245 if (offset_hms >= SECS_PER_DAY)
246 {
247 offset_day++;
248 offset_hms -= SECS_PER_DAY;
249 }
250 else if (offset_hms < 0)
251 {
252 offset_day--;
253 offset_hms += SECS_PER_DAY;
254 }
255
256 /* Convert date of time structure into a Julian day number.
257 */
258
259 time_year = tm->tm_year + 1900;
260 time_month = tm->tm_mon + 1;
261 time_day = tm->tm_mday;
262
263 time_jd = date_to_julian(time_year, time_month, time_day);
264
265 /* Work out Julian day of new date */
266 time_jd += offset_day;
267
268 if (time_jd < 0)
269 return 0;
270
271 /* Convert Julian day back to date */
272
273 julian_to_date(time_jd, &time_year, &time_month, &time_day);
274
275 if (time_year < 1900 || time_year > 9999)
276 return 0;
277
278 /* Update tm structure */
279
280 tm->tm_year = time_year - 1900;
281 tm->tm_mon = time_month - 1;
282 tm->tm_mday = time_day;
283
284 tm->tm_hour = offset_hms / 3600;
285 tm->tm_min = (offset_hms / 60) % 60;
286 tm->tm_sec = offset_hms % 60;
287
288 return 1;
289
290}
291
292/* Convert date to and from julian day
293 * Uses Fliegel & Van Flandern algorithm
294 */
295static long date_to_julian(int y, int m, int d)
296{
297 return (1461 * (y + 4800 + (m - 14) / 12)) / 4 +
298 (367 * (m - 2 - 12 * ((m - 14) / 12))) / 12 -
299 (3 * ((y + 4900 + (m - 14) / 12) / 100)) / 4 +
300 d - 32075;
301}
302
303static void julian_to_date(long jd, int *y, int *m, int *d)
304 {
305 long L = jd + 68569;
306 long n = (4 * L) / 146097;
307 long i, j;
308
309 L = L - (146097 * n + 3) / 4;
310 i = (4000 * (L + 1)) / 1461001;
311 L = L - (1461 * i) / 4 + 31;
312 j = (80 * L) / 2447;
313 *d = L - (2447 * j) / 80;
314 L = j / 11;
315 *m = j + 2 - (12 * L);
316 *y = 100 * (n - 49) + i + L;
317 }
318
319#ifdef OPENSSL_TIME_TEST
320
321#include <stdio.h>
322
323/* Time checking test code. Check times are identical for a wide range of
324 * offsets. This should be run on a machine with 64 bit time_t or it will
325 * trigger the very errors the routines fix.
326 */
327
328int main(int argc, char **argv)
329 {
330 long offset;
331 for (offset = 0; offset < 1000000; offset++)
332 {
333 check_time(offset);
334 check_time(-offset);
335 check_time(offset * 1000);
336 check_time(-offset * 1000);
337 }
338 }
339
340int check_time(long offset)
341 {
342 struct tm tm1, tm2;
343 time_t t1, t2;
344 time(&t1);
345 t2 = t1 + offset;
346 OPENSSL_gmtime(&t2, &tm2);
347 OPENSSL_gmtime(&t1, &tm1);
348 OPENSSL_gmtime_adj(&tm1, 0, offset);
349 if ((tm1.tm_year == tm2.tm_year) &&
350 (tm1.tm_mon == tm2.tm_mon) &&
351 (tm1.tm_mday == tm2.tm_mday) &&
352 (tm1.tm_hour == tm2.tm_hour) &&
353 (tm1.tm_min == tm2.tm_min) &&
354 (tm1.tm_sec == tm2.tm_sec))
355 return 1;
356 fprintf(stderr, "TIME ERROR!!\n");
357 fprintf(stderr, "Time1: %d/%d/%d, %d:%02d:%02d\n",
358 tm2.tm_mday, tm2.tm_mon + 1, tm2.tm_year + 1900,
359 tm2.tm_hour, tm2.tm_min, tm2.tm_sec);
360 fprintf(stderr, "Time2: %d/%d/%d, %d:%02d:%02d\n",
361 tm1.tm_mday, tm1.tm_mon + 1, tm1.tm_year + 1900,
362 tm1.tm_hour, tm1.tm_min, tm1.tm_sec);
363 return 0;
364 }
365
366#endif
diff --git a/src/lib/libcrypto/o_time.h b/src/lib/libcrypto/o_time.h
index e66044626d..e391da7508 100644
--- a/src/lib/libcrypto/o_time.h
+++ b/src/lib/libcrypto/o_time.h
@@ -62,5 +62,6 @@
62#include <time.h> 62#include <time.h>
63 63
64struct tm *OPENSSL_gmtime(const time_t *timer, struct tm *result); 64struct tm *OPENSSL_gmtime(const time_t *timer, struct tm *result);
65int OPENSSL_gmtime_adj(struct tm *tm, int offset_day, long offset_sec);
65 66
66#endif 67#endif
diff --git a/src/lib/libcrypto/objects/o_names.c b/src/lib/libcrypto/objects/o_names.c
index adb5731f76..84380a96a9 100644
--- a/src/lib/libcrypto/objects/o_names.c
+++ b/src/lib/libcrypto/objects/o_names.c
@@ -22,7 +22,8 @@
22/* I use the ex_data stuff to manage the identifiers for the obj_name_types 22/* I use the ex_data stuff to manage the identifiers for the obj_name_types
23 * that applications may define. I only really use the free function field. 23 * that applications may define. I only really use the free function field.
24 */ 24 */
25static LHASH *names_lh=NULL; 25DECLARE_LHASH_OF(OBJ_NAME);
26static LHASH_OF(OBJ_NAME) *names_lh=NULL;
26static int names_type_num=OBJ_NAME_TYPE_NUM; 27static int names_type_num=OBJ_NAME_TYPE_NUM;
27 28
28typedef struct name_funcs_st 29typedef struct name_funcs_st
@@ -46,11 +47,14 @@ static unsigned long obj_name_hash(const void *a_void);
46/* static int obj_name_cmp(OBJ_NAME *a,OBJ_NAME *b); */ 47/* static int obj_name_cmp(OBJ_NAME *a,OBJ_NAME *b); */
47static int obj_name_cmp(const void *a_void,const void *b_void); 48static int obj_name_cmp(const void *a_void,const void *b_void);
48 49
50static IMPLEMENT_LHASH_HASH_FN(obj_name, OBJ_NAME)
51static IMPLEMENT_LHASH_COMP_FN(obj_name, OBJ_NAME)
52
49int OBJ_NAME_init(void) 53int OBJ_NAME_init(void)
50 { 54 {
51 if (names_lh != NULL) return(1); 55 if (names_lh != NULL) return(1);
52 MemCheck_off(); 56 MemCheck_off();
53 names_lh=lh_new(obj_name_hash, obj_name_cmp); 57 names_lh=lh_OBJ_NAME_new();
54 MemCheck_on(); 58 MemCheck_on();
55 return(names_lh != NULL); 59 return(names_lh != NULL);
56 } 60 }
@@ -164,7 +168,7 @@ const char *OBJ_NAME_get(const char *name, int type)
164 168
165 for (;;) 169 for (;;)
166 { 170 {
167 ret=(OBJ_NAME *)lh_retrieve(names_lh,&on); 171 ret=lh_OBJ_NAME_retrieve(names_lh,&on);
168 if (ret == NULL) return(NULL); 172 if (ret == NULL) return(NULL);
169 if ((ret->alias) && !alias) 173 if ((ret->alias) && !alias)
170 { 174 {
@@ -200,7 +204,7 @@ int OBJ_NAME_add(const char *name, int type, const char *data)
200 onp->type=type; 204 onp->type=type;
201 onp->data=data; 205 onp->data=data;
202 206
203 ret=(OBJ_NAME *)lh_insert(names_lh,onp); 207 ret=lh_OBJ_NAME_insert(names_lh,onp);
204 if (ret != NULL) 208 if (ret != NULL)
205 { 209 {
206 /* free things */ 210 /* free things */
@@ -217,7 +221,7 @@ int OBJ_NAME_add(const char *name, int type, const char *data)
217 } 221 }
218 else 222 else
219 { 223 {
220 if (lh_error(names_lh)) 224 if (lh_OBJ_NAME_error(names_lh))
221 { 225 {
222 /* ERROR */ 226 /* ERROR */
223 return(0); 227 return(0);
@@ -235,7 +239,7 @@ int OBJ_NAME_remove(const char *name, int type)
235 type&= ~OBJ_NAME_ALIAS; 239 type&= ~OBJ_NAME_ALIAS;
236 on.name=name; 240 on.name=name;
237 on.type=type; 241 on.type=type;
238 ret=(OBJ_NAME *)lh_delete(names_lh,&on); 242 ret=lh_OBJ_NAME_delete(names_lh,&on);
239 if (ret != NULL) 243 if (ret != NULL)
240 { 244 {
241 /* free things */ 245 /* free things */
@@ -262,13 +266,13 @@ struct doall
262 void *arg; 266 void *arg;
263 }; 267 };
264 268
265static void do_all_fn(const OBJ_NAME *name,struct doall *d) 269static void do_all_fn_doall_arg(const OBJ_NAME *name,struct doall *d)
266 { 270 {
267 if(name->type == d->type) 271 if(name->type == d->type)
268 d->fn(name,d->arg); 272 d->fn(name,d->arg);
269 } 273 }
270 274
271static IMPLEMENT_LHASH_DOALL_ARG_FN(do_all_fn, const OBJ_NAME *, struct doall *) 275static IMPLEMENT_LHASH_DOALL_ARG_FN(do_all_fn, const OBJ_NAME, struct doall)
272 276
273void OBJ_NAME_do_all(int type,void (*fn)(const OBJ_NAME *,void *arg),void *arg) 277void OBJ_NAME_do_all(int type,void (*fn)(const OBJ_NAME *,void *arg),void *arg)
274 { 278 {
@@ -278,7 +282,8 @@ void OBJ_NAME_do_all(int type,void (*fn)(const OBJ_NAME *,void *arg),void *arg)
278 d.fn=fn; 282 d.fn=fn;
279 d.arg=arg; 283 d.arg=arg;
280 284
281 lh_doall_arg(names_lh,LHASH_DOALL_ARG_FN(do_all_fn),&d); 285 lh_OBJ_NAME_doall_arg(names_lh, LHASH_DOALL_ARG_FN(do_all_fn),
286 struct doall, &d);
282 } 287 }
283 288
284struct doall_sorted 289struct doall_sorted
@@ -313,7 +318,7 @@ void OBJ_NAME_do_all_sorted(int type,void (*fn)(const OBJ_NAME *,void *arg),
313 int n; 318 int n;
314 319
315 d.type=type; 320 d.type=type;
316 d.names=OPENSSL_malloc(lh_num_items(names_lh)*sizeof *d.names); 321 d.names=OPENSSL_malloc(lh_OBJ_NAME_num_items(names_lh)*sizeof *d.names);
317 d.n=0; 322 d.n=0;
318 OBJ_NAME_do_all(type,do_all_sorted_fn,&d); 323 OBJ_NAME_do_all(type,do_all_sorted_fn,&d);
319 324
@@ -327,18 +332,16 @@ void OBJ_NAME_do_all_sorted(int type,void (*fn)(const OBJ_NAME *,void *arg),
327 332
328static int free_type; 333static int free_type;
329 334
330static void names_lh_free(OBJ_NAME *onp) 335static void names_lh_free_doall(OBJ_NAME *onp)
331{ 336 {
332 if(onp == NULL) 337 if (onp == NULL)
333 return; 338 return;
334 339
335 if ((free_type < 0) || (free_type == onp->type)) 340 if (free_type < 0 || free_type == onp->type)
336 {
337 OBJ_NAME_remove(onp->name,onp->type); 341 OBJ_NAME_remove(onp->name,onp->type);
338 }
339 } 342 }
340 343
341static IMPLEMENT_LHASH_DOALL_FN(names_lh_free, OBJ_NAME *) 344static IMPLEMENT_LHASH_DOALL_FN(names_lh_free, OBJ_NAME)
342 345
343static void name_funcs_free(NAME_FUNCS *ptr) 346static void name_funcs_free(NAME_FUNCS *ptr)
344 { 347 {
@@ -352,18 +355,18 @@ void OBJ_NAME_cleanup(int type)
352 if (names_lh == NULL) return; 355 if (names_lh == NULL) return;
353 356
354 free_type=type; 357 free_type=type;
355 down_load=names_lh->down_load; 358 down_load=lh_OBJ_NAME_down_load(names_lh);
356 names_lh->down_load=0; 359 lh_OBJ_NAME_down_load(names_lh)=0;
357 360
358 lh_doall(names_lh,LHASH_DOALL_FN(names_lh_free)); 361 lh_OBJ_NAME_doall(names_lh,LHASH_DOALL_FN(names_lh_free));
359 if (type < 0) 362 if (type < 0)
360 { 363 {
361 lh_free(names_lh); 364 lh_OBJ_NAME_free(names_lh);
362 sk_NAME_FUNCS_pop_free(name_funcs_stack,name_funcs_free); 365 sk_NAME_FUNCS_pop_free(name_funcs_stack,name_funcs_free);
363 names_lh=NULL; 366 names_lh=NULL;
364 name_funcs_stack = NULL; 367 name_funcs_stack = NULL;
365 } 368 }
366 else 369 else
367 names_lh->down_load=down_load; 370 lh_OBJ_NAME_down_load(names_lh)=down_load;
368 } 371 }
369 372
diff --git a/src/lib/libcrypto/objects/obj_dat.c b/src/lib/libcrypto/objects/obj_dat.c
index 7fd7433241..8a342ba3eb 100644
--- a/src/lib/libcrypto/objects/obj_dat.c
+++ b/src/lib/libcrypto/objects/obj_dat.c
@@ -74,16 +74,17 @@
74#define NUM_SN 0 74#define NUM_SN 0
75#define NUM_LN 0 75#define NUM_LN 0
76#define NUM_OBJ 0 76#define NUM_OBJ 0
77static unsigned char lvalues[1]; 77static const unsigned char lvalues[1];
78static ASN1_OBJECT nid_objs[1]; 78static const ASN1_OBJECT nid_objs[1];
79static ASN1_OBJECT *sn_objs[1]; 79static const unsigned int sn_objs[1];
80static ASN1_OBJECT *ln_objs[1]; 80static const unsigned int ln_objs[1];
81static ASN1_OBJECT *obj_objs[1]; 81static const unsigned int obj_objs[1];
82#endif 82#endif
83 83
84static int sn_cmp(const void *a, const void *b); 84DECLARE_OBJ_BSEARCH_CMP_FN(const ASN1_OBJECT *, unsigned int, sn);
85static int ln_cmp(const void *a, const void *b); 85DECLARE_OBJ_BSEARCH_CMP_FN(const ASN1_OBJECT *, unsigned int, ln);
86static int obj_cmp(const void *a, const void *b); 86DECLARE_OBJ_BSEARCH_CMP_FN(const ASN1_OBJECT *, unsigned int, obj);
87
87#define ADDED_DATA 0 88#define ADDED_DATA 0
88#define ADDED_SNAME 1 89#define ADDED_SNAME 1
89#define ADDED_LNAME 2 90#define ADDED_LNAME 2
@@ -94,30 +95,27 @@ typedef struct added_obj_st
94 int type; 95 int type;
95 ASN1_OBJECT *obj; 96 ASN1_OBJECT *obj;
96 } ADDED_OBJ; 97 } ADDED_OBJ;
98DECLARE_LHASH_OF(ADDED_OBJ);
97 99
98static int new_nid=NUM_NID; 100static int new_nid=NUM_NID;
99static LHASH *added=NULL; 101static LHASH_OF(ADDED_OBJ) *added=NULL;
100 102
101static int sn_cmp(const void *a, const void *b) 103static int sn_cmp(const ASN1_OBJECT * const *a, const unsigned int *b)
102 { 104 { return(strcmp((*a)->sn,nid_objs[*b].sn)); }
103 const ASN1_OBJECT * const *ap = a, * const *bp = b;
104 return(strcmp((*ap)->sn,(*bp)->sn));
105 }
106 105
107static int ln_cmp(const void *a, const void *b) 106IMPLEMENT_OBJ_BSEARCH_CMP_FN(const ASN1_OBJECT *, unsigned int, sn);
108 { 107
109 const ASN1_OBJECT * const *ap = a, * const *bp = b; 108static int ln_cmp(const ASN1_OBJECT * const *a, const unsigned int *b)
110 return(strcmp((*ap)->ln,(*bp)->ln)); 109 { return(strcmp((*a)->ln,nid_objs[*b].ln)); }
111 }
112 110
113/* static unsigned long add_hash(ADDED_OBJ *ca) */ 111IMPLEMENT_OBJ_BSEARCH_CMP_FN(const ASN1_OBJECT *, unsigned int, ln);
114static unsigned long add_hash(const void *ca_void) 112
113static unsigned long added_obj_hash(const ADDED_OBJ *ca)
115 { 114 {
116 const ASN1_OBJECT *a; 115 const ASN1_OBJECT *a;
117 int i; 116 int i;
118 unsigned long ret=0; 117 unsigned long ret=0;
119 unsigned char *p; 118 unsigned char *p;
120 const ADDED_OBJ *ca = (const ADDED_OBJ *)ca_void;
121 119
122 a=ca->obj; 120 a=ca->obj;
123 switch (ca->type) 121 switch (ca->type)
@@ -145,14 +143,12 @@ static unsigned long add_hash(const void *ca_void)
145 ret|=ca->type<<30L; 143 ret|=ca->type<<30L;
146 return(ret); 144 return(ret);
147 } 145 }
146static IMPLEMENT_LHASH_HASH_FN(added_obj, ADDED_OBJ)
148 147
149/* static int add_cmp(ADDED_OBJ *ca, ADDED_OBJ *cb) */ 148static int added_obj_cmp(const ADDED_OBJ *ca, const ADDED_OBJ *cb)
150static int add_cmp(const void *ca_void, const void *cb_void)
151 { 149 {
152 ASN1_OBJECT *a,*b; 150 ASN1_OBJECT *a,*b;
153 int i; 151 int i;
154 const ADDED_OBJ *ca = (const ADDED_OBJ *)ca_void;
155 const ADDED_OBJ *cb = (const ADDED_OBJ *)cb_void;
156 152
157 i=ca->type-cb->type; 153 i=ca->type-cb->type;
158 if (i) return(i); 154 if (i) return(i);
@@ -179,15 +175,16 @@ static int add_cmp(const void *ca_void, const void *cb_void)
179 return 0; 175 return 0;
180 } 176 }
181 } 177 }
178static IMPLEMENT_LHASH_COMP_FN(added_obj, ADDED_OBJ)
182 179
183static int init_added(void) 180static int init_added(void)
184 { 181 {
185 if (added != NULL) return(1); 182 if (added != NULL) return(1);
186 added=lh_new(add_hash,add_cmp); 183 added=lh_ADDED_OBJ_new();
187 return(added != NULL); 184 return(added != NULL);
188 } 185 }
189 186
190static void cleanup1(ADDED_OBJ *a) 187static void cleanup1_doall(ADDED_OBJ *a)
191 { 188 {
192 a->obj->nid=0; 189 a->obj->nid=0;
193 a->obj->flags|=ASN1_OBJECT_FLAG_DYNAMIC| 190 a->obj->flags|=ASN1_OBJECT_FLAG_DYNAMIC|
@@ -195,28 +192,46 @@ static void cleanup1(ADDED_OBJ *a)
195 ASN1_OBJECT_FLAG_DYNAMIC_DATA; 192 ASN1_OBJECT_FLAG_DYNAMIC_DATA;
196 } 193 }
197 194
198static void cleanup2(ADDED_OBJ *a) 195static void cleanup2_doall(ADDED_OBJ *a)
199 { a->obj->nid++; } 196 { a->obj->nid++; }
200 197
201static void cleanup3(ADDED_OBJ *a) 198static void cleanup3_doall(ADDED_OBJ *a)
202 { 199 {
203 if (--a->obj->nid == 0) 200 if (--a->obj->nid == 0)
204 ASN1_OBJECT_free(a->obj); 201 ASN1_OBJECT_free(a->obj);
205 OPENSSL_free(a); 202 OPENSSL_free(a);
206 } 203 }
207 204
208static IMPLEMENT_LHASH_DOALL_FN(cleanup1, ADDED_OBJ *) 205static IMPLEMENT_LHASH_DOALL_FN(cleanup1, ADDED_OBJ)
209static IMPLEMENT_LHASH_DOALL_FN(cleanup2, ADDED_OBJ *) 206static IMPLEMENT_LHASH_DOALL_FN(cleanup2, ADDED_OBJ)
210static IMPLEMENT_LHASH_DOALL_FN(cleanup3, ADDED_OBJ *) 207static IMPLEMENT_LHASH_DOALL_FN(cleanup3, ADDED_OBJ)
208
209/* The purpose of obj_cleanup_defer is to avoid EVP_cleanup() attempting
210 * to use freed up OIDs. If neccessary the actual freeing up of OIDs is
211 * delayed.
212 */
213
214int obj_cleanup_defer = 0;
215
216void check_defer(int nid)
217 {
218 if (!obj_cleanup_defer && nid >= NUM_NID)
219 obj_cleanup_defer = 1;
220 }
211 221
212void OBJ_cleanup(void) 222void OBJ_cleanup(void)
213 { 223 {
224 if (obj_cleanup_defer)
225 {
226 obj_cleanup_defer = 2;
227 return ;
228 }
214 if (added == NULL) return; 229 if (added == NULL) return;
215 added->down_load=0; 230 lh_ADDED_OBJ_down_load(added) = 0;
216 lh_doall(added,LHASH_DOALL_FN(cleanup1)); /* zero counters */ 231 lh_ADDED_OBJ_doall(added,LHASH_DOALL_FN(cleanup1)); /* zero counters */
217 lh_doall(added,LHASH_DOALL_FN(cleanup2)); /* set counters */ 232 lh_ADDED_OBJ_doall(added,LHASH_DOALL_FN(cleanup2)); /* set counters */
218 lh_doall(added,LHASH_DOALL_FN(cleanup3)); /* free objects */ 233 lh_ADDED_OBJ_doall(added,LHASH_DOALL_FN(cleanup3)); /* free objects */
219 lh_free(added); 234 lh_ADDED_OBJ_free(added);
220 added=NULL; 235 added=NULL;
221 } 236 }
222 237
@@ -252,7 +267,7 @@ int OBJ_add_object(const ASN1_OBJECT *obj)
252 { 267 {
253 ao[i]->type=i; 268 ao[i]->type=i;
254 ao[i]->obj=o; 269 ao[i]->obj=o;
255 aop=(ADDED_OBJ *)lh_insert(added,ao[i]); 270 aop=lh_ADDED_OBJ_insert(added,ao[i]);
256 /* memory leak, buit should not normally matter */ 271 /* memory leak, buit should not normally matter */
257 if (aop != NULL) 272 if (aop != NULL)
258 OPENSSL_free(aop); 273 OPENSSL_free(aop);
@@ -292,7 +307,7 @@ ASN1_OBJECT *OBJ_nid2obj(int n)
292 ad.type=ADDED_NID; 307 ad.type=ADDED_NID;
293 ad.obj= &ob; 308 ad.obj= &ob;
294 ob.nid=n; 309 ob.nid=n;
295 adp=(ADDED_OBJ *)lh_retrieve(added,&ad); 310 adp=lh_ADDED_OBJ_retrieve(added,&ad);
296 if (adp != NULL) 311 if (adp != NULL)
297 return(adp->obj); 312 return(adp->obj);
298 else 313 else
@@ -324,7 +339,7 @@ const char *OBJ_nid2sn(int n)
324 ad.type=ADDED_NID; 339 ad.type=ADDED_NID;
325 ad.obj= &ob; 340 ad.obj= &ob;
326 ob.nid=n; 341 ob.nid=n;
327 adp=(ADDED_OBJ *)lh_retrieve(added,&ad); 342 adp=lh_ADDED_OBJ_retrieve(added,&ad);
328 if (adp != NULL) 343 if (adp != NULL)
329 return(adp->obj->sn); 344 return(adp->obj->sn);
330 else 345 else
@@ -356,7 +371,7 @@ const char *OBJ_nid2ln(int n)
356 ad.type=ADDED_NID; 371 ad.type=ADDED_NID;
357 ad.obj= &ob; 372 ad.obj= &ob;
358 ob.nid=n; 373 ob.nid=n;
359 adp=(ADDED_OBJ *)lh_retrieve(added,&ad); 374 adp=lh_ADDED_OBJ_retrieve(added,&ad);
360 if (adp != NULL) 375 if (adp != NULL)
361 return(adp->obj->ln); 376 return(adp->obj->ln);
362 else 377 else
@@ -367,9 +382,22 @@ const char *OBJ_nid2ln(int n)
367 } 382 }
368 } 383 }
369 384
385static int obj_cmp(const ASN1_OBJECT * const *ap, const unsigned int *bp)
386 {
387 int j;
388 const ASN1_OBJECT *a= *ap;
389 const ASN1_OBJECT *b= &nid_objs[*bp];
390
391 j=(a->length - b->length);
392 if (j) return(j);
393 return(memcmp(a->data,b->data,a->length));
394 }
395
396IMPLEMENT_OBJ_BSEARCH_CMP_FN(const ASN1_OBJECT *, unsigned int, obj);
397
370int OBJ_obj2nid(const ASN1_OBJECT *a) 398int OBJ_obj2nid(const ASN1_OBJECT *a)
371 { 399 {
372 ASN1_OBJECT **op; 400 const unsigned int *op;
373 ADDED_OBJ ad,*adp; 401 ADDED_OBJ ad,*adp;
374 402
375 if (a == NULL) 403 if (a == NULL)
@@ -381,14 +409,13 @@ int OBJ_obj2nid(const ASN1_OBJECT *a)
381 { 409 {
382 ad.type=ADDED_DATA; 410 ad.type=ADDED_DATA;
383 ad.obj=(ASN1_OBJECT *)a; /* XXX: ugly but harmless */ 411 ad.obj=(ASN1_OBJECT *)a; /* XXX: ugly but harmless */
384 adp=(ADDED_OBJ *)lh_retrieve(added,&ad); 412 adp=lh_ADDED_OBJ_retrieve(added,&ad);
385 if (adp != NULL) return (adp->obj->nid); 413 if (adp != NULL) return (adp->obj->nid);
386 } 414 }
387 op=(ASN1_OBJECT **)OBJ_bsearch((const char *)&a,(const char *)obj_objs, 415 op=OBJ_bsearch_obj(&a, obj_objs, NUM_OBJ);
388 NUM_OBJ, sizeof(ASN1_OBJECT *),obj_cmp);
389 if (op == NULL) 416 if (op == NULL)
390 return(NID_undef); 417 return(NID_undef);
391 return((*op)->nid); 418 return(nid_objs[*op].nid);
392 } 419 }
393 420
394/* Convert an object name into an ASN1_OBJECT 421/* Convert an object name into an ASN1_OBJECT
@@ -441,7 +468,7 @@ int OBJ_obj2txt(char *buf, int buf_len, const ASN1_OBJECT *a, int no_name)
441 int i,n=0,len,nid, first, use_bn; 468 int i,n=0,len,nid, first, use_bn;
442 BIGNUM *bl; 469 BIGNUM *bl;
443 unsigned long l; 470 unsigned long l;
444 unsigned char *p; 471 const unsigned char *p;
445 char tbuf[DECIMAL_SIZE(i)+DECIMAL_SIZE(l)+2]; 472 char tbuf[DECIMAL_SIZE(i)+DECIMAL_SIZE(l)+2];
446 473
447 if ((a == NULL) || (a->data == NULL)) { 474 if ((a == NULL) || (a->data == NULL)) {
@@ -456,10 +483,13 @@ int OBJ_obj2txt(char *buf, int buf_len, const ASN1_OBJECT *a, int no_name)
456 s=OBJ_nid2ln(nid); 483 s=OBJ_nid2ln(nid);
457 if (s == NULL) 484 if (s == NULL)
458 s=OBJ_nid2sn(nid); 485 s=OBJ_nid2sn(nid);
459 if (buf) 486 if (s)
460 BUF_strlcpy(buf,s,buf_len); 487 {
461 n=strlen(s); 488 if (buf)
462 return n; 489 BUF_strlcpy(buf,s,buf_len);
490 n=strlen(s);
491 return n;
492 }
463 } 493 }
464 494
465 495
@@ -607,62 +637,56 @@ int OBJ_txt2nid(const char *s)
607 637
608int OBJ_ln2nid(const char *s) 638int OBJ_ln2nid(const char *s)
609 { 639 {
610 ASN1_OBJECT o,*oo= &o,**op; 640 ASN1_OBJECT o;
641 const ASN1_OBJECT *oo= &o;
611 ADDED_OBJ ad,*adp; 642 ADDED_OBJ ad,*adp;
643 const unsigned int *op;
612 644
613 o.ln=s; 645 o.ln=s;
614 if (added != NULL) 646 if (added != NULL)
615 { 647 {
616 ad.type=ADDED_LNAME; 648 ad.type=ADDED_LNAME;
617 ad.obj= &o; 649 ad.obj= &o;
618 adp=(ADDED_OBJ *)lh_retrieve(added,&ad); 650 adp=lh_ADDED_OBJ_retrieve(added,&ad);
619 if (adp != NULL) return (adp->obj->nid); 651 if (adp != NULL) return (adp->obj->nid);
620 } 652 }
621 op=(ASN1_OBJECT **)OBJ_bsearch((char *)&oo,(char *)ln_objs, NUM_LN, 653 op=OBJ_bsearch_ln(&oo, ln_objs, NUM_LN);
622 sizeof(ASN1_OBJECT *),ln_cmp);
623 if (op == NULL) return(NID_undef); 654 if (op == NULL) return(NID_undef);
624 return((*op)->nid); 655 return(nid_objs[*op].nid);
625 } 656 }
626 657
627int OBJ_sn2nid(const char *s) 658int OBJ_sn2nid(const char *s)
628 { 659 {
629 ASN1_OBJECT o,*oo= &o,**op; 660 ASN1_OBJECT o;
661 const ASN1_OBJECT *oo= &o;
630 ADDED_OBJ ad,*adp; 662 ADDED_OBJ ad,*adp;
663 const unsigned int *op;
631 664
632 o.sn=s; 665 o.sn=s;
633 if (added != NULL) 666 if (added != NULL)
634 { 667 {
635 ad.type=ADDED_SNAME; 668 ad.type=ADDED_SNAME;
636 ad.obj= &o; 669 ad.obj= &o;
637 adp=(ADDED_OBJ *)lh_retrieve(added,&ad); 670 adp=lh_ADDED_OBJ_retrieve(added,&ad);
638 if (adp != NULL) return (adp->obj->nid); 671 if (adp != NULL) return (adp->obj->nid);
639 } 672 }
640 op=(ASN1_OBJECT **)OBJ_bsearch((char *)&oo,(char *)sn_objs,NUM_SN, 673 op=OBJ_bsearch_sn(&oo, sn_objs, NUM_SN);
641 sizeof(ASN1_OBJECT *),sn_cmp);
642 if (op == NULL) return(NID_undef); 674 if (op == NULL) return(NID_undef);
643 return((*op)->nid); 675 return(nid_objs[*op].nid);
644 } 676 }
645 677
646static int obj_cmp(const void *ap, const void *bp) 678const void *OBJ_bsearch_(const void *key, const void *base, int num, int size,
647 { 679 int (*cmp)(const void *, const void *))
648 int j;
649 const ASN1_OBJECT *a= *(ASN1_OBJECT * const *)ap;
650 const ASN1_OBJECT *b= *(ASN1_OBJECT * const *)bp;
651
652 j=(a->length - b->length);
653 if (j) return(j);
654 return(memcmp(a->data,b->data,a->length));
655 }
656
657const char *OBJ_bsearch(const char *key, const char *base, int num, int size,
658 int (*cmp)(const void *, const void *))
659 { 680 {
660 return OBJ_bsearch_ex(key, base, num, size, cmp, 0); 681 return OBJ_bsearch_ex_(key, base, num, size, cmp, 0);
661 } 682 }
662 683
663const char *OBJ_bsearch_ex(const char *key, const char *base, int num, 684const void *OBJ_bsearch_ex_(const void *key, const void *base_, int num,
664 int size, int (*cmp)(const void *, const void *), int flags) 685 int size,
686 int (*cmp)(const void *, const void *),
687 int flags)
665 { 688 {
689 const char *base=base_;
666 int l,h,i=0,c=0; 690 int l,h,i=0,c=0;
667 const char *p = NULL; 691 const char *p = NULL;
668 692
diff --git a/src/lib/libcrypto/objects/obj_dat.pl b/src/lib/libcrypto/objects/obj_dat.pl
index 7de2f77afd..c67f71c327 100644
--- a/src/lib/libcrypto/objects/obj_dat.pl
+++ b/src/lib/libcrypto/objects/obj_dat.pl
@@ -2,9 +2,7 @@
2 2
3# fixes bug in floating point emulation on sparc64 when 3# fixes bug in floating point emulation on sparc64 when
4# this script produces off-by-one output on sparc64 4# this script produces off-by-one output on sparc64
5eval 'use integer;'; 5use integer;
6
7print STDERR "Warning: perl module integer not found.\n" if ($@);
8 6
9sub obj_cmp 7sub obj_cmp
10 { 8 {
@@ -150,13 +148,13 @@ for ($i=0; $i<$n; $i++)
150@a=grep(defined($sn{$nid{$_}}),0 .. $n); 148@a=grep(defined($sn{$nid{$_}}),0 .. $n);
151foreach (sort { $sn{$nid{$a}} cmp $sn{$nid{$b}} } @a) 149foreach (sort { $sn{$nid{$a}} cmp $sn{$nid{$b}} } @a)
152 { 150 {
153 push(@sn,sprintf("&(nid_objs[%2d]),/* \"$sn{$nid{$_}}\" */\n",$_)); 151 push(@sn,sprintf("%2d,\t/* \"$sn{$nid{$_}}\" */\n",$_));
154 } 152 }
155 153
156@a=grep(defined($ln{$nid{$_}}),0 .. $n); 154@a=grep(defined($ln{$nid{$_}}),0 .. $n);
157foreach (sort { $ln{$nid{$a}} cmp $ln{$nid{$b}} } @a) 155foreach (sort { $ln{$nid{$a}} cmp $ln{$nid{$b}} } @a)
158 { 156 {
159 push(@ln,sprintf("&(nid_objs[%2d]),/* \"$ln{$nid{$_}}\" */\n",$_)); 157 push(@ln,sprintf("%2d,\t/* \"$ln{$nid{$_}}\" */\n",$_));
160 } 158 }
161 159
162@a=grep(defined($obj{$nid{$_}}),0 .. $n); 160@a=grep(defined($obj{$nid{$_}}),0 .. $n);
@@ -166,7 +164,7 @@ foreach (sort obj_cmp @a)
166 $v=$objd{$m}; 164 $v=$objd{$m};
167 $v =~ s/L//g; 165 $v =~ s/L//g;
168 $v =~ s/,/ /g; 166 $v =~ s/,/ /g;
169 push(@ob,sprintf("&(nid_objs[%2d]),/* %-32s %s */\n",$_,$m,$v)); 167 push(@ob,sprintf("%2d,\t/* %-32s %s */\n",$_,$m,$v));
170 } 168 }
171 169
172print OUT <<'EOF'; 170print OUT <<'EOF';
@@ -241,11 +239,11 @@ printf OUT "#define NUM_SN %d\n",$#sn+1;
241printf OUT "#define NUM_LN %d\n",$#ln+1; 239printf OUT "#define NUM_LN %d\n",$#ln+1;
242printf OUT "#define NUM_OBJ %d\n\n",$#ob+1; 240printf OUT "#define NUM_OBJ %d\n\n",$#ob+1;
243 241
244printf OUT "static unsigned char lvalues[%d]={\n",$lvalues+1; 242printf OUT "static const unsigned char lvalues[%d]={\n",$lvalues+1;
245print OUT @lvalues; 243print OUT @lvalues;
246print OUT "};\n\n"; 244print OUT "};\n\n";
247 245
248printf OUT "static ASN1_OBJECT nid_objs[NUM_NID]={\n"; 246printf OUT "static const ASN1_OBJECT nid_objs[NUM_NID]={\n";
249foreach (@out) 247foreach (@out)
250 { 248 {
251 if (length($_) > 75) 249 if (length($_) > 75)
@@ -269,15 +267,15 @@ foreach (@out)
269 } 267 }
270print OUT "};\n\n"; 268print OUT "};\n\n";
271 269
272printf OUT "static ASN1_OBJECT *sn_objs[NUM_SN]={\n"; 270printf OUT "static const unsigned int sn_objs[NUM_SN]={\n";
273print OUT @sn; 271print OUT @sn;
274print OUT "};\n\n"; 272print OUT "};\n\n";
275 273
276printf OUT "static ASN1_OBJECT *ln_objs[NUM_LN]={\n"; 274printf OUT "static const unsigned int ln_objs[NUM_LN]={\n";
277print OUT @ln; 275print OUT @ln;
278print OUT "};\n\n"; 276print OUT "};\n\n";
279 277
280printf OUT "static ASN1_OBJECT *obj_objs[NUM_OBJ]={\n"; 278printf OUT "static const unsigned int obj_objs[NUM_OBJ]={\n";
281print OUT @ob; 279print OUT @ob;
282print OUT "};\n\n"; 280print OUT "};\n\n";
283 281
diff --git a/src/lib/libcrypto/objects/obj_err.c b/src/lib/libcrypto/objects/obj_err.c
index 12b48850c6..2e7a034c3f 100644
--- a/src/lib/libcrypto/objects/obj_err.c
+++ b/src/lib/libcrypto/objects/obj_err.c
@@ -1,6 +1,6 @@
1/* crypto/objects/obj_err.c */ 1/* crypto/objects/obj_err.c */
2/* ==================================================================== 2/* ====================================================================
3 * Copyright (c) 1999-2005 The OpenSSL Project. All rights reserved. 3 * Copyright (c) 1999-2006 The OpenSSL Project. All rights reserved.
4 * 4 *
5 * Redistribution and use in source and binary forms, with or without 5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions 6 * modification, are permitted provided that the following conditions
diff --git a/src/lib/libcrypto/objects/obj_lib.c b/src/lib/libcrypto/objects/obj_lib.c
index 706fa0b0e7..23e9d48cdf 100644
--- a/src/lib/libcrypto/objects/obj_lib.c
+++ b/src/lib/libcrypto/objects/obj_lib.c
@@ -66,7 +66,8 @@ ASN1_OBJECT *OBJ_dup(const ASN1_OBJECT *o)
66 { 66 {
67 ASN1_OBJECT *r; 67 ASN1_OBJECT *r;
68 int i; 68 int i;
69 char *ln=NULL; 69 char *ln=NULL,*sn=NULL;
70 unsigned char *data=NULL;
70 71
71 if (o == NULL) return(NULL); 72 if (o == NULL) return(NULL);
72 if (!(o->flags & ASN1_OBJECT_FLAG_DYNAMIC)) 73 if (!(o->flags & ASN1_OBJECT_FLAG_DYNAMIC))
@@ -79,42 +80,42 @@ ASN1_OBJECT *OBJ_dup(const ASN1_OBJECT *o)
79 OBJerr(OBJ_F_OBJ_DUP,ERR_R_ASN1_LIB); 80 OBJerr(OBJ_F_OBJ_DUP,ERR_R_ASN1_LIB);
80 return(NULL); 81 return(NULL);
81 } 82 }
82 r->data=OPENSSL_malloc(o->length); 83 data=OPENSSL_malloc(o->length);
83 if (r->data == NULL) 84 if (data == NULL)
84 goto err; 85 goto err;
85 if (o->data != NULL) 86 if (o->data != NULL)
86 memcpy(r->data,o->data,o->length); 87 memcpy(data,o->data,o->length);
88 /* once data attached to object it remains const */
89 r->data = data;
87 r->length=o->length; 90 r->length=o->length;
88 r->nid=o->nid; 91 r->nid=o->nid;
89 r->ln=r->sn=NULL; 92 r->ln=r->sn=NULL;
90 if (o->ln != NULL) 93 if (o->ln != NULL)
91 { 94 {
92 i=strlen(o->ln)+1; 95 i=strlen(o->ln)+1;
93 r->ln=ln=OPENSSL_malloc(i); 96 ln=OPENSSL_malloc(i);
94 if (r->ln == NULL) goto err; 97 if (ln == NULL) goto err;
95 memcpy(ln,o->ln,i); 98 memcpy(ln,o->ln,i);
99 r->ln=ln;
96 } 100 }
97 101
98 if (o->sn != NULL) 102 if (o->sn != NULL)
99 { 103 {
100 char *s;
101
102 i=strlen(o->sn)+1; 104 i=strlen(o->sn)+1;
103 r->sn=s=OPENSSL_malloc(i); 105 sn=OPENSSL_malloc(i);
104 if (r->sn == NULL) goto err; 106 if (sn == NULL) goto err;
105 memcpy(s,o->sn,i); 107 memcpy(sn,o->sn,i);
108 r->sn=sn;
106 } 109 }
107 r->flags=o->flags|(ASN1_OBJECT_FLAG_DYNAMIC| 110 r->flags=o->flags|(ASN1_OBJECT_FLAG_DYNAMIC|
108 ASN1_OBJECT_FLAG_DYNAMIC_STRINGS|ASN1_OBJECT_FLAG_DYNAMIC_DATA); 111 ASN1_OBJECT_FLAG_DYNAMIC_STRINGS|ASN1_OBJECT_FLAG_DYNAMIC_DATA);
109 return(r); 112 return(r);
110err: 113err:
111 OBJerr(OBJ_F_OBJ_DUP,ERR_R_MALLOC_FAILURE); 114 OBJerr(OBJ_F_OBJ_DUP,ERR_R_MALLOC_FAILURE);
112 if (r != NULL) 115 if (ln != NULL) OPENSSL_free(ln);
113 { 116 if (sn != NULL) OPENSSL_free(sn);
114 if (ln != NULL) OPENSSL_free(ln); 117 if (data != NULL) OPENSSL_free(data);
115 if (r->data != NULL) OPENSSL_free(r->data); 118 if (r != NULL) OPENSSL_free(r);
116 OPENSSL_free(r);
117 }
118 return(NULL); 119 return(NULL);
119 } 120 }
120 121
diff --git a/src/lib/libcrypto/objects/obj_mac.num b/src/lib/libcrypto/objects/obj_mac.num
index e3f56bc52c..8c50aac27f 100644
--- a/src/lib/libcrypto/objects/obj_mac.num
+++ b/src/lib/libcrypto/objects/obj_mac.num
@@ -856,3 +856,37 @@ hmac 855
856LocalKeySet 856 856LocalKeySet 856
857freshest_crl 857 857freshest_crl 857
858id_on_permanentIdentifier 858 858id_on_permanentIdentifier 858
859searchGuide 859
860businessCategory 860
861postalAddress 861
862postOfficeBox 862
863physicalDeliveryOfficeName 863
864telephoneNumber 864
865telexNumber 865
866teletexTerminalIdentifier 866
867facsimileTelephoneNumber 867
868x121Address 868
869internationaliSDNNumber 869
870registeredAddress 870
871destinationIndicator 871
872preferredDeliveryMethod 872
873presentationAddress 873
874supportedApplicationContext 874
875member 875
876owner 876
877roleOccupant 877
878seeAlso 878
879userPassword 879
880userCertificate 880
881cACertificate 881
882authorityRevocationList 882
883certificateRevocationList 883
884crossCertificatePair 884
885enhancedSearchGuide 885
886protocolInformation 886
887distinguishedName 887
888uniqueMember 888
889houseIdentifier 889
890supportedAlgorithms 890
891deltaRevocationList 891
892dmdName 892
diff --git a/src/lib/libcrypto/objects/obj_xref.c b/src/lib/libcrypto/objects/obj_xref.c
new file mode 100644
index 0000000000..152eca5c67
--- /dev/null
+++ b/src/lib/libcrypto/objects/obj_xref.c
@@ -0,0 +1,231 @@
1/* crypto/objects/obj_xref.c */
2/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
3 * project 2006.
4 */
5/* ====================================================================
6 * Copyright (c) 2006 The OpenSSL Project. All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 *
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 *
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in
17 * the documentation and/or other materials provided with the
18 * distribution.
19 *
20 * 3. All advertising materials mentioning features or use of this
21 * software must display the following acknowledgment:
22 * "This product includes software developed by the OpenSSL Project
23 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
24 *
25 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
26 * endorse or promote products derived from this software without
27 * prior written permission. For written permission, please contact
28 * licensing@OpenSSL.org.
29 *
30 * 5. Products derived from this software may not be called "OpenSSL"
31 * nor may "OpenSSL" appear in their names without prior written
32 * permission of the OpenSSL Project.
33 *
34 * 6. Redistributions of any form whatsoever must retain the following
35 * acknowledgment:
36 * "This product includes software developed by the OpenSSL Project
37 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
38 *
39 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
40 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
43 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
50 * OF THE POSSIBILITY OF SUCH DAMAGE.
51 * ====================================================================
52 *
53 * This product includes cryptographic software written by Eric Young
54 * (eay@cryptsoft.com). This product includes software written by Tim
55 * Hudson (tjh@cryptsoft.com).
56 *
57 */
58
59#include <openssl/objects.h>
60#include "obj_xref.h"
61
62DECLARE_STACK_OF(nid_triple)
63STACK_OF(nid_triple) *sig_app, *sigx_app;
64
65static int sig_cmp(const nid_triple *a, const nid_triple *b)
66 {
67 return a->sign_id - b->sign_id;
68 }
69
70DECLARE_OBJ_BSEARCH_CMP_FN(nid_triple, nid_triple, sig);
71IMPLEMENT_OBJ_BSEARCH_CMP_FN(nid_triple, nid_triple, sig);
72
73static int sig_sk_cmp(const nid_triple * const *a, const nid_triple * const *b)
74 {
75 return (*a)->sign_id - (*b)->sign_id;
76 }
77
78DECLARE_OBJ_BSEARCH_CMP_FN(const nid_triple *, const nid_triple *, sigx);
79
80static int sigx_cmp(const nid_triple * const *a, const nid_triple * const *b)
81 {
82 int ret;
83 ret = (*a)->hash_id - (*b)->hash_id;
84 if (ret)
85 return ret;
86 return (*a)->pkey_id - (*b)->pkey_id;
87 }
88
89IMPLEMENT_OBJ_BSEARCH_CMP_FN(const nid_triple *, const nid_triple *, sigx);
90
91int OBJ_find_sigid_algs(int signid, int *pdig_nid, int *ppkey_nid)
92 {
93 nid_triple tmp;
94 const nid_triple *rv = NULL;
95 tmp.sign_id = signid;
96
97 if (sig_app)
98 {
99 int idx = sk_nid_triple_find(sig_app, &tmp);
100 if (idx >= 0)
101 rv = sk_nid_triple_value(sig_app, idx);
102 }
103
104#ifndef OBJ_XREF_TEST2
105 if (rv == NULL)
106 {
107 rv = OBJ_bsearch_sig(&tmp, sigoid_srt,
108 sizeof(sigoid_srt) / sizeof(nid_triple));
109 }
110#endif
111 if (rv == NULL)
112 return 0;
113 *pdig_nid = rv->hash_id;
114 *ppkey_nid = rv->pkey_id;
115 return 1;
116 }
117
118int OBJ_find_sigid_by_algs(int *psignid, int dig_nid, int pkey_nid)
119 {
120 nid_triple tmp;
121 const nid_triple *t=&tmp;
122 const nid_triple **rv = NULL;
123
124 tmp.hash_id = dig_nid;
125 tmp.pkey_id = pkey_nid;
126
127 if (sigx_app)
128 {
129 int idx = sk_nid_triple_find(sigx_app, &tmp);
130 if (idx >= 0)
131 {
132 t = sk_nid_triple_value(sigx_app, idx);
133 rv = &t;
134 }
135 }
136
137#ifndef OBJ_XREF_TEST2
138 if (rv == NULL)
139 {
140 rv = OBJ_bsearch_sigx(&t, sigoid_srt_xref,
141 sizeof(sigoid_srt_xref) / sizeof(nid_triple *)
142 );
143 }
144#endif
145 if (rv == NULL)
146 return 0;
147 *psignid = (*rv)->sign_id;
148 return 1;
149 }
150
151int OBJ_add_sigid(int signid, int dig_id, int pkey_id)
152 {
153 nid_triple *ntr;
154 if (!sig_app)
155 sig_app = sk_nid_triple_new(sig_sk_cmp);
156 if (!sig_app)
157 return 0;
158 if (!sigx_app)
159 sigx_app = sk_nid_triple_new(sigx_cmp);
160 if (!sigx_app)
161 return 0;
162 ntr = OPENSSL_malloc(sizeof(int) * 3);
163 if (!ntr)
164 return 0;
165 ntr->sign_id = signid;
166 ntr->hash_id = dig_id;
167 ntr->pkey_id = pkey_id;
168
169 if (!sk_nid_triple_push(sig_app, ntr))
170 {
171 OPENSSL_free(ntr);
172 return 0;
173 }
174
175 if (!sk_nid_triple_push(sigx_app, ntr))
176 return 0;
177
178 sk_nid_triple_sort(sig_app);
179 sk_nid_triple_sort(sigx_app);
180
181 return 1;
182 }
183
184static void sid_free(nid_triple *tt)
185 {
186 OPENSSL_free(tt);
187 }
188
189void OBJ_sigid_free(void)
190 {
191 if (sig_app)
192 {
193 sk_nid_triple_pop_free(sig_app, sid_free);
194 sig_app = NULL;
195 }
196 if (sigx_app)
197 {
198 sk_nid_triple_free(sigx_app);
199 sigx_app = NULL;
200 }
201 }
202
203#ifdef OBJ_XREF_TEST
204
205main()
206 {
207 int n1, n2, n3;
208
209 int i, rv;
210#ifdef OBJ_XREF_TEST2
211 for (i = 0; i < sizeof(sigoid_srt) / sizeof(nid_triple); i++)
212 {
213 OBJ_add_sigid(sigoid_srt[i][0], sigoid_srt[i][1],
214 sigoid_srt[i][2]);
215 }
216#endif
217
218 for (i = 0; i < sizeof(sigoid_srt) / sizeof(nid_triple); i++)
219 {
220 n1 = sigoid_srt[i][0];
221 rv = OBJ_find_sigid_algs(n1, &n2, &n3);
222 printf("Forward: %d, %s %s %s\n", rv,
223 OBJ_nid2ln(n1), OBJ_nid2ln(n2), OBJ_nid2ln(n3));
224 n1=0;
225 rv = OBJ_find_sigid_by_algs(&n1, n2, n3);
226 printf("Reverse: %d, %s %s %s\n", rv,
227 OBJ_nid2ln(n1), OBJ_nid2ln(n2), OBJ_nid2ln(n3));
228 }
229 }
230
231#endif
diff --git a/src/lib/libcrypto/objects/obj_xref.h b/src/lib/libcrypto/objects/obj_xref.h
new file mode 100644
index 0000000000..d5b9b8e198
--- /dev/null
+++ b/src/lib/libcrypto/objects/obj_xref.h
@@ -0,0 +1,75 @@
1/* AUTOGENERATED BY objxref.pl, DO NOT EDIT */
2
3typedef struct
4 {
5 int sign_id;
6 int hash_id;
7 int pkey_id;
8 } nid_triple;
9
10static const nid_triple sigoid_srt[] =
11 {
12 {NID_md2WithRSAEncryption, NID_md2, NID_rsaEncryption},
13 {NID_md5WithRSAEncryption, NID_md5, NID_rsaEncryption},
14 {NID_shaWithRSAEncryption, NID_sha, NID_rsaEncryption},
15 {NID_sha1WithRSAEncryption, NID_sha1, NID_rsaEncryption},
16 {NID_dsaWithSHA, NID_sha, NID_dsa},
17 {NID_dsaWithSHA1_2, NID_sha1, NID_dsa_2},
18 {NID_mdc2WithRSA, NID_mdc2, NID_rsaEncryption},
19 {NID_md5WithRSA, NID_md5, NID_rsa},
20 {NID_dsaWithSHA1, NID_sha1, NID_dsa},
21 {NID_sha1WithRSA, NID_sha1, NID_rsa},
22 {NID_ripemd160WithRSA, NID_ripemd160, NID_rsaEncryption},
23 {NID_md4WithRSAEncryption, NID_md4, NID_rsaEncryption},
24 {NID_ecdsa_with_SHA1, NID_sha1, NID_X9_62_id_ecPublicKey},
25 {NID_sha256WithRSAEncryption, NID_sha256, NID_rsaEncryption},
26 {NID_sha384WithRSAEncryption, NID_sha384, NID_rsaEncryption},
27 {NID_sha512WithRSAEncryption, NID_sha512, NID_rsaEncryption},
28 {NID_sha224WithRSAEncryption, NID_sha224, NID_rsaEncryption},
29 {NID_ecdsa_with_Recommended, NID_undef, NID_X9_62_id_ecPublicKey},
30 {NID_ecdsa_with_Specified, NID_undef, NID_X9_62_id_ecPublicKey},
31 {NID_ecdsa_with_SHA224, NID_sha224, NID_X9_62_id_ecPublicKey},
32 {NID_ecdsa_with_SHA256, NID_sha256, NID_X9_62_id_ecPublicKey},
33 {NID_ecdsa_with_SHA384, NID_sha384, NID_X9_62_id_ecPublicKey},
34 {NID_ecdsa_with_SHA512, NID_sha512, NID_X9_62_id_ecPublicKey},
35 {NID_dsa_with_SHA224, NID_sha224, NID_dsa},
36 {NID_dsa_with_SHA256, NID_sha256, NID_dsa},
37 {NID_id_GostR3411_94_with_GostR3410_2001, NID_id_GostR3411_94, NID_id_GostR3410_2001},
38 {NID_id_GostR3411_94_with_GostR3410_94, NID_id_GostR3411_94, NID_id_GostR3410_94},
39 {NID_id_GostR3411_94_with_GostR3410_94_cc, NID_id_GostR3411_94, NID_id_GostR3410_94_cc},
40 {NID_id_GostR3411_94_with_GostR3410_2001_cc, NID_id_GostR3411_94, NID_id_GostR3410_2001_cc},
41 };
42
43static const nid_triple * const sigoid_srt_xref[] =
44 {
45 &sigoid_srt[17],
46 &sigoid_srt[18],
47 &sigoid_srt[0],
48 &sigoid_srt[1],
49 &sigoid_srt[7],
50 &sigoid_srt[2],
51 &sigoid_srt[4],
52 &sigoid_srt[3],
53 &sigoid_srt[9],
54 &sigoid_srt[5],
55 &sigoid_srt[8],
56 &sigoid_srt[12],
57 &sigoid_srt[6],
58 &sigoid_srt[10],
59 &sigoid_srt[11],
60 &sigoid_srt[13],
61 &sigoid_srt[24],
62 &sigoid_srt[20],
63 &sigoid_srt[14],
64 &sigoid_srt[21],
65 &sigoid_srt[15],
66 &sigoid_srt[22],
67 &sigoid_srt[16],
68 &sigoid_srt[23],
69 &sigoid_srt[19],
70 &sigoid_srt[25],
71 &sigoid_srt[26],
72 &sigoid_srt[27],
73 &sigoid_srt[28],
74 };
75
diff --git a/src/lib/libcrypto/objects/obj_xref.txt b/src/lib/libcrypto/objects/obj_xref.txt
new file mode 100644
index 0000000000..e45b3d34b9
--- /dev/null
+++ b/src/lib/libcrypto/objects/obj_xref.txt
@@ -0,0 +1,42 @@
1# OID cross reference table.
2# Links signatures OIDs to their corresponding public key algorithms
3# and digests.
4
5md2WithRSAEncryption md2 rsaEncryption
6md5WithRSAEncryption md5 rsaEncryption
7shaWithRSAEncryption sha rsaEncryption
8sha1WithRSAEncryption sha1 rsaEncryption
9md4WithRSAEncryption md4 rsaEncryption
10sha256WithRSAEncryption sha256 rsaEncryption
11sha384WithRSAEncryption sha384 rsaEncryption
12sha512WithRSAEncryption sha512 rsaEncryption
13sha224WithRSAEncryption sha224 rsaEncryption
14mdc2WithRSA mdc2 rsaEncryption
15ripemd160WithRSA ripemd160 rsaEncryption
16
17# Alternative deprecated OIDs. By using the older "rsa" OID this
18# type will be recognized by not normally used.
19
20md5WithRSA md5 rsa
21sha1WithRSA sha1 rsa
22
23dsaWithSHA sha dsa
24dsaWithSHA1 sha1 dsa
25
26dsaWithSHA1_2 sha1 dsa_2
27
28ecdsa_with_SHA1 sha1 X9_62_id_ecPublicKey
29ecdsa_with_SHA224 sha224 X9_62_id_ecPublicKey
30ecdsa_with_SHA256 sha256 X9_62_id_ecPublicKey
31ecdsa_with_SHA384 sha384 X9_62_id_ecPublicKey
32ecdsa_with_SHA512 sha512 X9_62_id_ecPublicKey
33ecdsa_with_Recommended undef X9_62_id_ecPublicKey
34ecdsa_with_Specified undef X9_62_id_ecPublicKey
35
36dsa_with_SHA224 sha224 dsa
37dsa_with_SHA256 sha256 dsa
38
39id_GostR3411_94_with_GostR3410_2001 id_GostR3411_94 id_GostR3410_2001
40id_GostR3411_94_with_GostR3410_94 id_GostR3411_94 id_GostR3410_94
41id_GostR3411_94_with_GostR3410_94_cc id_GostR3411_94 id_GostR3410_94_cc
42id_GostR3411_94_with_GostR3410_2001_cc id_GostR3411_94 id_GostR3410_2001_cc
diff --git a/src/lib/libcrypto/objects/objects.h b/src/lib/libcrypto/objects/objects.h
index 7242f76fb0..bd0ee52feb 100644
--- a/src/lib/libcrypto/objects/objects.h
+++ b/src/lib/libcrypto/objects/objects.h
@@ -1011,10 +1011,91 @@ int OBJ_txt2nid(const char *s);
1011int OBJ_ln2nid(const char *s); 1011int OBJ_ln2nid(const char *s);
1012int OBJ_sn2nid(const char *s); 1012int OBJ_sn2nid(const char *s);
1013int OBJ_cmp(const ASN1_OBJECT *a,const ASN1_OBJECT *b); 1013int OBJ_cmp(const ASN1_OBJECT *a,const ASN1_OBJECT *b);
1014const char * OBJ_bsearch(const char *key,const char *base,int num,int size, 1014const void * OBJ_bsearch_(const void *key,const void *base,int num,int size,
1015 int (*cmp)(const void *, const void *)); 1015 int (*cmp)(const void *, const void *));
1016const char * OBJ_bsearch_ex(const char *key,const char *base,int num, 1016const void * OBJ_bsearch_ex_(const void *key,const void *base,int num,
1017 int size, int (*cmp)(const void *, const void *), int flags); 1017 int size,
1018 int (*cmp)(const void *, const void *),
1019 int flags);
1020
1021#define _DECLARE_OBJ_BSEARCH_CMP_FN(scope, type1, type2, nm) \
1022 static int nm##_cmp_BSEARCH_CMP_FN(const void *, const void *); \
1023 static int nm##_cmp(type1 const *, type2 const *); \
1024 scope type2 * OBJ_bsearch_##nm(type1 *key, type2 const *base, int num)
1025
1026#define DECLARE_OBJ_BSEARCH_CMP_FN(type1, type2, cmp) \
1027 _DECLARE_OBJ_BSEARCH_CMP_FN(static, type1, type2, cmp)
1028#define DECLARE_OBJ_BSEARCH_GLOBAL_CMP_FN(type1, type2, nm) \
1029 type2 * OBJ_bsearch_##nm(type1 *key, type2 const *base, int num)
1030
1031/*
1032 * Unsolved problem: if a type is actually a pointer type, like
1033 * nid_triple is, then its impossible to get a const where you need
1034 * it. Consider:
1035 *
1036 * typedef int nid_triple[3];
1037 * const void *a_;
1038 * const nid_triple const *a = a_;
1039 *
1040 * The assignement discards a const because what you really want is:
1041 *
1042 * const int const * const *a = a_;
1043 *
1044 * But if you do that, you lose the fact that a is an array of 3 ints,
1045 * which breaks comparison functions.
1046 *
1047 * Thus we end up having to cast, sadly, or unpack the
1048 * declarations. Or, as I finally did in this case, delcare nid_triple
1049 * to be a struct, which it should have been in the first place.
1050 *
1051 * Ben, August 2008.
1052 *
1053 * Also, strictly speaking not all types need be const, but handling
1054 * the non-constness means a lot of complication, and in practice
1055 * comparison routines do always not touch their arguments.
1056 */
1057
1058#define IMPLEMENT_OBJ_BSEARCH_CMP_FN(type1, type2, nm) \
1059 static int nm##_cmp_BSEARCH_CMP_FN(const void *a_, const void *b_) \
1060 { \
1061 type1 const *a = a_; \
1062 type2 const *b = b_; \
1063 return nm##_cmp(a,b); \
1064 } \
1065 static type2 *OBJ_bsearch_##nm(type1 *key, type2 const *base, int num) \
1066 { \
1067 return (type2 *)OBJ_bsearch_(key, base, num, sizeof(type2), \
1068 nm##_cmp_BSEARCH_CMP_FN); \
1069 } \
1070 extern void dummy_prototype(void)
1071
1072#define IMPLEMENT_OBJ_BSEARCH_GLOBAL_CMP_FN(type1, type2, nm) \
1073 static int nm##_cmp_BSEARCH_CMP_FN(const void *a_, const void *b_) \
1074 { \
1075 type1 const *a = a_; \
1076 type2 const *b = b_; \
1077 return nm##_cmp(a,b); \
1078 } \
1079 type2 *OBJ_bsearch_##nm(type1 *key, type2 const *base, int num) \
1080 { \
1081 return (type2 *)OBJ_bsearch_(key, base, num, sizeof(type2), \
1082 nm##_cmp_BSEARCH_CMP_FN); \
1083 } \
1084 extern void dummy_prototype(void)
1085
1086#define OBJ_bsearch(type1,key,type2,base,num,cmp) \
1087 ((type2 *)OBJ_bsearch_(CHECKED_PTR_OF(type1,key),CHECKED_PTR_OF(type2,base), \
1088 num,sizeof(type2), \
1089 ((void)CHECKED_PTR_OF(type1,cmp##_type_1), \
1090 (void)CHECKED_PTR_OF(type2,cmp##_type_2), \
1091 cmp##_BSEARCH_CMP_FN)))
1092
1093#define OBJ_bsearch_ex(type1,key,type2,base,num,cmp,flags) \
1094 ((type2 *)OBJ_bsearch_ex_(CHECKED_PTR_OF(type1,key),CHECKED_PTR_OF(type2,base), \
1095 num,sizeof(type2), \
1096 ((void)CHECKED_PTR_OF(type1,cmp##_type_1), \
1097 (void)type_2=CHECKED_PTR_OF(type2,cmp##_type_2), \
1098 cmp##_BSEARCH_CMP_FN)),flags)
1018 1099
1019int OBJ_new_nid(int num); 1100int OBJ_new_nid(int num);
1020int OBJ_add_object(const ASN1_OBJECT *obj); 1101int OBJ_add_object(const ASN1_OBJECT *obj);
@@ -1022,6 +1103,14 @@ int OBJ_create(const char *oid,const char *sn,const char *ln);
1022void OBJ_cleanup(void ); 1103void OBJ_cleanup(void );
1023int OBJ_create_objects(BIO *in); 1104int OBJ_create_objects(BIO *in);
1024 1105
1106int OBJ_find_sigid_algs(int signid, int *pdig_nid, int *ppkey_nid);
1107int OBJ_find_sigid_by_algs(int *psignid, int dig_nid, int pkey_nid);
1108int OBJ_add_sigid(int signid, int dig_id, int pkey_id);
1109void OBJ_sigid_free(void);
1110
1111extern int obj_cleanup_defer;
1112void check_defer(int nid);
1113
1025/* BEGIN ERROR CODES */ 1114/* BEGIN ERROR CODES */
1026/* The following lines are auto generated by the script mkerr.pl. Any changes 1115/* The following lines are auto generated by the script mkerr.pl. Any changes
1027 * made after this point may be overwritten when the script is next run. 1116 * made after this point may be overwritten when the script is next run.
diff --git a/src/lib/libcrypto/objects/objects.pl b/src/lib/libcrypto/objects/objects.pl
index 76c06cc8f9..15c00bbd52 100644
--- a/src/lib/libcrypto/objects/objects.pl
+++ b/src/lib/libcrypto/objects/objects.pl
@@ -14,6 +14,8 @@ while(<NUMIN>)
14 $Cname =~ s/^X//; 14 $Cname =~ s/^X//;
15 if (defined($nidn{$mynum})) 15 if (defined($nidn{$mynum}))
16 { die "$ARGV[1]:$o:There's already an object with NID ",$mynum," on line ",$order{$mynum},"\n"; } 16 { die "$ARGV[1]:$o:There's already an object with NID ",$mynum," on line ",$order{$mynum},"\n"; }
17 if (defined($nid{$Cname}))
18 { die "$ARGV[1]:$o:There's already an object with name ",$Cname," on line ",$order{$nid{$Cname}},"\n"; }
17 $nid{$Cname} = $mynum; 19 $nid{$Cname} = $mynum;
18 $nidn{$mynum} = $Cname; 20 $nidn{$mynum} = $Cname;
19 $order{$mynum} = $o; 21 $order{$mynum} = $o;
@@ -102,6 +104,7 @@ while (<IN>)
102 $max_nid++; 104 $max_nid++;
103 $nid{$Cname} = $max_nid; 105 $nid{$Cname} = $max_nid;
104 $nidn{$max_nid} = $Cname; 106 $nidn{$max_nid} = $Cname;
107print STDERR "Added OID $Cname\n";
105 } 108 }
106 $Cname=""; 109 $Cname="";
107 } 110 }
diff --git a/src/lib/libcrypto/objects/objects.txt b/src/lib/libcrypto/objects/objects.txt
index a6a811b8e7..e61fe60cbf 100644
--- a/src/lib/libcrypto/objects/objects.txt
+++ b/src/lib/libcrypto/objects/objects.txt
@@ -20,7 +20,7 @@ identified-organization 132 : certicom-arc
20joint-iso-itu-t 23 : international-organizations : International Organizations 20joint-iso-itu-t 23 : international-organizations : International Organizations
21 21
22international-organizations 43 : wap 22international-organizations 43 : wap
23wap 13 : wap-wsg 23wap 1 : wap-wsg
24 24
25joint-iso-itu-t 5 1 5 : selected-attribute-types : Selected Attribute Types 25joint-iso-itu-t 5 1 5 : selected-attribute-types : Selected Attribute Types
26 26
@@ -664,18 +664,52 @@ X509 5 : : serialNumber
664X509 6 : C : countryName 664X509 6 : C : countryName
665X509 7 : L : localityName 665X509 7 : L : localityName
666X509 8 : ST : stateOrProvinceName 666X509 8 : ST : stateOrProvinceName
667X509 9 : : streetAddress 667X509 9 : street : streetAddress
668X509 10 : O : organizationName 668X509 10 : O : organizationName
669X509 11 : OU : organizationalUnitName 669X509 11 : OU : organizationalUnitName
670X509 12 : : title 670X509 12 : title : title
671X509 13 : : description 671X509 13 : : description
672X509 17 : : postalCode 672X509 14 : : searchGuide
673X509 15 : : businessCategory
674X509 16 : : postalAddress
675X509 17 : : postalCode
676X509 18 : : postOfficeBox
677X509 19 : : physicalDeliveryOfficeName
678X509 20 : : telephoneNumber
679X509 21 : : telexNumber
680X509 22 : : teletexTerminalIdentifier
681X509 23 : : facsimileTelephoneNumber
682X509 24 : : x121Address
683X509 25 : : internationaliSDNNumber
684X509 26 : : registeredAddress
685X509 27 : : destinationIndicator
686X509 28 : : preferredDeliveryMethod
687X509 29 : : presentationAddress
688X509 30 : : supportedApplicationContext
689X509 31 : member :
690X509 32 : owner :
691X509 33 : : roleOccupant
692X509 34 : seeAlso :
693X509 35 : : userPassword
694X509 36 : : userCertificate
695X509 37 : : cACertificate
696X509 38 : : authorityRevocationList
697X509 39 : : certificateRevocationList
698X509 40 : : crossCertificatePair
673X509 41 : name : name 699X509 41 : name : name
674X509 42 : GN : givenName 700X509 42 : GN : givenName
675X509 43 : : initials 701X509 43 : initials : initials
676X509 44 : : generationQualifier 702X509 44 : : generationQualifier
677X509 45 : : x500UniqueIdentifier 703X509 45 : : x500UniqueIdentifier
678X509 46 : dnQualifier : dnQualifier 704X509 46 : dnQualifier : dnQualifier
705X509 47 : : enhancedSearchGuide
706X509 48 : : protocolInformation
707X509 49 : : distinguishedName
708X509 50 : : uniqueMember
709X509 51 : : houseIdentifier
710X509 52 : : supportedAlgorithms
711X509 53 : : deltaRevocationList
712X509 54 : dmdName :
679X509 65 : : pseudonym 713X509 65 : : pseudonym
680X509 72 : role : role 714X509 72 : role : role
681 715
diff --git a/src/lib/libcrypto/objects/objxref.pl b/src/lib/libcrypto/objects/objxref.pl
new file mode 100644
index 0000000000..731d3ae22c
--- /dev/null
+++ b/src/lib/libcrypto/objects/objxref.pl
@@ -0,0 +1,107 @@
1#!/usr/local/bin/perl
2
3use strict;
4
5my %xref_tbl;
6my %oid_tbl;
7
8my ($mac_file, $xref_file) = @ARGV;
9
10open(IN, $mac_file) || die "Can't open $mac_file";
11
12# Read in OID nid values for a lookup table.
13
14while (<IN>)
15 {
16 chomp;
17 my ($name, $num) = /^(\S+)\s+(\S+)$/;
18 $oid_tbl{$name} = $num;
19 }
20close IN;
21
22open(IN, $xref_file) || die "Can't open $xref_file";
23
24my $ln = 1;
25
26while (<IN>)
27 {
28 chomp;
29 s/#.*$//;
30 next if (/^\S*$/);
31 my ($xr, $p1, $p2) = /^(\S+)\s+(\S+)\s+(\S+)/;
32 check_oid($xr);
33 check_oid($p1);
34 check_oid($p2);
35 $xref_tbl{$xr} = [$p1, $p2, $ln];
36 }
37
38my @xrkeys = keys %xref_tbl;
39
40my @srt1 = sort { $oid_tbl{$a} <=> $oid_tbl{$b}} @xrkeys;
41
42for(my $i = 0; $i <= $#srt1; $i++)
43 {
44 $xref_tbl{$srt1[$i]}[2] = $i;
45 }
46
47my @srt2 = sort
48 {
49 my$ap1 = $oid_tbl{$xref_tbl{$a}[0]};
50 my$bp1 = $oid_tbl{$xref_tbl{$b}[0]};
51 return $ap1 - $bp1 if ($ap1 != $bp1);
52 my$ap2 = $oid_tbl{$xref_tbl{$a}[1]};
53 my$bp2 = $oid_tbl{$xref_tbl{$b}[1]};
54
55 return $ap2 - $bp2;
56 } @xrkeys;
57
58my $pname = $0;
59
60$pname =~ s|^.[^/]/||;
61
62print <<EOF;
63/* AUTOGENERATED BY $pname, DO NOT EDIT */
64
65typedef struct
66 {
67 int sign_id;
68 int hash_id;
69 int pkey_id;
70 } nid_triple;
71
72static const nid_triple sigoid_srt[] =
73 {
74EOF
75
76foreach (@srt1)
77 {
78 my $xr = $_;
79 my ($p1, $p2) = @{$xref_tbl{$_}};
80 print "\t{NID_$xr, NID_$p1, NID_$p2},\n";
81 }
82
83print "\t};";
84print <<EOF;
85
86
87static const nid_triple * const sigoid_srt_xref[] =
88 {
89EOF
90
91foreach (@srt2)
92 {
93 my $x = $xref_tbl{$_}[2];
94 print "\t\&sigoid_srt\[$x\],\n";
95 }
96
97print "\t};\n\n";
98
99sub check_oid
100 {
101 my ($chk) = @_;
102 if (!exists $oid_tbl{$chk})
103 {
104 die "Not Found \"$chk\"\n";
105 }
106 }
107
diff --git a/src/lib/libcrypto/ocsp/ocsp.h b/src/lib/libcrypto/ocsp/ocsp.h
index a0577a717e..31e45744ba 100644
--- a/src/lib/libcrypto/ocsp/ocsp.h
+++ b/src/lib/libcrypto/ocsp/ocsp.h
@@ -64,6 +64,7 @@
64#ifndef HEADER_OCSP_H 64#ifndef HEADER_OCSP_H
65#define HEADER_OCSP_H 65#define HEADER_OCSP_H
66 66
67#include <openssl/ossl_typ.h>
67#include <openssl/x509.h> 68#include <openssl/x509.h>
68#include <openssl/x509v3.h> 69#include <openssl/x509v3.h>
69#include <openssl/safestack.h> 70#include <openssl/safestack.h>
@@ -394,17 +395,20 @@ typedef struct ocsp_service_locator_st
394#define ASN1_BIT_STRING_digest(data,type,md,len) \ 395#define ASN1_BIT_STRING_digest(data,type,md,len) \
395 ASN1_item_digest(ASN1_ITEM_rptr(ASN1_BIT_STRING),type,data,md,len) 396 ASN1_item_digest(ASN1_ITEM_rptr(ASN1_BIT_STRING),type,data,md,len)
396 397
397#define OCSP_CERTID_dup(cid) ASN1_dup_of(OCSP_CERTID,i2d_OCSP_CERTID,d2i_OCSP_CERTID,cid)
398
399#define OCSP_CERTSTATUS_dup(cs)\ 398#define OCSP_CERTSTATUS_dup(cs)\
400 (OCSP_CERTSTATUS*)ASN1_dup((int(*)())i2d_OCSP_CERTSTATUS,\ 399 (OCSP_CERTSTATUS*)ASN1_dup((int(*)())i2d_OCSP_CERTSTATUS,\
401 (char *(*)())d2i_OCSP_CERTSTATUS,(char *)(cs)) 400 (char *(*)())d2i_OCSP_CERTSTATUS,(char *)(cs))
402 401
402OCSP_CERTID *OCSP_CERTID_dup(OCSP_CERTID *id);
403
403OCSP_RESPONSE *OCSP_sendreq_bio(BIO *b, char *path, OCSP_REQUEST *req); 404OCSP_RESPONSE *OCSP_sendreq_bio(BIO *b, char *path, OCSP_REQUEST *req);
404OCSP_REQ_CTX *OCSP_sendreq_new(BIO *io, char *path, OCSP_REQUEST *req, 405OCSP_REQ_CTX *OCSP_sendreq_new(BIO *io, char *path, OCSP_REQUEST *req,
405 int maxline); 406 int maxline);
406int OCSP_sendreq_nbio(OCSP_RESPONSE **presp, OCSP_REQ_CTX *rctx); 407int OCSP_sendreq_nbio(OCSP_RESPONSE **presp, OCSP_REQ_CTX *rctx);
407void OCSP_REQ_CTX_free(OCSP_REQ_CTX *rctx); 408void OCSP_REQ_CTX_free(OCSP_REQ_CTX *rctx);
409int OCSP_REQ_CTX_set1_req(OCSP_REQ_CTX *rctx, OCSP_REQUEST *req);
410int OCSP_REQ_CTX_add1_header(OCSP_REQ_CTX *rctx,
411 const char *name, const char *value);
408 412
409OCSP_CERTID *OCSP_cert_to_id(const EVP_MD *dgst, X509 *subject, X509 *issuer); 413OCSP_CERTID *OCSP_cert_to_id(const EVP_MD *dgst, X509 *subject, X509 *issuer);
410 414
@@ -474,11 +478,6 @@ int OCSP_basic_sign(OCSP_BASICRESP *brsp,
474 X509 *signer, EVP_PKEY *key, const EVP_MD *dgst, 478 X509 *signer, EVP_PKEY *key, const EVP_MD *dgst,
475 STACK_OF(X509) *certs, unsigned long flags); 479 STACK_OF(X509) *certs, unsigned long flags);
476 480
477ASN1_STRING *ASN1_STRING_encode(ASN1_STRING *s, i2d_of_void *i2d,
478 void *data, STACK_OF(ASN1_OBJECT) *sk);
479#define ASN1_STRING_encode_of(type,s,i2d,data,sk) \
480 ASN1_STRING_encode(s, CHECKED_I2D_OF(type, i2d), data, sk)
481
482X509_EXTENSION *OCSP_crlID_new(char *url, long *n, char *tim); 481X509_EXTENSION *OCSP_crlID_new(char *url, long *n, char *tim);
483 482
484X509_EXTENSION *OCSP_accept_responses_new(char **oids); 483X509_EXTENSION *OCSP_accept_responses_new(char **oids);
@@ -547,9 +546,9 @@ DECLARE_ASN1_FUNCTIONS(OCSP_REQINFO)
547DECLARE_ASN1_FUNCTIONS(OCSP_CRLID) 546DECLARE_ASN1_FUNCTIONS(OCSP_CRLID)
548DECLARE_ASN1_FUNCTIONS(OCSP_SERVICELOC) 547DECLARE_ASN1_FUNCTIONS(OCSP_SERVICELOC)
549 548
550char *OCSP_response_status_str(long s); 549const char *OCSP_response_status_str(long s);
551char *OCSP_cert_status_str(long s); 550const char *OCSP_cert_status_str(long s);
552char *OCSP_crl_reason_str(long s); 551const char *OCSP_crl_reason_str(long s);
553 552
554int OCSP_REQUEST_print(BIO *bp, OCSP_REQUEST* a, unsigned long flags); 553int OCSP_REQUEST_print(BIO *bp, OCSP_REQUEST* a, unsigned long flags);
555int OCSP_RESPONSE_print(BIO *bp, OCSP_RESPONSE* o, unsigned long flags); 554int OCSP_RESPONSE_print(BIO *bp, OCSP_RESPONSE* o, unsigned long flags);
@@ -582,7 +581,8 @@ void ERR_load_OCSP_strings(void);
582#define OCSP_F_OCSP_REQUEST_VERIFY 116 581#define OCSP_F_OCSP_REQUEST_VERIFY 116
583#define OCSP_F_OCSP_RESPONSE_GET1_BASIC 111 582#define OCSP_F_OCSP_RESPONSE_GET1_BASIC 111
584#define OCSP_F_OCSP_SENDREQ_BIO 112 583#define OCSP_F_OCSP_SENDREQ_BIO 112
585#define OCSP_F_PARSE_HTTP_LINE1 117 584#define OCSP_F_OCSP_SENDREQ_NBIO 117
585#define OCSP_F_PARSE_HTTP_LINE1 118
586#define OCSP_F_REQUEST_VERIFY 113 586#define OCSP_F_REQUEST_VERIFY 113
587 587
588/* Reason codes. */ 588/* Reason codes. */
diff --git a/src/lib/libcrypto/ocsp/ocsp_cl.c b/src/lib/libcrypto/ocsp/ocsp_cl.c
index 17bab5fc59..9c14d9da27 100644
--- a/src/lib/libcrypto/ocsp/ocsp_cl.c
+++ b/src/lib/libcrypto/ocsp/ocsp_cl.c
@@ -155,7 +155,6 @@ int OCSP_request_sign(OCSP_REQUEST *req,
155 goto err; 155 goto err;
156 156
157 if (!(req->optionalSignature = sig = OCSP_SIGNATURE_new())) goto err; 157 if (!(req->optionalSignature = sig = OCSP_SIGNATURE_new())) goto err;
158 if (!dgst) dgst = EVP_sha1();
159 if (key) 158 if (key)
160 { 159 {
161 if (!X509_check_private_key(signer, key)) 160 if (!X509_check_private_key(signer, key))
diff --git a/src/lib/libcrypto/ocsp/ocsp_err.c b/src/lib/libcrypto/ocsp/ocsp_err.c
index d2f2e79f44..0cedcea682 100644
--- a/src/lib/libcrypto/ocsp/ocsp_err.c
+++ b/src/lib/libcrypto/ocsp/ocsp_err.c
@@ -1,6 +1,6 @@
1/* crypto/ocsp/ocsp_err.c */ 1/* crypto/ocsp/ocsp_err.c */
2/* ==================================================================== 2/* ====================================================================
3 * Copyright (c) 1999-2007 The OpenSSL Project. All rights reserved. 3 * Copyright (c) 1999-2006 The OpenSSL Project. All rights reserved.
4 * 4 *
5 * Redistribution and use in source and binary forms, with or without 5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions 6 * modification, are permitted provided that the following conditions
@@ -86,6 +86,7 @@ static ERR_STRING_DATA OCSP_str_functs[]=
86{ERR_FUNC(OCSP_F_OCSP_REQUEST_VERIFY), "OCSP_request_verify"}, 86{ERR_FUNC(OCSP_F_OCSP_REQUEST_VERIFY), "OCSP_request_verify"},
87{ERR_FUNC(OCSP_F_OCSP_RESPONSE_GET1_BASIC), "OCSP_response_get1_basic"}, 87{ERR_FUNC(OCSP_F_OCSP_RESPONSE_GET1_BASIC), "OCSP_response_get1_basic"},
88{ERR_FUNC(OCSP_F_OCSP_SENDREQ_BIO), "OCSP_sendreq_bio"}, 88{ERR_FUNC(OCSP_F_OCSP_SENDREQ_BIO), "OCSP_sendreq_bio"},
89{ERR_FUNC(OCSP_F_OCSP_SENDREQ_NBIO), "OCSP_sendreq_nbio"},
89{ERR_FUNC(OCSP_F_PARSE_HTTP_LINE1), "PARSE_HTTP_LINE1"}, 90{ERR_FUNC(OCSP_F_PARSE_HTTP_LINE1), "PARSE_HTTP_LINE1"},
90{ERR_FUNC(OCSP_F_REQUEST_VERIFY), "REQUEST_VERIFY"}, 91{ERR_FUNC(OCSP_F_REQUEST_VERIFY), "REQUEST_VERIFY"},
91{0,NULL} 92{0,NULL}
diff --git a/src/lib/libcrypto/ocsp/ocsp_ext.c b/src/lib/libcrypto/ocsp/ocsp_ext.c
index 815cc29d58..ec884cb08f 100644
--- a/src/lib/libcrypto/ocsp/ocsp_ext.c
+++ b/src/lib/libcrypto/ocsp/ocsp_ext.c
@@ -264,7 +264,7 @@ int OCSP_SINGLERESP_add_ext(OCSP_SINGLERESP *x, X509_EXTENSION *ex, int loc)
264 } 264 }
265 265
266/* also CRL Entry Extensions */ 266/* also CRL Entry Extensions */
267 267#if 0
268ASN1_STRING *ASN1_STRING_encode(ASN1_STRING *s, i2d_of_void *i2d, 268ASN1_STRING *ASN1_STRING_encode(ASN1_STRING *s, i2d_of_void *i2d,
269 void *data, STACK_OF(ASN1_OBJECT) *sk) 269 void *data, STACK_OF(ASN1_OBJECT) *sk)
270 { 270 {
@@ -305,6 +305,7 @@ err:
305 if (b) OPENSSL_free(b); 305 if (b) OPENSSL_free(b);
306 return NULL; 306 return NULL;
307 } 307 }
308#endif
308 309
309/* Nonce handling functions */ 310/* Nonce handling functions */
310 311
@@ -442,17 +443,10 @@ X509_EXTENSION *OCSP_crlID_new(char *url, long *n, char *tim)
442 if (!(ASN1_GENERALIZEDTIME_set_string(cid->crlTime, tim))) 443 if (!(ASN1_GENERALIZEDTIME_set_string(cid->crlTime, tim)))
443 goto err; 444 goto err;
444 } 445 }
445 if (!(x = X509_EXTENSION_new())) goto err; 446 x = X509V3_EXT_i2d(NID_id_pkix_OCSP_CrlID, 0, cid);
446 if (!(x->object = OBJ_nid2obj(NID_id_pkix_OCSP_CrlID))) goto err;
447 if (!(ASN1_STRING_encode_of(OCSP_CRLID,x->value,i2d_OCSP_CRLID,cid,
448 NULL)))
449 goto err;
450 OCSP_CRLID_free(cid);
451 return x;
452err: 447err:
453 if (x) X509_EXTENSION_free(x);
454 if (cid) OCSP_CRLID_free(cid); 448 if (cid) OCSP_CRLID_free(cid);
455 return NULL; 449 return x;
456 } 450 }
457 451
458/* AcceptableResponses ::= SEQUENCE OF OBJECT IDENTIFIER */ 452/* AcceptableResponses ::= SEQUENCE OF OBJECT IDENTIFIER */
@@ -470,18 +464,10 @@ X509_EXTENSION *OCSP_accept_responses_new(char **oids)
470 sk_ASN1_OBJECT_push(sk, o); 464 sk_ASN1_OBJECT_push(sk, o);
471 oids++; 465 oids++;
472 } 466 }
473 if (!(x = X509_EXTENSION_new())) goto err; 467 x = X509V3_EXT_i2d(NID_id_pkix_OCSP_acceptableResponses, 0, sk);
474 if (!(x->object = OBJ_nid2obj(NID_id_pkix_OCSP_acceptableResponses)))
475 goto err;
476 if (!(ASN1_STRING_encode_of(ASN1_OBJECT,x->value,i2d_ASN1_OBJECT,NULL,
477 sk)))
478 goto err;
479 sk_ASN1_OBJECT_pop_free(sk, ASN1_OBJECT_free);
480 return x;
481err: 468err:
482 if (x) X509_EXTENSION_free(x);
483 if (sk) sk_ASN1_OBJECT_pop_free(sk, ASN1_OBJECT_free); 469 if (sk) sk_ASN1_OBJECT_pop_free(sk, ASN1_OBJECT_free);
484 return NULL; 470 return x;
485 } 471 }
486 472
487/* ArchiveCutoff ::= GeneralizedTime */ 473/* ArchiveCutoff ::= GeneralizedTime */
@@ -492,16 +478,10 @@ X509_EXTENSION *OCSP_archive_cutoff_new(char* tim)
492 478
493 if (!(gt = ASN1_GENERALIZEDTIME_new())) goto err; 479 if (!(gt = ASN1_GENERALIZEDTIME_new())) goto err;
494 if (!(ASN1_GENERALIZEDTIME_set_string(gt, tim))) goto err; 480 if (!(ASN1_GENERALIZEDTIME_set_string(gt, tim))) goto err;
495 if (!(x = X509_EXTENSION_new())) goto err; 481 x = X509V3_EXT_i2d(NID_id_pkix_OCSP_archiveCutoff, 0, gt);
496 if (!(x->object=OBJ_nid2obj(NID_id_pkix_OCSP_archiveCutoff)))goto err;
497 if (!(ASN1_STRING_encode_of(ASN1_GENERALIZEDTIME,x->value,
498 i2d_ASN1_GENERALIZEDTIME,gt,NULL))) goto err;
499 ASN1_GENERALIZEDTIME_free(gt);
500 return x;
501err: 482err:
502 if (gt) ASN1_GENERALIZEDTIME_free(gt); 483 if (gt) ASN1_GENERALIZEDTIME_free(gt);
503 if (x) X509_EXTENSION_free(x); 484 return x;
504 return NULL;
505 } 485 }
506 486
507/* per ACCESS_DESCRIPTION parameter are oids, of which there are currently 487/* per ACCESS_DESCRIPTION parameter are oids, of which there are currently
@@ -530,16 +510,9 @@ X509_EXTENSION *OCSP_url_svcloc_new(X509_NAME* issuer, char **urls)
530 if (!sk_ACCESS_DESCRIPTION_push(sloc->locator, ad)) goto err; 510 if (!sk_ACCESS_DESCRIPTION_push(sloc->locator, ad)) goto err;
531 urls++; 511 urls++;
532 } 512 }
533 if (!(x = X509_EXTENSION_new())) goto err; 513 x = X509V3_EXT_i2d(NID_id_pkix_OCSP_serviceLocator, 0, sloc);
534 if (!(x->object = OBJ_nid2obj(NID_id_pkix_OCSP_serviceLocator)))
535 goto err;
536 if (!(ASN1_STRING_encode_of(OCSP_SERVICELOC,x->value,
537 i2d_OCSP_SERVICELOC,sloc,NULL))) goto err;
538 OCSP_SERVICELOC_free(sloc);
539 return x;
540err: 514err:
541 if (x) X509_EXTENSION_free(x);
542 if (sloc) OCSP_SERVICELOC_free(sloc); 515 if (sloc) OCSP_SERVICELOC_free(sloc);
543 return NULL; 516 return x;
544 } 517 }
545 518
diff --git a/src/lib/libcrypto/ocsp/ocsp_ht.c b/src/lib/libcrypto/ocsp/ocsp_ht.c
index 6abb30b2c0..12bbfcffd1 100644
--- a/src/lib/libcrypto/ocsp/ocsp_ht.c
+++ b/src/lib/libcrypto/ocsp/ocsp_ht.c
@@ -118,39 +118,65 @@ void OCSP_REQ_CTX_free(OCSP_REQ_CTX *rctx)
118 OPENSSL_free(rctx); 118 OPENSSL_free(rctx);
119 } 119 }
120 120
121OCSP_REQ_CTX *OCSP_sendreq_new(BIO *io, char *path, OCSP_REQUEST *req, 121int OCSP_REQ_CTX_set1_req(OCSP_REQ_CTX *rctx, OCSP_REQUEST *req)
122 int maxline)
123 { 122 {
124 static char post_hdr[] = "POST %s HTTP/1.0\r\n" 123 static const char req_hdr[] =
125 "Content-Type: application/ocsp-request\r\n" 124 "Content-Type: application/ocsp-request\r\n"
126 "Content-Length: %d\r\n\r\n"; 125 "Content-Length: %d\r\n\r\n";
126 if (BIO_printf(rctx->mem, req_hdr, i2d_OCSP_REQUEST(req, NULL)) <= 0)
127 return 0;
128 if (i2d_OCSP_REQUEST_bio(rctx->mem, req) <= 0)
129 return 0;
130 rctx->state = OHS_ASN1_WRITE;
131 rctx->asn1_len = BIO_get_mem_data(rctx->mem, NULL);
132 return 1;
133 }
134
135int OCSP_REQ_CTX_add1_header(OCSP_REQ_CTX *rctx,
136 const char *name, const char *value)
137 {
138 if (!name)
139 return 0;
140 if (BIO_puts(rctx->mem, name) <= 0)
141 return 0;
142 if (value)
143 {
144 if (BIO_write(rctx->mem, ": ", 2) != 2)
145 return 0;
146 if (BIO_puts(rctx->mem, value) <= 0)
147 return 0;
148 }
149 if (BIO_write(rctx->mem, "\r\n", 2) != 2)
150 return 0;
151 return 1;
152 }
153
154OCSP_REQ_CTX *OCSP_sendreq_new(BIO *io, char *path, OCSP_REQUEST *req,
155 int maxline)
156 {
157 static const char post_hdr[] = "POST %s HTTP/1.0\r\n";
127 158
128 OCSP_REQ_CTX *rctx; 159 OCSP_REQ_CTX *rctx;
129 rctx = OPENSSL_malloc(sizeof(OCSP_REQ_CTX)); 160 rctx = OPENSSL_malloc(sizeof(OCSP_REQ_CTX));
130 rctx->state = OHS_FIRSTLINE; 161 rctx->state = OHS_ERROR;
131 rctx->mem = BIO_new(BIO_s_mem()); 162 rctx->mem = BIO_new(BIO_s_mem());
132 rctx->io = io; 163 rctx->io = io;
164 rctx->asn1_len = 0;
133 if (maxline > 0) 165 if (maxline > 0)
134 rctx->iobuflen = maxline; 166 rctx->iobuflen = maxline;
135 else 167 else
136 rctx->iobuflen = OCSP_MAX_LINE_LEN; 168 rctx->iobuflen = OCSP_MAX_LINE_LEN;
137 rctx->iobuf = OPENSSL_malloc(rctx->iobuflen); 169 rctx->iobuf = OPENSSL_malloc(rctx->iobuflen);
170 if (!rctx->iobuf)
171 return 0;
138 if (!path) 172 if (!path)
139 path = "/"; 173 path = "/";
140 174
141 if (BIO_printf(rctx->mem, post_hdr, path, 175 if (BIO_printf(rctx->mem, post_hdr, path) <= 0)
142 i2d_OCSP_REQUEST(req, NULL)) <= 0)
143 {
144 rctx->state = OHS_ERROR;
145 return 0; 176 return 0;
146 } 177
147 if (i2d_OCSP_REQUEST_bio(rctx->mem, req) <= 0) 178 if (req && !OCSP_REQ_CTX_set1_req(rctx, req))
148 {
149 rctx->state = OHS_ERROR;
150 return 0; 179 return 0;
151 }
152 rctx->state = OHS_ASN1_WRITE;
153 rctx->asn1_len = BIO_get_mem_data(rctx->mem, NULL);
154 180
155 return rctx; 181 return rctx;
156 } 182 }
diff --git a/src/lib/libcrypto/ocsp/ocsp_lib.c b/src/lib/libcrypto/ocsp/ocsp_lib.c
index 27450811d7..36905d76cd 100644
--- a/src/lib/libcrypto/ocsp/ocsp_lib.c
+++ b/src/lib/libcrypto/ocsp/ocsp_lib.c
@@ -69,6 +69,7 @@
69#include <openssl/pem.h> 69#include <openssl/pem.h>
70#include <openssl/x509v3.h> 70#include <openssl/x509v3.h>
71#include <openssl/ocsp.h> 71#include <openssl/ocsp.h>
72#include <openssl/asn1t.h>
72 73
73/* Convert a certificate and its issuer to an OCSP_CERTID */ 74/* Convert a certificate and its issuer to an OCSP_CERTID */
74 75
@@ -260,3 +261,5 @@ int OCSP_parse_url(char *url, char **phost, char **pport, char **ppath, int *pss
260 return 0; 261 return 0;
261 262
262 } 263 }
264
265IMPLEMENT_ASN1_DUP_FUNCTION(OCSP_CERTID)
diff --git a/src/lib/libcrypto/ocsp/ocsp_prn.c b/src/lib/libcrypto/ocsp/ocsp_prn.c
index 3dfb51c1e4..1695c9c4ad 100644
--- a/src/lib/libcrypto/ocsp/ocsp_prn.c
+++ b/src/lib/libcrypto/ocsp/ocsp_prn.c
@@ -85,21 +85,21 @@ static int ocsp_certid_print(BIO *bp, OCSP_CERTID* a, int indent)
85typedef struct 85typedef struct
86 { 86 {
87 long t; 87 long t;
88 char *m; 88 const char *m;
89 } OCSP_TBLSTR; 89 } OCSP_TBLSTR;
90 90
91static char *table2string(long s, OCSP_TBLSTR *ts, int len) 91static const char *table2string(long s, const OCSP_TBLSTR *ts, int len)
92{ 92{
93 OCSP_TBLSTR *p; 93 const OCSP_TBLSTR *p;
94 for (p=ts; p < ts + len; p++) 94 for (p=ts; p < ts + len; p++)
95 if (p->t == s) 95 if (p->t == s)
96 return p->m; 96 return p->m;
97 return "(UNKNOWN)"; 97 return "(UNKNOWN)";
98} 98}
99 99
100char *OCSP_response_status_str(long s) 100const char *OCSP_response_status_str(long s)
101 { 101 {
102 static OCSP_TBLSTR rstat_tbl[] = { 102 static const OCSP_TBLSTR rstat_tbl[] = {
103 { OCSP_RESPONSE_STATUS_SUCCESSFUL, "successful" }, 103 { OCSP_RESPONSE_STATUS_SUCCESSFUL, "successful" },
104 { OCSP_RESPONSE_STATUS_MALFORMEDREQUEST, "malformedrequest" }, 104 { OCSP_RESPONSE_STATUS_MALFORMEDREQUEST, "malformedrequest" },
105 { OCSP_RESPONSE_STATUS_INTERNALERROR, "internalerror" }, 105 { OCSP_RESPONSE_STATUS_INTERNALERROR, "internalerror" },
@@ -109,18 +109,18 @@ char *OCSP_response_status_str(long s)
109 return table2string(s, rstat_tbl, 6); 109 return table2string(s, rstat_tbl, 6);
110 } 110 }
111 111
112char *OCSP_cert_status_str(long s) 112const char *OCSP_cert_status_str(long s)
113 { 113 {
114 static OCSP_TBLSTR cstat_tbl[] = { 114 static const OCSP_TBLSTR cstat_tbl[] = {
115 { V_OCSP_CERTSTATUS_GOOD, "good" }, 115 { V_OCSP_CERTSTATUS_GOOD, "good" },
116 { V_OCSP_CERTSTATUS_REVOKED, "revoked" }, 116 { V_OCSP_CERTSTATUS_REVOKED, "revoked" },
117 { V_OCSP_CERTSTATUS_UNKNOWN, "unknown" } }; 117 { V_OCSP_CERTSTATUS_UNKNOWN, "unknown" } };
118 return table2string(s, cstat_tbl, 3); 118 return table2string(s, cstat_tbl, 3);
119 } 119 }
120 120
121char *OCSP_crl_reason_str(long s) 121const char *OCSP_crl_reason_str(long s)
122 { 122 {
123 OCSP_TBLSTR reason_tbl[] = { 123 static const OCSP_TBLSTR reason_tbl[] = {
124 { OCSP_REVOKED_STATUS_UNSPECIFIED, "unspecified" }, 124 { OCSP_REVOKED_STATUS_UNSPECIFIED, "unspecified" },
125 { OCSP_REVOKED_STATUS_KEYCOMPROMISE, "keyCompromise" }, 125 { OCSP_REVOKED_STATUS_KEYCOMPROMISE, "keyCompromise" },
126 { OCSP_REVOKED_STATUS_CACOMPROMISE, "cACompromise" }, 126 { OCSP_REVOKED_STATUS_CACOMPROMISE, "cACompromise" },
@@ -266,15 +266,16 @@ int OCSP_RESPONSE_print(BIO *bp, OCSP_RESPONSE* o, unsigned long flags)
266 if (!ASN1_GENERALIZEDTIME_print(bp,single->nextUpdate)) 266 if (!ASN1_GENERALIZEDTIME_print(bp,single->nextUpdate))
267 goto err; 267 goto err;
268 } 268 }
269 if (!BIO_write(bp,"\n",1)) goto err; 269 if (BIO_write(bp,"\n",1) <= 0) goto err;
270 if (!X509V3_extensions_print(bp, 270 if (!X509V3_extensions_print(bp,
271 "Response Single Extensions", 271 "Response Single Extensions",
272 single->singleExtensions, flags, 8)) 272 single->singleExtensions, flags, 8))
273 goto err; 273 goto err;
274 if (!BIO_write(bp,"\n",1)) goto err; 274 if (BIO_write(bp,"\n",1) <= 0) goto err;
275 } 275 }
276 if (!X509V3_extensions_print(bp, "Response Extensions", 276 if (!X509V3_extensions_print(bp, "Response Extensions",
277 rd->responseExtensions, flags, 4)) 277 rd->responseExtensions, flags, 4))
278 goto err;
278 if(X509_signature_print(bp, br->signatureAlgorithm, br->signature) <= 0) 279 if(X509_signature_print(bp, br->signatureAlgorithm, br->signature) <= 0)
279 goto err; 280 goto err;
280 281
diff --git a/src/lib/libcrypto/ocsp/ocsp_vfy.c b/src/lib/libcrypto/ocsp/ocsp_vfy.c
index 4a0c3870d8..415d67e61c 100644
--- a/src/lib/libcrypto/ocsp/ocsp_vfy.c
+++ b/src/lib/libcrypto/ocsp/ocsp_vfy.c
@@ -308,6 +308,8 @@ static int ocsp_match_issuerid(X509 *cert, OCSP_CERTID *cid,
308 } 308 }
309 309
310 mdlen = EVP_MD_size(dgst); 310 mdlen = EVP_MD_size(dgst);
311 if (mdlen < 0)
312 return -1;
311 if ((cid->issuerNameHash->length != mdlen) || 313 if ((cid->issuerNameHash->length != mdlen) ||
312 (cid->issuerKeyHash->length != mdlen)) 314 (cid->issuerKeyHash->length != mdlen))
313 return 0; 315 return 0;
@@ -316,7 +318,7 @@ static int ocsp_match_issuerid(X509 *cert, OCSP_CERTID *cid,
316 return -1; 318 return -1;
317 if (memcmp(md, cid->issuerNameHash->data, mdlen)) 319 if (memcmp(md, cid->issuerNameHash->data, mdlen))
318 return 0; 320 return 0;
319 X509_pubkey_digest(cert, EVP_sha1(), md, NULL); 321 X509_pubkey_digest(cert, dgst, md, NULL);
320 if (memcmp(md, cid->issuerKeyHash->data, mdlen)) 322 if (memcmp(md, cid->issuerKeyHash->data, mdlen))
321 return 0; 323 return 0;
322 324
diff --git a/src/lib/libcrypto/opensslv.h b/src/lib/libcrypto/opensslv.h
index c6207f76b2..2fb110fa0e 100644
--- a/src/lib/libcrypto/opensslv.h
+++ b/src/lib/libcrypto/opensslv.h
@@ -12,7 +12,7 @@
12 * 0.9.3-beta2 0x00903002 (same as ...beta2-dev) 12 * 0.9.3-beta2 0x00903002 (same as ...beta2-dev)
13 * 0.9.3 0x0090300f 13 * 0.9.3 0x0090300f
14 * 0.9.3a 0x0090301f 14 * 0.9.3a 0x0090301f
15 * 0.9.4 0x0090400f 15 * 0.9.4 0x0090400f
16 * 1.2.3z 0x102031af 16 * 1.2.3z 0x102031af
17 * 17 *
18 * For continuity reasons (because 0.9.5 is already out, and is coded 18 * For continuity reasons (because 0.9.5 is already out, and is coded
@@ -25,11 +25,11 @@
25 * (Prior to 0.9.5a beta1, a different scheme was used: MMNNFFRBB for 25 * (Prior to 0.9.5a beta1, a different scheme was used: MMNNFFRBB for
26 * major minor fix final patch/beta) 26 * major minor fix final patch/beta)
27 */ 27 */
28#define OPENSSL_VERSION_NUMBER 0x009080bfL 28#define OPENSSL_VERSION_NUMBER 0x1000001fL
29#ifdef OPENSSL_FIPS 29#ifdef OPENSSL_FIPS
30#define OPENSSL_VERSION_TEXT "OpenSSL 0.9.8k-fips 25 Mar 2009" 30#define OPENSSL_VERSION_TEXT "OpenSSL 1.0.0a-fips 1 Jun 2010"
31#else 31#else
32#define OPENSSL_VERSION_TEXT "OpenSSL 0.9.8k 25 Mar 2009" 32#define OPENSSL_VERSION_TEXT "OpenSSL 1.0.0a 1 Jun 2010"
33#endif 33#endif
34#define OPENSSL_VERSION_PTEXT " part of " OPENSSL_VERSION_TEXT 34#define OPENSSL_VERSION_PTEXT " part of " OPENSSL_VERSION_TEXT
35 35
@@ -83,7 +83,7 @@
83 * should only keep the versions that are binary compatible with the current. 83 * should only keep the versions that are binary compatible with the current.
84 */ 84 */
85#define SHLIB_VERSION_HISTORY "" 85#define SHLIB_VERSION_HISTORY ""
86#define SHLIB_VERSION_NUMBER "0.9.8" 86#define SHLIB_VERSION_NUMBER "1.0.0"
87 87
88 88
89#endif /* HEADER_OPENSSLV_H */ 89#endif /* HEADER_OPENSSLV_H */
diff --git a/src/lib/libcrypto/ossl_typ.h b/src/lib/libcrypto/ossl_typ.h
index 0e7a380880..12bd7014de 100644
--- a/src/lib/libcrypto/ossl_typ.h
+++ b/src/lib/libcrypto/ossl_typ.h
@@ -95,6 +95,8 @@ typedef int ASN1_BOOLEAN;
95typedef int ASN1_NULL; 95typedef int ASN1_NULL;
96#endif 96#endif
97 97
98typedef struct asn1_pctx_st ASN1_PCTX;
99
98#ifdef OPENSSL_SYS_WIN32 100#ifdef OPENSSL_SYS_WIN32
99#undef X509_NAME 101#undef X509_NAME
100#undef X509_EXTENSIONS 102#undef X509_EXTENSIONS
@@ -122,6 +124,11 @@ typedef struct env_md_st EVP_MD;
122typedef struct env_md_ctx_st EVP_MD_CTX; 124typedef struct env_md_ctx_st EVP_MD_CTX;
123typedef struct evp_pkey_st EVP_PKEY; 125typedef struct evp_pkey_st EVP_PKEY;
124 126
127typedef struct evp_pkey_asn1_method_st EVP_PKEY_ASN1_METHOD;
128
129typedef struct evp_pkey_method_st EVP_PKEY_METHOD;
130typedef struct evp_pkey_ctx_st EVP_PKEY_CTX;
131
125typedef struct dh_st DH; 132typedef struct dh_st DH;
126typedef struct dh_method DH_METHOD; 133typedef struct dh_method DH_METHOD;
127 134
@@ -139,11 +146,14 @@ typedef struct ecdsa_method ECDSA_METHOD;
139typedef struct x509_st X509; 146typedef struct x509_st X509;
140typedef struct X509_algor_st X509_ALGOR; 147typedef struct X509_algor_st X509_ALGOR;
141typedef struct X509_crl_st X509_CRL; 148typedef struct X509_crl_st X509_CRL;
149typedef struct x509_crl_method_st X509_CRL_METHOD;
150typedef struct x509_revoked_st X509_REVOKED;
142typedef struct X509_name_st X509_NAME; 151typedef struct X509_name_st X509_NAME;
152typedef struct X509_pubkey_st X509_PUBKEY;
143typedef struct x509_store_st X509_STORE; 153typedef struct x509_store_st X509_STORE;
144typedef struct x509_store_ctx_st X509_STORE_CTX; 154typedef struct x509_store_ctx_st X509_STORE_CTX;
145typedef struct ssl_st SSL; 155
146typedef struct ssl_ctx_st SSL_CTX; 156typedef struct pkcs8_priv_key_info_st PKCS8_PRIV_KEY_INFO;
147 157
148typedef struct v3_ext_ctx X509V3_CTX; 158typedef struct v3_ext_ctx X509V3_CTX;
149typedef struct conf_st CONF; 159typedef struct conf_st CONF;
@@ -157,12 +167,19 @@ typedef struct ui_method_st UI_METHOD;
157typedef struct st_ERR_FNS ERR_FNS; 167typedef struct st_ERR_FNS ERR_FNS;
158 168
159typedef struct engine_st ENGINE; 169typedef struct engine_st ENGINE;
170typedef struct ssl_st SSL;
171typedef struct ssl_ctx_st SSL_CTX;
160 172
161typedef struct X509_POLICY_NODE_st X509_POLICY_NODE; 173typedef struct X509_POLICY_NODE_st X509_POLICY_NODE;
162typedef struct X509_POLICY_LEVEL_st X509_POLICY_LEVEL; 174typedef struct X509_POLICY_LEVEL_st X509_POLICY_LEVEL;
163typedef struct X509_POLICY_TREE_st X509_POLICY_TREE; 175typedef struct X509_POLICY_TREE_st X509_POLICY_TREE;
164typedef struct X509_POLICY_CACHE_st X509_POLICY_CACHE; 176typedef struct X509_POLICY_CACHE_st X509_POLICY_CACHE;
165 177
178typedef struct AUTHORITY_KEYID_st AUTHORITY_KEYID;
179typedef struct DIST_POINT_st DIST_POINT;
180typedef struct ISSUING_DIST_POINT_st ISSUING_DIST_POINT;
181typedef struct NAME_CONSTRAINTS_st NAME_CONSTRAINTS;
182
166 /* If placed in pkcs12.h, we end up with a circular depency with pkcs7.h */ 183 /* If placed in pkcs12.h, we end up with a circular depency with pkcs7.h */
167#define DECLARE_PKCS12_STACK_OF(type) /* Nothing */ 184#define DECLARE_PKCS12_STACK_OF(type) /* Nothing */
168#define IMPLEMENT_PKCS12_STACK_OF(type) /* Nothing */ 185#define IMPLEMENT_PKCS12_STACK_OF(type) /* Nothing */
diff --git a/src/lib/libcrypto/pem/pem.h b/src/lib/libcrypto/pem/pem.h
index 6c193f1cbf..8a6ababe3a 100644
--- a/src/lib/libcrypto/pem/pem.h
+++ b/src/lib/libcrypto/pem/pem.h
@@ -134,6 +134,7 @@ extern "C" {
134#define PEM_STRING_ECDSA_PUBLIC "ECDSA PUBLIC KEY" 134#define PEM_STRING_ECDSA_PUBLIC "ECDSA PUBLIC KEY"
135#define PEM_STRING_ECPARAMETERS "EC PARAMETERS" 135#define PEM_STRING_ECPARAMETERS "EC PARAMETERS"
136#define PEM_STRING_ECPRIVATEKEY "EC PRIVATE KEY" 136#define PEM_STRING_ECPRIVATEKEY "EC PRIVATE KEY"
137#define PEM_STRING_PARAMETERS "PARAMETERS"
137#define PEM_STRING_CMS "CMS" 138#define PEM_STRING_CMS "CMS"
138 139
139 /* Note that this structure is initialised by PEM_SealInit and cleaned up 140 /* Note that this structure is initialised by PEM_SealInit and cleaned up
@@ -183,11 +184,8 @@ typedef struct pem_ctx_st
183 int num_recipient; 184 int num_recipient;
184 PEM_USER **recipient; 185 PEM_USER **recipient;
185 186
186#ifndef OPENSSL_NO_STACK 187 /* XXX(ben): don#t think this is used!
187 STACK *x509_chain; /* certificate chain */ 188 STACK *x509_chain; / * certificate chain */
188#else
189 char *x509_chain; /* certificate chain */
190#endif
191 EVP_MD *md; /* signature type */ 189 EVP_MD *md; /* signature type */
192 190
193 int md_enc; /* is the md encrypted or not? */ 191 int md_enc; /* is the md encrypted or not? */
@@ -224,28 +222,19 @@ typedef struct pem_ctx_st
224#define IMPLEMENT_PEM_read_fp(name, type, str, asn1) \ 222#define IMPLEMENT_PEM_read_fp(name, type, str, asn1) \
225type *PEM_read_##name(FILE *fp, type **x, pem_password_cb *cb, void *u)\ 223type *PEM_read_##name(FILE *fp, type **x, pem_password_cb *cb, void *u)\
226{ \ 224{ \
227 return (type*)PEM_ASN1_read(CHECKED_D2I_OF(type, d2i_##asn1), \ 225return PEM_ASN1_read((d2i_of_void *)d2i_##asn1, str,fp,(void **)x,cb,u); \
228 str, fp, \
229 CHECKED_PPTR_OF(type, x), \
230 cb, u); \
231} 226}
232 227
233#define IMPLEMENT_PEM_write_fp(name, type, str, asn1) \ 228#define IMPLEMENT_PEM_write_fp(name, type, str, asn1) \
234int PEM_write_##name(FILE *fp, type *x) \ 229int PEM_write_##name(FILE *fp, type *x) \
235{ \ 230{ \
236 return PEM_ASN1_write(CHECKED_I2D_OF(type, i2d_##asn1), \ 231return PEM_ASN1_write((i2d_of_void *)i2d_##asn1,str,fp,x,NULL,NULL,0,NULL,NULL); \
237 str, fp, \
238 CHECKED_PTR_OF(type, x), \
239 NULL, NULL, 0, NULL, NULL); \
240} 232}
241 233
242#define IMPLEMENT_PEM_write_fp_const(name, type, str, asn1) \ 234#define IMPLEMENT_PEM_write_fp_const(name, type, str, asn1) \
243int PEM_write_##name(FILE *fp, const type *x) \ 235int PEM_write_##name(FILE *fp, const type *x) \
244{ \ 236{ \
245 return PEM_ASN1_write(CHECKED_I2D_OF(const type, i2d_##asn1), \ 237return PEM_ASN1_write((i2d_of_void *)i2d_##asn1,str,fp,(void *)x,NULL,NULL,0,NULL,NULL); \
246 str, fp, \
247 CHECKED_PTR_OF(const type, x), \
248 NULL, NULL, 0, NULL, NULL); \
249} 238}
250 239
251#define IMPLEMENT_PEM_write_cb_fp(name, type, str, asn1) \ 240#define IMPLEMENT_PEM_write_cb_fp(name, type, str, asn1) \
@@ -253,10 +242,7 @@ int PEM_write_##name(FILE *fp, type *x, const EVP_CIPHER *enc, \
253 unsigned char *kstr, int klen, pem_password_cb *cb, \ 242 unsigned char *kstr, int klen, pem_password_cb *cb, \
254 void *u) \ 243 void *u) \
255 { \ 244 { \
256 return PEM_ASN1_write(CHECKED_I2D_OF(type, i2d_##asn1), \ 245 return PEM_ASN1_write((i2d_of_void *)i2d_##asn1,str,fp,x,enc,kstr,klen,cb,u); \
257 str, fp, \
258 CHECKED_PTR_OF(type, x), \
259 enc, kstr, klen, cb, u); \
260 } 246 }
261 247
262#define IMPLEMENT_PEM_write_cb_fp_const(name, type, str, asn1) \ 248#define IMPLEMENT_PEM_write_cb_fp_const(name, type, str, asn1) \
@@ -264,10 +250,7 @@ int PEM_write_##name(FILE *fp, type *x, const EVP_CIPHER *enc, \
264 unsigned char *kstr, int klen, pem_password_cb *cb, \ 250 unsigned char *kstr, int klen, pem_password_cb *cb, \
265 void *u) \ 251 void *u) \
266 { \ 252 { \
267 return PEM_ASN1_write(CHECKED_I2D_OF(const type, i2d_##asn1), \ 253 return PEM_ASN1_write((i2d_of_void *)i2d_##asn1,str,fp,x,enc,kstr,klen,cb,u); \
268 str, fp, \
269 CHECKED_PTR_OF(const type, x), \
270 enc, kstr, klen, cb, u); \
271 } 254 }
272 255
273#endif 256#endif
@@ -275,48 +258,33 @@ int PEM_write_##name(FILE *fp, type *x, const EVP_CIPHER *enc, \
275#define IMPLEMENT_PEM_read_bio(name, type, str, asn1) \ 258#define IMPLEMENT_PEM_read_bio(name, type, str, asn1) \
276type *PEM_read_bio_##name(BIO *bp, type **x, pem_password_cb *cb, void *u)\ 259type *PEM_read_bio_##name(BIO *bp, type **x, pem_password_cb *cb, void *u)\
277{ \ 260{ \
278 return (type*)PEM_ASN1_read_bio(CHECKED_D2I_OF(type, d2i_##asn1), \ 261return PEM_ASN1_read_bio((d2i_of_void *)d2i_##asn1, str,bp,(void **)x,cb,u); \
279 str, bp, \
280 CHECKED_PPTR_OF(type, x), \
281 cb, u); \
282} 262}
283 263
284#define IMPLEMENT_PEM_write_bio(name, type, str, asn1) \ 264#define IMPLEMENT_PEM_write_bio(name, type, str, asn1) \
285int PEM_write_bio_##name(BIO *bp, type *x) \ 265int PEM_write_bio_##name(BIO *bp, type *x) \
286{ \ 266{ \
287 return PEM_ASN1_write_bio(CHECKED_I2D_OF(type, i2d_##asn1), \ 267return PEM_ASN1_write_bio((i2d_of_void *)i2d_##asn1,str,bp,x,NULL,NULL,0,NULL,NULL); \
288 str, bp, \
289 CHECKED_PTR_OF(type, x), \
290 NULL, NULL, 0, NULL, NULL); \
291} 268}
292 269
293#define IMPLEMENT_PEM_write_bio_const(name, type, str, asn1) \ 270#define IMPLEMENT_PEM_write_bio_const(name, type, str, asn1) \
294int PEM_write_bio_##name(BIO *bp, const type *x) \ 271int PEM_write_bio_##name(BIO *bp, const type *x) \
295{ \ 272{ \
296 return PEM_ASN1_write_bio(CHECKED_I2D_OF(const type, i2d_##asn1), \ 273return PEM_ASN1_write_bio((i2d_of_void *)i2d_##asn1,str,bp,(void *)x,NULL,NULL,0,NULL,NULL); \
297 str, bp, \
298 CHECKED_PTR_OF(const type, x), \
299 NULL, NULL, 0, NULL, NULL); \
300} 274}
301 275
302#define IMPLEMENT_PEM_write_cb_bio(name, type, str, asn1) \ 276#define IMPLEMENT_PEM_write_cb_bio(name, type, str, asn1) \
303int PEM_write_bio_##name(BIO *bp, type *x, const EVP_CIPHER *enc, \ 277int PEM_write_bio_##name(BIO *bp, type *x, const EVP_CIPHER *enc, \
304 unsigned char *kstr, int klen, pem_password_cb *cb, void *u) \ 278 unsigned char *kstr, int klen, pem_password_cb *cb, void *u) \
305 { \ 279 { \
306 return PEM_ASN1_write_bio(CHECKED_I2D_OF(type, i2d_##asn1), \ 280 return PEM_ASN1_write_bio((i2d_of_void *)i2d_##asn1,str,bp,x,enc,kstr,klen,cb,u); \
307 str, bp, \
308 CHECKED_PTR_OF(type, x), \
309 enc, kstr, klen, cb, u); \
310 } 281 }
311 282
312#define IMPLEMENT_PEM_write_cb_bio_const(name, type, str, asn1) \ 283#define IMPLEMENT_PEM_write_cb_bio_const(name, type, str, asn1) \
313int PEM_write_bio_##name(BIO *bp, type *x, const EVP_CIPHER *enc, \ 284int PEM_write_bio_##name(BIO *bp, type *x, const EVP_CIPHER *enc, \
314 unsigned char *kstr, int klen, pem_password_cb *cb, void *u) \ 285 unsigned char *kstr, int klen, pem_password_cb *cb, void *u) \
315 { \ 286 { \
316 return PEM_ASN1_write_bio(CHECKED_I2D_OF(const type, i2d_##asn1), \ 287 return PEM_ASN1_write_bio((i2d_of_void *)i2d_##asn1,str,bp,(void *)x,enc,kstr,klen,cb,u); \
317 str, bp, \
318 CHECKED_PTR_OF(const type, x), \
319 enc, kstr, klen, cb, u); \
320 } 288 }
321 289
322#define IMPLEMENT_PEM_write(name, type, str, asn1) \ 290#define IMPLEMENT_PEM_write(name, type, str, asn1) \
@@ -353,11 +321,10 @@ int PEM_write_bio_##name(BIO *bp, type *x, const EVP_CIPHER *enc, \
353 321
354/* These are the same except they are for the declarations */ 322/* These are the same except they are for the declarations */
355 323
356#if defined(OPENSSL_SYS_WIN16) || defined(OPENSSL_NO_FP_API) 324#if defined(OPENSSL_NO_FP_API)
357 325
358#define DECLARE_PEM_read_fp(name, type) /**/ 326#define DECLARE_PEM_read_fp(name, type) /**/
359#define DECLARE_PEM_write_fp(name, type) /**/ 327#define DECLARE_PEM_write_fp(name, type) /**/
360#define DECLARE_PEM_write_fp_const(name, type) /**/
361#define DECLARE_PEM_write_cb_fp(name, type) /**/ 328#define DECLARE_PEM_write_cb_fp(name, type) /**/
362 329
363#else 330#else
@@ -428,138 +395,6 @@ int PEM_write_bio_##name(BIO *bp, type *x, const EVP_CIPHER *enc, \
428 DECLARE_PEM_read(name, type) \ 395 DECLARE_PEM_read(name, type) \
429 DECLARE_PEM_write_cb(name, type) 396 DECLARE_PEM_write_cb(name, type)
430 397
431#ifdef SSLEAY_MACROS
432
433#define PEM_write_SSL_SESSION(fp,x) \
434 PEM_ASN1_write((int (*)())i2d_SSL_SESSION, \
435 PEM_STRING_SSL_SESSION,fp, (char *)x, NULL,NULL,0,NULL,NULL)
436#define PEM_write_X509(fp,x) \
437 PEM_ASN1_write((int (*)())i2d_X509,PEM_STRING_X509,fp, \
438 (char *)x, NULL,NULL,0,NULL,NULL)
439#define PEM_write_X509_REQ(fp,x) PEM_ASN1_write( \
440 (int (*)())i2d_X509_REQ,PEM_STRING_X509_REQ,fp,(char *)x, \
441 NULL,NULL,0,NULL,NULL)
442#define PEM_write_X509_CRL(fp,x) \
443 PEM_ASN1_write((int (*)())i2d_X509_CRL,PEM_STRING_X509_CRL, \
444 fp,(char *)x, NULL,NULL,0,NULL,NULL)
445#define PEM_write_RSAPrivateKey(fp,x,enc,kstr,klen,cb,u) \
446 PEM_ASN1_write((int (*)())i2d_RSAPrivateKey,PEM_STRING_RSA,fp,\
447 (char *)x,enc,kstr,klen,cb,u)
448#define PEM_write_RSAPublicKey(fp,x) \
449 PEM_ASN1_write((int (*)())i2d_RSAPublicKey,\
450 PEM_STRING_RSA_PUBLIC,fp,(char *)x,NULL,NULL,0,NULL,NULL)
451#define PEM_write_DSAPrivateKey(fp,x,enc,kstr,klen,cb,u) \
452 PEM_ASN1_write((int (*)())i2d_DSAPrivateKey,PEM_STRING_DSA,fp,\
453 (char *)x,enc,kstr,klen,cb,u)
454#define PEM_write_PrivateKey(bp,x,enc,kstr,klen,cb,u) \
455 PEM_ASN1_write((int (*)())i2d_PrivateKey,\
456 (((x)->type == EVP_PKEY_DSA)?PEM_STRING_DSA:PEM_STRING_RSA),\
457 bp,(char *)x,enc,kstr,klen,cb,u)
458#define PEM_write_PKCS7(fp,x) \
459 PEM_ASN1_write((int (*)())i2d_PKCS7,PEM_STRING_PKCS7,fp, \
460 (char *)x, NULL,NULL,0,NULL,NULL)
461#define PEM_write_DHparams(fp,x) \
462 PEM_ASN1_write((int (*)())i2d_DHparams,PEM_STRING_DHPARAMS,fp,\
463 (char *)x,NULL,NULL,0,NULL,NULL)
464
465#define PEM_write_NETSCAPE_CERT_SEQUENCE(fp,x) \
466 PEM_ASN1_write((int (*)())i2d_NETSCAPE_CERT_SEQUENCE, \
467 PEM_STRING_X509,fp, \
468 (char *)x, NULL,NULL,0,NULL,NULL)
469
470#define PEM_read_SSL_SESSION(fp,x,cb,u) (SSL_SESSION *)PEM_ASN1_read( \
471 (char *(*)())d2i_SSL_SESSION,PEM_STRING_SSL_SESSION,fp,(char **)x,cb,u)
472#define PEM_read_X509(fp,x,cb,u) (X509 *)PEM_ASN1_read( \
473 (char *(*)())d2i_X509,PEM_STRING_X509,fp,(char **)x,cb,u)
474#define PEM_read_X509_REQ(fp,x,cb,u) (X509_REQ *)PEM_ASN1_read( \
475 (char *(*)())d2i_X509_REQ,PEM_STRING_X509_REQ,fp,(char **)x,cb,u)
476#define PEM_read_X509_CRL(fp,x,cb,u) (X509_CRL *)PEM_ASN1_read( \
477 (char *(*)())d2i_X509_CRL,PEM_STRING_X509_CRL,fp,(char **)x,cb,u)
478#define PEM_read_RSAPrivateKey(fp,x,cb,u) (RSA *)PEM_ASN1_read( \
479 (char *(*)())d2i_RSAPrivateKey,PEM_STRING_RSA,fp,(char **)x,cb,u)
480#define PEM_read_RSAPublicKey(fp,x,cb,u) (RSA *)PEM_ASN1_read( \
481 (char *(*)())d2i_RSAPublicKey,PEM_STRING_RSA_PUBLIC,fp,(char **)x,cb,u)
482#define PEM_read_DSAPrivateKey(fp,x,cb,u) (DSA *)PEM_ASN1_read( \
483 (char *(*)())d2i_DSAPrivateKey,PEM_STRING_DSA,fp,(char **)x,cb,u)
484#define PEM_read_PrivateKey(fp,x,cb,u) (EVP_PKEY *)PEM_ASN1_read( \
485 (char *(*)())d2i_PrivateKey,PEM_STRING_EVP_PKEY,fp,(char **)x,cb,u)
486#define PEM_read_PKCS7(fp,x,cb,u) (PKCS7 *)PEM_ASN1_read( \
487 (char *(*)())d2i_PKCS7,PEM_STRING_PKCS7,fp,(char **)x,cb,u)
488#define PEM_read_DHparams(fp,x,cb,u) (DH *)PEM_ASN1_read( \
489 (char *(*)())d2i_DHparams,PEM_STRING_DHPARAMS,fp,(char **)x,cb,u)
490
491#define PEM_read_NETSCAPE_CERT_SEQUENCE(fp,x,cb,u) \
492 (NETSCAPE_CERT_SEQUENCE *)PEM_ASN1_read( \
493 (char *(*)())d2i_NETSCAPE_CERT_SEQUENCE,PEM_STRING_X509,fp,\
494 (char **)x,cb,u)
495
496#define PEM_write_bio_X509(bp,x) \
497 PEM_ASN1_write_bio((int (*)())i2d_X509,PEM_STRING_X509,bp, \
498 (char *)x, NULL,NULL,0,NULL,NULL)
499#define PEM_write_bio_X509_REQ(bp,x) PEM_ASN1_write_bio( \
500 (int (*)())i2d_X509_REQ,PEM_STRING_X509_REQ,bp,(char *)x, \
501 NULL,NULL,0,NULL,NULL)
502#define PEM_write_bio_X509_CRL(bp,x) \
503 PEM_ASN1_write_bio((int (*)())i2d_X509_CRL,PEM_STRING_X509_CRL,\
504 bp,(char *)x, NULL,NULL,0,NULL,NULL)
505#define PEM_write_bio_RSAPrivateKey(bp,x,enc,kstr,klen,cb,u) \
506 PEM_ASN1_write_bio((int (*)())i2d_RSAPrivateKey,PEM_STRING_RSA,\
507 bp,(char *)x,enc,kstr,klen,cb,u)
508#define PEM_write_bio_RSAPublicKey(bp,x) \
509 PEM_ASN1_write_bio((int (*)())i2d_RSAPublicKey, \
510 PEM_STRING_RSA_PUBLIC,\
511 bp,(char *)x,NULL,NULL,0,NULL,NULL)
512#define PEM_write_bio_DSAPrivateKey(bp,x,enc,kstr,klen,cb,u) \
513 PEM_ASN1_write_bio((int (*)())i2d_DSAPrivateKey,PEM_STRING_DSA,\
514 bp,(char *)x,enc,kstr,klen,cb,u)
515#define PEM_write_bio_PrivateKey(bp,x,enc,kstr,klen,cb,u) \
516 PEM_ASN1_write_bio((int (*)())i2d_PrivateKey,\
517 (((x)->type == EVP_PKEY_DSA)?PEM_STRING_DSA:PEM_STRING_RSA),\
518 bp,(char *)x,enc,kstr,klen,cb,u)
519#define PEM_write_bio_PKCS7(bp,x) \
520 PEM_ASN1_write_bio((int (*)())i2d_PKCS7,PEM_STRING_PKCS7,bp, \
521 (char *)x, NULL,NULL,0,NULL,NULL)
522#define PEM_write_bio_DHparams(bp,x) \
523 PEM_ASN1_write_bio((int (*)())i2d_DHparams,PEM_STRING_DHPARAMS,\
524 bp,(char *)x,NULL,NULL,0,NULL,NULL)
525#define PEM_write_bio_DSAparams(bp,x) \
526 PEM_ASN1_write_bio((int (*)())i2d_DSAparams, \
527 PEM_STRING_DSAPARAMS,bp,(char *)x,NULL,NULL,0,NULL,NULL)
528
529#define PEM_write_bio_NETSCAPE_CERT_SEQUENCE(bp,x) \
530 PEM_ASN1_write_bio((int (*)())i2d_NETSCAPE_CERT_SEQUENCE, \
531 PEM_STRING_X509,bp, \
532 (char *)x, NULL,NULL,0,NULL,NULL)
533
534#define PEM_read_bio_X509(bp,x,cb,u) (X509 *)PEM_ASN1_read_bio( \
535 (char *(*)())d2i_X509,PEM_STRING_X509,bp,(char **)x,cb,u)
536#define PEM_read_bio_X509_REQ(bp,x,cb,u) (X509_REQ *)PEM_ASN1_read_bio( \
537 (char *(*)())d2i_X509_REQ,PEM_STRING_X509_REQ,bp,(char **)x,cb,u)
538#define PEM_read_bio_X509_CRL(bp,x,cb,u) (X509_CRL *)PEM_ASN1_read_bio( \
539 (char *(*)())d2i_X509_CRL,PEM_STRING_X509_CRL,bp,(char **)x,cb,u)
540#define PEM_read_bio_RSAPrivateKey(bp,x,cb,u) (RSA *)PEM_ASN1_read_bio( \
541 (char *(*)())d2i_RSAPrivateKey,PEM_STRING_RSA,bp,(char **)x,cb,u)
542#define PEM_read_bio_RSAPublicKey(bp,x,cb,u) (RSA *)PEM_ASN1_read_bio( \
543 (char *(*)())d2i_RSAPublicKey,PEM_STRING_RSA_PUBLIC,bp,(char **)x,cb,u)
544#define PEM_read_bio_DSAPrivateKey(bp,x,cb,u) (DSA *)PEM_ASN1_read_bio( \
545 (char *(*)())d2i_DSAPrivateKey,PEM_STRING_DSA,bp,(char **)x,cb,u)
546#define PEM_read_bio_PrivateKey(bp,x,cb,u) (EVP_PKEY *)PEM_ASN1_read_bio( \
547 (char *(*)())d2i_PrivateKey,PEM_STRING_EVP_PKEY,bp,(char **)x,cb,u)
548
549#define PEM_read_bio_PKCS7(bp,x,cb,u) (PKCS7 *)PEM_ASN1_read_bio( \
550 (char *(*)())d2i_PKCS7,PEM_STRING_PKCS7,bp,(char **)x,cb,u)
551#define PEM_read_bio_DHparams(bp,x,cb,u) (DH *)PEM_ASN1_read_bio( \
552 (char *(*)())d2i_DHparams,PEM_STRING_DHPARAMS,bp,(char **)x,cb,u)
553#define PEM_read_bio_DSAparams(bp,x,cb,u) (DSA *)PEM_ASN1_read_bio( \
554 (char *(*)())d2i_DSAparams,PEM_STRING_DSAPARAMS,bp,(char **)x,cb,u)
555
556#define PEM_read_bio_NETSCAPE_CERT_SEQUENCE(bp,x,cb,u) \
557 (NETSCAPE_CERT_SEQUENCE *)PEM_ASN1_read_bio( \
558 (char *(*)())d2i_NETSCAPE_CERT_SEQUENCE,PEM_STRING_X509,bp,\
559 (char **)x,cb,u)
560
561#endif
562
563#if 1 398#if 1
564/* "userdata": new with OpenSSL 0.9.4 */ 399/* "userdata": new with OpenSSL 0.9.4 */
565typedef int pem_password_cb(char *buf, int size, int rwflag, void *userdata); 400typedef int pem_password_cb(char *buf, int size, int rwflag, void *userdata);
@@ -581,40 +416,25 @@ int PEM_bytes_read_bio(unsigned char **pdata, long *plen, char **pnm, const char
581 pem_password_cb *cb, void *u); 416 pem_password_cb *cb, void *u);
582void * PEM_ASN1_read_bio(d2i_of_void *d2i, const char *name, BIO *bp, 417void * PEM_ASN1_read_bio(d2i_of_void *d2i, const char *name, BIO *bp,
583 void **x, pem_password_cb *cb, void *u); 418 void **x, pem_password_cb *cb, void *u);
584 419int PEM_ASN1_write_bio(i2d_of_void *i2d,const char *name,BIO *bp, void *x,
585#define PEM_ASN1_read_bio_of(type,d2i,name,bp,x,cb,u) \
586 ((type*)PEM_ASN1_read_bio(CHECKED_D2I_OF(type, d2i), \
587 name, bp, \
588 CHECKED_PPTR_OF(type, x), \
589 cb, u))
590
591int PEM_ASN1_write_bio(i2d_of_void *i2d,const char *name,BIO *bp,char *x,
592 const EVP_CIPHER *enc,unsigned char *kstr,int klen, 420 const EVP_CIPHER *enc,unsigned char *kstr,int klen,
593 pem_password_cb *cb, void *u); 421 pem_password_cb *cb, void *u);
594 422
595#define PEM_ASN1_write_bio_of(type,i2d,name,bp,x,enc,kstr,klen,cb,u) \
596 (PEM_ASN1_write_bio(CHECKED_I2D_OF(type, i2d), \
597 name, bp, \
598 CHECKED_PTR_OF(type, x), \
599 enc, kstr, klen, cb, u))
600
601STACK_OF(X509_INFO) * PEM_X509_INFO_read_bio(BIO *bp, STACK_OF(X509_INFO) *sk, pem_password_cb *cb, void *u); 423STACK_OF(X509_INFO) * PEM_X509_INFO_read_bio(BIO *bp, STACK_OF(X509_INFO) *sk, pem_password_cb *cb, void *u);
602int PEM_X509_INFO_write_bio(BIO *bp,X509_INFO *xi, EVP_CIPHER *enc, 424int PEM_X509_INFO_write_bio(BIO *bp,X509_INFO *xi, EVP_CIPHER *enc,
603 unsigned char *kstr, int klen, pem_password_cb *cd, void *u); 425 unsigned char *kstr, int klen, pem_password_cb *cd, void *u);
604#endif 426#endif
605 427
606#ifndef OPENSSL_SYS_WIN16
607int PEM_read(FILE *fp, char **name, char **header, 428int PEM_read(FILE *fp, char **name, char **header,
608 unsigned char **data,long *len); 429 unsigned char **data,long *len);
609int PEM_write(FILE *fp,char *name,char *hdr,unsigned char *data,long len); 430int PEM_write(FILE *fp,char *name,char *hdr,unsigned char *data,long len);
610void * PEM_ASN1_read(d2i_of_void *d2i, const char *name, FILE *fp, void **x, 431void * PEM_ASN1_read(d2i_of_void *d2i, const char *name, FILE *fp, void **x,
611 pem_password_cb *cb, void *u); 432 pem_password_cb *cb, void *u);
612int PEM_ASN1_write(i2d_of_void *i2d,const char *name,FILE *fp, 433int PEM_ASN1_write(i2d_of_void *i2d,const char *name,FILE *fp,
613 char *x,const EVP_CIPHER *enc,unsigned char *kstr, 434 void *x,const EVP_CIPHER *enc,unsigned char *kstr,
614 int klen,pem_password_cb *callback, void *u); 435 int klen,pem_password_cb *callback, void *u);
615STACK_OF(X509_INFO) * PEM_X509_INFO_read(FILE *fp, STACK_OF(X509_INFO) *sk, 436STACK_OF(X509_INFO) * PEM_X509_INFO_read(FILE *fp, STACK_OF(X509_INFO) *sk,
616 pem_password_cb *cb, void *u); 437 pem_password_cb *cb, void *u);
617#endif
618 438
619int PEM_SealInit(PEM_ENCODE_SEAL_CTX *ctx, EVP_CIPHER *type, 439int PEM_SealInit(PEM_ENCODE_SEAL_CTX *ctx, EVP_CIPHER *type,
620 EVP_MD *md_type, unsigned char **ek, int *ekl, 440 EVP_MD *md_type, unsigned char **ek, int *ekl,
@@ -633,7 +453,6 @@ int PEM_def_callback(char *buf, int num, int w, void *key);
633void PEM_proc_type(char *buf, int type); 453void PEM_proc_type(char *buf, int type);
634void PEM_dek_info(char *buf, const char *type, int len, char *str); 454void PEM_dek_info(char *buf, const char *type, int len, char *str);
635 455
636#ifndef SSLEAY_MACROS
637 456
638#include <openssl/symhacks.h> 457#include <openssl/symhacks.h>
639 458
@@ -719,7 +538,21 @@ EVP_PKEY *d2i_PKCS8PrivateKey_fp(FILE *fp, EVP_PKEY **x, pem_password_cb *cb, vo
719int PEM_write_PKCS8PrivateKey(FILE *fp,EVP_PKEY *x,const EVP_CIPHER *enc, 538int PEM_write_PKCS8PrivateKey(FILE *fp,EVP_PKEY *x,const EVP_CIPHER *enc,
720 char *kstr,int klen, pem_password_cb *cd, void *u); 539 char *kstr,int klen, pem_password_cb *cd, void *u);
721 540
722#endif /* SSLEAY_MACROS */ 541EVP_PKEY *PEM_read_bio_Parameters(BIO *bp, EVP_PKEY **x);
542int PEM_write_bio_Parameters(BIO *bp, EVP_PKEY *x);
543
544
545EVP_PKEY *b2i_PrivateKey(const unsigned char **in, long length);
546EVP_PKEY *b2i_PublicKey(const unsigned char **in, long length);
547EVP_PKEY *b2i_PrivateKey_bio(BIO *in);
548EVP_PKEY *b2i_PublicKey_bio(BIO *in);
549int i2b_PrivateKey_bio(BIO *out, EVP_PKEY *pk);
550int i2b_PublicKey_bio(BIO *out, EVP_PKEY *pk);
551#ifndef OPENSSL_NO_RC4
552EVP_PKEY *b2i_PVK_bio(BIO *in, pem_password_cb *cb, void *u);
553int i2b_PVK_bio(BIO *out, EVP_PKEY *pk, int enclevel,
554 pem_password_cb *cb, void *u);
555#endif
723 556
724 557
725/* BEGIN ERROR CODES */ 558/* BEGIN ERROR CODES */
@@ -731,10 +564,22 @@ void ERR_load_PEM_strings(void);
731/* Error codes for the PEM functions. */ 564/* Error codes for the PEM functions. */
732 565
733/* Function codes. */ 566/* Function codes. */
567#define PEM_F_B2I_DSS 127
568#define PEM_F_B2I_PVK_BIO 128
569#define PEM_F_B2I_RSA 129
570#define PEM_F_CHECK_BITLEN_DSA 130
571#define PEM_F_CHECK_BITLEN_RSA 131
734#define PEM_F_D2I_PKCS8PRIVATEKEY_BIO 120 572#define PEM_F_D2I_PKCS8PRIVATEKEY_BIO 120
735#define PEM_F_D2I_PKCS8PRIVATEKEY_FP 121 573#define PEM_F_D2I_PKCS8PRIVATEKEY_FP 121
574#define PEM_F_DO_B2I 132
575#define PEM_F_DO_B2I_BIO 133
576#define PEM_F_DO_BLOB_HEADER 134
736#define PEM_F_DO_PK8PKEY 126 577#define PEM_F_DO_PK8PKEY 126
737#define PEM_F_DO_PK8PKEY_FP 125 578#define PEM_F_DO_PK8PKEY_FP 125
579#define PEM_F_DO_PVK_BODY 135
580#define PEM_F_DO_PVK_HEADER 136
581#define PEM_F_I2B_PVK 137
582#define PEM_F_I2B_PVK_BIO 138
738#define PEM_F_LOAD_IV 101 583#define PEM_F_LOAD_IV 101
739#define PEM_F_PEM_ASN1_READ 102 584#define PEM_F_PEM_ASN1_READ 102
740#define PEM_F_PEM_ASN1_READ_BIO 103 585#define PEM_F_PEM_ASN1_READ_BIO 103
@@ -747,6 +592,7 @@ void ERR_load_PEM_strings(void);
747#define PEM_F_PEM_PK8PKEY 119 592#define PEM_F_PEM_PK8PKEY 119
748#define PEM_F_PEM_READ 108 593#define PEM_F_PEM_READ 108
749#define PEM_F_PEM_READ_BIO 109 594#define PEM_F_PEM_READ_BIO 109
595#define PEM_F_PEM_READ_BIO_PARAMETERS 140
750#define PEM_F_PEM_READ_BIO_PRIVATEKEY 123 596#define PEM_F_PEM_READ_BIO_PRIVATEKEY 123
751#define PEM_F_PEM_READ_PRIVATEKEY 124 597#define PEM_F_PEM_READ_PRIVATEKEY 124
752#define PEM_F_PEM_SEALFINAL 110 598#define PEM_F_PEM_SEALFINAL 110
@@ -754,6 +600,7 @@ void ERR_load_PEM_strings(void);
754#define PEM_F_PEM_SIGNFINAL 112 600#define PEM_F_PEM_SIGNFINAL 112
755#define PEM_F_PEM_WRITE 113 601#define PEM_F_PEM_WRITE 113
756#define PEM_F_PEM_WRITE_BIO 114 602#define PEM_F_PEM_WRITE_BIO 114
603#define PEM_F_PEM_WRITE_PRIVATEKEY 139
757#define PEM_F_PEM_X509_INFO_READ 115 604#define PEM_F_PEM_X509_INFO_READ 115
758#define PEM_F_PEM_X509_INFO_READ_BIO 116 605#define PEM_F_PEM_X509_INFO_READ_BIO 116
759#define PEM_F_PEM_X509_INFO_WRITE_BIO 117 606#define PEM_F_PEM_X509_INFO_WRITE_BIO 117
@@ -763,18 +610,30 @@ void ERR_load_PEM_strings(void);
763#define PEM_R_BAD_DECRYPT 101 610#define PEM_R_BAD_DECRYPT 101
764#define PEM_R_BAD_END_LINE 102 611#define PEM_R_BAD_END_LINE 102
765#define PEM_R_BAD_IV_CHARS 103 612#define PEM_R_BAD_IV_CHARS 103
613#define PEM_R_BAD_MAGIC_NUMBER 116
766#define PEM_R_BAD_PASSWORD_READ 104 614#define PEM_R_BAD_PASSWORD_READ 104
615#define PEM_R_BAD_VERSION_NUMBER 117
616#define PEM_R_BIO_WRITE_FAILURE 118
617#define PEM_R_CIPHER_IS_NULL 127
767#define PEM_R_ERROR_CONVERTING_PRIVATE_KEY 115 618#define PEM_R_ERROR_CONVERTING_PRIVATE_KEY 115
619#define PEM_R_EXPECTING_PRIVATE_KEY_BLOB 119
620#define PEM_R_EXPECTING_PUBLIC_KEY_BLOB 120
621#define PEM_R_INCONSISTENT_HEADER 121
622#define PEM_R_KEYBLOB_HEADER_PARSE_ERROR 122
623#define PEM_R_KEYBLOB_TOO_SHORT 123
768#define PEM_R_NOT_DEK_INFO 105 624#define PEM_R_NOT_DEK_INFO 105
769#define PEM_R_NOT_ENCRYPTED 106 625#define PEM_R_NOT_ENCRYPTED 106
770#define PEM_R_NOT_PROC_TYPE 107 626#define PEM_R_NOT_PROC_TYPE 107
771#define PEM_R_NO_START_LINE 108 627#define PEM_R_NO_START_LINE 108
772#define PEM_R_PROBLEMS_GETTING_PASSWORD 109 628#define PEM_R_PROBLEMS_GETTING_PASSWORD 109
773#define PEM_R_PUBLIC_KEY_NO_RSA 110 629#define PEM_R_PUBLIC_KEY_NO_RSA 110
630#define PEM_R_PVK_DATA_TOO_SHORT 124
631#define PEM_R_PVK_TOO_SHORT 125
774#define PEM_R_READ_KEY 111 632#define PEM_R_READ_KEY 111
775#define PEM_R_SHORT_HEADER 112 633#define PEM_R_SHORT_HEADER 112
776#define PEM_R_UNSUPPORTED_CIPHER 113 634#define PEM_R_UNSUPPORTED_CIPHER 113
777#define PEM_R_UNSUPPORTED_ENCRYPTION 114 635#define PEM_R_UNSUPPORTED_ENCRYPTION 114
636#define PEM_R_UNSUPPORTED_KEY_COMPONENTS 126
778 637
779#ifdef __cplusplus 638#ifdef __cplusplus
780} 639}
diff --git a/src/lib/libcrypto/pem/pem_all.c b/src/lib/libcrypto/pem/pem_all.c
index 69dd19bf2e..3e7a6093ad 100644
--- a/src/lib/libcrypto/pem/pem_all.c
+++ b/src/lib/libcrypto/pem/pem_all.c
@@ -110,7 +110,6 @@
110 */ 110 */
111 111
112#include <stdio.h> 112#include <stdio.h>
113#undef SSLEAY_MACROS
114#include "cryptlib.h" 113#include "cryptlib.h"
115#include <openssl/bio.h> 114#include <openssl/bio.h>
116#include <openssl/evp.h> 115#include <openssl/evp.h>
@@ -194,49 +193,7 @@ RSA *PEM_read_RSAPrivateKey(FILE *fp, RSA **rsa, pem_password_cb *cb,
194 193
195#endif 194#endif
196 195
197#ifdef OPENSSL_FIPS
198
199int PEM_write_bio_RSAPrivateKey(BIO *bp, RSA *x, const EVP_CIPHER *enc,
200 unsigned char *kstr, int klen,
201 pem_password_cb *cb, void *u)
202{
203 EVP_PKEY *k;
204 int ret;
205 k = EVP_PKEY_new();
206 if (!k)
207 return 0;
208 EVP_PKEY_set1_RSA(k, x);
209
210 ret = PEM_write_bio_PrivateKey(bp, k, enc, kstr, klen, cb, u);
211 EVP_PKEY_free(k);
212 return ret;
213}
214
215#ifndef OPENSSL_NO_FP_API
216int PEM_write_RSAPrivateKey(FILE *fp, RSA *x, const EVP_CIPHER *enc,
217 unsigned char *kstr, int klen,
218 pem_password_cb *cb, void *u)
219{
220 EVP_PKEY *k;
221 int ret;
222 k = EVP_PKEY_new();
223 if (!k)
224 return 0;
225
226 EVP_PKEY_set1_RSA(k, x);
227
228 ret = PEM_write_PrivateKey(fp, k, enc, kstr, klen, cb, u);
229 EVP_PKEY_free(k);
230 return ret;
231}
232#endif
233
234#else
235
236IMPLEMENT_PEM_write_cb_const(RSAPrivateKey, RSA, PEM_STRING_RSA, RSAPrivateKey) 196IMPLEMENT_PEM_write_cb_const(RSAPrivateKey, RSA, PEM_STRING_RSA, RSAPrivateKey)
237
238#endif
239
240IMPLEMENT_PEM_rw_const(RSAPublicKey, RSA, PEM_STRING_RSA_PUBLIC, RSAPublicKey) 197IMPLEMENT_PEM_rw_const(RSAPublicKey, RSA, PEM_STRING_RSA_PUBLIC, RSAPublicKey)
241IMPLEMENT_PEM_rw(RSA_PUBKEY, RSA, PEM_STRING_PUBLIC, RSA_PUBKEY) 198IMPLEMENT_PEM_rw(RSA_PUBKEY, RSA, PEM_STRING_PUBLIC, RSA_PUBKEY)
242 199
@@ -263,50 +220,10 @@ DSA *PEM_read_bio_DSAPrivateKey(BIO *bp, DSA **dsa, pem_password_cb *cb,
263{ 220{
264 EVP_PKEY *pktmp; 221 EVP_PKEY *pktmp;
265 pktmp = PEM_read_bio_PrivateKey(bp, NULL, cb, u); 222 pktmp = PEM_read_bio_PrivateKey(bp, NULL, cb, u);
266 return pkey_get_dsa(pktmp, dsa); 223 return pkey_get_dsa(pktmp, dsa); /* will free pktmp */
267} 224}
268 225
269#ifdef OPENSSL_FIPS
270
271int PEM_write_bio_DSAPrivateKey(BIO *bp, DSA *x, const EVP_CIPHER *enc,
272 unsigned char *kstr, int klen,
273 pem_password_cb *cb, void *u)
274{
275 EVP_PKEY *k;
276 int ret;
277 k = EVP_PKEY_new();
278 if (!k)
279 return 0;
280 EVP_PKEY_set1_DSA(k, x);
281
282 ret = PEM_write_bio_PrivateKey(bp, k, enc, kstr, klen, cb, u);
283 EVP_PKEY_free(k);
284 return ret;
285}
286
287#ifndef OPENSSL_NO_FP_API
288int PEM_write_DSAPrivateKey(FILE *fp, DSA *x, const EVP_CIPHER *enc,
289 unsigned char *kstr, int klen,
290 pem_password_cb *cb, void *u)
291{
292 EVP_PKEY *k;
293 int ret;
294 k = EVP_PKEY_new();
295 if (!k)
296 return 0;
297 EVP_PKEY_set1_DSA(k, x);
298 ret = PEM_write_PrivateKey(fp, k, enc, kstr, klen, cb, u);
299 EVP_PKEY_free(k);
300 return ret;
301}
302#endif
303
304#else
305
306IMPLEMENT_PEM_write_cb_const(DSAPrivateKey, DSA, PEM_STRING_DSA, DSAPrivateKey) 226IMPLEMENT_PEM_write_cb_const(DSAPrivateKey, DSA, PEM_STRING_DSA, DSAPrivateKey)
307
308#endif
309
310IMPLEMENT_PEM_rw(DSA_PUBKEY, DSA, PEM_STRING_PUBLIC, DSA_PUBKEY) 227IMPLEMENT_PEM_rw(DSA_PUBKEY, DSA, PEM_STRING_PUBLIC, DSA_PUBKEY)
311 228
312#ifndef OPENSSL_NO_FP_API 229#ifndef OPENSSL_NO_FP_API
@@ -316,7 +233,7 @@ DSA *PEM_read_DSAPrivateKey(FILE *fp, DSA **dsa, pem_password_cb *cb,
316{ 233{
317 EVP_PKEY *pktmp; 234 EVP_PKEY *pktmp;
318 pktmp = PEM_read_PrivateKey(fp, NULL, cb, u); 235 pktmp = PEM_read_PrivateKey(fp, NULL, cb, u);
319 return pkey_get_dsa(pktmp, dsa); 236 return pkey_get_dsa(pktmp, dsa); /* will free pktmp */
320} 237}
321 238
322#endif 239#endif
@@ -347,54 +264,13 @@ EC_KEY *PEM_read_bio_ECPrivateKey(BIO *bp, EC_KEY **key, pem_password_cb *cb,
347{ 264{
348 EVP_PKEY *pktmp; 265 EVP_PKEY *pktmp;
349 pktmp = PEM_read_bio_PrivateKey(bp, NULL, cb, u); 266 pktmp = PEM_read_bio_PrivateKey(bp, NULL, cb, u);
350 return pkey_get_eckey(pktmp, key); 267 return pkey_get_eckey(pktmp, key); /* will free pktmp */
351} 268}
352 269
353IMPLEMENT_PEM_rw_const(ECPKParameters, EC_GROUP, PEM_STRING_ECPARAMETERS, ECPKParameters) 270IMPLEMENT_PEM_rw_const(ECPKParameters, EC_GROUP, PEM_STRING_ECPARAMETERS, ECPKParameters)
354 271
355
356
357#ifdef OPENSSL_FIPS
358
359int PEM_write_bio_ECPrivateKey(BIO *bp, EC_KEY *x, const EVP_CIPHER *enc,
360 unsigned char *kstr, int klen,
361 pem_password_cb *cb, void *u)
362{
363 EVP_PKEY *k;
364 int ret;
365 k = EVP_PKEY_new();
366 if (!k)
367 return 0;
368 EVP_PKEY_set1_EC_KEY(k, x);
369
370 ret = PEM_write_bio_PrivateKey(bp, k, enc, kstr, klen, cb, u);
371 EVP_PKEY_free(k);
372 return ret;
373}
374
375#ifndef OPENSSL_NO_FP_API
376int PEM_write_ECPrivateKey(FILE *fp, EC_KEY *x, const EVP_CIPHER *enc,
377 unsigned char *kstr, int klen,
378 pem_password_cb *cb, void *u)
379{
380 EVP_PKEY *k;
381 int ret;
382 k = EVP_PKEY_new();
383 if (!k)
384 return 0;
385 EVP_PKEY_set1_EC_KEY(k, x);
386 ret = PEM_write_PrivateKey(fp, k, enc, kstr, klen, cb, u);
387 EVP_PKEY_free(k);
388 return ret;
389}
390#endif
391
392#else
393
394IMPLEMENT_PEM_write_cb(ECPrivateKey, EC_KEY, PEM_STRING_ECPRIVATEKEY, ECPrivateKey) 272IMPLEMENT_PEM_write_cb(ECPrivateKey, EC_KEY, PEM_STRING_ECPRIVATEKEY, ECPrivateKey)
395 273
396#endif
397
398IMPLEMENT_PEM_rw(EC_PUBKEY, EC_KEY, PEM_STRING_PUBLIC, EC_PUBKEY) 274IMPLEMENT_PEM_rw(EC_PUBKEY, EC_KEY, PEM_STRING_PUBLIC, EC_PUBKEY)
399 275
400#ifndef OPENSSL_NO_FP_API 276#ifndef OPENSSL_NO_FP_API
@@ -404,7 +280,7 @@ EC_KEY *PEM_read_ECPrivateKey(FILE *fp, EC_KEY **eckey, pem_password_cb *cb,
404{ 280{
405 EVP_PKEY *pktmp; 281 EVP_PKEY *pktmp;
406 pktmp = PEM_read_PrivateKey(fp, NULL, cb, u); 282 pktmp = PEM_read_PrivateKey(fp, NULL, cb, u);
407 return pkey_get_eckey(pktmp, eckey); 283 return pkey_get_eckey(pktmp, eckey); /* will free pktmp */
408} 284}
409 285
410#endif 286#endif
@@ -417,66 +293,4 @@ IMPLEMENT_PEM_rw_const(DHparams, DH, PEM_STRING_DHPARAMS, DHparams)
417 293
418#endif 294#endif
419 295
420
421/* The PrivateKey case is not that straightforward.
422 * IMPLEMENT_PEM_rw_cb(PrivateKey, EVP_PKEY, PEM_STRING_EVP_PKEY, PrivateKey)
423 * does not work, RSA and DSA keys have specific strings.
424 * (When reading, parameter PEM_STRING_EVP_PKEY is a wildcard for anything
425 * appropriate.)
426 */
427
428#ifdef OPENSSL_FIPS
429
430static const char *pkey_str(EVP_PKEY *x)
431 {
432 switch (x->type)
433 {
434 case EVP_PKEY_RSA:
435 return PEM_STRING_RSA;
436
437 case EVP_PKEY_DSA:
438 return PEM_STRING_DSA;
439
440 case EVP_PKEY_EC:
441 return PEM_STRING_ECPRIVATEKEY;
442
443 default:
444 return NULL;
445 }
446 }
447
448
449int PEM_write_bio_PrivateKey(BIO *bp, EVP_PKEY *x, const EVP_CIPHER *enc,
450 unsigned char *kstr, int klen,
451 pem_password_cb *cb, void *u)
452 {
453 if (FIPS_mode())
454 return PEM_write_bio_PKCS8PrivateKey(bp, x, enc,
455 (char *)kstr, klen, cb, u);
456 else
457 return PEM_ASN1_write_bio((i2d_of_void *)i2d_PrivateKey,
458 pkey_str(x), bp,(char *)x,enc,kstr,klen,cb,u);
459 }
460
461#ifndef OPENSSL_NO_FP_API
462int PEM_write_PrivateKey(FILE *fp, EVP_PKEY *x, const EVP_CIPHER *enc,
463 unsigned char *kstr, int klen,
464 pem_password_cb *cb, void *u)
465 {
466 if (FIPS_mode())
467 return PEM_write_PKCS8PrivateKey(fp, x, enc,
468 (char *)kstr, klen, cb, u);
469 else
470 return PEM_ASN1_write((i2d_of_void *)i2d_PrivateKey,
471 pkey_str(x), fp,(char *)x,enc,kstr,klen,cb,u);
472 }
473#endif
474
475#else
476IMPLEMENT_PEM_write_cb(PrivateKey, EVP_PKEY, ((x->type == EVP_PKEY_DSA)?PEM_STRING_DSA:\
477 (x->type == EVP_PKEY_RSA)?PEM_STRING_RSA:PEM_STRING_ECPRIVATEKEY), PrivateKey)
478
479#endif
480
481IMPLEMENT_PEM_rw(PUBKEY, EVP_PKEY, PEM_STRING_PUBLIC, PUBKEY) 296IMPLEMENT_PEM_rw(PUBKEY, EVP_PKEY, PEM_STRING_PUBLIC, PUBKEY)
482
diff --git a/src/lib/libcrypto/pem/pem_err.c b/src/lib/libcrypto/pem/pem_err.c
index 3133563d77..d644aeedd4 100644
--- a/src/lib/libcrypto/pem/pem_err.c
+++ b/src/lib/libcrypto/pem/pem_err.c
@@ -1,6 +1,6 @@
1/* crypto/pem/pem_err.c */ 1/* crypto/pem/pem_err.c */
2/* ==================================================================== 2/* ====================================================================
3 * Copyright (c) 1999-2005 The OpenSSL Project. All rights reserved. 3 * Copyright (c) 1999-2007 The OpenSSL Project. All rights reserved.
4 * 4 *
5 * Redistribution and use in source and binary forms, with or without 5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions 6 * modification, are permitted provided that the following conditions
@@ -70,10 +70,22 @@
70 70
71static ERR_STRING_DATA PEM_str_functs[]= 71static ERR_STRING_DATA PEM_str_functs[]=
72 { 72 {
73{ERR_FUNC(PEM_F_B2I_DSS), "B2I_DSS"},
74{ERR_FUNC(PEM_F_B2I_PVK_BIO), "b2i_PVK_bio"},
75{ERR_FUNC(PEM_F_B2I_RSA), "B2I_RSA"},
76{ERR_FUNC(PEM_F_CHECK_BITLEN_DSA), "CHECK_BITLEN_DSA"},
77{ERR_FUNC(PEM_F_CHECK_BITLEN_RSA), "CHECK_BITLEN_RSA"},
73{ERR_FUNC(PEM_F_D2I_PKCS8PRIVATEKEY_BIO), "d2i_PKCS8PrivateKey_bio"}, 78{ERR_FUNC(PEM_F_D2I_PKCS8PRIVATEKEY_BIO), "d2i_PKCS8PrivateKey_bio"},
74{ERR_FUNC(PEM_F_D2I_PKCS8PRIVATEKEY_FP), "d2i_PKCS8PrivateKey_fp"}, 79{ERR_FUNC(PEM_F_D2I_PKCS8PRIVATEKEY_FP), "d2i_PKCS8PrivateKey_fp"},
80{ERR_FUNC(PEM_F_DO_B2I), "DO_B2I"},
81{ERR_FUNC(PEM_F_DO_B2I_BIO), "DO_B2I_BIO"},
82{ERR_FUNC(PEM_F_DO_BLOB_HEADER), "DO_BLOB_HEADER"},
75{ERR_FUNC(PEM_F_DO_PK8PKEY), "DO_PK8PKEY"}, 83{ERR_FUNC(PEM_F_DO_PK8PKEY), "DO_PK8PKEY"},
76{ERR_FUNC(PEM_F_DO_PK8PKEY_FP), "DO_PK8PKEY_FP"}, 84{ERR_FUNC(PEM_F_DO_PK8PKEY_FP), "DO_PK8PKEY_FP"},
85{ERR_FUNC(PEM_F_DO_PVK_BODY), "DO_PVK_BODY"},
86{ERR_FUNC(PEM_F_DO_PVK_HEADER), "DO_PVK_HEADER"},
87{ERR_FUNC(PEM_F_I2B_PVK), "I2B_PVK"},
88{ERR_FUNC(PEM_F_I2B_PVK_BIO), "i2b_PVK_bio"},
77{ERR_FUNC(PEM_F_LOAD_IV), "LOAD_IV"}, 89{ERR_FUNC(PEM_F_LOAD_IV), "LOAD_IV"},
78{ERR_FUNC(PEM_F_PEM_ASN1_READ), "PEM_ASN1_read"}, 90{ERR_FUNC(PEM_F_PEM_ASN1_READ), "PEM_ASN1_read"},
79{ERR_FUNC(PEM_F_PEM_ASN1_READ_BIO), "PEM_ASN1_read_bio"}, 91{ERR_FUNC(PEM_F_PEM_ASN1_READ_BIO), "PEM_ASN1_read_bio"},
@@ -86,6 +98,7 @@ static ERR_STRING_DATA PEM_str_functs[]=
86{ERR_FUNC(PEM_F_PEM_PK8PKEY), "PEM_PK8PKEY"}, 98{ERR_FUNC(PEM_F_PEM_PK8PKEY), "PEM_PK8PKEY"},
87{ERR_FUNC(PEM_F_PEM_READ), "PEM_read"}, 99{ERR_FUNC(PEM_F_PEM_READ), "PEM_read"},
88{ERR_FUNC(PEM_F_PEM_READ_BIO), "PEM_read_bio"}, 100{ERR_FUNC(PEM_F_PEM_READ_BIO), "PEM_read_bio"},
101{ERR_FUNC(PEM_F_PEM_READ_BIO_PARAMETERS), "PEM_read_bio_Parameters"},
89{ERR_FUNC(PEM_F_PEM_READ_BIO_PRIVATEKEY), "PEM_READ_BIO_PRIVATEKEY"}, 102{ERR_FUNC(PEM_F_PEM_READ_BIO_PRIVATEKEY), "PEM_READ_BIO_PRIVATEKEY"},
90{ERR_FUNC(PEM_F_PEM_READ_PRIVATEKEY), "PEM_READ_PRIVATEKEY"}, 103{ERR_FUNC(PEM_F_PEM_READ_PRIVATEKEY), "PEM_READ_PRIVATEKEY"},
91{ERR_FUNC(PEM_F_PEM_SEALFINAL), "PEM_SealFinal"}, 104{ERR_FUNC(PEM_F_PEM_SEALFINAL), "PEM_SealFinal"},
@@ -93,6 +106,7 @@ static ERR_STRING_DATA PEM_str_functs[]=
93{ERR_FUNC(PEM_F_PEM_SIGNFINAL), "PEM_SignFinal"}, 106{ERR_FUNC(PEM_F_PEM_SIGNFINAL), "PEM_SignFinal"},
94{ERR_FUNC(PEM_F_PEM_WRITE), "PEM_write"}, 107{ERR_FUNC(PEM_F_PEM_WRITE), "PEM_write"},
95{ERR_FUNC(PEM_F_PEM_WRITE_BIO), "PEM_write_bio"}, 108{ERR_FUNC(PEM_F_PEM_WRITE_BIO), "PEM_write_bio"},
109{ERR_FUNC(PEM_F_PEM_WRITE_PRIVATEKEY), "PEM_WRITE_PRIVATEKEY"},
96{ERR_FUNC(PEM_F_PEM_X509_INFO_READ), "PEM_X509_INFO_read"}, 110{ERR_FUNC(PEM_F_PEM_X509_INFO_READ), "PEM_X509_INFO_read"},
97{ERR_FUNC(PEM_F_PEM_X509_INFO_READ_BIO), "PEM_X509_INFO_read_bio"}, 111{ERR_FUNC(PEM_F_PEM_X509_INFO_READ_BIO), "PEM_X509_INFO_read_bio"},
98{ERR_FUNC(PEM_F_PEM_X509_INFO_WRITE_BIO), "PEM_X509_INFO_write_bio"}, 112{ERR_FUNC(PEM_F_PEM_X509_INFO_WRITE_BIO), "PEM_X509_INFO_write_bio"},
@@ -105,18 +119,30 @@ static ERR_STRING_DATA PEM_str_reasons[]=
105{ERR_REASON(PEM_R_BAD_DECRYPT) ,"bad decrypt"}, 119{ERR_REASON(PEM_R_BAD_DECRYPT) ,"bad decrypt"},
106{ERR_REASON(PEM_R_BAD_END_LINE) ,"bad end line"}, 120{ERR_REASON(PEM_R_BAD_END_LINE) ,"bad end line"},
107{ERR_REASON(PEM_R_BAD_IV_CHARS) ,"bad iv chars"}, 121{ERR_REASON(PEM_R_BAD_IV_CHARS) ,"bad iv chars"},
122{ERR_REASON(PEM_R_BAD_MAGIC_NUMBER) ,"bad magic number"},
108{ERR_REASON(PEM_R_BAD_PASSWORD_READ) ,"bad password read"}, 123{ERR_REASON(PEM_R_BAD_PASSWORD_READ) ,"bad password read"},
124{ERR_REASON(PEM_R_BAD_VERSION_NUMBER) ,"bad version number"},
125{ERR_REASON(PEM_R_BIO_WRITE_FAILURE) ,"bio write failure"},
126{ERR_REASON(PEM_R_CIPHER_IS_NULL) ,"cipher is null"},
109{ERR_REASON(PEM_R_ERROR_CONVERTING_PRIVATE_KEY),"error converting private key"}, 127{ERR_REASON(PEM_R_ERROR_CONVERTING_PRIVATE_KEY),"error converting private key"},
128{ERR_REASON(PEM_R_EXPECTING_PRIVATE_KEY_BLOB),"expecting private key blob"},
129{ERR_REASON(PEM_R_EXPECTING_PUBLIC_KEY_BLOB),"expecting public key blob"},
130{ERR_REASON(PEM_R_INCONSISTENT_HEADER) ,"inconsistent header"},
131{ERR_REASON(PEM_R_KEYBLOB_HEADER_PARSE_ERROR),"keyblob header parse error"},
132{ERR_REASON(PEM_R_KEYBLOB_TOO_SHORT) ,"keyblob too short"},
110{ERR_REASON(PEM_R_NOT_DEK_INFO) ,"not dek info"}, 133{ERR_REASON(PEM_R_NOT_DEK_INFO) ,"not dek info"},
111{ERR_REASON(PEM_R_NOT_ENCRYPTED) ,"not encrypted"}, 134{ERR_REASON(PEM_R_NOT_ENCRYPTED) ,"not encrypted"},
112{ERR_REASON(PEM_R_NOT_PROC_TYPE) ,"not proc type"}, 135{ERR_REASON(PEM_R_NOT_PROC_TYPE) ,"not proc type"},
113{ERR_REASON(PEM_R_NO_START_LINE) ,"no start line"}, 136{ERR_REASON(PEM_R_NO_START_LINE) ,"no start line"},
114{ERR_REASON(PEM_R_PROBLEMS_GETTING_PASSWORD),"problems getting password"}, 137{ERR_REASON(PEM_R_PROBLEMS_GETTING_PASSWORD),"problems getting password"},
115{ERR_REASON(PEM_R_PUBLIC_KEY_NO_RSA) ,"public key no rsa"}, 138{ERR_REASON(PEM_R_PUBLIC_KEY_NO_RSA) ,"public key no rsa"},
139{ERR_REASON(PEM_R_PVK_DATA_TOO_SHORT) ,"pvk data too short"},
140{ERR_REASON(PEM_R_PVK_TOO_SHORT) ,"pvk too short"},
116{ERR_REASON(PEM_R_READ_KEY) ,"read key"}, 141{ERR_REASON(PEM_R_READ_KEY) ,"read key"},
117{ERR_REASON(PEM_R_SHORT_HEADER) ,"short header"}, 142{ERR_REASON(PEM_R_SHORT_HEADER) ,"short header"},
118{ERR_REASON(PEM_R_UNSUPPORTED_CIPHER) ,"unsupported cipher"}, 143{ERR_REASON(PEM_R_UNSUPPORTED_CIPHER) ,"unsupported cipher"},
119{ERR_REASON(PEM_R_UNSUPPORTED_ENCRYPTION),"unsupported encryption"}, 144{ERR_REASON(PEM_R_UNSUPPORTED_ENCRYPTION),"unsupported encryption"},
145{ERR_REASON(PEM_R_UNSUPPORTED_KEY_COMPONENTS),"unsupported key components"},
120{0,NULL} 146{0,NULL}
121 }; 147 };
122 148
diff --git a/src/lib/libcrypto/pem/pem_info.c b/src/lib/libcrypto/pem/pem_info.c
index 3a273f6f70..1b2be527ed 100644
--- a/src/lib/libcrypto/pem/pem_info.c
+++ b/src/lib/libcrypto/pem/pem_info.c
@@ -98,8 +98,8 @@ STACK_OF(X509_INFO) *PEM_X509_INFO_read_bio(BIO *bp, STACK_OF(X509_INFO) *sk, pe
98 long len,error=0; 98 long len,error=0;
99 int ok=0; 99 int ok=0;
100 STACK_OF(X509_INFO) *ret=NULL; 100 STACK_OF(X509_INFO) *ret=NULL;
101 unsigned int i,raw; 101 unsigned int i,raw,ptype;
102 d2i_of_void *d2i; 102 d2i_of_void *d2i = 0;
103 103
104 if (sk == NULL) 104 if (sk == NULL)
105 { 105 {
@@ -116,6 +116,7 @@ STACK_OF(X509_INFO) *PEM_X509_INFO_read_bio(BIO *bp, STACK_OF(X509_INFO) *sk, pe
116 for (;;) 116 for (;;)
117 { 117 {
118 raw=0; 118 raw=0;
119 ptype = 0;
119 i=PEM_read_bio(bp,&name,&header,&data,&len); 120 i=PEM_read_bio(bp,&name,&header,&data,&len);
120 if (i == 0) 121 if (i == 0)
121 { 122 {
@@ -166,7 +167,6 @@ start:
166#ifndef OPENSSL_NO_RSA 167#ifndef OPENSSL_NO_RSA
167 if (strcmp(name,PEM_STRING_RSA) == 0) 168 if (strcmp(name,PEM_STRING_RSA) == 0)
168 { 169 {
169 d2i=(D2I_OF(void))d2i_RSAPrivateKey;
170 if (xi->x_pkey != NULL) 170 if (xi->x_pkey != NULL)
171 { 171 {
172 if (!sk_X509_INFO_push(ret,xi)) goto err; 172 if (!sk_X509_INFO_push(ret,xi)) goto err;
@@ -178,10 +178,8 @@ start:
178 xi->enc_len=0; 178 xi->enc_len=0;
179 179
180 xi->x_pkey=X509_PKEY_new(); 180 xi->x_pkey=X509_PKEY_new();
181 if ((xi->x_pkey->dec_pkey=EVP_PKEY_new()) == NULL) 181 ptype=EVP_PKEY_RSA;
182 goto err; 182 pp=&xi->x_pkey->dec_pkey;
183 xi->x_pkey->dec_pkey->type=EVP_PKEY_RSA;
184 pp=&(xi->x_pkey->dec_pkey->pkey.rsa);
185 if ((int)strlen(header) > 10) /* assume encrypted */ 183 if ((int)strlen(header) > 10) /* assume encrypted */
186 raw=1; 184 raw=1;
187 } 185 }
@@ -202,10 +200,8 @@ start:
202 xi->enc_len=0; 200 xi->enc_len=0;
203 201
204 xi->x_pkey=X509_PKEY_new(); 202 xi->x_pkey=X509_PKEY_new();
205 if ((xi->x_pkey->dec_pkey=EVP_PKEY_new()) == NULL) 203 ptype = EVP_PKEY_DSA;
206 goto err; 204 pp=&xi->x_pkey->dec_pkey;
207 xi->x_pkey->dec_pkey->type=EVP_PKEY_DSA;
208 pp=&xi->x_pkey->dec_pkey->pkey.dsa;
209 if ((int)strlen(header) > 10) /* assume encrypted */ 205 if ((int)strlen(header) > 10) /* assume encrypted */
210 raw=1; 206 raw=1;
211 } 207 }
@@ -226,10 +222,8 @@ start:
226 xi->enc_len=0; 222 xi->enc_len=0;
227 223
228 xi->x_pkey=X509_PKEY_new(); 224 xi->x_pkey=X509_PKEY_new();
229 if ((xi->x_pkey->dec_pkey=EVP_PKEY_new()) == NULL) 225 ptype = EVP_PKEY_EC;
230 goto err; 226 pp=&xi->x_pkey->dec_pkey;
231 xi->x_pkey->dec_pkey->type=EVP_PKEY_EC;
232 pp=&(xi->x_pkey->dec_pkey->pkey.ec);
233 if ((int)strlen(header) > 10) /* assume encrypted */ 227 if ((int)strlen(header) > 10) /* assume encrypted */
234 raw=1; 228 raw=1;
235 } 229 }
@@ -251,7 +245,15 @@ start:
251 if (!PEM_do_header(&cipher,data,&len,cb,u)) 245 if (!PEM_do_header(&cipher,data,&len,cb,u))
252 goto err; 246 goto err;
253 p=data; 247 p=data;
254 if (d2i(pp,&p,len) == NULL) 248 if (ptype)
249 {
250 if (!d2i_PrivateKey(ptype, pp, &p, len))
251 {
252 PEMerr(PEM_F_PEM_X509_INFO_READ_BIO,ERR_R_ASN1_LIB);
253 goto err;
254 }
255 }
256 else if (d2i(pp,&p,len) == NULL)
255 { 257 {
256 PEMerr(PEM_F_PEM_X509_INFO_READ_BIO,ERR_R_ASN1_LIB); 258 PEMerr(PEM_F_PEM_X509_INFO_READ_BIO,ERR_R_ASN1_LIB);
257 goto err; 259 goto err;
@@ -337,6 +339,12 @@ int PEM_X509_INFO_write_bio(BIO *bp, X509_INFO *xi, EVP_CIPHER *enc,
337 { 339 {
338 if ( (xi->enc_data!=NULL) && (xi->enc_len>0) ) 340 if ( (xi->enc_data!=NULL) && (xi->enc_len>0) )
339 { 341 {
342 if (enc == NULL)
343 {
344 PEMerr(PEM_F_PEM_X509_INFO_WRITE_BIO,PEM_R_CIPHER_IS_NULL);
345 goto err;
346 }
347
340 /* copy from weirdo names into more normal things */ 348 /* copy from weirdo names into more normal things */
341 iv=xi->enc_cipher.iv; 349 iv=xi->enc_cipher.iv;
342 data=(unsigned char *)xi->enc_data; 350 data=(unsigned char *)xi->enc_data;
diff --git a/src/lib/libcrypto/pem/pem_lib.c b/src/lib/libcrypto/pem/pem_lib.c
index cbafefe416..42e4861bc1 100644
--- a/src/lib/libcrypto/pem/pem_lib.c
+++ b/src/lib/libcrypto/pem/pem_lib.c
@@ -57,6 +57,7 @@
57 */ 57 */
58 58
59#include <stdio.h> 59#include <stdio.h>
60#include <ctype.h>
60#include "cryptlib.h" 61#include "cryptlib.h"
61#include <openssl/buffer.h> 62#include <openssl/buffer.h>
62#include <openssl/objects.h> 63#include <openssl/objects.h>
@@ -65,9 +66,13 @@
65#include <openssl/x509.h> 66#include <openssl/x509.h>
66#include <openssl/pem.h> 67#include <openssl/pem.h>
67#include <openssl/pkcs12.h> 68#include <openssl/pkcs12.h>
69#include "asn1_locl.h"
68#ifndef OPENSSL_NO_DES 70#ifndef OPENSSL_NO_DES
69#include <openssl/des.h> 71#include <openssl/des.h>
70#endif 72#endif
73#ifndef OPENSSL_NO_ENGINE
74#include <openssl/engine.h>
75#endif
71 76
72const char PEM_version[]="PEM" OPENSSL_VERSION_PTEXT; 77const char PEM_version[]="PEM" OPENSSL_VERSION_PTEXT;
73 78
@@ -75,6 +80,7 @@ const char PEM_version[]="PEM" OPENSSL_VERSION_PTEXT;
75 80
76static int load_iv(char **fromp,unsigned char *to, int num); 81static int load_iv(char **fromp,unsigned char *to, int num);
77static int check_pem(const char *nm, const char *name); 82static int check_pem(const char *nm, const char *name);
83int pem_check_suffix(const char *pem_str, const char *suffix);
78 84
79int PEM_def_callback(char *buf, int num, int w, void *key) 85int PEM_def_callback(char *buf, int num, int w, void *key)
80 { 86 {
@@ -99,7 +105,7 @@ int PEM_def_callback(char *buf, int num, int w, void *key)
99 105
100 for (;;) 106 for (;;)
101 { 107 {
102 i=EVP_read_pw_string(buf,num,prompt,w); 108 i=EVP_read_pw_string_min(buf,MIN_LENGTH,num,prompt,w);
103 if (i != 0) 109 if (i != 0)
104 { 110 {
105 PEMerr(PEM_F_PEM_DEF_CALLBACK,PEM_R_PROBLEMS_GETTING_PASSWORD); 111 PEMerr(PEM_F_PEM_DEF_CALLBACK,PEM_R_PROBLEMS_GETTING_PASSWORD);
@@ -183,20 +189,54 @@ static int check_pem(const char *nm, const char *name)
183 189
184 /* Make PEM_STRING_EVP_PKEY match any private key */ 190 /* Make PEM_STRING_EVP_PKEY match any private key */
185 191
186 if(!strcmp(nm,PEM_STRING_PKCS8) && 192 if(!strcmp(name,PEM_STRING_EVP_PKEY))
187 !strcmp(name,PEM_STRING_EVP_PKEY)) return 1; 193 {
188 194 int slen;
189 if(!strcmp(nm,PEM_STRING_PKCS8INF) && 195 const EVP_PKEY_ASN1_METHOD *ameth;
190 !strcmp(name,PEM_STRING_EVP_PKEY)) return 1; 196 if(!strcmp(nm,PEM_STRING_PKCS8))
191 197 return 1;
192 if(!strcmp(nm,PEM_STRING_RSA) && 198 if(!strcmp(nm,PEM_STRING_PKCS8INF))
193 !strcmp(name,PEM_STRING_EVP_PKEY)) return 1; 199 return 1;
200 slen = pem_check_suffix(nm, "PRIVATE KEY");
201 if (slen > 0)
202 {
203 /* NB: ENGINE implementations wont contain
204 * a deprecated old private key decode function
205 * so don't look for them.
206 */
207 ameth = EVP_PKEY_asn1_find_str(NULL, nm, slen);
208 if (ameth && ameth->old_priv_decode)
209 return 1;
210 }
211 return 0;
212 }
194 213
195 if(!strcmp(nm,PEM_STRING_DSA) && 214 if(!strcmp(name,PEM_STRING_PARAMETERS))
196 !strcmp(name,PEM_STRING_EVP_PKEY)) return 1; 215 {
216 int slen;
217 const EVP_PKEY_ASN1_METHOD *ameth;
218 slen = pem_check_suffix(nm, "PARAMETERS");
219 if (slen > 0)
220 {
221 ENGINE *e;
222 ameth = EVP_PKEY_asn1_find_str(&e, nm, slen);
223 if (ameth)
224 {
225 int r;
226 if (ameth->param_decode)
227 r = 1;
228 else
229 r = 0;
230#ifndef OPENSSL_NO_ENGINE
231 if (e)
232 ENGINE_finish(e);
233#endif
234 return r;
235 }
236 }
237 return 0;
238 }
197 239
198 if(!strcmp(nm,PEM_STRING_ECPRIVATEKEY) &&
199 !strcmp(name,PEM_STRING_EVP_PKEY)) return 1;
200 /* Permit older strings */ 240 /* Permit older strings */
201 241
202 if(!strcmp(nm,PEM_STRING_X509_OLD) && 242 if(!strcmp(nm,PEM_STRING_X509_OLD) &&
@@ -219,6 +259,14 @@ static int check_pem(const char *nm, const char *name)
219 if(!strcmp(nm, PEM_STRING_PKCS7_SIGNED) && 259 if(!strcmp(nm, PEM_STRING_PKCS7_SIGNED) &&
220 !strcmp(name, PEM_STRING_PKCS7)) return 1; 260 !strcmp(name, PEM_STRING_PKCS7)) return 1;
221 261
262#ifndef OPENSSL_NO_CMS
263 if(!strcmp(nm, PEM_STRING_X509) &&
264 !strcmp(name, PEM_STRING_CMS)) return 1;
265 /* Allow CMS to be read from PKCS#7 headers */
266 if(!strcmp(nm, PEM_STRING_PKCS7) &&
267 !strcmp(name, PEM_STRING_CMS)) return 1;
268#endif
269
222 return 0; 270 return 0;
223} 271}
224 272
@@ -264,7 +312,7 @@ err:
264 312
265#ifndef OPENSSL_NO_FP_API 313#ifndef OPENSSL_NO_FP_API
266int PEM_ASN1_write(i2d_of_void *i2d, const char *name, FILE *fp, 314int PEM_ASN1_write(i2d_of_void *i2d, const char *name, FILE *fp,
267 char *x, const EVP_CIPHER *enc, unsigned char *kstr, 315 void *x, const EVP_CIPHER *enc, unsigned char *kstr,
268 int klen, pem_password_cb *callback, void *u) 316 int klen, pem_password_cb *callback, void *u)
269 { 317 {
270 BIO *b; 318 BIO *b;
@@ -283,7 +331,7 @@ int PEM_ASN1_write(i2d_of_void *i2d, const char *name, FILE *fp,
283#endif 331#endif
284 332
285int PEM_ASN1_write_bio(i2d_of_void *i2d, const char *name, BIO *bp, 333int PEM_ASN1_write_bio(i2d_of_void *i2d, const char *name, BIO *bp,
286 char *x, const EVP_CIPHER *enc, unsigned char *kstr, 334 void *x, const EVP_CIPHER *enc, unsigned char *kstr,
287 int klen, pem_password_cb *callback, void *u) 335 int klen, pem_password_cb *callback, void *u)
288 { 336 {
289 EVP_CIPHER_CTX ctx; 337 EVP_CIPHER_CTX ctx;
@@ -782,3 +830,25 @@ err:
782 BUF_MEM_free(dataB); 830 BUF_MEM_free(dataB);
783 return(0); 831 return(0);
784 } 832 }
833
834/* Check pem string and return prefix length.
835 * If for example the pem_str == "RSA PRIVATE KEY" and suffix = "PRIVATE KEY"
836 * the return value is 3 for the string "RSA".
837 */
838
839int pem_check_suffix(const char *pem_str, const char *suffix)
840 {
841 int pem_len = strlen(pem_str);
842 int suffix_len = strlen(suffix);
843 const char *p;
844 if (suffix_len + 1 >= pem_len)
845 return 0;
846 p = pem_str + pem_len - suffix_len;
847 if (strcmp(p, suffix))
848 return 0;
849 p--;
850 if (*p != ' ')
851 return 0;
852 return p - pem_str;
853 }
854
diff --git a/src/lib/libcrypto/pem/pem_pkey.c b/src/lib/libcrypto/pem/pem_pkey.c
index 4da4c31ce5..8ecf24903b 100644
--- a/src/lib/libcrypto/pem/pem_pkey.c
+++ b/src/lib/libcrypto/pem/pem_pkey.c
@@ -65,7 +65,12 @@
65#include <openssl/x509.h> 65#include <openssl/x509.h>
66#include <openssl/pkcs12.h> 66#include <openssl/pkcs12.h>
67#include <openssl/pem.h> 67#include <openssl/pem.h>
68#ifndef OPENSSL_NO_ENGINE
69#include <openssl/engine.h>
70#endif
71#include "asn1_locl.h"
68 72
73int pem_check_suffix(const char *pem_str, const char *suffix);
69 74
70EVP_PKEY *PEM_read_bio_PrivateKey(BIO *bp, EVP_PKEY **x, pem_password_cb *cb, void *u) 75EVP_PKEY *PEM_read_bio_PrivateKey(BIO *bp, EVP_PKEY **x, pem_password_cb *cb, void *u)
71 { 76 {
@@ -73,19 +78,14 @@ EVP_PKEY *PEM_read_bio_PrivateKey(BIO *bp, EVP_PKEY **x, pem_password_cb *cb, vo
73 const unsigned char *p=NULL; 78 const unsigned char *p=NULL;
74 unsigned char *data=NULL; 79 unsigned char *data=NULL;
75 long len; 80 long len;
81 int slen;
76 EVP_PKEY *ret=NULL; 82 EVP_PKEY *ret=NULL;
77 83
78 if (!PEM_bytes_read_bio(&data, &len, &nm, PEM_STRING_EVP_PKEY, bp, cb, u)) 84 if (!PEM_bytes_read_bio(&data, &len, &nm, PEM_STRING_EVP_PKEY, bp, cb, u))
79 return NULL; 85 return NULL;
80 p = data; 86 p = data;
81 87
82 if (strcmp(nm,PEM_STRING_RSA) == 0) 88 if (strcmp(nm,PEM_STRING_PKCS8INF) == 0) {
83 ret=d2i_PrivateKey(EVP_PKEY_RSA,x,&p,len);
84 else if (strcmp(nm,PEM_STRING_DSA) == 0)
85 ret=d2i_PrivateKey(EVP_PKEY_DSA,x,&p,len);
86 else if (strcmp(nm,PEM_STRING_ECPRIVATEKEY) == 0)
87 ret=d2i_PrivateKey(EVP_PKEY_EC,x,&p,len);
88 else if (strcmp(nm,PEM_STRING_PKCS8INF) == 0) {
89 PKCS8_PRIV_KEY_INFO *p8inf; 89 PKCS8_PRIV_KEY_INFO *p8inf;
90 p8inf=d2i_PKCS8_PRIV_KEY_INFO(NULL, &p, len); 90 p8inf=d2i_PKCS8_PRIV_KEY_INFO(NULL, &p, len);
91 if(!p8inf) goto p8err; 91 if(!p8inf) goto p8err;
@@ -119,7 +119,14 @@ EVP_PKEY *PEM_read_bio_PrivateKey(BIO *bp, EVP_PKEY **x, pem_password_cb *cb, vo
119 *x = ret; 119 *x = ret;
120 } 120 }
121 PKCS8_PRIV_KEY_INFO_free(p8inf); 121 PKCS8_PRIV_KEY_INFO_free(p8inf);
122 } 122 } else if ((slen = pem_check_suffix(nm, "PRIVATE KEY")) > 0)
123 {
124 const EVP_PKEY_ASN1_METHOD *ameth;
125 ameth = EVP_PKEY_asn1_find_str(NULL, nm, slen);
126 if (!ameth || !ameth->old_priv_decode)
127 goto p8err;
128 ret=d2i_PrivateKey(ameth->pkey_id,x,&p,len);
129 }
123p8err: 130p8err:
124 if (ret == NULL) 131 if (ret == NULL)
125 PEMerr(PEM_F_PEM_READ_BIO_PRIVATEKEY,ERR_R_ASN1_LIB); 132 PEMerr(PEM_F_PEM_READ_BIO_PRIVATEKEY,ERR_R_ASN1_LIB);
@@ -130,6 +137,74 @@ err:
130 return(ret); 137 return(ret);
131 } 138 }
132 139
140int PEM_write_bio_PrivateKey(BIO *bp, EVP_PKEY *x, const EVP_CIPHER *enc,
141 unsigned char *kstr, int klen,
142 pem_password_cb *cb, void *u)
143 {
144 char pem_str[80];
145 if (!x->ameth || x->ameth->priv_encode)
146 return PEM_write_bio_PKCS8PrivateKey(bp, x, enc,
147 (char *)kstr, klen,
148 cb, u);
149
150 BIO_snprintf(pem_str, 80, "%s PRIVATE KEY", x->ameth->pem_str);
151 return PEM_ASN1_write_bio((i2d_of_void *)i2d_PrivateKey,
152 pem_str,bp,x,enc,kstr,klen,cb,u);
153 }
154
155EVP_PKEY *PEM_read_bio_Parameters(BIO *bp, EVP_PKEY **x)
156 {
157 char *nm=NULL;
158 const unsigned char *p=NULL;
159 unsigned char *data=NULL;
160 long len;
161 int slen;
162 EVP_PKEY *ret=NULL;
163
164 if (!PEM_bytes_read_bio(&data, &len, &nm, PEM_STRING_PARAMETERS,
165 bp, 0, NULL))
166 return NULL;
167 p = data;
168
169 if ((slen = pem_check_suffix(nm, "PARAMETERS")) > 0)
170 {
171 ret = EVP_PKEY_new();
172 if (!ret)
173 goto err;
174 if (!EVP_PKEY_set_type_str(ret, nm, slen)
175 || !ret->ameth->param_decode
176 || !ret->ameth->param_decode(ret, &p, len))
177 {
178 EVP_PKEY_free(ret);
179 ret = NULL;
180 goto err;
181 }
182 if(x)
183 {
184 if(*x) EVP_PKEY_free((EVP_PKEY *)*x);
185 *x = ret;
186 }
187 }
188err:
189 if (ret == NULL)
190 PEMerr(PEM_F_PEM_READ_BIO_PARAMETERS,ERR_R_ASN1_LIB);
191 OPENSSL_free(nm);
192 OPENSSL_free(data);
193 return(ret);
194 }
195
196int PEM_write_bio_Parameters(BIO *bp, EVP_PKEY *x)
197 {
198 char pem_str[80];
199 if (!x->ameth || !x->ameth->param_encode)
200 return 0;
201
202 BIO_snprintf(pem_str, 80, "%s PARAMETERS", x->ameth->pem_str);
203 return PEM_ASN1_write_bio(
204 (i2d_of_void *)x->ameth->param_encode,
205 pem_str,bp,x,NULL,NULL,0,0,NULL);
206 }
207
133#ifndef OPENSSL_NO_FP_API 208#ifndef OPENSSL_NO_FP_API
134EVP_PKEY *PEM_read_PrivateKey(FILE *fp, EVP_PKEY **x, pem_password_cb *cb, void *u) 209EVP_PKEY *PEM_read_PrivateKey(FILE *fp, EVP_PKEY **x, pem_password_cb *cb, void *u)
135 { 210 {
@@ -146,4 +221,22 @@ EVP_PKEY *PEM_read_PrivateKey(FILE *fp, EVP_PKEY **x, pem_password_cb *cb, void
146 BIO_free(b); 221 BIO_free(b);
147 return(ret); 222 return(ret);
148 } 223 }
224
225int PEM_write_PrivateKey(FILE *fp, EVP_PKEY *x, const EVP_CIPHER *enc,
226 unsigned char *kstr, int klen,
227 pem_password_cb *cb, void *u)
228 {
229 BIO *b;
230 int ret;
231
232 if ((b=BIO_new_fp(fp, BIO_NOCLOSE)) == NULL)
233 {
234 PEMerr(PEM_F_PEM_WRITE_PRIVATEKEY,ERR_R_BUF_LIB);
235 return 0;
236 }
237 ret=PEM_write_bio_PrivateKey(b, x, enc, kstr, klen, cb, u);
238 BIO_free(b);
239 return ret;
240 }
241
149#endif 242#endif
diff --git a/src/lib/libcrypto/pem/pem_seal.c b/src/lib/libcrypto/pem/pem_seal.c
index 4e554e5481..59690b56ae 100644
--- a/src/lib/libcrypto/pem/pem_seal.c
+++ b/src/lib/libcrypto/pem/pem_seal.c
@@ -100,7 +100,7 @@ int PEM_SealInit(PEM_ENCODE_SEAL_CTX *ctx, EVP_CIPHER *type, EVP_MD *md_type,
100 100
101 EVP_CIPHER_CTX_init(&ctx->cipher); 101 EVP_CIPHER_CTX_init(&ctx->cipher);
102 ret=EVP_SealInit(&ctx->cipher,type,ek,ekl,iv,pubk,npubk); 102 ret=EVP_SealInit(&ctx->cipher,type,ek,ekl,iv,pubk,npubk);
103 if (!ret) goto err; 103 if (ret <= 0) goto err;
104 104
105 /* base64 encode the keys */ 105 /* base64 encode the keys */
106 for (i=0; i<npubk; i++) 106 for (i=0; i<npubk; i++)
diff --git a/src/lib/libcrypto/pem/pem_x509.c b/src/lib/libcrypto/pem/pem_x509.c
index 3f709f13e6..b531057dc9 100644
--- a/src/lib/libcrypto/pem/pem_x509.c
+++ b/src/lib/libcrypto/pem/pem_x509.c
@@ -57,7 +57,6 @@
57 */ 57 */
58 58
59#include <stdio.h> 59#include <stdio.h>
60#undef SSLEAY_MACROS
61#include "cryptlib.h" 60#include "cryptlib.h"
62#include <openssl/bio.h> 61#include <openssl/bio.h>
63#include <openssl/evp.h> 62#include <openssl/evp.h>
diff --git a/src/lib/libcrypto/pem/pem_xaux.c b/src/lib/libcrypto/pem/pem_xaux.c
index 7cc7491009..328f796200 100644
--- a/src/lib/libcrypto/pem/pem_xaux.c
+++ b/src/lib/libcrypto/pem/pem_xaux.c
@@ -57,7 +57,6 @@
57 */ 57 */
58 58
59#include <stdio.h> 59#include <stdio.h>
60#undef SSLEAY_MACROS
61#include "cryptlib.h" 60#include "cryptlib.h"
62#include <openssl/bio.h> 61#include <openssl/bio.h>
63#include <openssl/evp.h> 62#include <openssl/evp.h>
diff --git a/src/lib/libcrypto/pem/pvkfmt.c b/src/lib/libcrypto/pem/pvkfmt.c
new file mode 100644
index 0000000000..d998a67fa5
--- /dev/null
+++ b/src/lib/libcrypto/pem/pvkfmt.c
@@ -0,0 +1,942 @@
1/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
2 * project 2005.
3 */
4/* ====================================================================
5 * Copyright (c) 2005 The OpenSSL Project. All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 *
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 *
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in
16 * the documentation and/or other materials provided with the
17 * distribution.
18 *
19 * 3. All advertising materials mentioning features or use of this
20 * software must display the following acknowledgment:
21 * "This product includes software developed by the OpenSSL Project
22 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
23 *
24 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
25 * endorse or promote products derived from this software without
26 * prior written permission. For written permission, please contact
27 * licensing@OpenSSL.org.
28 *
29 * 5. Products derived from this software may not be called "OpenSSL"
30 * nor may "OpenSSL" appear in their names without prior written
31 * permission of the OpenSSL Project.
32 *
33 * 6. Redistributions of any form whatsoever must retain the following
34 * acknowledgment:
35 * "This product includes software developed by the OpenSSL Project
36 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
37 *
38 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
39 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
40 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
41 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
42 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
43 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
44 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
45 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
46 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
47 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
48 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
49 * OF THE POSSIBILITY OF SUCH DAMAGE.
50 * ====================================================================
51 *
52 * This product includes cryptographic software written by Eric Young
53 * (eay@cryptsoft.com). This product includes software written by Tim
54 * Hudson (tjh@cryptsoft.com).
55 *
56 */
57
58/* Support for PVK format keys and related structures (such a PUBLICKEYBLOB
59 * and PRIVATEKEYBLOB).
60 */
61
62#include "cryptlib.h"
63#include <openssl/pem.h>
64#include <openssl/rand.h>
65#include <openssl/bn.h>
66#if !defined(OPENSSL_NO_RSA) && !defined(OPENSSL_NO_DSA)
67#include <openssl/dsa.h>
68#include <openssl/rsa.h>
69
70/* Utility function: read a DWORD (4 byte unsigned integer) in little endian
71 * format
72 */
73
74static unsigned int read_ledword(const unsigned char **in)
75 {
76 const unsigned char *p = *in;
77 unsigned int ret;
78 ret = *p++;
79 ret |= (*p++ << 8);
80 ret |= (*p++ << 16);
81 ret |= (*p++ << 24);
82 *in = p;
83 return ret;
84 }
85
86/* Read a BIGNUM in little endian format. The docs say that this should take up
87 * bitlen/8 bytes.
88 */
89
90static int read_lebn(const unsigned char **in, unsigned int nbyte, BIGNUM **r)
91 {
92 const unsigned char *p;
93 unsigned char *tmpbuf, *q;
94 unsigned int i;
95 p = *in + nbyte - 1;
96 tmpbuf = OPENSSL_malloc(nbyte);
97 if (!tmpbuf)
98 return 0;
99 q = tmpbuf;
100 for (i = 0; i < nbyte; i++)
101 *q++ = *p--;
102 *r = BN_bin2bn(tmpbuf, nbyte, NULL);
103 OPENSSL_free(tmpbuf);
104 if (*r)
105 {
106 *in += nbyte;
107 return 1;
108 }
109 else
110 return 0;
111 }
112
113
114/* Convert private key blob to EVP_PKEY: RSA and DSA keys supported */
115
116#define MS_PUBLICKEYBLOB 0x6
117#define MS_PRIVATEKEYBLOB 0x7
118#define MS_RSA1MAGIC 0x31415352L
119#define MS_RSA2MAGIC 0x32415352L
120#define MS_DSS1MAGIC 0x31535344L
121#define MS_DSS2MAGIC 0x32535344L
122
123#define MS_KEYALG_RSA_KEYX 0xa400
124#define MS_KEYALG_DSS_SIGN 0x2200
125
126#define MS_KEYTYPE_KEYX 0x1
127#define MS_KEYTYPE_SIGN 0x2
128
129/* The PVK file magic number: seems to spell out "bobsfile", who is Bob? */
130#define MS_PVKMAGIC 0xb0b5f11eL
131/* Salt length for PVK files */
132#define PVK_SALTLEN 0x10
133
134static EVP_PKEY *b2i_rsa(const unsigned char **in, unsigned int length,
135 unsigned int bitlen, int ispub);
136static EVP_PKEY *b2i_dss(const unsigned char **in, unsigned int length,
137 unsigned int bitlen, int ispub);
138
139static int do_blob_header(const unsigned char **in, unsigned int length,
140 unsigned int *pmagic, unsigned int *pbitlen,
141 int *pisdss, int *pispub)
142 {
143 const unsigned char *p = *in;
144 if (length < 16)
145 return 0;
146 /* bType */
147 if (*p == MS_PUBLICKEYBLOB)
148 {
149 if (*pispub == 0)
150 {
151 PEMerr(PEM_F_DO_BLOB_HEADER,
152 PEM_R_EXPECTING_PRIVATE_KEY_BLOB);
153 return 0;
154 }
155 *pispub = 1;
156 }
157 else if (*p == MS_PRIVATEKEYBLOB)
158 {
159 if (*pispub == 1)
160 {
161 PEMerr(PEM_F_DO_BLOB_HEADER,
162 PEM_R_EXPECTING_PUBLIC_KEY_BLOB);
163 return 0;
164 }
165 *pispub = 0;
166 }
167 else
168 return 0;
169 p++;
170 /* Version */
171 if (*p++ != 0x2)
172 {
173 PEMerr(PEM_F_DO_BLOB_HEADER, PEM_R_BAD_VERSION_NUMBER);
174 return 0;
175 }
176 /* Ignore reserved, aiKeyAlg */
177 p+= 6;
178 *pmagic = read_ledword(&p);
179 *pbitlen = read_ledword(&p);
180 *pisdss = 0;
181 switch (*pmagic)
182 {
183
184 case MS_DSS1MAGIC:
185 *pisdss = 1;
186 case MS_RSA1MAGIC:
187 if (*pispub == 0)
188 {
189 PEMerr(PEM_F_DO_BLOB_HEADER,
190 PEM_R_EXPECTING_PRIVATE_KEY_BLOB);
191 return 0;
192 }
193 break;
194
195 case MS_DSS2MAGIC:
196 *pisdss = 1;
197 case MS_RSA2MAGIC:
198 if (*pispub == 1)
199 {
200 PEMerr(PEM_F_DO_BLOB_HEADER,
201 PEM_R_EXPECTING_PUBLIC_KEY_BLOB);
202 return 0;
203 }
204 break;
205
206 default:
207 PEMerr(PEM_F_DO_BLOB_HEADER, PEM_R_BAD_MAGIC_NUMBER);
208 return -1;
209 }
210 *in = p;
211 return 1;
212 }
213
214static unsigned int blob_length(unsigned bitlen, int isdss, int ispub)
215 {
216 unsigned int nbyte, hnbyte;
217 nbyte = (bitlen + 7) >> 3;
218 hnbyte = (bitlen + 15) >> 4;
219 if (isdss)
220 {
221
222 /* Expected length: 20 for q + 3 components bitlen each + 24
223 * for seed structure.
224 */
225 if (ispub)
226 return 44 + 3 * nbyte;
227 /* Expected length: 20 for q, priv, 2 bitlen components + 24
228 * for seed structure.
229 */
230 else
231 return 64 + 2 * nbyte;
232 }
233 else
234 {
235 /* Expected length: 4 for 'e' + 'n' */
236 if (ispub)
237 return 4 + nbyte;
238 else
239 /* Expected length: 4 for 'e' and 7 other components.
240 * 2 components are bitlen size, 5 are bitlen/2
241 */
242 return 4 + 2*nbyte + 5*hnbyte;
243 }
244
245 }
246
247static EVP_PKEY *do_b2i(const unsigned char **in, unsigned int length,
248 int ispub)
249 {
250 const unsigned char *p = *in;
251 unsigned int bitlen, magic;
252 int isdss;
253 if (do_blob_header(&p, length, &magic, &bitlen, &isdss, &ispub) <= 0)
254 {
255 PEMerr(PEM_F_DO_B2I, PEM_R_KEYBLOB_HEADER_PARSE_ERROR);
256 return NULL;
257 }
258 length -= 16;
259 if (length < blob_length(bitlen, isdss, ispub))
260 {
261 PEMerr(PEM_F_DO_B2I, PEM_R_KEYBLOB_TOO_SHORT);
262 return NULL;
263 }
264 if (isdss)
265 return b2i_dss(&p, length, bitlen, ispub);
266 else
267 return b2i_rsa(&p, length, bitlen, ispub);
268 }
269
270static EVP_PKEY *do_b2i_bio(BIO *in, int ispub)
271 {
272 const unsigned char *p;
273 unsigned char hdr_buf[16], *buf = NULL;
274 unsigned int bitlen, magic, length;
275 int isdss;
276 EVP_PKEY *ret = NULL;
277 if (BIO_read(in, hdr_buf, 16) != 16)
278 {
279 PEMerr(PEM_F_DO_B2I_BIO, PEM_R_KEYBLOB_TOO_SHORT);
280 return NULL;
281 }
282 p = hdr_buf;
283 if (do_blob_header(&p, 16, &magic, &bitlen, &isdss, &ispub) <= 0)
284 return NULL;
285
286 length = blob_length(bitlen, isdss, ispub);
287 buf = OPENSSL_malloc(length);
288 if (!buf)
289 {
290 PEMerr(PEM_F_DO_B2I_BIO, ERR_R_MALLOC_FAILURE);
291 goto err;
292 }
293 p = buf;
294 if (BIO_read(in, buf, length) != (int)length)
295 {
296 PEMerr(PEM_F_DO_B2I_BIO, PEM_R_KEYBLOB_TOO_SHORT);
297 goto err;
298 }
299
300 if (isdss)
301 ret = b2i_dss(&p, length, bitlen, ispub);
302 else
303 ret = b2i_rsa(&p, length, bitlen, ispub);
304
305 err:
306 if (buf)
307 OPENSSL_free(buf);
308 return ret;
309 }
310
311static EVP_PKEY *b2i_dss(const unsigned char **in, unsigned int length,
312 unsigned int bitlen, int ispub)
313 {
314 const unsigned char *p = *in;
315 EVP_PKEY *ret = NULL;
316 DSA *dsa = NULL;
317 BN_CTX *ctx = NULL;
318 unsigned int nbyte;
319 nbyte = (bitlen + 7) >> 3;
320
321 dsa = DSA_new();
322 ret = EVP_PKEY_new();
323 if (!dsa || !ret)
324 goto memerr;
325 if (!read_lebn(&p, nbyte, &dsa->p))
326 goto memerr;
327 if (!read_lebn(&p, 20, &dsa->q))
328 goto memerr;
329 if (!read_lebn(&p, nbyte, &dsa->g))
330 goto memerr;
331 if (ispub)
332 {
333 if (!read_lebn(&p, nbyte, &dsa->pub_key))
334 goto memerr;
335 }
336 else
337 {
338 if (!read_lebn(&p, 20, &dsa->priv_key))
339 goto memerr;
340 /* Calculate public key */
341 if (!(dsa->pub_key = BN_new()))
342 goto memerr;
343 if (!(ctx = BN_CTX_new()))
344 goto memerr;
345
346 if (!BN_mod_exp(dsa->pub_key, dsa->g,
347 dsa->priv_key, dsa->p, ctx))
348
349 goto memerr;
350 BN_CTX_free(ctx);
351 }
352
353 EVP_PKEY_set1_DSA(ret, dsa);
354 DSA_free(dsa);
355 *in = p;
356 return ret;
357
358 memerr:
359 PEMerr(PEM_F_B2I_DSS, ERR_R_MALLOC_FAILURE);
360 if (dsa)
361 DSA_free(dsa);
362 if (ret)
363 EVP_PKEY_free(ret);
364 if (ctx)
365 BN_CTX_free(ctx);
366 return NULL;
367 }
368
369static EVP_PKEY *b2i_rsa(const unsigned char **in, unsigned int length,
370 unsigned int bitlen, int ispub)
371
372 {
373 const unsigned char *p = *in;
374 EVP_PKEY *ret = NULL;
375 RSA *rsa = NULL;
376 unsigned int nbyte, hnbyte;
377 nbyte = (bitlen + 7) >> 3;
378 hnbyte = (bitlen + 15) >> 4;
379 rsa = RSA_new();
380 ret = EVP_PKEY_new();
381 if (!rsa || !ret)
382 goto memerr;
383 rsa->e = BN_new();
384 if (!rsa->e)
385 goto memerr;
386 if (!BN_set_word(rsa->e, read_ledword(&p)))
387 goto memerr;
388 if (!read_lebn(&p, nbyte, &rsa->n))
389 goto memerr;
390 if (!ispub)
391 {
392 if (!read_lebn(&p, hnbyte, &rsa->p))
393 goto memerr;
394 if (!read_lebn(&p, hnbyte, &rsa->q))
395 goto memerr;
396 if (!read_lebn(&p, hnbyte, &rsa->dmp1))
397 goto memerr;
398 if (!read_lebn(&p, hnbyte, &rsa->dmq1))
399 goto memerr;
400 if (!read_lebn(&p, hnbyte, &rsa->iqmp))
401 goto memerr;
402 if (!read_lebn(&p, nbyte, &rsa->d))
403 goto memerr;
404 }
405
406 EVP_PKEY_set1_RSA(ret, rsa);
407 RSA_free(rsa);
408 *in = p;
409 return ret;
410 memerr:
411 PEMerr(PEM_F_B2I_RSA, ERR_R_MALLOC_FAILURE);
412 if (rsa)
413 RSA_free(rsa);
414 if (ret)
415 EVP_PKEY_free(ret);
416 return NULL;
417 }
418
419EVP_PKEY *b2i_PrivateKey(const unsigned char **in, long length)
420 {
421 return do_b2i(in, length, 0);
422 }
423
424EVP_PKEY *b2i_PublicKey(const unsigned char **in, long length)
425 {
426 return do_b2i(in, length, 1);
427 }
428
429
430EVP_PKEY *b2i_PrivateKey_bio(BIO *in)
431 {
432 return do_b2i_bio(in, 0);
433 }
434
435EVP_PKEY *b2i_PublicKey_bio(BIO *in)
436 {
437 return do_b2i_bio(in, 1);
438 }
439
440static void write_ledword(unsigned char **out, unsigned int dw)
441 {
442 unsigned char *p = *out;
443 *p++ = dw & 0xff;
444 *p++ = (dw>>8) & 0xff;
445 *p++ = (dw>>16) & 0xff;
446 *p++ = (dw>>24) & 0xff;
447 *out = p;
448 }
449
450static void write_lebn(unsigned char **out, const BIGNUM *bn, int len)
451 {
452 int nb, i;
453 unsigned char *p = *out, *q, c;
454 nb = BN_num_bytes(bn);
455 BN_bn2bin(bn, p);
456 q = p + nb - 1;
457 /* In place byte order reversal */
458 for (i = 0; i < nb/2; i++)
459 {
460 c = *p;
461 *p++ = *q;
462 *q-- = c;
463 }
464 *out += nb;
465 /* Pad with zeroes if we have to */
466 if (len > 0)
467 {
468 len -= nb;
469 if (len > 0)
470 {
471 memset(*out, 0, len);
472 *out += len;
473 }
474 }
475 }
476
477
478static int check_bitlen_rsa(RSA *rsa, int ispub, unsigned int *magic);
479static int check_bitlen_dsa(DSA *dsa, int ispub, unsigned int *magic);
480
481static void write_rsa(unsigned char **out, RSA *rsa, int ispub);
482static void write_dsa(unsigned char **out, DSA *dsa, int ispub);
483
484static int do_i2b(unsigned char **out, EVP_PKEY *pk, int ispub)
485 {
486 unsigned char *p;
487 unsigned int bitlen, magic = 0, keyalg;
488 int outlen, noinc = 0;
489 if (pk->type == EVP_PKEY_DSA)
490 {
491 bitlen = check_bitlen_dsa(pk->pkey.dsa, ispub, &magic);
492 keyalg = MS_KEYALG_DSS_SIGN;
493 }
494 else if (pk->type == EVP_PKEY_RSA)
495 {
496 bitlen = check_bitlen_rsa(pk->pkey.rsa, ispub, &magic);
497 keyalg = MS_KEYALG_RSA_KEYX;
498 }
499 else
500 return -1;
501 if (bitlen == 0)
502 return -1;
503 outlen = 16 + blob_length(bitlen,
504 keyalg == MS_KEYALG_DSS_SIGN ? 1 : 0, ispub);
505 if (out == NULL)
506 return outlen;
507 if (*out)
508 p = *out;
509 else
510 {
511 p = OPENSSL_malloc(outlen);
512 if (!p)
513 return -1;
514 *out = p;
515 noinc = 1;
516 }
517 if (ispub)
518 *p++ = MS_PUBLICKEYBLOB;
519 else
520 *p++ = MS_PRIVATEKEYBLOB;
521 *p++ = 0x2;
522 *p++ = 0;
523 *p++ = 0;
524 write_ledword(&p, keyalg);
525 write_ledword(&p, magic);
526 write_ledword(&p, bitlen);
527 if (keyalg == MS_KEYALG_DSS_SIGN)
528 write_dsa(&p, pk->pkey.dsa, ispub);
529 else
530 write_rsa(&p, pk->pkey.rsa, ispub);
531 if (!noinc)
532 *out += outlen;
533 return outlen;
534 }
535
536static int do_i2b_bio(BIO *out, EVP_PKEY *pk, int ispub)
537 {
538 unsigned char *tmp = NULL;
539 int outlen, wrlen;
540 outlen = do_i2b(&tmp, pk, ispub);
541 if (outlen < 0)
542 return -1;
543 wrlen = BIO_write(out, tmp, outlen);
544 OPENSSL_free(tmp);
545 if (wrlen == outlen)
546 return outlen;
547 return -1;
548 }
549
550static int check_bitlen_dsa(DSA *dsa, int ispub, unsigned int *pmagic)
551 {
552 int bitlen;
553 bitlen = BN_num_bits(dsa->p);
554 if ((bitlen & 7) || (BN_num_bits(dsa->q) != 160)
555 || (BN_num_bits(dsa->g) > bitlen))
556 goto badkey;
557 if (ispub)
558 {
559 if (BN_num_bits(dsa->pub_key) > bitlen)
560 goto badkey;
561 *pmagic = MS_DSS1MAGIC;
562 }
563 else
564 {
565 if (BN_num_bits(dsa->priv_key) > 160)
566 goto badkey;
567 *pmagic = MS_DSS2MAGIC;
568 }
569
570 return bitlen;
571 badkey:
572 PEMerr(PEM_F_CHECK_BITLEN_DSA, PEM_R_UNSUPPORTED_KEY_COMPONENTS);
573 return 0;
574 }
575
576static int check_bitlen_rsa(RSA *rsa, int ispub, unsigned int *pmagic)
577 {
578 int nbyte, hnbyte, bitlen;
579 if (BN_num_bits(rsa->e) > 32)
580 goto badkey;
581 bitlen = BN_num_bits(rsa->n);
582 nbyte = BN_num_bytes(rsa->n);
583 hnbyte = (BN_num_bits(rsa->n) + 15) >> 4;
584 if (ispub)
585 {
586 *pmagic = MS_RSA1MAGIC;
587 return bitlen;
588 }
589 else
590 {
591 *pmagic = MS_RSA2MAGIC;
592 /* For private key each component must fit within nbyte or
593 * hnbyte.
594 */
595 if (BN_num_bytes(rsa->d) > nbyte)
596 goto badkey;
597 if ((BN_num_bytes(rsa->iqmp) > hnbyte)
598 || (BN_num_bytes(rsa->p) > hnbyte)
599 || (BN_num_bytes(rsa->q) > hnbyte)
600 || (BN_num_bytes(rsa->dmp1) > hnbyte)
601 || (BN_num_bytes(rsa->dmq1) > hnbyte))
602 goto badkey;
603 }
604 return bitlen;
605 badkey:
606 PEMerr(PEM_F_CHECK_BITLEN_RSA, PEM_R_UNSUPPORTED_KEY_COMPONENTS);
607 return 0;
608 }
609
610
611static void write_rsa(unsigned char **out, RSA *rsa, int ispub)
612 {
613 int nbyte, hnbyte;
614 nbyte = BN_num_bytes(rsa->n);
615 hnbyte = (BN_num_bits(rsa->n) + 15) >> 4;
616 write_lebn(out, rsa->e, 4);
617 write_lebn(out, rsa->n, -1);
618 if (ispub)
619 return;
620 write_lebn(out, rsa->p, hnbyte);
621 write_lebn(out, rsa->q, hnbyte);
622 write_lebn(out, rsa->dmp1, hnbyte);
623 write_lebn(out, rsa->dmq1, hnbyte);
624 write_lebn(out, rsa->iqmp, hnbyte);
625 write_lebn(out, rsa->d, nbyte);
626 }
627
628
629static void write_dsa(unsigned char **out, DSA *dsa, int ispub)
630 {
631 int nbyte;
632 nbyte = BN_num_bytes(dsa->p);
633 write_lebn(out, dsa->p, nbyte);
634 write_lebn(out, dsa->q, 20);
635 write_lebn(out, dsa->g, nbyte);
636 if (ispub)
637 write_lebn(out, dsa->pub_key, nbyte);
638 else
639 write_lebn(out, dsa->priv_key, 20);
640 /* Set "invalid" for seed structure values */
641 memset(*out, 0xff, 24);
642 *out += 24;
643 return;
644 }
645
646
647int i2b_PrivateKey_bio(BIO *out, EVP_PKEY *pk)
648 {
649 return do_i2b_bio(out, pk, 0);
650 }
651
652int i2b_PublicKey_bio(BIO *out, EVP_PKEY *pk)
653 {
654 return do_i2b_bio(out, pk, 1);
655 }
656
657#ifndef OPENSSL_NO_RC4
658
659static int do_PVK_header(const unsigned char **in, unsigned int length,
660 int skip_magic,
661 unsigned int *psaltlen, unsigned int *pkeylen)
662
663 {
664 const unsigned char *p = *in;
665 unsigned int pvk_magic, keytype, is_encrypted;
666 if (skip_magic)
667 {
668 if (length < 20)
669 {
670 PEMerr(PEM_F_DO_PVK_HEADER, PEM_R_PVK_TOO_SHORT);
671 return 0;
672 }
673 length -= 20;
674 }
675 else
676 {
677 if (length < 24)
678 {
679 PEMerr(PEM_F_DO_PVK_HEADER, PEM_R_PVK_TOO_SHORT);
680 return 0;
681 }
682 length -= 24;
683 pvk_magic = read_ledword(&p);
684 if (pvk_magic != MS_PVKMAGIC)
685 {
686 PEMerr(PEM_F_DO_PVK_HEADER, PEM_R_BAD_MAGIC_NUMBER);
687 return 0;
688 }
689 }
690 /* Skip reserved */
691 p += 4;
692 keytype = read_ledword(&p);
693 is_encrypted = read_ledword(&p);
694 *psaltlen = read_ledword(&p);
695 *pkeylen = read_ledword(&p);
696
697 if (is_encrypted && !*psaltlen)
698 {
699 PEMerr(PEM_F_DO_PVK_HEADER, PEM_R_INCONSISTENT_HEADER);
700 return 0;
701 }
702
703 *in = p;
704 return 1;
705 }
706
707static int derive_pvk_key(unsigned char *key,
708 const unsigned char *salt, unsigned int saltlen,
709 const unsigned char *pass, int passlen)
710 {
711 EVP_MD_CTX mctx;
712 EVP_MD_CTX_init(&mctx);
713 EVP_DigestInit_ex(&mctx, EVP_sha1(), NULL);
714 EVP_DigestUpdate(&mctx, salt, saltlen);
715 EVP_DigestUpdate(&mctx, pass, passlen);
716 EVP_DigestFinal_ex(&mctx, key, NULL);
717 EVP_MD_CTX_cleanup(&mctx);
718 return 1;
719 }
720
721
722static EVP_PKEY *do_PVK_body(const unsigned char **in,
723 unsigned int saltlen, unsigned int keylen,
724 pem_password_cb *cb, void *u)
725 {
726 EVP_PKEY *ret = NULL;
727 const unsigned char *p = *in;
728 unsigned int magic;
729 unsigned char *enctmp = NULL, *q;
730 if (saltlen)
731 {
732 char psbuf[PEM_BUFSIZE];
733 unsigned char keybuf[20];
734 EVP_CIPHER_CTX cctx;
735 int enctmplen, inlen;
736 if (cb)
737 inlen=cb(psbuf,PEM_BUFSIZE,0,u);
738 else
739 inlen=PEM_def_callback(psbuf,PEM_BUFSIZE,0,u);
740 if (inlen <= 0)
741 {
742 PEMerr(PEM_F_DO_PVK_BODY,PEM_R_BAD_PASSWORD_READ);
743 return NULL;
744 }
745 enctmp = OPENSSL_malloc(keylen + 8);
746 if (!enctmp)
747 {
748 PEMerr(PEM_F_DO_PVK_BODY, ERR_R_MALLOC_FAILURE);
749 return NULL;
750 }
751 if (!derive_pvk_key(keybuf, p, saltlen,
752 (unsigned char *)psbuf, inlen))
753 return NULL;
754 p += saltlen;
755 /* Copy BLOBHEADER across, decrypt rest */
756 memcpy(enctmp, p, 8);
757 p += 8;
758 inlen = keylen - 8;
759 q = enctmp + 8;
760 EVP_CIPHER_CTX_init(&cctx);
761 EVP_DecryptInit_ex(&cctx, EVP_rc4(), NULL, keybuf, NULL);
762 EVP_DecryptUpdate(&cctx, q, &enctmplen, p, inlen);
763 EVP_DecryptFinal_ex(&cctx, q + enctmplen, &enctmplen);
764 magic = read_ledword((const unsigned char **)&q);
765 if (magic != MS_RSA2MAGIC && magic != MS_DSS2MAGIC)
766 {
767 q = enctmp + 8;
768 memset(keybuf + 5, 0, 11);
769 EVP_DecryptInit_ex(&cctx, EVP_rc4(), NULL, keybuf,
770 NULL);
771 OPENSSL_cleanse(keybuf, 20);
772 EVP_DecryptUpdate(&cctx, q, &enctmplen, p, inlen);
773 EVP_DecryptFinal_ex(&cctx, q + enctmplen,
774 &enctmplen);
775 magic = read_ledword((const unsigned char **)&q);
776 if (magic != MS_RSA2MAGIC && magic != MS_DSS2MAGIC)
777 {
778 EVP_CIPHER_CTX_cleanup(&cctx);
779 PEMerr(PEM_F_DO_PVK_BODY, PEM_R_BAD_DECRYPT);
780 goto err;
781 }
782 }
783 else
784 OPENSSL_cleanse(keybuf, 20);
785 EVP_CIPHER_CTX_cleanup(&cctx);
786 p = enctmp;
787 }
788
789 ret = b2i_PrivateKey(&p, keylen);
790 err:
791 if (enctmp && saltlen)
792 OPENSSL_free(enctmp);
793 return ret;
794 }
795
796
797EVP_PKEY *b2i_PVK_bio(BIO *in, pem_password_cb *cb, void *u)
798 {
799 unsigned char pvk_hdr[24], *buf = NULL;
800 const unsigned char *p;
801 int buflen;
802 EVP_PKEY *ret = NULL;
803 unsigned int saltlen, keylen;
804 if (BIO_read(in, pvk_hdr, 24) != 24)
805 {
806 PEMerr(PEM_F_B2I_PVK_BIO, PEM_R_PVK_DATA_TOO_SHORT);
807 return NULL;
808 }
809 p = pvk_hdr;
810
811 if (!do_PVK_header(&p, 24, 0, &saltlen, &keylen))
812 return 0;
813 buflen = (int) keylen + saltlen;
814 buf = OPENSSL_malloc(buflen);
815 if (!buf)
816 {
817 PEMerr(PEM_F_B2I_PVK_BIO, ERR_R_MALLOC_FAILURE);
818 return 0;
819 }
820 p = buf;
821 if (BIO_read(in, buf, buflen) != buflen)
822 {
823 PEMerr(PEM_F_B2I_PVK_BIO, PEM_R_PVK_DATA_TOO_SHORT);
824 goto err;
825 }
826 ret = do_PVK_body(&p, saltlen, keylen, cb, u);
827
828 err:
829 if (buf)
830 {
831 OPENSSL_cleanse(buf, buflen);
832 OPENSSL_free(buf);
833 }
834 return ret;
835 }
836
837
838
839static int i2b_PVK(unsigned char **out, EVP_PKEY*pk, int enclevel,
840 pem_password_cb *cb, void *u)
841 {
842 int outlen = 24, noinc, pklen;
843 unsigned char *p, *salt = NULL;
844 if (enclevel)
845 outlen += PVK_SALTLEN;
846 pklen = do_i2b(NULL, pk, 0);
847 if (pklen < 0)
848 return -1;
849 outlen += pklen;
850 if (!out)
851 return outlen;
852 if (*out)
853 {
854 p = *out;
855 noinc = 0;
856 }
857 else
858 {
859 p = OPENSSL_malloc(outlen);
860 if (!p)
861 {
862 PEMerr(PEM_F_I2B_PVK,ERR_R_MALLOC_FAILURE);
863 return -1;
864 }
865 *out = p;
866 noinc = 1;
867 }
868
869 write_ledword(&p, MS_PVKMAGIC);
870 write_ledword(&p, 0);
871 if (pk->type == EVP_PKEY_DSA)
872 write_ledword(&p, MS_KEYTYPE_SIGN);
873 else
874 write_ledword(&p, MS_KEYTYPE_KEYX);
875 write_ledword(&p, enclevel ? 1 : 0);
876 write_ledword(&p, enclevel ? PVK_SALTLEN: 0);
877 write_ledword(&p, pklen);
878 if (enclevel)
879 {
880 if (RAND_bytes(p, PVK_SALTLEN) <= 0)
881 goto error;
882 salt = p;
883 p += PVK_SALTLEN;
884 }
885 do_i2b(&p, pk, 0);
886 if (enclevel == 0)
887 return outlen;
888 else
889 {
890 char psbuf[PEM_BUFSIZE];
891 unsigned char keybuf[20];
892 EVP_CIPHER_CTX cctx;
893 int enctmplen, inlen;
894 if (cb)
895 inlen=cb(psbuf,PEM_BUFSIZE,1,u);
896 else
897 inlen=PEM_def_callback(psbuf,PEM_BUFSIZE,1,u);
898 if (inlen <= 0)
899 {
900 PEMerr(PEM_F_I2B_PVK,PEM_R_BAD_PASSWORD_READ);
901 goto error;
902 }
903 if (!derive_pvk_key(keybuf, salt, PVK_SALTLEN,
904 (unsigned char *)psbuf, inlen))
905 goto error;
906 if (enclevel == 1)
907 memset(keybuf + 5, 0, 11);
908 p = salt + PVK_SALTLEN + 8;
909 EVP_CIPHER_CTX_init(&cctx);
910 EVP_EncryptInit_ex(&cctx, EVP_rc4(), NULL, keybuf, NULL);
911 OPENSSL_cleanse(keybuf, 20);
912 EVP_DecryptUpdate(&cctx, p, &enctmplen, p, pklen - 8);
913 EVP_DecryptFinal_ex(&cctx, p + enctmplen, &enctmplen);
914 EVP_CIPHER_CTX_cleanup(&cctx);
915 }
916 return outlen;
917
918 error:
919 return -1;
920 }
921
922int i2b_PVK_bio(BIO *out, EVP_PKEY *pk, int enclevel,
923 pem_password_cb *cb, void *u)
924 {
925 unsigned char *tmp = NULL;
926 int outlen, wrlen;
927 outlen = i2b_PVK(&tmp, pk, enclevel, cb, u);
928 if (outlen < 0)
929 return -1;
930 wrlen = BIO_write(out, tmp, outlen);
931 OPENSSL_free(tmp);
932 if (wrlen == outlen)
933 {
934 PEMerr(PEM_F_I2B_PVK_BIO, PEM_R_BIO_WRITE_FAILURE);
935 return outlen;
936 }
937 return -1;
938 }
939
940#endif
941
942#endif
diff --git a/src/lib/libcrypto/perlasm/ppc-xlate.pl b/src/lib/libcrypto/perlasm/ppc-xlate.pl
new file mode 100755
index 0000000000..4579671c97
--- /dev/null
+++ b/src/lib/libcrypto/perlasm/ppc-xlate.pl
@@ -0,0 +1,152 @@
1#!/usr/bin/env perl
2
3# PowerPC assembler distiller by <appro>.
4
5my $flavour = shift;
6my $output = shift;
7open STDOUT,">$output" || die "can't open $output: $!";
8
9my %GLOBALS;
10my $dotinlocallabels=($flavour=~/linux/)?1:0;
11
12################################################################
13# directives which need special treatment on different platforms
14################################################################
15my $globl = sub {
16 my $junk = shift;
17 my $name = shift;
18 my $global = \$GLOBALS{$name};
19 my $ret;
20
21 $name =~ s|^[\.\_]||;
22
23 SWITCH: for ($flavour) {
24 /aix/ && do { $name = ".$name";
25 last;
26 };
27 /osx/ && do { $name = "_$name";
28 last;
29 };
30 /linux.*32/ && do { $ret .= ".globl $name\n";
31 $ret .= ".type $name,\@function";
32 last;
33 };
34 /linux.*64/ && do { $ret .= ".globl .$name\n";
35 $ret .= ".type .$name,\@function\n";
36 $ret .= ".section \".opd\",\"aw\"\n";
37 $ret .= ".globl $name\n";
38 $ret .= ".align 3\n";
39 $ret .= "$name:\n";
40 $ret .= ".quad .$name,.TOC.\@tocbase,0\n";
41 $ret .= ".size $name,24\n";
42 $ret .= ".previous\n";
43
44 $name = ".$name";
45 last;
46 };
47 }
48
49 $ret = ".globl $name" if (!$ret);
50 $$global = $name;
51 $ret;
52};
53my $text = sub {
54 ($flavour =~ /aix/) ? ".csect" : ".text";
55};
56my $machine = sub {
57 my $junk = shift;
58 my $arch = shift;
59 if ($flavour =~ /osx/)
60 { $arch =~ s/\"//g;
61 $arch = ($flavour=~/64/) ? "ppc970-64" : "ppc970" if ($arch eq "any");
62 }
63 ".machine $arch";
64};
65my $asciz = sub {
66 shift;
67 my $line = join(",",@_);
68 if ($line =~ /^"(.*)"$/)
69 { ".byte " . join(",",unpack("C*",$1),0) . "\n.align 2"; }
70 else
71 { ""; }
72};
73
74################################################################
75# simplified mnemonics not handled by at least one assembler
76################################################################
77my $cmplw = sub {
78 my $f = shift;
79 my $cr = 0; $cr = shift if ($#_>1);
80 # Some out-of-date 32-bit GNU assembler just can't handle cmplw...
81 ($flavour =~ /linux.*32/) ?
82 " .long ".sprintf "0x%x",31<<26|$cr<<23|$_[0]<<16|$_[1]<<11|64 :
83 " cmplw ".join(',',$cr,@_);
84};
85my $bdnz = sub {
86 my $f = shift;
87 my $bo = $f=~/[\+\-]/ ? 16+9 : 16; # optional "to be taken" hint
88 " bc $bo,0,".shift;
89} if ($flavour!~/linux/);
90my $bltlr = sub {
91 my $f = shift;
92 my $bo = $f=~/\-/ ? 12+2 : 12; # optional "not to be taken" hint
93 ($flavour =~ /linux/) ? # GNU as doesn't allow most recent hints
94 " .long ".sprintf "0x%x",19<<26|$bo<<21|16<<1 :
95 " bclr $bo,0";
96};
97my $bnelr = sub {
98 my $f = shift;
99 my $bo = $f=~/\-/ ? 4+2 : 4; # optional "not to be taken" hint
100 ($flavour =~ /linux/) ? # GNU as doesn't allow most recent hints
101 " .long ".sprintf "0x%x",19<<26|$bo<<21|2<<16|16<<1 :
102 " bclr $bo,2";
103};
104my $beqlr = sub {
105 my $f = shift;
106 my $bo = $f=~/-/ ? 12+2 : 12; # optional "not to be taken" hint
107 ($flavour =~ /linux/) ? # GNU as doesn't allow most recent hints
108 " .long ".sprintf "0x%X",19<<26|$bo<<21|2<<16|16<<1 :
109 " bclr $bo,2";
110};
111# GNU assembler can't handle extrdi rA,rS,16,48, or when sum of last two
112# arguments is 64, with "operand out of range" error.
113my $extrdi = sub {
114 my ($f,$ra,$rs,$n,$b) = @_;
115 $b = ($b+$n)&63; $n = 64-$n;
116 " rldicl $ra,$rs,$b,$n";
117};
118
119while($line=<>) {
120
121 $line =~ s|[#!;].*$||; # get rid of asm-style comments...
122 $line =~ s|/\*.*\*/||; # ... and C-style comments...
123 $line =~ s|^\s+||; # ... and skip white spaces in beginning...
124 $line =~ s|\s+$||; # ... and at the end
125
126 {
127 $line =~ s|\b\.L(\w+)|L$1|g; # common denominator for Locallabel
128 $line =~ s|\bL(\w+)|\.L$1|g if ($dotinlocallabels);
129 }
130
131 {
132 $line =~ s|(^[\.\w]+)\:\s*||;
133 my $label = $1;
134 printf "%s:",($GLOBALS{$label} or $label) if ($label);
135 }
136
137 {
138 $line =~ s|^\s*(\.?)(\w+)([\.\+\-]?)\s*||;
139 my $c = $1; $c = "\t" if ($c eq "");
140 my $mnemonic = $2;
141 my $f = $3;
142 my $opcode = eval("\$$mnemonic");
143 $line =~ s|\bc?[rf]([0-9]+)\b|$1|g if ($c ne "." and $flavour !~ /osx/);
144 if (ref($opcode) eq 'CODE') { $line = &$opcode($f,split(',',$line)); }
145 elsif ($mnemonic) { $line = $c.$mnemonic.$f."\t".$line; }
146 }
147
148 print $line if ($line);
149 print "\n";
150}
151
152close STDOUT;
diff --git a/src/lib/libcrypto/perlasm/x86_64-xlate.pl b/src/lib/libcrypto/perlasm/x86_64-xlate.pl
index a4af769b4a..354673acc1 100755
--- a/src/lib/libcrypto/perlasm/x86_64-xlate.pl
+++ b/src/lib/libcrypto/perlasm/x86_64-xlate.pl
@@ -1,6 +1,6 @@
1#!/usr/bin/env perl 1#!/usr/bin/env perl
2 2
3# Ascetic x86_64 AT&T to MASM assembler translator by <appro>. 3# Ascetic x86_64 AT&T to MASM/NASM assembler translator by <appro>.
4# 4#
5# Why AT&T to MASM and not vice versa? Several reasons. Because AT&T 5# Why AT&T to MASM and not vice versa? Several reasons. Because AT&T
6# format is way easier to parse. Because it's simpler to "gear" from 6# format is way easier to parse. Because it's simpler to "gear" from
@@ -20,12 +20,11 @@
20# Currently recognized limitations: 20# Currently recognized limitations:
21# 21#
22# - can't use multiple ops per line; 22# - can't use multiple ops per line;
23# - indirect calls and jumps are not supported;
24# 23#
25# Dual-ABI styling rules. 24# Dual-ABI styling rules.
26# 25#
27# 1. Adhere to Unix register and stack layout [see the end for 26# 1. Adhere to Unix register and stack layout [see cross-reference
28# explanation]. 27# ABI "card" at the end for explanation].
29# 2. Forget about "red zone," stick to more traditional blended 28# 2. Forget about "red zone," stick to more traditional blended
30# stack frame allocation. If volatile storage is actually required 29# stack frame allocation. If volatile storage is actually required
31# that is. If not, just leave the stack as is. 30# that is. If not, just leave the stack as is.
@@ -42,21 +41,26 @@
42# 6. Don't use [or hand-code with .byte] "rep ret." "ret" mnemonic is 41# 6. Don't use [or hand-code with .byte] "rep ret." "ret" mnemonic is
43# required to identify the spots, where to inject Win64 epilogue! 42# required to identify the spots, where to inject Win64 epilogue!
44# But on the pros, it's then prefixed with rep automatically:-) 43# But on the pros, it's then prefixed with rep automatically:-)
45# 7. Due to MASM limitations [and certain general counter-intuitivity 44# 7. Stick to explicit ip-relative addressing. If you have to use
46# of ip-relative addressing] generation of position-independent 45# GOTPCREL addressing, stick to mov symbol@GOTPCREL(%rip),%r??.
47# code is assisted by synthetic directive, .picmeup, which puts 46# Both are recognized and translated to proper Win64 addressing
48# address of the *next* instruction into target register. 47# modes. To support legacy code a synthetic directive, .picmeup,
48# is implemented. It puts address of the *next* instruction into
49# target register, e.g.:
49# 50#
50# Example 1:
51# .picmeup %rax 51# .picmeup %rax
52# lea .Label-.(%rax),%rax 52# lea .Label-.(%rax),%rax
53# Example 2: 53#
54# .picmeup %rcx 54# 8. In order to provide for structured exception handling unified
55# .Lpic_point: 55# Win64 prologue copies %rsp value to %rax. For further details
56# ... 56# see SEH paragraph at the end.
57# lea .Label-.Lpic_point(%rcx),%rbp 57# 9. .init segment is allowed to contain calls to functions only.
58 58# a. If function accepts more than 4 arguments *and* >4th argument
59my $output = shift; 59# is declared as non 64-bit value, do clear its upper part.
60
61my $flavour = shift;
62my $output = shift;
63if ($flavour =~ /\./) { $output = $flavour; undef $flavour; }
60 64
61{ my ($stddev,$stdino,@junk)=stat(STDOUT); 65{ my ($stddev,$stdino,@junk)=stat(STDOUT);
62 my ($outdev,$outino,@junk)=stat($output); 66 my ($outdev,$outino,@junk)=stat($output);
@@ -65,13 +69,40 @@ my $output = shift;
65 if ($stddev!=$outdev || $stdino!=$outino); 69 if ($stddev!=$outdev || $stdino!=$outino);
66} 70}
67 71
72my $gas=1; $gas=0 if ($output =~ /\.asm$/);
73my $elf=1; $elf=0 if (!$gas);
74my $win64=0;
75my $prefix="";
76my $decor=".L";
77
68my $masmref=8 + 50727*2**-32; # 8.00.50727 shipped with VS2005 78my $masmref=8 + 50727*2**-32; # 8.00.50727 shipped with VS2005
69my $masm=$masmref if ($output =~ /\.asm/); 79my $masm=0;
70if ($masm && `ml64 2>&1` =~ m/Version ([0-9]+)\.([0-9]+)(\.([0-9]+))?/) 80my $PTR=" PTR";
71{ $masm=$1 + $2*2**-16 + $4*2**-32; } 81
82my $nasmref=2.03;
83my $nasm=0;
84
85if ($flavour eq "mingw64") { $gas=1; $elf=0; $win64=1;
86 $prefix=`echo __USER_LABEL_PREFIX__ | $ENV{CC} -E -P -`;
87 chomp($prefix);
88 }
89elsif ($flavour eq "macosx") { $gas=1; $elf=0; $prefix="_"; $decor="L\$"; }
90elsif ($flavour eq "masm") { $gas=0; $elf=0; $masm=$masmref; $win64=1; $decor="\$L\$"; }
91elsif ($flavour eq "nasm") { $gas=0; $elf=0; $nasm=$nasmref; $win64=1; $decor="\$L\$"; $PTR=""; }
92elsif (!$gas)
93{ if ($ENV{ASM} =~ m/nasm/ && `nasm -v` =~ m/version ([0-9]+)\.([0-9]+)/i)
94 { $nasm = $1 + $2*0.01; $PTR=""; }
95 elsif (`ml64 2>&1` =~ m/Version ([0-9]+)\.([0-9]+)(\.([0-9]+))?/)
96 { $masm = $1 + $2*2**-16 + $4*2**-32; }
97 die "no assembler found on %PATH" if (!($nasm || $masm));
98 $win64=1;
99 $elf=0;
100 $decor="\$L\$";
101}
72 102
73my $current_segment; 103my $current_segment;
74my $current_function; 104my $current_function;
105my %globals;
75 106
76{ package opcode; # pick up opcodes 107{ package opcode; # pick up opcodes
77 sub re { 108 sub re {
@@ -88,8 +119,10 @@ my $current_function;
88 if ($self->{op} =~ /^(movz)b.*/) { # movz is pain... 119 if ($self->{op} =~ /^(movz)b.*/) { # movz is pain...
89 $self->{op} = $1; 120 $self->{op} = $1;
90 $self->{sz} = "b"; 121 $self->{sz} = "b";
91 } elsif ($self->{op} =~ /call/) { 122 } elsif ($self->{op} =~ /call|jmp/) {
92 $self->{sz} = "" 123 $self->{sz} = "";
124 } elsif ($self->{op} =~ /^p/ && $' !~ /^(ush|op)/) { # SSEn
125 $self->{sz} = "";
93 } elsif ($self->{op} =~ /([a-z]{3,})([qlwb])$/) { 126 } elsif ($self->{op} =~ /([a-z]{3,})([qlwb])$/) {
94 $self->{op} = $1; 127 $self->{op} = $1;
95 $self->{sz} = $2; 128 $self->{sz} = $2;
@@ -105,13 +138,20 @@ my $current_function;
105 } 138 }
106 sub out { 139 sub out {
107 my $self = shift; 140 my $self = shift;
108 if (!$masm) { 141 if ($gas) {
109 if ($self->{op} eq "movz") { # movz is pain... 142 if ($self->{op} eq "movz") { # movz is pain...
110 sprintf "%s%s%s",$self->{op},$self->{sz},shift; 143 sprintf "%s%s%s",$self->{op},$self->{sz},shift;
111 } elsif ($self->{op} =~ /^set/) { 144 } elsif ($self->{op} =~ /^set/) {
112 "$self->{op}"; 145 "$self->{op}";
113 } elsif ($self->{op} eq "ret") { 146 } elsif ($self->{op} eq "ret") {
114 ".byte 0xf3,0xc3"; 147 my $epilogue = "";
148 if ($win64 && $current_function->{abi} eq "svr4") {
149 $epilogue = "movq 8(%rsp),%rdi\n\t" .
150 "movq 16(%rsp),%rsi\n\t";
151 }
152 $epilogue . ".byte 0xf3,0xc3";
153 } elsif ($self->{op} eq "call" && !$elf && $current_segment eq ".init") {
154 ".p2align\t3\n\t.quad";
115 } else { 155 } else {
116 "$self->{op}$self->{sz}"; 156 "$self->{op}$self->{sz}";
117 } 157 }
@@ -119,15 +159,25 @@ my $current_function;
119 $self->{op} =~ s/^movz/movzx/; 159 $self->{op} =~ s/^movz/movzx/;
120 if ($self->{op} eq "ret") { 160 if ($self->{op} eq "ret") {
121 $self->{op} = ""; 161 $self->{op} = "";
122 if ($current_function->{abi} eq "svr4") { 162 if ($win64 && $current_function->{abi} eq "svr4") {
123 $self->{op} = "mov rdi,QWORD PTR 8[rsp]\t;WIN64 epilogue\n\t". 163 $self->{op} = "mov rdi,QWORD${PTR}[8+rsp]\t;WIN64 epilogue\n\t".
124 "mov rsi,QWORD PTR 16[rsp]\n\t"; 164 "mov rsi,QWORD${PTR}[16+rsp]\n\t";
125 } 165 }
126 $self->{op} .= "DB\t0F3h,0C3h\t\t;repret"; 166 $self->{op} .= "DB\t0F3h,0C3h\t\t;repret";
127 } 167 } elsif ($self->{op} =~ /^(pop|push)f/) {
168 $self->{op} .= $self->{sz};
169 } elsif ($self->{op} eq "call" && $current_segment eq ".CRT\$XCU") {
170 $self->{op} = "ALIGN\t8\n\tDQ";
171 }
128 $self->{op}; 172 $self->{op};
129 } 173 }
130 } 174 }
175 sub mnemonic {
176 my $self=shift;
177 my $op=shift;
178 $self->{op}=$op if (defined($op));
179 $self->{op};
180 }
131} 181}
132{ package const; # pick up constants, which start with $ 182{ package const; # pick up constants, which start with $
133 sub re { 183 sub re {
@@ -145,14 +195,15 @@ my $current_function;
145 sub out { 195 sub out {
146 my $self = shift; 196 my $self = shift;
147 197
148 if (!$masm) { 198 if ($gas) {
149 # Solaris /usr/ccs/bin/as can't handle multiplications 199 # Solaris /usr/ccs/bin/as can't handle multiplications
150 # in $self->{value} 200 # in $self->{value}
151 $self->{value} =~ s/(?<![0-9a-f])(0[x0-9a-f]+)/oct($1)/egi; 201 $self->{value} =~ s/(?<![\w\$\.])(0x?[0-9a-f]+)/oct($1)/egi;
152 $self->{value} =~ s/([0-9]+\s*[\*\/\%]\s*[0-9]+)/eval($1)/eg; 202 $self->{value} =~ s/([0-9]+\s*[\*\/\%]\s*[0-9]+)/eval($1)/eg;
153 sprintf "\$%s",$self->{value}; 203 sprintf "\$%s",$self->{value};
154 } else { 204 } else {
155 $self->{value} =~ s/0x([0-9a-f]+)/0$1h/ig; 205 $self->{value} =~ s/(0b[0-1]+)/oct($1)/eig;
206 $self->{value} =~ s/0x([0-9a-f]+)/0$1h/ig if ($masm);
156 sprintf "%s",$self->{value}; 207 sprintf "%s",$self->{value};
157 } 208 }
158 } 209 }
@@ -163,13 +214,19 @@ my $current_function;
163 local *line = shift; 214 local *line = shift;
164 undef $ret; 215 undef $ret;
165 216
166 if ($line =~ /^([^\(,]*)\(([%\w,]+)\)/) { 217 # optional * ---vvv--- appears in indirect jmp/call
167 $self->{label} = $1; 218 if ($line =~ /^(\*?)([^\(,]*)\(([%\w,]+)\)/) {
168 ($self->{base},$self->{index},$self->{scale})=split(/,/,$2); 219 $self->{asterisk} = $1;
220 $self->{label} = $2;
221 ($self->{base},$self->{index},$self->{scale})=split(/,/,$3);
169 $self->{scale} = 1 if (!defined($self->{scale})); 222 $self->{scale} = 1 if (!defined($self->{scale}));
170 $ret = $self; 223 $ret = $self;
171 $line = substr($line,@+[0]); $line =~ s/^\s+//; 224 $line = substr($line,@+[0]); $line =~ s/^\s+//;
172 225
226 if ($win64 && $self->{label} =~ s/\@GOTPCREL//) {
227 die if (opcode->mnemonic() ne "mov");
228 opcode->mnemonic("lea");
229 }
173 $self->{base} =~ s/^%//; 230 $self->{base} =~ s/^%//;
174 $self->{index} =~ s/^%// if (defined($self->{index})); 231 $self->{index} =~ s/^%// if (defined($self->{index}));
175 } 232 }
@@ -180,42 +237,50 @@ my $current_function;
180 my $self = shift; 237 my $self = shift;
181 my $sz = shift; 238 my $sz = shift;
182 239
240 $self->{label} =~ s/([_a-z][_a-z0-9]*)/$globals{$1} or $1/gei;
241 $self->{label} =~ s/\.L/$decor/g;
242
183 # Silently convert all EAs to 64-bit. This is required for 243 # Silently convert all EAs to 64-bit. This is required for
184 # elder GNU assembler and results in more compact code, 244 # elder GNU assembler and results in more compact code,
185 # *but* most importantly AES module depends on this feature! 245 # *but* most importantly AES module depends on this feature!
186 $self->{index} =~ s/^[er](.?[0-9xpi])[d]?$/r\1/; 246 $self->{index} =~ s/^[er](.?[0-9xpi])[d]?$/r\1/;
187 $self->{base} =~ s/^[er](.?[0-9xpi])[d]?$/r\1/; 247 $self->{base} =~ s/^[er](.?[0-9xpi])[d]?$/r\1/;
188 248
189 if (!$masm) { 249 if ($gas) {
190 # Solaris /usr/ccs/bin/as can't handle multiplications 250 # Solaris /usr/ccs/bin/as can't handle multiplications
191 # in $self->{label} 251 # in $self->{label}, new gas requires sign extension...
192 $self->{label} =~ s/(?<![0-9a-f])(0[x0-9a-f]+)/oct($1)/egi; 252 use integer;
253 $self->{label} =~ s/(?<![\w\$\.])(0x?[0-9a-f]+)/oct($1)/egi;
193 $self->{label} =~ s/([0-9]+\s*[\*\/\%]\s*[0-9]+)/eval($1)/eg; 254 $self->{label} =~ s/([0-9]+\s*[\*\/\%]\s*[0-9]+)/eval($1)/eg;
255 $self->{label} =~ s/([0-9]+)/$1<<32>>32/eg;
256 $self->{label} =~ s/^___imp_/__imp__/ if ($flavour eq "mingw64");
194 257
195 if (defined($self->{index})) { 258 if (defined($self->{index})) {
196 sprintf "%s(%%%s,%%%s,%d)", 259 sprintf "%s%s(%%%s,%%%s,%d)",$self->{asterisk},
197 $self->{label},$self->{base}, 260 $self->{label},$self->{base},
198 $self->{index},$self->{scale}; 261 $self->{index},$self->{scale};
199 } else { 262 } else {
200 sprintf "%s(%%%s)", $self->{label},$self->{base}; 263 sprintf "%s%s(%%%s)", $self->{asterisk},$self->{label},$self->{base};
201 } 264 }
202 } else { 265 } else {
203 %szmap = ( b=>"BYTE", w=>"WORD", l=>"DWORD", q=>"QWORD" ); 266 %szmap = ( b=>"BYTE$PTR", w=>"WORD$PTR", l=>"DWORD$PTR", q=>"QWORD$PTR" );
204 267
205 $self->{label} =~ s/\./\$/g; 268 $self->{label} =~ s/\./\$/g;
206 $self->{label} =~ s/0x([0-9a-f]+)/0$1h/ig; 269 $self->{label} =~ s/(?<![\w\$\.])0x([0-9a-f]+)/0$1h/ig;
207 $self->{label} = "($self->{label})" if ($self->{label} =~ /[\*\+\-\/]/); 270 $self->{label} = "($self->{label})" if ($self->{label} =~ /[\*\+\-\/]/);
271 $sz="q" if ($self->{asterisk});
208 272
209 if (defined($self->{index})) { 273 if (defined($self->{index})) {
210 sprintf "%s PTR %s[%s*%d+%s]",$szmap{$sz}, 274 sprintf "%s[%s%s*%d+%s]",$szmap{$sz},
211 $self->{label}, 275 $self->{label}?"$self->{label}+":"",
212 $self->{index},$self->{scale}, 276 $self->{index},$self->{scale},
213 $self->{base}; 277 $self->{base};
214 } elsif ($self->{base} eq "rip") { 278 } elsif ($self->{base} eq "rip") {
215 sprintf "%s PTR %s",$szmap{$sz},$self->{label}; 279 sprintf "%s[%s]",$szmap{$sz},$self->{label};
216 } else { 280 } else {
217 sprintf "%s PTR %s[%s]",$szmap{$sz}, 281 sprintf "%s[%s%s]",$szmap{$sz},
218 $self->{label},$self->{base}; 282 $self->{label}?"$self->{label}+":"",
283 $self->{base};
219 } 284 }
220 } 285 }
221 } 286 }
@@ -227,9 +292,11 @@ my $current_function;
227 local *line = shift; 292 local *line = shift;
228 undef $ret; 293 undef $ret;
229 294
230 if ($line =~ /^%(\w+)/) { 295 # optional * ---vvv--- appears in indirect jmp/call
296 if ($line =~ /^(\*?)%(\w+)/) {
231 bless $self,$class; 297 bless $self,$class;
232 $self->{value} = $1; 298 $self->{asterisk} = $1;
299 $self->{value} = $2;
233 $ret = $self; 300 $ret = $self;
234 $line = substr($line,@+[0]); $line =~ s/^\s+//; 301 $line = substr($line,@+[0]); $line =~ s/^\s+//;
235 } 302 }
@@ -252,7 +319,8 @@ my $current_function;
252 } 319 }
253 sub out { 320 sub out {
254 my $self = shift; 321 my $self = shift;
255 sprintf $masm?"%s":"%%%s",$self->{value}; 322 if ($gas) { sprintf "%s%%%s",$self->{asterisk},$self->{value}; }
323 else { $self->{value}; }
256 } 324 }
257} 325}
258{ package label; # pick up labels, which end with : 326{ package label; # pick up labels, which end with :
@@ -261,37 +329,63 @@ my $current_function;
261 local *line = shift; 329 local *line = shift;
262 undef $ret; 330 undef $ret;
263 331
264 if ($line =~ /(^[\.\w]+\:)/) { 332 if ($line =~ /(^[\.\w]+)\:/) {
265 $self->{value} = $1; 333 $self->{value} = $1;
266 $ret = $self; 334 $ret = $self;
267 $line = substr($line,@+[0]); $line =~ s/^\s+//; 335 $line = substr($line,@+[0]); $line =~ s/^\s+//;
268 336
269 $self->{value} =~ s/\.L/\$L/ if ($masm); 337 $self->{value} =~ s/^\.L/$decor/;
270 } 338 }
271 $ret; 339 $ret;
272 } 340 }
273 sub out { 341 sub out {
274 my $self = shift; 342 my $self = shift;
275 343
276 if (!$masm) { 344 if ($gas) {
277 $self->{value}; 345 my $func = ($globals{$self->{value}} or $self->{value}) . ":";
278 } elsif ($self->{value} ne "$current_function->{name}:") { 346 if ($win64 &&
279 $self->{value}; 347 $current_function->{name} eq $self->{value} &&
280 } elsif ($current_function->{abi} eq "svr4") { 348 $current_function->{abi} eq "svr4") {
281 my $func = "$current_function->{name} PROC\n". 349 $func .= "\n";
282 " mov QWORD PTR 8[rsp],rdi\t;WIN64 prologue\n". 350 $func .= " movq %rdi,8(%rsp)\n";
283 " mov QWORD PTR 16[rsp],rsi\n"; 351 $func .= " movq %rsi,16(%rsp)\n";
352 $func .= " movq %rsp,%rax\n";
353 $func .= "${decor}SEH_begin_$current_function->{name}:\n";
354 my $narg = $current_function->{narg};
355 $narg=6 if (!defined($narg));
356 $func .= " movq %rcx,%rdi\n" if ($narg>0);
357 $func .= " movq %rdx,%rsi\n" if ($narg>1);
358 $func .= " movq %r8,%rdx\n" if ($narg>2);
359 $func .= " movq %r9,%rcx\n" if ($narg>3);
360 $func .= " movq 40(%rsp),%r8\n" if ($narg>4);
361 $func .= " movq 48(%rsp),%r9\n" if ($narg>5);
362 }
363 $func;
364 } elsif ($self->{value} ne "$current_function->{name}") {
365 $self->{value} .= ":" if ($masm && $ret!~m/^\$/);
366 $self->{value} . ":";
367 } elsif ($win64 && $current_function->{abi} eq "svr4") {
368 my $func = "$current_function->{name}" .
369 ($nasm ? ":" : "\tPROC $current_function->{scope}") .
370 "\n";
371 $func .= " mov QWORD${PTR}[8+rsp],rdi\t;WIN64 prologue\n";
372 $func .= " mov QWORD${PTR}[16+rsp],rsi\n";
373 $func .= " mov rax,rsp\n";
374 $func .= "${decor}SEH_begin_$current_function->{name}:";
375 $func .= ":" if ($masm);
376 $func .= "\n";
284 my $narg = $current_function->{narg}; 377 my $narg = $current_function->{narg};
285 $narg=6 if (!defined($narg)); 378 $narg=6 if (!defined($narg));
286 $func .= " mov rdi,rcx\n" if ($narg>0); 379 $func .= " mov rdi,rcx\n" if ($narg>0);
287 $func .= " mov rsi,rdx\n" if ($narg>1); 380 $func .= " mov rsi,rdx\n" if ($narg>1);
288 $func .= " mov rdx,r8\n" if ($narg>2); 381 $func .= " mov rdx,r8\n" if ($narg>2);
289 $func .= " mov rcx,r9\n" if ($narg>3); 382 $func .= " mov rcx,r9\n" if ($narg>3);
290 $func .= " mov r8,QWORD PTR 40[rsp]\n" if ($narg>4); 383 $func .= " mov r8,QWORD${PTR}[40+rsp]\n" if ($narg>4);
291 $func .= " mov r9,QWORD PTR 48[rsp]\n" if ($narg>5); 384 $func .= " mov r9,QWORD${PTR}[48+rsp]\n" if ($narg>5);
292 $func .= "\n"; 385 $func .= "\n";
293 } else { 386 } else {
294 "$current_function->{name} PROC"; 387 "$current_function->{name}".
388 ($nasm ? ":" : "\tPROC $current_function->{scope}");
295 } 389 }
296 } 390 }
297} 391}
@@ -306,13 +400,19 @@ my $current_function;
306 $ret = $self; 400 $ret = $self;
307 $line = substr($line,@+[0]); $line =~ s/^\s+//; 401 $line = substr($line,@+[0]); $line =~ s/^\s+//;
308 402
309 $self->{value} =~ s/\.L/\$L/g if ($masm); 403 $self->{value} =~ s/\@PLT// if (!$elf);
404 $self->{value} =~ s/([_a-z][_a-z0-9]*)/$globals{$1} or $1/gei;
405 $self->{value} =~ s/\.L/$decor/g;
310 } 406 }
311 $ret; 407 $ret;
312 } 408 }
313 sub out { 409 sub out {
314 my $self = shift; 410 my $self = shift;
315 $self->{value}; 411 if ($nasm && opcode->mnemonic()=~m/^j/) {
412 "NEAR ".$self->{value};
413 } else {
414 $self->{value};
415 }
316 } 416 }
317} 417}
318{ package directive; # pick up directives, which start with . 418{ package directive; # pick up directives, which start with .
@@ -332,89 +432,181 @@ my $current_function;
332 "%r14"=>0x01358d4c, "%r15"=>0x013d8d4c ); 432 "%r14"=>0x01358d4c, "%r15"=>0x013d8d4c );
333 433
334 if ($line =~ /^\s*(\.\w+)/) { 434 if ($line =~ /^\s*(\.\w+)/) {
335 if (!$masm) {
336 $self->{value} = $1;
337 $line =~ s/\@abi\-omnipotent/\@function/;
338 $line =~ s/\@function.*/\@function/;
339 if ($line =~ /\.picmeup\s+(%r[\w]+)/i) {
340 $self->{value} = sprintf "\t.long\t0x%x,0x90000000",$opcode{$1};
341 } elsif ($line =~ /\.asciz\s+"(.*)"$/) {
342 $self->{value} = ".byte\t".join(",",unpack("C*",$1),0);
343 } elsif ($line =~ /\.extern/) {
344 $self->{value} = ""; # swallow extern
345 } else {
346 $self->{value} = $line;
347 }
348 $line = "";
349 return $self;
350 }
351
352 $dir = $1; 435 $dir = $1;
353 $ret = $self; 436 $ret = $self;
354 undef $self->{value}; 437 undef $self->{value};
355 $line = substr($line,@+[0]); $line =~ s/^\s+//; 438 $line = substr($line,@+[0]); $line =~ s/^\s+//;
439
356 SWITCH: for ($dir) { 440 SWITCH: for ($dir) {
357 /\.(text)/ 441 /\.picmeup/ && do { if ($line =~ /(%r[\w]+)/i) {
358 && do { my $v=undef; 442 $dir="\t.long";
359 $v="$current_segment\tENDS\n" if ($current_segment); 443 $line=sprintf "0x%x,0x90000000",$opcode{$1};
360 $current_segment = "_$1\$"; 444 }
361 $current_segment =~ tr/[a-z]/[A-Z]/; 445 last;
362 $v.="$current_segment\tSEGMENT "; 446 };
363 $v.=$masm>=$masmref ? "ALIGN(64)" : "PAGE"; 447 /\.global|\.globl|\.extern/
364 $v.=" 'CODE'"; 448 && do { $globals{$line} = $prefix . $line;
365 $self->{value} = $v; 449 $line = $globals{$line} if ($prefix);
366 last; 450 last;
367 }; 451 };
368 /\.extern/ && do { $self->{value} = "EXTRN\t".$line.":BYTE"; last; };
369 /\.globl/ && do { $self->{value} = "PUBLIC\t".$line; last; };
370 /\.type/ && do { ($sym,$type,$narg) = split(',',$line); 452 /\.type/ && do { ($sym,$type,$narg) = split(',',$line);
371 if ($type eq "\@function") { 453 if ($type eq "\@function") {
372 undef $current_function; 454 undef $current_function;
373 $current_function->{name} = $sym; 455 $current_function->{name} = $sym;
374 $current_function->{abi} = "svr4"; 456 $current_function->{abi} = "svr4";
375 $current_function->{narg} = $narg; 457 $current_function->{narg} = $narg;
458 $current_function->{scope} = defined($globals{$sym})?"PUBLIC":"PRIVATE";
376 } elsif ($type eq "\@abi-omnipotent") { 459 } elsif ($type eq "\@abi-omnipotent") {
377 undef $current_function; 460 undef $current_function;
378 $current_function->{name} = $sym; 461 $current_function->{name} = $sym;
462 $current_function->{scope} = defined($globals{$sym})?"PUBLIC":"PRIVATE";
463 }
464 $line =~ s/\@abi\-omnipotent/\@function/;
465 $line =~ s/\@function.*/\@function/;
466 last;
467 };
468 /\.asciz/ && do { if ($line =~ /^"(.*)"$/) {
469 $dir = ".byte";
470 $line = join(",",unpack("C*",$1),0);
379 } 471 }
380 last; 472 last;
381 }; 473 };
474 /\.rva|\.long|\.quad/
475 && do { $line =~ s/([_a-z][_a-z0-9]*)/$globals{$1} or $1/gei;
476 $line =~ s/\.L/$decor/g;
477 last;
478 };
479 }
480
481 if ($gas) {
482 $self->{value} = $dir . "\t" . $line;
483
484 if ($dir =~ /\.extern/) {
485 $self->{value} = ""; # swallow extern
486 } elsif (!$elf && $dir =~ /\.type/) {
487 $self->{value} = "";
488 $self->{value} = ".def\t" . ($globals{$1} or $1) . ";\t" .
489 (defined($globals{$1})?".scl 2;":".scl 3;") .
490 "\t.type 32;\t.endef"
491 if ($win64 && $line =~ /([^,]+),\@function/);
492 } elsif (!$elf && $dir =~ /\.size/) {
493 $self->{value} = "";
494 if (defined($current_function)) {
495 $self->{value} .= "${decor}SEH_end_$current_function->{name}:"
496 if ($win64 && $current_function->{abi} eq "svr4");
497 undef $current_function;
498 }
499 } elsif (!$elf && $dir =~ /\.align/) {
500 $self->{value} = ".p2align\t" . (log($line)/log(2));
501 } elsif ($dir eq ".section") {
502 $current_segment=$line;
503 if (!$elf && $current_segment eq ".init") {
504 if ($flavour eq "macosx") { $self->{value} = ".mod_init_func"; }
505 elsif ($flavour eq "mingw64") { $self->{value} = ".section\t.ctors"; }
506 }
507 } elsif ($dir =~ /\.(text|data)/) {
508 $current_segment=".$1";
509 }
510 $line = "";
511 return $self;
512 }
513
514 # non-gas case or nasm/masm
515 SWITCH: for ($dir) {
516 /\.text/ && do { my $v=undef;
517 if ($nasm) {
518 $v="section .text code align=64\n";
519 } else {
520 $v="$current_segment\tENDS\n" if ($current_segment);
521 $current_segment = ".text\$";
522 $v.="$current_segment\tSEGMENT ";
523 $v.=$masm>=$masmref ? "ALIGN(64)" : "PAGE";
524 $v.=" 'CODE'";
525 }
526 $self->{value} = $v;
527 last;
528 };
529 /\.data/ && do { my $v=undef;
530 if ($nasm) {
531 $v="section .data data align=8\n";
532 } else {
533 $v="$current_segment\tENDS\n" if ($current_segment);
534 $current_segment = "_DATA";
535 $v.="$current_segment\tSEGMENT";
536 }
537 $self->{value} = $v;
538 last;
539 };
540 /\.section/ && do { my $v=undef;
541 $line =~ s/([^,]*).*/$1/;
542 $line = ".CRT\$XCU" if ($line eq ".init");
543 if ($nasm) {
544 $v="section $line";
545 if ($line=~/\.([px])data/) {
546 $v.=" rdata align=";
547 $v.=$1 eq "p"? 4 : 8;
548 }
549 } else {
550 $v="$current_segment\tENDS\n" if ($current_segment);
551 $v.="$line\tSEGMENT";
552 if ($line=~/\.([px])data/) {
553 $v.=" READONLY";
554 $v.=" ALIGN(".($1 eq "p" ? 4 : 8).")" if ($masm>=$masmref);
555 }
556 }
557 $current_segment = $line;
558 $self->{value} = $v;
559 last;
560 };
561 /\.extern/ && do { $self->{value} = "EXTERN\t".$line;
562 $self->{value} .= ":NEAR" if ($masm);
563 last;
564 };
565 /\.globl|.global/
566 && do { $self->{value} = $masm?"PUBLIC":"global";
567 $self->{value} .= "\t".$line;
568 last;
569 };
382 /\.size/ && do { if (defined($current_function)) { 570 /\.size/ && do { if (defined($current_function)) {
383 $self->{value}="$current_function->{name}\tENDP"; 571 undef $self->{value};
572 if ($current_function->{abi} eq "svr4") {
573 $self->{value}="${decor}SEH_end_$current_function->{name}:";
574 $self->{value}.=":\n" if($masm);
575 }
576 $self->{value}.="$current_function->{name}\tENDP" if($masm);
384 undef $current_function; 577 undef $current_function;
385 } 578 }
386 last; 579 last;
387 }; 580 };
388 /\.align/ && do { $self->{value} = "ALIGN\t".$line; last; }; 581 /\.align/ && do { $self->{value} = "ALIGN\t".$line; last; };
389 /\.(byte|value|long|quad)/ 582 /\.(value|long|rva|quad)/
390 && do { my @arr = split(',',$line); 583 && do { my $sz = substr($1,0,1);
391 my $sz = substr($1,0,1); 584 my @arr = split(/,\s*/,$line);
392 my $last = pop(@arr); 585 my $last = pop(@arr);
393 my $conv = sub { my $var=shift; 586 my $conv = sub { my $var=shift;
394 if ($var=~s/0x([0-9a-f]+)/0$1h/i) { $var; } 587 $var=~s/^(0b[0-1]+)/oct($1)/eig;
395 else { sprintf"0%Xh",$var; } 588 $var=~s/^0x([0-9a-f]+)/0$1h/ig if ($masm);
589 if ($sz eq "D" && ($current_segment=~/.[px]data/ || $dir eq ".rva"))
590 { $var=~s/([_a-z\$\@][_a-z0-9\$\@]*)/$nasm?"$1 wrt ..imagebase":"imagerel $1"/egi; }
591 $var;
396 }; 592 };
397 593
398 $sz =~ tr/bvlq/BWDQ/; 594 $sz =~ tr/bvlrq/BWDDQ/;
399 $self->{value} = "\tD$sz\t"; 595 $self->{value} = "\tD$sz\t";
400 for (@arr) { $self->{value} .= &$conv($_).","; } 596 for (@arr) { $self->{value} .= &$conv($_).","; }
401 $self->{value} .= &$conv($last); 597 $self->{value} .= &$conv($last);
402 last; 598 last;
403 }; 599 };
404 /\.picmeup/ && do { $self->{value} = sprintf"\tDD\t 0%Xh,090000000h",$opcode{$line}; 600 /\.byte/ && do { my @str=split(/,\s*/,$line);
405 last; 601 map(s/(0b[0-1]+)/oct($1)/eig,@str);
406 }; 602 map(s/0x([0-9a-f]+)/0$1h/ig,@str) if ($masm);
407 /\.asciz/ && do { if ($line =~ /^"(.*)"$/) { 603 while ($#str>15) {
408 my @str=unpack("C*",$1);
409 push @str,0;
410 while ($#str>15) {
411 $self->{value}.="DB\t"
412 .join(",",@str[0..15])."\n";
413 foreach (0..15) { shift @str; }
414 }
415 $self->{value}.="DB\t" 604 $self->{value}.="DB\t"
416 .join(",",@str) if (@str); 605 .join(",",@str[0..15])."\n";
606 foreach (0..15) { shift @str; }
417 } 607 }
608 $self->{value}.="DB\t"
609 .join(",",@str) if (@str);
418 last; 610 last;
419 }; 611 };
420 } 612 }
@@ -429,6 +621,15 @@ my $current_function;
429 } 621 }
430} 622}
431 623
624if ($nasm) {
625 print <<___;
626default rel
627___
628} elsif ($masm) {
629 print <<___;
630OPTION DOTNAME
631___
632}
432while($line=<>) { 633while($line=<>) {
433 634
434 chomp($line); 635 chomp($line);
@@ -439,43 +640,42 @@ while($line=<>) {
439 640
440 undef $label; 641 undef $label;
441 undef $opcode; 642 undef $opcode;
442 undef $dst;
443 undef $src;
444 undef $sz; 643 undef $sz;
644 undef @args;
445 645
446 if ($label=label->re(\$line)) { print $label->out(); } 646 if ($label=label->re(\$line)) { print $label->out(); }
447 647
448 if (directive->re(\$line)) { 648 if (directive->re(\$line)) {
449 printf "%s",directive->out(); 649 printf "%s",directive->out();
450 } elsif ($opcode=opcode->re(\$line)) { ARGUMENT: { 650 } elsif ($opcode=opcode->re(\$line)) { ARGUMENT: while (1) {
451 651 my $arg;
452 if ($src=register->re(\$line)) { opcode->size($src->size()); }
453 elsif ($src=const->re(\$line)) { }
454 elsif ($src=ea->re(\$line)) { }
455 elsif ($src=expr->re(\$line)) { }
456 652
457 last ARGUMENT if ($line !~ /^,/); 653 if ($arg=register->re(\$line)) { opcode->size($arg->size()); }
654 elsif ($arg=const->re(\$line)) { }
655 elsif ($arg=ea->re(\$line)) { }
656 elsif ($arg=expr->re(\$line)) { }
657 else { last ARGUMENT; }
458 658
459 $line = substr($line,1); $line =~ s/^\s+//; 659 push @args,$arg;
460 660
461 if ($dst=register->re(\$line)) { opcode->size($dst->size()); } 661 last ARGUMENT if ($line !~ /^,/);
462 elsif ($dst=const->re(\$line)) { }
463 elsif ($dst=ea->re(\$line)) { }
464 662
663 $line =~ s/^,\s*//;
465 } # ARGUMENT: 664 } # ARGUMENT:
466 665
467 $sz=opcode->size(); 666 $sz=opcode->size();
468 667
469 if (defined($dst)) { 668 if ($#args>=0) {
470 if (!$masm) { 669 my $insn;
471 printf "\t%s\t%s,%s", $opcode->out($dst->size()), 670 if ($gas) {
472 $src->out($sz),$dst->out($sz); 671 $insn = $opcode->out($#args>=1?$args[$#args]->size():$sz);
473 } else { 672 } else {
474 printf "\t%s\t%s,%s", $opcode->out(), 673 $insn = $opcode->out();
475 $dst->out($sz),$src->out($sz); 674 $insn .= $sz if (map($_->out() =~ /x?mm/,@args));
675 @args = reverse(@args);
676 undef $sz if ($nasm && $opcode->mnemonic() eq "lea");
476 } 677 }
477 } elsif (defined($src)) { 678 printf "\t%s\t%s",$insn,join(",",map($_->out($sz),@args));
478 printf "\t%s\t%s",$opcode->out(),$src->out($sz);
479 } else { 679 } else {
480 printf "\t%s",$opcode->out(); 680 printf "\t%s",$opcode->out();
481 } 681 }
@@ -484,11 +684,12 @@ while($line=<>) {
484 print $line,"\n"; 684 print $line,"\n";
485} 685}
486 686
487print "\n$current_segment\tENDS\nEND\n" if ($masm); 687print "\n$current_segment\tENDS\n" if ($current_segment && $masm);
688print "END\n" if ($masm);
488 689
489close STDOUT; 690close STDOUT;
490 691
491################################################# 692 #################################################
492# Cross-reference x86_64 ABI "card" 693# Cross-reference x86_64 ABI "card"
493# 694#
494# Unix Win64 695# Unix Win64
@@ -552,3 +753,161 @@ close STDOUT;
552# movq 16(%rsp),%rsi 753# movq 16(%rsp),%rsi
553# endif 754# endif
554# ret 755# ret
756#
757 #################################################
758# Win64 SEH, Structured Exception Handling.
759#
760# Unlike on Unix systems(*) lack of Win64 stack unwinding information
761# has undesired side-effect at run-time: if an exception is raised in
762# assembler subroutine such as those in question (basically we're
763# referring to segmentation violations caused by malformed input
764# parameters), the application is briskly terminated without invoking
765# any exception handlers, most notably without generating memory dump
766# or any user notification whatsoever. This poses a problem. It's
767# possible to address it by registering custom language-specific
768# handler that would restore processor context to the state at
769# subroutine entry point and return "exception is not handled, keep
770# unwinding" code. Writing such handler can be a challenge... But it's
771# doable, though requires certain coding convention. Consider following
772# snippet:
773#
774# .type function,@function
775# function:
776# movq %rsp,%rax # copy rsp to volatile register
777# pushq %r15 # save non-volatile registers
778# pushq %rbx
779# pushq %rbp
780# movq %rsp,%r11
781# subq %rdi,%r11 # prepare [variable] stack frame
782# andq $-64,%r11
783# movq %rax,0(%r11) # check for exceptions
784# movq %r11,%rsp # allocate [variable] stack frame
785# movq %rax,0(%rsp) # save original rsp value
786# magic_point:
787# ...
788# movq 0(%rsp),%rcx # pull original rsp value
789# movq -24(%rcx),%rbp # restore non-volatile registers
790# movq -16(%rcx),%rbx
791# movq -8(%rcx),%r15
792# movq %rcx,%rsp # restore original rsp
793# ret
794# .size function,.-function
795#
796# The key is that up to magic_point copy of original rsp value remains
797# in chosen volatile register and no non-volatile register, except for
798# rsp, is modified. While past magic_point rsp remains constant till
799# the very end of the function. In this case custom language-specific
800# exception handler would look like this:
801#
802# EXCEPTION_DISPOSITION handler (EXCEPTION_RECORD *rec,ULONG64 frame,
803# CONTEXT *context,DISPATCHER_CONTEXT *disp)
804# { ULONG64 *rsp = (ULONG64 *)context->Rax;
805# if (context->Rip >= magic_point)
806# { rsp = ((ULONG64 **)context->Rsp)[0];
807# context->Rbp = rsp[-3];
808# context->Rbx = rsp[-2];
809# context->R15 = rsp[-1];
810# }
811# context->Rsp = (ULONG64)rsp;
812# context->Rdi = rsp[1];
813# context->Rsi = rsp[2];
814#
815# memcpy (disp->ContextRecord,context,sizeof(CONTEXT));
816# RtlVirtualUnwind(UNW_FLAG_NHANDLER,disp->ImageBase,
817# dips->ControlPc,disp->FunctionEntry,disp->ContextRecord,
818# &disp->HandlerData,&disp->EstablisherFrame,NULL);
819# return ExceptionContinueSearch;
820# }
821#
822# It's appropriate to implement this handler in assembler, directly in
823# function's module. In order to do that one has to know members'
824# offsets in CONTEXT and DISPATCHER_CONTEXT structures and some constant
825# values. Here they are:
826#
827# CONTEXT.Rax 120
828# CONTEXT.Rcx 128
829# CONTEXT.Rdx 136
830# CONTEXT.Rbx 144
831# CONTEXT.Rsp 152
832# CONTEXT.Rbp 160
833# CONTEXT.Rsi 168
834# CONTEXT.Rdi 176
835# CONTEXT.R8 184
836# CONTEXT.R9 192
837# CONTEXT.R10 200
838# CONTEXT.R11 208
839# CONTEXT.R12 216
840# CONTEXT.R13 224
841# CONTEXT.R14 232
842# CONTEXT.R15 240
843# CONTEXT.Rip 248
844# CONTEXT.Xmm6 512
845# sizeof(CONTEXT) 1232
846# DISPATCHER_CONTEXT.ControlPc 0
847# DISPATCHER_CONTEXT.ImageBase 8
848# DISPATCHER_CONTEXT.FunctionEntry 16
849# DISPATCHER_CONTEXT.EstablisherFrame 24
850# DISPATCHER_CONTEXT.TargetIp 32
851# DISPATCHER_CONTEXT.ContextRecord 40
852# DISPATCHER_CONTEXT.LanguageHandler 48
853# DISPATCHER_CONTEXT.HandlerData 56
854# UNW_FLAG_NHANDLER 0
855# ExceptionContinueSearch 1
856#
857# In order to tie the handler to the function one has to compose
858# couple of structures: one for .xdata segment and one for .pdata.
859#
860# UNWIND_INFO structure for .xdata segment would be
861#
862# function_unwind_info:
863# .byte 9,0,0,0
864# .rva handler
865#
866# This structure designates exception handler for a function with
867# zero-length prologue, no stack frame or frame register.
868#
869# To facilitate composing of .pdata structures, auto-generated "gear"
870# prologue copies rsp value to rax and denotes next instruction with
871# .LSEH_begin_{function_name} label. This essentially defines the SEH
872# styling rule mentioned in the beginning. Position of this label is
873# chosen in such manner that possible exceptions raised in the "gear"
874# prologue would be accounted to caller and unwound from latter's frame.
875# End of function is marked with respective .LSEH_end_{function_name}
876# label. To summarize, .pdata segment would contain
877#
878# .rva .LSEH_begin_function
879# .rva .LSEH_end_function
880# .rva function_unwind_info
881#
882# Reference to functon_unwind_info from .xdata segment is the anchor.
883# In case you wonder why references are 32-bit .rvas and not 64-bit
884# .quads. References put into these two segments are required to be
885# *relative* to the base address of the current binary module, a.k.a.
886# image base. No Win64 module, be it .exe or .dll, can be larger than
887# 2GB and thus such relative references can be and are accommodated in
888# 32 bits.
889#
890# Having reviewed the example function code, one can argue that "movq
891# %rsp,%rax" above is redundant. It is not! Keep in mind that on Unix
892# rax would contain an undefined value. If this "offends" you, use
893# another register and refrain from modifying rax till magic_point is
894# reached, i.e. as if it was a non-volatile register. If more registers
895# are required prior [variable] frame setup is completed, note that
896# nobody says that you can have only one "magic point." You can
897# "liberate" non-volatile registers by denoting last stack off-load
898# instruction and reflecting it in finer grade unwind logic in handler.
899# After all, isn't it why it's called *language-specific* handler...
900#
901# Attentive reader can notice that exceptions would be mishandled in
902# auto-generated "gear" epilogue. Well, exception effectively can't
903# occur there, because if memory area used by it was subject to
904# segmentation violation, then it would be raised upon call to the
905# function (and as already mentioned be accounted to caller, which is
906# not a problem). If you're still not comfortable, then define tail
907# "magic point" just prior ret instruction and have handler treat it...
908#
909# (*) Note that we're talking about run-time, not debug-time. Lack of
910# unwind information makes debugging hard on both Windows and
911# Unix. "Unlike" referes to the fact that on Unix signal handler
912# will always be invoked, core dumped and appropriate exit code
913# returned to parent (for user notification).
diff --git a/src/lib/libcrypto/perlasm/x86asm.pl b/src/lib/libcrypto/perlasm/x86asm.pl
index 5979122158..28080caaa6 100644
--- a/src/lib/libcrypto/perlasm/x86asm.pl
+++ b/src/lib/libcrypto/perlasm/x86asm.pl
@@ -1,130 +1,207 @@
1#!/usr/local/bin/perl 1#!/usr/bin/env perl
2 2
3# require 'x86asm.pl'; 3# require 'x86asm.pl';
4# &asm_init("cpp","des-586.pl"); 4# &asm_init(<flavor>,"des-586.pl"[,$i386only]);
5# XXX 5# &function_begin("foo");
6# XXX 6# ...
7# main'asm_finish 7# &function_end("foo");
8 8# &asm_finish
9sub main'asm_finish 9
10 { 10$out=();
11 &file_end(); 11$i386=0;
12 &asm_finish_cpp() if $cpp; 12
13 print &asm_get_output(); 13# AUTOLOAD is this context has quite unpleasant side effect, namely
14 } 14# that typos in function calls effectively go to assembler output,
15 15# but on the pros side we don't have to implement one subroutine per
16sub main'asm_init 16# each opcode...
17 { 17sub ::AUTOLOAD
18 ($type,$fn,$i386)=@_; 18{ my $opcode = $AUTOLOAD;
19 $filename=$fn; 19
20 20 die "more than 4 arguments passed to $opcode" if ($#_>3);
21 $elf=$cpp=$coff=$aout=$win32=$netware=$mwerks=0; 21
22 if ( ($type eq "elf")) 22 $opcode =~ s/.*:://;
23 { $elf=1; require "x86unix.pl"; } 23 if ($opcode =~ /^push/) { $stack+=4; }
24 elsif ( ($type eq "a.out")) 24 elsif ($opcode =~ /^pop/) { $stack-=4; }
25 { $aout=1; require "x86unix.pl"; } 25
26 elsif ( ($type eq "coff" or $type eq "gaswin")) 26 &generic($opcode,@_) or die "undefined subroutine \&$AUTOLOAD";
27 { $coff=1; require "x86unix.pl"; } 27}
28 elsif ( ($type eq "cpp")) 28
29 { $cpp=1; require "x86unix.pl"; } 29sub ::emit
30 elsif ( ($type eq "win32")) 30{ my $opcode=shift;
31 { $win32=1; require "x86ms.pl"; } 31
32 elsif ( ($type eq "win32n")) 32 if ($#_==-1) { push(@out,"\t$opcode\n"); }
33 { $win32=1; require "x86nasm.pl"; } 33 else { push(@out,"\t$opcode\t".join(',',@_)."\n"); }
34 elsif ( ($type eq "nw-nasm")) 34}
35 { $netware=1; require "x86nasm.pl"; } 35
36 elsif ( ($type eq "nw-mwasm")) 36sub ::LB
37 { $netware=1; $mwerks=1; require "x86nasm.pl"; } 37{ $_[0] =~ m/^e?([a-d])x$/o or die "$_[0] does not have a 'low byte'";
38 else 38 $1."l";
39 { 39}
40 print STDERR <<"EOF"; 40sub ::HB
41{ $_[0] =~ m/^e?([a-d])x$/o or die "$_[0] does not have a 'high byte'";
42 $1."h";
43}
44sub ::stack_push{ my $num=$_[0]*4; $stack+=$num; &sub("esp",$num); }
45sub ::stack_pop { my $num=$_[0]*4; $stack-=$num; &add("esp",$num); }
46sub ::blindpop { &pop($_[0]); $stack+=4; }
47sub ::wparam { &DWP($stack+4*$_[0],"esp"); }
48sub ::swtmp { &DWP(4*$_[0],"esp"); }
49
50sub ::bswap
51{ if ($i386) # emulate bswap for i386
52 { &comment("bswap @_");
53 &xchg(&HB(@_),&LB(@_));
54 &ror (@_,16);
55 &xchg(&HB(@_),&LB(@_));
56 }
57 else
58 { &generic("bswap",@_); }
59}
60# These are made-up opcodes introduced over the years essentially
61# by ignorance, just alias them to real ones...
62sub ::movb { &mov(@_); }
63sub ::xorb { &xor(@_); }
64sub ::rotl { &rol(@_); }
65sub ::rotr { &ror(@_); }
66sub ::exch { &xchg(@_); }
67sub ::halt { &hlt; }
68sub ::movz { &movzx(@_); }
69sub ::pushf { &pushfd; }
70sub ::popf { &popfd; }
71
72# 3 argument instructions
73sub ::movq
74{ my($p1,$p2,$optimize)=@_;
75
76 if ($optimize && $p1=~/^mm[0-7]$/ && $p2=~/^mm[0-7]$/)
77 # movq between mmx registers can sink Intel CPUs
78 { &::pshufw($p1,$p2,0xe4); }
79 else
80 { &::generic("movq",@_); }
81}
82
83# label management
84$lbdecor="L"; # local label decoration, set by package
85$label="000";
86
87sub ::islabel # see is argument is a known label
88{ my $i;
89 foreach $i (values %label) { return $i if ($i eq $_[0]); }
90 $label{$_[0]}; # can be undef
91}
92
93sub ::label # instantiate a function-scope label
94{ if (!defined($label{$_[0]}))
95 { $label{$_[0]}="${lbdecor}${label}${_[0]}"; $label++; }
96 $label{$_[0]};
97}
98
99sub ::LABEL # instantiate a file-scope label
100{ $label{$_[0]}=$_[1] if (!defined($label{$_[0]}));
101 $label{$_[0]};
102}
103
104sub ::static_label { &::LABEL($_[0],$lbdecor.$_[0]); }
105
106sub ::set_label_B { push(@out,"@_:\n"); }
107sub ::set_label
108{ my $label=&::label($_[0]);
109 &::align($_[1]) if ($_[1]>1);
110 &::set_label_B($label);
111 $label;
112}
113
114sub ::wipe_labels # wipes function-scope labels
115{ foreach $i (keys %label)
116 { delete $label{$i} if ($label{$i} =~ /^\Q${lbdecor}\E[0-9]{3}/); }
117}
118
119# subroutine management
120sub ::function_begin
121{ &function_begin_B(@_);
122 $stack=4;
123 &push("ebp");
124 &push("ebx");
125 &push("esi");
126 &push("edi");
127}
128
129sub ::function_end
130{ &pop("edi");
131 &pop("esi");
132 &pop("ebx");
133 &pop("ebp");
134 &ret();
135 &function_end_B(@_);
136 $stack=0;
137 &wipe_labels();
138}
139
140sub ::function_end_A
141{ &pop("edi");
142 &pop("esi");
143 &pop("ebx");
144 &pop("ebp");
145 &ret();
146 $stack+=16; # readjust esp as if we didn't pop anything
147}
148
149sub ::asciz
150{ my @str=unpack("C*",shift);
151 push @str,0;
152 while ($#str>15) {
153 &data_byte(@str[0..15]);
154 foreach (0..15) { shift @str; }
155 }
156 &data_byte(@str) if (@str);
157}
158
159sub ::asm_finish
160{ &file_end();
161 print @out;
162}
163
164sub ::asm_init
165{ my ($type,$fn,$cpu)=@_;
166
167 $filename=$fn;
168 $i386=$cpu;
169
170 $elf=$cpp=$coff=$aout=$macosx=$win32=$netware=$mwerks=0;
171 if (($type eq "elf"))
172 { $elf=1; require "x86gas.pl"; }
173 elsif (($type eq "a\.out"))
174 { $aout=1; require "x86gas.pl"; }
175 elsif (($type eq "coff" or $type eq "gaswin"))
176 { $coff=1; require "x86gas.pl"; }
177 elsif (($type eq "win32n"))
178 { $win32=1; require "x86nasm.pl"; }
179 elsif (($type eq "nw-nasm"))
180 { $netware=1; require "x86nasm.pl"; }
181 #elsif (($type eq "nw-mwasm"))
182 #{ $netware=1; $mwerks=1; require "x86nasm.pl"; }
183 elsif (($type eq "win32"))
184 { $win32=1; require "x86masm.pl"; }
185 elsif (($type eq "macosx"))
186 { $aout=1; $macosx=1; require "x86gas.pl"; }
187 else
188 { print STDERR <<"EOF";
41Pick one target type from 189Pick one target type from
42 elf - Linux, FreeBSD, Solaris x86, etc. 190 elf - Linux, FreeBSD, Solaris x86, etc.
43 a.out - OpenBSD, DJGPP, etc. 191 a.out - DJGPP, elder OpenBSD, etc.
44 coff - GAS/COFF such as Win32 targets 192 coff - GAS/COFF such as Win32 targets
45 win32 - Windows 95/Windows NT
46 win32n - Windows 95/Windows NT NASM format 193 win32n - Windows 95/Windows NT NASM format
47 nw-nasm - NetWare NASM format 194 nw-nasm - NetWare NASM format
48 nw-mwasm- NetWare Metrowerks Assembler 195 macosx - Mac OS X
49EOF 196EOF
50 exit(1); 197 exit(1);
51 } 198 }
52 199
53 $pic=0; 200 $pic=0;
54 for (@ARGV) { $pic=1 if (/\-[fK]PIC/i); } 201 for (@ARGV) { $pic=1 if (/\-[fK]PIC/i); }
55 202
56 &asm_init_output(); 203 $filename =~ s/\.pl$//;
57 204 &file($filename);
58&comment("Don't even think of reading this code"); 205}
59&comment("It was automatically generated by $filename");
60&comment("Which is a perl program used to generate the x86 assember for");
61&comment("any of ELF, a.out, COFF, Win32, ...");
62&comment("eric <eay\@cryptsoft.com>");
63&comment("");
64
65 $filename =~ s/\.pl$//;
66 &file($filename);
67 }
68
69sub asm_finish_cpp
70 {
71 return unless $cpp;
72
73 local($tmp,$i);
74 foreach $i (&get_labels())
75 {
76 $tmp.="#define $i _$i\n";
77 }
78 print <<"EOF";
79/* Run the C pre-processor over this file with one of the following defined
80 * ELF - elf object files,
81 * OUT - a.out object files,
82 * BSDI - BSDI style a.out object files
83 * SOL - Solaris style elf
84 */
85
86#define TYPE(a,b) .type a,b
87#define SIZE(a,b) .size a,b
88
89#if defined(OUT) || (defined(BSDI) && !defined(ELF))
90$tmp
91#endif
92
93#ifdef OUT
94#define OK 1
95#define ALIGN 4
96#if defined(__CYGWIN__) || defined(__DJGPP__) || (__MINGW32__)
97#undef SIZE
98#undef TYPE
99#define SIZE(a,b)
100#define TYPE(a,b) .def a; .scl 2; .type 32; .endef
101#endif /* __CYGWIN || __DJGPP */
102#endif
103
104#if defined(BSDI) && !defined(ELF)
105#define OK 1
106#define ALIGN 4
107#undef SIZE
108#undef TYPE
109#define SIZE(a,b)
110#define TYPE(a,b)
111#endif
112
113#if defined(ELF) || defined(SOL)
114#define OK 1
115#define ALIGN 16
116#endif
117
118#ifndef OK
119You need to define one of
120ELF - elf systems - linux-elf, NetBSD and DG-UX
121OUT - a.out systems - linux-a.out and FreeBSD
122SOL - solaris systems, which are elf with strange comment lines
123BSDI - a.out with a very primative version of as.
124#endif
125
126/* Let the Assembler begin :-) */
127EOF
128 }
129 206
1301; 2071;
diff --git a/src/lib/libcrypto/perlasm/x86gas.pl b/src/lib/libcrypto/perlasm/x86gas.pl
new file mode 100644
index 0000000000..6eab727fd4
--- /dev/null
+++ b/src/lib/libcrypto/perlasm/x86gas.pl
@@ -0,0 +1,247 @@
1#!/usr/bin/env perl
2
3package x86gas;
4
5*out=\@::out;
6
7$::lbdecor=$::aout?"L":".L"; # local label decoration
8$nmdecor=($::aout or $::coff)?"_":""; # external name decoration
9
10$initseg="";
11
12$align=16;
13$align=log($align)/log(2) if ($::aout);
14$com_start="#" if ($::aout or $::coff);
15
16sub opsize()
17{ my $reg=shift;
18 if ($reg =~ m/^%e/o) { "l"; }
19 elsif ($reg =~ m/^%[a-d][hl]$/o) { "b"; }
20 elsif ($reg =~ m/^%[xm]/o) { undef; }
21 else { "w"; }
22}
23
24# swap arguments;
25# expand opcode with size suffix;
26# prefix numeric constants with $;
27sub ::generic
28{ my($opcode,@arg)=@_;
29 my($suffix,$dst,$src);
30
31 @arg=reverse(@arg);
32
33 for (@arg)
34 { s/^(\*?)(e?[a-dsixphl]{2})$/$1%$2/o; # gp registers
35 s/^([xy]?mm[0-7])$/%$1/o; # xmm/mmx registers
36 s/^(\-?[0-9]+)$/\$$1/o; # constants
37 s/^(\-?0x[0-9a-f]+)$/\$$1/o; # constants
38 }
39
40 $dst = $arg[$#arg] if ($#arg>=0);
41 $src = $arg[$#arg-1] if ($#arg>=1);
42 if ($dst =~ m/^%/o) { $suffix=&opsize($dst); }
43 elsif ($src =~ m/^%/o) { $suffix=&opsize($src); }
44 else { $suffix="l"; }
45 undef $suffix if ($dst =~ m/^%[xm]/o || $src =~ m/^%[xm]/o);
46
47 if ($#_==0) { &::emit($opcode); }
48 elsif ($opcode =~ m/^j/o && $#_==1) { &::emit($opcode,@arg); }
49 elsif ($opcode eq "call" && $#_==1) { &::emit($opcode,@arg); }
50 elsif ($opcode =~ m/^set/&& $#_==1) { &::emit($opcode,@arg); }
51 else { &::emit($opcode.$suffix,@arg);}
52
53 1;
54}
55#
56# opcodes not covered by ::generic above, mostly inconsistent namings...
57#
58sub ::movzx { &::movzb(@_); }
59sub ::pushfd { &::pushfl; }
60sub ::popfd { &::popfl; }
61sub ::cpuid { &::emit(".byte\t0x0f,0xa2"); }
62sub ::rdtsc { &::emit(".byte\t0x0f,0x31"); }
63
64sub ::call { &::emit("call",(&::islabel($_[0]) or "$nmdecor$_[0]")); }
65sub ::call_ptr { &::generic("call","*$_[0]"); }
66sub ::jmp_ptr { &::generic("jmp","*$_[0]"); }
67
68*::bswap = sub { &::emit("bswap","%$_[0]"); } if (!$::i386);
69
70sub ::DWP
71{ my($addr,$reg1,$reg2,$idx)=@_;
72 my $ret="";
73
74 $addr =~ s/^\s+//;
75 # prepend global references with optional underscore
76 $addr =~ s/^([^\+\-0-9][^\+\-]*)/&::islabel($1) or "$nmdecor$1"/ige;
77
78 $reg1 = "%$reg1" if ($reg1);
79 $reg2 = "%$reg2" if ($reg2);
80
81 $ret .= $addr if (($addr ne "") && ($addr ne 0));
82
83 if ($reg2)
84 { $idx!= 0 or $idx=1;
85 $ret .= "($reg1,$reg2,$idx)";
86 }
87 elsif ($reg1)
88 { $ret .= "($reg1)"; }
89
90 $ret;
91}
92sub ::QWP { &::DWP(@_); }
93sub ::BP { &::DWP(@_); }
94sub ::BC { @_; }
95sub ::DWC { @_; }
96
97sub ::file
98{ push(@out,".file\t\"$_[0].s\"\n.text\n"); }
99
100sub ::function_begin_B
101{ my $func=shift;
102 my $global=($func !~ /^_/);
103 my $begin="${::lbdecor}_${func}_begin";
104
105 &::LABEL($func,$global?"$begin":"$nmdecor$func");
106 $func=$nmdecor.$func;
107
108 push(@out,".globl\t$func\n") if ($global);
109 if ($::coff)
110 { push(@out,".def\t$func;\t.scl\t".(3-$global).";\t.type\t32;\t.endef\n"); }
111 elsif (($::aout and !$::pic) or $::macosx)
112 { }
113 else
114 { push(@out,".type $func,\@function\n"); }
115 push(@out,".align\t$align\n");
116 push(@out,"$func:\n");
117 push(@out,"$begin:\n") if ($global);
118 $::stack=4;
119}
120
121sub ::function_end_B
122{ my $func=shift;
123 push(@out,".size\t$nmdecor$func,.-".&::LABEL($func)."\n") if ($::elf);
124 $::stack=0;
125 &::wipe_labels();
126}
127
128sub ::comment
129 {
130 if (!defined($com_start) or $::elf)
131 { # Regarding $::elf above...
132 # GNU and SVR4 as'es use different comment delimiters,
133 push(@out,"\n"); # so we just skip ELF comments...
134 return;
135 }
136 foreach (@_)
137 {
138 if (/^\s*$/)
139 { push(@out,"\n"); }
140 else
141 { push(@out,"\t$com_start $_ $com_end\n"); }
142 }
143 }
144
145sub ::external_label
146{ foreach(@_) { &::LABEL($_,$nmdecor.$_); } }
147
148sub ::public_label
149{ push(@out,".globl\t".&::LABEL($_[0],$nmdecor.$_[0])."\n"); }
150
151sub ::file_end
152{ if (grep {/\b${nmdecor}OPENSSL_ia32cap_P\b/i} @out) {
153 my $tmp=".comm\t${nmdecor}OPENSSL_ia32cap_P,4";
154 if ($::elf) { push (@out,"$tmp,4\n"); }
155 else { push (@out,"$tmp\n"); }
156 }
157 if ($::macosx)
158 { if (%non_lazy_ptr)
159 { push(@out,".section __IMPORT,__pointers,non_lazy_symbol_pointers\n");
160 foreach $i (keys %non_lazy_ptr)
161 { push(@out,"$non_lazy_ptr{$i}:\n.indirect_symbol\t$i\n.long\t0\n"); }
162 }
163 }
164 push(@out,$initseg) if ($initseg);
165}
166
167sub ::data_byte { push(@out,".byte\t".join(',',@_)."\n"); }
168sub ::data_word { push(@out,".long\t".join(',',@_)."\n"); }
169
170sub ::align
171{ my $val=$_[0],$p2,$i;
172 if ($::aout)
173 { for ($p2=0;$val!=0;$val>>=1) { $p2++; }
174 $val=$p2-1;
175 $val.=",0x90";
176 }
177 push(@out,".align\t$val\n");
178}
179
180sub ::picmeup
181{ my($dst,$sym,$base,$reflabel)=@_;
182
183 if ($::pic && ($::elf || $::aout))
184 { if (!defined($base))
185 { &::call(&::label("PIC_me_up"));
186 &::set_label("PIC_me_up");
187 &::blindpop($dst);
188 $base=$dst;
189 $reflabel=&::label("PIC_me_up");
190 }
191 if ($::macosx)
192 { my $indirect=&::static_label("$nmdecor$sym\$non_lazy_ptr");
193 &::mov($dst,&::DWP("$indirect-$reflabel",$base));
194 $non_lazy_ptr{"$nmdecor$sym"}=$indirect;
195 }
196 else
197 { &::lea($dst,&::DWP("_GLOBAL_OFFSET_TABLE_+[.-$reflabel]",
198 $base));
199 &::mov($dst,&::DWP("$sym\@GOT",$dst));
200 }
201 }
202 else
203 { &::lea($dst,&::DWP($sym)); }
204}
205
206sub ::initseg
207{ my $f=$nmdecor.shift;
208
209 if ($::elf)
210 { $initseg.=<<___;
211.section .init
212 call $f
213 jmp .Linitalign
214.align $align
215.Linitalign:
216___
217 }
218 elsif ($::coff)
219 { $initseg.=<<___; # applies to both Cygwin and Mingw
220.section .ctors
221.long $f
222___
223 }
224 elsif ($::macosx)
225 { $initseg.=<<___;
226.mod_init_func
227.align 2
228.long $f
229___
230 }
231 elsif ($::aout)
232 { my $ctor="${nmdecor}_GLOBAL_\$I\$$f";
233 $initseg.=".text\n";
234 $initseg.=".type $ctor,\@function\n" if ($::pic);
235 $initseg.=<<___; # OpenBSD way...
236.globl $ctor
237.align 2
238$ctor:
239 jmp $f
240___
241 }
242}
243
244sub ::dataseg
245{ push(@out,".data\n"); }
246
2471;
diff --git a/src/lib/libcrypto/pkcs12/p12_add.c b/src/lib/libcrypto/pkcs12/p12_add.c
index 1f3e378f5c..27ac5facfa 100644
--- a/src/lib/libcrypto/pkcs12/p12_add.c
+++ b/src/lib/libcrypto/pkcs12/p12_add.c
@@ -106,6 +106,7 @@ PKCS12_SAFEBAG *PKCS12_MAKE_SHKEYBAG(int pbe_nid, const char *pass,
106 PKCS8_PRIV_KEY_INFO *p8) 106 PKCS8_PRIV_KEY_INFO *p8)
107{ 107{
108 PKCS12_SAFEBAG *bag; 108 PKCS12_SAFEBAG *bag;
109 const EVP_CIPHER *pbe_ciph;
109 110
110 /* Set up the safe bag */ 111 /* Set up the safe bag */
111 if (!(bag = PKCS12_SAFEBAG_new())) { 112 if (!(bag = PKCS12_SAFEBAG_new())) {
@@ -114,8 +115,14 @@ PKCS12_SAFEBAG *PKCS12_MAKE_SHKEYBAG(int pbe_nid, const char *pass,
114 } 115 }
115 116
116 bag->type = OBJ_nid2obj(NID_pkcs8ShroudedKeyBag); 117 bag->type = OBJ_nid2obj(NID_pkcs8ShroudedKeyBag);
118
119 pbe_ciph = EVP_get_cipherbynid(pbe_nid);
120
121 if (pbe_ciph)
122 pbe_nid = -1;
123
117 if (!(bag->value.shkeybag = 124 if (!(bag->value.shkeybag =
118 PKCS8_encrypt(pbe_nid, NULL, pass, passlen, salt, saltlen, iter, 125 PKCS8_encrypt(pbe_nid, pbe_ciph, pass, passlen, salt, saltlen, iter,
119 p8))) { 126 p8))) {
120 PKCS12err(PKCS12_F_PKCS12_MAKE_SHKEYBAG, ERR_R_MALLOC_FAILURE); 127 PKCS12err(PKCS12_F_PKCS12_MAKE_SHKEYBAG, ERR_R_MALLOC_FAILURE);
121 return NULL; 128 return NULL;
@@ -164,6 +171,7 @@ PKCS7 *PKCS12_pack_p7encdata(int pbe_nid, const char *pass, int passlen,
164{ 171{
165 PKCS7 *p7; 172 PKCS7 *p7;
166 X509_ALGOR *pbe; 173 X509_ALGOR *pbe;
174 const EVP_CIPHER *pbe_ciph;
167 if (!(p7 = PKCS7_new())) { 175 if (!(p7 = PKCS7_new())) {
168 PKCS12err(PKCS12_F_PKCS12_PACK_P7ENCDATA, ERR_R_MALLOC_FAILURE); 176 PKCS12err(PKCS12_F_PKCS12_PACK_P7ENCDATA, ERR_R_MALLOC_FAILURE);
169 return NULL; 177 return NULL;
@@ -173,7 +181,15 @@ PKCS7 *PKCS12_pack_p7encdata(int pbe_nid, const char *pass, int passlen,
173 PKCS12_R_ERROR_SETTING_ENCRYPTED_DATA_TYPE); 181 PKCS12_R_ERROR_SETTING_ENCRYPTED_DATA_TYPE);
174 return NULL; 182 return NULL;
175 } 183 }
176 if (!(pbe = PKCS5_pbe_set(pbe_nid, iter, salt, saltlen))) { 184
185 pbe_ciph = EVP_get_cipherbynid(pbe_nid);
186
187 if (pbe_ciph)
188 pbe = PKCS5_pbe2_set(pbe_ciph, iter, salt, saltlen);
189 else
190 pbe = PKCS5_pbe_set(pbe_nid, iter, salt, saltlen);
191
192 if (!pbe) {
177 PKCS12err(PKCS12_F_PKCS12_PACK_P7ENCDATA, ERR_R_MALLOC_FAILURE); 193 PKCS12err(PKCS12_F_PKCS12_PACK_P7ENCDATA, ERR_R_MALLOC_FAILURE);
178 return NULL; 194 return NULL;
179 } 195 }
diff --git a/src/lib/libcrypto/pkcs12/p12_attr.c b/src/lib/libcrypto/pkcs12/p12_attr.c
index 68d6c5ad15..e4d9c25647 100644
--- a/src/lib/libcrypto/pkcs12/p12_attr.c
+++ b/src/lib/libcrypto/pkcs12/p12_attr.c
@@ -139,7 +139,7 @@ char *PKCS12_get_friendlyname(PKCS12_SAFEBAG *bag)
139 ASN1_TYPE *atype; 139 ASN1_TYPE *atype;
140 if (!(atype = PKCS12_get_attr(bag, NID_friendlyName))) return NULL; 140 if (!(atype = PKCS12_get_attr(bag, NID_friendlyName))) return NULL;
141 if (atype->type != V_ASN1_BMPSTRING) return NULL; 141 if (atype->type != V_ASN1_BMPSTRING) return NULL;
142 return uni2asc(atype->value.bmpstring->data, 142 return OPENSSL_uni2asc(atype->value.bmpstring->data,
143 atype->value.bmpstring->length); 143 atype->value.bmpstring->length);
144} 144}
145 145
diff --git a/src/lib/libcrypto/pkcs12/p12_crpt.c b/src/lib/libcrypto/pkcs12/p12_crpt.c
index f8b952e27e..b71d07b4d0 100644
--- a/src/lib/libcrypto/pkcs12/p12_crpt.c
+++ b/src/lib/libcrypto/pkcs12/p12_crpt.c
@@ -60,28 +60,10 @@
60#include "cryptlib.h" 60#include "cryptlib.h"
61#include <openssl/pkcs12.h> 61#include <openssl/pkcs12.h>
62 62
63/* PKCS#12 specific PBE functions */ 63/* PKCS#12 PBE algorithms now in static table */
64 64
65void PKCS12_PBE_add(void) 65void PKCS12_PBE_add(void)
66{ 66{
67#ifndef OPENSSL_NO_RC4
68EVP_PBE_alg_add(NID_pbe_WithSHA1And128BitRC4, EVP_rc4(), EVP_sha1(),
69 PKCS12_PBE_keyivgen);
70EVP_PBE_alg_add(NID_pbe_WithSHA1And40BitRC4, EVP_rc4_40(), EVP_sha1(),
71 PKCS12_PBE_keyivgen);
72#endif
73#ifndef OPENSSL_NO_DES
74EVP_PBE_alg_add(NID_pbe_WithSHA1And3_Key_TripleDES_CBC,
75 EVP_des_ede3_cbc(), EVP_sha1(), PKCS12_PBE_keyivgen);
76EVP_PBE_alg_add(NID_pbe_WithSHA1And2_Key_TripleDES_CBC,
77 EVP_des_ede_cbc(), EVP_sha1(), PKCS12_PBE_keyivgen);
78#endif
79#ifndef OPENSSL_NO_RC2
80EVP_PBE_alg_add(NID_pbe_WithSHA1And128BitRC2_CBC, EVP_rc2_cbc(),
81 EVP_sha1(), PKCS12_PBE_keyivgen);
82EVP_PBE_alg_add(NID_pbe_WithSHA1And40BitRC2_CBC, EVP_rc2_40_cbc(),
83 EVP_sha1(), PKCS12_PBE_keyivgen);
84#endif
85} 67}
86 68
87int PKCS12_PBE_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, int passlen, 69int PKCS12_PBE_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, int passlen,
diff --git a/src/lib/libcrypto/pkcs12/p12_crt.c b/src/lib/libcrypto/pkcs12/p12_crt.c
index 9522342fa5..96b131defa 100644
--- a/src/lib/libcrypto/pkcs12/p12_crt.c
+++ b/src/lib/libcrypto/pkcs12/p12_crt.c
@@ -59,10 +59,6 @@
59#include <stdio.h> 59#include <stdio.h>
60#include "cryptlib.h" 60#include "cryptlib.h"
61#include <openssl/pkcs12.h> 61#include <openssl/pkcs12.h>
62#ifdef OPENSSL_FIPS
63#include <openssl/fips.h>
64#endif
65
66 62
67 63
68static int pkcs12_add_bag(STACK_OF(PKCS12_SAFEBAG) **pbags, PKCS12_SAFEBAG *bag); 64static int pkcs12_add_bag(STACK_OF(PKCS12_SAFEBAG) **pbags, PKCS12_SAFEBAG *bag);
@@ -94,14 +90,7 @@ PKCS12 *PKCS12_create(char *pass, char *name, EVP_PKEY *pkey, X509 *cert,
94 90
95 /* Set defaults */ 91 /* Set defaults */
96 if (!nid_cert) 92 if (!nid_cert)
97 {
98#ifdef OPENSSL_FIPS
99 if (FIPS_mode())
100 nid_cert = NID_pbe_WithSHA1And3_Key_TripleDES_CBC;
101 else
102#endif
103 nid_cert = NID_pbe_WithSHA1And40BitRC2_CBC; 93 nid_cert = NID_pbe_WithSHA1And40BitRC2_CBC;
104 }
105 if (!nid_key) 94 if (!nid_key)
106 nid_key = NID_pbe_WithSHA1And3_Key_TripleDES_CBC; 95 nid_key = NID_pbe_WithSHA1And3_Key_TripleDES_CBC;
107 if (!iter) 96 if (!iter)
diff --git a/src/lib/libcrypto/pkcs12/p12_key.c b/src/lib/libcrypto/pkcs12/p12_key.c
index 9e57eee4a4..a29794bbbc 100644
--- a/src/lib/libcrypto/pkcs12/p12_key.c
+++ b/src/lib/libcrypto/pkcs12/p12_key.c
@@ -81,15 +81,18 @@ int PKCS12_key_gen_asc(const char *pass, int passlen, unsigned char *salt,
81 int ret; 81 int ret;
82 unsigned char *unipass; 82 unsigned char *unipass;
83 int uniplen; 83 int uniplen;
84
84 if(!pass) { 85 if(!pass) {
85 unipass = NULL; 86 unipass = NULL;
86 uniplen = 0; 87 uniplen = 0;
87 } else if (!asc2uni(pass, passlen, &unipass, &uniplen)) { 88 } else if (!OPENSSL_asc2uni(pass, passlen, &unipass, &uniplen)) {
88 PKCS12err(PKCS12_F_PKCS12_KEY_GEN_ASC,ERR_R_MALLOC_FAILURE); 89 PKCS12err(PKCS12_F_PKCS12_KEY_GEN_ASC,ERR_R_MALLOC_FAILURE);
89 return 0; 90 return 0;
90 } 91 }
91 ret = PKCS12_key_gen_uni(unipass, uniplen, salt, saltlen, 92 ret = PKCS12_key_gen_uni(unipass, uniplen, salt, saltlen,
92 id, iter, n, out, md_type); 93 id, iter, n, out, md_type);
94 if (ret <= 0)
95 return 0;
93 if(unipass) { 96 if(unipass) {
94 OPENSSL_cleanse(unipass, uniplen); /* Clear password from memory */ 97 OPENSSL_cleanse(unipass, uniplen); /* Clear password from memory */
95 OPENSSL_free(unipass); 98 OPENSSL_free(unipass);
@@ -129,6 +132,8 @@ int PKCS12_key_gen_uni(unsigned char *pass, int passlen, unsigned char *salt,
129#endif 132#endif
130 v = EVP_MD_block_size (md_type); 133 v = EVP_MD_block_size (md_type);
131 u = EVP_MD_size (md_type); 134 u = EVP_MD_size (md_type);
135 if (u < 0)
136 return 0;
132 D = OPENSSL_malloc (v); 137 D = OPENSSL_malloc (v);
133 Ai = OPENSSL_malloc (u); 138 Ai = OPENSSL_malloc (u);
134 B = OPENSSL_malloc (v + 1); 139 B = OPENSSL_malloc (v + 1);
diff --git a/src/lib/libcrypto/pkcs12/p12_kiss.c b/src/lib/libcrypto/pkcs12/p12_kiss.c
index 5c4c6ec988..292cc3ed4a 100644
--- a/src/lib/libcrypto/pkcs12/p12_kiss.c
+++ b/src/lib/libcrypto/pkcs12/p12_kiss.c
@@ -63,16 +63,13 @@
63/* Simplified PKCS#12 routines */ 63/* Simplified PKCS#12 routines */
64 64
65static int parse_pk12( PKCS12 *p12, const char *pass, int passlen, 65static int parse_pk12( PKCS12 *p12, const char *pass, int passlen,
66 EVP_PKEY **pkey, X509 **cert, STACK_OF(X509) **ca); 66 EVP_PKEY **pkey, STACK_OF(X509) *ocerts);
67 67
68static int parse_bags( STACK_OF(PKCS12_SAFEBAG) *bags, const char *pass, 68static int parse_bags( STACK_OF(PKCS12_SAFEBAG) *bags, const char *pass,
69 int passlen, EVP_PKEY **pkey, X509 **cert, 69 int passlen, EVP_PKEY **pkey, STACK_OF(X509) *ocerts);
70 STACK_OF(X509) **ca, ASN1_OCTET_STRING **keyid,
71 char *keymatch);
72 70
73static int parse_bag( PKCS12_SAFEBAG *bag, const char *pass, int passlen, 71static int parse_bag( PKCS12_SAFEBAG *bag, const char *pass, int passlen,
74 EVP_PKEY **pkey, X509 **cert, STACK_OF(X509) **ca, 72 EVP_PKEY **pkey, STACK_OF(X509) *ocerts);
75 ASN1_OCTET_STRING **keyid, char *keymatch);
76 73
77/* Parse and decrypt a PKCS#12 structure returning user key, user cert 74/* Parse and decrypt a PKCS#12 structure returning user key, user cert
78 * and other (CA) certs. Note either ca should be NULL, *ca should be NULL, 75 * and other (CA) certs. Note either ca should be NULL, *ca should be NULL,
@@ -83,24 +80,20 @@ static int parse_bag( PKCS12_SAFEBAG *bag, const char *pass, int passlen,
83int PKCS12_parse(PKCS12 *p12, const char *pass, EVP_PKEY **pkey, X509 **cert, 80int PKCS12_parse(PKCS12 *p12, const char *pass, EVP_PKEY **pkey, X509 **cert,
84 STACK_OF(X509) **ca) 81 STACK_OF(X509) **ca)
85{ 82{
86 83 STACK_OF(X509) *ocerts = NULL;
84 X509 *x = NULL;
87 /* Check for NULL PKCS12 structure */ 85 /* Check for NULL PKCS12 structure */
88 86
89 if(!p12) { 87 if(!p12)
88 {
90 PKCS12err(PKCS12_F_PKCS12_PARSE,PKCS12_R_INVALID_NULL_PKCS12_POINTER); 89 PKCS12err(PKCS12_F_PKCS12_PARSE,PKCS12_R_INVALID_NULL_PKCS12_POINTER);
91 return 0; 90 return 0;
92 }
93
94 /* Allocate stack for ca certificates if needed */
95 if ((ca != NULL) && (*ca == NULL)) {
96 if (!(*ca = sk_X509_new_null())) {
97 PKCS12err(PKCS12_F_PKCS12_PARSE,ERR_R_MALLOC_FAILURE);
98 return 0;
99 } 91 }
100 }
101 92
102 if(pkey) *pkey = NULL; 93 if(pkey)
103 if(cert) *cert = NULL; 94 *pkey = NULL;
95 if(cert)
96 *cert = NULL;
104 97
105 /* Check the mac */ 98 /* Check the mac */
106 99
@@ -122,19 +115,61 @@ int PKCS12_parse(PKCS12 *p12, const char *pass, EVP_PKEY **pkey, X509 **cert,
122 goto err; 115 goto err;
123 } 116 }
124 117
125 if (!parse_pk12 (p12, pass, -1, pkey, cert, ca)) 118 /* Allocate stack for other certificates */
119 ocerts = sk_X509_new_null();
120
121 if (!ocerts)
122 {
123 PKCS12err(PKCS12_F_PKCS12_PARSE,ERR_R_MALLOC_FAILURE);
124 return 0;
125 }
126
127 if (!parse_pk12 (p12, pass, -1, pkey, ocerts))
126 { 128 {
127 PKCS12err(PKCS12_F_PKCS12_PARSE,PKCS12_R_PARSE_ERROR); 129 PKCS12err(PKCS12_F_PKCS12_PARSE,PKCS12_R_PARSE_ERROR);
128 goto err; 130 goto err;
129 } 131 }
130 132
133 while ((x = sk_X509_pop(ocerts)))
134 {
135 if (pkey && *pkey && cert && !*cert)
136 {
137 if (X509_check_private_key(x, *pkey))
138 {
139 *cert = x;
140 x = NULL;
141 }
142 }
143
144 if (ca && x)
145 {
146 if (!*ca)
147 *ca = sk_X509_new_null();
148 if (!*ca)
149 goto err;
150 if (!sk_X509_push(*ca, x))
151 goto err;
152 x = NULL;
153 }
154 if (x)
155 X509_free(x);
156 }
157
158 if (ocerts)
159 sk_X509_pop_free(ocerts, X509_free);
160
131 return 1; 161 return 1;
132 162
133 err: 163 err:
134 164
135 if (pkey && *pkey) EVP_PKEY_free(*pkey); 165 if (pkey && *pkey)
136 if (cert && *cert) X509_free(*cert); 166 EVP_PKEY_free(*pkey);
137 if (ca) sk_X509_pop_free(*ca, X509_free); 167 if (cert && *cert)
168 X509_free(*cert);
169 if (x)
170 X509_free(*cert);
171 if (ocerts)
172 sk_X509_pop_free(ocerts, X509_free);
138 return 0; 173 return 0;
139 174
140} 175}
@@ -142,15 +177,13 @@ int PKCS12_parse(PKCS12 *p12, const char *pass, EVP_PKEY **pkey, X509 **cert,
142/* Parse the outer PKCS#12 structure */ 177/* Parse the outer PKCS#12 structure */
143 178
144static int parse_pk12(PKCS12 *p12, const char *pass, int passlen, 179static int parse_pk12(PKCS12 *p12, const char *pass, int passlen,
145 EVP_PKEY **pkey, X509 **cert, STACK_OF(X509) **ca) 180 EVP_PKEY **pkey, STACK_OF(X509) *ocerts)
146{ 181{
147 STACK_OF(PKCS7) *asafes; 182 STACK_OF(PKCS7) *asafes;
148 STACK_OF(PKCS12_SAFEBAG) *bags; 183 STACK_OF(PKCS12_SAFEBAG) *bags;
149 int i, bagnid; 184 int i, bagnid;
150 PKCS7 *p7; 185 PKCS7 *p7;
151 ASN1_OCTET_STRING *keyid = NULL;
152 186
153 char keymatch = 0;
154 if (!(asafes = PKCS12_unpack_authsafes (p12))) return 0; 187 if (!(asafes = PKCS12_unpack_authsafes (p12))) return 0;
155 for (i = 0; i < sk_PKCS7_num (asafes); i++) { 188 for (i = 0; i < sk_PKCS7_num (asafes); i++) {
156 p7 = sk_PKCS7_value (asafes, i); 189 p7 = sk_PKCS7_value (asafes, i);
@@ -164,8 +197,7 @@ static int parse_pk12(PKCS12 *p12, const char *pass, int passlen,
164 sk_PKCS7_pop_free(asafes, PKCS7_free); 197 sk_PKCS7_pop_free(asafes, PKCS7_free);
165 return 0; 198 return 0;
166 } 199 }
167 if (!parse_bags(bags, pass, passlen, pkey, cert, ca, 200 if (!parse_bags(bags, pass, passlen, pkey, ocerts)) {
168 &keyid, &keymatch)) {
169 sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free); 201 sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free);
170 sk_PKCS7_pop_free(asafes, PKCS7_free); 202 sk_PKCS7_pop_free(asafes, PKCS7_free);
171 return 0; 203 return 0;
@@ -173,89 +205,65 @@ static int parse_pk12(PKCS12 *p12, const char *pass, int passlen,
173 sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free); 205 sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free);
174 } 206 }
175 sk_PKCS7_pop_free(asafes, PKCS7_free); 207 sk_PKCS7_pop_free(asafes, PKCS7_free);
176 if (keyid) M_ASN1_OCTET_STRING_free(keyid);
177 return 1; 208 return 1;
178} 209}
179 210
180 211
181static int parse_bags(STACK_OF(PKCS12_SAFEBAG) *bags, const char *pass, 212static int parse_bags(STACK_OF(PKCS12_SAFEBAG) *bags, const char *pass,
182 int passlen, EVP_PKEY **pkey, X509 **cert, 213 int passlen, EVP_PKEY **pkey, STACK_OF(X509) *ocerts)
183 STACK_OF(X509) **ca, ASN1_OCTET_STRING **keyid,
184 char *keymatch)
185{ 214{
186 int i; 215 int i;
187 for (i = 0; i < sk_PKCS12_SAFEBAG_num(bags); i++) { 216 for (i = 0; i < sk_PKCS12_SAFEBAG_num(bags); i++) {
188 if (!parse_bag(sk_PKCS12_SAFEBAG_value (bags, i), 217 if (!parse_bag(sk_PKCS12_SAFEBAG_value (bags, i),
189 pass, passlen, pkey, cert, ca, keyid, 218 pass, passlen, pkey, ocerts))
190 keymatch)) return 0; 219 return 0;
191 } 220 }
192 return 1; 221 return 1;
193} 222}
194 223
195#define MATCH_KEY 0x1
196#define MATCH_CERT 0x2
197#define MATCH_ALL 0x3
198
199static int parse_bag(PKCS12_SAFEBAG *bag, const char *pass, int passlen, 224static int parse_bag(PKCS12_SAFEBAG *bag, const char *pass, int passlen,
200 EVP_PKEY **pkey, X509 **cert, STACK_OF(X509) **ca, 225 EVP_PKEY **pkey, STACK_OF(X509) *ocerts)
201 ASN1_OCTET_STRING **keyid,
202 char *keymatch)
203{ 226{
204 PKCS8_PRIV_KEY_INFO *p8; 227 PKCS8_PRIV_KEY_INFO *p8;
205 X509 *x509; 228 X509 *x509;
206 ASN1_OCTET_STRING *lkey = NULL, *ckid = NULL;
207 ASN1_TYPE *attrib; 229 ASN1_TYPE *attrib;
208 ASN1_BMPSTRING *fname = NULL; 230 ASN1_BMPSTRING *fname = NULL;
231 ASN1_OCTET_STRING *lkid = NULL;
209 232
210 if ((attrib = PKCS12_get_attr (bag, NID_friendlyName))) 233 if ((attrib = PKCS12_get_attr (bag, NID_friendlyName)))
211 fname = attrib->value.bmpstring; 234 fname = attrib->value.bmpstring;
212 235
213 if ((attrib = PKCS12_get_attr (bag, NID_localKeyID))) { 236 if ((attrib = PKCS12_get_attr (bag, NID_localKeyID)))
214 lkey = attrib->value.octet_string; 237 lkid = attrib->value.octet_string;
215 ckid = lkey;
216 }
217 238
218 /* Check for any local key id matching (if needed) */
219 if (lkey && ((*keymatch & MATCH_ALL) != MATCH_ALL)) {
220 if (*keyid) {
221 if (M_ASN1_OCTET_STRING_cmp(*keyid, lkey)) lkey = NULL;
222 } else {
223 if (!(*keyid = M_ASN1_OCTET_STRING_dup(lkey))) {
224 PKCS12err(PKCS12_F_PARSE_BAG,ERR_R_MALLOC_FAILURE);
225 return 0;
226 }
227 }
228 }
229
230 switch (M_PKCS12_bag_type(bag)) 239 switch (M_PKCS12_bag_type(bag))
231 { 240 {
232 case NID_keyBag: 241 case NID_keyBag:
233 if (!lkey || !pkey) return 1; 242 if (!pkey || *pkey)
234 if (!(*pkey = EVP_PKCS82PKEY(bag->value.keybag))) return 0; 243 return 1;
235 *keymatch |= MATCH_KEY; 244 if (!(*pkey = EVP_PKCS82PKEY(bag->value.keybag)))
245 return 0;
236 break; 246 break;
237 247
238 case NID_pkcs8ShroudedKeyBag: 248 case NID_pkcs8ShroudedKeyBag:
239 if (!lkey || !pkey) return 1; 249 if (!pkey || *pkey)
250 return 1;
240 if (!(p8 = PKCS12_decrypt_skey(bag, pass, passlen))) 251 if (!(p8 = PKCS12_decrypt_skey(bag, pass, passlen)))
241 return 0; 252 return 0;
242 *pkey = EVP_PKCS82PKEY(p8); 253 *pkey = EVP_PKCS82PKEY(p8);
243 PKCS8_PRIV_KEY_INFO_free(p8); 254 PKCS8_PRIV_KEY_INFO_free(p8);
244 if (!(*pkey)) return 0; 255 if (!(*pkey)) return 0;
245 *keymatch |= MATCH_KEY;
246 break; 256 break;
247 257
248 case NID_certBag: 258 case NID_certBag:
249 if (M_PKCS12_cert_bag_type(bag) != NID_x509Certificate ) 259 if (M_PKCS12_cert_bag_type(bag) != NID_x509Certificate )
250 return 1; 260 return 1;
251 if (!(x509 = PKCS12_certbag2x509(bag))) return 0; 261 if (!(x509 = PKCS12_certbag2x509(bag)))
252 if(ckid) 262 return 0;
263 if(lkid && !X509_keyid_set1(x509, lkid->data, lkid->length))
253 { 264 {
254 if (!X509_keyid_set1(x509, ckid->data, ckid->length)) 265 X509_free(x509);
255 { 266 return 0;
256 X509_free(x509);
257 return 0;
258 }
259 } 267 }
260 if(fname) { 268 if(fname) {
261 int len, r; 269 int len, r;
@@ -272,20 +280,17 @@ static int parse_bag(PKCS12_SAFEBAG *bag, const char *pass, int passlen,
272 } 280 }
273 } 281 }
274 282
283 if(!sk_X509_push(ocerts, x509))
284 {
285 X509_free(x509);
286 return 0;
287 }
275 288
276 if (lkey) {
277 *keymatch |= MATCH_CERT;
278 if (cert) *cert = x509;
279 else X509_free(x509);
280 } else {
281 if(ca) sk_X509_push (*ca, x509);
282 else X509_free(x509);
283 }
284 break; 289 break;
285 290
286 case NID_safeContentsBag: 291 case NID_safeContentsBag:
287 return parse_bags(bag->value.safes, pass, passlen, 292 return parse_bags(bag->value.safes, pass, passlen,
288 pkey, cert, ca, keyid, keymatch); 293 pkey, ocerts);
289 break; 294 break;
290 295
291 default: 296 default:
diff --git a/src/lib/libcrypto/pkcs12/p12_mutl.c b/src/lib/libcrypto/pkcs12/p12_mutl.c
index 70bfef6e5d..9ab740d51f 100644
--- a/src/lib/libcrypto/pkcs12/p12_mutl.c
+++ b/src/lib/libcrypto/pkcs12/p12_mutl.c
@@ -71,6 +71,7 @@ int PKCS12_gen_mac(PKCS12 *p12, const char *pass, int passlen,
71 HMAC_CTX hmac; 71 HMAC_CTX hmac;
72 unsigned char key[EVP_MAX_MD_SIZE], *salt; 72 unsigned char key[EVP_MAX_MD_SIZE], *salt;
73 int saltlen, iter; 73 int saltlen, iter;
74 int md_size;
74 75
75 if (!PKCS7_type_is_data(p12->authsafes)) 76 if (!PKCS7_type_is_data(p12->authsafes))
76 { 77 {
@@ -87,13 +88,16 @@ int PKCS12_gen_mac(PKCS12 *p12, const char *pass, int passlen,
87 PKCS12err(PKCS12_F_PKCS12_GEN_MAC,PKCS12_R_UNKNOWN_DIGEST_ALGORITHM); 88 PKCS12err(PKCS12_F_PKCS12_GEN_MAC,PKCS12_R_UNKNOWN_DIGEST_ALGORITHM);
88 return 0; 89 return 0;
89 } 90 }
91 md_size = EVP_MD_size(md_type);
92 if (md_size < 0)
93 return 0;
90 if(!PKCS12_key_gen (pass, passlen, salt, saltlen, PKCS12_MAC_ID, iter, 94 if(!PKCS12_key_gen (pass, passlen, salt, saltlen, PKCS12_MAC_ID, iter,
91 EVP_MD_size(md_type), key, md_type)) { 95 md_size, key, md_type)) {
92 PKCS12err(PKCS12_F_PKCS12_GEN_MAC,PKCS12_R_KEY_GEN_ERROR); 96 PKCS12err(PKCS12_F_PKCS12_GEN_MAC,PKCS12_R_KEY_GEN_ERROR);
93 return 0; 97 return 0;
94 } 98 }
95 HMAC_CTX_init(&hmac); 99 HMAC_CTX_init(&hmac);
96 HMAC_Init_ex(&hmac, key, EVP_MD_size(md_type), md_type, NULL); 100 HMAC_Init_ex(&hmac, key, md_size, md_type, NULL);
97 HMAC_Update(&hmac, p12->authsafes->d.data->data, 101 HMAC_Update(&hmac, p12->authsafes->d.data->data,
98 p12->authsafes->d.data->length); 102 p12->authsafes->d.data->length);
99 HMAC_Final(&hmac, mac, maclen); 103 HMAC_Final(&hmac, mac, maclen);
diff --git a/src/lib/libcrypto/pkcs12/p12_npas.c b/src/lib/libcrypto/pkcs12/p12_npas.c
index 47e5e9c377..2f71355150 100644
--- a/src/lib/libcrypto/pkcs12/p12_npas.c
+++ b/src/lib/libcrypto/pkcs12/p12_npas.c
@@ -120,8 +120,13 @@ static int newpass_p12(PKCS12 *p12, char *oldpass, char *newpass)
120 bags = PKCS12_unpack_p7data(p7); 120 bags = PKCS12_unpack_p7data(p7);
121 } else if (bagnid == NID_pkcs7_encrypted) { 121 } else if (bagnid == NID_pkcs7_encrypted) {
122 bags = PKCS12_unpack_p7encdata(p7, oldpass, -1); 122 bags = PKCS12_unpack_p7encdata(p7, oldpass, -1);
123 alg_get(p7->d.encrypted->enc_data->algorithm, 123 if (!alg_get(p7->d.encrypted->enc_data->algorithm,
124 &pbe_nid, &pbe_iter, &pbe_saltlen); 124 &pbe_nid, &pbe_iter, &pbe_saltlen))
125 {
126 sk_PKCS12_SAFEBAG_pop_free(bags,
127 PKCS12_SAFEBAG_free);
128 bags = NULL;
129 }
125 } else continue; 130 } else continue;
126 if (!bags) { 131 if (!bags) {
127 sk_PKCS7_pop_free(asafes, PKCS7_free); 132 sk_PKCS7_pop_free(asafes, PKCS7_free);
@@ -193,7 +198,9 @@ static int newpass_bag(PKCS12_SAFEBAG *bag, char *oldpass, char *newpass)
193 if(M_PKCS12_bag_type(bag) != NID_pkcs8ShroudedKeyBag) return 1; 198 if(M_PKCS12_bag_type(bag) != NID_pkcs8ShroudedKeyBag) return 1;
194 199
195 if (!(p8 = PKCS8_decrypt(bag->value.shkeybag, oldpass, -1))) return 0; 200 if (!(p8 = PKCS8_decrypt(bag->value.shkeybag, oldpass, -1))) return 0;
196 alg_get(bag->value.shkeybag->algor, &p8_nid, &p8_iter, &p8_saltlen); 201 if (!alg_get(bag->value.shkeybag->algor, &p8_nid, &p8_iter,
202 &p8_saltlen))
203 return 0;
197 if(!(p8new = PKCS8_encrypt(p8_nid, NULL, newpass, -1, NULL, p8_saltlen, 204 if(!(p8new = PKCS8_encrypt(p8_nid, NULL, newpass, -1, NULL, p8_saltlen,
198 p8_iter, p8))) return 0; 205 p8_iter, p8))) return 0;
199 X509_SIG_free(bag->value.shkeybag); 206 X509_SIG_free(bag->value.shkeybag);
@@ -208,9 +215,11 @@ static int alg_get(X509_ALGOR *alg, int *pnid, int *piter, int *psaltlen)
208 215
209 p = alg->parameter->value.sequence->data; 216 p = alg->parameter->value.sequence->data;
210 pbe = d2i_PBEPARAM(NULL, &p, alg->parameter->value.sequence->length); 217 pbe = d2i_PBEPARAM(NULL, &p, alg->parameter->value.sequence->length);
218 if (!pbe)
219 return 0;
211 *pnid = OBJ_obj2nid(alg->algorithm); 220 *pnid = OBJ_obj2nid(alg->algorithm);
212 *piter = ASN1_INTEGER_get(pbe->iter); 221 *piter = ASN1_INTEGER_get(pbe->iter);
213 *psaltlen = pbe->salt->length; 222 *psaltlen = pbe->salt->length;
214 PBEPARAM_free(pbe); 223 PBEPARAM_free(pbe);
215 return 0; 224 return 1;
216} 225}
diff --git a/src/lib/libcrypto/pkcs12/p12_utl.c b/src/lib/libcrypto/pkcs12/p12_utl.c
index ca30ac4f6d..59c6f453f6 100644
--- a/src/lib/libcrypto/pkcs12/p12_utl.c
+++ b/src/lib/libcrypto/pkcs12/p12_utl.c
@@ -62,7 +62,7 @@
62 62
63/* Cheap and nasty Unicode stuff */ 63/* Cheap and nasty Unicode stuff */
64 64
65unsigned char *asc2uni(const char *asc, int asclen, unsigned char **uni, int *unilen) 65unsigned char *OPENSSL_asc2uni(const char *asc, int asclen, unsigned char **uni, int *unilen)
66{ 66{
67 int ulen, i; 67 int ulen, i;
68 unsigned char *unitmp; 68 unsigned char *unitmp;
@@ -81,7 +81,7 @@ unsigned char *asc2uni(const char *asc, int asclen, unsigned char **uni, int *un
81 return unitmp; 81 return unitmp;
82} 82}
83 83
84char *uni2asc(unsigned char *uni, int unilen) 84char *OPENSSL_uni2asc(unsigned char *uni, int unilen)
85{ 85{
86 int asclen, i; 86 int asclen, i;
87 char *asctmp; 87 char *asctmp;
diff --git a/src/lib/libcrypto/pkcs12/pk12err.c b/src/lib/libcrypto/pkcs12/pk12err.c
index 07a1fb6907..f6ddf2df12 100644
--- a/src/lib/libcrypto/pkcs12/pk12err.c
+++ b/src/lib/libcrypto/pkcs12/pk12err.c
@@ -1,6 +1,6 @@
1/* crypto/pkcs12/pk12err.c */ 1/* crypto/pkcs12/pk12err.c */
2/* ==================================================================== 2/* ====================================================================
3 * Copyright (c) 1999-2005 The OpenSSL Project. All rights reserved. 3 * Copyright (c) 1999-2006 The OpenSSL Project. All rights reserved.
4 * 4 *
5 * Redistribution and use in source and binary forms, with or without 5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions 6 * modification, are permitted provided that the following conditions
diff --git a/src/lib/libcrypto/pkcs12/pkcs12.h b/src/lib/libcrypto/pkcs12/pkcs12.h
index 4bee605dc0..b17eb9f42b 100644
--- a/src/lib/libcrypto/pkcs12/pkcs12.h
+++ b/src/lib/libcrypto/pkcs12/pkcs12.h
@@ -108,8 +108,6 @@ PKCS12_MAC_DATA *mac;
108PKCS7 *authsafes; 108PKCS7 *authsafes;
109} PKCS12; 109} PKCS12;
110 110
111PREDECLARE_STACK_OF(PKCS12_SAFEBAG)
112
113typedef struct { 111typedef struct {
114ASN1_OBJECT *type; 112ASN1_OBJECT *type;
115union { 113union {
@@ -232,8 +230,8 @@ int PKCS12_set_mac(PKCS12 *p12, const char *pass, int passlen,
232 const EVP_MD *md_type); 230 const EVP_MD *md_type);
233int PKCS12_setup_mac(PKCS12 *p12, int iter, unsigned char *salt, 231int PKCS12_setup_mac(PKCS12 *p12, int iter, unsigned char *salt,
234 int saltlen, const EVP_MD *md_type); 232 int saltlen, const EVP_MD *md_type);
235unsigned char *asc2uni(const char *asc, int asclen, unsigned char **uni, int *unilen); 233unsigned char *OPENSSL_asc2uni(const char *asc, int asclen, unsigned char **uni, int *unilen);
236char *uni2asc(unsigned char *uni, int unilen); 234char *OPENSSL_uni2asc(unsigned char *uni, int unilen);
237 235
238DECLARE_ASN1_FUNCTIONS(PKCS12) 236DECLARE_ASN1_FUNCTIONS(PKCS12)
239DECLARE_ASN1_FUNCTIONS(PKCS12_MAC_DATA) 237DECLARE_ASN1_FUNCTIONS(PKCS12_MAC_DATA)
diff --git a/src/lib/libcrypto/pkcs7/bio_pk7.c b/src/lib/libcrypto/pkcs7/bio_pk7.c
new file mode 100644
index 0000000000..c8d06d6cdc
--- /dev/null
+++ b/src/lib/libcrypto/pkcs7/bio_pk7.c
@@ -0,0 +1,69 @@
1/* bio_pk7.c */
2/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
3 * project.
4 */
5/* ====================================================================
6 * Copyright (c) 2008 The OpenSSL Project. All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 *
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 *
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in
17 * the documentation and/or other materials provided with the
18 * distribution.
19 *
20 * 3. All advertising materials mentioning features or use of this
21 * software must display the following acknowledgment:
22 * "This product includes software developed by the OpenSSL Project
23 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
24 *
25 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
26 * endorse or promote products derived from this software without
27 * prior written permission. For written permission, please contact
28 * licensing@OpenSSL.org.
29 *
30 * 5. Products derived from this software may not be called "OpenSSL"
31 * nor may "OpenSSL" appear in their names without prior written
32 * permission of the OpenSSL Project.
33 *
34 * 6. Redistributions of any form whatsoever must retain the following
35 * acknowledgment:
36 * "This product includes software developed by the OpenSSL Project
37 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
38 *
39 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
40 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
43 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
50 * OF THE POSSIBILITY OF SUCH DAMAGE.
51 * ====================================================================
52 *
53 */
54
55#include <openssl/asn1.h>
56#include <openssl/pkcs7.h>
57#include <openssl/bio.h>
58
59#ifndef OPENSSL_SYSNAME_NETWARE
60#include <memory.h>
61#endif
62#include <stdio.h>
63
64/* Streaming encode support for PKCS#7 */
65
66BIO *BIO_new_PKCS7(BIO *out, PKCS7 *p7)
67 {
68 return BIO_new_NDEF(out, (ASN1_VALUE *)p7, ASN1_ITEM_rptr(PKCS7));
69 }
diff --git a/src/lib/libcrypto/pkcs7/pk7_asn1.c b/src/lib/libcrypto/pkcs7/pk7_asn1.c
index 1f70d31386..b7ec2883cb 100644
--- a/src/lib/libcrypto/pkcs7/pk7_asn1.c
+++ b/src/lib/libcrypto/pkcs7/pk7_asn1.c
@@ -77,10 +77,39 @@ ASN1_ADB(PKCS7) = {
77 ADB_ENTRY(NID_pkcs7_encrypted, ASN1_NDEF_EXP_OPT(PKCS7, d.encrypted, PKCS7_ENCRYPT, 0)) 77 ADB_ENTRY(NID_pkcs7_encrypted, ASN1_NDEF_EXP_OPT(PKCS7, d.encrypted, PKCS7_ENCRYPT, 0))
78} ASN1_ADB_END(PKCS7, 0, type, 0, &p7default_tt, NULL); 78} ASN1_ADB_END(PKCS7, 0, type, 0, &p7default_tt, NULL);
79 79
80ASN1_NDEF_SEQUENCE(PKCS7) = { 80/* PKCS#7 streaming support */
81static int pk7_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
82 void *exarg)
83{
84 ASN1_STREAM_ARG *sarg = exarg;
85 PKCS7 **pp7 = (PKCS7 **)pval;
86
87 switch(operation)
88 {
89
90 case ASN1_OP_STREAM_PRE:
91 if (PKCS7_stream(&sarg->boundary, *pp7) <= 0)
92 return 0;
93 case ASN1_OP_DETACHED_PRE:
94 sarg->ndef_bio = PKCS7_dataInit(*pp7, sarg->out);
95 if (!sarg->ndef_bio)
96 return 0;
97 break;
98
99 case ASN1_OP_STREAM_POST:
100 case ASN1_OP_DETACHED_POST:
101 if (PKCS7_dataFinal(*pp7, sarg->ndef_bio) <= 0)
102 return 0;
103 break;
104
105 }
106 return 1;
107}
108
109ASN1_NDEF_SEQUENCE_cb(PKCS7, pk7_cb) = {
81 ASN1_SIMPLE(PKCS7, type, ASN1_OBJECT), 110 ASN1_SIMPLE(PKCS7, type, ASN1_OBJECT),
82 ASN1_ADB_OBJECT(PKCS7) 111 ASN1_ADB_OBJECT(PKCS7)
83}ASN1_NDEF_SEQUENCE_END(PKCS7) 112}ASN1_NDEF_SEQUENCE_END_cb(PKCS7, PKCS7)
84 113
85IMPLEMENT_ASN1_FUNCTIONS(PKCS7) 114IMPLEMENT_ASN1_FUNCTIONS(PKCS7)
86IMPLEMENT_ASN1_NDEF_FUNCTION(PKCS7) 115IMPLEMENT_ASN1_NDEF_FUNCTION(PKCS7)
@@ -98,7 +127,8 @@ ASN1_NDEF_SEQUENCE(PKCS7_SIGNED) = {
98IMPLEMENT_ASN1_FUNCTIONS(PKCS7_SIGNED) 127IMPLEMENT_ASN1_FUNCTIONS(PKCS7_SIGNED)
99 128
100/* Minor tweak to operation: free up EVP_PKEY */ 129/* Minor tweak to operation: free up EVP_PKEY */
101static int si_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it) 130static int si_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
131 void *exarg)
102{ 132{
103 if(operation == ASN1_OP_FREE_POST) { 133 if(operation == ASN1_OP_FREE_POST) {
104 PKCS7_SIGNER_INFO *si = (PKCS7_SIGNER_INFO *)*pval; 134 PKCS7_SIGNER_INFO *si = (PKCS7_SIGNER_INFO *)*pval;
@@ -140,7 +170,8 @@ ASN1_NDEF_SEQUENCE(PKCS7_ENVELOPE) = {
140IMPLEMENT_ASN1_FUNCTIONS(PKCS7_ENVELOPE) 170IMPLEMENT_ASN1_FUNCTIONS(PKCS7_ENVELOPE)
141 171
142/* Minor tweak to operation: free up X509 */ 172/* Minor tweak to operation: free up X509 */
143static int ri_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it) 173static int ri_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
174 void *exarg)
144{ 175{
145 if(operation == ASN1_OP_FREE_POST) { 176 if(operation == ASN1_OP_FREE_POST) {
146 PKCS7_RECIP_INFO *ri = (PKCS7_RECIP_INFO *)*pval; 177 PKCS7_RECIP_INFO *ri = (PKCS7_RECIP_INFO *)*pval;
@@ -161,7 +192,7 @@ IMPLEMENT_ASN1_FUNCTIONS(PKCS7_RECIP_INFO)
161ASN1_NDEF_SEQUENCE(PKCS7_ENC_CONTENT) = { 192ASN1_NDEF_SEQUENCE(PKCS7_ENC_CONTENT) = {
162 ASN1_SIMPLE(PKCS7_ENC_CONTENT, content_type, ASN1_OBJECT), 193 ASN1_SIMPLE(PKCS7_ENC_CONTENT, content_type, ASN1_OBJECT),
163 ASN1_SIMPLE(PKCS7_ENC_CONTENT, algorithm, X509_ALGOR), 194 ASN1_SIMPLE(PKCS7_ENC_CONTENT, algorithm, X509_ALGOR),
164 ASN1_IMP_OPT(PKCS7_ENC_CONTENT, enc_data, ASN1_OCTET_STRING, 0) 195 ASN1_IMP_OPT(PKCS7_ENC_CONTENT, enc_data, ASN1_OCTET_STRING_NDEF, 0)
165} ASN1_NDEF_SEQUENCE_END(PKCS7_ENC_CONTENT) 196} ASN1_NDEF_SEQUENCE_END(PKCS7_ENC_CONTENT)
166 197
167IMPLEMENT_ASN1_FUNCTIONS(PKCS7_ENC_CONTENT) 198IMPLEMENT_ASN1_FUNCTIONS(PKCS7_ENC_CONTENT)
@@ -212,3 +243,5 @@ ASN1_ITEM_TEMPLATE(PKCS7_ATTR_VERIFY) =
212 ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF | ASN1_TFLG_IMPTAG | ASN1_TFLG_UNIVERSAL, 243 ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF | ASN1_TFLG_IMPTAG | ASN1_TFLG_UNIVERSAL,
213 V_ASN1_SET, PKCS7_ATTRIBUTES, X509_ATTRIBUTE) 244 V_ASN1_SET, PKCS7_ATTRIBUTES, X509_ATTRIBUTE)
214ASN1_ITEM_TEMPLATE_END(PKCS7_ATTR_VERIFY) 245ASN1_ITEM_TEMPLATE_END(PKCS7_ATTR_VERIFY)
246
247IMPLEMENT_ASN1_PRINT_FUNCTION(PKCS7)
diff --git a/src/lib/libcrypto/pkcs7/pk7_attr.c b/src/lib/libcrypto/pkcs7/pk7_attr.c
index d549717169..a97db51210 100644
--- a/src/lib/libcrypto/pkcs7/pk7_attr.c
+++ b/src/lib/libcrypto/pkcs7/pk7_attr.c
@@ -60,6 +60,7 @@
60#include <stdlib.h> 60#include <stdlib.h>
61#include <openssl/bio.h> 61#include <openssl/bio.h>
62#include <openssl/asn1.h> 62#include <openssl/asn1.h>
63#include <openssl/asn1t.h>
63#include <openssl/pem.h> 64#include <openssl/pem.h>
64#include <openssl/pkcs7.h> 65#include <openssl/pkcs7.h>
65#include <openssl/x509.h> 66#include <openssl/x509.h>
@@ -68,27 +69,12 @@
68int PKCS7_add_attrib_smimecap(PKCS7_SIGNER_INFO *si, STACK_OF(X509_ALGOR) *cap) 69int PKCS7_add_attrib_smimecap(PKCS7_SIGNER_INFO *si, STACK_OF(X509_ALGOR) *cap)
69{ 70{
70 ASN1_STRING *seq; 71 ASN1_STRING *seq;
71 unsigned char *p, *pp;
72 int len;
73 len=i2d_ASN1_SET_OF_X509_ALGOR(cap,NULL,i2d_X509_ALGOR,
74 V_ASN1_SEQUENCE,V_ASN1_UNIVERSAL,
75 IS_SEQUENCE);
76 if(!(pp=(unsigned char *)OPENSSL_malloc(len))) {
77 PKCS7err(PKCS7_F_PKCS7_ADD_ATTRIB_SMIMECAP,ERR_R_MALLOC_FAILURE);
78 return 0;
79 }
80 p=pp;
81 i2d_ASN1_SET_OF_X509_ALGOR(cap,&p,i2d_X509_ALGOR, V_ASN1_SEQUENCE,
82 V_ASN1_UNIVERSAL, IS_SEQUENCE);
83 if(!(seq = ASN1_STRING_new())) { 72 if(!(seq = ASN1_STRING_new())) {
84 PKCS7err(PKCS7_F_PKCS7_ADD_ATTRIB_SMIMECAP,ERR_R_MALLOC_FAILURE); 73 PKCS7err(PKCS7_F_PKCS7_ADD_ATTRIB_SMIMECAP,ERR_R_MALLOC_FAILURE);
85 return 0; 74 return 0;
86 } 75 }
87 if(!ASN1_STRING_set (seq, pp, len)) { 76 seq->length = ASN1_item_i2d((ASN1_VALUE *)cap,&seq->data,
88 PKCS7err(PKCS7_F_PKCS7_ADD_ATTRIB_SMIMECAP,ERR_R_MALLOC_FAILURE); 77 ASN1_ITEM_rptr(X509_ALGORS));
89 return 0;
90 }
91 OPENSSL_free (pp);
92 return PKCS7_add_signed_attribute(si, NID_SMIMECapabilities, 78 return PKCS7_add_signed_attribute(si, NID_SMIMECapabilities,
93 V_ASN1_SEQUENCE, seq); 79 V_ASN1_SEQUENCE, seq);
94} 80}
@@ -102,10 +88,9 @@ STACK_OF(X509_ALGOR) *PKCS7_get_smimecap(PKCS7_SIGNER_INFO *si)
102 if (!cap || (cap->type != V_ASN1_SEQUENCE)) 88 if (!cap || (cap->type != V_ASN1_SEQUENCE))
103 return NULL; 89 return NULL;
104 p = cap->value.sequence->data; 90 p = cap->value.sequence->data;
105 return d2i_ASN1_SET_OF_X509_ALGOR(NULL, &p, 91 return (STACK_OF(X509_ALGOR) *)
106 cap->value.sequence->length, 92 ASN1_item_d2i(NULL, &p, cap->value.sequence->length,
107 d2i_X509_ALGOR, X509_ALGOR_free, 93 ASN1_ITEM_rptr(X509_ALGORS));
108 V_ASN1_SEQUENCE, V_ASN1_UNIVERSAL);
109 } 94 }
110 95
111/* Basic smime-capabilities OID and optional integer arg */ 96/* Basic smime-capabilities OID and optional integer arg */
@@ -139,3 +124,42 @@ int PKCS7_simple_smimecap(STACK_OF(X509_ALGOR) *sk, int nid, int arg)
139 sk_X509_ALGOR_push (sk, alg); 124 sk_X509_ALGOR_push (sk, alg);
140 return 1; 125 return 1;
141} 126}
127
128int PKCS7_add_attrib_content_type(PKCS7_SIGNER_INFO *si, ASN1_OBJECT *coid)
129 {
130 if (PKCS7_get_signed_attribute(si, NID_pkcs9_contentType))
131 return 0;
132 if (!coid)
133 coid = OBJ_nid2obj(NID_pkcs7_data);
134 return PKCS7_add_signed_attribute(si, NID_pkcs9_contentType,
135 V_ASN1_OBJECT, coid);
136 }
137
138int PKCS7_add0_attrib_signing_time(PKCS7_SIGNER_INFO *si, ASN1_TIME *t)
139 {
140 if (!t && !(t=X509_gmtime_adj(NULL,0)))
141 {
142 PKCS7err(PKCS7_F_PKCS7_ADD0_ATTRIB_SIGNING_TIME,
143 ERR_R_MALLOC_FAILURE);
144 return 0;
145 }
146 return PKCS7_add_signed_attribute(si, NID_pkcs9_signingTime,
147 V_ASN1_UTCTIME, t);
148 }
149
150int PKCS7_add1_attrib_digest(PKCS7_SIGNER_INFO *si,
151 const unsigned char *md, int mdlen)
152 {
153 ASN1_OCTET_STRING *os;
154 os = ASN1_OCTET_STRING_new();
155 if (!os)
156 return 0;
157 if (!ASN1_STRING_set(os, md, mdlen)
158 || !PKCS7_add_signed_attribute(si, NID_pkcs9_messageDigest,
159 V_ASN1_OCTET_STRING, os))
160 {
161 ASN1_OCTET_STRING_free(os);
162 return 0;
163 }
164 return 1;
165 }
diff --git a/src/lib/libcrypto/pkcs7/pk7_doit.c b/src/lib/libcrypto/pkcs7/pk7_doit.c
index a03d7ebedf..451de84489 100644
--- a/src/lib/libcrypto/pkcs7/pk7_doit.c
+++ b/src/lib/libcrypto/pkcs7/pk7_doit.c
@@ -138,6 +138,121 @@ static int PKCS7_bio_add_digest(BIO **pbio, X509_ALGOR *alg)
138 138
139 } 139 }
140 140
141static int pkcs7_encode_rinfo(PKCS7_RECIP_INFO *ri,
142 unsigned char *key, int keylen)
143 {
144 EVP_PKEY_CTX *pctx = NULL;
145 EVP_PKEY *pkey = NULL;
146 unsigned char *ek = NULL;
147 int ret = 0;
148 size_t eklen;
149
150 pkey = X509_get_pubkey(ri->cert);
151
152 if (!pkey)
153 return 0;
154
155 pctx = EVP_PKEY_CTX_new(pkey, NULL);
156 if (!pctx)
157 return 0;
158
159 if (EVP_PKEY_encrypt_init(pctx) <= 0)
160 goto err;
161
162 if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_ENCRYPT,
163 EVP_PKEY_CTRL_PKCS7_ENCRYPT, 0, ri) <= 0)
164 {
165 PKCS7err(PKCS7_F_PKCS7_ENCODE_RINFO, PKCS7_R_CTRL_ERROR);
166 goto err;
167 }
168
169 if (EVP_PKEY_encrypt(pctx, NULL, &eklen, key, keylen) <= 0)
170 goto err;
171
172 ek = OPENSSL_malloc(eklen);
173
174 if (ek == NULL)
175 {
176 PKCS7err(PKCS7_F_PKCS7_ENCODE_RINFO, ERR_R_MALLOC_FAILURE);
177 goto err;
178 }
179
180 if (EVP_PKEY_encrypt(pctx, ek, &eklen, key, keylen) <= 0)
181 goto err;
182
183 ASN1_STRING_set0(ri->enc_key, ek, eklen);
184 ek = NULL;
185
186 ret = 1;
187
188 err:
189 if (pkey)
190 EVP_PKEY_free(pkey);
191 if (pctx)
192 EVP_PKEY_CTX_free(pctx);
193 if (ek)
194 OPENSSL_free(ek);
195 return ret;
196
197 }
198
199
200static int pkcs7_decrypt_rinfo(unsigned char **pek, int *peklen,
201 PKCS7_RECIP_INFO *ri, EVP_PKEY *pkey)
202 {
203 EVP_PKEY_CTX *pctx = NULL;
204 unsigned char *ek = NULL;
205 size_t eklen;
206
207 int ret = 0;
208
209 pctx = EVP_PKEY_CTX_new(pkey, NULL);
210 if (!pctx)
211 return 0;
212
213 if (EVP_PKEY_decrypt_init(pctx) <= 0)
214 goto err;
215
216 if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_DECRYPT,
217 EVP_PKEY_CTRL_PKCS7_DECRYPT, 0, ri) <= 0)
218 {
219 PKCS7err(PKCS7_F_PKCS7_DECRYPT_RINFO, PKCS7_R_CTRL_ERROR);
220 goto err;
221 }
222
223 if (EVP_PKEY_decrypt(pctx, NULL, &eklen,
224 ri->enc_key->data, ri->enc_key->length) <= 0)
225 goto err;
226
227 ek = OPENSSL_malloc(eklen);
228
229 if (ek == NULL)
230 {
231 PKCS7err(PKCS7_F_PKCS7_DECRYPT_RINFO, ERR_R_MALLOC_FAILURE);
232 goto err;
233 }
234
235 if (EVP_PKEY_decrypt(pctx, ek, &eklen,
236 ri->enc_key->data, ri->enc_key->length) <= 0)
237 {
238 PKCS7err(PKCS7_F_PKCS7_DECRYPT_RINFO, ERR_R_EVP_LIB);
239 goto err;
240 }
241
242 ret = 1;
243
244 *pek = ek;
245 *peklen = eklen;
246
247 err:
248 if (pctx)
249 EVP_PKEY_CTX_free(pctx);
250 if (!ret && ek)
251 OPENSSL_free(ek);
252
253 return ret;
254 }
255
141BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio) 256BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio)
142 { 257 {
143 int i; 258 int i;
@@ -148,7 +263,6 @@ BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio)
148 STACK_OF(PKCS7_RECIP_INFO) *rsk=NULL; 263 STACK_OF(PKCS7_RECIP_INFO) *rsk=NULL;
149 X509_ALGOR *xalg=NULL; 264 X509_ALGOR *xalg=NULL;
150 PKCS7_RECIP_INFO *ri=NULL; 265 PKCS7_RECIP_INFO *ri=NULL;
151 EVP_PKEY *pkey;
152 ASN1_OCTET_STRING *os=NULL; 266 ASN1_OCTET_STRING *os=NULL;
153 267
154 i=OBJ_obj2nid(p7->type); 268 i=OBJ_obj2nid(p7->type);
@@ -187,6 +301,8 @@ BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio)
187 xa = p7->d.digest->md; 301 xa = p7->d.digest->md;
188 os = PKCS7_get_octet_string(p7->d.digest->contents); 302 os = PKCS7_get_octet_string(p7->d.digest->contents);
189 break; 303 break;
304 case NID_pkcs7_data:
305 break;
190 default: 306 default:
191 PKCS7err(PKCS7_F_PKCS7_DATAINIT,PKCS7_R_UNSUPPORTED_CONTENT_TYPE); 307 PKCS7err(PKCS7_F_PKCS7_DATAINIT,PKCS7_R_UNSUPPORTED_CONTENT_TYPE);
192 goto err; 308 goto err;
@@ -204,8 +320,6 @@ BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio)
204 unsigned char key[EVP_MAX_KEY_LENGTH]; 320 unsigned char key[EVP_MAX_KEY_LENGTH];
205 unsigned char iv[EVP_MAX_IV_LENGTH]; 321 unsigned char iv[EVP_MAX_IV_LENGTH];
206 int keylen,ivlen; 322 int keylen,ivlen;
207 int jj,max;
208 unsigned char *tmp;
209 EVP_CIPHER_CTX *ctx; 323 EVP_CIPHER_CTX *ctx;
210 324
211 if ((btmp=BIO_new(BIO_f_cipher())) == NULL) 325 if ((btmp=BIO_new(BIO_f_cipher())) == NULL)
@@ -234,52 +348,16 @@ BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio)
234 goto err; 348 goto err;
235 } 349 }
236 if(EVP_CIPHER_param_to_asn1(ctx, xalg->parameter) < 0) 350 if(EVP_CIPHER_param_to_asn1(ctx, xalg->parameter) < 0)
237 goto err; 351 goto err;
238 } 352 }
239 353
240 /* Lets do the pub key stuff :-) */ 354 /* Lets do the pub key stuff :-) */
241 max=0;
242 for (i=0; i<sk_PKCS7_RECIP_INFO_num(rsk); i++) 355 for (i=0; i<sk_PKCS7_RECIP_INFO_num(rsk); i++)
243 { 356 {
244 ri=sk_PKCS7_RECIP_INFO_value(rsk,i); 357 ri=sk_PKCS7_RECIP_INFO_value(rsk,i);
245 if (ri->cert == NULL) 358 if (pkcs7_encode_rinfo(ri, key, keylen) <= 0)
246 {
247 PKCS7err(PKCS7_F_PKCS7_DATAINIT,PKCS7_R_MISSING_CERIPEND_INFO);
248 goto err;
249 }
250 if ((pkey=X509_get_pubkey(ri->cert)) == NULL)
251 goto err;
252 jj=EVP_PKEY_size(pkey);
253 EVP_PKEY_free(pkey);
254 if (max < jj) max=jj;
255 }
256 if ((tmp=(unsigned char *)OPENSSL_malloc(max)) == NULL)
257 {
258 PKCS7err(PKCS7_F_PKCS7_DATAINIT,ERR_R_MALLOC_FAILURE);
259 goto err;
260 }
261 for (i=0; i<sk_PKCS7_RECIP_INFO_num(rsk); i++)
262 {
263 ri=sk_PKCS7_RECIP_INFO_value(rsk,i);
264 if ((pkey=X509_get_pubkey(ri->cert)) == NULL)
265 goto err;
266 jj=EVP_PKEY_encrypt(tmp,key,keylen,pkey);
267 EVP_PKEY_free(pkey);
268 if (jj <= 0)
269 {
270 PKCS7err(PKCS7_F_PKCS7_DATAINIT,ERR_R_EVP_LIB);
271 OPENSSL_free(tmp);
272 goto err; 359 goto err;
273 }
274 if (!M_ASN1_OCTET_STRING_set(ri->enc_key,tmp,jj))
275 {
276 PKCS7err(PKCS7_F_PKCS7_DATAINIT,
277 ERR_R_MALLOC_FAILURE);
278 OPENSSL_free(tmp);
279 goto err;
280 }
281 } 360 }
282 OPENSSL_free(tmp);
283 OPENSSL_cleanse(key, keylen); 361 OPENSSL_cleanse(key, keylen);
284 362
285 if (out == NULL) 363 if (out == NULL)
@@ -303,7 +381,10 @@ BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio)
303 BIO_set_mem_eof_return(bio,0); 381 BIO_set_mem_eof_return(bio,0);
304 } 382 }
305 } 383 }
306 BIO_push(out,bio); 384 if (out)
385 BIO_push(out,bio);
386 else
387 out = bio;
307 bio=NULL; 388 bio=NULL;
308 if (0) 389 if (0)
309 { 390 {
@@ -333,7 +414,6 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert)
333 { 414 {
334 int i,j; 415 int i,j;
335 BIO *out=NULL,*btmp=NULL,*etmp=NULL,*bio=NULL; 416 BIO *out=NULL,*btmp=NULL,*etmp=NULL,*bio=NULL;
336 unsigned char *tmp=NULL;
337 X509_ALGOR *xa; 417 X509_ALGOR *xa;
338 ASN1_OCTET_STRING *data_body=NULL; 418 ASN1_OCTET_STRING *data_body=NULL;
339 const EVP_MD *evp_md; 419 const EVP_MD *evp_md;
@@ -423,7 +503,8 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert)
423 int max; 503 int max;
424 X509_OBJECT ret; 504 X509_OBJECT ret;
425#endif 505#endif
426 int jj; 506 unsigned char *ek = NULL;
507 int eklen;
427 508
428 if ((etmp=BIO_new(BIO_f_cipher())) == NULL) 509 if ((etmp=BIO_new(BIO_f_cipher())) == NULL)
429 { 510 {
@@ -438,26 +519,21 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert)
438 * (if any) 519 * (if any)
439 */ 520 */
440 521
441 if (pcert) { 522 if (pcert)
442 for (i=0; i<sk_PKCS7_RECIP_INFO_num(rsk); i++) { 523 {
524 for (i=0; i<sk_PKCS7_RECIP_INFO_num(rsk); i++)
525 {
443 ri=sk_PKCS7_RECIP_INFO_value(rsk,i); 526 ri=sk_PKCS7_RECIP_INFO_value(rsk,i);
444 if (!pkcs7_cmp_ri(ri, pcert)) 527 if (!pkcs7_cmp_ri(ri, pcert))
445 break; 528 break;
446 ri=NULL; 529 ri=NULL;
447 } 530 }
448 if (ri == NULL) { 531 if (ri == NULL)
532 {
449 PKCS7err(PKCS7_F_PKCS7_DATADECODE, 533 PKCS7err(PKCS7_F_PKCS7_DATADECODE,
450 PKCS7_R_NO_RECIPIENT_MATCHES_CERTIFICATE); 534 PKCS7_R_NO_RECIPIENT_MATCHES_CERTIFICATE);
451 goto err; 535 goto err;
452 } 536 }
453 }
454
455 jj=EVP_PKEY_size(pkey);
456 tmp=(unsigned char *)OPENSSL_malloc(jj+10);
457 if (tmp == NULL)
458 {
459 PKCS7err(PKCS7_F_PKCS7_DATADECODE,ERR_R_MALLOC_FAILURE);
460 goto err;
461 } 537 }
462 538
463 /* If we haven't got a certificate try each ri in turn */ 539 /* If we haven't got a certificate try each ri in turn */
@@ -467,11 +543,8 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert)
467 for (i=0; i<sk_PKCS7_RECIP_INFO_num(rsk); i++) 543 for (i=0; i<sk_PKCS7_RECIP_INFO_num(rsk); i++)
468 { 544 {
469 ri=sk_PKCS7_RECIP_INFO_value(rsk,i); 545 ri=sk_PKCS7_RECIP_INFO_value(rsk,i);
470 jj=EVP_PKEY_decrypt(tmp, 546 if (pkcs7_decrypt_rinfo(&ek, &eklen,
471 M_ASN1_STRING_data(ri->enc_key), 547 ri, pkey) > 0)
472 M_ASN1_STRING_length(ri->enc_key),
473 pkey);
474 if (jj > 0)
475 break; 548 break;
476 ERR_clear_error(); 549 ERR_clear_error();
477 ri = NULL; 550 ri = NULL;
@@ -485,15 +558,8 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert)
485 } 558 }
486 else 559 else
487 { 560 {
488 jj=EVP_PKEY_decrypt(tmp, 561 if (pkcs7_decrypt_rinfo(&ek, &eklen, ri, pkey) <= 0)
489 M_ASN1_STRING_data(ri->enc_key),
490 M_ASN1_STRING_length(ri->enc_key), pkey);
491 if (jj <= 0)
492 {
493 PKCS7err(PKCS7_F_PKCS7_DATADECODE,
494 ERR_R_EVP_LIB);
495 goto err; 562 goto err;
496 }
497 } 563 }
498 564
499 evp_ctx=NULL; 565 evp_ctx=NULL;
@@ -503,22 +569,26 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert)
503 if (EVP_CIPHER_asn1_to_param(evp_ctx,enc_alg->parameter) < 0) 569 if (EVP_CIPHER_asn1_to_param(evp_ctx,enc_alg->parameter) < 0)
504 goto err; 570 goto err;
505 571
506 if (jj != EVP_CIPHER_CTX_key_length(evp_ctx)) { 572 if (eklen != EVP_CIPHER_CTX_key_length(evp_ctx)) {
507 /* Some S/MIME clients don't use the same key 573 /* Some S/MIME clients don't use the same key
508 * and effective key length. The key length is 574 * and effective key length. The key length is
509 * determined by the size of the decrypted RSA key. 575 * determined by the size of the decrypted RSA key.
510 */ 576 */
511 if(!EVP_CIPHER_CTX_set_key_length(evp_ctx, jj)) 577 if(!EVP_CIPHER_CTX_set_key_length(evp_ctx, eklen))
512 { 578 {
513 PKCS7err(PKCS7_F_PKCS7_DATADECODE, 579 PKCS7err(PKCS7_F_PKCS7_DATADECODE,
514 PKCS7_R_DECRYPTED_KEY_IS_WRONG_LENGTH); 580 PKCS7_R_DECRYPTED_KEY_IS_WRONG_LENGTH);
515 goto err; 581 goto err;
516 } 582 }
517 } 583 }
518 if (EVP_CipherInit_ex(evp_ctx,NULL,NULL,tmp,NULL,0) <= 0) 584 if (EVP_CipherInit_ex(evp_ctx,NULL,NULL,ek,NULL,0) <= 0)
519 goto err; 585 goto err;
520 586
521 OPENSSL_cleanse(tmp,jj); 587 if (ek)
588 {
589 OPENSSL_cleanse(ek,eklen);
590 OPENSSL_free(ek);
591 }
522 592
523 if (out == NULL) 593 if (out == NULL)
524 out=etmp; 594 out=etmp;
@@ -566,8 +636,6 @@ err:
566 if (bio != NULL) BIO_free_all(bio); 636 if (bio != NULL) BIO_free_all(bio);
567 out=NULL; 637 out=NULL;
568 } 638 }
569 if (tmp != NULL)
570 OPENSSL_free(tmp);
571 return(out); 639 return(out);
572 } 640 }
573 641
@@ -594,13 +662,43 @@ static BIO *PKCS7_find_digest(EVP_MD_CTX **pmd, BIO *bio, int nid)
594 return NULL; 662 return NULL;
595 } 663 }
596 664
665static int do_pkcs7_signed_attrib(PKCS7_SIGNER_INFO *si, EVP_MD_CTX *mctx)
666 {
667 unsigned char md_data[EVP_MAX_MD_SIZE];
668 unsigned int md_len;
669
670 /* Add signing time if not already present */
671 if (!PKCS7_get_signed_attribute(si, NID_pkcs9_signingTime))
672 {
673 if (!PKCS7_add0_attrib_signing_time(si, NULL))
674 {
675 PKCS7err(PKCS7_F_DO_PKCS7_SIGNED_ATTRIB,
676 ERR_R_MALLOC_FAILURE);
677 return 0;
678 }
679 }
680
681 /* Add digest */
682 EVP_DigestFinal_ex(mctx, md_data,&md_len);
683 if (!PKCS7_add1_attrib_digest(si, md_data, md_len))
684 {
685 PKCS7err(PKCS7_F_DO_PKCS7_SIGNED_ATTRIB, ERR_R_MALLOC_FAILURE);
686 return 0;
687 }
688
689 /* Now sign the attributes */
690 if (!PKCS7_SIGNER_INFO_sign(si))
691 return 0;
692
693 return 1;
694 }
695
696
597int PKCS7_dataFinal(PKCS7 *p7, BIO *bio) 697int PKCS7_dataFinal(PKCS7 *p7, BIO *bio)
598 { 698 {
599 int ret=0; 699 int ret=0;
600 int i,j; 700 int i,j;
601 BIO *btmp; 701 BIO *btmp;
602 BUF_MEM *buf_mem=NULL;
603 BUF_MEM *buf=NULL;
604 PKCS7_SIGNER_INFO *si; 702 PKCS7_SIGNER_INFO *si;
605 EVP_MD_CTX *mdc,ctx_tmp; 703 EVP_MD_CTX *mdc,ctx_tmp;
606 STACK_OF(X509_ATTRIBUTE) *sk; 704 STACK_OF(X509_ATTRIBUTE) *sk;
@@ -613,24 +711,37 @@ int PKCS7_dataFinal(PKCS7 *p7, BIO *bio)
613 711
614 switch (i) 712 switch (i)
615 { 713 {
714 case NID_pkcs7_data:
715 os = p7->d.data;
716 break;
616 case NID_pkcs7_signedAndEnveloped: 717 case NID_pkcs7_signedAndEnveloped:
617 /* XXXXXXXXXXXXXXXX */ 718 /* XXXXXXXXXXXXXXXX */
618 si_sk=p7->d.signed_and_enveloped->signer_info; 719 si_sk=p7->d.signed_and_enveloped->signer_info;
619 if (!(os=M_ASN1_OCTET_STRING_new())) 720 os = p7->d.signed_and_enveloped->enc_data->enc_data;
721 if (!os)
620 { 722 {
621 PKCS7err(PKCS7_F_PKCS7_DATAFINAL,ERR_R_MALLOC_FAILURE); 723 os=M_ASN1_OCTET_STRING_new();
622 goto err; 724 if (!os)
725 {
726 PKCS7err(PKCS7_F_PKCS7_DATAFINAL,ERR_R_MALLOC_FAILURE);
727 goto err;
728 }
729 p7->d.signed_and_enveloped->enc_data->enc_data=os;
623 } 730 }
624 p7->d.signed_and_enveloped->enc_data->enc_data=os;
625 break; 731 break;
626 case NID_pkcs7_enveloped: 732 case NID_pkcs7_enveloped:
627 /* XXXXXXXXXXXXXXXX */ 733 /* XXXXXXXXXXXXXXXX */
628 if (!(os=M_ASN1_OCTET_STRING_new())) 734 os = p7->d.enveloped->enc_data->enc_data;
735 if (!os)
629 { 736 {
630 PKCS7err(PKCS7_F_PKCS7_DATAFINAL,ERR_R_MALLOC_FAILURE); 737 os=M_ASN1_OCTET_STRING_new();
631 goto err; 738 if (!os)
739 {
740 PKCS7err(PKCS7_F_PKCS7_DATAFINAL,ERR_R_MALLOC_FAILURE);
741 goto err;
742 }
743 p7->d.enveloped->enc_data->enc_data=os;
632 } 744 }
633 p7->d.enveloped->enc_data->enc_data=os;
634 break; 745 break;
635 case NID_pkcs7_signed: 746 case NID_pkcs7_signed:
636 si_sk=p7->d.sign->signer_info; 747 si_sk=p7->d.sign->signer_info;
@@ -652,21 +763,20 @@ int PKCS7_dataFinal(PKCS7 *p7, BIO *bio)
652 } 763 }
653 break; 764 break;
654 765
766 default:
767 PKCS7err(PKCS7_F_PKCS7_DATAFINAL,PKCS7_R_UNSUPPORTED_CONTENT_TYPE);
768 goto err;
655 } 769 }
656 770
657 if (si_sk != NULL) 771 if (si_sk != NULL)
658 { 772 {
659 if ((buf=BUF_MEM_new()) == NULL)
660 {
661 PKCS7err(PKCS7_F_PKCS7_DATAFINAL,ERR_R_BIO_LIB);
662 goto err;
663 }
664 for (i=0; i<sk_PKCS7_SIGNER_INFO_num(si_sk); i++) 773 for (i=0; i<sk_PKCS7_SIGNER_INFO_num(si_sk); i++)
665 { 774 {
666 si=sk_PKCS7_SIGNER_INFO_value(si_sk,i); 775 si=sk_PKCS7_SIGNER_INFO_value(si_sk,i);
667 if (si->pkey == NULL) continue; 776 if (si->pkey == NULL)
777 continue;
668 778
669 j=OBJ_obj2nid(si->digest_alg->algorithm); 779 j = OBJ_obj2nid(si->digest_alg->algorithm);
670 780
671 btmp=bio; 781 btmp=bio;
672 782
@@ -678,97 +788,33 @@ int PKCS7_dataFinal(PKCS7 *p7, BIO *bio)
678 /* We now have the EVP_MD_CTX, lets do the 788 /* We now have the EVP_MD_CTX, lets do the
679 * signing. */ 789 * signing. */
680 EVP_MD_CTX_copy_ex(&ctx_tmp,mdc); 790 EVP_MD_CTX_copy_ex(&ctx_tmp,mdc);
681 if (!BUF_MEM_grow_clean(buf,EVP_PKEY_size(si->pkey)))
682 {
683 PKCS7err(PKCS7_F_PKCS7_DATAFINAL,ERR_R_BIO_LIB);
684 goto err;
685 }
686 791
687 sk=si->auth_attr; 792 sk=si->auth_attr;
688 793
689 /* If there are attributes, we add the digest 794 /* If there are attributes, we add the digest
690 * attribute and only sign the attributes */ 795 * attribute and only sign the attributes */
691 if ((sk != NULL) && (sk_X509_ATTRIBUTE_num(sk) != 0)) 796 if (sk_X509_ATTRIBUTE_num(sk) > 0)
692 { 797 {
693 unsigned char md_data[EVP_MAX_MD_SIZE], *abuf=NULL; 798 if (!do_pkcs7_signed_attrib(si, &ctx_tmp))
694 unsigned int md_len, alen;
695 ASN1_OCTET_STRING *digest;
696 ASN1_UTCTIME *sign_time;
697 const EVP_MD *md_tmp;
698
699 /* Add signing time if not already present */
700 if (!PKCS7_get_signed_attribute(si,
701 NID_pkcs9_signingTime))
702 {
703 if (!(sign_time=X509_gmtime_adj(NULL,0)))
704 {
705 PKCS7err(PKCS7_F_PKCS7_DATAFINAL,
706 ERR_R_MALLOC_FAILURE);
707 goto err;
708 }
709 if (!PKCS7_add_signed_attribute(si,
710 NID_pkcs9_signingTime,
711 V_ASN1_UTCTIME,sign_time))
712 {
713 M_ASN1_UTCTIME_free(sign_time);
714 goto err;
715 }
716 }
717
718 /* Add digest */
719 md_tmp=EVP_MD_CTX_md(&ctx_tmp);
720 EVP_DigestFinal_ex(&ctx_tmp,md_data,&md_len);
721 if (!(digest=M_ASN1_OCTET_STRING_new()))
722 {
723 PKCS7err(PKCS7_F_PKCS7_DATAFINAL,
724 ERR_R_MALLOC_FAILURE);
725 goto err; 799 goto err;
726 } 800 }
727 if (!M_ASN1_OCTET_STRING_set(digest,md_data, 801 else
728 md_len)) 802 {
729 { 803 unsigned char *abuf = NULL;
730 PKCS7err(PKCS7_F_PKCS7_DATAFINAL, 804 unsigned int abuflen;
731 ERR_R_MALLOC_FAILURE); 805 abuflen = EVP_PKEY_size(si->pkey);
732 M_ASN1_OCTET_STRING_free(digest); 806 abuf = OPENSSL_malloc(abuflen);
807 if (!abuf)
733 goto err; 808 goto err;
734 } 809
735 if (!PKCS7_add_signed_attribute(si, 810 if (!EVP_SignFinal(&ctx_tmp, abuf, &abuflen,
736 NID_pkcs9_messageDigest, 811 si->pkey))
737 V_ASN1_OCTET_STRING,digest))
738 { 812 {
739 M_ASN1_OCTET_STRING_free(digest); 813 PKCS7err(PKCS7_F_PKCS7_DATAFINAL,
814 ERR_R_EVP_LIB);
740 goto err; 815 goto err;
741 } 816 }
742 817 ASN1_STRING_set0(si->enc_digest, abuf, abuflen);
743 /* Now sign the attributes */
744 EVP_SignInit_ex(&ctx_tmp,md_tmp,NULL);
745 alen = ASN1_item_i2d((ASN1_VALUE *)sk,&abuf,
746 ASN1_ITEM_rptr(PKCS7_ATTR_SIGN));
747 if(!abuf) goto err;
748 EVP_SignUpdate(&ctx_tmp,abuf,alen);
749 OPENSSL_free(abuf);
750 }
751
752#ifndef OPENSSL_NO_DSA
753 if (si->pkey->type == EVP_PKEY_DSA)
754 ctx_tmp.digest=EVP_dss1();
755#endif
756#ifndef OPENSSL_NO_ECDSA
757 if (si->pkey->type == EVP_PKEY_EC)
758 ctx_tmp.digest=EVP_ecdsa();
759#endif
760
761 if (!EVP_SignFinal(&ctx_tmp,(unsigned char *)buf->data,
762 (unsigned int *)&buf->length,si->pkey))
763 {
764 PKCS7err(PKCS7_F_PKCS7_DATAFINAL,ERR_R_EVP_LIB);
765 goto err;
766 }
767 if (!ASN1_STRING_set(si->enc_digest,
768 (unsigned char *)buf->data,buf->length))
769 {
770 PKCS7err(PKCS7_F_PKCS7_DATAFINAL,ERR_R_ASN1_LIB);
771 goto err;
772 } 818 }
773 } 819 }
774 } 820 }
@@ -783,34 +829,90 @@ int PKCS7_dataFinal(PKCS7 *p7, BIO *bio)
783 M_ASN1_OCTET_STRING_set(p7->d.digest->digest, md_data, md_len); 829 M_ASN1_OCTET_STRING_set(p7->d.digest->digest, md_data, md_len);
784 } 830 }
785 831
786 if (!PKCS7_is_detached(p7)) 832 if (!PKCS7_is_detached(p7) && !(os->flags & ASN1_STRING_FLAG_NDEF))
787 { 833 {
834 char *cont;
835 long contlen;
788 btmp=BIO_find_type(bio,BIO_TYPE_MEM); 836 btmp=BIO_find_type(bio,BIO_TYPE_MEM);
789 if (btmp == NULL) 837 if (btmp == NULL)
790 { 838 {
791 PKCS7err(PKCS7_F_PKCS7_DATAFINAL,PKCS7_R_UNABLE_TO_FIND_MEM_BIO); 839 PKCS7err(PKCS7_F_PKCS7_DATAFINAL,PKCS7_R_UNABLE_TO_FIND_MEM_BIO);
792 goto err; 840 goto err;
793 } 841 }
794 BIO_get_mem_ptr(btmp,&buf_mem); 842 contlen = BIO_get_mem_data(btmp, &cont);
795 /* Mark the BIO read only then we can use its copy of the data 843 /* Mark the BIO read only then we can use its copy of the data
796 * instead of making an extra copy. 844 * instead of making an extra copy.
797 */ 845 */
798 BIO_set_flags(btmp, BIO_FLAGS_MEM_RDONLY); 846 BIO_set_flags(btmp, BIO_FLAGS_MEM_RDONLY);
799 BIO_set_mem_eof_return(btmp, 0); 847 BIO_set_mem_eof_return(btmp, 0);
800 os->data = (unsigned char *)buf_mem->data; 848 ASN1_STRING_set0(os, (unsigned char *)cont, contlen);
801 os->length = buf_mem->length;
802#if 0
803 M_ASN1_OCTET_STRING_set(os,
804 (unsigned char *)buf_mem->data,buf_mem->length);
805#endif
806 } 849 }
807 ret=1; 850 ret=1;
808err: 851err:
809 EVP_MD_CTX_cleanup(&ctx_tmp); 852 EVP_MD_CTX_cleanup(&ctx_tmp);
810 if (buf != NULL) BUF_MEM_free(buf);
811 return(ret); 853 return(ret);
812 } 854 }
813 855
856int PKCS7_SIGNER_INFO_sign(PKCS7_SIGNER_INFO *si)
857 {
858 EVP_MD_CTX mctx;
859 EVP_PKEY_CTX *pctx;
860 unsigned char *abuf = NULL;
861 int alen;
862 size_t siglen;
863 const EVP_MD *md = NULL;
864
865 md = EVP_get_digestbyobj(si->digest_alg->algorithm);
866 if (md == NULL)
867 return 0;
868
869 EVP_MD_CTX_init(&mctx);
870 if (EVP_DigestSignInit(&mctx, &pctx, md,NULL, si->pkey) <= 0)
871 goto err;
872
873 if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_SIGN,
874 EVP_PKEY_CTRL_PKCS7_SIGN, 0, si) <= 0)
875 {
876 PKCS7err(PKCS7_F_PKCS7_SIGNER_INFO_SIGN, PKCS7_R_CTRL_ERROR);
877 goto err;
878 }
879
880 alen = ASN1_item_i2d((ASN1_VALUE *)si->auth_attr,&abuf,
881 ASN1_ITEM_rptr(PKCS7_ATTR_SIGN));
882 if(!abuf)
883 goto err;
884 if (EVP_DigestSignUpdate(&mctx,abuf,alen) <= 0)
885 goto err;
886 OPENSSL_free(abuf);
887 if (EVP_DigestSignFinal(&mctx, NULL, &siglen) <= 0)
888 goto err;
889 abuf = OPENSSL_malloc(siglen);
890 if(!abuf)
891 goto err;
892 if (EVP_DigestSignFinal(&mctx, abuf, &siglen) <= 0)
893 goto err;
894
895 if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_SIGN,
896 EVP_PKEY_CTRL_PKCS7_SIGN, 1, si) <= 0)
897 {
898 PKCS7err(PKCS7_F_PKCS7_SIGNER_INFO_SIGN, PKCS7_R_CTRL_ERROR);
899 goto err;
900 }
901
902 EVP_MD_CTX_cleanup(&mctx);
903
904 ASN1_STRING_set0(si->enc_digest, abuf, siglen);
905
906 return 1;
907
908 err:
909 if (abuf)
910 OPENSSL_free(abuf);
911 EVP_MD_CTX_cleanup(&mctx);
912 return 0;
913
914 }
915
814int PKCS7_dataVerify(X509_STORE *cert_store, X509_STORE_CTX *ctx, BIO *bio, 916int PKCS7_dataVerify(X509_STORE *cert_store, X509_STORE_CTX *ctx, BIO *bio,
815 PKCS7 *p7, PKCS7_SIGNER_INFO *si) 917 PKCS7 *p7, PKCS7_SIGNER_INFO *si)
816 { 918 {
@@ -922,7 +1024,8 @@ int PKCS7_signatureVerify(BIO *bio, PKCS7 *p7, PKCS7_SIGNER_INFO *si,
922 if ((sk != NULL) && (sk_X509_ATTRIBUTE_num(sk) != 0)) 1024 if ((sk != NULL) && (sk_X509_ATTRIBUTE_num(sk) != 0))
923 { 1025 {
924 unsigned char md_dat[EVP_MAX_MD_SIZE], *abuf = NULL; 1026 unsigned char md_dat[EVP_MAX_MD_SIZE], *abuf = NULL;
925 unsigned int md_len, alen; 1027 unsigned int md_len;
1028 int alen;
926 ASN1_OCTET_STRING *message_digest; 1029 ASN1_OCTET_STRING *message_digest;
927 1030
928 EVP_DigestFinal_ex(&mdc_tmp,md_dat,&md_len); 1031 EVP_DigestFinal_ex(&mdc_tmp,md_dat,&md_len);
@@ -954,6 +1057,12 @@ for (ii=0; ii<md_len; ii++) printf("%02X",md_dat[ii]); printf(" calc\n");
954 1057
955 alen = ASN1_item_i2d((ASN1_VALUE *)sk, &abuf, 1058 alen = ASN1_item_i2d((ASN1_VALUE *)sk, &abuf,
956 ASN1_ITEM_rptr(PKCS7_ATTR_VERIFY)); 1059 ASN1_ITEM_rptr(PKCS7_ATTR_VERIFY));
1060 if (alen <= 0)
1061 {
1062 PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY,ERR_R_ASN1_LIB);
1063 ret = -1;
1064 goto err;
1065 }
957 EVP_VerifyUpdate(&mdc_tmp, abuf, alen); 1066 EVP_VerifyUpdate(&mdc_tmp, abuf, alen);
958 1067
959 OPENSSL_free(abuf); 1068 OPENSSL_free(abuf);
@@ -966,12 +1075,6 @@ for (ii=0; ii<md_len; ii++) printf("%02X",md_dat[ii]); printf(" calc\n");
966 ret = -1; 1075 ret = -1;
967 goto err; 1076 goto err;
968 } 1077 }
969#ifndef OPENSSL_NO_DSA
970 if(pkey->type == EVP_PKEY_DSA) mdc_tmp.digest=EVP_dss1();
971#endif
972#ifndef OPENSSL_NO_ECDSA
973 if (pkey->type == EVP_PKEY_EC) mdc_tmp.digest=EVP_ecdsa();
974#endif
975 1078
976 i=EVP_VerifyFinal(&mdc_tmp,os->data,os->length, pkey); 1079 i=EVP_VerifyFinal(&mdc_tmp,os->data,os->length, pkey);
977 EVP_PKEY_free(pkey); 1080 EVP_PKEY_free(pkey);
@@ -1107,8 +1210,9 @@ static int add_attribute(STACK_OF(X509_ATTRIBUTE) **sk, int nid, int atrtype,
1107 1210
1108 if (*sk == NULL) 1211 if (*sk == NULL)
1109 { 1212 {
1110 if (!(*sk = sk_X509_ATTRIBUTE_new_null())) 1213 *sk = sk_X509_ATTRIBUTE_new_null();
1111 return 0; 1214 if (*sk == NULL)
1215 return 0;
1112new_attrib: 1216new_attrib:
1113 if (!(attr=X509_ATTRIBUTE_create(nid,atrtype,value))) 1217 if (!(attr=X509_ATTRIBUTE_create(nid,atrtype,value)))
1114 return 0; 1218 return 0;
diff --git a/src/lib/libcrypto/pkcs7/pk7_lib.c b/src/lib/libcrypto/pkcs7/pk7_lib.c
index f2490941a3..3ca0952792 100644
--- a/src/lib/libcrypto/pkcs7/pk7_lib.c
+++ b/src/lib/libcrypto/pkcs7/pk7_lib.c
@@ -60,6 +60,7 @@
60#include "cryptlib.h" 60#include "cryptlib.h"
61#include <openssl/objects.h> 61#include <openssl/objects.h>
62#include <openssl/x509.h> 62#include <openssl/x509.h>
63#include "asn1_locl.h"
63 64
64long PKCS7_ctrl(PKCS7 *p7, int cmd, long larg, char *parg) 65long PKCS7_ctrl(PKCS7 *p7, int cmd, long larg, char *parg)
65 { 66 {
@@ -314,7 +315,7 @@ int PKCS7_add_certificate(PKCS7 *p7, X509 *x509)
314 *sk=sk_X509_new_null(); 315 *sk=sk_X509_new_null();
315 if (*sk == NULL) 316 if (*sk == NULL)
316 { 317 {
317 PKCS7err(PKCS7_F_PKCS7_ADD_CERTIFICATE,ERR_R_MALLOC_FAILURE); 318 PKCS7err(PKCS7_F_PKCS7_ADD_CERTIFICATE, ERR_R_MALLOC_FAILURE);
318 return 0; 319 return 0;
319 } 320 }
320 CRYPTO_add(&x509->references,1,CRYPTO_LOCK_X509); 321 CRYPTO_add(&x509->references,1,CRYPTO_LOCK_X509);
@@ -365,13 +366,8 @@ int PKCS7_add_crl(PKCS7 *p7, X509_CRL *crl)
365int PKCS7_SIGNER_INFO_set(PKCS7_SIGNER_INFO *p7i, X509 *x509, EVP_PKEY *pkey, 366int PKCS7_SIGNER_INFO_set(PKCS7_SIGNER_INFO *p7i, X509 *x509, EVP_PKEY *pkey,
366 const EVP_MD *dgst) 367 const EVP_MD *dgst)
367 { 368 {
368 int nid; 369 int ret;
369 char is_dsa;
370 370
371 if (pkey->type == EVP_PKEY_DSA || pkey->type == EVP_PKEY_EC)
372 is_dsa = 1;
373 else
374 is_dsa = 0;
375 /* We now need to add another PKCS7_SIGNER_INFO entry */ 371 /* We now need to add another PKCS7_SIGNER_INFO entry */
376 if (!ASN1_INTEGER_set(p7i->version,1)) 372 if (!ASN1_INTEGER_set(p7i->version,1))
377 goto err; 373 goto err;
@@ -391,65 +387,55 @@ int PKCS7_SIGNER_INFO_set(PKCS7_SIGNER_INFO *p7i, X509 *x509, EVP_PKEY *pkey,
391 p7i->pkey=pkey; 387 p7i->pkey=pkey;
392 388
393 /* Set the algorithms */ 389 /* Set the algorithms */
394 if (is_dsa) p7i->digest_alg->algorithm=OBJ_nid2obj(NID_sha1);
395 else
396 p7i->digest_alg->algorithm=OBJ_nid2obj(EVP_MD_type(dgst));
397 390
398 if (p7i->digest_alg->parameter != NULL) 391 X509_ALGOR_set0(p7i->digest_alg, OBJ_nid2obj(EVP_MD_type(dgst)),
399 ASN1_TYPE_free(p7i->digest_alg->parameter); 392 V_ASN1_NULL, NULL);
400 if ((p7i->digest_alg->parameter=ASN1_TYPE_new()) == NULL)
401 goto err;
402 p7i->digest_alg->parameter->type=V_ASN1_NULL;
403 393
404 if (p7i->digest_enc_alg->parameter != NULL) 394 if (pkey->ameth && pkey->ameth->pkey_ctrl)
405 ASN1_TYPE_free(p7i->digest_enc_alg->parameter);
406 nid = EVP_PKEY_type(pkey->type);
407 if (nid == EVP_PKEY_RSA)
408 { 395 {
409 p7i->digest_enc_alg->algorithm=OBJ_nid2obj(NID_rsaEncryption); 396 ret = pkey->ameth->pkey_ctrl(pkey, ASN1_PKEY_CTRL_PKCS7_SIGN,
410 if (!(p7i->digest_enc_alg->parameter=ASN1_TYPE_new())) 397 0, p7i);
411 goto err; 398 if (ret > 0)
412 p7i->digest_enc_alg->parameter->type=V_ASN1_NULL; 399 return 1;
413 } 400 if (ret != -2)
414 else if (nid == EVP_PKEY_DSA) 401 {
415 { 402 PKCS7err(PKCS7_F_PKCS7_SIGNER_INFO_SET,
416#if 1 403 PKCS7_R_SIGNING_CTRL_FAILURE);
417 /* use 'dsaEncryption' OID for compatibility with other software 404 return 0;
418 * (PKCS #7 v1.5 does specify how to handle DSA) ... */ 405 }
419 p7i->digest_enc_alg->algorithm=OBJ_nid2obj(NID_dsa);
420#else
421 /* ... although the 'dsaWithSHA1' OID (as required by RFC 2630 for CMS)
422 * would make more sense. */
423 p7i->digest_enc_alg->algorithm=OBJ_nid2obj(NID_dsaWithSHA1);
424#endif
425 p7i->digest_enc_alg->parameter = NULL; /* special case for DSA: omit 'parameter'! */
426 }
427 else if (nid == EVP_PKEY_EC)
428 {
429 p7i->digest_enc_alg->algorithm=OBJ_nid2obj(NID_ecdsa_with_SHA1);
430 if (!(p7i->digest_enc_alg->parameter=ASN1_TYPE_new()))
431 goto err;
432 p7i->digest_enc_alg->parameter->type=V_ASN1_NULL;
433 } 406 }
434 else 407 PKCS7err(PKCS7_F_PKCS7_SIGNER_INFO_SET,
435 return(0); 408 PKCS7_R_SIGNING_NOT_SUPPORTED_FOR_THIS_KEY_TYPE);
436
437 return(1);
438err: 409err:
439 return(0); 410 return 0;
440 } 411 }
441 412
442PKCS7_SIGNER_INFO *PKCS7_add_signature(PKCS7 *p7, X509 *x509, EVP_PKEY *pkey, 413PKCS7_SIGNER_INFO *PKCS7_add_signature(PKCS7 *p7, X509 *x509, EVP_PKEY *pkey,
443 const EVP_MD *dgst) 414 const EVP_MD *dgst)
444 { 415 {
445 PKCS7_SIGNER_INFO *si; 416 PKCS7_SIGNER_INFO *si = NULL;
417
418 if (dgst == NULL)
419 {
420 int def_nid;
421 if (EVP_PKEY_get_default_digest_nid(pkey, &def_nid) <= 0)
422 goto err;
423 dgst = EVP_get_digestbynid(def_nid);
424 if (dgst == NULL)
425 {
426 PKCS7err(PKCS7_F_PKCS7_ADD_SIGNATURE,
427 PKCS7_R_NO_DEFAULT_DIGEST);
428 goto err;
429 }
430 }
446 431
447 if ((si=PKCS7_SIGNER_INFO_new()) == NULL) goto err; 432 if ((si=PKCS7_SIGNER_INFO_new()) == NULL) goto err;
448 if (!PKCS7_SIGNER_INFO_set(si,x509,pkey,dgst)) goto err; 433 if (!PKCS7_SIGNER_INFO_set(si,x509,pkey,dgst)) goto err;
449 if (!PKCS7_add_signer(p7,si)) goto err; 434 if (!PKCS7_add_signer(p7,si)) goto err;
450 return(si); 435 return(si);
451err: 436err:
452 PKCS7_SIGNER_INFO_free(si); 437 if (si)
438 PKCS7_SIGNER_INFO_free(si);
453 return(NULL); 439 return(NULL);
454 } 440 }
455 441
@@ -485,6 +471,23 @@ STACK_OF(PKCS7_SIGNER_INFO) *PKCS7_get_signer_info(PKCS7 *p7)
485 return(NULL); 471 return(NULL);
486 } 472 }
487 473
474void PKCS7_SIGNER_INFO_get0_algs(PKCS7_SIGNER_INFO *si, EVP_PKEY **pk,
475 X509_ALGOR **pdig, X509_ALGOR **psig)
476 {
477 if (pk)
478 *pk = si->pkey;
479 if (pdig)
480 *pdig = si->digest_alg;
481 if (psig)
482 *psig = si->digest_enc_alg;
483 }
484
485void PKCS7_RECIP_INFO_get0_alg(PKCS7_RECIP_INFO *ri, X509_ALGOR **penc)
486 {
487 if (penc)
488 *penc = ri->key_enc_algor;
489 }
490
488PKCS7_RECIP_INFO *PKCS7_add_recipient(PKCS7 *p7, X509 *x509) 491PKCS7_RECIP_INFO *PKCS7_add_recipient(PKCS7 *p7, X509 *x509)
489 { 492 {
490 PKCS7_RECIP_INFO *ri; 493 PKCS7_RECIP_INFO *ri;
@@ -492,10 +495,11 @@ PKCS7_RECIP_INFO *PKCS7_add_recipient(PKCS7 *p7, X509 *x509)
492 if ((ri=PKCS7_RECIP_INFO_new()) == NULL) goto err; 495 if ((ri=PKCS7_RECIP_INFO_new()) == NULL) goto err;
493 if (!PKCS7_RECIP_INFO_set(ri,x509)) goto err; 496 if (!PKCS7_RECIP_INFO_set(ri,x509)) goto err;
494 if (!PKCS7_add_recipient_info(p7,ri)) goto err; 497 if (!PKCS7_add_recipient_info(p7,ri)) goto err;
495 return(ri); 498 return ri;
496err: 499err:
497 PKCS7_RECIP_INFO_free(ri); 500 if (ri)
498 return(NULL); 501 PKCS7_RECIP_INFO_free(ri);
502 return NULL;
499 } 503 }
500 504
501int PKCS7_add_recipient_info(PKCS7 *p7, PKCS7_RECIP_INFO *ri) 505int PKCS7_add_recipient_info(PKCS7 *p7, PKCS7_RECIP_INFO *ri)
@@ -524,6 +528,8 @@ int PKCS7_add_recipient_info(PKCS7 *p7, PKCS7_RECIP_INFO *ri)
524 528
525int PKCS7_RECIP_INFO_set(PKCS7_RECIP_INFO *p7i, X509 *x509) 529int PKCS7_RECIP_INFO_set(PKCS7_RECIP_INFO *p7i, X509 *x509)
526 { 530 {
531 int ret;
532 EVP_PKEY *pkey = NULL;
527 if (!ASN1_INTEGER_set(p7i->version,0)) 533 if (!ASN1_INTEGER_set(p7i->version,0))
528 return 0; 534 return 0;
529 if (!X509_NAME_set(&p7i->issuer_and_serial->issuer, 535 if (!X509_NAME_set(&p7i->issuer_and_serial->issuer,
@@ -535,14 +541,41 @@ int PKCS7_RECIP_INFO_set(PKCS7_RECIP_INFO *p7i, X509 *x509)
535 M_ASN1_INTEGER_dup(X509_get_serialNumber(x509)))) 541 M_ASN1_INTEGER_dup(X509_get_serialNumber(x509))))
536 return 0; 542 return 0;
537 543
538 X509_ALGOR_free(p7i->key_enc_algor); 544 pkey = X509_get_pubkey(x509);
539 if (!(p7i->key_enc_algor= X509_ALGOR_dup(x509->cert_info->key->algor))) 545
540 return 0; 546 if (!pkey || !pkey->ameth || !pkey->ameth->pkey_ctrl)
547 {
548 PKCS7err(PKCS7_F_PKCS7_RECIP_INFO_SET,
549 PKCS7_R_ENCRYPTION_NOT_SUPPORTED_FOR_THIS_KEY_TYPE);
550 goto err;
551 }
552
553 ret = pkey->ameth->pkey_ctrl(pkey, ASN1_PKEY_CTRL_PKCS7_ENCRYPT,
554 0, p7i);
555 if (ret == -2)
556 {
557 PKCS7err(PKCS7_F_PKCS7_RECIP_INFO_SET,
558 PKCS7_R_ENCRYPTION_NOT_SUPPORTED_FOR_THIS_KEY_TYPE);
559 goto err;
560 }
561 if (ret <= 0)
562 {
563 PKCS7err(PKCS7_F_PKCS7_RECIP_INFO_SET,
564 PKCS7_R_ENCRYPTION_CTRL_FAILURE);
565 goto err;
566 }
567
568 EVP_PKEY_free(pkey);
541 569
542 CRYPTO_add(&x509->references,1,CRYPTO_LOCK_X509); 570 CRYPTO_add(&x509->references,1,CRYPTO_LOCK_X509);
543 p7i->cert=x509; 571 p7i->cert=x509;
544 572
545 return(1); 573 return 1;
574
575 err:
576 if (pkey)
577 EVP_PKEY_free(pkey);
578 return 0;
546 } 579 }
547 580
548X509 *PKCS7_cert_from_signer_info(PKCS7 *p7, PKCS7_SIGNER_INFO *si) 581X509 *PKCS7_cert_from_signer_info(PKCS7 *p7, PKCS7_SIGNER_INFO *si)
@@ -587,3 +620,48 @@ int PKCS7_set_cipher(PKCS7 *p7, const EVP_CIPHER *cipher)
587 return 1; 620 return 1;
588 } 621 }
589 622
623int PKCS7_stream(unsigned char ***boundary, PKCS7 *p7)
624 {
625 ASN1_OCTET_STRING *os = NULL;
626
627 switch (OBJ_obj2nid(p7->type))
628 {
629 case NID_pkcs7_data:
630 os = p7->d.data;
631 break;
632
633 case NID_pkcs7_signedAndEnveloped:
634 os = p7->d.signed_and_enveloped->enc_data->enc_data;
635 if (os == NULL)
636 {
637 os=M_ASN1_OCTET_STRING_new();
638 p7->d.signed_and_enveloped->enc_data->enc_data=os;
639 }
640 break;
641
642 case NID_pkcs7_enveloped:
643 os = p7->d.enveloped->enc_data->enc_data;
644 if (os == NULL)
645 {
646 os=M_ASN1_OCTET_STRING_new();
647 p7->d.enveloped->enc_data->enc_data=os;
648 }
649 break;
650
651 case NID_pkcs7_signed:
652 os=p7->d.sign->contents->d.data;
653 break;
654
655 default:
656 os = NULL;
657 break;
658 }
659
660 if (os == NULL)
661 return 0;
662
663 os->flags |= ASN1_STRING_FLAG_NDEF;
664 *boundary = &os->data;
665
666 return 1;
667 }
diff --git a/src/lib/libcrypto/pkcs7/pk7_mime.c b/src/lib/libcrypto/pkcs7/pk7_mime.c
index bf190360d7..938f79a646 100644
--- a/src/lib/libcrypto/pkcs7/pk7_mime.c
+++ b/src/lib/libcrypto/pkcs7/pk7_mime.c
@@ -50,10 +50,6 @@
50 * OF THE POSSIBILITY OF SUCH DAMAGE. 50 * OF THE POSSIBILITY OF SUCH DAMAGE.
51 * ==================================================================== 51 * ====================================================================
52 * 52 *
53 * This product includes cryptographic software written by Eric Young
54 * (eay@cryptsoft.com). This product includes software written by Tim
55 * Hudson (tjh@cryptsoft.com).
56 *
57 */ 53 */
58 54
59#include <stdio.h> 55#include <stdio.h>
@@ -61,662 +57,41 @@
61#include "cryptlib.h" 57#include "cryptlib.h"
62#include <openssl/rand.h> 58#include <openssl/rand.h>
63#include <openssl/x509.h> 59#include <openssl/x509.h>
60#include <openssl/asn1.h>
64 61
65/* MIME and related routines */ 62/* PKCS#7 wrappers round generalised stream and MIME routines */
66
67/* MIME format structures
68 * Note that all are translated to lower case apart from
69 * parameter values. Quotes are stripped off
70 */
71
72typedef struct {
73char *param_name; /* Param name e.g. "micalg" */
74char *param_value; /* Param value e.g. "sha1" */
75} MIME_PARAM;
76
77DECLARE_STACK_OF(MIME_PARAM)
78IMPLEMENT_STACK_OF(MIME_PARAM)
79
80typedef struct {
81char *name; /* Name of line e.g. "content-type" */
82char *value; /* Value of line e.g. "text/plain" */
83STACK_OF(MIME_PARAM) *params; /* Zero or more parameters */
84} MIME_HEADER;
85 63
86DECLARE_STACK_OF(MIME_HEADER) 64int i2d_PKCS7_bio_stream(BIO *out, PKCS7 *p7, BIO *in, int flags)
87IMPLEMENT_STACK_OF(MIME_HEADER) 65 {
88 66 return i2d_ASN1_bio_stream(out, (ASN1_VALUE *)p7, in, flags,
89static int pkcs7_output_data(BIO *bio, BIO *data, PKCS7 *p7, int flags); 67 ASN1_ITEM_rptr(PKCS7));
90static int B64_write_PKCS7(BIO *bio, PKCS7 *p7);
91static PKCS7 *B64_read_PKCS7(BIO *bio);
92static char * strip_ends(char *name);
93static char * strip_start(char *name);
94static char * strip_end(char *name);
95static MIME_HEADER *mime_hdr_new(char *name, char *value);
96static int mime_hdr_addparam(MIME_HEADER *mhdr, char *name, char *value);
97static STACK_OF(MIME_HEADER) *mime_parse_hdr(BIO *bio);
98static int mime_hdr_cmp(const MIME_HEADER * const *a,
99 const MIME_HEADER * const *b);
100static int mime_param_cmp(const MIME_PARAM * const *a,
101 const MIME_PARAM * const *b);
102static void mime_param_free(MIME_PARAM *param);
103static int mime_bound_check(char *line, int linelen, char *bound, int blen);
104static int multi_split(BIO *bio, char *bound, STACK_OF(BIO) **ret);
105static int strip_eol(char *linebuf, int *plen);
106static MIME_HEADER *mime_hdr_find(STACK_OF(MIME_HEADER) *hdrs, char *name);
107static MIME_PARAM *mime_param_find(MIME_HEADER *hdr, char *name);
108static void mime_hdr_free(MIME_HEADER *hdr);
109
110#define MAX_SMLEN 1024
111#define mime_debug(x) /* x */
112
113/* Base 64 read and write of PKCS#7 structure */
114
115static int B64_write_PKCS7(BIO *bio, PKCS7 *p7)
116{
117 BIO *b64;
118 if(!(b64 = BIO_new(BIO_f_base64()))) {
119 PKCS7err(PKCS7_F_B64_WRITE_PKCS7,ERR_R_MALLOC_FAILURE);
120 return 0;
121 } 68 }
122 bio = BIO_push(b64, bio);
123 i2d_PKCS7_bio(bio, p7);
124 (void)BIO_flush(bio);
125 bio = BIO_pop(bio);
126 BIO_free(b64);
127 return 1;
128}
129 69
130static PKCS7 *B64_read_PKCS7(BIO *bio) 70int PEM_write_bio_PKCS7_stream(BIO *out, PKCS7 *p7, BIO *in, int flags)
131{ 71 {
132 BIO *b64; 72 return PEM_write_bio_ASN1_stream(out, (ASN1_VALUE *) p7, in, flags,
133 PKCS7 *p7; 73 "PKCS7",
134 if(!(b64 = BIO_new(BIO_f_base64()))) { 74 ASN1_ITEM_rptr(PKCS7));
135 PKCS7err(PKCS7_F_B64_READ_PKCS7,ERR_R_MALLOC_FAILURE);
136 return 0;
137 } 75 }
138 bio = BIO_push(b64, bio);
139 if(!(p7 = d2i_PKCS7_bio(bio, NULL)))
140 PKCS7err(PKCS7_F_B64_READ_PKCS7,PKCS7_R_DECODE_ERROR);
141 (void)BIO_flush(bio);
142 bio = BIO_pop(bio);
143 BIO_free(b64);
144 return p7;
145}
146
147/* SMIME sender */
148 76
149int SMIME_write_PKCS7(BIO *bio, PKCS7 *p7, BIO *data, int flags) 77int SMIME_write_PKCS7(BIO *bio, PKCS7 *p7, BIO *data, int flags)
150{
151 char bound[33], c;
152 int i;
153 char *mime_prefix, *mime_eol, *msg_type=NULL;
154 if (flags & PKCS7_NOOLDMIMETYPE)
155 mime_prefix = "application/pkcs7-";
156 else
157 mime_prefix = "application/x-pkcs7-";
158
159 if (flags & PKCS7_CRLFEOL)
160 mime_eol = "\r\n";
161 else
162 mime_eol = "\n";
163 if((flags & PKCS7_DETACHED) && data) {
164 /* We want multipart/signed */
165 /* Generate a random boundary */
166 RAND_pseudo_bytes((unsigned char *)bound, 32);
167 for(i = 0; i < 32; i++) {
168 c = bound[i] & 0xf;
169 if(c < 10) c += '0';
170 else c += 'A' - 10;
171 bound[i] = c;
172 }
173 bound[32] = 0;
174 BIO_printf(bio, "MIME-Version: 1.0%s", mime_eol);
175 BIO_printf(bio, "Content-Type: multipart/signed;");
176 BIO_printf(bio, " protocol=\"%ssignature\";", mime_prefix);
177 BIO_printf(bio, " micalg=sha1; boundary=\"----%s\"%s%s",
178 bound, mime_eol, mime_eol);
179 BIO_printf(bio, "This is an S/MIME signed message%s%s",
180 mime_eol, mime_eol);
181 /* Now write out the first part */
182 BIO_printf(bio, "------%s%s", bound, mime_eol);
183 pkcs7_output_data(bio, data, p7, flags);
184 BIO_printf(bio, "%s------%s%s", mime_eol, bound, mime_eol);
185
186 /* Headers for signature */
187
188 BIO_printf(bio, "Content-Type: %ssignature;", mime_prefix);
189 BIO_printf(bio, " name=\"smime.p7s\"%s", mime_eol);
190 BIO_printf(bio, "Content-Transfer-Encoding: base64%s",
191 mime_eol);
192 BIO_printf(bio, "Content-Disposition: attachment;");
193 BIO_printf(bio, " filename=\"smime.p7s\"%s%s",
194 mime_eol, mime_eol);
195 B64_write_PKCS7(bio, p7);
196 BIO_printf(bio,"%s------%s--%s%s", mime_eol, bound,
197 mime_eol, mime_eol);
198 return 1;
199 }
200
201 /* Determine smime-type header */
202
203 if (PKCS7_type_is_enveloped(p7))
204 msg_type = "enveloped-data";
205 else if (PKCS7_type_is_signed(p7))
206 {
207 /* If we have any signers it is signed-data othewise
208 * certs-only.
209 */
210 STACK_OF(PKCS7_SIGNER_INFO) *sinfos;
211 sinfos = PKCS7_get_signer_info(p7);
212 if (sk_PKCS7_SIGNER_INFO_num(sinfos) > 0)
213 msg_type = "signed-data";
214 else
215 msg_type = "certs-only";
216 }
217 /* MIME headers */
218 BIO_printf(bio, "MIME-Version: 1.0%s", mime_eol);
219 BIO_printf(bio, "Content-Disposition: attachment;");
220 BIO_printf(bio, " filename=\"smime.p7m\"%s", mime_eol);
221 BIO_printf(bio, "Content-Type: %smime;", mime_prefix);
222 if (msg_type)
223 BIO_printf(bio, " smime-type=%s;", msg_type);
224 BIO_printf(bio, " name=\"smime.p7m\"%s", mime_eol);
225 BIO_printf(bio, "Content-Transfer-Encoding: base64%s%s",
226 mime_eol, mime_eol);
227 B64_write_PKCS7(bio, p7);
228 BIO_printf(bio, "%s", mime_eol);
229 return 1;
230}
231
232/* Handle output of PKCS#7 data */
233
234
235static int pkcs7_output_data(BIO *out, BIO *data, PKCS7 *p7, int flags)
236 { 78 {
237 BIO *tmpbio, *p7bio; 79 STACK_OF(X509_ALGOR) *mdalgs;
238 80 int ctype_nid = OBJ_obj2nid(p7->type);
239 if (!(flags & PKCS7_STREAM)) 81 if (ctype_nid == NID_pkcs7_signed)
240 { 82 mdalgs = p7->d.sign->md_algs;
241 SMIME_crlf_copy(data, out, flags); 83 else
242 return 1; 84 mdalgs = NULL;
243 }
244
245 /* Partial sign operation */
246
247 /* Initialize sign operation */
248 p7bio = PKCS7_dataInit(p7, out);
249
250 /* Copy data across, computing digests etc */
251 SMIME_crlf_copy(data, p7bio, flags);
252
253 /* Must be detached */
254 PKCS7_set_detached(p7, 1);
255
256 /* Finalize signatures */
257 PKCS7_dataFinal(p7, p7bio);
258
259 /* Now remove any digests prepended to the BIO */
260 85
261 while (p7bio != out) 86 flags ^= SMIME_OLDMIME;
262 {
263 tmpbio = BIO_pop(p7bio);
264 BIO_free(p7bio);
265 p7bio = tmpbio;
266 }
267 87
268 return 1;
269 88
89 return SMIME_write_ASN1(bio, (ASN1_VALUE *)p7, data, flags,
90 ctype_nid, NID_undef, mdalgs,
91 ASN1_ITEM_rptr(PKCS7));
270 } 92 }
271 93
272/* SMIME reader: handle multipart/signed and opaque signing.
273 * in multipart case the content is placed in a memory BIO
274 * pointed to by "bcont". In opaque this is set to NULL
275 */
276
277PKCS7 *SMIME_read_PKCS7(BIO *bio, BIO **bcont) 94PKCS7 *SMIME_read_PKCS7(BIO *bio, BIO **bcont)
278{
279 BIO *p7in;
280 STACK_OF(MIME_HEADER) *headers = NULL;
281 STACK_OF(BIO) *parts = NULL;
282 MIME_HEADER *hdr;
283 MIME_PARAM *prm;
284 PKCS7 *p7;
285 int ret;
286
287 if(bcont) *bcont = NULL;
288
289 if (!(headers = mime_parse_hdr(bio))) {
290 PKCS7err(PKCS7_F_SMIME_READ_PKCS7,PKCS7_R_MIME_PARSE_ERROR);
291 return NULL;
292 }
293
294 if(!(hdr = mime_hdr_find(headers, "content-type")) || !hdr->value) {
295 sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
296 PKCS7err(PKCS7_F_SMIME_READ_PKCS7, PKCS7_R_NO_CONTENT_TYPE);
297 return NULL;
298 }
299
300 /* Handle multipart/signed */
301
302 if(!strcmp(hdr->value, "multipart/signed")) {
303 /* Split into two parts */
304 prm = mime_param_find(hdr, "boundary");
305 if(!prm || !prm->param_value) {
306 sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
307 PKCS7err(PKCS7_F_SMIME_READ_PKCS7, PKCS7_R_NO_MULTIPART_BOUNDARY);
308 return NULL;
309 }
310 ret = multi_split(bio, prm->param_value, &parts);
311 sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
312 if(!ret || (sk_BIO_num(parts) != 2) ) {
313 PKCS7err(PKCS7_F_SMIME_READ_PKCS7, PKCS7_R_NO_MULTIPART_BODY_FAILURE);
314 sk_BIO_pop_free(parts, BIO_vfree);
315 return NULL;
316 }
317
318 /* Parse the signature piece */
319 p7in = sk_BIO_value(parts, 1);
320
321 if (!(headers = mime_parse_hdr(p7in))) {
322 PKCS7err(PKCS7_F_SMIME_READ_PKCS7,PKCS7_R_MIME_SIG_PARSE_ERROR);
323 sk_BIO_pop_free(parts, BIO_vfree);
324 return NULL;
325 }
326
327 /* Get content type */
328
329 if(!(hdr = mime_hdr_find(headers, "content-type")) ||
330 !hdr->value) {
331 sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
332 PKCS7err(PKCS7_F_SMIME_READ_PKCS7, PKCS7_R_NO_SIG_CONTENT_TYPE);
333 return NULL;
334 }
335
336 if(strcmp(hdr->value, "application/x-pkcs7-signature") &&
337 strcmp(hdr->value, "application/pkcs7-signature")) {
338 sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
339 PKCS7err(PKCS7_F_SMIME_READ_PKCS7,PKCS7_R_SIG_INVALID_MIME_TYPE);
340 ERR_add_error_data(2, "type: ", hdr->value);
341 sk_BIO_pop_free(parts, BIO_vfree);
342 return NULL;
343 }
344 sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
345 /* Read in PKCS#7 */
346 if(!(p7 = B64_read_PKCS7(p7in))) {
347 PKCS7err(PKCS7_F_SMIME_READ_PKCS7,PKCS7_R_PKCS7_SIG_PARSE_ERROR);
348 sk_BIO_pop_free(parts, BIO_vfree);
349 return NULL;
350 }
351
352 if(bcont) {
353 *bcont = sk_BIO_value(parts, 0);
354 BIO_free(p7in);
355 sk_BIO_free(parts);
356 } else sk_BIO_pop_free(parts, BIO_vfree);
357 return p7;
358 }
359
360 /* OK, if not multipart/signed try opaque signature */
361
362 if (strcmp (hdr->value, "application/x-pkcs7-mime") &&
363 strcmp (hdr->value, "application/pkcs7-mime")) {
364 PKCS7err(PKCS7_F_SMIME_READ_PKCS7,PKCS7_R_INVALID_MIME_TYPE);
365 ERR_add_error_data(2, "type: ", hdr->value);
366 sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
367 return NULL;
368 }
369
370 sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
371
372 if(!(p7 = B64_read_PKCS7(bio))) {
373 PKCS7err(PKCS7_F_SMIME_READ_PKCS7, PKCS7_R_PKCS7_PARSE_ERROR);
374 return NULL;
375 }
376 return p7;
377
378}
379
380/* Split a multipart/XXX message body into component parts: result is
381 * canonical parts in a STACK of bios
382 */
383
384static int multi_split(BIO *bio, char *bound, STACK_OF(BIO) **ret)
385{
386 char linebuf[MAX_SMLEN];
387 int len, blen;
388 int eol = 0, next_eol = 0;
389 BIO *bpart = NULL;
390 STACK_OF(BIO) *parts;
391 char state, part, first;
392
393 blen = strlen(bound);
394 part = 0;
395 state = 0;
396 first = 1;
397 parts = sk_BIO_new_null();
398 *ret = parts;
399 while ((len = BIO_gets(bio, linebuf, MAX_SMLEN)) > 0) {
400 state = mime_bound_check(linebuf, len, bound, blen);
401 if(state == 1) {
402 first = 1;
403 part++;
404 } else if(state == 2) {
405 sk_BIO_push(parts, bpart);
406 return 1;
407 } else if(part) {
408 /* Strip CR+LF from linebuf */
409 next_eol = strip_eol(linebuf, &len);
410 if(first) {
411 first = 0;
412 if(bpart) sk_BIO_push(parts, bpart);
413 bpart = BIO_new(BIO_s_mem());
414 BIO_set_mem_eof_return(bpart, 0);
415 } else if (eol)
416 BIO_write(bpart, "\r\n", 2);
417 eol = next_eol;
418 if (len)
419 BIO_write(bpart, linebuf, len);
420 }
421 }
422 return 0;
423}
424
425/* This is the big one: parse MIME header lines up to message body */
426
427#define MIME_INVALID 0
428#define MIME_START 1
429#define MIME_TYPE 2
430#define MIME_NAME 3
431#define MIME_VALUE 4
432#define MIME_QUOTE 5
433#define MIME_COMMENT 6
434
435
436static STACK_OF(MIME_HEADER) *mime_parse_hdr(BIO *bio)
437{
438 char *p, *q, c;
439 char *ntmp;
440 char linebuf[MAX_SMLEN];
441 MIME_HEADER *mhdr = NULL;
442 STACK_OF(MIME_HEADER) *headers;
443 int len, state, save_state = 0;
444
445 headers = sk_MIME_HEADER_new(mime_hdr_cmp);
446 while ((len = BIO_gets(bio, linebuf, MAX_SMLEN)) > 0) {
447 /* If whitespace at line start then continuation line */
448 if(mhdr && isspace((unsigned char)linebuf[0])) state = MIME_NAME;
449 else state = MIME_START;
450 ntmp = NULL;
451 /* Go through all characters */
452 for(p = linebuf, q = linebuf; (c = *p) && (c!='\r') && (c!='\n'); p++) {
453
454 /* State machine to handle MIME headers
455 * if this looks horrible that's because it *is*
456 */
457
458 switch(state) {
459 case MIME_START:
460 if(c == ':') {
461 state = MIME_TYPE;
462 *p = 0;
463 ntmp = strip_ends(q);
464 q = p + 1;
465 }
466 break;
467
468 case MIME_TYPE:
469 if(c == ';') {
470 mime_debug("Found End Value\n");
471 *p = 0;
472 mhdr = mime_hdr_new(ntmp, strip_ends(q));
473 sk_MIME_HEADER_push(headers, mhdr);
474 ntmp = NULL;
475 q = p + 1;
476 state = MIME_NAME;
477 } else if(c == '(') {
478 save_state = state;
479 state = MIME_COMMENT;
480 }
481 break;
482
483 case MIME_COMMENT:
484 if(c == ')') {
485 state = save_state;
486 }
487 break;
488
489 case MIME_NAME:
490 if(c == '=') {
491 state = MIME_VALUE;
492 *p = 0;
493 ntmp = strip_ends(q);
494 q = p + 1;
495 }
496 break ;
497
498 case MIME_VALUE:
499 if(c == ';') {
500 state = MIME_NAME;
501 *p = 0;
502 mime_hdr_addparam(mhdr, ntmp, strip_ends(q));
503 ntmp = NULL;
504 q = p + 1;
505 } else if (c == '"') {
506 mime_debug("Found Quote\n");
507 state = MIME_QUOTE;
508 } else if(c == '(') {
509 save_state = state;
510 state = MIME_COMMENT;
511 }
512 break;
513
514 case MIME_QUOTE:
515 if(c == '"') {
516 mime_debug("Found Match Quote\n");
517 state = MIME_VALUE;
518 }
519 break;
520 }
521 }
522
523 if(state == MIME_TYPE) {
524 mhdr = mime_hdr_new(ntmp, strip_ends(q));
525 sk_MIME_HEADER_push(headers, mhdr);
526 } else if(state == MIME_VALUE)
527 mime_hdr_addparam(mhdr, ntmp, strip_ends(q));
528 if(p == linebuf) break; /* Blank line means end of headers */
529}
530
531return headers;
532
533}
534
535static char *strip_ends(char *name)
536{
537 return strip_end(strip_start(name));
538}
539
540/* Strip a parameter of whitespace from start of param */
541static char *strip_start(char *name)
542{
543 char *p, c;
544 /* Look for first non white space or quote */
545 for(p = name; (c = *p) ;p++) {
546 if(c == '"') {
547 /* Next char is start of string if non null */
548 if(p[1]) return p + 1;
549 /* Else null string */
550 return NULL;
551 }
552 if(!isspace((unsigned char)c)) return p;
553 }
554 return NULL;
555}
556
557/* As above but strip from end of string : maybe should handle brackets? */
558static char *strip_end(char *name)
559{
560 char *p, c;
561 if(!name) return NULL;
562 /* Look for first non white space or quote */
563 for(p = name + strlen(name) - 1; p >= name ;p--) {
564 c = *p;
565 if(c == '"') {
566 if(p - 1 == name) return NULL;
567 *p = 0;
568 return name;
569 }
570 if(isspace((unsigned char)c)) *p = 0;
571 else return name;
572 }
573 return NULL;
574}
575
576static MIME_HEADER *mime_hdr_new(char *name, char *value)
577{
578 MIME_HEADER *mhdr;
579 char *tmpname, *tmpval, *p;
580 int c;
581 if(name) {
582 if(!(tmpname = BUF_strdup(name))) return NULL;
583 for(p = tmpname ; *p; p++) {
584 c = *p;
585 if(isupper(c)) {
586 c = tolower(c);
587 *p = c;
588 }
589 }
590 } else tmpname = NULL;
591 if(value) {
592 if(!(tmpval = BUF_strdup(value))) return NULL;
593 for(p = tmpval ; *p; p++) {
594 c = *p;
595 if(isupper(c)) {
596 c = tolower(c);
597 *p = c;
598 }
599 }
600 } else tmpval = NULL;
601 mhdr = (MIME_HEADER *) OPENSSL_malloc(sizeof(MIME_HEADER));
602 if(!mhdr) return NULL;
603 mhdr->name = tmpname;
604 mhdr->value = tmpval;
605 if(!(mhdr->params = sk_MIME_PARAM_new(mime_param_cmp))) return NULL;
606 return mhdr;
607}
608
609static int mime_hdr_addparam(MIME_HEADER *mhdr, char *name, char *value)
610{
611 char *tmpname, *tmpval, *p;
612 int c;
613 MIME_PARAM *mparam;
614 if(name) {
615 tmpname = BUF_strdup(name);
616 if(!tmpname) return 0;
617 for(p = tmpname ; *p; p++) {
618 c = *p;
619 if(isupper(c)) {
620 c = tolower(c);
621 *p = c;
622 }
623 }
624 } else tmpname = NULL;
625 if(value) {
626 tmpval = BUF_strdup(value);
627 if(!tmpval) return 0;
628 } else tmpval = NULL;
629 /* Parameter values are case sensitive so leave as is */
630 mparam = (MIME_PARAM *) OPENSSL_malloc(sizeof(MIME_PARAM));
631 if(!mparam) return 0;
632 mparam->param_name = tmpname;
633 mparam->param_value = tmpval;
634 sk_MIME_PARAM_push(mhdr->params, mparam);
635 return 1;
636}
637
638static int mime_hdr_cmp(const MIME_HEADER * const *a,
639 const MIME_HEADER * const *b)
640{
641 return(strcmp((*a)->name, (*b)->name));
642}
643
644static int mime_param_cmp(const MIME_PARAM * const *a,
645 const MIME_PARAM * const *b)
646{
647 return(strcmp((*a)->param_name, (*b)->param_name));
648}
649
650/* Find a header with a given name (if possible) */
651
652static MIME_HEADER *mime_hdr_find(STACK_OF(MIME_HEADER) *hdrs, char *name)
653{
654 MIME_HEADER htmp;
655 int idx;
656 htmp.name = name;
657 idx = sk_MIME_HEADER_find(hdrs, &htmp);
658 if(idx < 0) return NULL;
659 return sk_MIME_HEADER_value(hdrs, idx);
660}
661
662static MIME_PARAM *mime_param_find(MIME_HEADER *hdr, char *name)
663{
664 MIME_PARAM param;
665 int idx;
666 param.param_name = name;
667 idx = sk_MIME_PARAM_find(hdr->params, &param);
668 if(idx < 0) return NULL;
669 return sk_MIME_PARAM_value(hdr->params, idx);
670}
671
672static void mime_hdr_free(MIME_HEADER *hdr)
673{
674 if(hdr->name) OPENSSL_free(hdr->name);
675 if(hdr->value) OPENSSL_free(hdr->value);
676 if(hdr->params) sk_MIME_PARAM_pop_free(hdr->params, mime_param_free);
677 OPENSSL_free(hdr);
678}
679
680static void mime_param_free(MIME_PARAM *param)
681{
682 if(param->param_name) OPENSSL_free(param->param_name);
683 if(param->param_value) OPENSSL_free(param->param_value);
684 OPENSSL_free(param);
685}
686
687/* Check for a multipart boundary. Returns:
688 * 0 : no boundary
689 * 1 : part boundary
690 * 2 : final boundary
691 */
692static int mime_bound_check(char *line, int linelen, char *bound, int blen)
693{
694 if(linelen == -1) linelen = strlen(line);
695 if(blen == -1) blen = strlen(bound);
696 /* Quickly eliminate if line length too short */
697 if(blen + 2 > linelen) return 0;
698 /* Check for part boundary */
699 if(!strncmp(line, "--", 2) && !strncmp(line + 2, bound, blen)) {
700 if(!strncmp(line + blen + 2, "--", 2)) return 2;
701 else return 1;
702 }
703 return 0;
704}
705
706static int strip_eol(char *linebuf, int *plen)
707 { 95 {
708 int len = *plen; 96 return (PKCS7 *)SMIME_read_ASN1(bio, bcont, ASN1_ITEM_rptr(PKCS7));
709 char *p, c;
710 int is_eol = 0;
711 p = linebuf + len - 1;
712 for (p = linebuf + len - 1; len > 0; len--, p--)
713 {
714 c = *p;
715 if (c == '\n')
716 is_eol = 1;
717 else if (c != '\r')
718 break;
719 }
720 *plen = len;
721 return is_eol;
722 } 97 }
diff --git a/src/lib/libcrypto/pkcs7/pk7_smime.c b/src/lib/libcrypto/pkcs7/pk7_smime.c
index fd18ec3d95..86742d0dcd 100644
--- a/src/lib/libcrypto/pkcs7/pk7_smime.c
+++ b/src/lib/libcrypto/pkcs7/pk7_smime.c
@@ -63,24 +63,19 @@
63#include <openssl/x509.h> 63#include <openssl/x509.h>
64#include <openssl/x509v3.h> 64#include <openssl/x509v3.h>
65 65
66static int pkcs7_copy_existing_digest(PKCS7 *p7, PKCS7_SIGNER_INFO *si);
67
66PKCS7 *PKCS7_sign(X509 *signcert, EVP_PKEY *pkey, STACK_OF(X509) *certs, 68PKCS7 *PKCS7_sign(X509 *signcert, EVP_PKEY *pkey, STACK_OF(X509) *certs,
67 BIO *data, int flags) 69 BIO *data, int flags)
68{ 70{
69 PKCS7 *p7 = NULL; 71 PKCS7 *p7;
70 PKCS7_SIGNER_INFO *si;
71 BIO *p7bio = NULL;
72 STACK_OF(X509_ALGOR) *smcap = NULL;
73 int i; 72 int i;
74 73
75 if(!X509_check_private_key(signcert, pkey)) { 74 if(!(p7 = PKCS7_new()))
76 PKCS7err(PKCS7_F_PKCS7_SIGN,PKCS7_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE); 75 {
77 return NULL;
78 }
79
80 if(!(p7 = PKCS7_new())) {
81 PKCS7err(PKCS7_F_PKCS7_SIGN,ERR_R_MALLOC_FAILURE); 76 PKCS7err(PKCS7_F_PKCS7_SIGN,ERR_R_MALLOC_FAILURE);
82 return NULL; 77 return NULL;
83 } 78 }
84 79
85 if (!PKCS7_set_type(p7, NID_pkcs7_signed)) 80 if (!PKCS7_set_type(p7, NID_pkcs7_signed))
86 goto err; 81 goto err;
@@ -88,82 +83,185 @@ PKCS7 *PKCS7_sign(X509 *signcert, EVP_PKEY *pkey, STACK_OF(X509) *certs,
88 if (!PKCS7_content_new(p7, NID_pkcs7_data)) 83 if (!PKCS7_content_new(p7, NID_pkcs7_data))
89 goto err; 84 goto err;
90 85
91 if (!(si = PKCS7_add_signature(p7,signcert,pkey,EVP_sha1()))) { 86 if (pkey && !PKCS7_sign_add_signer(p7, signcert, pkey, NULL, flags))
92 PKCS7err(PKCS7_F_PKCS7_SIGN,PKCS7_R_PKCS7_ADD_SIGNATURE_ERROR); 87 {
88 PKCS7err(PKCS7_F_PKCS7_SIGN,PKCS7_R_PKCS7_ADD_SIGNER_ERROR);
93 goto err; 89 goto err;
94 } 90 }
95 91
96 if(!(flags & PKCS7_NOCERTS)) { 92 if(!(flags & PKCS7_NOCERTS))
97 if (!PKCS7_add_certificate(p7, signcert)) 93 {
98 goto err; 94 for(i = 0; i < sk_X509_num(certs); i++)
99 if(certs) for(i = 0; i < sk_X509_num(certs); i++) 95 {
100 if (!PKCS7_add_certificate(p7, sk_X509_value(certs, i))) 96 if (!PKCS7_add_certificate(p7, sk_X509_value(certs, i)))
101 goto err; 97 goto err;
102 } 98 }
99 }
103 100
104 if(!(flags & PKCS7_NOATTR)) { 101 if(flags & PKCS7_DETACHED)
105 if (!PKCS7_add_signed_attribute(si, NID_pkcs9_contentType, 102 PKCS7_set_detached(p7, 1);
106 V_ASN1_OBJECT, OBJ_nid2obj(NID_pkcs7_data))) 103
107 goto err; 104 if (flags & (PKCS7_STREAM|PKCS7_PARTIAL))
108 /* Add SMIMECapabilities */ 105 return p7;
109 if(!(flags & PKCS7_NOSMIMECAP)) 106
107 if (PKCS7_final(p7, data, flags))
108 return p7;
109
110 err:
111 PKCS7_free(p7);
112 return NULL;
113}
114
115int PKCS7_final(PKCS7 *p7, BIO *data, int flags)
116 {
117 BIO *p7bio;
118 int ret = 0;
119 if (!(p7bio = PKCS7_dataInit(p7, NULL)))
110 { 120 {
111 if(!(smcap = sk_X509_ALGOR_new_null())) { 121 PKCS7err(PKCS7_F_PKCS7_FINAL,ERR_R_MALLOC_FAILURE);
112 PKCS7err(PKCS7_F_PKCS7_SIGN,ERR_R_MALLOC_FAILURE); 122 return 0;
113 goto err;
114 }
115#ifndef OPENSSL_NO_DES
116 if (!PKCS7_simple_smimecap (smcap, NID_des_ede3_cbc, -1))
117 goto err;
118#endif
119#ifndef OPENSSL_NO_RC2
120 if (!PKCS7_simple_smimecap (smcap, NID_rc2_cbc, 128))
121 goto err;
122 if (!PKCS7_simple_smimecap (smcap, NID_rc2_cbc, 64))
123 goto err;
124#endif
125#ifndef OPENSSL_NO_DES
126 if (!PKCS7_simple_smimecap (smcap, NID_des_cbc, -1))
127 goto err;
128#endif
129#ifndef OPENSSL_NO_RC2
130 if (!PKCS7_simple_smimecap (smcap, NID_rc2_cbc, 40))
131 goto err;
132#endif
133 if (!PKCS7_add_attrib_smimecap (si, smcap))
134 goto err;
135 sk_X509_ALGOR_pop_free(smcap, X509_ALGOR_free);
136 smcap = NULL;
137 } 123 }
138 }
139 124
140 if(flags & PKCS7_DETACHED)PKCS7_set_detached(p7, 1); 125 SMIME_crlf_copy(data, p7bio, flags);
141 126
142 if (flags & PKCS7_STREAM) 127 (void)BIO_flush(p7bio);
143 return p7;
144 128
145 129
146 if (!(p7bio = PKCS7_dataInit(p7, NULL))) { 130 if (!PKCS7_dataFinal(p7,p7bio))
147 PKCS7err(PKCS7_F_PKCS7_SIGN,ERR_R_MALLOC_FAILURE); 131 {
132 PKCS7err(PKCS7_F_PKCS7_FINAL,PKCS7_R_PKCS7_DATASIGN);
148 goto err; 133 goto err;
134 }
135
136 ret = 1;
137
138 err:
139 BIO_free_all(p7bio);
140
141 return ret;
142
149 } 143 }
150 144
151 SMIME_crlf_copy(data, p7bio, flags); 145/* Check to see if a cipher exists and if so add S/MIME capabilities */
152 146
147static int add_cipher_smcap(STACK_OF(X509_ALGOR) *sk, int nid, int arg)
148 {
149 if (EVP_get_cipherbynid(nid))
150 return PKCS7_simple_smimecap(sk, nid, arg);
151 return 1;
152 }
153 153
154 if (!PKCS7_dataFinal(p7,p7bio)) { 154static int add_digest_smcap(STACK_OF(X509_ALGOR) *sk, int nid, int arg)
155 PKCS7err(PKCS7_F_PKCS7_SIGN,PKCS7_R_PKCS7_DATASIGN); 155 {
156 goto err; 156 if (EVP_get_digestbynid(nid))
157 return PKCS7_simple_smimecap(sk, nid, arg);
158 return 1;
157 } 159 }
158 160
159 BIO_free_all(p7bio); 161PKCS7_SIGNER_INFO *PKCS7_sign_add_signer(PKCS7 *p7, X509 *signcert,
160 return p7; 162 EVP_PKEY *pkey, const EVP_MD *md,
161err: 163 int flags)
162 sk_X509_ALGOR_pop_free(smcap, X509_ALGOR_free); 164 {
163 BIO_free_all(p7bio); 165 PKCS7_SIGNER_INFO *si = NULL;
164 PKCS7_free(p7); 166 STACK_OF(X509_ALGOR) *smcap = NULL;
167 if(!X509_check_private_key(signcert, pkey))
168 {
169 PKCS7err(PKCS7_F_PKCS7_SIGN_ADD_SIGNER,
170 PKCS7_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE);
171 return NULL;
172 }
173
174 if (!(si = PKCS7_add_signature(p7,signcert,pkey, md)))
175 {
176 PKCS7err(PKCS7_F_PKCS7_SIGN_ADD_SIGNER,
177 PKCS7_R_PKCS7_ADD_SIGNATURE_ERROR);
178 return NULL;
179 }
180
181 if(!(flags & PKCS7_NOCERTS))
182 {
183 if (!PKCS7_add_certificate(p7, signcert))
184 goto err;
185 }
186
187 if(!(flags & PKCS7_NOATTR))
188 {
189 if (!PKCS7_add_attrib_content_type(si, NULL))
190 goto err;
191 /* Add SMIMECapabilities */
192 if(!(flags & PKCS7_NOSMIMECAP))
193 {
194 if(!(smcap = sk_X509_ALGOR_new_null()))
195 {
196 PKCS7err(PKCS7_F_PKCS7_SIGN_ADD_SIGNER,
197 ERR_R_MALLOC_FAILURE);
198 goto err;
199 }
200 if (!add_cipher_smcap(smcap, NID_aes_256_cbc, -1)
201 || !add_digest_smcap(smcap, NID_id_GostR3411_94, -1)
202 || !add_cipher_smcap(smcap, NID_id_Gost28147_89, -1)
203 || !add_cipher_smcap(smcap, NID_aes_192_cbc, -1)
204 || !add_cipher_smcap(smcap, NID_aes_128_cbc, -1)
205 || !add_cipher_smcap(smcap, NID_des_ede3_cbc, -1)
206 || !add_cipher_smcap(smcap, NID_rc2_cbc, 128)
207 || !add_cipher_smcap(smcap, NID_rc2_cbc, 64)
208 || !add_cipher_smcap(smcap, NID_des_cbc, -1)
209 || !add_cipher_smcap(smcap, NID_rc2_cbc, 40)
210 || !PKCS7_add_attrib_smimecap (si, smcap))
211 goto err;
212 sk_X509_ALGOR_pop_free(smcap, X509_ALGOR_free);
213 smcap = NULL;
214 }
215 if (flags & PKCS7_REUSE_DIGEST)
216 {
217 if (!pkcs7_copy_existing_digest(p7, si))
218 goto err;
219 if (!(flags & PKCS7_PARTIAL) &&
220 !PKCS7_SIGNER_INFO_sign(si))
221 goto err;
222 }
223 }
224 return si;
225 err:
226 if (smcap)
227 sk_X509_ALGOR_pop_free(smcap, X509_ALGOR_free);
165 return NULL; 228 return NULL;
166} 229 }
230
231/* Search for a digest matching SignerInfo digest type and if found
232 * copy across.
233 */
234
235static int pkcs7_copy_existing_digest(PKCS7 *p7, PKCS7_SIGNER_INFO *si)
236 {
237 int i;
238 STACK_OF(PKCS7_SIGNER_INFO) *sinfos;
239 PKCS7_SIGNER_INFO *sitmp;
240 ASN1_OCTET_STRING *osdig = NULL;
241 sinfos = PKCS7_get_signer_info(p7);
242 for (i = 0; i < sk_PKCS7_SIGNER_INFO_num(sinfos); i++)
243 {
244 sitmp = sk_PKCS7_SIGNER_INFO_value(sinfos, i);
245 if (si == sitmp)
246 break;
247 if (sk_X509_ATTRIBUTE_num(sitmp->auth_attr) <= 0)
248 continue;
249 if (!OBJ_cmp(si->digest_alg->algorithm,
250 sitmp->digest_alg->algorithm))
251 {
252 osdig = PKCS7_digest_from_attributes(sitmp->auth_attr);
253 break;
254 }
255
256 }
257
258 if (osdig)
259 return PKCS7_add1_attrib_digest(si, osdig->data, osdig->length);
260
261 PKCS7err(PKCS7_F_PKCS7_COPY_EXISTING_DIGEST,
262 PKCS7_R_NO_MATCHING_DIGEST_TYPE_FOUND);
263 return 0;
264 }
167 265
168int PKCS7_verify(PKCS7 *p7, STACK_OF(X509) *certs, X509_STORE *store, 266int PKCS7_verify(PKCS7 *p7, STACK_OF(X509) *certs, X509_STORE *store,
169 BIO *indata, BIO *out, int flags) 267 BIO *indata, BIO *out, int flags)
@@ -354,7 +452,7 @@ STACK_OF(X509) *PKCS7_get0_signers(PKCS7 *p7, STACK_OF(X509) *certs, int flags)
354 452
355 if(sk_PKCS7_SIGNER_INFO_num(sinfos) <= 0) { 453 if(sk_PKCS7_SIGNER_INFO_num(sinfos) <= 0) {
356 PKCS7err(PKCS7_F_PKCS7_GET0_SIGNERS,PKCS7_R_NO_SIGNERS); 454 PKCS7err(PKCS7_F_PKCS7_GET0_SIGNERS,PKCS7_R_NO_SIGNERS);
357 return NULL; 455 return 0;
358 } 456 }
359 457
360 if(!(signers = sk_X509_new_null())) { 458 if(!(signers = sk_X509_new_null())) {
@@ -377,12 +475,12 @@ STACK_OF(X509) *PKCS7_get0_signers(PKCS7 *p7, STACK_OF(X509) *certs, int flags)
377 if (!signer) { 475 if (!signer) {
378 PKCS7err(PKCS7_F_PKCS7_GET0_SIGNERS,PKCS7_R_SIGNER_CERTIFICATE_NOT_FOUND); 476 PKCS7err(PKCS7_F_PKCS7_GET0_SIGNERS,PKCS7_R_SIGNER_CERTIFICATE_NOT_FOUND);
379 sk_X509_free(signers); 477 sk_X509_free(signers);
380 return NULL; 478 return 0;
381 } 479 }
382 480
383 if (!sk_X509_push(signers, signer)) { 481 if (!sk_X509_push(signers, signer)) {
384 sk_X509_free(signers); 482 sk_X509_free(signers);
385 return NULL; 483 return NULL;
386 } 484 }
387 } 485 }
388 return signers; 486 return signers;
@@ -405,7 +503,7 @@ PKCS7 *PKCS7_encrypt(STACK_OF(X509) *certs, BIO *in, const EVP_CIPHER *cipher,
405 503
406 if (!PKCS7_set_type(p7, NID_pkcs7_enveloped)) 504 if (!PKCS7_set_type(p7, NID_pkcs7_enveloped))
407 goto err; 505 goto err;
408 if(!PKCS7_set_cipher(p7, cipher)) { 506 if (!PKCS7_set_cipher(p7, cipher)) {
409 PKCS7err(PKCS7_F_PKCS7_ENCRYPT,PKCS7_R_ERROR_SETTING_CIPHER); 507 PKCS7err(PKCS7_F_PKCS7_ENCRYPT,PKCS7_R_ERROR_SETTING_CIPHER);
410 goto err; 508 goto err;
411 } 509 }
@@ -419,22 +517,11 @@ PKCS7 *PKCS7_encrypt(STACK_OF(X509) *certs, BIO *in, const EVP_CIPHER *cipher,
419 } 517 }
420 } 518 }
421 519
422 if(!(p7bio = PKCS7_dataInit(p7, NULL))) { 520 if (flags & PKCS7_STREAM)
423 PKCS7err(PKCS7_F_PKCS7_ENCRYPT,ERR_R_MALLOC_FAILURE); 521 return p7;
424 goto err;
425 }
426
427 SMIME_crlf_copy(in, p7bio, flags);
428
429 (void)BIO_flush(p7bio);
430
431 if (!PKCS7_dataFinal(p7,p7bio)) {
432 PKCS7err(PKCS7_F_PKCS7_ENCRYPT,PKCS7_R_PKCS7_DATAFINAL_ERROR);
433 goto err;
434 }
435 BIO_free_all(p7bio);
436 522
437 return p7; 523 if (PKCS7_final(p7, in, flags))
524 return p7;
438 525
439 err: 526 err:
440 527
diff --git a/src/lib/libcrypto/pkcs7/pkcs7.h b/src/lib/libcrypto/pkcs7/pkcs7.h
index cc092d262d..e4d443193c 100644
--- a/src/lib/libcrypto/pkcs7/pkcs7.h
+++ b/src/lib/libcrypto/pkcs7/pkcs7.h
@@ -232,6 +232,9 @@ DECLARE_PKCS12_STACK_OF(PKCS7)
232#define PKCS7_type_is_signedAndEnveloped(a) \ 232#define PKCS7_type_is_signedAndEnveloped(a) \
233 (OBJ_obj2nid((a)->type) == NID_pkcs7_signedAndEnveloped) 233 (OBJ_obj2nid((a)->type) == NID_pkcs7_signedAndEnveloped)
234#define PKCS7_type_is_data(a) (OBJ_obj2nid((a)->type) == NID_pkcs7_data) 234#define PKCS7_type_is_data(a) (OBJ_obj2nid((a)->type) == NID_pkcs7_data)
235#define PKCS7_type_is_digest(a) (OBJ_obj2nid((a)->type) == NID_pkcs7_digest)
236#define PKCS7_type_is_encrypted(a) \
237 (OBJ_obj2nid((a)->type) == NID_pkcs7_encrypted)
235 238
236#define PKCS7_type_is_digest(a) (OBJ_obj2nid((a)->type) == NID_pkcs7_digest) 239#define PKCS7_type_is_digest(a) (OBJ_obj2nid((a)->type) == NID_pkcs7_digest)
237 240
@@ -242,14 +245,6 @@ DECLARE_PKCS12_STACK_OF(PKCS7)
242 245
243#define PKCS7_is_detached(p7) (PKCS7_type_is_signed(p7) && PKCS7_get_detached(p7)) 246#define PKCS7_is_detached(p7) (PKCS7_type_is_signed(p7) && PKCS7_get_detached(p7))
244 247
245#ifdef SSLEAY_MACROS
246#ifndef PKCS7_ISSUER_AND_SERIAL_digest
247#define PKCS7_ISSUER_AND_SERIAL_digest(data,type,md,len) \
248 ASN1_digest((int (*)())i2d_PKCS7_ISSUER_AND_SERIAL,type,\
249 (char *)data,md,len)
250#endif
251#endif
252
253/* S/MIME related flags */ 248/* S/MIME related flags */
254 249
255#define PKCS7_TEXT 0x1 250#define PKCS7_TEXT 0x1
@@ -266,6 +261,8 @@ DECLARE_PKCS12_STACK_OF(PKCS7)
266#define PKCS7_CRLFEOL 0x800 261#define PKCS7_CRLFEOL 0x800
267#define PKCS7_STREAM 0x1000 262#define PKCS7_STREAM 0x1000
268#define PKCS7_NOCRL 0x2000 263#define PKCS7_NOCRL 0x2000
264#define PKCS7_PARTIAL 0x4000
265#define PKCS7_REUSE_DIGEST 0x8000
269 266
270/* Flags: for compatibility with older code */ 267/* Flags: for compatibility with older code */
271 268
@@ -281,7 +278,6 @@ DECLARE_PKCS12_STACK_OF(PKCS7)
281 278
282DECLARE_ASN1_FUNCTIONS(PKCS7_ISSUER_AND_SERIAL) 279DECLARE_ASN1_FUNCTIONS(PKCS7_ISSUER_AND_SERIAL)
283 280
284#ifndef SSLEAY_MACROS
285int PKCS7_ISSUER_AND_SERIAL_digest(PKCS7_ISSUER_AND_SERIAL *data,const EVP_MD *type, 281int PKCS7_ISSUER_AND_SERIAL_digest(PKCS7_ISSUER_AND_SERIAL *data,const EVP_MD *type,
286 unsigned char *md,unsigned int *len); 282 unsigned char *md,unsigned int *len);
287#ifndef OPENSSL_NO_FP_API 283#ifndef OPENSSL_NO_FP_API
@@ -291,7 +287,8 @@ int i2d_PKCS7_fp(FILE *fp,PKCS7 *p7);
291PKCS7 *PKCS7_dup(PKCS7 *p7); 287PKCS7 *PKCS7_dup(PKCS7 *p7);
292PKCS7 *d2i_PKCS7_bio(BIO *bp,PKCS7 **p7); 288PKCS7 *d2i_PKCS7_bio(BIO *bp,PKCS7 **p7);
293int i2d_PKCS7_bio(BIO *bp,PKCS7 *p7); 289int i2d_PKCS7_bio(BIO *bp,PKCS7 *p7);
294#endif 290int i2d_PKCS7_bio_stream(BIO *out, PKCS7 *p7, BIO *in, int flags);
291int PEM_write_bio_PKCS7_stream(BIO *out, PKCS7 *p7, BIO *in, int flags);
295 292
296DECLARE_ASN1_FUNCTIONS(PKCS7_SIGNER_INFO) 293DECLARE_ASN1_FUNCTIONS(PKCS7_SIGNER_INFO)
297DECLARE_ASN1_FUNCTIONS(PKCS7_RECIP_INFO) 294DECLARE_ASN1_FUNCTIONS(PKCS7_RECIP_INFO)
@@ -307,6 +304,7 @@ DECLARE_ASN1_ITEM(PKCS7_ATTR_SIGN)
307DECLARE_ASN1_ITEM(PKCS7_ATTR_VERIFY) 304DECLARE_ASN1_ITEM(PKCS7_ATTR_VERIFY)
308 305
309DECLARE_ASN1_NDEF_FUNCTION(PKCS7) 306DECLARE_ASN1_NDEF_FUNCTION(PKCS7)
307DECLARE_ASN1_PRINT_FUNCTION(PKCS7)
310 308
311long PKCS7_ctrl(PKCS7 *p7, int cmd, long larg, char *parg); 309long PKCS7_ctrl(PKCS7 *p7, int cmd, long larg, char *parg);
312 310
@@ -315,6 +313,7 @@ int PKCS7_set0_type_other(PKCS7 *p7, int type, ASN1_TYPE *other);
315int PKCS7_set_content(PKCS7 *p7, PKCS7 *p7_data); 313int PKCS7_set_content(PKCS7 *p7, PKCS7 *p7_data);
316int PKCS7_SIGNER_INFO_set(PKCS7_SIGNER_INFO *p7i, X509 *x509, EVP_PKEY *pkey, 314int PKCS7_SIGNER_INFO_set(PKCS7_SIGNER_INFO *p7i, X509 *x509, EVP_PKEY *pkey,
317 const EVP_MD *dgst); 315 const EVP_MD *dgst);
316int PKCS7_SIGNER_INFO_sign(PKCS7_SIGNER_INFO *si);
318int PKCS7_add_signer(PKCS7 *p7, PKCS7_SIGNER_INFO *p7i); 317int PKCS7_add_signer(PKCS7 *p7, PKCS7_SIGNER_INFO *p7i);
319int PKCS7_add_certificate(PKCS7 *p7, X509 *x509); 318int PKCS7_add_certificate(PKCS7 *p7, X509 *x509);
320int PKCS7_add_crl(PKCS7 *p7, X509_CRL *x509); 319int PKCS7_add_crl(PKCS7 *p7, X509_CRL *x509);
@@ -336,9 +335,13 @@ int PKCS7_set_digest(PKCS7 *p7, const EVP_MD *md);
336STACK_OF(PKCS7_SIGNER_INFO) *PKCS7_get_signer_info(PKCS7 *p7); 335STACK_OF(PKCS7_SIGNER_INFO) *PKCS7_get_signer_info(PKCS7 *p7);
337 336
338PKCS7_RECIP_INFO *PKCS7_add_recipient(PKCS7 *p7, X509 *x509); 337PKCS7_RECIP_INFO *PKCS7_add_recipient(PKCS7 *p7, X509 *x509);
338void PKCS7_SIGNER_INFO_get0_algs(PKCS7_SIGNER_INFO *si, EVP_PKEY **pk,
339 X509_ALGOR **pdig, X509_ALGOR **psig);
340void PKCS7_RECIP_INFO_get0_alg(PKCS7_RECIP_INFO *ri, X509_ALGOR **penc);
339int PKCS7_add_recipient_info(PKCS7 *p7, PKCS7_RECIP_INFO *ri); 341int PKCS7_add_recipient_info(PKCS7 *p7, PKCS7_RECIP_INFO *ri);
340int PKCS7_RECIP_INFO_set(PKCS7_RECIP_INFO *p7i, X509 *x509); 342int PKCS7_RECIP_INFO_set(PKCS7_RECIP_INFO *p7i, X509 *x509);
341int PKCS7_set_cipher(PKCS7 *p7, const EVP_CIPHER *cipher); 343int PKCS7_set_cipher(PKCS7 *p7, const EVP_CIPHER *cipher);
344int PKCS7_stream(unsigned char ***boundary, PKCS7 *p7);
342 345
343PKCS7_ISSUER_AND_SERIAL *PKCS7_get_issuer_and_serial(PKCS7 *p7, int idx); 346PKCS7_ISSUER_AND_SERIAL *PKCS7_get_issuer_and_serial(PKCS7 *p7, int idx);
344ASN1_OCTET_STRING *PKCS7_digest_from_attributes(STACK_OF(X509_ATTRIBUTE) *sk); 347ASN1_OCTET_STRING *PKCS7_digest_from_attributes(STACK_OF(X509_ATTRIBUTE) *sk);
@@ -355,6 +358,12 @@ int PKCS7_set_attributes(PKCS7_SIGNER_INFO *p7si,STACK_OF(X509_ATTRIBUTE) *sk);
355 358
356PKCS7 *PKCS7_sign(X509 *signcert, EVP_PKEY *pkey, STACK_OF(X509) *certs, 359PKCS7 *PKCS7_sign(X509 *signcert, EVP_PKEY *pkey, STACK_OF(X509) *certs,
357 BIO *data, int flags); 360 BIO *data, int flags);
361
362PKCS7_SIGNER_INFO *PKCS7_sign_add_signer(PKCS7 *p7,
363 X509 *signcert, EVP_PKEY *pkey, const EVP_MD *md,
364 int flags);
365
366int PKCS7_final(PKCS7 *p7, BIO *data, int flags);
358int PKCS7_verify(PKCS7 *p7, STACK_OF(X509) *certs, X509_STORE *store, 367int PKCS7_verify(PKCS7 *p7, STACK_OF(X509) *certs, X509_STORE *store,
359 BIO *indata, BIO *out, int flags); 368 BIO *indata, BIO *out, int flags);
360STACK_OF(X509) *PKCS7_get0_signers(PKCS7 *p7, STACK_OF(X509) *certs, int flags); 369STACK_OF(X509) *PKCS7_get0_signers(PKCS7 *p7, STACK_OF(X509) *certs, int flags);
@@ -367,10 +376,16 @@ int PKCS7_add_attrib_smimecap(PKCS7_SIGNER_INFO *si,
367STACK_OF(X509_ALGOR) *PKCS7_get_smimecap(PKCS7_SIGNER_INFO *si); 376STACK_OF(X509_ALGOR) *PKCS7_get_smimecap(PKCS7_SIGNER_INFO *si);
368int PKCS7_simple_smimecap(STACK_OF(X509_ALGOR) *sk, int nid, int arg); 377int PKCS7_simple_smimecap(STACK_OF(X509_ALGOR) *sk, int nid, int arg);
369 378
379int PKCS7_add_attrib_content_type(PKCS7_SIGNER_INFO *si, ASN1_OBJECT *coid);
380int PKCS7_add0_attrib_signing_time(PKCS7_SIGNER_INFO *si, ASN1_TIME *t);
381int PKCS7_add1_attrib_digest(PKCS7_SIGNER_INFO *si,
382 const unsigned char *md, int mdlen);
383
370int SMIME_write_PKCS7(BIO *bio, PKCS7 *p7, BIO *data, int flags); 384int SMIME_write_PKCS7(BIO *bio, PKCS7 *p7, BIO *data, int flags);
371PKCS7 *SMIME_read_PKCS7(BIO *bio, BIO **bcont); 385PKCS7 *SMIME_read_PKCS7(BIO *bio, BIO **bcont);
372int SMIME_crlf_copy(BIO *in, BIO *out, int flags); 386
373int SMIME_text(BIO *in, BIO *out); 387BIO *BIO_new_PKCS7(BIO *out, PKCS7 *p7);
388
374 389
375/* BEGIN ERROR CODES */ 390/* BEGIN ERROR CODES */
376/* The following lines are auto generated by the script mkerr.pl. Any changes 391/* The following lines are auto generated by the script mkerr.pl. Any changes
@@ -383,12 +398,17 @@ void ERR_load_PKCS7_strings(void);
383/* Function codes. */ 398/* Function codes. */
384#define PKCS7_F_B64_READ_PKCS7 120 399#define PKCS7_F_B64_READ_PKCS7 120
385#define PKCS7_F_B64_WRITE_PKCS7 121 400#define PKCS7_F_B64_WRITE_PKCS7 121
401#define PKCS7_F_DO_PKCS7_SIGNED_ATTRIB 136
402#define PKCS7_F_I2D_PKCS7_BIO_STREAM 140
403#define PKCS7_F_PKCS7_ADD0_ATTRIB_SIGNING_TIME 135
386#define PKCS7_F_PKCS7_ADD_ATTRIB_SMIMECAP 118 404#define PKCS7_F_PKCS7_ADD_ATTRIB_SMIMECAP 118
387#define PKCS7_F_PKCS7_ADD_CERTIFICATE 100 405#define PKCS7_F_PKCS7_ADD_CERTIFICATE 100
388#define PKCS7_F_PKCS7_ADD_CRL 101 406#define PKCS7_F_PKCS7_ADD_CRL 101
389#define PKCS7_F_PKCS7_ADD_RECIPIENT_INFO 102 407#define PKCS7_F_PKCS7_ADD_RECIPIENT_INFO 102
408#define PKCS7_F_PKCS7_ADD_SIGNATURE 131
390#define PKCS7_F_PKCS7_ADD_SIGNER 103 409#define PKCS7_F_PKCS7_ADD_SIGNER 103
391#define PKCS7_F_PKCS7_BIO_ADD_DIGEST 125 410#define PKCS7_F_PKCS7_BIO_ADD_DIGEST 125
411#define PKCS7_F_PKCS7_COPY_EXISTING_DIGEST 138
392#define PKCS7_F_PKCS7_CTRL 104 412#define PKCS7_F_PKCS7_CTRL 104
393#define PKCS7_F_PKCS7_DATADECODE 112 413#define PKCS7_F_PKCS7_DATADECODE 112
394#define PKCS7_F_PKCS7_DATAFINAL 128 414#define PKCS7_F_PKCS7_DATAFINAL 128
@@ -396,15 +416,22 @@ void ERR_load_PKCS7_strings(void);
396#define PKCS7_F_PKCS7_DATASIGN 106 416#define PKCS7_F_PKCS7_DATASIGN 106
397#define PKCS7_F_PKCS7_DATAVERIFY 107 417#define PKCS7_F_PKCS7_DATAVERIFY 107
398#define PKCS7_F_PKCS7_DECRYPT 114 418#define PKCS7_F_PKCS7_DECRYPT 114
419#define PKCS7_F_PKCS7_DECRYPT_RINFO 133
420#define PKCS7_F_PKCS7_ENCODE_RINFO 132
399#define PKCS7_F_PKCS7_ENCRYPT 115 421#define PKCS7_F_PKCS7_ENCRYPT 115
422#define PKCS7_F_PKCS7_FINAL 134
400#define PKCS7_F_PKCS7_FIND_DIGEST 127 423#define PKCS7_F_PKCS7_FIND_DIGEST 127
401#define PKCS7_F_PKCS7_GET0_SIGNERS 124 424#define PKCS7_F_PKCS7_GET0_SIGNERS 124
425#define PKCS7_F_PKCS7_RECIP_INFO_SET 130
402#define PKCS7_F_PKCS7_SET_CIPHER 108 426#define PKCS7_F_PKCS7_SET_CIPHER 108
403#define PKCS7_F_PKCS7_SET_CONTENT 109 427#define PKCS7_F_PKCS7_SET_CONTENT 109
404#define PKCS7_F_PKCS7_SET_DIGEST 126 428#define PKCS7_F_PKCS7_SET_DIGEST 126
405#define PKCS7_F_PKCS7_SET_TYPE 110 429#define PKCS7_F_PKCS7_SET_TYPE 110
406#define PKCS7_F_PKCS7_SIGN 116 430#define PKCS7_F_PKCS7_SIGN 116
407#define PKCS7_F_PKCS7_SIGNATUREVERIFY 113 431#define PKCS7_F_PKCS7_SIGNATUREVERIFY 113
432#define PKCS7_F_PKCS7_SIGNER_INFO_SET 129
433#define PKCS7_F_PKCS7_SIGNER_INFO_SIGN 139
434#define PKCS7_F_PKCS7_SIGN_ADD_SIGNER 137
408#define PKCS7_F_PKCS7_SIMPLE_SMIMECAP 119 435#define PKCS7_F_PKCS7_SIMPLE_SMIMECAP 119
409#define PKCS7_F_PKCS7_VERIFY 117 436#define PKCS7_F_PKCS7_VERIFY 117
410#define PKCS7_F_SMIME_READ_PKCS7 122 437#define PKCS7_F_SMIME_READ_PKCS7 122
@@ -415,10 +442,13 @@ void ERR_load_PKCS7_strings(void);
415#define PKCS7_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER 144 442#define PKCS7_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER 144
416#define PKCS7_R_CIPHER_NOT_INITIALIZED 116 443#define PKCS7_R_CIPHER_NOT_INITIALIZED 116
417#define PKCS7_R_CONTENT_AND_DATA_PRESENT 118 444#define PKCS7_R_CONTENT_AND_DATA_PRESENT 118
445#define PKCS7_R_CTRL_ERROR 152
418#define PKCS7_R_DECODE_ERROR 130 446#define PKCS7_R_DECODE_ERROR 130
419#define PKCS7_R_DECRYPTED_KEY_IS_WRONG_LENGTH 100 447#define PKCS7_R_DECRYPTED_KEY_IS_WRONG_LENGTH 100
420#define PKCS7_R_DECRYPT_ERROR 119 448#define PKCS7_R_DECRYPT_ERROR 119
421#define PKCS7_R_DIGEST_FAILURE 101 449#define PKCS7_R_DIGEST_FAILURE 101
450#define PKCS7_R_ENCRYPTION_CTRL_FAILURE 149
451#define PKCS7_R_ENCRYPTION_NOT_SUPPORTED_FOR_THIS_KEY_TYPE 150
422#define PKCS7_R_ERROR_ADDING_RECIPIENT 120 452#define PKCS7_R_ERROR_ADDING_RECIPIENT 120
423#define PKCS7_R_ERROR_SETTING_CIPHER 121 453#define PKCS7_R_ERROR_SETTING_CIPHER 121
424#define PKCS7_R_INVALID_MIME_TYPE 131 454#define PKCS7_R_INVALID_MIME_TYPE 131
@@ -429,6 +459,8 @@ void ERR_load_PKCS7_strings(void);
429#define PKCS7_R_MISSING_CERIPEND_INFO 103 459#define PKCS7_R_MISSING_CERIPEND_INFO 103
430#define PKCS7_R_NO_CONTENT 122 460#define PKCS7_R_NO_CONTENT 122
431#define PKCS7_R_NO_CONTENT_TYPE 135 461#define PKCS7_R_NO_CONTENT_TYPE 135
462#define PKCS7_R_NO_DEFAULT_DIGEST 151
463#define PKCS7_R_NO_MATCHING_DIGEST_TYPE_FOUND 154
432#define PKCS7_R_NO_MULTIPART_BODY_FAILURE 136 464#define PKCS7_R_NO_MULTIPART_BODY_FAILURE 136
433#define PKCS7_R_NO_MULTIPART_BOUNDARY 137 465#define PKCS7_R_NO_MULTIPART_BOUNDARY 137
434#define PKCS7_R_NO_RECIPIENT_MATCHES_CERTIFICATE 115 466#define PKCS7_R_NO_RECIPIENT_MATCHES_CERTIFICATE 115
@@ -438,6 +470,7 @@ void ERR_load_PKCS7_strings(void);
438#define PKCS7_R_NO_SIG_CONTENT_TYPE 138 470#define PKCS7_R_NO_SIG_CONTENT_TYPE 138
439#define PKCS7_R_OPERATION_NOT_SUPPORTED_ON_THIS_TYPE 104 471#define PKCS7_R_OPERATION_NOT_SUPPORTED_ON_THIS_TYPE 104
440#define PKCS7_R_PKCS7_ADD_SIGNATURE_ERROR 124 472#define PKCS7_R_PKCS7_ADD_SIGNATURE_ERROR 124
473#define PKCS7_R_PKCS7_ADD_SIGNER_ERROR 153
441#define PKCS7_R_PKCS7_DATAFINAL 126 474#define PKCS7_R_PKCS7_DATAFINAL 126
442#define PKCS7_R_PKCS7_DATAFINAL_ERROR 125 475#define PKCS7_R_PKCS7_DATAFINAL_ERROR 125
443#define PKCS7_R_PKCS7_DATASIGN 145 476#define PKCS7_R_PKCS7_DATASIGN 145
@@ -446,6 +479,8 @@ void ERR_load_PKCS7_strings(void);
446#define PKCS7_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE 127 479#define PKCS7_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE 127
447#define PKCS7_R_SIGNATURE_FAILURE 105 480#define PKCS7_R_SIGNATURE_FAILURE 105
448#define PKCS7_R_SIGNER_CERTIFICATE_NOT_FOUND 128 481#define PKCS7_R_SIGNER_CERTIFICATE_NOT_FOUND 128
482#define PKCS7_R_SIGNING_CTRL_FAILURE 147
483#define PKCS7_R_SIGNING_NOT_SUPPORTED_FOR_THIS_KEY_TYPE 148
449#define PKCS7_R_SIG_INVALID_MIME_TYPE 141 484#define PKCS7_R_SIG_INVALID_MIME_TYPE 141
450#define PKCS7_R_SMIME_TEXT_ERROR 129 485#define PKCS7_R_SMIME_TEXT_ERROR 129
451#define PKCS7_R_UNABLE_TO_FIND_CERTIFICATE 106 486#define PKCS7_R_UNABLE_TO_FIND_CERTIFICATE 106
diff --git a/src/lib/libcrypto/pkcs7/pkcs7err.c b/src/lib/libcrypto/pkcs7/pkcs7err.c
index c0e3d4cd33..d0af32a265 100644
--- a/src/lib/libcrypto/pkcs7/pkcs7err.c
+++ b/src/lib/libcrypto/pkcs7/pkcs7err.c
@@ -1,6 +1,6 @@
1/* crypto/pkcs7/pkcs7err.c */ 1/* crypto/pkcs7/pkcs7err.c */
2/* ==================================================================== 2/* ====================================================================
3 * Copyright (c) 1999-2005 The OpenSSL Project. All rights reserved. 3 * Copyright (c) 1999-2007 The OpenSSL Project. All rights reserved.
4 * 4 *
5 * Redistribution and use in source and binary forms, with or without 5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions 6 * modification, are permitted provided that the following conditions
@@ -72,12 +72,17 @@ static ERR_STRING_DATA PKCS7_str_functs[]=
72 { 72 {
73{ERR_FUNC(PKCS7_F_B64_READ_PKCS7), "B64_READ_PKCS7"}, 73{ERR_FUNC(PKCS7_F_B64_READ_PKCS7), "B64_READ_PKCS7"},
74{ERR_FUNC(PKCS7_F_B64_WRITE_PKCS7), "B64_WRITE_PKCS7"}, 74{ERR_FUNC(PKCS7_F_B64_WRITE_PKCS7), "B64_WRITE_PKCS7"},
75{ERR_FUNC(PKCS7_F_DO_PKCS7_SIGNED_ATTRIB), "DO_PKCS7_SIGNED_ATTRIB"},
76{ERR_FUNC(PKCS7_F_I2D_PKCS7_BIO_STREAM), "i2d_PKCS7_bio_stream"},
77{ERR_FUNC(PKCS7_F_PKCS7_ADD0_ATTRIB_SIGNING_TIME), "PKCS7_add0_attrib_signing_time"},
75{ERR_FUNC(PKCS7_F_PKCS7_ADD_ATTRIB_SMIMECAP), "PKCS7_add_attrib_smimecap"}, 78{ERR_FUNC(PKCS7_F_PKCS7_ADD_ATTRIB_SMIMECAP), "PKCS7_add_attrib_smimecap"},
76{ERR_FUNC(PKCS7_F_PKCS7_ADD_CERTIFICATE), "PKCS7_add_certificate"}, 79{ERR_FUNC(PKCS7_F_PKCS7_ADD_CERTIFICATE), "PKCS7_add_certificate"},
77{ERR_FUNC(PKCS7_F_PKCS7_ADD_CRL), "PKCS7_add_crl"}, 80{ERR_FUNC(PKCS7_F_PKCS7_ADD_CRL), "PKCS7_add_crl"},
78{ERR_FUNC(PKCS7_F_PKCS7_ADD_RECIPIENT_INFO), "PKCS7_add_recipient_info"}, 81{ERR_FUNC(PKCS7_F_PKCS7_ADD_RECIPIENT_INFO), "PKCS7_add_recipient_info"},
82{ERR_FUNC(PKCS7_F_PKCS7_ADD_SIGNATURE), "PKCS7_add_signature"},
79{ERR_FUNC(PKCS7_F_PKCS7_ADD_SIGNER), "PKCS7_add_signer"}, 83{ERR_FUNC(PKCS7_F_PKCS7_ADD_SIGNER), "PKCS7_add_signer"},
80{ERR_FUNC(PKCS7_F_PKCS7_BIO_ADD_DIGEST), "PKCS7_BIO_ADD_DIGEST"}, 84{ERR_FUNC(PKCS7_F_PKCS7_BIO_ADD_DIGEST), "PKCS7_BIO_ADD_DIGEST"},
85{ERR_FUNC(PKCS7_F_PKCS7_COPY_EXISTING_DIGEST), "PKCS7_COPY_EXISTING_DIGEST"},
81{ERR_FUNC(PKCS7_F_PKCS7_CTRL), "PKCS7_ctrl"}, 86{ERR_FUNC(PKCS7_F_PKCS7_CTRL), "PKCS7_ctrl"},
82{ERR_FUNC(PKCS7_F_PKCS7_DATADECODE), "PKCS7_dataDecode"}, 87{ERR_FUNC(PKCS7_F_PKCS7_DATADECODE), "PKCS7_dataDecode"},
83{ERR_FUNC(PKCS7_F_PKCS7_DATAFINAL), "PKCS7_dataFinal"}, 88{ERR_FUNC(PKCS7_F_PKCS7_DATAFINAL), "PKCS7_dataFinal"},
@@ -85,15 +90,22 @@ static ERR_STRING_DATA PKCS7_str_functs[]=
85{ERR_FUNC(PKCS7_F_PKCS7_DATASIGN), "PKCS7_DATASIGN"}, 90{ERR_FUNC(PKCS7_F_PKCS7_DATASIGN), "PKCS7_DATASIGN"},
86{ERR_FUNC(PKCS7_F_PKCS7_DATAVERIFY), "PKCS7_dataVerify"}, 91{ERR_FUNC(PKCS7_F_PKCS7_DATAVERIFY), "PKCS7_dataVerify"},
87{ERR_FUNC(PKCS7_F_PKCS7_DECRYPT), "PKCS7_decrypt"}, 92{ERR_FUNC(PKCS7_F_PKCS7_DECRYPT), "PKCS7_decrypt"},
93{ERR_FUNC(PKCS7_F_PKCS7_DECRYPT_RINFO), "PKCS7_DECRYPT_RINFO"},
94{ERR_FUNC(PKCS7_F_PKCS7_ENCODE_RINFO), "PKCS7_ENCODE_RINFO"},
88{ERR_FUNC(PKCS7_F_PKCS7_ENCRYPT), "PKCS7_encrypt"}, 95{ERR_FUNC(PKCS7_F_PKCS7_ENCRYPT), "PKCS7_encrypt"},
96{ERR_FUNC(PKCS7_F_PKCS7_FINAL), "PKCS7_final"},
89{ERR_FUNC(PKCS7_F_PKCS7_FIND_DIGEST), "PKCS7_FIND_DIGEST"}, 97{ERR_FUNC(PKCS7_F_PKCS7_FIND_DIGEST), "PKCS7_FIND_DIGEST"},
90{ERR_FUNC(PKCS7_F_PKCS7_GET0_SIGNERS), "PKCS7_get0_signers"}, 98{ERR_FUNC(PKCS7_F_PKCS7_GET0_SIGNERS), "PKCS7_get0_signers"},
99{ERR_FUNC(PKCS7_F_PKCS7_RECIP_INFO_SET), "PKCS7_RECIP_INFO_set"},
91{ERR_FUNC(PKCS7_F_PKCS7_SET_CIPHER), "PKCS7_set_cipher"}, 100{ERR_FUNC(PKCS7_F_PKCS7_SET_CIPHER), "PKCS7_set_cipher"},
92{ERR_FUNC(PKCS7_F_PKCS7_SET_CONTENT), "PKCS7_set_content"}, 101{ERR_FUNC(PKCS7_F_PKCS7_SET_CONTENT), "PKCS7_set_content"},
93{ERR_FUNC(PKCS7_F_PKCS7_SET_DIGEST), "PKCS7_set_digest"}, 102{ERR_FUNC(PKCS7_F_PKCS7_SET_DIGEST), "PKCS7_set_digest"},
94{ERR_FUNC(PKCS7_F_PKCS7_SET_TYPE), "PKCS7_set_type"}, 103{ERR_FUNC(PKCS7_F_PKCS7_SET_TYPE), "PKCS7_set_type"},
95{ERR_FUNC(PKCS7_F_PKCS7_SIGN), "PKCS7_sign"}, 104{ERR_FUNC(PKCS7_F_PKCS7_SIGN), "PKCS7_sign"},
96{ERR_FUNC(PKCS7_F_PKCS7_SIGNATUREVERIFY), "PKCS7_signatureVerify"}, 105{ERR_FUNC(PKCS7_F_PKCS7_SIGNATUREVERIFY), "PKCS7_signatureVerify"},
106{ERR_FUNC(PKCS7_F_PKCS7_SIGNER_INFO_SET), "PKCS7_SIGNER_INFO_set"},
107{ERR_FUNC(PKCS7_F_PKCS7_SIGNER_INFO_SIGN), "PKCS7_SIGNER_INFO_sign"},
108{ERR_FUNC(PKCS7_F_PKCS7_SIGN_ADD_SIGNER), "PKCS7_sign_add_signer"},
97{ERR_FUNC(PKCS7_F_PKCS7_SIMPLE_SMIMECAP), "PKCS7_simple_smimecap"}, 109{ERR_FUNC(PKCS7_F_PKCS7_SIMPLE_SMIMECAP), "PKCS7_simple_smimecap"},
98{ERR_FUNC(PKCS7_F_PKCS7_VERIFY), "PKCS7_verify"}, 110{ERR_FUNC(PKCS7_F_PKCS7_VERIFY), "PKCS7_verify"},
99{ERR_FUNC(PKCS7_F_SMIME_READ_PKCS7), "SMIME_read_PKCS7"}, 111{ERR_FUNC(PKCS7_F_SMIME_READ_PKCS7), "SMIME_read_PKCS7"},
@@ -107,10 +119,13 @@ static ERR_STRING_DATA PKCS7_str_reasons[]=
107{ERR_REASON(PKCS7_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER),"cipher has no object identifier"}, 119{ERR_REASON(PKCS7_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER),"cipher has no object identifier"},
108{ERR_REASON(PKCS7_R_CIPHER_NOT_INITIALIZED),"cipher not initialized"}, 120{ERR_REASON(PKCS7_R_CIPHER_NOT_INITIALIZED),"cipher not initialized"},
109{ERR_REASON(PKCS7_R_CONTENT_AND_DATA_PRESENT),"content and data present"}, 121{ERR_REASON(PKCS7_R_CONTENT_AND_DATA_PRESENT),"content and data present"},
122{ERR_REASON(PKCS7_R_CTRL_ERROR) ,"ctrl error"},
110{ERR_REASON(PKCS7_R_DECODE_ERROR) ,"decode error"}, 123{ERR_REASON(PKCS7_R_DECODE_ERROR) ,"decode error"},
111{ERR_REASON(PKCS7_R_DECRYPTED_KEY_IS_WRONG_LENGTH),"decrypted key is wrong length"}, 124{ERR_REASON(PKCS7_R_DECRYPTED_KEY_IS_WRONG_LENGTH),"decrypted key is wrong length"},
112{ERR_REASON(PKCS7_R_DECRYPT_ERROR) ,"decrypt error"}, 125{ERR_REASON(PKCS7_R_DECRYPT_ERROR) ,"decrypt error"},
113{ERR_REASON(PKCS7_R_DIGEST_FAILURE) ,"digest failure"}, 126{ERR_REASON(PKCS7_R_DIGEST_FAILURE) ,"digest failure"},
127{ERR_REASON(PKCS7_R_ENCRYPTION_CTRL_FAILURE),"encryption ctrl failure"},
128{ERR_REASON(PKCS7_R_ENCRYPTION_NOT_SUPPORTED_FOR_THIS_KEY_TYPE),"encryption not supported for this key type"},
114{ERR_REASON(PKCS7_R_ERROR_ADDING_RECIPIENT),"error adding recipient"}, 129{ERR_REASON(PKCS7_R_ERROR_ADDING_RECIPIENT),"error adding recipient"},
115{ERR_REASON(PKCS7_R_ERROR_SETTING_CIPHER),"error setting cipher"}, 130{ERR_REASON(PKCS7_R_ERROR_SETTING_CIPHER),"error setting cipher"},
116{ERR_REASON(PKCS7_R_INVALID_MIME_TYPE) ,"invalid mime type"}, 131{ERR_REASON(PKCS7_R_INVALID_MIME_TYPE) ,"invalid mime type"},
@@ -121,6 +136,8 @@ static ERR_STRING_DATA PKCS7_str_reasons[]=
121{ERR_REASON(PKCS7_R_MISSING_CERIPEND_INFO),"missing ceripend info"}, 136{ERR_REASON(PKCS7_R_MISSING_CERIPEND_INFO),"missing ceripend info"},
122{ERR_REASON(PKCS7_R_NO_CONTENT) ,"no content"}, 137{ERR_REASON(PKCS7_R_NO_CONTENT) ,"no content"},
123{ERR_REASON(PKCS7_R_NO_CONTENT_TYPE) ,"no content type"}, 138{ERR_REASON(PKCS7_R_NO_CONTENT_TYPE) ,"no content type"},
139{ERR_REASON(PKCS7_R_NO_DEFAULT_DIGEST) ,"no default digest"},
140{ERR_REASON(PKCS7_R_NO_MATCHING_DIGEST_TYPE_FOUND),"no matching digest type found"},
124{ERR_REASON(PKCS7_R_NO_MULTIPART_BODY_FAILURE),"no multipart body failure"}, 141{ERR_REASON(PKCS7_R_NO_MULTIPART_BODY_FAILURE),"no multipart body failure"},
125{ERR_REASON(PKCS7_R_NO_MULTIPART_BOUNDARY),"no multipart boundary"}, 142{ERR_REASON(PKCS7_R_NO_MULTIPART_BOUNDARY),"no multipart boundary"},
126{ERR_REASON(PKCS7_R_NO_RECIPIENT_MATCHES_CERTIFICATE),"no recipient matches certificate"}, 143{ERR_REASON(PKCS7_R_NO_RECIPIENT_MATCHES_CERTIFICATE),"no recipient matches certificate"},
@@ -130,6 +147,7 @@ static ERR_STRING_DATA PKCS7_str_reasons[]=
130{ERR_REASON(PKCS7_R_NO_SIG_CONTENT_TYPE) ,"no sig content type"}, 147{ERR_REASON(PKCS7_R_NO_SIG_CONTENT_TYPE) ,"no sig content type"},
131{ERR_REASON(PKCS7_R_OPERATION_NOT_SUPPORTED_ON_THIS_TYPE),"operation not supported on this type"}, 148{ERR_REASON(PKCS7_R_OPERATION_NOT_SUPPORTED_ON_THIS_TYPE),"operation not supported on this type"},
132{ERR_REASON(PKCS7_R_PKCS7_ADD_SIGNATURE_ERROR),"pkcs7 add signature error"}, 149{ERR_REASON(PKCS7_R_PKCS7_ADD_SIGNATURE_ERROR),"pkcs7 add signature error"},
150{ERR_REASON(PKCS7_R_PKCS7_ADD_SIGNER_ERROR),"pkcs7 add signer error"},
133{ERR_REASON(PKCS7_R_PKCS7_DATAFINAL) ,"pkcs7 datafinal"}, 151{ERR_REASON(PKCS7_R_PKCS7_DATAFINAL) ,"pkcs7 datafinal"},
134{ERR_REASON(PKCS7_R_PKCS7_DATAFINAL_ERROR),"pkcs7 datafinal error"}, 152{ERR_REASON(PKCS7_R_PKCS7_DATAFINAL_ERROR),"pkcs7 datafinal error"},
135{ERR_REASON(PKCS7_R_PKCS7_DATASIGN) ,"pkcs7 datasign"}, 153{ERR_REASON(PKCS7_R_PKCS7_DATASIGN) ,"pkcs7 datasign"},
@@ -138,6 +156,8 @@ static ERR_STRING_DATA PKCS7_str_reasons[]=
138{ERR_REASON(PKCS7_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE),"private key does not match certificate"}, 156{ERR_REASON(PKCS7_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE),"private key does not match certificate"},
139{ERR_REASON(PKCS7_R_SIGNATURE_FAILURE) ,"signature failure"}, 157{ERR_REASON(PKCS7_R_SIGNATURE_FAILURE) ,"signature failure"},
140{ERR_REASON(PKCS7_R_SIGNER_CERTIFICATE_NOT_FOUND),"signer certificate not found"}, 158{ERR_REASON(PKCS7_R_SIGNER_CERTIFICATE_NOT_FOUND),"signer certificate not found"},
159{ERR_REASON(PKCS7_R_SIGNING_CTRL_FAILURE),"signing ctrl failure"},
160{ERR_REASON(PKCS7_R_SIGNING_NOT_SUPPORTED_FOR_THIS_KEY_TYPE),"signing not supported for this key type"},
141{ERR_REASON(PKCS7_R_SIG_INVALID_MIME_TYPE),"sig invalid mime type"}, 161{ERR_REASON(PKCS7_R_SIG_INVALID_MIME_TYPE),"sig invalid mime type"},
142{ERR_REASON(PKCS7_R_SMIME_TEXT_ERROR) ,"smime text error"}, 162{ERR_REASON(PKCS7_R_SMIME_TEXT_ERROR) ,"smime text error"},
143{ERR_REASON(PKCS7_R_UNABLE_TO_FIND_CERTIFICATE),"unable to find certificate"}, 163{ERR_REASON(PKCS7_R_UNABLE_TO_FIND_CERTIFICATE),"unable to find certificate"},
diff --git a/src/lib/libcrypto/ppccpuid.pl b/src/lib/libcrypto/ppccpuid.pl
index fe44ff07bc..369e1d0df9 100755
--- a/src/lib/libcrypto/ppccpuid.pl
+++ b/src/lib/libcrypto/ppccpuid.pl
@@ -67,6 +67,8 @@ Loop: lwarx r5,0,r3
67 $CMPLI r4,7 67 $CMPLI r4,7
68 li r0,0 68 li r0,0
69 bge Lot 69 bge Lot
70 $CMPLI r4,0
71 beqlr-
70Little: mtctr r4 72Little: mtctr r4
71 stb r0,0(r3) 73 stb r0,0(r3)
72 addi r3,r3,1 74 addi r3,r3,1
diff --git a/src/lib/libcrypto/rand/rand.h b/src/lib/libcrypto/rand/rand.h
index ea89153cba..ac6c021763 100644
--- a/src/lib/libcrypto/rand/rand.h
+++ b/src/lib/libcrypto/rand/rand.h
@@ -72,7 +72,7 @@ extern "C" {
72#endif 72#endif
73 73
74#if defined(OPENSSL_FIPS) 74#if defined(OPENSSL_FIPS)
75#define FIPS_RAND_SIZE_T int 75#define FIPS_RAND_SIZE_T size_t
76#endif 76#endif
77 77
78/* Already defined in ossl_typ.h */ 78/* Already defined in ossl_typ.h */
@@ -111,15 +111,6 @@ int RAND_query_egd_bytes(const char *path, unsigned char *buf, int bytes);
111int RAND_egd(const char *path); 111int RAND_egd(const char *path);
112int RAND_egd_bytes(const char *path,int bytes); 112int RAND_egd_bytes(const char *path,int bytes);
113int RAND_poll(void); 113int RAND_poll(void);
114#ifndef OPENSSL_NO_ENGINE
115#ifdef OPENSSL_FIPS
116void int_RAND_init_engine_callbacks(void);
117void int_RAND_set_callbacks(
118 int (*set_rand_func)(const RAND_METHOD *meth,
119 const RAND_METHOD **pmeth),
120 const RAND_METHOD *(*get_rand_func)(const RAND_METHOD **pmeth));
121#endif
122#endif
123 114
124#if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_WIN32) 115#if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_WIN32)
125 116
@@ -137,29 +128,11 @@ void ERR_load_RAND_strings(void);
137/* Error codes for the RAND functions. */ 128/* Error codes for the RAND functions. */
138 129
139/* Function codes. */ 130/* Function codes. */
140#define RAND_F_ENG_RAND_GET_RAND_METHOD 108
141#define RAND_F_FIPS_RAND 103
142#define RAND_F_FIPS_RAND_BYTES 102
143#define RAND_F_FIPS_RAND_GET_RAND_METHOD 109
144#define RAND_F_FIPS_RAND_SET_DT 106
145#define RAND_F_FIPS_SET_DT 104
146#define RAND_F_FIPS_SET_PRNG_SEED 107
147#define RAND_F_FIPS_SET_TEST_MODE 105
148#define RAND_F_RAND_GET_RAND_METHOD 101 131#define RAND_F_RAND_GET_RAND_METHOD 101
149#define RAND_F_SSLEAY_RAND_BYTES 100 132#define RAND_F_SSLEAY_RAND_BYTES 100
150 133
151/* Reason codes. */ 134/* Reason codes. */
152#define RAND_R_NON_FIPS_METHOD 105
153#define RAND_R_NOT_IN_TEST_MODE 106
154#define RAND_R_NO_KEY_SET 107
155#define RAND_R_PRNG_ASKING_FOR_TOO_MUCH 101
156#define RAND_R_PRNG_ERROR 108
157#define RAND_R_PRNG_KEYED 109
158#define RAND_R_PRNG_NOT_REKEYED 102
159#define RAND_R_PRNG_NOT_RESEEDED 103
160#define RAND_R_PRNG_NOT_SEEDED 100 135#define RAND_R_PRNG_NOT_SEEDED 100
161#define RAND_R_PRNG_SEED_MUST_NOT_MATCH_KEY 110
162#define RAND_R_PRNG_STUCK 104
163 136
164#ifdef __cplusplus 137#ifdef __cplusplus
165} 138}
diff --git a/src/lib/libcrypto/rand/rand_err.c b/src/lib/libcrypto/rand/rand_err.c
index 829fb44d77..03cda4dd92 100644
--- a/src/lib/libcrypto/rand/rand_err.c
+++ b/src/lib/libcrypto/rand/rand_err.c
@@ -1,6 +1,6 @@
1/* crypto/rand/rand_err.c */ 1/* crypto/rand/rand_err.c */
2/* ==================================================================== 2/* ====================================================================
3 * Copyright (c) 1999-2007 The OpenSSL Project. All rights reserved. 3 * Copyright (c) 1999-2006 The OpenSSL Project. All rights reserved.
4 * 4 *
5 * Redistribution and use in source and binary forms, with or without 5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions 6 * modification, are permitted provided that the following conditions
@@ -70,14 +70,6 @@
70 70
71static ERR_STRING_DATA RAND_str_functs[]= 71static ERR_STRING_DATA RAND_str_functs[]=
72 { 72 {
73{ERR_FUNC(RAND_F_ENG_RAND_GET_RAND_METHOD), "ENG_RAND_GET_RAND_METHOD"},
74{ERR_FUNC(RAND_F_FIPS_RAND), "FIPS_RAND"},
75{ERR_FUNC(RAND_F_FIPS_RAND_BYTES), "FIPS_RAND_BYTES"},
76{ERR_FUNC(RAND_F_FIPS_RAND_GET_RAND_METHOD), "FIPS_RAND_GET_RAND_METHOD"},
77{ERR_FUNC(RAND_F_FIPS_RAND_SET_DT), "FIPS_RAND_SET_DT"},
78{ERR_FUNC(RAND_F_FIPS_SET_DT), "FIPS_SET_DT"},
79{ERR_FUNC(RAND_F_FIPS_SET_PRNG_SEED), "FIPS_SET_PRNG_SEED"},
80{ERR_FUNC(RAND_F_FIPS_SET_TEST_MODE), "FIPS_SET_TEST_MODE"},
81{ERR_FUNC(RAND_F_RAND_GET_RAND_METHOD), "RAND_get_rand_method"}, 73{ERR_FUNC(RAND_F_RAND_GET_RAND_METHOD), "RAND_get_rand_method"},
82{ERR_FUNC(RAND_F_SSLEAY_RAND_BYTES), "SSLEAY_RAND_BYTES"}, 74{ERR_FUNC(RAND_F_SSLEAY_RAND_BYTES), "SSLEAY_RAND_BYTES"},
83{0,NULL} 75{0,NULL}
@@ -85,17 +77,7 @@ static ERR_STRING_DATA RAND_str_functs[]=
85 77
86static ERR_STRING_DATA RAND_str_reasons[]= 78static ERR_STRING_DATA RAND_str_reasons[]=
87 { 79 {
88{ERR_REASON(RAND_R_NON_FIPS_METHOD) ,"non fips method"},
89{ERR_REASON(RAND_R_NOT_IN_TEST_MODE) ,"not in test mode"},
90{ERR_REASON(RAND_R_NO_KEY_SET) ,"no key set"},
91{ERR_REASON(RAND_R_PRNG_ASKING_FOR_TOO_MUCH),"prng asking for too much"},
92{ERR_REASON(RAND_R_PRNG_ERROR) ,"prng error"},
93{ERR_REASON(RAND_R_PRNG_KEYED) ,"prng keyed"},
94{ERR_REASON(RAND_R_PRNG_NOT_REKEYED) ,"prng not rekeyed"},
95{ERR_REASON(RAND_R_PRNG_NOT_RESEEDED) ,"prng not reseeded"},
96{ERR_REASON(RAND_R_PRNG_NOT_SEEDED) ,"PRNG not seeded"}, 80{ERR_REASON(RAND_R_PRNG_NOT_SEEDED) ,"PRNG not seeded"},
97{ERR_REASON(RAND_R_PRNG_SEED_MUST_NOT_MATCH_KEY),"prng seed must not match key"},
98{ERR_REASON(RAND_R_PRNG_STUCK) ,"prng stuck"},
99{0,NULL} 81{0,NULL}
100 }; 82 };
101 83
diff --git a/src/lib/libcrypto/rand/rand_lib.c b/src/lib/libcrypto/rand/rand_lib.c
index da6b4e0e86..513e338985 100644
--- a/src/lib/libcrypto/rand/rand_lib.c
+++ b/src/lib/libcrypto/rand/rand_lib.c
@@ -60,82 +60,15 @@
60#include <time.h> 60#include <time.h>
61#include "cryptlib.h" 61#include "cryptlib.h"
62#include <openssl/rand.h> 62#include <openssl/rand.h>
63#include "rand_lcl.h"
64#ifdef OPENSSL_FIPS
65#include <openssl/fips.h>
66#include <openssl/fips_rand.h>
67#endif
68
69#ifndef OPENSSL_NO_ENGINE 63#ifndef OPENSSL_NO_ENGINE
70#include <openssl/engine.h> 64#include <openssl/engine.h>
71#endif 65#endif
72 66
73static const RAND_METHOD *default_RAND_meth = NULL;
74
75#ifdef OPENSSL_FIPS
76
77static int fips_RAND_set_rand_method(const RAND_METHOD *meth,
78 const RAND_METHOD **pmeth)
79 {
80 *pmeth = meth;
81 return 1;
82 }
83
84static const RAND_METHOD *fips_RAND_get_rand_method(const RAND_METHOD **pmeth)
85 {
86 if (!*pmeth)
87 {
88 if(FIPS_mode())
89 *pmeth=FIPS_rand_method();
90 else
91 *pmeth = RAND_SSLeay();
92 }
93
94 if(FIPS_mode()
95 && *pmeth != FIPS_rand_check())
96 {
97 RANDerr(RAND_F_FIPS_RAND_GET_RAND_METHOD,RAND_R_NON_FIPS_METHOD);
98 return 0;
99 }
100
101 return *pmeth;
102 }
103
104static int (*RAND_set_rand_method_func)(const RAND_METHOD *meth,
105 const RAND_METHOD **pmeth)
106 = fips_RAND_set_rand_method;
107static const RAND_METHOD *(*RAND_get_rand_method_func)
108 (const RAND_METHOD **pmeth)
109 = fips_RAND_get_rand_method;
110
111#ifndef OPENSSL_NO_ENGINE
112void int_RAND_set_callbacks(
113 int (*set_rand_func)(const RAND_METHOD *meth,
114 const RAND_METHOD **pmeth),
115 const RAND_METHOD *(*get_rand_func)
116 (const RAND_METHOD **pmeth))
117 {
118 RAND_set_rand_method_func = set_rand_func;
119 RAND_get_rand_method_func = get_rand_func;
120 }
121#endif
122
123int RAND_set_rand_method(const RAND_METHOD *meth)
124 {
125 return RAND_set_rand_method_func(meth, &default_RAND_meth);
126 }
127
128const RAND_METHOD *RAND_get_rand_method(void)
129 {
130 return RAND_get_rand_method_func(&default_RAND_meth);
131 }
132
133#else
134
135#ifndef OPENSSL_NO_ENGINE 67#ifndef OPENSSL_NO_ENGINE
136/* non-NULL if default_RAND_meth is ENGINE-provided */ 68/* non-NULL if default_RAND_meth is ENGINE-provided */
137static ENGINE *funct_ref =NULL; 69static ENGINE *funct_ref =NULL;
138#endif 70#endif
71static const RAND_METHOD *default_RAND_meth = NULL;
139 72
140int RAND_set_rand_method(const RAND_METHOD *meth) 73int RAND_set_rand_method(const RAND_METHOD *meth)
141 { 74 {
@@ -196,8 +129,6 @@ int RAND_set_rand_engine(ENGINE *engine)
196 } 129 }
197#endif 130#endif
198 131
199#endif
200
201void RAND_cleanup(void) 132void RAND_cleanup(void)
202 { 133 {
203 const RAND_METHOD *meth = RAND_get_rand_method(); 134 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 d108353bbc..4ed40b7b70 100644
--- a/src/lib/libcrypto/rand/randfile.c
+++ b/src/lib/libcrypto/rand/randfile.c
@@ -75,9 +75,7 @@
75#ifndef NO_SYS_TYPES_H 75#ifndef NO_SYS_TYPES_H
76# include <sys/types.h> 76# include <sys/types.h>
77#endif 77#endif
78#ifdef MAC_OS_pre_X 78#ifndef OPENSSL_NO_POSIX_IO
79# include <stat.h>
80#else
81# include <sys/stat.h> 79# include <sys/stat.h>
82#endif 80#endif
83 81
@@ -111,14 +109,26 @@ int RAND_load_file(const char *file, long bytes)
111 * if bytes == -1, read complete file. */ 109 * if bytes == -1, read complete file. */
112 110
113 MS_STATIC unsigned char buf[BUFSIZE]; 111 MS_STATIC unsigned char buf[BUFSIZE];
112#ifndef OPENSSL_NO_POSIX_IO
114 struct stat sb; 113 struct stat sb;
114#endif
115 int i,ret=0,n; 115 int i,ret=0,n;
116 FILE *in; 116 FILE *in;
117 117
118 if (file == NULL) return(0); 118 if (file == NULL) return(0);
119 119
120#ifndef OPENSSL_NO_POSIX_IO
121#ifdef PURIFY
122 /* struct stat can have padding and unused fields that may not be
123 * initialized in the call to stat(). We need to clear the entire
124 * structure before calling RAND_add() to avoid complaints from
125 * applications such as Valgrind.
126 */
127 memset(&sb, 0, sizeof(sb));
128#endif
120 if (stat(file,&sb) < 0) return(0); 129 if (stat(file,&sb) < 0) return(0);
121 RAND_add(&sb,sizeof(sb),0.0); 130 RAND_add(&sb,sizeof(sb),0.0);
131#endif
122 if (bytes == 0) return(ret); 132 if (bytes == 0) return(ret);
123 133
124#ifdef OPENSSL_SYS_VMS 134#ifdef OPENSSL_SYS_VMS
@@ -127,7 +137,7 @@ int RAND_load_file(const char *file, long bytes)
127 in=fopen(file,"rb"); 137 in=fopen(file,"rb");
128#endif 138#endif
129 if (in == NULL) goto err; 139 if (in == NULL) goto err;
130#if defined(S_IFBLK) && defined(S_IFCHR) 140#if defined(S_IFBLK) && defined(S_IFCHR) && !defined(OPNESSL_NO_POSIX_IO)
131 if (sb.st_mode & (S_IFBLK | S_IFCHR)) { 141 if (sb.st_mode & (S_IFBLK | S_IFCHR)) {
132 /* this file is a device. we don't want read an infinite number 142 /* this file is a device. we don't want read an infinite number
133 * of bytes from a random device, nor do we want to use buffered 143 * of bytes from a random device, nor do we want to use buffered
@@ -170,12 +180,13 @@ int RAND_write_file(const char *file)
170 int i,ret=0,rand_err=0; 180 int i,ret=0,rand_err=0;
171 FILE *out = NULL; 181 FILE *out = NULL;
172 int n; 182 int n;
183#ifndef OPENSSL_NO_POSIX_IO
173 struct stat sb; 184 struct stat sb;
174 185
175 i=stat(file,&sb); 186 i=stat(file,&sb);
176 if (i != -1) { 187 if (i != -1) {
177#if defined(S_IFBLK) && defined(S_IFCHR) 188#if defined(S_ISBLK) && defined(S_ISCHR)
178 if (sb.st_mode & (S_IFBLK | S_IFCHR)) { 189 if (S_ISBLK(sb.st_mode) || S_ISCHR(sb.st_mode)) {
179 /* this file is a device. we don't write back to it. 190 /* this file is a device. we don't write back to it.
180 * we "succeed" on the assumption this is some sort 191 * we "succeed" on the assumption this is some sort
181 * of random device. Otherwise attempting to write to 192 * of random device. Otherwise attempting to write to
@@ -185,14 +196,16 @@ int RAND_write_file(const char *file)
185 } 196 }
186#endif 197#endif
187 } 198 }
199#endif
188 200
189#if defined(O_CREAT) && !defined(OPENSSL_SYS_WIN32) && !defined(OPENSSL_SYS_VMS) 201#if defined(O_CREAT) && !defined(OPENSSL_NO_POSIX_IO) && !defined(OPENSSL_SYS_VMS)
190 { 202 {
191 /* For some reason Win32 can't write to files created this way */ 203#ifndef O_BINARY
192 204#define O_BINARY 0
205#endif
193 /* chmod(..., 0600) is too late to protect the file, 206 /* chmod(..., 0600) is too late to protect the file,
194 * permissions should be restrictive from the start */ 207 * permissions should be restrictive from the start */
195 int fd = open(file, O_CREAT, 0600); 208 int fd = open(file, O_WRONLY|O_CREAT|O_BINARY, 0600);
196 if (fd != -1) 209 if (fd != -1)
197 out = fdopen(fd, "wb"); 210 out = fdopen(fd, "wb");
198 } 211 }
diff --git a/src/lib/libcrypto/rc2/rc2.h b/src/lib/libcrypto/rc2/rc2.h
index e542ec94ff..34c8362317 100644
--- a/src/lib/libcrypto/rc2/rc2.h
+++ b/src/lib/libcrypto/rc2/rc2.h
@@ -79,9 +79,7 @@ typedef struct rc2_key_st
79 RC2_INT data[64]; 79 RC2_INT data[64];
80 } RC2_KEY; 80 } RC2_KEY;
81 81
82#ifdef OPENSSL_FIPS 82
83void private_RC2_set_key(RC2_KEY *key, int len, const unsigned char *data,int bits);
84#endif
85void RC2_set_key(RC2_KEY *key, int len, const unsigned char *data,int bits); 83void RC2_set_key(RC2_KEY *key, int len, const unsigned char *data,int bits);
86void RC2_ecb_encrypt(const unsigned char *in,unsigned char *out,RC2_KEY *key, 84void RC2_ecb_encrypt(const unsigned char *in,unsigned char *out,RC2_KEY *key,
87 int enc); 85 int enc);
diff --git a/src/lib/libcrypto/rc2/rc2_skey.c b/src/lib/libcrypto/rc2/rc2_skey.c
index 4e000e5b99..0150b0e035 100644
--- a/src/lib/libcrypto/rc2/rc2_skey.c
+++ b/src/lib/libcrypto/rc2/rc2_skey.c
@@ -57,14 +57,9 @@
57 */ 57 */
58 58
59#include <openssl/rc2.h> 59#include <openssl/rc2.h>
60#include <openssl/crypto.h>
61#ifdef OPENSSL_FIPS
62#include <openssl/fips.h>
63#endif
64
65#include "rc2_locl.h" 60#include "rc2_locl.h"
66 61
67static unsigned char key_table[256]={ 62static const unsigned char key_table[256]={
68 0xd9,0x78,0xf9,0xc4,0x19,0xdd,0xb5,0xed,0x28,0xe9,0xfd,0x79, 63 0xd9,0x78,0xf9,0xc4,0x19,0xdd,0xb5,0xed,0x28,0xe9,0xfd,0x79,
69 0x4a,0xa0,0xd8,0x9d,0xc6,0x7e,0x37,0x83,0x2b,0x76,0x53,0x8e, 64 0x4a,0xa0,0xd8,0x9d,0xc6,0x7e,0x37,0x83,0x2b,0x76,0x53,0x8e,
70 0x62,0x4c,0x64,0x88,0x44,0x8b,0xfb,0xa2,0x17,0x9a,0x59,0xf5, 65 0x62,0x4c,0x64,0x88,0x44,0x8b,0xfb,0xa2,0x17,0x9a,0x59,0xf5,
@@ -99,20 +94,8 @@ static unsigned char key_table[256]={
99 * BSAFE uses the 'retarded' version. What I previously shipped is 94 * BSAFE uses the 'retarded' version. What I previously shipped is
100 * the same as specifying 1024 for the 'bits' parameter. Bsafe uses 95 * the same as specifying 1024 for the 'bits' parameter. Bsafe uses
101 * a version where the bits parameter is the same as len*8 */ 96 * a version where the bits parameter is the same as len*8 */
102
103#ifdef OPENSSL_FIPS
104void RC2_set_key(RC2_KEY *key, int len, const unsigned char *data, int bits) 97void RC2_set_key(RC2_KEY *key, int len, const unsigned char *data, int bits)
105 { 98 {
106 if (FIPS_mode())
107 FIPS_BAD_ABORT(RC2)
108 private_RC2_set_key(key, len, data, bits);
109 }
110void private_RC2_set_key(RC2_KEY *key, int len, const unsigned char *data,
111 int bits)
112#else
113void RC2_set_key(RC2_KEY *key, int len, const unsigned char *data, int bits)
114#endif
115 {
116 int i,j; 99 int i,j;
117 unsigned char *k; 100 unsigned char *k;
118 RC2_INT *ki; 101 RC2_INT *ki;
diff --git a/src/lib/libcrypto/rc4/asm/rc4-586.pl b/src/lib/libcrypto/rc4/asm/rc4-586.pl
index ef7eee766c..38a44a70ef 100644
--- a/src/lib/libcrypto/rc4/asm/rc4-586.pl
+++ b/src/lib/libcrypto/rc4/asm/rc4-586.pl
@@ -1,14 +1,21 @@
1#!/usr/local/bin/perl 1#!/usr/bin/env perl
2
3# ====================================================================
4# [Re]written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
5# project. The module is, however, dual licensed under OpenSSL and
6# CRYPTOGAMS licenses depending on where you obtain it. For further
7# details see http://www.openssl.org/~appro/cryptogams/.
8# ====================================================================
2 9
3# At some point it became apparent that the original SSLeay RC4 10# At some point it became apparent that the original SSLeay RC4
4# assembler implementation performs suboptimaly on latest IA-32 11# assembler implementation performs suboptimally on latest IA-32
5# microarchitectures. After re-tuning performance has changed as 12# microarchitectures. After re-tuning performance has changed as
6# following: 13# following:
7# 14#
8# Pentium +0% 15# Pentium -10%
9# Pentium III +17% 16# Pentium III +12%
10# AMD +52%(*) 17# AMD +50%(*)
11# P4 +180%(**) 18# P4 +250%(**)
12# 19#
13# (*) This number is actually a trade-off:-) It's possible to 20# (*) This number is actually a trade-off:-) It's possible to
14# achieve +72%, but at the cost of -48% off PIII performance. 21# achieve +72%, but at the cost of -48% off PIII performance.
@@ -17,214 +24,247 @@
17# For reference! This code delivers ~80% of rc4-amd64.pl 24# For reference! This code delivers ~80% of rc4-amd64.pl
18# performance on the same Opteron machine. 25# performance on the same Opteron machine.
19# (**) This number requires compressed key schedule set up by 26# (**) This number requires compressed key schedule set up by
20# RC4_set_key and therefore doesn't apply to 0.9.7 [option for 27# RC4_set_key [see commentary below for further details].
21# compressed key schedule is implemented in 0.9.8 and later,
22# see commentary section in rc4_skey.c for further details].
23# 28#
24# <appro@fy.chalmers.se> 29# <appro@fy.chalmers.se>
25 30
26push(@INC,"perlasm","../../perlasm"); 31$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
32push(@INC,"${dir}","${dir}../../perlasm");
27require "x86asm.pl"; 33require "x86asm.pl";
28 34
29&asm_init($ARGV[0],"rc4-586.pl"); 35&asm_init($ARGV[0],"rc4-586.pl");
30 36
31$x="eax"; 37$xx="eax";
32$y="ebx"; 38$yy="ebx";
33$tx="ecx"; 39$tx="ecx";
34$ty="edx"; 40$ty="edx";
35$in="esi"; 41$inp="esi";
36$out="edi"; 42$out="ebp";
37$d="ebp"; 43$dat="edi";
38 44
39&RC4("RC4"); 45sub RC4_loop {
40 46 my $i=shift;
41&asm_finish(); 47 my $func = ($i==0)?*mov:*or;
42 48
43sub RC4_loop 49 &add (&LB($yy),&LB($tx));
44 { 50 &mov ($ty,&DWP(0,$dat,$yy,4));
45 local($n,$p,$char)=@_; 51 &mov (&DWP(0,$dat,$yy,4),$tx);
46 52 &mov (&DWP(0,$dat,$xx,4),$ty);
47 &comment("Round $n"); 53 &add ($ty,$tx);
48 54 &inc (&LB($xx));
49 if ($char) 55 &and ($ty,0xff);
50 { 56 &ror ($out,8) if ($i!=0);
51 if ($p >= 0) 57 if ($i<3) {
52 { 58 &mov ($tx,&DWP(0,$dat,$xx,4));
53 &mov($ty, &swtmp(2)); 59 } else {
54 &cmp($ty, $in); 60 &mov ($tx,&wparam(3)); # reload [re-biased] out
55 &jbe(&label("finished"));
56 &inc($in);
57 }
58 else
59 {
60 &add($ty, 8);
61 &inc($in);
62 &cmp($ty, $in);
63 &jb(&label("finished"));
64 &mov(&swtmp(2), $ty);
65 }
66 }
67 # Moved out
68 # &mov( $tx, &DWP(0,$d,$x,4)) if $p < 0;
69
70 &add( &LB($y), &LB($tx));
71 &mov( $ty, &DWP(0,$d,$y,4));
72 # XXX
73 &mov( &DWP(0,$d,$x,4),$ty);
74 &add( $ty, $tx);
75 &mov( &DWP(0,$d,$y,4),$tx);
76 &and( $ty, 0xff);
77 &inc( &LB($x)); # NEXT ROUND
78 &mov( $tx, &DWP(0,$d,$x,4)) if $p < 1; # NEXT ROUND
79 &mov( $ty, &DWP(0,$d,$ty,4));
80
81 if (!$char)
82 {
83 #moved up into last round
84 if ($p >= 1)
85 {
86 &add( $out, 8)
87 }
88 &movb( &BP($n,"esp","",0), &LB($ty));
89 }
90 else
91 {
92 # Note in+=8 has occured
93 &movb( &HB($ty), &BP(-1,$in,"",0));
94 # XXX
95 &xorb(&LB($ty), &HB($ty));
96 # XXX
97 &movb(&BP($n,$out,"",0),&LB($ty));
98 }
99 } 61 }
100 62 &$func ($out,&DWP(0,$dat,$ty,4));
101 63}
102sub RC4 64
103 { 65# void RC4(RC4_KEY *key,size_t len,const unsigned char *inp,unsigned char *out);
104 local($name)=@_; 66&function_begin("RC4");
105 67 &mov ($dat,&wparam(0)); # load key schedule pointer
106 &function_begin_B($name,""); 68 &mov ($ty, &wparam(1)); # load len
107 69 &mov ($inp,&wparam(2)); # load inp
108 &mov($ty,&wparam(1)); # len 70 &mov ($out,&wparam(3)); # load out
109 &cmp($ty,0); 71
110 &jne(&label("proceed")); 72 &xor ($xx,$xx); # avoid partial register stalls
111 &ret(); 73 &xor ($yy,$yy);
112 &set_label("proceed"); 74
113 75 &cmp ($ty,0); # safety net
114 &comment(""); 76 &je (&label("abort"));
115 77
116 &push("ebp"); 78 &mov (&LB($xx),&BP(0,$dat)); # load key->x
117 &push("ebx"); 79 &mov (&LB($yy),&BP(4,$dat)); # load key->y
118 &push("esi"); 80 &add ($dat,8);
119 &xor( $x, $x); # avoid partial register stalls 81
120 &push("edi"); 82 &lea ($tx,&DWP(0,$inp,$ty));
121 &xor( $y, $y); # avoid partial register stalls 83 &sub ($out,$inp); # re-bias out
122 &mov( $d, &wparam(0)); # key 84 &mov (&wparam(1),$tx); # save input+len
123 &mov( $in, &wparam(2)); 85
124 86 &inc (&LB($xx));
125 &movb( &LB($x), &BP(0,$d,"",1)); 87
126 &movb( &LB($y), &BP(4,$d,"",1)); 88 # detect compressed key schedule...
127 89 &cmp (&DWP(256,$dat),-1);
128 &mov( $out, &wparam(3)); 90 &je (&label("RC4_CHAR"));
129 &inc( &LB($x)); 91
130 92 &mov ($tx,&DWP(0,$dat,$xx,4));
131 &stack_push(3); # 3 temp variables 93
132 &add( $d, 8); 94 &and ($ty,-4); # how many 4-byte chunks?
133 95 &jz (&label("loop1"));
134 # detect compressed schedule, see commentary section in rc4_skey.c... 96
135 # in 0.9.7 context ~50 bytes below RC4_CHAR label remain redundant, 97 &lea ($ty,&DWP(-4,$inp,$ty));
136 # as compressed key schedule is set up in 0.9.8 and later. 98 &mov (&wparam(2),$ty); # save input+(len/4)*4-4
137 &cmp(&DWP(256,$d),-1); 99 &mov (&wparam(3),$out); # $out as accumulator in this loop
138 &je(&label("RC4_CHAR")); 100
139 101 &set_label("loop4",16);
140 &lea( $ty, &DWP(-8,$ty,$in)); 102 for ($i=0;$i<4;$i++) { RC4_loop($i); }
141 103 &ror ($out,8);
142 # check for 0 length input 104 &xor ($out,&DWP(0,$inp));
143 105 &cmp ($inp,&wparam(2)); # compare to input+(len/4)*4-4
144 &mov( &swtmp(2), $ty); # this is now address to exit at 106 &mov (&DWP(0,$tx,$inp),$out);# $tx holds re-biased out here
145 &mov( $tx, &DWP(0,$d,$x,4)); 107 &lea ($inp,&DWP(4,$inp));
146 108 &mov ($tx,&DWP(0,$dat,$xx,4));
147 &cmp( $ty, $in); 109 &jb (&label("loop4"));
148 &jb( &label("end")); # less than 8 bytes 110
149 111 &cmp ($inp,&wparam(1)); # compare to input+len
150 &set_label("start"); 112 &je (&label("done"));
151 113 &mov ($out,&wparam(3)); # restore $out
152 # filling DELAY SLOT 114
153 &add( $in, 8); 115 &set_label("loop1",16);
154 116 &add (&LB($yy),&LB($tx));
155 &RC4_loop(0,-1,0); 117 &mov ($ty,&DWP(0,$dat,$yy,4));
156 &RC4_loop(1,0,0); 118 &mov (&DWP(0,$dat,$yy,4),$tx);
157 &RC4_loop(2,0,0); 119 &mov (&DWP(0,$dat,$xx,4),$ty);
158 &RC4_loop(3,0,0); 120 &add ($ty,$tx);
159 &RC4_loop(4,0,0); 121 &inc (&LB($xx));
160 &RC4_loop(5,0,0); 122 &and ($ty,0xff);
161 &RC4_loop(6,0,0); 123 &mov ($ty,&DWP(0,$dat,$ty,4));
162 &RC4_loop(7,1,0); 124 &xor (&LB($ty),&BP(0,$inp));
163 125 &lea ($inp,&DWP(1,$inp));
164 &comment("apply the cipher text"); 126 &mov ($tx,&DWP(0,$dat,$xx,4));
165 # xor the cipher data with input 127 &cmp ($inp,&wparam(1)); # compare to input+len
166 128 &mov (&BP(-1,$out,$inp),&LB($ty));
167 #&add( $out, 8); #moved up into last round 129 &jb (&label("loop1"));
168 130
169 &mov( $tx, &swtmp(0)); 131 &jmp (&label("done"));
170 &mov( $ty, &DWP(-8,$in,"",0)); 132
171 &xor( $tx, $ty); 133# this is essentially Intel P4 specific codepath...
172 &mov( $ty, &DWP(-4,$in,"",0)); 134&set_label("RC4_CHAR",16);
173 &mov( &DWP(-8,$out,"",0), $tx); 135 &movz ($tx,&BP(0,$dat,$xx));
174 &mov( $tx, &swtmp(1));
175 &xor( $tx, $ty);
176 &mov( $ty, &swtmp(2)); # load end ptr;
177 &mov( &DWP(-4,$out,"",0), $tx);
178 &mov( $tx, &DWP(0,$d,$x,4));
179 &cmp($in, $ty);
180 &jbe(&label("start"));
181
182 &set_label("end");
183
184 # There is quite a bit of extra crap in RC4_loop() for this
185 # first round
186 &RC4_loop(0,-1,1);
187 &RC4_loop(1,0,1);
188 &RC4_loop(2,0,1);
189 &RC4_loop(3,0,1);
190 &RC4_loop(4,0,1);
191 &RC4_loop(5,0,1);
192 &RC4_loop(6,1,1);
193
194 &jmp(&label("finished"));
195
196 &align(16);
197 # this is essentially Intel P4 specific codepath, see rc4_skey.c,
198 # and is engaged in 0.9.8 and later context...
199 &set_label("RC4_CHAR");
200
201 &lea ($ty,&DWP(0,$in,$ty));
202 &mov (&swtmp(2),$ty);
203 &movz ($tx,&BP(0,$d,$x));
204
205 # strangely enough unrolled loop performs over 20% slower... 136 # strangely enough unrolled loop performs over 20% slower...
206 &set_label("RC4_CHAR_loop"); 137 &set_label("cloop1");
207 &add (&LB($y),&LB($tx)); 138 &add (&LB($yy),&LB($tx));
208 &movz ($ty,&BP(0,$d,$y)); 139 &movz ($ty,&BP(0,$dat,$yy));
209 &movb (&BP(0,$d,$y),&LB($tx)); 140 &mov (&BP(0,$dat,$yy),&LB($tx));
210 &movb (&BP(0,$d,$x),&LB($ty)); 141 &mov (&BP(0,$dat,$xx),&LB($ty));
211 &add (&LB($ty),&LB($tx)); 142 &add (&LB($ty),&LB($tx));
212 &movz ($ty,&BP(0,$d,$ty)); 143 &movz ($ty,&BP(0,$dat,$ty));
213 &add (&LB($x),1); 144 &add (&LB($xx),1);
214 &xorb (&LB($ty),&BP(0,$in)); 145 &xor (&LB($ty),&BP(0,$inp));
215 &lea ($in,&DWP(1,$in)); 146 &lea ($inp,&DWP(1,$inp));
216 &movz ($tx,&BP(0,$d,$x)); 147 &movz ($tx,&BP(0,$dat,$xx));
217 &cmp ($in,&swtmp(2)); 148 &cmp ($inp,&wparam(1));
218 &movb (&BP(0,$out),&LB($ty)); 149 &mov (&BP(-1,$out,$inp),&LB($ty));
219 &lea ($out,&DWP(1,$out)); 150 &jb (&label("cloop1"));
220 &jb (&label("RC4_CHAR_loop")); 151
221 152&set_label("done");
222 &set_label("finished"); 153 &dec (&LB($xx));
223 &dec( $x); 154 &mov (&BP(-4,$dat),&LB($yy)); # save key->y
224 &stack_pop(3); 155 &mov (&BP(-8,$dat),&LB($xx)); # save key->x
225 &movb( &BP(-4,$d,"",0),&LB($y)); 156&set_label("abort");
226 &movb( &BP(-8,$d,"",0),&LB($x)); 157&function_end("RC4");
227 158
228 &function_end($name); 159########################################################################
229 } 160
161$inp="esi";
162$out="edi";
163$idi="ebp";
164$ido="ecx";
165$idx="edx";
166
167&external_label("OPENSSL_ia32cap_P");
168
169# void RC4_set_key(RC4_KEY *key,int len,const unsigned char *data);
170&function_begin("RC4_set_key");
171 &mov ($out,&wparam(0)); # load key
172 &mov ($idi,&wparam(1)); # load len
173 &mov ($inp,&wparam(2)); # load data
174 &picmeup($idx,"OPENSSL_ia32cap_P");
175
176 &lea ($out,&DWP(2*4,$out)); # &key->data
177 &lea ($inp,&DWP(0,$inp,$idi)); # $inp to point at the end
178 &neg ($idi);
179 &xor ("eax","eax");
180 &mov (&DWP(-4,$out),$idi); # borrow key->y
181
182 &bt (&DWP(0,$idx),20); # check for bit#20
183 &jc (&label("c1stloop"));
184
185&set_label("w1stloop",16);
186 &mov (&DWP(0,$out,"eax",4),"eax"); # key->data[i]=i;
187 &add (&LB("eax"),1); # i++;
188 &jnc (&label("w1stloop"));
189
190 &xor ($ido,$ido);
191 &xor ($idx,$idx);
192
193&set_label("w2ndloop",16);
194 &mov ("eax",&DWP(0,$out,$ido,4));
195 &add (&LB($idx),&BP(0,$inp,$idi));
196 &add (&LB($idx),&LB("eax"));
197 &add ($idi,1);
198 &mov ("ebx",&DWP(0,$out,$idx,4));
199 &jnz (&label("wnowrap"));
200 &mov ($idi,&DWP(-4,$out));
201 &set_label("wnowrap");
202 &mov (&DWP(0,$out,$idx,4),"eax");
203 &mov (&DWP(0,$out,$ido,4),"ebx");
204 &add (&LB($ido),1);
205 &jnc (&label("w2ndloop"));
206&jmp (&label("exit"));
207
208# Unlike all other x86 [and x86_64] implementations, Intel P4 core
209# [including EM64T] was found to perform poorly with above "32-bit" key
210# schedule, a.k.a. RC4_INT. Performance improvement for IA-32 hand-coded
211# assembler turned out to be 3.5x if re-coded for compressed 8-bit one,
212# a.k.a. RC4_CHAR! It's however inappropriate to just switch to 8-bit
213# schedule for x86[_64], because non-P4 implementations suffer from
214# significant performance losses then, e.g. PIII exhibits >2x
215# deterioration, and so does Opteron. In order to assure optimal
216# all-round performance, we detect P4 at run-time and set up compressed
217# key schedule, which is recognized by RC4 procedure.
218
219&set_label("c1stloop",16);
220 &mov (&BP(0,$out,"eax"),&LB("eax")); # key->data[i]=i;
221 &add (&LB("eax"),1); # i++;
222 &jnc (&label("c1stloop"));
223
224 &xor ($ido,$ido);
225 &xor ($idx,$idx);
226 &xor ("ebx","ebx");
227
228&set_label("c2ndloop",16);
229 &mov (&LB("eax"),&BP(0,$out,$ido));
230 &add (&LB($idx),&BP(0,$inp,$idi));
231 &add (&LB($idx),&LB("eax"));
232 &add ($idi,1);
233 &mov (&LB("ebx"),&BP(0,$out,$idx));
234 &jnz (&label("cnowrap"));
235 &mov ($idi,&DWP(-4,$out));
236 &set_label("cnowrap");
237 &mov (&BP(0,$out,$idx),&LB("eax"));
238 &mov (&BP(0,$out,$ido),&LB("ebx"));
239 &add (&LB($ido),1);
240 &jnc (&label("c2ndloop"));
241
242 &mov (&DWP(256,$out),-1); # mark schedule as compressed
243
244&set_label("exit");
245 &xor ("eax","eax");
246 &mov (&DWP(-8,$out),"eax"); # key->x=0;
247 &mov (&DWP(-4,$out),"eax"); # key->y=0;
248&function_end("RC4_set_key");
249
250# const char *RC4_options(void);
251&function_begin_B("RC4_options");
252 &call (&label("pic_point"));
253&set_label("pic_point");
254 &blindpop("eax");
255 &lea ("eax",&DWP(&label("opts")."-".&label("pic_point"),"eax"));
256 &picmeup("edx","OPENSSL_ia32cap_P");
257 &bt (&DWP(0,"edx"),20);
258 &jnc (&label("skip"));
259 &add ("eax",12);
260 &set_label("skip");
261 &ret ();
262&set_label("opts",64);
263&asciz ("rc4(4x,int)");
264&asciz ("rc4(1x,char)");
265&asciz ("RC4 for x86, CRYPTOGAMS by <appro\@openssl.org>");
266&align (64);
267&function_end_B("RC4_options");
268
269&asm_finish();
230 270
diff --git a/src/lib/libcrypto/rc4/asm/rc4-ia64.pl b/src/lib/libcrypto/rc4/asm/rc4-ia64.pl
new file mode 100644
index 0000000000..49cd5b5e69
--- /dev/null
+++ b/src/lib/libcrypto/rc4/asm/rc4-ia64.pl
@@ -0,0 +1,755 @@
1#!/usr/bin/env perl
2#
3# ====================================================================
4# Written by David Mosberger <David.Mosberger@acm.org> based on the
5# Itanium optimized Crypto code which was released by HP Labs at
6# http://www.hpl.hp.com/research/linux/crypto/.
7#
8# Copyright (c) 2005 Hewlett-Packard Development Company, L.P.
9#
10# Permission is hereby granted, free of charge, to any person obtaining
11# a copy of this software and associated documentation files (the
12# "Software"), to deal in the Software without restriction, including
13# without limitation the rights to use, copy, modify, merge, publish,
14# distribute, sublicense, and/or sell copies of the Software, and to
15# permit persons to whom the Software is furnished to do so, subject to
16# the following conditions:
17#
18# The above copyright notice and this permission notice shall be
19# included in all copies or substantial portions of the Software.
20
21# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
22# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
24# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
25# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
26# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
27# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
28
29
30
31# This is a little helper program which generates a software-pipelined
32# for RC4 encryption. The basic algorithm looks like this:
33#
34# for (counter = 0; counter < len; ++counter)
35# {
36# in = inp[counter];
37# SI = S[I];
38# J = (SI + J) & 0xff;
39# SJ = S[J];
40# T = (SI + SJ) & 0xff;
41# S[I] = SJ, S[J] = SI;
42# ST = S[T];
43# outp[counter] = in ^ ST;
44# I = (I + 1) & 0xff;
45# }
46#
47# Pipelining this loop isn't easy, because the stores to the S[] array
48# need to be observed in the right order. The loop generated by the
49# code below has the following pipeline diagram:
50#
51# cycle
52# | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |10 |11 |12 |13 |14 |15 |16 |17 |
53# iter
54# 1: xxx LDI xxx xxx xxx LDJ xxx SWP xxx LDT xxx xxx
55# 2: xxx LDI xxx xxx xxx LDJ xxx SWP xxx LDT xxx xxx
56# 3: xxx LDI xxx xxx xxx LDJ xxx SWP xxx LDT xxx xxx
57#
58# where:
59# LDI = load of S[I]
60# LDJ = load of S[J]
61# SWP = swap of S[I] and S[J]
62# LDT = load of S[T]
63#
64# Note that in the above diagram, the major trouble-spot is that LDI
65# of the 2nd iteration is performed BEFORE the SWP of the first
66# iteration. Fortunately, this is easy to detect (I of the 1st
67# iteration will be equal to J of the 2nd iteration) and when this
68# happens, we simply forward the proper value from the 1st iteration
69# to the 2nd one. The proper value in this case is simply the value
70# of S[I] from the first iteration (thanks to the fact that SWP
71# simply swaps the contents of S[I] and S[J]).
72#
73# Another potential trouble-spot is in cycle 7, where SWP of the 1st
74# iteration issues at the same time as the LDI of the 3rd iteration.
75# However, thanks to IA-64 execution semantics, this can be taken
76# care of simply by placing LDI later in the instruction-group than
77# SWP. IA-64 CPUs will automatically forward the value if they
78# detect that the SWP and LDI are accessing the same memory-location.
79
80# The core-loop that can be pipelined then looks like this (annotated
81# with McKinley/Madison issue port & latency numbers, assuming L1
82# cache hits for the most part):
83
84# operation: instruction: issue-ports: latency
85# ------------------ ----------------------------- ------------- -------
86
87# Data = *inp++ ld1 data = [inp], 1 M0-M1 1 cyc c0
88# shladd Iptr = I, KeyTable, 3 M0-M3, I0, I1 1 cyc
89# I = (I + 1) & 0xff padd1 nextI = I, one M0-M3, I0, I1 3 cyc
90# ;;
91# SI = S[I] ld8 SI = [Iptr] M0-M1 1 cyc c1 * after SWAP!
92# ;;
93# cmp.eq.unc pBypass = I, J * after J is valid!
94# J = SI + J add J = J, SI M0-M3, I0, I1 1 cyc c2
95# (pBypass) br.cond.spnt Bypass
96# ;;
97# ---------------------------------------------------------------------------------------
98# J = J & 0xff zxt1 J = J I0, I1, 1 cyc c3
99# ;;
100# shladd Jptr = J, KeyTable, 3 M0-M3, I0, I1 1 cyc c4
101# ;;
102# SJ = S[J] ld8 SJ = [Jptr] M0-M1 1 cyc c5
103# ;;
104# ---------------------------------------------------------------------------------------
105# T = (SI + SJ) add T = SI, SJ M0-M3, I0, I1 1 cyc c6
106# ;;
107# T = T & 0xff zxt1 T = T I0, I1 1 cyc
108# S[I] = SJ st8 [Iptr] = SJ M2-M3 c7
109# S[J] = SI st8 [Jptr] = SI M2-M3
110# ;;
111# shladd Tptr = T, KeyTable, 3 M0-M3, I0, I1 1 cyc c8
112# ;;
113# ---------------------------------------------------------------------------------------
114# T = S[T] ld8 T = [Tptr] M0-M1 1 cyc c9
115# ;;
116# data ^= T xor data = data, T M0-M3, I0, I1 1 cyc c10
117# ;;
118# *out++ = Data ^ T dep word = word, data, 8, POS I0, I1 1 cyc c11
119# ;;
120# ---------------------------------------------------------------------------------------
121
122# There are several points worth making here:
123
124# - Note that due to the bypass/forwarding-path, the first two
125# phases of the loop are strangly mingled together. In
126# particular, note that the first stage of the pipeline is
127# using the value of "J", as calculated by the second stage.
128# - Each bundle-pair will have exactly 6 instructions.
129# - Pipelined, the loop can execute in 3 cycles/iteration and
130# 4 stages. However, McKinley/Madison can issue "st1" to
131# the same bank at a rate of at most one per 4 cycles. Thus,
132# instead of storing each byte, we accumulate them in a word
133# and then write them back at once with a single "st8" (this
134# implies that the setup code needs to ensure that the output
135# buffer is properly aligned, if need be, by encoding the
136# first few bytes separately).
137# - There is no space for a "br.ctop" instruction. For this
138# reason we can't use module-loop support in IA-64 and have
139# to do a traditional, purely software-pipelined loop.
140# - We can't replace any of the remaining "add/zxt1" pairs with
141# "padd1" because the latency for that instruction is too high
142# and would push the loop to the point where more bypasses
143# would be needed, which we don't have space for.
144# - The above loop runs at around 3.26 cycles/byte, or roughly
145# 440 MByte/sec on a 1.5GHz Madison. This is well below the
146# system bus bandwidth and hence with judicious use of
147# "lfetch" this loop can run at (almost) peak speed even when
148# the input and output data reside in memory. The
149# max. latency that can be tolerated is (PREFETCH_DISTANCE *
150# L2_LINE_SIZE * 3 cyc), or about 384 cycles assuming (at
151# least) 1-ahead prefetching of 128 byte cache-lines. Note
152# that we do NOT prefetch into L1, since that would only
153# interfere with the S[] table values stored there. This is
154# acceptable because there is a 10 cycle latency between
155# load and first use of the input data.
156# - We use a branch to out-of-line bypass-code of cycle-pressure:
157# we calculate the next J, check for the need to activate the
158# bypass path, and activate the bypass path ALL IN THE SAME
159# CYCLE. If we didn't have these constraints, we could do
160# the bypass with a simple conditional move instruction.
161# Fortunately, the bypass paths get activated relatively
162# infrequently, so the extra branches don't cost all that much
163# (about 0.04 cycles/byte, measured on a 16396 byte file with
164# random input data).
165#
166
167$phases = 4; # number of stages/phases in the pipelined-loop
168$unroll_count = 6; # number of times we unrolled it
169$pComI = (1 << 0);
170$pComJ = (1 << 1);
171$pComT = (1 << 2);
172$pOut = (1 << 3);
173
174$NData = 4;
175$NIP = 3;
176$NJP = 2;
177$NI = 2;
178$NSI = 3;
179$NSJ = 2;
180$NT = 2;
181$NOutWord = 2;
182
183#
184# $threshold is the minimum length before we attempt to use the
185# big software-pipelined loop. It MUST be greater-or-equal
186# to:
187# PHASES * (UNROLL_COUNT + 1) + 7
188#
189# The "+ 7" comes from the fact we may have to encode up to
190# 7 bytes separately before the output pointer is aligned.
191#
192$threshold = (3 * ($phases * ($unroll_count + 1)) + 7);
193
194sub I {
195 local *code = shift;
196 local $format = shift;
197 $code .= sprintf ("\t\t".$format."\n", @_);
198}
199
200sub P {
201 local *code = shift;
202 local $format = shift;
203 $code .= sprintf ($format."\n", @_);
204}
205
206sub STOP {
207 local *code = shift;
208 $code .=<<___;
209 ;;
210___
211}
212
213sub emit_body {
214 local *c = shift;
215 local *bypass = shift;
216 local ($iteration, $p) = @_;
217
218 local $i0 = $iteration;
219 local $i1 = $iteration - 1;
220 local $i2 = $iteration - 2;
221 local $i3 = $iteration - 3;
222 local $iw0 = ($iteration - 3) / 8;
223 local $iw1 = ($iteration > 3) ? ($iteration - 4) / 8 : 1;
224 local $byte_num = ($iteration - 3) % 8;
225 local $label = $iteration + 1;
226 local $pAny = ($p & 0xf) == 0xf;
227 local $pByp = (($p & $pComI) && ($iteration > 0));
228
229 $c.=<<___;
230//////////////////////////////////////////////////
231___
232
233 if (($p & 0xf) == 0) {
234 $c.="#ifdef HOST_IS_BIG_ENDIAN\n";
235 &I(\$c,"shr.u OutWord[%u] = OutWord[%u], 32;;",
236 $iw1 % $NOutWord, $iw1 % $NOutWord);
237 $c.="#endif\n";
238 &I(\$c, "st4 [OutPtr] = OutWord[%u], 4", $iw1 % $NOutWord);
239 return;
240 }
241
242 # Cycle 0
243 &I(\$c, "{ .mmi") if ($pAny);
244 &I(\$c, "ld1 Data[%u] = [InPtr], 1", $i0 % $NData) if ($p & $pComI);
245 &I(\$c, "padd1 I[%u] = One, I[%u]", $i0 % $NI, $i1 % $NI)if ($p & $pComI);
246 &I(\$c, "zxt1 J = J") if ($p & $pComJ);
247 &I(\$c, "}") if ($pAny);
248 &I(\$c, "{ .mmi") if ($pAny);
249 &I(\$c, "LKEY T[%u] = [T[%u]]", $i1 % $NT, $i1 % $NT) if ($p & $pOut);
250 &I(\$c, "add T[%u] = SI[%u], SJ[%u]",
251 $i0 % $NT, $i2 % $NSI, $i1 % $NSJ) if ($p & $pComT);
252 &I(\$c, "KEYADDR(IPr[%u], I[%u])", $i0 % $NIP, $i1 % $NI) if ($p & $pComI);
253 &I(\$c, "}") if ($pAny);
254 &STOP(\$c);
255
256 # Cycle 1
257 &I(\$c, "{ .mmi") if ($pAny);
258 &I(\$c, "SKEY [IPr[%u]] = SJ[%u]", $i2 % $NIP, $i1%$NSJ)if ($p & $pComT);
259 &I(\$c, "SKEY [JP[%u]] = SI[%u]", $i1 % $NJP, $i2%$NSI) if ($p & $pComT);
260 &I(\$c, "zxt1 T[%u] = T[%u]", $i0 % $NT, $i0 % $NT) if ($p & $pComT);
261 &I(\$c, "}") if ($pAny);
262 &I(\$c, "{ .mmi") if ($pAny);
263 &I(\$c, "LKEY SI[%u] = [IPr[%u]]", $i0 % $NSI, $i0%$NIP)if ($p & $pComI);
264 &I(\$c, "KEYADDR(JP[%u], J)", $i0 % $NJP) if ($p & $pComJ);
265 &I(\$c, "xor Data[%u] = Data[%u], T[%u]",
266 $i3 % $NData, $i3 % $NData, $i1 % $NT) if ($p & $pOut);
267 &I(\$c, "}") if ($pAny);
268 &STOP(\$c);
269
270 # Cycle 2
271 &I(\$c, "{ .mmi") if ($pAny);
272 &I(\$c, "LKEY SJ[%u] = [JP[%u]]", $i0 % $NSJ, $i0%$NJP) if ($p & $pComJ);
273 &I(\$c, "cmp.eq pBypass, p0 = I[%u], J", $i1 % $NI) if ($pByp);
274 &I(\$c, "dep OutWord[%u] = Data[%u], OutWord[%u], BYTE_POS(%u), 8",
275 $iw0%$NOutWord, $i3%$NData, $iw1%$NOutWord, $byte_num) if ($p & $pOut);
276 &I(\$c, "}") if ($pAny);
277 &I(\$c, "{ .mmb") if ($pAny);
278 &I(\$c, "add J = J, SI[%u]", $i0 % $NSI) if ($p & $pComI);
279 &I(\$c, "KEYADDR(T[%u], T[%u])", $i0 % $NT, $i0 % $NT) if ($p & $pComT);
280 &P(\$c, "(pBypass)\tbr.cond.spnt.many .rc4Bypass%u",$label)if ($pByp);
281 &I(\$c, "}") if ($pAny);
282 &STOP(\$c);
283
284 &P(\$c, ".rc4Resume%u:", $label) if ($pByp);
285 if ($byte_num == 0 && $iteration >= $phases) {
286 &I(\$c, "st8 [OutPtr] = OutWord[%u], 8",
287 $iw1 % $NOutWord) if ($p & $pOut);
288 if ($iteration == (1 + $unroll_count) * $phases - 1) {
289 if ($unroll_count == 6) {
290 &I(\$c, "mov OutWord[%u] = OutWord[%u]",
291 $iw1 % $NOutWord, $iw0 % $NOutWord);
292 }
293 &I(\$c, "lfetch.nt1 [InPrefetch], %u",
294 $unroll_count * $phases);
295 &I(\$c, "lfetch.excl.nt1 [OutPrefetch], %u",
296 $unroll_count * $phases);
297 &I(\$c, "br.cloop.sptk.few .rc4Loop");
298 }
299 }
300
301 if ($pByp) {
302 &P(\$bypass, ".rc4Bypass%u:", $label);
303 &I(\$bypass, "sub J = J, SI[%u]", $i0 % $NSI);
304 &I(\$bypass, "nop 0");
305 &I(\$bypass, "nop 0");
306 &I(\$bypass, ";;");
307 &I(\$bypass, "add J = J, SI[%u]", $i1 % $NSI);
308 &I(\$bypass, "mov SI[%u] = SI[%u]", $i0 % $NSI, $i1 % $NSI);
309 &I(\$bypass, "br.sptk.many .rc4Resume%u\n", $label);
310 &I(\$bypass, ";;");
311 }
312}
313
314$code=<<___;
315.ident \"rc4-ia64.s, version 3.0\"
316.ident \"Copyright (c) 2005 Hewlett-Packard Development Company, L.P.\"
317
318#define LCSave r8
319#define PRSave r9
320
321/* Inputs become invalid once rotation begins! */
322
323#define StateTable in0
324#define DataLen in1
325#define InputBuffer in2
326#define OutputBuffer in3
327
328#define KTable r14
329#define J r15
330#define InPtr r16
331#define OutPtr r17
332#define InPrefetch r18
333#define OutPrefetch r19
334#define One r20
335#define LoopCount r21
336#define Remainder r22
337#define IFinal r23
338#define EndPtr r24
339
340#define tmp0 r25
341#define tmp1 r26
342
343#define pBypass p6
344#define pDone p7
345#define pSmall p8
346#define pAligned p9
347#define pUnaligned p10
348
349#define pComputeI pPhase[0]
350#define pComputeJ pPhase[1]
351#define pComputeT pPhase[2]
352#define pOutput pPhase[3]
353
354#define RetVal r8
355#define L_OK p7
356#define L_NOK p8
357
358#define _NINPUTS 4
359#define _NOUTPUT 0
360
361#define _NROTATE 24
362#define _NLOCALS (_NROTATE - _NINPUTS - _NOUTPUT)
363
364#ifndef SZ
365# define SZ 4 // this must be set to sizeof(RC4_INT)
366#endif
367
368#if SZ == 1
369# define LKEY ld1
370# define SKEY st1
371# define KEYADDR(dst, i) add dst = i, KTable
372#elif SZ == 2
373# define LKEY ld2
374# define SKEY st2
375# define KEYADDR(dst, i) shladd dst = i, 1, KTable
376#elif SZ == 4
377# define LKEY ld4
378# define SKEY st4
379# define KEYADDR(dst, i) shladd dst = i, 2, KTable
380#else
381# define LKEY ld8
382# define SKEY st8
383# define KEYADDR(dst, i) shladd dst = i, 3, KTable
384#endif
385
386#if defined(_HPUX_SOURCE) && !defined(_LP64)
387# define ADDP addp4
388#else
389# define ADDP add
390#endif
391
392/* Define a macro for the bit number of the n-th byte: */
393
394#if defined(_HPUX_SOURCE) || defined(B_ENDIAN)
395# define HOST_IS_BIG_ENDIAN
396# define BYTE_POS(n) (56 - (8 * (n)))
397#else
398# define BYTE_POS(n) (8 * (n))
399#endif
400
401/*
402 We must perform the first phase of the pipeline explicitly since
403 we will always load from the stable the first time. The br.cexit
404 will never be taken since regardless of the number of bytes because
405 the epilogue count is 4.
406*/
407/* MODSCHED_RC4 macro was split to _PROLOGUE and _LOOP, because HP-UX
408 assembler failed on original macro with syntax error. <appro> */
409#define MODSCHED_RC4_PROLOGUE \\
410 { \\
411 ld1 Data[0] = [InPtr], 1; \\
412 add IFinal = 1, I[1]; \\
413 KEYADDR(IPr[0], I[1]); \\
414 } ;; \\
415 { \\
416 LKEY SI[0] = [IPr[0]]; \\
417 mov pr.rot = 0x10000; \\
418 mov ar.ec = 4; \\
419 } ;; \\
420 { \\
421 add J = J, SI[0]; \\
422 zxt1 I[0] = IFinal; \\
423 br.cexit.spnt.few .+16; /* never taken */ \\
424 } ;;
425#define MODSCHED_RC4_LOOP(label) \\
426label: \\
427 { .mmi; \\
428 (pComputeI) ld1 Data[0] = [InPtr], 1; \\
429 (pComputeI) add IFinal = 1, I[1]; \\
430 (pComputeJ) zxt1 J = J; \\
431 }{ .mmi; \\
432 (pOutput) LKEY T[1] = [T[1]]; \\
433 (pComputeT) add T[0] = SI[2], SJ[1]; \\
434 (pComputeI) KEYADDR(IPr[0], I[1]); \\
435 } ;; \\
436 { .mmi; \\
437 (pComputeT) SKEY [IPr[2]] = SJ[1]; \\
438 (pComputeT) SKEY [JP[1]] = SI[2]; \\
439 (pComputeT) zxt1 T[0] = T[0]; \\
440 }{ .mmi; \\
441 (pComputeI) LKEY SI[0] = [IPr[0]]; \\
442 (pComputeJ) KEYADDR(JP[0], J); \\
443 (pComputeI) cmp.eq.unc pBypass, p0 = I[1], J; \\
444 } ;; \\
445 { .mmi; \\
446 (pComputeJ) LKEY SJ[0] = [JP[0]]; \\
447 (pOutput) xor Data[3] = Data[3], T[1]; \\
448 nop 0x0; \\
449 }{ .mmi; \\
450 (pComputeT) KEYADDR(T[0], T[0]); \\
451 (pBypass) mov SI[0] = SI[1]; \\
452 (pComputeI) zxt1 I[0] = IFinal; \\
453 } ;; \\
454 { .mmb; \\
455 (pOutput) st1 [OutPtr] = Data[3], 1; \\
456 (pComputeI) add J = J, SI[0]; \\
457 br.ctop.sptk.few label; \\
458 } ;;
459
460 .text
461
462 .align 32
463
464 .type RC4, \@function
465 .global RC4
466
467 .proc RC4
468 .prologue
469
470RC4:
471 {
472 .mmi
473 alloc r2 = ar.pfs, _NINPUTS, _NLOCALS, _NOUTPUT, _NROTATE
474
475 .rotr Data[4], I[2], IPr[3], SI[3], JP[2], SJ[2], T[2], \\
476 OutWord[2]
477 .rotp pPhase[4]
478
479 ADDP InPrefetch = 0, InputBuffer
480 ADDP KTable = 0, StateTable
481 }
482 {
483 .mmi
484 ADDP InPtr = 0, InputBuffer
485 ADDP OutPtr = 0, OutputBuffer
486 mov RetVal = r0
487 }
488 ;;
489 {
490 .mmi
491 lfetch.nt1 [InPrefetch], 0x80
492 ADDP OutPrefetch = 0, OutputBuffer
493 }
494 { // Return 0 if the input length is nonsensical
495 .mib
496 ADDP StateTable = 0, StateTable
497 cmp.ge.unc L_NOK, L_OK = r0, DataLen
498 (L_NOK) br.ret.sptk.few rp
499 }
500 ;;
501 {
502 .mib
503 cmp.eq.or L_NOK, L_OK = r0, InPtr
504 cmp.eq.or L_NOK, L_OK = r0, OutPtr
505 nop 0x0
506 }
507 {
508 .mib
509 cmp.eq.or L_NOK, L_OK = r0, StateTable
510 nop 0x0
511 (L_NOK) br.ret.sptk.few rp
512 }
513 ;;
514 LKEY I[1] = [KTable], SZ
515/* Prefetch the state-table. It contains 256 elements of size SZ */
516
517#if SZ == 1
518 ADDP tmp0 = 1*128, StateTable
519#elif SZ == 2
520 ADDP tmp0 = 3*128, StateTable
521 ADDP tmp1 = 2*128, StateTable
522#elif SZ == 4
523 ADDP tmp0 = 7*128, StateTable
524 ADDP tmp1 = 6*128, StateTable
525#elif SZ == 8
526 ADDP tmp0 = 15*128, StateTable
527 ADDP tmp1 = 14*128, StateTable
528#endif
529 ;;
530#if SZ >= 8
531 lfetch.fault.nt1 [tmp0], -256 // 15
532 lfetch.fault.nt1 [tmp1], -256;;
533 lfetch.fault.nt1 [tmp0], -256 // 13
534 lfetch.fault.nt1 [tmp1], -256;;
535 lfetch.fault.nt1 [tmp0], -256 // 11
536 lfetch.fault.nt1 [tmp1], -256;;
537 lfetch.fault.nt1 [tmp0], -256 // 9
538 lfetch.fault.nt1 [tmp1], -256;;
539#endif
540#if SZ >= 4
541 lfetch.fault.nt1 [tmp0], -256 // 7
542 lfetch.fault.nt1 [tmp1], -256;;
543 lfetch.fault.nt1 [tmp0], -256 // 5
544 lfetch.fault.nt1 [tmp1], -256;;
545#endif
546#if SZ >= 2
547 lfetch.fault.nt1 [tmp0], -256 // 3
548 lfetch.fault.nt1 [tmp1], -256;;
549#endif
550 {
551 .mii
552 lfetch.fault.nt1 [tmp0] // 1
553 add I[1]=1,I[1];;
554 zxt1 I[1]=I[1]
555 }
556 {
557 .mmi
558 lfetch.nt1 [InPrefetch], 0x80
559 lfetch.excl.nt1 [OutPrefetch], 0x80
560 .save pr, PRSave
561 mov PRSave = pr
562 } ;;
563 {
564 .mmi
565 lfetch.excl.nt1 [OutPrefetch], 0x80
566 LKEY J = [KTable], SZ
567 ADDP EndPtr = DataLen, InPtr
568 } ;;
569 {
570 .mmi
571 ADDP EndPtr = -1, EndPtr // Make it point to
572 // last data byte.
573 mov One = 1
574 .save ar.lc, LCSave
575 mov LCSave = ar.lc
576 .body
577 } ;;
578 {
579 .mmb
580 sub Remainder = 0, OutPtr
581 cmp.gtu pSmall, p0 = $threshold, DataLen
582(pSmall) br.cond.dpnt .rc4Remainder // Data too small for
583 // big loop.
584 } ;;
585 {
586 .mmi
587 and Remainder = 0x7, Remainder
588 ;;
589 cmp.eq pAligned, pUnaligned = Remainder, r0
590 nop 0x0
591 } ;;
592 {
593 .mmb
594.pred.rel "mutex",pUnaligned,pAligned
595(pUnaligned) add Remainder = -1, Remainder
596(pAligned) sub Remainder = EndPtr, InPtr
597(pAligned) br.cond.dptk.many .rc4Aligned
598 } ;;
599 {
600 .mmi
601 nop 0x0
602 nop 0x0
603 mov.i ar.lc = Remainder
604 }
605
606/* Do the initial few bytes via the compact, modulo-scheduled loop
607 until the output pointer is 8-byte-aligned. */
608
609 MODSCHED_RC4_PROLOGUE
610 MODSCHED_RC4_LOOP(.RC4AlignLoop)
611
612 {
613 .mib
614 sub Remainder = EndPtr, InPtr
615 zxt1 IFinal = IFinal
616 clrrrb // Clear CFM.rrb.pr so
617 ;; // next "mov pr.rot = N"
618 // does the right thing.
619 }
620 {
621 .mmi
622 mov I[1] = IFinal
623 nop 0x0
624 nop 0x0
625 } ;;
626
627
628.rc4Aligned:
629
630/*
631 Unrolled loop count = (Remainder - ($unroll_count+1)*$phases)/($unroll_count*$phases)
632 */
633
634 {
635 .mlx
636 add LoopCount = 1 - ($unroll_count + 1)*$phases, Remainder
637 movl Remainder = 0xaaaaaaaaaaaaaaab
638 } ;;
639 {
640 .mmi
641 setf.sig f6 = LoopCount // M2, M3 6 cyc
642 setf.sig f7 = Remainder // M2, M3 6 cyc
643 nop 0x0
644 } ;;
645 {
646 .mfb
647 nop 0x0
648 xmpy.hu f6 = f6, f7
649 nop 0x0
650 } ;;
651 {
652 .mmi
653 getf.sig LoopCount = f6;; // M2 5 cyc
654 nop 0x0
655 shr.u LoopCount = LoopCount, 4
656 } ;;
657 {
658 .mmi
659 nop 0x0
660 nop 0x0
661 mov.i ar.lc = LoopCount
662 } ;;
663
664/* Now comes the unrolled loop: */
665
666.rc4Prologue:
667___
668
669$iteration = 0;
670
671# Generate the prologue:
672$predicates = 1;
673for ($i = 0; $i < $phases; ++$i) {
674 &emit_body (\$code, \$bypass, $iteration++, $predicates);
675 $predicates = ($predicates << 1) | 1;
676}
677
678$code.=<<___;
679.rc4Loop:
680___
681
682# Generate the body:
683for ($i = 0; $i < $unroll_count*$phases; ++$i) {
684 &emit_body (\$code, \$bypass, $iteration++, $predicates);
685}
686
687$code.=<<___;
688.rc4Epilogue:
689___
690
691# Generate the epilogue:
692for ($i = 0; $i < $phases; ++$i) {
693 $predicates <<= 1;
694 &emit_body (\$code, \$bypass, $iteration++, $predicates);
695}
696
697$code.=<<___;
698 {
699 .mmi
700 lfetch.nt1 [EndPtr] // fetch line with last byte
701 mov IFinal = I[1]
702 nop 0x0
703 }
704
705.rc4Remainder:
706 {
707 .mmi
708 sub Remainder = EndPtr, InPtr // Calculate
709 // # of bytes
710 // left - 1
711 nop 0x0
712 nop 0x0
713 } ;;
714 {
715 .mib
716 cmp.eq pDone, p0 = -1, Remainder // done already?
717 mov.i ar.lc = Remainder
718(pDone) br.cond.dptk.few .rc4Complete
719 }
720
721/* Do the remaining bytes via the compact, modulo-scheduled loop */
722
723 MODSCHED_RC4_PROLOGUE
724 MODSCHED_RC4_LOOP(.RC4RestLoop)
725
726.rc4Complete:
727 {
728 .mmi
729 add KTable = -SZ, KTable
730 add IFinal = -1, IFinal
731 mov ar.lc = LCSave
732 } ;;
733 {
734 .mii
735 SKEY [KTable] = J,-SZ
736 zxt1 IFinal = IFinal
737 mov pr = PRSave, 0x1FFFF
738 } ;;
739 {
740 .mib
741 SKEY [KTable] = IFinal
742 add RetVal = 1, r0
743 br.ret.sptk.few rp
744 } ;;
745___
746
747# Last but not least, emit the code for the bypass-code of the unrolled loop:
748
749$code.=$bypass;
750
751$code.=<<___;
752 .endp RC4
753___
754
755print $code;
diff --git a/src/lib/libcrypto/rc4/asm/rc4-s390x.pl b/src/lib/libcrypto/rc4/asm/rc4-s390x.pl
new file mode 100644
index 0000000000..96681fa05e
--- /dev/null
+++ b/src/lib/libcrypto/rc4/asm/rc4-s390x.pl
@@ -0,0 +1,205 @@
1#!/usr/bin/env perl
2#
3# ====================================================================
4# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
5# project. The module is, however, dual licensed under OpenSSL and
6# CRYPTOGAMS licenses depending on where you obtain it. For further
7# details see http://www.openssl.org/~appro/cryptogams/.
8# ====================================================================
9#
10# February 2009
11#
12# Performance is 2x of gcc 3.4.6 on z10. Coding "secret" is to
13# "cluster" Address Generation Interlocks, so that one pipeline stall
14# resolves several dependencies.
15
16$rp="%r14";
17$sp="%r15";
18$code=<<___;
19.text
20
21___
22
23# void RC4(RC4_KEY *key,size_t len,const void *inp,void *out)
24{
25$acc="%r0";
26$cnt="%r1";
27$key="%r2";
28$len="%r3";
29$inp="%r4";
30$out="%r5";
31
32@XX=("%r6","%r7");
33@TX=("%r8","%r9");
34$YY="%r10";
35$TY="%r11";
36
37$code.=<<___;
38.globl RC4
39.type RC4,\@function
40.align 64
41RC4:
42 stmg %r6,%r11,48($sp)
43 llgc $XX[0],0($key)
44 llgc $YY,1($key)
45 la $XX[0],1($XX[0])
46 nill $XX[0],0xff
47 srlg $cnt,$len,3
48 ltgr $cnt,$cnt
49 llgc $TX[0],2($XX[0],$key)
50 jz .Lshort
51 j .Loop8
52
53.align 64
54.Loop8:
55___
56for ($i=0;$i<8;$i++) {
57$code.=<<___;
58 la $YY,0($YY,$TX[0]) # $i
59 nill $YY,255
60 la $XX[1],1($XX[0])
61 nill $XX[1],255
62___
63$code.=<<___ if ($i==1);
64 llgc $acc,2($TY,$key)
65___
66$code.=<<___ if ($i>1);
67 sllg $acc,$acc,8
68 ic $acc,2($TY,$key)
69___
70$code.=<<___;
71 llgc $TY,2($YY,$key)
72 stc $TX[0],2($YY,$key)
73 llgc $TX[1],2($XX[1],$key)
74 stc $TY,2($XX[0],$key)
75 cr $XX[1],$YY
76 jne .Lcmov$i
77 la $TX[1],0($TX[0])
78.Lcmov$i:
79 la $TY,0($TY,$TX[0])
80 nill $TY,255
81___
82push(@TX,shift(@TX)); push(@XX,shift(@XX)); # "rotate" registers
83}
84
85$code.=<<___;
86 lg $TX[1],0($inp)
87 sllg $acc,$acc,8
88 la $inp,8($inp)
89 ic $acc,2($TY,$key)
90 xgr $acc,$TX[1]
91 stg $acc,0($out)
92 la $out,8($out)
93 brct $cnt,.Loop8
94
95.Lshort:
96 lghi $acc,7
97 ngr $len,$acc
98 jz .Lexit
99 j .Loop1
100
101.align 16
102.Loop1:
103 la $YY,0($YY,$TX[0])
104 nill $YY,255
105 llgc $TY,2($YY,$key)
106 stc $TX[0],2($YY,$key)
107 stc $TY,2($XX[0],$key)
108 ar $TY,$TX[0]
109 ahi $XX[0],1
110 nill $TY,255
111 nill $XX[0],255
112 llgc $acc,0($inp)
113 la $inp,1($inp)
114 llgc $TY,2($TY,$key)
115 llgc $TX[0],2($XX[0],$key)
116 xr $acc,$TY
117 stc $acc,0($out)
118 la $out,1($out)
119 brct $len,.Loop1
120
121.Lexit:
122 ahi $XX[0],-1
123 stc $XX[0],0($key)
124 stc $YY,1($key)
125 lmg %r6,%r11,48($sp)
126 br $rp
127.size RC4,.-RC4
128.string "RC4 for s390x, CRYPTOGAMS by <appro\@openssl.org>"
129
130___
131}
132
133# void RC4_set_key(RC4_KEY *key,unsigned int len,const void *inp)
134{
135$cnt="%r0";
136$idx="%r1";
137$key="%r2";
138$len="%r3";
139$inp="%r4";
140$acc="%r5";
141$dat="%r6";
142$ikey="%r7";
143$iinp="%r8";
144
145$code.=<<___;
146.globl RC4_set_key
147.type RC4_set_key,\@function
148.align 64
149RC4_set_key:
150 stmg %r6,%r8,48($sp)
151 lhi $cnt,256
152 la $idx,0(%r0)
153 sth $idx,0($key)
154.align 4
155.L1stloop:
156 stc $idx,2($idx,$key)
157 la $idx,1($idx)
158 brct $cnt,.L1stloop
159
160 lghi $ikey,-256
161 lr $cnt,$len
162 la $iinp,0(%r0)
163 la $idx,0(%r0)
164.align 16
165.L2ndloop:
166 llgc $acc,2+256($ikey,$key)
167 llgc $dat,0($iinp,$inp)
168 la $idx,0($idx,$acc)
169 la $ikey,1($ikey)
170 la $idx,0($idx,$dat)
171 nill $idx,255
172 la $iinp,1($iinp)
173 tml $ikey,255
174 llgc $dat,2($idx,$key)
175 stc $dat,2+256-1($ikey,$key)
176 stc $acc,2($idx,$key)
177 jz .Ldone
178 brct $cnt,.L2ndloop
179 lr $cnt,$len
180 la $iinp,0(%r0)
181 j .L2ndloop
182.Ldone:
183 lmg %r6,%r8,48($sp)
184 br $rp
185.size RC4_set_key,.-RC4_set_key
186
187___
188}
189
190# const char *RC4_options()
191$code.=<<___;
192.globl RC4_options
193.type RC4_options,\@function
194.align 16
195RC4_options:
196 larl %r2,.Loptions
197 br %r14
198.size RC4_options,.-RC4_options
199.section .rodata
200.Loptions:
201.align 8
202.string "rc4(8x,char)"
203___
204
205print $code;
diff --git a/src/lib/libcrypto/rc4/asm/rc4-x86_64.pl b/src/lib/libcrypto/rc4/asm/rc4-x86_64.pl
index 00c6fa28aa..677be5fe25 100755
--- a/src/lib/libcrypto/rc4/asm/rc4-x86_64.pl
+++ b/src/lib/libcrypto/rc4/asm/rc4-x86_64.pl
@@ -58,14 +58,18 @@
58# fit for Core2 and therefore the code was modified to skip cloop8 on 58# fit for Core2 and therefore the code was modified to skip cloop8 on
59# this CPU. 59# this CPU.
60 60
61$output=shift; 61$flavour = shift;
62$output = shift;
63if ($flavour =~ /\./) { $output = $flavour; undef $flavour; }
64
65$win64=0; $win64=1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/);
62 66
63$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; 67$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
64( $xlate="${dir}x86_64-xlate.pl" and -f $xlate ) or 68( $xlate="${dir}x86_64-xlate.pl" and -f $xlate ) or
65( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or 69( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or
66die "can't locate x86_64-xlate.pl"; 70die "can't locate x86_64-xlate.pl";
67 71
68open STDOUT,"| $^X $xlate $output"; 72open STDOUT,"| $^X $xlate $flavour $output";
69 73
70$dat="%rdi"; # arg1 74$dat="%rdi"; # arg1
71$len="%rsi"; # arg2 75$len="%rsi"; # arg2
@@ -87,8 +91,10 @@ RC4: or $len,$len
87 jne .Lentry 91 jne .Lentry
88 ret 92 ret
89.Lentry: 93.Lentry:
94 push %rbx
90 push %r12 95 push %r12
91 push %r13 96 push %r13
97.Lprologue:
92 98
93 add \$8,$dat 99 add \$8,$dat
94 movl -8($dat),$XX[0]#d 100 movl -8($dat),$XX[0]#d
@@ -133,16 +139,8 @@ $code.=<<___;
133 jnz .Lloop8 139 jnz .Lloop8
134 cmp \$0,$len 140 cmp \$0,$len
135 jne .Lloop1 141 jne .Lloop1
136___ 142 jmp .Lexit
137$code.=<<___;
138.Lexit:
139 sub \$1,$XX[0]#b
140 movl $XX[0]#d,-8($dat)
141 movl $YY#d,-4($dat)
142 143
143 pop %r13
144 pop %r12
145 ret
146.align 16 144.align 16
147.Lloop1: 145.Lloop1:
148 add $TX[0]#b,$YY#b 146 add $TX[0]#b,$YY#b
@@ -167,9 +165,8 @@ $code.=<<___;
167 movzb ($dat,$XX[0]),$TX[0]#d 165 movzb ($dat,$XX[0]),$TX[0]#d
168 test \$-8,$len 166 test \$-8,$len
169 jz .Lcloop1 167 jz .Lcloop1
170 cmp \$0,260($dat) 168 cmpl \$0,260($dat)
171 jnz .Lcloop1 169 jnz .Lcloop1
172 push %rbx
173 jmp .Lcloop8 170 jmp .Lcloop8
174.align 16 171.align 16
175.Lcloop8: 172.Lcloop8:
@@ -224,7 +221,6 @@ $code.=<<___;
224 221
225 test \$-8,$len 222 test \$-8,$len
226 jnz .Lcloop8 223 jnz .Lcloop8
227 pop %rbx
228 cmp \$0,$len 224 cmp \$0,$len
229 jne .Lcloop1 225 jne .Lcloop1
230 jmp .Lexit 226 jmp .Lexit
@@ -249,6 +245,19 @@ $code.=<<___;
249 sub \$1,$len 245 sub \$1,$len
250 jnz .Lcloop1 246 jnz .Lcloop1
251 jmp .Lexit 247 jmp .Lexit
248
249.align 16
250.Lexit:
251 sub \$1,$XX[0]#b
252 movl $XX[0]#d,-8($dat)
253 movl $YY#d,-4($dat)
254
255 mov (%rsp),%r13
256 mov 8(%rsp),%r12
257 mov 16(%rsp),%rbx
258 add \$24,%rsp
259.Lepilogue:
260 ret
252.size RC4,.-RC4 261.size RC4,.-RC4
253___ 262___
254 263
@@ -333,11 +342,10 @@ RC4_set_key:
333.size RC4_set_key,.-RC4_set_key 342.size RC4_set_key,.-RC4_set_key
334 343
335.globl RC4_options 344.globl RC4_options
336.type RC4_options,\@function,0 345.type RC4_options,\@abi-omnipotent
337.align 16 346.align 16
338RC4_options: 347RC4_options:
339 .picmeup %rax 348 lea .Lopts(%rip),%rax
340 lea .Lopts-.(%rax),%rax
341 mov OPENSSL_ia32cap_P(%rip),%edx 349 mov OPENSSL_ia32cap_P(%rip),%edx
342 bt \$20,%edx 350 bt \$20,%edx
343 jnc .Ldone 351 jnc .Ldone
@@ -357,9 +365,139 @@ RC4_options:
357.size RC4_options,.-RC4_options 365.size RC4_options,.-RC4_options
358___ 366___
359 367
360$code =~ s/#([bwd])/$1/gm; 368# EXCEPTION_DISPOSITION handler (EXCEPTION_RECORD *rec,ULONG64 frame,
369# CONTEXT *context,DISPATCHER_CONTEXT *disp)
370if ($win64) {
371$rec="%rcx";
372$frame="%rdx";
373$context="%r8";
374$disp="%r9";
375
376$code.=<<___;
377.extern __imp_RtlVirtualUnwind
378.type stream_se_handler,\@abi-omnipotent
379.align 16
380stream_se_handler:
381 push %rsi
382 push %rdi
383 push %rbx
384 push %rbp
385 push %r12
386 push %r13
387 push %r14
388 push %r15
389 pushfq
390 sub \$64,%rsp
361 391
362$code =~ s/RC4_set_key/private_RC4_set_key/g if ($ENV{FIPSCANLIB} ne ""); 392 mov 120($context),%rax # pull context->Rax
393 mov 248($context),%rbx # pull context->Rip
394
395 lea .Lprologue(%rip),%r10
396 cmp %r10,%rbx # context->Rip<prologue label
397 jb .Lin_prologue
398
399 mov 152($context),%rax # pull context->Rsp
400
401 lea .Lepilogue(%rip),%r10
402 cmp %r10,%rbx # context->Rip>=epilogue label
403 jae .Lin_prologue
404
405 lea 24(%rax),%rax
406
407 mov -8(%rax),%rbx
408 mov -16(%rax),%r12
409 mov -24(%rax),%r13
410 mov %rbx,144($context) # restore context->Rbx
411 mov %r12,216($context) # restore context->R12
412 mov %r13,224($context) # restore context->R13
413
414.Lin_prologue:
415 mov 8(%rax),%rdi
416 mov 16(%rax),%rsi
417 mov %rax,152($context) # restore context->Rsp
418 mov %rsi,168($context) # restore context->Rsi
419 mov %rdi,176($context) # restore context->Rdi
420
421 jmp .Lcommon_seh_exit
422.size stream_se_handler,.-stream_se_handler
423
424.type key_se_handler,\@abi-omnipotent
425.align 16
426key_se_handler:
427 push %rsi
428 push %rdi
429 push %rbx
430 push %rbp
431 push %r12
432 push %r13
433 push %r14
434 push %r15
435 pushfq
436 sub \$64,%rsp
437
438 mov 152($context),%rax # pull context->Rsp
439 mov 8(%rax),%rdi
440 mov 16(%rax),%rsi
441 mov %rsi,168($context) # restore context->Rsi
442 mov %rdi,176($context) # restore context->Rdi
443
444.Lcommon_seh_exit:
445
446 mov 40($disp),%rdi # disp->ContextRecord
447 mov $context,%rsi # context
448 mov \$154,%ecx # sizeof(CONTEXT)
449 .long 0xa548f3fc # cld; rep movsq
450
451 mov $disp,%rsi
452 xor %rcx,%rcx # arg1, UNW_FLAG_NHANDLER
453 mov 8(%rsi),%rdx # arg2, disp->ImageBase
454 mov 0(%rsi),%r8 # arg3, disp->ControlPc
455 mov 16(%rsi),%r9 # arg4, disp->FunctionEntry
456 mov 40(%rsi),%r10 # disp->ContextRecord
457 lea 56(%rsi),%r11 # &disp->HandlerData
458 lea 24(%rsi),%r12 # &disp->EstablisherFrame
459 mov %r10,32(%rsp) # arg5
460 mov %r11,40(%rsp) # arg6
461 mov %r12,48(%rsp) # arg7
462 mov %rcx,56(%rsp) # arg8, (NULL)
463 call *__imp_RtlVirtualUnwind(%rip)
464
465 mov \$1,%eax # ExceptionContinueSearch
466 add \$64,%rsp
467 popfq
468 pop %r15
469 pop %r14
470 pop %r13
471 pop %r12
472 pop %rbp
473 pop %rbx
474 pop %rdi
475 pop %rsi
476 ret
477.size key_se_handler,.-key_se_handler
478
479.section .pdata
480.align 4
481 .rva .LSEH_begin_RC4
482 .rva .LSEH_end_RC4
483 .rva .LSEH_info_RC4
484
485 .rva .LSEH_begin_RC4_set_key
486 .rva .LSEH_end_RC4_set_key
487 .rva .LSEH_info_RC4_set_key
488
489.section .xdata
490.align 8
491.LSEH_info_RC4:
492 .byte 9,0,0,0
493 .rva stream_se_handler
494.LSEH_info_RC4_set_key:
495 .byte 9,0,0,0
496 .rva key_se_handler
497___
498}
499
500$code =~ s/#([bwd])/$1/gm;
363 501
364print $code; 502print $code;
365 503
diff --git a/src/lib/libcrypto/rc4/rc4.h b/src/lib/libcrypto/rc4/rc4.h
index 2d8620d33b..29d1acccf5 100644
--- a/src/lib/libcrypto/rc4/rc4.h
+++ b/src/lib/libcrypto/rc4/rc4.h
@@ -64,6 +64,8 @@
64#error RC4 is disabled. 64#error RC4 is disabled.
65#endif 65#endif
66 66
67#include <stddef.h>
68
67#ifdef __cplusplus 69#ifdef __cplusplus
68extern "C" { 70extern "C" {
69#endif 71#endif
@@ -76,11 +78,8 @@ typedef struct rc4_key_st
76 78
77 79
78const char *RC4_options(void); 80const char *RC4_options(void);
79#ifdef OPENSSL_FIPS
80void private_RC4_set_key(RC4_KEY *key, int len, const unsigned char *data);
81#endif
82void RC4_set_key(RC4_KEY *key, int len, const unsigned char *data); 81void RC4_set_key(RC4_KEY *key, int len, const unsigned char *data);
83void RC4(RC4_KEY *key, unsigned long len, const unsigned char *indata, 82void RC4(RC4_KEY *key, size_t len, const unsigned char *indata,
84 unsigned char *outdata); 83 unsigned char *outdata);
85 84
86#ifdef __cplusplus 85#ifdef __cplusplus
diff --git a/src/lib/libcrypto/rc4/rc4_enc.c b/src/lib/libcrypto/rc4/rc4_enc.c
index 0660ea60a2..8c4fc6c7a3 100644
--- a/src/lib/libcrypto/rc4/rc4_enc.c
+++ b/src/lib/libcrypto/rc4/rc4_enc.c
@@ -67,12 +67,12 @@
67 * Date: Wed, 14 Sep 1994 06:35:31 GMT 67 * Date: Wed, 14 Sep 1994 06:35:31 GMT
68 */ 68 */
69 69
70void RC4(RC4_KEY *key, unsigned long len, const unsigned char *indata, 70void RC4(RC4_KEY *key, size_t len, const unsigned char *indata,
71 unsigned char *outdata) 71 unsigned char *outdata)
72 { 72 {
73 register RC4_INT *d; 73 register RC4_INT *d;
74 register RC4_INT x,y,tx,ty; 74 register RC4_INT x,y,tx,ty;
75 int i; 75 size_t i;
76 76
77 x=key->x; 77 x=key->x;
78 y=key->y; 78 y=key->y;
@@ -120,8 +120,8 @@ void RC4(RC4_KEY *key, unsigned long len, const unsigned char *indata,
120 (RC4_CHUNK)d[(tx+ty)&0xff]\ 120 (RC4_CHUNK)d[(tx+ty)&0xff]\
121 ) 121 )
122 122
123 if ( ( ((unsigned long)indata & (sizeof(RC4_CHUNK)-1)) | 123 if ( ( ((size_t)indata & (sizeof(RC4_CHUNK)-1)) |
124 ((unsigned long)outdata & (sizeof(RC4_CHUNK)-1)) ) == 0 ) 124 ((size_t)outdata & (sizeof(RC4_CHUNK)-1)) ) == 0 )
125 { 125 {
126 RC4_CHUNK ichunk,otp; 126 RC4_CHUNK ichunk,otp;
127 const union { long one; char little; } is_endian = {1}; 127 const union { long one; char little; } is_endian = {1};
@@ -157,7 +157,7 @@ void RC4(RC4_KEY *key, unsigned long len, const unsigned char *indata,
157 if (!is_endian.little) 157 if (!is_endian.little)
158 { /* BIG-ENDIAN CASE */ 158 { /* BIG-ENDIAN CASE */
159# define BESHFT(c) (((sizeof(RC4_CHUNK)-(c)-1)*8)&(sizeof(RC4_CHUNK)*8-1)) 159# define BESHFT(c) (((sizeof(RC4_CHUNK)-(c)-1)*8)&(sizeof(RC4_CHUNK)*8-1))
160 for (;len&~(sizeof(RC4_CHUNK)-1);len-=sizeof(RC4_CHUNK)) 160 for (;len&(0-sizeof(RC4_CHUNK));len-=sizeof(RC4_CHUNK))
161 { 161 {
162 ichunk = *(RC4_CHUNK *)indata; 162 ichunk = *(RC4_CHUNK *)indata;
163 otp = RC4_STEP<<BESHFT(0); 163 otp = RC4_STEP<<BESHFT(0);
@@ -210,7 +210,7 @@ void RC4(RC4_KEY *key, unsigned long len, const unsigned char *indata,
210 else 210 else
211 { /* LITTLE-ENDIAN CASE */ 211 { /* LITTLE-ENDIAN CASE */
212# define LESHFT(c) (((c)*8)&(sizeof(RC4_CHUNK)*8-1)) 212# define LESHFT(c) (((c)*8)&(sizeof(RC4_CHUNK)*8-1))
213 for (;len&~(sizeof(RC4_CHUNK)-1);len-=sizeof(RC4_CHUNK)) 213 for (;len&(0-sizeof(RC4_CHUNK));len-=sizeof(RC4_CHUNK))
214 { 214 {
215 ichunk = *(RC4_CHUNK *)indata; 215 ichunk = *(RC4_CHUNK *)indata;
216 otp = RC4_STEP; 216 otp = RC4_STEP;
@@ -276,7 +276,7 @@ void RC4(RC4_KEY *key, unsigned long len, const unsigned char *indata,
276#define RC4_LOOP(a,b,i) LOOP(a[i],b[i]) 276#define RC4_LOOP(a,b,i) LOOP(a[i],b[i])
277#endif 277#endif
278 278
279 i=(int)(len>>3L); 279 i=len>>3;
280 if (i) 280 if (i)
281 { 281 {
282 for (;;) 282 for (;;)
@@ -296,7 +296,7 @@ void RC4(RC4_KEY *key, unsigned long len, const unsigned char *indata,
296 if (--i == 0) break; 296 if (--i == 0) break;
297 } 297 }
298 } 298 }
299 i=(int)len&0x07; 299 i=len&0x07;
300 if (i) 300 if (i)
301 { 301 {
302 for (;;) 302 for (;;)
diff --git a/src/lib/libcrypto/rc4/rc4_skey.c b/src/lib/libcrypto/rc4/rc4_skey.c
index 4478d1a4b3..b22c40b0bd 100644
--- a/src/lib/libcrypto/rc4/rc4_skey.c
+++ b/src/lib/libcrypto/rc4/rc4_skey.c
@@ -59,11 +59,6 @@
59#include <openssl/rc4.h> 59#include <openssl/rc4.h>
60#include "rc4_locl.h" 60#include "rc4_locl.h"
61#include <openssl/opensslv.h> 61#include <openssl/opensslv.h>
62#include <openssl/crypto.h>
63#ifdef OPENSSL_FIPS
64#include <openssl/fips.h>
65#endif
66
67 62
68const char RC4_version[]="RC4" OPENSSL_VERSION_PTEXT; 63const char RC4_version[]="RC4" OPENSSL_VERSION_PTEXT;
69 64
@@ -90,11 +85,7 @@ const char *RC4_options(void)
90 * Date: Wed, 14 Sep 1994 06:35:31 GMT 85 * Date: Wed, 14 Sep 1994 06:35:31 GMT
91 */ 86 */
92 87
93#ifdef OPENSSL_FIPS
94void private_RC4_set_key(RC4_KEY *key, int len, const unsigned char *data)
95#else
96void RC4_set_key(RC4_KEY *key, int len, const unsigned char *data) 88void RC4_set_key(RC4_KEY *key, int len, const unsigned char *data)
97#endif
98 { 89 {
99 register RC4_INT tmp; 90 register RC4_INT tmp;
100 register int id1,id2; 91 register int id1,id2;
@@ -128,20 +119,14 @@ void RC4_set_key(RC4_KEY *key, int len, const unsigned char *data)
128 * implementations suffer from significant performance 119 * implementations suffer from significant performance
129 * losses then, e.g. PIII exhibits >2x deterioration, 120 * losses then, e.g. PIII exhibits >2x deterioration,
130 * and so does Opteron. In order to assure optimal 121 * and so does Opteron. In order to assure optimal
131 * all-round performance, we detect P4 at run-time by 122 * all-round performance, let us [try to] detect P4 at
132 * checking upon reserved bit 20 in CPU capability 123 * run-time by checking upon HTT bit in CPU capability
133 * vector and set up compressed key schedule, which is 124 * vector and set up compressed key schedule, which is
134 * recognized by correspondingly updated assembler 125 * recognized by correspondingly updated assembler
135 * module... Bit 20 is set up by OPENSSL_ia32_cpuid. 126 * module...
136 *
137 * <appro@fy.chalmers.se> 127 * <appro@fy.chalmers.se>
138 */ 128 */
139#ifdef OPENSSL_FIPS
140 unsigned long *ia32cap_ptr = OPENSSL_ia32cap_loc();
141 if (ia32cap_ptr && (*ia32cap_ptr & (1<<28))) {
142#else
143 if (OPENSSL_ia32cap_P & (1<<28)) { 129 if (OPENSSL_ia32cap_P & (1<<28)) {
144#endif
145 unsigned char *cp=(unsigned char *)d; 130 unsigned char *cp=(unsigned char *)d;
146 131
147 for (i=0;i<256;i++) cp[i]=i; 132 for (i=0;i<256;i++) cp[i]=i;
diff --git a/src/lib/libcrypto/ripemd/asm/rmd-586.pl b/src/lib/libcrypto/ripemd/asm/rmd-586.pl
index 4f3c4c967f..e8b2bc2db2 100644
--- a/src/lib/libcrypto/ripemd/asm/rmd-586.pl
+++ b/src/lib/libcrypto/ripemd/asm/rmd-586.pl
@@ -5,7 +5,8 @@
5 5
6$normal=0; 6$normal=0;
7 7
8push(@INC,"perlasm","../../perlasm"); 8$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
9push(@INC,"${dir}","${dir}../../perlasm");
9require "x86asm.pl"; 10require "x86asm.pl";
10 11
11&asm_init($ARGV[0],$0); 12&asm_init($ARGV[0],$0);
diff --git a/src/lib/libcrypto/ripemd/ripemd.h b/src/lib/libcrypto/ripemd/ripemd.h
index 3b6d04386d..5942eb6180 100644
--- a/src/lib/libcrypto/ripemd/ripemd.h
+++ b/src/lib/libcrypto/ripemd/ripemd.h
@@ -70,7 +70,7 @@ extern "C" {
70#error RIPEMD is disabled. 70#error RIPEMD is disabled.
71#endif 71#endif
72 72
73#if defined(OPENSSL_SYS_WIN16) || defined(__LP32__) 73#if defined(__LP32__)
74#define RIPEMD160_LONG unsigned long 74#define RIPEMD160_LONG unsigned long
75#elif defined(OPENSSL_SYS_CRAY) || defined(__ILP64__) 75#elif defined(OPENSSL_SYS_CRAY) || defined(__ILP64__)
76#define RIPEMD160_LONG unsigned long 76#define RIPEMD160_LONG unsigned long
@@ -90,9 +90,7 @@ typedef struct RIPEMD160state_st
90 RIPEMD160_LONG data[RIPEMD160_LBLOCK]; 90 RIPEMD160_LONG data[RIPEMD160_LBLOCK];
91 unsigned int num; 91 unsigned int num;
92 } RIPEMD160_CTX; 92 } RIPEMD160_CTX;
93#ifdef OPENSSL_FIPS 93
94int private_RIPEMD160_Init(RIPEMD160_CTX *c);
95#endif
96int RIPEMD160_Init(RIPEMD160_CTX *c); 94int RIPEMD160_Init(RIPEMD160_CTX *c);
97int RIPEMD160_Update(RIPEMD160_CTX *c, const void *data, size_t len); 95int RIPEMD160_Update(RIPEMD160_CTX *c, const void *data, size_t len);
98int RIPEMD160_Final(unsigned char *md, RIPEMD160_CTX *c); 96int 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 ead11d075a..59b017f8c0 100644
--- a/src/lib/libcrypto/ripemd/rmd_dgst.c
+++ b/src/lib/libcrypto/ripemd/rmd_dgst.c
@@ -59,11 +59,6 @@
59#include <stdio.h> 59#include <stdio.h>
60#include "rmd_locl.h" 60#include "rmd_locl.h"
61#include <openssl/opensslv.h> 61#include <openssl/opensslv.h>
62#include <openssl/err.h>
63#ifdef OPENSSL_FIPS
64#include <openssl/fips.h>
65#endif
66
67 62
68const char RMD160_version[]="RIPE-MD160" OPENSSL_VERSION_PTEXT; 63const char RMD160_version[]="RIPE-MD160" OPENSSL_VERSION_PTEXT;
69 64
@@ -74,16 +69,14 @@ const char RMD160_version[]="RIPE-MD160" OPENSSL_VERSION_PTEXT;
74 void ripemd160_block(RIPEMD160_CTX *c, unsigned long *p,size_t num); 69 void ripemd160_block(RIPEMD160_CTX *c, unsigned long *p,size_t num);
75# endif 70# endif
76 71
77FIPS_NON_FIPS_MD_Init(RIPEMD160) 72int RIPEMD160_Init(RIPEMD160_CTX *c)
78 { 73 {
74 memset (c,0,sizeof(*c));
79 c->A=RIPEMD160_A; 75 c->A=RIPEMD160_A;
80 c->B=RIPEMD160_B; 76 c->B=RIPEMD160_B;
81 c->C=RIPEMD160_C; 77 c->C=RIPEMD160_C;
82 c->D=RIPEMD160_D; 78 c->D=RIPEMD160_D;
83 c->E=RIPEMD160_E; 79 c->E=RIPEMD160_E;
84 c->Nl=0;
85 c->Nh=0;
86 c->num=0;
87 return 1; 80 return 1;
88 } 81 }
89 82
diff --git a/src/lib/libcrypto/ripemd/rmd_locl.h b/src/lib/libcrypto/ripemd/rmd_locl.h
index ce12a8000e..f14b346e66 100644
--- a/src/lib/libcrypto/ripemd/rmd_locl.h
+++ b/src/lib/libcrypto/ripemd/rmd_locl.h
@@ -72,7 +72,7 @@
72 */ 72 */
73#ifdef RMD160_ASM 73#ifdef RMD160_ASM
74# if defined(__i386) || defined(__i386__) || defined(_M_IX86) || defined(__INTEL__) 74# if defined(__i386) || defined(__i386__) || defined(_M_IX86) || defined(__INTEL__)
75# define ripemd160_block_host_order ripemd160_block_asm_data_order 75# define ripemd160_block_data_order ripemd160_block_asm_data_order
76# endif 76# endif
77#endif 77#endif
78 78
diff --git a/src/lib/libcrypto/rsa/rsa.h b/src/lib/libcrypto/rsa/rsa.h
index 5bb932ae15..cf74343657 100644
--- a/src/lib/libcrypto/rsa/rsa.h
+++ b/src/lib/libcrypto/rsa/rsa.h
@@ -74,25 +74,6 @@
74#error RSA is disabled. 74#error RSA is disabled.
75#endif 75#endif
76 76
77/* If this flag is set the RSA method is FIPS compliant and can be used
78 * in FIPS mode. This is set in the validated module method. If an
79 * application sets this flag in its own methods it is its reposibility
80 * to ensure the result is compliant.
81 */
82
83#define RSA_FLAG_FIPS_METHOD 0x0400
84
85/* If this flag is set the operations normally disabled in FIPS mode are
86 * permitted it is then the applications responsibility to ensure that the
87 * usage is compliant.
88 */
89
90#define RSA_FLAG_NON_FIPS_ALLOW 0x0400
91
92#ifdef OPENSSL_FIPS
93#define FIPS_RSA_SIZE_T int
94#endif
95
96#ifdef __cplusplus 77#ifdef __cplusplus
97extern "C" { 78extern "C" {
98#endif 79#endif
@@ -136,7 +117,8 @@ struct rsa_meth_st
136 unsigned char *sigret, unsigned int *siglen, const RSA *rsa); 117 unsigned char *sigret, unsigned int *siglen, const RSA *rsa);
137 int (*rsa_verify)(int dtype, 118 int (*rsa_verify)(int dtype,
138 const unsigned char *m, unsigned int m_length, 119 const unsigned char *m, unsigned int m_length,
139 unsigned char *sigbuf, unsigned int siglen, const RSA *rsa); 120 const unsigned char *sigbuf, unsigned int siglen,
121 const RSA *rsa);
140/* If this callback is NULL, the builtin software RSA key-gen will be used. This 122/* If this callback is NULL, the builtin software RSA key-gen will be used. This
141 * is for behavioural compatibility whilst the code gets rewired, but one day 123 * is for behavioural compatibility whilst the code gets rewired, but one day
142 * it would be nice to assume there are no such things as "builtin software" 124 * it would be nice to assume there are no such things as "builtin software"
@@ -182,8 +164,6 @@ struct rsa_st
182# define OPENSSL_RSA_MAX_MODULUS_BITS 16384 164# define OPENSSL_RSA_MAX_MODULUS_BITS 16384
183#endif 165#endif
184 166
185#define OPENSSL_RSA_FIPS_MIN_MODULUS_BITS 1024
186
187#ifndef OPENSSL_RSA_SMALL_MODULUS_BITS 167#ifndef OPENSSL_RSA_SMALL_MODULUS_BITS
188# define OPENSSL_RSA_SMALL_MODULUS_BITS 3072 168# define OPENSSL_RSA_SMALL_MODULUS_BITS 3072
189#endif 169#endif
@@ -238,11 +218,37 @@ struct rsa_st
238#endif 218#endif
239 219
240 220
221#define EVP_PKEY_CTX_set_rsa_padding(ctx, pad) \
222 EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, -1, EVP_PKEY_CTRL_RSA_PADDING, \
223 pad, NULL)
224
225#define EVP_PKEY_CTX_set_rsa_pss_saltlen(ctx, len) \
226 EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, \
227 (EVP_PKEY_OP_SIGN|EVP_PKEY_OP_VERIFY), \
228 EVP_PKEY_CTRL_RSA_PSS_SALTLEN, \
229 len, NULL)
230
231#define EVP_PKEY_CTX_set_rsa_keygen_bits(ctx, bits) \
232 EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_KEYGEN, \
233 EVP_PKEY_CTRL_RSA_KEYGEN_BITS, bits, NULL)
234
235#define EVP_PKEY_CTX_set_rsa_keygen_pubexp(ctx, pubexp) \
236 EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_KEYGEN, \
237 EVP_PKEY_CTRL_RSA_KEYGEN_PUBEXP, 0, pubexp)
238
239#define EVP_PKEY_CTRL_RSA_PADDING (EVP_PKEY_ALG_CTRL + 1)
240#define EVP_PKEY_CTRL_RSA_PSS_SALTLEN (EVP_PKEY_ALG_CTRL + 2)
241
242#define EVP_PKEY_CTRL_RSA_KEYGEN_BITS (EVP_PKEY_ALG_CTRL + 3)
243#define EVP_PKEY_CTRL_RSA_KEYGEN_PUBEXP (EVP_PKEY_ALG_CTRL + 4)
244
241#define RSA_PKCS1_PADDING 1 245#define RSA_PKCS1_PADDING 1
242#define RSA_SSLV23_PADDING 2 246#define RSA_SSLV23_PADDING 2
243#define RSA_NO_PADDING 3 247#define RSA_NO_PADDING 3
244#define RSA_PKCS1_OAEP_PADDING 4 248#define RSA_PKCS1_OAEP_PADDING 4
245#define RSA_X931_PADDING 5 249#define RSA_X931_PADDING 5
250/* EVP_PKEY_ only */
251#define RSA_PKCS1_PSS_PADDING 6
246 252
247#define RSA_PKCS1_PADDING_SIZE 11 253#define RSA_PKCS1_PADDING_SIZE 11
248 254
@@ -261,11 +267,6 @@ RSA * RSA_generate_key(int bits, unsigned long e,void
261 267
262/* New version */ 268/* New version */
263int RSA_generate_key_ex(RSA *rsa, int bits, BIGNUM *e, BN_GENCB *cb); 269int RSA_generate_key_ex(RSA *rsa, int bits, BIGNUM *e, BN_GENCB *cb);
264int RSA_X931_derive_ex(RSA *rsa, BIGNUM *p1, BIGNUM *p2, BIGNUM *q1, BIGNUM *q2,
265 const BIGNUM *Xp1, const BIGNUM *Xp2, const BIGNUM *Xp,
266 const BIGNUM *Xq1, const BIGNUM *Xq2, const BIGNUM *Xq,
267 const BIGNUM *e, BN_GENCB *cb);
268int RSA_X931_generate_key_ex(RSA *rsa, int bits, const BIGNUM *e, BN_GENCB *cb);
269 270
270int RSA_check_key(const RSA *); 271int RSA_check_key(const RSA *);
271 /* next 4 return -1 on error */ 272 /* next 4 return -1 on error */
@@ -283,11 +284,6 @@ int RSA_up_ref(RSA *r);
283 284
284int RSA_flags(const RSA *r); 285int RSA_flags(const RSA *r);
285 286
286#ifdef OPENSSL_FIPS
287RSA *FIPS_rsa_new(void);
288void FIPS_rsa_free(RSA *r);
289#endif
290
291void RSA_set_default_method(const RSA_METHOD *meth); 287void RSA_set_default_method(const RSA_METHOD *meth);
292const RSA_METHOD *RSA_get_default_method(void); 288const RSA_METHOD *RSA_get_default_method(void);
293const RSA_METHOD *RSA_get_method(const RSA *rsa); 289const RSA_METHOD *RSA_get_method(const RSA *rsa);
@@ -333,7 +329,7 @@ RSA *d2i_Netscape_RSA(RSA **a, const unsigned char **pp, long length,
333int RSA_sign(int type, const unsigned char *m, unsigned int m_length, 329int RSA_sign(int type, const unsigned char *m, unsigned int m_length,
334 unsigned char *sigret, unsigned int *siglen, RSA *rsa); 330 unsigned char *sigret, unsigned int *siglen, RSA *rsa);
335int RSA_verify(int type, const unsigned char *m, unsigned int m_length, 331int RSA_verify(int type, const unsigned char *m, unsigned int m_length,
336 unsigned char *sigbuf, unsigned int siglen, RSA *rsa); 332 const unsigned char *sigbuf, unsigned int siglen, RSA *rsa);
337 333
338/* The following 2 function sign and verify a ASN1_OCTET_STRING 334/* The following 2 function sign and verify a ASN1_OCTET_STRING
339 * object inside PKCS#1 padded RSA encryption */ 335 * object inside PKCS#1 padded RSA encryption */
@@ -401,9 +397,15 @@ void ERR_load_RSA_strings(void);
401/* Error codes for the RSA functions. */ 397/* Error codes for the RSA functions. */
402 398
403/* Function codes. */ 399/* Function codes. */
404#define RSA_F_FIPS_RSA_SIGN 140 400#define RSA_F_CHECK_PADDING_MD 140
405#define RSA_F_FIPS_RSA_VERIFY 141 401#define RSA_F_DO_RSA_PRINT 146
402#define RSA_F_INT_RSA_VERIFY 145
406#define RSA_F_MEMORY_LOCK 100 403#define RSA_F_MEMORY_LOCK 100
404#define RSA_F_OLD_RSA_PRIV_DECODE 147
405#define RSA_F_PKEY_RSA_CTRL 143
406#define RSA_F_PKEY_RSA_CTRL_STR 144
407#define RSA_F_PKEY_RSA_SIGN 142
408#define RSA_F_PKEY_RSA_VERIFYRECOVER 141
407#define RSA_F_RSA_BUILTIN_KEYGEN 129 409#define RSA_F_RSA_BUILTIN_KEYGEN 129
408#define RSA_F_RSA_CHECK_KEY 123 410#define RSA_F_RSA_CHECK_KEY 123
409#define RSA_F_RSA_EAY_PRIVATE_DECRYPT 101 411#define RSA_F_RSA_EAY_PRIVATE_DECRYPT 101
@@ -434,11 +436,10 @@ void ERR_load_RSA_strings(void);
434#define RSA_F_RSA_PADDING_CHECK_X931 128 436#define RSA_F_RSA_PADDING_CHECK_X931 128
435#define RSA_F_RSA_PRINT 115 437#define RSA_F_RSA_PRINT 115
436#define RSA_F_RSA_PRINT_FP 116 438#define RSA_F_RSA_PRINT_FP 116
437#define RSA_F_RSA_PRIVATE_ENCRYPT 137 439#define RSA_F_RSA_PRIV_DECODE 137
438#define RSA_F_RSA_PUBLIC_DECRYPT 138 440#define RSA_F_RSA_PRIV_ENCODE 138
441#define RSA_F_RSA_PUB_DECODE 139
439#define RSA_F_RSA_SETUP_BLINDING 136 442#define RSA_F_RSA_SETUP_BLINDING 136
440#define RSA_F_RSA_SET_DEFAULT_METHOD 139
441#define RSA_F_RSA_SET_METHOD 142
442#define RSA_F_RSA_SIGN 117 443#define RSA_F_RSA_SIGN 117
443#define RSA_F_RSA_SIGN_ASN1_OCTET_STRING 118 444#define RSA_F_RSA_SIGN_ASN1_OCTET_STRING 118
444#define RSA_F_RSA_VERIFY 119 445#define RSA_F_RSA_VERIFY 119
@@ -464,20 +465,25 @@ void ERR_load_RSA_strings(void);
464#define RSA_R_DMQ1_NOT_CONGRUENT_TO_D 125 465#define RSA_R_DMQ1_NOT_CONGRUENT_TO_D 125
465#define RSA_R_D_E_NOT_CONGRUENT_TO_1 123 466#define RSA_R_D_E_NOT_CONGRUENT_TO_1 123
466#define RSA_R_FIRST_OCTET_INVALID 133 467#define RSA_R_FIRST_OCTET_INVALID 133
468#define RSA_R_ILLEGAL_OR_UNSUPPORTED_PADDING_MODE 144
469#define RSA_R_INVALID_DIGEST_LENGTH 143
467#define RSA_R_INVALID_HEADER 137 470#define RSA_R_INVALID_HEADER 137
471#define RSA_R_INVALID_KEYBITS 145
468#define RSA_R_INVALID_MESSAGE_LENGTH 131 472#define RSA_R_INVALID_MESSAGE_LENGTH 131
469#define RSA_R_INVALID_PADDING 138 473#define RSA_R_INVALID_PADDING 138
474#define RSA_R_INVALID_PADDING_MODE 141
475#define RSA_R_INVALID_PSS_SALTLEN 146
470#define RSA_R_INVALID_TRAILER 139 476#define RSA_R_INVALID_TRAILER 139
477#define RSA_R_INVALID_X931_DIGEST 142
471#define RSA_R_IQMP_NOT_INVERSE_OF_Q 126 478#define RSA_R_IQMP_NOT_INVERSE_OF_Q 126
472#define RSA_R_KEY_SIZE_TOO_SMALL 120 479#define RSA_R_KEY_SIZE_TOO_SMALL 120
473#define RSA_R_LAST_OCTET_INVALID 134 480#define RSA_R_LAST_OCTET_INVALID 134
474#define RSA_R_MODULUS_TOO_LARGE 105 481#define RSA_R_MODULUS_TOO_LARGE 105
475#define RSA_R_NON_FIPS_METHOD 141
476#define RSA_R_NO_PUBLIC_EXPONENT 140 482#define RSA_R_NO_PUBLIC_EXPONENT 140
477#define RSA_R_NULL_BEFORE_BLOCK_MISSING 113 483#define RSA_R_NULL_BEFORE_BLOCK_MISSING 113
478#define RSA_R_N_DOES_NOT_EQUAL_P_Q 127 484#define RSA_R_N_DOES_NOT_EQUAL_P_Q 127
479#define RSA_R_OAEP_DECODING_ERROR 121 485#define RSA_R_OAEP_DECODING_ERROR 121
480#define RSA_R_OPERATION_NOT_ALLOWED_IN_FIPS_MODE 142 486#define RSA_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE 148
481#define RSA_R_PADDING_CHECK_FAILED 114 487#define RSA_R_PADDING_CHECK_FAILED 114
482#define RSA_R_P_NOT_PRIME 128 488#define RSA_R_P_NOT_PRIME 128
483#define RSA_R_Q_NOT_PRIME 129 489#define RSA_R_Q_NOT_PRIME 129
@@ -488,6 +494,7 @@ void ERR_load_RSA_strings(void);
488#define RSA_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD 116 494#define RSA_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD 116
489#define RSA_R_UNKNOWN_ALGORITHM_TYPE 117 495#define RSA_R_UNKNOWN_ALGORITHM_TYPE 117
490#define RSA_R_UNKNOWN_PADDING_TYPE 118 496#define RSA_R_UNKNOWN_PADDING_TYPE 118
497#define RSA_R_VALUE_MISSING 147
491#define RSA_R_WRONG_SIGNATURE_LENGTH 119 498#define RSA_R_WRONG_SIGNATURE_LENGTH 119
492 499
493#ifdef __cplusplus 500#ifdef __cplusplus
diff --git a/src/lib/libcrypto/rsa/rsa_ameth.c b/src/lib/libcrypto/rsa/rsa_ameth.c
new file mode 100644
index 0000000000..8c3209885e
--- /dev/null
+++ b/src/lib/libcrypto/rsa/rsa_ameth.c
@@ -0,0 +1,349 @@
1/* crypto/rsa/rsa_ameth.c */
2/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
3 * project 2006.
4 */
5/* ====================================================================
6 * Copyright (c) 2006 The OpenSSL Project. All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 *
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 *
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in
17 * the documentation and/or other materials provided with the
18 * distribution.
19 *
20 * 3. All advertising materials mentioning features or use of this
21 * software must display the following acknowledgment:
22 * "This product includes software developed by the OpenSSL Project
23 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
24 *
25 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
26 * endorse or promote products derived from this software without
27 * prior written permission. For written permission, please contact
28 * licensing@OpenSSL.org.
29 *
30 * 5. Products derived from this software may not be called "OpenSSL"
31 * nor may "OpenSSL" appear in their names without prior written
32 * permission of the OpenSSL Project.
33 *
34 * 6. Redistributions of any form whatsoever must retain the following
35 * acknowledgment:
36 * "This product includes software developed by the OpenSSL Project
37 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
38 *
39 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
40 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
43 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
50 * OF THE POSSIBILITY OF SUCH DAMAGE.
51 * ====================================================================
52 *
53 * This product includes cryptographic software written by Eric Young
54 * (eay@cryptsoft.com). This product includes software written by Tim
55 * Hudson (tjh@cryptsoft.com).
56 *
57 */
58
59#include <stdio.h>
60#include "cryptlib.h"
61#include <openssl/asn1t.h>
62#include <openssl/x509.h>
63#include <openssl/rsa.h>
64#include <openssl/bn.h>
65#ifndef OPENSSL_NO_CMS
66#include <openssl/cms.h>
67#endif
68#include "asn1_locl.h"
69
70static int rsa_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey)
71 {
72 unsigned char *penc = NULL;
73 int penclen;
74 penclen = i2d_RSAPublicKey(pkey->pkey.rsa, &penc);
75 if (penclen <= 0)
76 return 0;
77 if (X509_PUBKEY_set0_param(pk, OBJ_nid2obj(EVP_PKEY_RSA),
78 V_ASN1_NULL, NULL, penc, penclen))
79 return 1;
80
81 OPENSSL_free(penc);
82 return 0;
83 }
84
85static int rsa_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey)
86 {
87 const unsigned char *p;
88 int pklen;
89 RSA *rsa = NULL;
90 if (!X509_PUBKEY_get0_param(NULL, &p, &pklen, NULL, pubkey))
91 return 0;
92 if (!(rsa = d2i_RSAPublicKey(NULL, &p, pklen)))
93 {
94 RSAerr(RSA_F_RSA_PUB_DECODE, ERR_R_RSA_LIB);
95 return 0;
96 }
97 EVP_PKEY_assign_RSA (pkey, rsa);
98 return 1;
99 }
100
101static int rsa_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b)
102 {
103 if (BN_cmp(b->pkey.rsa->n,a->pkey.rsa->n) != 0
104 || BN_cmp(b->pkey.rsa->e,a->pkey.rsa->e) != 0)
105 return 0;
106 return 1;
107 }
108
109static int old_rsa_priv_decode(EVP_PKEY *pkey,
110 const unsigned char **pder, int derlen)
111 {
112 RSA *rsa;
113 if (!(rsa = d2i_RSAPrivateKey (NULL, pder, derlen)))
114 {
115 RSAerr(RSA_F_OLD_RSA_PRIV_DECODE, ERR_R_RSA_LIB);
116 return 0;
117 }
118 EVP_PKEY_assign_RSA(pkey, rsa);
119 return 1;
120 }
121
122static int old_rsa_priv_encode(const EVP_PKEY *pkey, unsigned char **pder)
123 {
124 return i2d_RSAPrivateKey(pkey->pkey.rsa, pder);
125 }
126
127static int rsa_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey)
128 {
129 unsigned char *rk = NULL;
130 int rklen;
131 rklen = i2d_RSAPrivateKey(pkey->pkey.rsa, &rk);
132
133 if (rklen <= 0)
134 {
135 RSAerr(RSA_F_RSA_PRIV_ENCODE,ERR_R_MALLOC_FAILURE);
136 return 0;
137 }
138
139 if (!PKCS8_pkey_set0(p8, OBJ_nid2obj(NID_rsaEncryption), 0,
140 V_ASN1_NULL, NULL, rk, rklen))
141 {
142 RSAerr(RSA_F_RSA_PRIV_ENCODE,ERR_R_MALLOC_FAILURE);
143 return 0;
144 }
145
146 return 1;
147 }
148
149static int rsa_priv_decode(EVP_PKEY *pkey, PKCS8_PRIV_KEY_INFO *p8)
150 {
151 const unsigned char *p;
152 int pklen;
153 if (!PKCS8_pkey_get0(NULL, &p, &pklen, NULL, p8))
154 return 0;
155 return old_rsa_priv_decode(pkey, &p, pklen);
156 }
157
158static int int_rsa_size(const EVP_PKEY *pkey)
159 {
160 return RSA_size(pkey->pkey.rsa);
161 }
162
163static int rsa_bits(const EVP_PKEY *pkey)
164 {
165 return BN_num_bits(pkey->pkey.rsa->n);
166 }
167
168static void int_rsa_free(EVP_PKEY *pkey)
169 {
170 RSA_free(pkey->pkey.rsa);
171 }
172
173
174static void update_buflen(const BIGNUM *b, size_t *pbuflen)
175 {
176 size_t i;
177 if (!b)
178 return;
179 if (*pbuflen < (i = (size_t)BN_num_bytes(b)))
180 *pbuflen = i;
181 }
182
183static int do_rsa_print(BIO *bp, const RSA *x, int off, int priv)
184 {
185 char *str;
186 const char *s;
187 unsigned char *m=NULL;
188 int ret=0, mod_len = 0;
189 size_t buf_len=0;
190
191 update_buflen(x->n, &buf_len);
192 update_buflen(x->e, &buf_len);
193
194 if (priv)
195 {
196 update_buflen(x->d, &buf_len);
197 update_buflen(x->p, &buf_len);
198 update_buflen(x->q, &buf_len);
199 update_buflen(x->dmp1, &buf_len);
200 update_buflen(x->dmq1, &buf_len);
201 update_buflen(x->iqmp, &buf_len);
202 }
203
204 m=(unsigned char *)OPENSSL_malloc(buf_len+10);
205 if (m == NULL)
206 {
207 RSAerr(RSA_F_DO_RSA_PRINT,ERR_R_MALLOC_FAILURE);
208 goto err;
209 }
210
211 if (x->n != NULL)
212 mod_len = BN_num_bits(x->n);
213
214 if(!BIO_indent(bp,off,128))
215 goto err;
216
217 if (priv && x->d)
218 {
219 if (BIO_printf(bp,"Private-Key: (%d bit)\n", mod_len)
220 <= 0) goto err;
221 str = "modulus:";
222 s = "publicExponent:";
223 }
224 else
225 {
226 if (BIO_printf(bp,"Public-Key: (%d bit)\n", mod_len)
227 <= 0) goto err;
228 str = "Modulus:";
229 s= "Exponent:";
230 }
231 if (!ASN1_bn_print(bp,str,x->n,m,off)) goto err;
232 if (!ASN1_bn_print(bp,s,x->e,m,off))
233 goto err;
234 if (priv)
235 {
236 if (!ASN1_bn_print(bp,"privateExponent:",x->d,m,off))
237 goto err;
238 if (!ASN1_bn_print(bp,"prime1:",x->p,m,off))
239 goto err;
240 if (!ASN1_bn_print(bp,"prime2:",x->q,m,off))
241 goto err;
242 if (!ASN1_bn_print(bp,"exponent1:",x->dmp1,m,off))
243 goto err;
244 if (!ASN1_bn_print(bp,"exponent2:",x->dmq1,m,off))
245 goto err;
246 if (!ASN1_bn_print(bp,"coefficient:",x->iqmp,m,off))
247 goto err;
248 }
249 ret=1;
250err:
251 if (m != NULL) OPENSSL_free(m);
252 return(ret);
253 }
254
255static int rsa_pub_print(BIO *bp, const EVP_PKEY *pkey, int indent,
256 ASN1_PCTX *ctx)
257 {
258 return do_rsa_print(bp, pkey->pkey.rsa, indent, 0);
259 }
260
261
262static int rsa_priv_print(BIO *bp, const EVP_PKEY *pkey, int indent,
263 ASN1_PCTX *ctx)
264 {
265 return do_rsa_print(bp, pkey->pkey.rsa, indent, 1);
266 }
267
268
269static int rsa_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2)
270 {
271 X509_ALGOR *alg = NULL;
272 switch (op)
273 {
274
275 case ASN1_PKEY_CTRL_PKCS7_SIGN:
276 if (arg1 == 0)
277 PKCS7_SIGNER_INFO_get0_algs(arg2, NULL, NULL, &alg);
278 break;
279
280 case ASN1_PKEY_CTRL_PKCS7_ENCRYPT:
281 if (arg1 == 0)
282 PKCS7_RECIP_INFO_get0_alg(arg2, &alg);
283 break;
284#ifndef OPENSSL_NO_CMS
285 case ASN1_PKEY_CTRL_CMS_SIGN:
286 if (arg1 == 0)
287 CMS_SignerInfo_get0_algs(arg2, NULL, NULL, NULL, &alg);
288 break;
289
290 case ASN1_PKEY_CTRL_CMS_ENVELOPE:
291 if (arg1 == 0)
292 CMS_RecipientInfo_ktri_get0_algs(arg2, NULL, NULL, &alg);
293 break;
294#endif
295
296 case ASN1_PKEY_CTRL_DEFAULT_MD_NID:
297 *(int *)arg2 = NID_sha1;
298 return 1;
299
300 default:
301 return -2;
302
303 }
304
305 if (alg)
306 X509_ALGOR_set0(alg, OBJ_nid2obj(NID_rsaEncryption),
307 V_ASN1_NULL, 0);
308
309 return 1;
310
311 }
312
313
314const EVP_PKEY_ASN1_METHOD rsa_asn1_meths[] =
315 {
316 {
317 EVP_PKEY_RSA,
318 EVP_PKEY_RSA,
319 ASN1_PKEY_SIGPARAM_NULL,
320
321 "RSA",
322 "OpenSSL RSA method",
323
324 rsa_pub_decode,
325 rsa_pub_encode,
326 rsa_pub_cmp,
327 rsa_pub_print,
328
329 rsa_priv_decode,
330 rsa_priv_encode,
331 rsa_priv_print,
332
333 int_rsa_size,
334 rsa_bits,
335
336 0,0,0,0,0,0,
337
338 int_rsa_free,
339 rsa_pkey_ctrl,
340 old_rsa_priv_decode,
341 old_rsa_priv_encode
342 },
343
344 {
345 EVP_PKEY_RSA2,
346 EVP_PKEY_RSA,
347 ASN1_PKEY_ALIAS
348 }
349 };
diff --git a/src/lib/libcrypto/rsa/rsa_asn1.c b/src/lib/libcrypto/rsa/rsa_asn1.c
index 6e8a803e81..4efca8cdc8 100644
--- a/src/lib/libcrypto/rsa/rsa_asn1.c
+++ b/src/lib/libcrypto/rsa/rsa_asn1.c
@@ -3,7 +3,7 @@
3 * project 2000. 3 * project 2000.
4 */ 4 */
5/* ==================================================================== 5/* ====================================================================
6 * Copyright (c) 2000 The OpenSSL Project. All rights reserved. 6 * Copyright (c) 2000-2005 The OpenSSL Project. All rights reserved.
7 * 7 *
8 * Redistribution and use in source and binary forms, with or without 8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions 9 * modification, are permitted provided that the following conditions
@@ -62,19 +62,9 @@
62#include <openssl/rsa.h> 62#include <openssl/rsa.h>
63#include <openssl/asn1t.h> 63#include <openssl/asn1t.h>
64 64
65static ASN1_METHOD method={
66 (I2D_OF(void)) i2d_RSAPrivateKey,
67 (D2I_OF(void)) d2i_RSAPrivateKey,
68 (void *(*)(void)) RSA_new,
69 (void (*)(void *)) RSA_free};
70
71ASN1_METHOD *RSAPrivateKey_asn1_meth(void)
72 {
73 return(&method);
74 }
75
76/* Override the default free and new methods */ 65/* Override the default free and new methods */
77static int rsa_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it) 66static int rsa_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
67 void *exarg)
78{ 68{
79 if(operation == ASN1_OP_NEW_PRE) { 69 if(operation == ASN1_OP_NEW_PRE) {
80 *pval = (ASN1_VALUE *)RSA_new(); 70 *pval = (ASN1_VALUE *)RSA_new();
diff --git a/src/lib/libcrypto/rsa/rsa_eay.c b/src/lib/libcrypto/rsa/rsa_eay.c
index 0ac6418449..c5eaeeae6b 100644
--- a/src/lib/libcrypto/rsa/rsa_eay.c
+++ b/src/lib/libcrypto/rsa/rsa_eay.c
@@ -115,7 +115,7 @@
115#include <openssl/rsa.h> 115#include <openssl/rsa.h>
116#include <openssl/rand.h> 116#include <openssl/rand.h>
117 117
118#if !defined(RSA_NULL) && !defined(OPENSSL_FIPS) 118#ifndef RSA_NULL
119 119
120static int RSA_eay_public_encrypt(int flen, const unsigned char *from, 120static int RSA_eay_public_encrypt(int flen, const unsigned char *from,
121 unsigned char *to, RSA *rsa,int padding); 121 unsigned char *to, RSA *rsa,int padding);
@@ -256,6 +256,7 @@ static BN_BLINDING *rsa_get_blinding(RSA *rsa, int *local, BN_CTX *ctx)
256{ 256{
257 BN_BLINDING *ret; 257 BN_BLINDING *ret;
258 int got_write_lock = 0; 258 int got_write_lock = 0;
259 CRYPTO_THREADID cur;
259 260
260 CRYPTO_r_lock(CRYPTO_LOCK_RSA); 261 CRYPTO_r_lock(CRYPTO_LOCK_RSA);
261 262
@@ -273,7 +274,8 @@ static BN_BLINDING *rsa_get_blinding(RSA *rsa, int *local, BN_CTX *ctx)
273 if (ret == NULL) 274 if (ret == NULL)
274 goto err; 275 goto err;
275 276
276 if (BN_BLINDING_get_thread_id(ret) == CRYPTO_thread_id()) 277 CRYPTO_THREADID_current(&cur);
278 if (!CRYPTO_THREADID_cmp(&cur, BN_BLINDING_thread_id(ret)))
277 { 279 {
278 /* rsa->blinding is ours! */ 280 /* rsa->blinding is ours! */
279 281
diff --git a/src/lib/libcrypto/rsa/rsa_err.c b/src/lib/libcrypto/rsa/rsa_err.c
index 501f5ea389..cf9f1106b0 100644
--- a/src/lib/libcrypto/rsa/rsa_err.c
+++ b/src/lib/libcrypto/rsa/rsa_err.c
@@ -1,6 +1,6 @@
1/* crypto/rsa/rsa_err.c */ 1/* crypto/rsa/rsa_err.c */
2/* ==================================================================== 2/* ====================================================================
3 * Copyright (c) 1999-2007 The OpenSSL Project. All rights reserved. 3 * Copyright (c) 1999-2008 The OpenSSL Project. All rights reserved.
4 * 4 *
5 * Redistribution and use in source and binary forms, with or without 5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions 6 * modification, are permitted provided that the following conditions
@@ -70,9 +70,15 @@
70 70
71static ERR_STRING_DATA RSA_str_functs[]= 71static ERR_STRING_DATA RSA_str_functs[]=
72 { 72 {
73{ERR_FUNC(RSA_F_FIPS_RSA_SIGN), "FIPS_RSA_SIGN"}, 73{ERR_FUNC(RSA_F_CHECK_PADDING_MD), "CHECK_PADDING_MD"},
74{ERR_FUNC(RSA_F_FIPS_RSA_VERIFY), "FIPS_RSA_VERIFY"}, 74{ERR_FUNC(RSA_F_DO_RSA_PRINT), "DO_RSA_PRINT"},
75{ERR_FUNC(RSA_F_INT_RSA_VERIFY), "INT_RSA_VERIFY"},
75{ERR_FUNC(RSA_F_MEMORY_LOCK), "MEMORY_LOCK"}, 76{ERR_FUNC(RSA_F_MEMORY_LOCK), "MEMORY_LOCK"},
77{ERR_FUNC(RSA_F_OLD_RSA_PRIV_DECODE), "OLD_RSA_PRIV_DECODE"},
78{ERR_FUNC(RSA_F_PKEY_RSA_CTRL), "PKEY_RSA_CTRL"},
79{ERR_FUNC(RSA_F_PKEY_RSA_CTRL_STR), "PKEY_RSA_CTRL_STR"},
80{ERR_FUNC(RSA_F_PKEY_RSA_SIGN), "PKEY_RSA_SIGN"},
81{ERR_FUNC(RSA_F_PKEY_RSA_VERIFYRECOVER), "PKEY_RSA_VERIFYRECOVER"},
76{ERR_FUNC(RSA_F_RSA_BUILTIN_KEYGEN), "RSA_BUILTIN_KEYGEN"}, 82{ERR_FUNC(RSA_F_RSA_BUILTIN_KEYGEN), "RSA_BUILTIN_KEYGEN"},
77{ERR_FUNC(RSA_F_RSA_CHECK_KEY), "RSA_check_key"}, 83{ERR_FUNC(RSA_F_RSA_CHECK_KEY), "RSA_check_key"},
78{ERR_FUNC(RSA_F_RSA_EAY_PRIVATE_DECRYPT), "RSA_EAY_PRIVATE_DECRYPT"}, 84{ERR_FUNC(RSA_F_RSA_EAY_PRIVATE_DECRYPT), "RSA_EAY_PRIVATE_DECRYPT"},
@@ -103,11 +109,10 @@ static ERR_STRING_DATA RSA_str_functs[]=
103{ERR_FUNC(RSA_F_RSA_PADDING_CHECK_X931), "RSA_padding_check_X931"}, 109{ERR_FUNC(RSA_F_RSA_PADDING_CHECK_X931), "RSA_padding_check_X931"},
104{ERR_FUNC(RSA_F_RSA_PRINT), "RSA_print"}, 110{ERR_FUNC(RSA_F_RSA_PRINT), "RSA_print"},
105{ERR_FUNC(RSA_F_RSA_PRINT_FP), "RSA_print_fp"}, 111{ERR_FUNC(RSA_F_RSA_PRINT_FP), "RSA_print_fp"},
106{ERR_FUNC(RSA_F_RSA_PRIVATE_ENCRYPT), "RSA_private_encrypt"}, 112{ERR_FUNC(RSA_F_RSA_PRIV_DECODE), "RSA_PRIV_DECODE"},
107{ERR_FUNC(RSA_F_RSA_PUBLIC_DECRYPT), "RSA_public_decrypt"}, 113{ERR_FUNC(RSA_F_RSA_PRIV_ENCODE), "RSA_PRIV_ENCODE"},
114{ERR_FUNC(RSA_F_RSA_PUB_DECODE), "RSA_PUB_DECODE"},
108{ERR_FUNC(RSA_F_RSA_SETUP_BLINDING), "RSA_setup_blinding"}, 115{ERR_FUNC(RSA_F_RSA_SETUP_BLINDING), "RSA_setup_blinding"},
109{ERR_FUNC(RSA_F_RSA_SET_DEFAULT_METHOD), "RSA_set_default_method"},
110{ERR_FUNC(RSA_F_RSA_SET_METHOD), "RSA_set_method"},
111{ERR_FUNC(RSA_F_RSA_SIGN), "RSA_sign"}, 116{ERR_FUNC(RSA_F_RSA_SIGN), "RSA_sign"},
112{ERR_FUNC(RSA_F_RSA_SIGN_ASN1_OCTET_STRING), "RSA_sign_ASN1_OCTET_STRING"}, 117{ERR_FUNC(RSA_F_RSA_SIGN_ASN1_OCTET_STRING), "RSA_sign_ASN1_OCTET_STRING"},
113{ERR_FUNC(RSA_F_RSA_VERIFY), "RSA_verify"}, 118{ERR_FUNC(RSA_F_RSA_VERIFY), "RSA_verify"},
@@ -136,20 +141,25 @@ static ERR_STRING_DATA RSA_str_reasons[]=
136{ERR_REASON(RSA_R_DMQ1_NOT_CONGRUENT_TO_D),"dmq1 not congruent to d"}, 141{ERR_REASON(RSA_R_DMQ1_NOT_CONGRUENT_TO_D),"dmq1 not congruent to d"},
137{ERR_REASON(RSA_R_D_E_NOT_CONGRUENT_TO_1),"d e not congruent to 1"}, 142{ERR_REASON(RSA_R_D_E_NOT_CONGRUENT_TO_1),"d e not congruent to 1"},
138{ERR_REASON(RSA_R_FIRST_OCTET_INVALID) ,"first octet invalid"}, 143{ERR_REASON(RSA_R_FIRST_OCTET_INVALID) ,"first octet invalid"},
144{ERR_REASON(RSA_R_ILLEGAL_OR_UNSUPPORTED_PADDING_MODE),"illegal or unsupported padding mode"},
145{ERR_REASON(RSA_R_INVALID_DIGEST_LENGTH) ,"invalid digest length"},
139{ERR_REASON(RSA_R_INVALID_HEADER) ,"invalid header"}, 146{ERR_REASON(RSA_R_INVALID_HEADER) ,"invalid header"},
147{ERR_REASON(RSA_R_INVALID_KEYBITS) ,"invalid keybits"},
140{ERR_REASON(RSA_R_INVALID_MESSAGE_LENGTH),"invalid message length"}, 148{ERR_REASON(RSA_R_INVALID_MESSAGE_LENGTH),"invalid message length"},
141{ERR_REASON(RSA_R_INVALID_PADDING) ,"invalid padding"}, 149{ERR_REASON(RSA_R_INVALID_PADDING) ,"invalid padding"},
150{ERR_REASON(RSA_R_INVALID_PADDING_MODE) ,"invalid padding mode"},
151{ERR_REASON(RSA_R_INVALID_PSS_SALTLEN) ,"invalid pss saltlen"},
142{ERR_REASON(RSA_R_INVALID_TRAILER) ,"invalid trailer"}, 152{ERR_REASON(RSA_R_INVALID_TRAILER) ,"invalid trailer"},
153{ERR_REASON(RSA_R_INVALID_X931_DIGEST) ,"invalid x931 digest"},
143{ERR_REASON(RSA_R_IQMP_NOT_INVERSE_OF_Q) ,"iqmp not inverse of q"}, 154{ERR_REASON(RSA_R_IQMP_NOT_INVERSE_OF_Q) ,"iqmp not inverse of q"},
144{ERR_REASON(RSA_R_KEY_SIZE_TOO_SMALL) ,"key size too small"}, 155{ERR_REASON(RSA_R_KEY_SIZE_TOO_SMALL) ,"key size too small"},
145{ERR_REASON(RSA_R_LAST_OCTET_INVALID) ,"last octet invalid"}, 156{ERR_REASON(RSA_R_LAST_OCTET_INVALID) ,"last octet invalid"},
146{ERR_REASON(RSA_R_MODULUS_TOO_LARGE) ,"modulus too large"}, 157{ERR_REASON(RSA_R_MODULUS_TOO_LARGE) ,"modulus too large"},
147{ERR_REASON(RSA_R_NON_FIPS_METHOD) ,"non fips method"},
148{ERR_REASON(RSA_R_NO_PUBLIC_EXPONENT) ,"no public exponent"}, 158{ERR_REASON(RSA_R_NO_PUBLIC_EXPONENT) ,"no public exponent"},
149{ERR_REASON(RSA_R_NULL_BEFORE_BLOCK_MISSING),"null before block missing"}, 159{ERR_REASON(RSA_R_NULL_BEFORE_BLOCK_MISSING),"null before block missing"},
150{ERR_REASON(RSA_R_N_DOES_NOT_EQUAL_P_Q) ,"n does not equal p q"}, 160{ERR_REASON(RSA_R_N_DOES_NOT_EQUAL_P_Q) ,"n does not equal p q"},
151{ERR_REASON(RSA_R_OAEP_DECODING_ERROR) ,"oaep decoding error"}, 161{ERR_REASON(RSA_R_OAEP_DECODING_ERROR) ,"oaep decoding error"},
152{ERR_REASON(RSA_R_OPERATION_NOT_ALLOWED_IN_FIPS_MODE),"operation not allowed in fips mode"}, 162{ERR_REASON(RSA_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE),"operation not supported for this keytype"},
153{ERR_REASON(RSA_R_PADDING_CHECK_FAILED) ,"padding check failed"}, 163{ERR_REASON(RSA_R_PADDING_CHECK_FAILED) ,"padding check failed"},
154{ERR_REASON(RSA_R_P_NOT_PRIME) ,"p not prime"}, 164{ERR_REASON(RSA_R_P_NOT_PRIME) ,"p not prime"},
155{ERR_REASON(RSA_R_Q_NOT_PRIME) ,"q not prime"}, 165{ERR_REASON(RSA_R_Q_NOT_PRIME) ,"q not prime"},
@@ -160,6 +170,7 @@ static ERR_STRING_DATA RSA_str_reasons[]=
160{ERR_REASON(RSA_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD),"the asn1 object identifier is not known for this md"}, 170{ERR_REASON(RSA_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD),"the asn1 object identifier is not known for this md"},
161{ERR_REASON(RSA_R_UNKNOWN_ALGORITHM_TYPE),"unknown algorithm type"}, 171{ERR_REASON(RSA_R_UNKNOWN_ALGORITHM_TYPE),"unknown algorithm type"},
162{ERR_REASON(RSA_R_UNKNOWN_PADDING_TYPE) ,"unknown padding type"}, 172{ERR_REASON(RSA_R_UNKNOWN_PADDING_TYPE) ,"unknown padding type"},
173{ERR_REASON(RSA_R_VALUE_MISSING) ,"value missing"},
163{ERR_REASON(RSA_R_WRONG_SIGNATURE_LENGTH),"wrong signature length"}, 174{ERR_REASON(RSA_R_WRONG_SIGNATURE_LENGTH),"wrong signature length"},
164{0,NULL} 175{0,NULL}
165 }; 176 };
diff --git a/src/lib/libcrypto/rsa/rsa_gen.c b/src/lib/libcrypto/rsa/rsa_gen.c
index 41278f83c6..767f7ab682 100644
--- a/src/lib/libcrypto/rsa/rsa_gen.c
+++ b/src/lib/libcrypto/rsa/rsa_gen.c
@@ -68,8 +68,6 @@
68#include <openssl/bn.h> 68#include <openssl/bn.h>
69#include <openssl/rsa.h> 69#include <openssl/rsa.h>
70 70
71#ifndef OPENSSL_FIPS
72
73static int rsa_builtin_keygen(RSA *rsa, int bits, BIGNUM *e_value, BN_GENCB *cb); 71static int rsa_builtin_keygen(RSA *rsa, int bits, BIGNUM *e_value, BN_GENCB *cb);
74 72
75/* NB: this wrapper would normally be placed in rsa_lib.c and the static 73/* NB: this wrapper would normally be placed in rsa_lib.c and the static
@@ -219,4 +217,3 @@ err:
219 return ok; 217 return ok;
220 } 218 }
221 219
222#endif
diff --git a/src/lib/libcrypto/rsa/rsa_lib.c b/src/lib/libcrypto/rsa/rsa_lib.c
index 5714841f4c..de45088d76 100644
--- a/src/lib/libcrypto/rsa/rsa_lib.c
+++ b/src/lib/libcrypto/rsa/rsa_lib.c
@@ -67,6 +67,224 @@
67#include <openssl/engine.h> 67#include <openssl/engine.h>
68#endif 68#endif
69 69
70const char RSA_version[]="RSA" OPENSSL_VERSION_PTEXT;
71
72static const RSA_METHOD *default_RSA_meth=NULL;
73
74RSA *RSA_new(void)
75 {
76 RSA *r=RSA_new_method(NULL);
77
78 return r;
79 }
80
81void RSA_set_default_method(const RSA_METHOD *meth)
82 {
83 default_RSA_meth = meth;
84 }
85
86const RSA_METHOD *RSA_get_default_method(void)
87 {
88 if (default_RSA_meth == NULL)
89 {
90#ifdef RSA_NULL
91 default_RSA_meth=RSA_null_method();
92#else
93#if 0 /* was: #ifdef RSAref */
94 default_RSA_meth=RSA_PKCS1_RSAref();
95#else
96 default_RSA_meth=RSA_PKCS1_SSLeay();
97#endif
98#endif
99 }
100
101 return default_RSA_meth;
102 }
103
104const RSA_METHOD *RSA_get_method(const RSA *rsa)
105 {
106 return rsa->meth;
107 }
108
109int RSA_set_method(RSA *rsa, const RSA_METHOD *meth)
110 {
111 /* NB: The caller is specifically setting a method, so it's not up to us
112 * to deal with which ENGINE it comes from. */
113 const RSA_METHOD *mtmp;
114 mtmp = rsa->meth;
115 if (mtmp->finish) mtmp->finish(rsa);
116#ifndef OPENSSL_NO_ENGINE
117 if (rsa->engine)
118 {
119 ENGINE_finish(rsa->engine);
120 rsa->engine = NULL;
121 }
122#endif
123 rsa->meth = meth;
124 if (meth->init) meth->init(rsa);
125 return 1;
126 }
127
128RSA *RSA_new_method(ENGINE *engine)
129 {
130 RSA *ret;
131
132 ret=(RSA *)OPENSSL_malloc(sizeof(RSA));
133 if (ret == NULL)
134 {
135 RSAerr(RSA_F_RSA_NEW_METHOD,ERR_R_MALLOC_FAILURE);
136 return NULL;
137 }
138
139 ret->meth = RSA_get_default_method();
140#ifndef OPENSSL_NO_ENGINE
141 if (engine)
142 {
143 if (!ENGINE_init(engine))
144 {
145 RSAerr(RSA_F_RSA_NEW_METHOD, ERR_R_ENGINE_LIB);
146 OPENSSL_free(ret);
147 return NULL;
148 }
149 ret->engine = engine;
150 }
151 else
152 ret->engine = ENGINE_get_default_RSA();
153 if(ret->engine)
154 {
155 ret->meth = ENGINE_get_RSA(ret->engine);
156 if(!ret->meth)
157 {
158 RSAerr(RSA_F_RSA_NEW_METHOD,
159 ERR_R_ENGINE_LIB);
160 ENGINE_finish(ret->engine);
161 OPENSSL_free(ret);
162 return NULL;
163 }
164 }
165#endif
166
167 ret->pad=0;
168 ret->version=0;
169 ret->n=NULL;
170 ret->e=NULL;
171 ret->d=NULL;
172 ret->p=NULL;
173 ret->q=NULL;
174 ret->dmp1=NULL;
175 ret->dmq1=NULL;
176 ret->iqmp=NULL;
177 ret->references=1;
178 ret->_method_mod_n=NULL;
179 ret->_method_mod_p=NULL;
180 ret->_method_mod_q=NULL;
181 ret->blinding=NULL;
182 ret->mt_blinding=NULL;
183 ret->bignum_data=NULL;
184 ret->flags=ret->meth->flags;
185 if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_RSA, ret, &ret->ex_data))
186 {
187#ifndef OPENSSL_NO_ENGINE
188 if (ret->engine)
189 ENGINE_finish(ret->engine);
190#endif
191 OPENSSL_free(ret);
192 return(NULL);
193 }
194
195 if ((ret->meth->init != NULL) && !ret->meth->init(ret))
196 {
197#ifndef OPENSSL_NO_ENGINE
198 if (ret->engine)
199 ENGINE_finish(ret->engine);
200#endif
201 CRYPTO_free_ex_data(CRYPTO_EX_INDEX_RSA, ret, &ret->ex_data);
202 OPENSSL_free(ret);
203 ret=NULL;
204 }
205 return(ret);
206 }
207
208void RSA_free(RSA *r)
209 {
210 int i;
211
212 if (r == NULL) return;
213
214 i=CRYPTO_add(&r->references,-1,CRYPTO_LOCK_RSA);
215#ifdef REF_PRINT
216 REF_PRINT("RSA",r);
217#endif
218 if (i > 0) return;
219#ifdef REF_CHECK
220 if (i < 0)
221 {
222 fprintf(stderr,"RSA_free, bad reference count\n");
223 abort();
224 }
225#endif
226
227 if (r->meth->finish)
228 r->meth->finish(r);
229#ifndef OPENSSL_NO_ENGINE
230 if (r->engine)
231 ENGINE_finish(r->engine);
232#endif
233
234 CRYPTO_free_ex_data(CRYPTO_EX_INDEX_RSA, r, &r->ex_data);
235
236 if (r->n != NULL) BN_clear_free(r->n);
237 if (r->e != NULL) BN_clear_free(r->e);
238 if (r->d != NULL) BN_clear_free(r->d);
239 if (r->p != NULL) BN_clear_free(r->p);
240 if (r->q != NULL) BN_clear_free(r->q);
241 if (r->dmp1 != NULL) BN_clear_free(r->dmp1);
242 if (r->dmq1 != NULL) BN_clear_free(r->dmq1);
243 if (r->iqmp != NULL) BN_clear_free(r->iqmp);
244 if (r->blinding != NULL) BN_BLINDING_free(r->blinding);
245 if (r->mt_blinding != NULL) BN_BLINDING_free(r->mt_blinding);
246 if (r->bignum_data != NULL) OPENSSL_free_locked(r->bignum_data);
247 OPENSSL_free(r);
248 }
249
250int RSA_up_ref(RSA *r)
251 {
252 int i = CRYPTO_add(&r->references, 1, CRYPTO_LOCK_RSA);
253#ifdef REF_PRINT
254 REF_PRINT("RSA",r);
255#endif
256#ifdef REF_CHECK
257 if (i < 2)
258 {
259 fprintf(stderr, "RSA_up_ref, bad reference count\n");
260 abort();
261 }
262#endif
263 return ((i > 1) ? 1 : 0);
264 }
265
266int RSA_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
267 CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func)
268 {
269 return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_RSA, argl, argp,
270 new_func, dup_func, free_func);
271 }
272
273int RSA_set_ex_data(RSA *r, int idx, void *arg)
274 {
275 return(CRYPTO_set_ex_data(&r->ex_data,idx,arg));
276 }
277
278void *RSA_get_ex_data(const RSA *r, int idx)
279 {
280 return(CRYPTO_get_ex_data(&r->ex_data,idx));
281 }
282
283int RSA_size(const RSA *r)
284 {
285 return(BN_num_bytes(r->n));
286 }
287
70int RSA_public_encrypt(int flen, const unsigned char *from, unsigned char *to, 288int RSA_public_encrypt(int flen, const unsigned char *from, unsigned char *to,
71 RSA *rsa, int padding) 289 RSA *rsa, int padding)
72 { 290 {
@@ -76,13 +294,6 @@ int RSA_public_encrypt(int flen, const unsigned char *from, unsigned char *to,
76int RSA_private_encrypt(int flen, const unsigned char *from, unsigned char *to, 294int RSA_private_encrypt(int flen, const unsigned char *from, unsigned char *to,
77 RSA *rsa, int padding) 295 RSA *rsa, int padding)
78 { 296 {
79#ifdef OPENSSL_FIPS
80 if(FIPS_mode() && !(rsa->flags & RSA_FLAG_NON_FIPS_ALLOW))
81 {
82 RSAerr(RSA_F_RSA_PRIVATE_ENCRYPT, RSA_R_OPERATION_NOT_ALLOWED_IN_FIPS_MODE);
83 return 0;
84 }
85#endif
86 return(rsa->meth->rsa_priv_enc(flen, from, to, rsa, padding)); 297 return(rsa->meth->rsa_priv_enc(flen, from, to, rsa, padding));
87 } 298 }
88 299
@@ -95,19 +306,12 @@ int RSA_private_decrypt(int flen, const unsigned char *from, unsigned char *to,
95int RSA_public_decrypt(int flen, const unsigned char *from, unsigned char *to, 306int RSA_public_decrypt(int flen, const unsigned char *from, unsigned char *to,
96 RSA *rsa, int padding) 307 RSA *rsa, int padding)
97 { 308 {
98#ifdef OPENSSL_FIPS
99 if(FIPS_mode() && !(rsa->flags & RSA_FLAG_NON_FIPS_ALLOW))
100 {
101 RSAerr(RSA_F_RSA_PUBLIC_DECRYPT, RSA_R_OPERATION_NOT_ALLOWED_IN_FIPS_MODE);
102 return 0;
103 }
104#endif
105 return(rsa->meth->rsa_pub_dec(flen, from, to, rsa, padding)); 309 return(rsa->meth->rsa_pub_dec(flen, from, to, rsa, padding));
106 } 310 }
107 311
108int RSA_size(const RSA *r) 312int RSA_flags(const RSA *r)
109 { 313 {
110 return(BN_num_bytes(r->n)); 314 return((r == NULL)?0:r->meth->flags);
111 } 315 }
112 316
113void RSA_blinding_off(RSA *rsa) 317void RSA_blinding_off(RSA *rsa)
@@ -222,7 +426,7 @@ BN_BLINDING *RSA_setup_blinding(RSA *rsa, BN_CTX *in_ctx)
222 RSAerr(RSA_F_RSA_SETUP_BLINDING, ERR_R_BN_LIB); 426 RSAerr(RSA_F_RSA_SETUP_BLINDING, ERR_R_BN_LIB);
223 goto err; 427 goto err;
224 } 428 }
225 BN_BLINDING_set_thread_id(ret, CRYPTO_thread_id()); 429 CRYPTO_THREADID_current(BN_BLINDING_thread_id(ret));
226err: 430err:
227 BN_CTX_end(ctx); 431 BN_CTX_end(ctx);
228 if (in_ctx == NULL) 432 if (in_ctx == NULL)
@@ -232,3 +436,48 @@ err:
232 436
233 return ret; 437 return ret;
234} 438}
439
440int RSA_memory_lock(RSA *r)
441 {
442 int i,j,k,off;
443 char *p;
444 BIGNUM *bn,**t[6],*b;
445 BN_ULONG *ul;
446
447 if (r->d == NULL) return(1);
448 t[0]= &r->d;
449 t[1]= &r->p;
450 t[2]= &r->q;
451 t[3]= &r->dmp1;
452 t[4]= &r->dmq1;
453 t[5]= &r->iqmp;
454 k=sizeof(BIGNUM)*6;
455 off=k/sizeof(BN_ULONG)+1;
456 j=1;
457 for (i=0; i<6; i++)
458 j+= (*t[i])->top;
459 if ((p=OPENSSL_malloc_locked((off+j)*sizeof(BN_ULONG))) == NULL)
460 {
461 RSAerr(RSA_F_RSA_MEMORY_LOCK,ERR_R_MALLOC_FAILURE);
462 return(0);
463 }
464 bn=(BIGNUM *)p;
465 ul=(BN_ULONG *)&(p[off]);
466 for (i=0; i<6; i++)
467 {
468 b= *(t[i]);
469 *(t[i])= &(bn[i]);
470 memcpy((char *)&(bn[i]),(char *)b,sizeof(BIGNUM));
471 bn[i].flags=BN_FLG_STATIC_DATA;
472 bn[i].d=ul;
473 memcpy((char *)ul,b->d,sizeof(BN_ULONG)*b->top);
474 ul+=b->top;
475 BN_clear_free(b);
476 }
477
478 /* I should fix this so it can still be done */
479 r->flags&= ~(RSA_FLAG_CACHE_PRIVATE|RSA_FLAG_CACHE_PUBLIC);
480
481 r->bignum_data=p;
482 return(1);
483 }
diff --git a/src/lib/libcrypto/rsa/rsa_locl.h b/src/lib/libcrypto/rsa/rsa_locl.h
new file mode 100644
index 0000000000..f5d2d56628
--- /dev/null
+++ b/src/lib/libcrypto/rsa/rsa_locl.h
@@ -0,0 +1,4 @@
1extern int int_rsa_verify(int dtype, const unsigned char *m, unsigned int m_len,
2 unsigned char *rm, size_t *prm_len,
3 const unsigned char *sigbuf, size_t siglen,
4 RSA *rsa);
diff --git a/src/lib/libcrypto/rsa/rsa_oaep.c b/src/lib/libcrypto/rsa/rsa_oaep.c
index 4d30c9d2d3..e238d10e5c 100644
--- a/src/lib/libcrypto/rsa/rsa_oaep.c
+++ b/src/lib/libcrypto/rsa/rsa_oaep.c
@@ -28,7 +28,7 @@
28#include <openssl/rand.h> 28#include <openssl/rand.h>
29#include <openssl/sha.h> 29#include <openssl/sha.h>
30 30
31int MGF1(unsigned char *mask, long len, 31static int MGF1(unsigned char *mask, long len,
32 const unsigned char *seed, long seedlen); 32 const unsigned char *seed, long seedlen);
33 33
34int RSA_padding_add_PKCS1_OAEP(unsigned char *to, int tlen, 34int RSA_padding_add_PKCS1_OAEP(unsigned char *to, int tlen,
@@ -52,13 +52,6 @@ int RSA_padding_add_PKCS1_OAEP(unsigned char *to, int tlen,
52 return 0; 52 return 0;
53 } 53 }
54 54
55 dbmask = OPENSSL_malloc(emlen - SHA_DIGEST_LENGTH);
56 if (dbmask == NULL)
57 {
58 RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_OAEP, ERR_R_MALLOC_FAILURE);
59 return 0;
60 }
61
62 to[0] = 0; 55 to[0] = 0;
63 seed = to + 1; 56 seed = to + 1;
64 db = to + SHA_DIGEST_LENGTH + 1; 57 db = to + SHA_DIGEST_LENGTH + 1;
@@ -76,11 +69,20 @@ int RSA_padding_add_PKCS1_OAEP(unsigned char *to, int tlen,
76 20); 69 20);
77#endif 70#endif
78 71
79 MGF1(dbmask, emlen - SHA_DIGEST_LENGTH, seed, SHA_DIGEST_LENGTH); 72 dbmask = OPENSSL_malloc(emlen - SHA_DIGEST_LENGTH);
73 if (dbmask == NULL)
74 {
75 RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_OAEP, ERR_R_MALLOC_FAILURE);
76 return 0;
77 }
78
79 if (MGF1(dbmask, emlen - SHA_DIGEST_LENGTH, seed, SHA_DIGEST_LENGTH) < 0)
80 return 0;
80 for (i = 0; i < emlen - SHA_DIGEST_LENGTH; i++) 81 for (i = 0; i < emlen - SHA_DIGEST_LENGTH; i++)
81 db[i] ^= dbmask[i]; 82 db[i] ^= dbmask[i];
82 83
83 MGF1(seedmask, SHA_DIGEST_LENGTH, db, emlen - SHA_DIGEST_LENGTH); 84 if (MGF1(seedmask, SHA_DIGEST_LENGTH, db, emlen - SHA_DIGEST_LENGTH) < 0)
85 return 0;
84 for (i = 0; i < SHA_DIGEST_LENGTH; i++) 86 for (i = 0; i < SHA_DIGEST_LENGTH; i++)
85 seed[i] ^= seedmask[i]; 87 seed[i] ^= seedmask[i];
86 88
@@ -133,11 +135,13 @@ int RSA_padding_check_PKCS1_OAEP(unsigned char *to, int tlen,
133 135
134 maskeddb = padded_from + SHA_DIGEST_LENGTH; 136 maskeddb = padded_from + SHA_DIGEST_LENGTH;
135 137
136 MGF1(seed, SHA_DIGEST_LENGTH, maskeddb, dblen); 138 if (MGF1(seed, SHA_DIGEST_LENGTH, maskeddb, dblen))
139 return -1;
137 for (i = 0; i < SHA_DIGEST_LENGTH; i++) 140 for (i = 0; i < SHA_DIGEST_LENGTH; i++)
138 seed[i] ^= padded_from[i]; 141 seed[i] ^= padded_from[i];
139 142
140 MGF1(db, dblen, seed, SHA_DIGEST_LENGTH); 143 if (MGF1(db, dblen, seed, SHA_DIGEST_LENGTH))
144 return -1;
141 for (i = 0; i < dblen; i++) 145 for (i = 0; i < dblen; i++)
142 db[i] ^= maskeddb[i]; 146 db[i] ^= maskeddb[i];
143 147
@@ -187,7 +191,9 @@ int PKCS1_MGF1(unsigned char *mask, long len,
187 int mdlen; 191 int mdlen;
188 192
189 EVP_MD_CTX_init(&c); 193 EVP_MD_CTX_init(&c);
190 mdlen = M_EVP_MD_size(dgst); 194 mdlen = EVP_MD_size(dgst);
195 if (mdlen < 0)
196 return -1;
191 for (i = 0; outlen < len; i++) 197 for (i = 0; outlen < len; i++)
192 { 198 {
193 cnt[0] = (unsigned char)((i >> 24) & 255); 199 cnt[0] = (unsigned char)((i >> 24) & 255);
@@ -213,7 +219,8 @@ int PKCS1_MGF1(unsigned char *mask, long len,
213 return 0; 219 return 0;
214 } 220 }
215 221
216int MGF1(unsigned char *mask, long len, const unsigned char *seed, long seedlen) 222static int MGF1(unsigned char *mask, long len, const unsigned char *seed,
223 long seedlen)
217 { 224 {
218 return PKCS1_MGF1(mask, len, seed, seedlen, EVP_sha1()); 225 return PKCS1_MGF1(mask, len, seed, seedlen, EVP_sha1());
219 } 226 }
diff --git a/src/lib/libcrypto/rsa/rsa_pmeth.c b/src/lib/libcrypto/rsa/rsa_pmeth.c
new file mode 100644
index 0000000000..c6892ecd09
--- /dev/null
+++ b/src/lib/libcrypto/rsa/rsa_pmeth.c
@@ -0,0 +1,587 @@
1/* crypto/rsa/rsa_pmeth.c */
2/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
3 * project 2006.
4 */
5/* ====================================================================
6 * Copyright (c) 2006 The OpenSSL Project. All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 *
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 *
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in
17 * the documentation and/or other materials provided with the
18 * distribution.
19 *
20 * 3. All advertising materials mentioning features or use of this
21 * software must display the following acknowledgment:
22 * "This product includes software developed by the OpenSSL Project
23 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
24 *
25 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
26 * endorse or promote products derived from this software without
27 * prior written permission. For written permission, please contact
28 * licensing@OpenSSL.org.
29 *
30 * 5. Products derived from this software may not be called "OpenSSL"
31 * nor may "OpenSSL" appear in their names without prior written
32 * permission of the OpenSSL Project.
33 *
34 * 6. Redistributions of any form whatsoever must retain the following
35 * acknowledgment:
36 * "This product includes software developed by the OpenSSL Project
37 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
38 *
39 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
40 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
43 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
50 * OF THE POSSIBILITY OF SUCH DAMAGE.
51 * ====================================================================
52 *
53 * This product includes cryptographic software written by Eric Young
54 * (eay@cryptsoft.com). This product includes software written by Tim
55 * Hudson (tjh@cryptsoft.com).
56 *
57 */
58
59#include <stdio.h>
60#include "cryptlib.h"
61#include <openssl/asn1t.h>
62#include <openssl/x509.h>
63#include <openssl/rsa.h>
64#include <openssl/bn.h>
65#include <openssl/evp.h>
66#include "evp_locl.h"
67#include "rsa_locl.h"
68
69/* RSA pkey context structure */
70
71typedef struct
72 {
73 /* Key gen parameters */
74 int nbits;
75 BIGNUM *pub_exp;
76 /* Keygen callback info */
77 int gentmp[2];
78 /* RSA padding mode */
79 int pad_mode;
80 /* message digest */
81 const EVP_MD *md;
82 /* PSS/OAEP salt length */
83 int saltlen;
84 /* Temp buffer */
85 unsigned char *tbuf;
86 } RSA_PKEY_CTX;
87
88static int pkey_rsa_init(EVP_PKEY_CTX *ctx)
89 {
90 RSA_PKEY_CTX *rctx;
91 rctx = OPENSSL_malloc(sizeof(RSA_PKEY_CTX));
92 if (!rctx)
93 return 0;
94 rctx->nbits = 1024;
95 rctx->pub_exp = NULL;
96 rctx->pad_mode = RSA_PKCS1_PADDING;
97 rctx->md = NULL;
98 rctx->tbuf = NULL;
99
100 rctx->saltlen = -2;
101
102 ctx->data = rctx;
103 ctx->keygen_info = rctx->gentmp;
104 ctx->keygen_info_count = 2;
105
106 return 1;
107 }
108
109static int pkey_rsa_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src)
110 {
111 RSA_PKEY_CTX *dctx, *sctx;
112 if (!pkey_rsa_init(dst))
113 return 0;
114 sctx = src->data;
115 dctx = dst->data;
116 dctx->nbits = sctx->nbits;
117 if (sctx->pub_exp)
118 {
119 dctx->pub_exp = BN_dup(sctx->pub_exp);
120 if (!dctx->pub_exp)
121 return 0;
122 }
123 dctx->pad_mode = sctx->pad_mode;
124 dctx->md = sctx->md;
125 return 1;
126 }
127
128static int setup_tbuf(RSA_PKEY_CTX *ctx, EVP_PKEY_CTX *pk)
129 {
130 if (ctx->tbuf)
131 return 1;
132 ctx->tbuf = OPENSSL_malloc(EVP_PKEY_size(pk->pkey));
133 if (!ctx->tbuf)
134 return 0;
135 return 1;
136 }
137
138static void pkey_rsa_cleanup(EVP_PKEY_CTX *ctx)
139 {
140 RSA_PKEY_CTX *rctx = ctx->data;
141 if (rctx)
142 {
143 if (rctx->pub_exp)
144 BN_free(rctx->pub_exp);
145 if (rctx->tbuf)
146 OPENSSL_free(rctx->tbuf);
147 OPENSSL_free(rctx);
148 }
149 }
150
151static int pkey_rsa_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen,
152 const unsigned char *tbs, size_t tbslen)
153 {
154 int ret;
155 RSA_PKEY_CTX *rctx = ctx->data;
156 RSA *rsa = ctx->pkey->pkey.rsa;
157
158 if (rctx->md)
159 {
160 if (tbslen != (size_t)EVP_MD_size(rctx->md))
161 {
162 RSAerr(RSA_F_PKEY_RSA_SIGN,
163 RSA_R_INVALID_DIGEST_LENGTH);
164 return -1;
165 }
166 if (rctx->pad_mode == RSA_X931_PADDING)
167 {
168 if (!setup_tbuf(rctx, ctx))
169 return -1;
170 memcpy(rctx->tbuf, tbs, tbslen);
171 rctx->tbuf[tbslen] =
172 RSA_X931_hash_id(EVP_MD_type(rctx->md));
173 ret = RSA_private_encrypt(tbslen + 1, rctx->tbuf,
174 sig, rsa, RSA_X931_PADDING);
175 }
176 else if (rctx->pad_mode == RSA_PKCS1_PADDING)
177 {
178 unsigned int sltmp;
179 ret = RSA_sign(EVP_MD_type(rctx->md),
180 tbs, tbslen, sig, &sltmp, rsa);
181 if (ret <= 0)
182 return ret;
183 ret = sltmp;
184 }
185 else if (rctx->pad_mode == RSA_PKCS1_PSS_PADDING)
186 {
187 if (!setup_tbuf(rctx, ctx))
188 return -1;
189 if (!RSA_padding_add_PKCS1_PSS(rsa, rctx->tbuf, tbs,
190 rctx->md, rctx->saltlen))
191 return -1;
192 ret = RSA_private_encrypt(RSA_size(rsa), rctx->tbuf,
193 sig, rsa, RSA_NO_PADDING);
194 }
195 else
196 return -1;
197 }
198 else
199 ret = RSA_private_encrypt(tbslen, tbs, sig, ctx->pkey->pkey.rsa,
200 rctx->pad_mode);
201 if (ret < 0)
202 return ret;
203 *siglen = ret;
204 return 1;
205 }
206
207
208static int pkey_rsa_verifyrecover(EVP_PKEY_CTX *ctx,
209 unsigned char *rout, size_t *routlen,
210 const unsigned char *sig, size_t siglen)
211 {
212 int ret;
213 RSA_PKEY_CTX *rctx = ctx->data;
214
215 if (rctx->md)
216 {
217 if (rctx->pad_mode == RSA_X931_PADDING)
218 {
219 if (!setup_tbuf(rctx, ctx))
220 return -1;
221 ret = RSA_public_decrypt(siglen, sig,
222 rctx->tbuf, ctx->pkey->pkey.rsa,
223 RSA_X931_PADDING);
224 if (ret < 1)
225 return 0;
226 ret--;
227 if (rctx->tbuf[ret] !=
228 RSA_X931_hash_id(EVP_MD_type(rctx->md)))
229 {
230 RSAerr(RSA_F_PKEY_RSA_VERIFYRECOVER,
231 RSA_R_ALGORITHM_MISMATCH);
232 return 0;
233 }
234 if (ret != EVP_MD_size(rctx->md))
235 {
236 RSAerr(RSA_F_PKEY_RSA_VERIFYRECOVER,
237 RSA_R_INVALID_DIGEST_LENGTH);
238 return 0;
239 }
240 if (rout)
241 memcpy(rout, rctx->tbuf, ret);
242 }
243 else if (rctx->pad_mode == RSA_PKCS1_PADDING)
244 {
245 size_t sltmp;
246 ret = int_rsa_verify(EVP_MD_type(rctx->md),
247 NULL, 0, rout, &sltmp,
248 sig, siglen, ctx->pkey->pkey.rsa);
249 if (ret <= 0)
250 return 0;
251 ret = sltmp;
252 }
253 else
254 return -1;
255 }
256 else
257 ret = RSA_public_decrypt(siglen, sig, rout, ctx->pkey->pkey.rsa,
258 rctx->pad_mode);
259 if (ret < 0)
260 return ret;
261 *routlen = ret;
262 return 1;
263 }
264
265static int pkey_rsa_verify(EVP_PKEY_CTX *ctx,
266 const unsigned char *sig, size_t siglen,
267 const unsigned char *tbs, size_t tbslen)
268 {
269 RSA_PKEY_CTX *rctx = ctx->data;
270 RSA *rsa = ctx->pkey->pkey.rsa;
271 size_t rslen;
272 if (rctx->md)
273 {
274 if (rctx->pad_mode == RSA_PKCS1_PADDING)
275 return RSA_verify(EVP_MD_type(rctx->md), tbs, tbslen,
276 sig, siglen, rsa);
277 if (rctx->pad_mode == RSA_X931_PADDING)
278 {
279 if (pkey_rsa_verifyrecover(ctx, NULL, &rslen,
280 sig, siglen) <= 0)
281 return 0;
282 }
283 else if (rctx->pad_mode == RSA_PKCS1_PSS_PADDING)
284 {
285 int ret;
286 if (!setup_tbuf(rctx, ctx))
287 return -1;
288 ret = RSA_public_decrypt(siglen, sig, rctx->tbuf,
289 rsa, RSA_NO_PADDING);
290 if (ret <= 0)
291 return 0;
292 ret = RSA_verify_PKCS1_PSS(rsa, tbs, rctx->md,
293 rctx->tbuf, rctx->saltlen);
294 if (ret <= 0)
295 return 0;
296 return 1;
297 }
298 else
299 return -1;
300 }
301 else
302 {
303 if (!setup_tbuf(rctx, ctx))
304 return -1;
305 rslen = RSA_public_decrypt(siglen, sig, rctx->tbuf,
306 rsa, rctx->pad_mode);
307 if (rslen == 0)
308 return 0;
309 }
310
311 if ((rslen != tbslen) || memcmp(tbs, rctx->tbuf, rslen))
312 return 0;
313
314 return 1;
315
316 }
317
318
319static int pkey_rsa_encrypt(EVP_PKEY_CTX *ctx,
320 unsigned char *out, size_t *outlen,
321 const unsigned char *in, size_t inlen)
322 {
323 int ret;
324 RSA_PKEY_CTX *rctx = ctx->data;
325 ret = RSA_public_encrypt(inlen, in, out, ctx->pkey->pkey.rsa,
326 rctx->pad_mode);
327 if (ret < 0)
328 return ret;
329 *outlen = ret;
330 return 1;
331 }
332
333static int pkey_rsa_decrypt(EVP_PKEY_CTX *ctx,
334 unsigned char *out, size_t *outlen,
335 const unsigned char *in, size_t inlen)
336 {
337 int ret;
338 RSA_PKEY_CTX *rctx = ctx->data;
339 ret = RSA_private_decrypt(inlen, in, out, ctx->pkey->pkey.rsa,
340 rctx->pad_mode);
341 if (ret < 0)
342 return ret;
343 *outlen = ret;
344 return 1;
345 }
346
347static int check_padding_md(const EVP_MD *md, int padding)
348 {
349 if (!md)
350 return 1;
351
352 if (padding == RSA_NO_PADDING)
353 {
354 RSAerr(RSA_F_CHECK_PADDING_MD, RSA_R_INVALID_PADDING_MODE);
355 return 0;
356 }
357
358 if (padding == RSA_X931_PADDING)
359 {
360 if (RSA_X931_hash_id(EVP_MD_type(md)) == -1)
361 {
362 RSAerr(RSA_F_CHECK_PADDING_MD,
363 RSA_R_INVALID_X931_DIGEST);
364 return 0;
365 }
366 return 1;
367 }
368
369 return 1;
370 }
371
372
373static int pkey_rsa_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
374 {
375 RSA_PKEY_CTX *rctx = ctx->data;
376 switch (type)
377 {
378 case EVP_PKEY_CTRL_RSA_PADDING:
379 if ((p1 >= RSA_PKCS1_PADDING) && (p1 <= RSA_PKCS1_PSS_PADDING))
380 {
381 if (!check_padding_md(rctx->md, p1))
382 return 0;
383 if (p1 == RSA_PKCS1_PSS_PADDING)
384 {
385 if (!(ctx->operation &
386 (EVP_PKEY_OP_SIGN | EVP_PKEY_OP_VERIFY)))
387 goto bad_pad;
388 if (!rctx->md)
389 rctx->md = EVP_sha1();
390 }
391 if (p1 == RSA_PKCS1_OAEP_PADDING)
392 {
393 if (!(ctx->operation & EVP_PKEY_OP_TYPE_CRYPT))
394 goto bad_pad;
395 if (!rctx->md)
396 rctx->md = EVP_sha1();
397 }
398 rctx->pad_mode = p1;
399 return 1;
400 }
401 bad_pad:
402 RSAerr(RSA_F_PKEY_RSA_CTRL,
403 RSA_R_ILLEGAL_OR_UNSUPPORTED_PADDING_MODE);
404 return -2;
405
406 case EVP_PKEY_CTRL_RSA_PSS_SALTLEN:
407 if (p1 < -2)
408 return -2;
409 if (rctx->pad_mode != RSA_PKCS1_PSS_PADDING)
410 {
411 RSAerr(RSA_F_PKEY_RSA_CTRL, RSA_R_INVALID_PSS_SALTLEN);
412 return -2;
413 }
414 rctx->saltlen = p1;
415 return 1;
416
417 case EVP_PKEY_CTRL_RSA_KEYGEN_BITS:
418 if (p1 < 256)
419 {
420 RSAerr(RSA_F_PKEY_RSA_CTRL, RSA_R_INVALID_KEYBITS);
421 return -2;
422 }
423 rctx->nbits = p1;
424 return 1;
425
426 case EVP_PKEY_CTRL_RSA_KEYGEN_PUBEXP:
427 if (!p2)
428 return -2;
429 rctx->pub_exp = p2;
430 return 1;
431
432 case EVP_PKEY_CTRL_MD:
433 if (!check_padding_md(p2, rctx->pad_mode))
434 return 0;
435 rctx->md = p2;
436 return 1;
437
438 case EVP_PKEY_CTRL_DIGESTINIT:
439 case EVP_PKEY_CTRL_PKCS7_ENCRYPT:
440 case EVP_PKEY_CTRL_PKCS7_DECRYPT:
441 case EVP_PKEY_CTRL_PKCS7_SIGN:
442#ifndef OPENSSL_NO_CMS
443 case EVP_PKEY_CTRL_CMS_ENCRYPT:
444 case EVP_PKEY_CTRL_CMS_DECRYPT:
445 case EVP_PKEY_CTRL_CMS_SIGN:
446#endif
447 return 1;
448 case EVP_PKEY_CTRL_PEER_KEY:
449 RSAerr(RSA_F_PKEY_RSA_CTRL,
450 RSA_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
451 return -2;
452
453 default:
454 return -2;
455
456 }
457 }
458
459static int pkey_rsa_ctrl_str(EVP_PKEY_CTX *ctx,
460 const char *type, const char *value)
461 {
462 if (!value)
463 {
464 RSAerr(RSA_F_PKEY_RSA_CTRL_STR, RSA_R_VALUE_MISSING);
465 return 0;
466 }
467 if (!strcmp(type, "rsa_padding_mode"))
468 {
469 int pm;
470 if (!strcmp(value, "pkcs1"))
471 pm = RSA_PKCS1_PADDING;
472 else if (!strcmp(value, "sslv23"))
473 pm = RSA_SSLV23_PADDING;
474 else if (!strcmp(value, "none"))
475 pm = RSA_NO_PADDING;
476 else if (!strcmp(value, "oeap"))
477 pm = RSA_PKCS1_OAEP_PADDING;
478 else if (!strcmp(value, "x931"))
479 pm = RSA_X931_PADDING;
480 else if (!strcmp(value, "pss"))
481 pm = RSA_PKCS1_PSS_PADDING;
482 else
483 {
484 RSAerr(RSA_F_PKEY_RSA_CTRL_STR,
485 RSA_R_UNKNOWN_PADDING_TYPE);
486 return -2;
487 }
488 return EVP_PKEY_CTX_set_rsa_padding(ctx, pm);
489 }
490
491 if (!strcmp(type, "rsa_pss_saltlen"))
492 {
493 int saltlen;
494 saltlen = atoi(value);
495 return EVP_PKEY_CTX_set_rsa_pss_saltlen(ctx, saltlen);
496 }
497
498 if (!strcmp(type, "rsa_keygen_bits"))
499 {
500 int nbits;
501 nbits = atoi(value);
502 return EVP_PKEY_CTX_set_rsa_keygen_bits(ctx, nbits);
503 }
504
505 if (!strcmp(type, "rsa_keygen_pubexp"))
506 {
507 int ret;
508 BIGNUM *pubexp = NULL;
509 if (!BN_asc2bn(&pubexp, value))
510 return 0;
511 ret = EVP_PKEY_CTX_set_rsa_keygen_pubexp(ctx, pubexp);
512 if (ret <= 0)
513 BN_free(pubexp);
514 return ret;
515 }
516
517 return -2;
518 }
519
520static int pkey_rsa_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
521 {
522 RSA *rsa = NULL;
523 RSA_PKEY_CTX *rctx = ctx->data;
524 BN_GENCB *pcb, cb;
525 int ret;
526 if (!rctx->pub_exp)
527 {
528 rctx->pub_exp = BN_new();
529 if (!rctx->pub_exp || !BN_set_word(rctx->pub_exp, RSA_F4))
530 return 0;
531 }
532 rsa = RSA_new();
533 if (!rsa)
534 return 0;
535 if (ctx->pkey_gencb)
536 {
537 pcb = &cb;
538 evp_pkey_set_cb_translate(pcb, ctx);
539 }
540 else
541 pcb = NULL;
542 ret = RSA_generate_key_ex(rsa, rctx->nbits, rctx->pub_exp, pcb);
543 if (ret > 0)
544 EVP_PKEY_assign_RSA(pkey, rsa);
545 else
546 RSA_free(rsa);
547 return ret;
548 }
549
550const EVP_PKEY_METHOD rsa_pkey_meth =
551 {
552 EVP_PKEY_RSA,
553 EVP_PKEY_FLAG_AUTOARGLEN,
554 pkey_rsa_init,
555 pkey_rsa_copy,
556 pkey_rsa_cleanup,
557
558 0,0,
559
560 0,
561 pkey_rsa_keygen,
562
563 0,
564 pkey_rsa_sign,
565
566 0,
567 pkey_rsa_verify,
568
569 0,
570 pkey_rsa_verifyrecover,
571
572
573 0,0,0,0,
574
575 0,
576 pkey_rsa_encrypt,
577
578 0,
579 pkey_rsa_decrypt,
580
581 0,0,
582
583 pkey_rsa_ctrl,
584 pkey_rsa_ctrl_str
585
586
587 };
diff --git a/src/lib/libcrypto/rsa/rsa_prn.c b/src/lib/libcrypto/rsa/rsa_prn.c
new file mode 100644
index 0000000000..224db0fae5
--- /dev/null
+++ b/src/lib/libcrypto/rsa/rsa_prn.c
@@ -0,0 +1,93 @@
1/* crypto/rsa/rsa_prn.c */
2/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
3 * project 2006.
4 */
5/* ====================================================================
6 * Copyright (c) 2006 The OpenSSL Project. All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 *
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 *
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in
17 * the documentation and/or other materials provided with the
18 * distribution.
19 *
20 * 3. All advertising materials mentioning features or use of this
21 * software must display the following acknowledgment:
22 * "This product includes software developed by the OpenSSL Project
23 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
24 *
25 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
26 * endorse or promote products derived from this software without
27 * prior written permission. For written permission, please contact
28 * licensing@OpenSSL.org.
29 *
30 * 5. Products derived from this software may not be called "OpenSSL"
31 * nor may "OpenSSL" appear in their names without prior written
32 * permission of the OpenSSL Project.
33 *
34 * 6. Redistributions of any form whatsoever must retain the following
35 * acknowledgment:
36 * "This product includes software developed by the OpenSSL Project
37 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
38 *
39 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
40 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
43 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
50 * OF THE POSSIBILITY OF SUCH DAMAGE.
51 * ====================================================================
52 *
53 * This product includes cryptographic software written by Eric Young
54 * (eay@cryptsoft.com). This product includes software written by Tim
55 * Hudson (tjh@cryptsoft.com).
56 *
57 */
58
59#include <stdio.h>
60#include "cryptlib.h"
61#include <openssl/rsa.h>
62#include <openssl/evp.h>
63
64#ifndef OPENSSL_NO_FP_API
65int RSA_print_fp(FILE *fp, const RSA *x, int off)
66 {
67 BIO *b;
68 int ret;
69
70 if ((b=BIO_new(BIO_s_file())) == NULL)
71 {
72 RSAerr(RSA_F_RSA_PRINT_FP,ERR_R_BUF_LIB);
73 return(0);
74 }
75 BIO_set_fp(b,fp,BIO_NOCLOSE);
76 ret=RSA_print(b,x,off);
77 BIO_free(b);
78 return(ret);
79 }
80#endif
81
82int RSA_print(BIO *bp, const RSA *x, int off)
83 {
84 EVP_PKEY *pk;
85 int ret;
86 pk = EVP_PKEY_new();
87 if (!pk || !EVP_PKEY_set1_RSA(pk, (RSA *)x))
88 return 0;
89 ret = EVP_PKEY_print_private(bp, pk, off, NULL);
90 EVP_PKEY_free(pk);
91 return ret;
92 }
93
diff --git a/src/lib/libcrypto/rsa/rsa_pss.c b/src/lib/libcrypto/rsa/rsa_pss.c
index 9b993aca49..ac211e2ffe 100644
--- a/src/lib/libcrypto/rsa/rsa_pss.c
+++ b/src/lib/libcrypto/rsa/rsa_pss.c
@@ -81,7 +81,9 @@ int RSA_verify_PKCS1_PSS(RSA *rsa, const unsigned char *mHash,
81 EVP_MD_CTX ctx; 81 EVP_MD_CTX ctx;
82 unsigned char H_[EVP_MAX_MD_SIZE]; 82 unsigned char H_[EVP_MAX_MD_SIZE];
83 83
84 hLen = M_EVP_MD_size(Hash); 84 hLen = EVP_MD_size(Hash);
85 if (hLen < 0)
86 goto err;
85 /* 87 /*
86 * Negative sLen has special meanings: 88 * Negative sLen has special meanings:
87 * -1 sLen == hLen 89 * -1 sLen == hLen
@@ -126,7 +128,8 @@ int RSA_verify_PKCS1_PSS(RSA *rsa, const unsigned char *mHash,
126 RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS, ERR_R_MALLOC_FAILURE); 128 RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS, ERR_R_MALLOC_FAILURE);
127 goto err; 129 goto err;
128 } 130 }
129 PKCS1_MGF1(DB, maskedDBLen, H, hLen, Hash); 131 if (PKCS1_MGF1(DB, maskedDBLen, H, hLen, Hash) < 0)
132 goto err;
130 for (i = 0; i < maskedDBLen; i++) 133 for (i = 0; i < maskedDBLen; i++)
131 DB[i] ^= EM[i]; 134 DB[i] ^= EM[i];
132 if (MSBits) 135 if (MSBits)
@@ -176,7 +179,9 @@ int RSA_padding_add_PKCS1_PSS(RSA *rsa, unsigned char *EM,
176 unsigned char *H, *salt = NULL, *p; 179 unsigned char *H, *salt = NULL, *p;
177 EVP_MD_CTX ctx; 180 EVP_MD_CTX ctx;
178 181
179 hLen = M_EVP_MD_size(Hash); 182 hLen = EVP_MD_size(Hash);
183 if (hLen < 0)
184 goto err;
180 /* 185 /*
181 * Negative sLen has special meanings: 186 * Negative sLen has special meanings:
182 * -1 sLen == hLen 187 * -1 sLen == hLen
@@ -217,7 +222,7 @@ int RSA_padding_add_PKCS1_PSS(RSA *rsa, unsigned char *EM,
217 ERR_R_MALLOC_FAILURE); 222 ERR_R_MALLOC_FAILURE);
218 goto err; 223 goto err;
219 } 224 }
220 if (!RAND_bytes(salt, sLen)) 225 if (RAND_bytes(salt, sLen) <= 0)
221 goto err; 226 goto err;
222 } 227 }
223 maskedDBLen = emLen - hLen - 1; 228 maskedDBLen = emLen - hLen - 1;
@@ -232,7 +237,8 @@ int RSA_padding_add_PKCS1_PSS(RSA *rsa, unsigned char *EM,
232 EVP_MD_CTX_cleanup(&ctx); 237 EVP_MD_CTX_cleanup(&ctx);
233 238
234 /* Generate dbMask in place then perform XOR on it */ 239 /* Generate dbMask in place then perform XOR on it */
235 PKCS1_MGF1(EM, maskedDBLen, H, hLen, Hash); 240 if (PKCS1_MGF1(EM, maskedDBLen, H, hLen, Hash))
241 goto err;
236 242
237 p = EM; 243 p = EM;
238 244
diff --git a/src/lib/libcrypto/rsa/rsa_sign.c b/src/lib/libcrypto/rsa/rsa_sign.c
index 5488c06f6d..0be4ec7fb0 100644
--- a/src/lib/libcrypto/rsa/rsa_sign.c
+++ b/src/lib/libcrypto/rsa/rsa_sign.c
@@ -62,6 +62,7 @@
62#include <openssl/rsa.h> 62#include <openssl/rsa.h>
63#include <openssl/objects.h> 63#include <openssl/objects.h>
64#include <openssl/x509.h> 64#include <openssl/x509.h>
65#include "rsa_locl.h"
65 66
66/* Size of an SSL signature: MD5+SHA1 */ 67/* Size of an SSL signature: MD5+SHA1 */
67#define SSL_SIG_LENGTH 36 68#define SSL_SIG_LENGTH 36
@@ -90,14 +91,6 @@ int RSA_sign(int type, const unsigned char *m, unsigned int m_len,
90 i = SSL_SIG_LENGTH; 91 i = SSL_SIG_LENGTH;
91 s = m; 92 s = m;
92 } else { 93 } else {
93 /* NB: in FIPS mode block anything that isn't a TLS signature */
94#ifdef OPENSSL_FIPS
95 if(FIPS_mode() && !(rsa->flags & RSA_FLAG_NON_FIPS_ALLOW))
96 {
97 RSAerr(RSA_F_RSA_SIGN, RSA_R_OPERATION_NOT_ALLOWED_IN_FIPS_MODE);
98 return 0;
99 }
100#endif
101 sig.algor= &algor; 94 sig.algor= &algor;
102 sig.algor->algorithm=OBJ_nid2obj(type); 95 sig.algor->algorithm=OBJ_nid2obj(type);
103 if (sig.algor->algorithm == NULL) 96 if (sig.algor->algorithm == NULL)
@@ -150,8 +143,11 @@ int RSA_sign(int type, const unsigned char *m, unsigned int m_len,
150 return(ret); 143 return(ret);
151 } 144 }
152 145
153int RSA_verify(int dtype, const unsigned char *m, unsigned int m_len, 146int int_rsa_verify(int dtype, const unsigned char *m,
154 unsigned char *sigbuf, unsigned int siglen, RSA *rsa) 147 unsigned int m_len,
148 unsigned char *rm, size_t *prm_len,
149 const unsigned char *sigbuf, size_t siglen,
150 RSA *rsa)
155 { 151 {
156 int i,ret=0,sigtype; 152 int i,ret=0,sigtype;
157 unsigned char *s; 153 unsigned char *s;
@@ -159,38 +155,30 @@ int RSA_verify(int dtype, const unsigned char *m, unsigned int m_len,
159 155
160 if (siglen != (unsigned int)RSA_size(rsa)) 156 if (siglen != (unsigned int)RSA_size(rsa))
161 { 157 {
162 RSAerr(RSA_F_RSA_VERIFY,RSA_R_WRONG_SIGNATURE_LENGTH); 158 RSAerr(RSA_F_INT_RSA_VERIFY,RSA_R_WRONG_SIGNATURE_LENGTH);
163 return(0); 159 return(0);
164 } 160 }
165 161
166 if((rsa->flags & RSA_FLAG_SIGN_VER) && rsa->meth->rsa_verify) 162 if((dtype == NID_md5_sha1) && rm)
167 { 163 {
168 return rsa->meth->rsa_verify(dtype, m, m_len, 164 i = RSA_public_decrypt((int)siglen,
169 sigbuf, siglen, rsa); 165 sigbuf,rm,rsa,RSA_PKCS1_PADDING);
166 if (i <= 0)
167 return 0;
168 *prm_len = i;
169 return 1;
170 } 170 }
171 171
172 s=(unsigned char *)OPENSSL_malloc((unsigned int)siglen); 172 s=(unsigned char *)OPENSSL_malloc((unsigned int)siglen);
173 if (s == NULL) 173 if (s == NULL)
174 { 174 {
175 RSAerr(RSA_F_RSA_VERIFY,ERR_R_MALLOC_FAILURE); 175 RSAerr(RSA_F_INT_RSA_VERIFY,ERR_R_MALLOC_FAILURE);
176 goto err; 176 goto err;
177 } 177 }
178 if(dtype == NID_md5_sha1) 178 if((dtype == NID_md5_sha1) && (m_len != SSL_SIG_LENGTH) ) {
179 { 179 RSAerr(RSA_F_INT_RSA_VERIFY,RSA_R_INVALID_MESSAGE_LENGTH);
180 if (m_len != SSL_SIG_LENGTH)
181 {
182 RSAerr(RSA_F_RSA_VERIFY,RSA_R_INVALID_MESSAGE_LENGTH);
183 goto err; 180 goto err;
184 } 181 }
185 }
186 /* NB: in FIPS mode block anything that isn't a TLS signature */
187#ifdef OPENSSL_FIPS
188 else if(FIPS_mode() && !(rsa->flags & RSA_FLAG_NON_FIPS_ALLOW))
189 {
190 RSAerr(RSA_F_RSA_VERIFY, RSA_R_OPERATION_NOT_ALLOWED_IN_FIPS_MODE);
191 return 0;
192 }
193#endif
194 i=RSA_public_decrypt((int)siglen,sigbuf,s,rsa,RSA_PKCS1_PADDING); 182 i=RSA_public_decrypt((int)siglen,sigbuf,s,rsa,RSA_PKCS1_PADDING);
195 183
196 if (i <= 0) goto err; 184 if (i <= 0) goto err;
@@ -198,7 +186,7 @@ int RSA_verify(int dtype, const unsigned char *m, unsigned int m_len,
198 /* Special case: SSL signature */ 186 /* Special case: SSL signature */
199 if(dtype == NID_md5_sha1) { 187 if(dtype == NID_md5_sha1) {
200 if((i != SSL_SIG_LENGTH) || memcmp(s, m, SSL_SIG_LENGTH)) 188 if((i != SSL_SIG_LENGTH) || memcmp(s, m, SSL_SIG_LENGTH))
201 RSAerr(RSA_F_RSA_VERIFY,RSA_R_BAD_SIGNATURE); 189 RSAerr(RSA_F_INT_RSA_VERIFY,RSA_R_BAD_SIGNATURE);
202 else ret = 1; 190 else ret = 1;
203 } else { 191 } else {
204 const unsigned char *p=s; 192 const unsigned char *p=s;
@@ -209,7 +197,7 @@ int RSA_verify(int dtype, const unsigned char *m, unsigned int m_len,
209 /* Excess data can be used to create forgeries */ 197 /* Excess data can be used to create forgeries */
210 if(p != s+i) 198 if(p != s+i)
211 { 199 {
212 RSAerr(RSA_F_RSA_VERIFY,RSA_R_BAD_SIGNATURE); 200 RSAerr(RSA_F_INT_RSA_VERIFY,RSA_R_BAD_SIGNATURE);
213 goto err; 201 goto err;
214 } 202 }
215 203
@@ -218,7 +206,7 @@ int RSA_verify(int dtype, const unsigned char *m, unsigned int m_len,
218 if(sig->algor->parameter 206 if(sig->algor->parameter
219 && ASN1_TYPE_get(sig->algor->parameter) != V_ASN1_NULL) 207 && ASN1_TYPE_get(sig->algor->parameter) != V_ASN1_NULL)
220 { 208 {
221 RSAerr(RSA_F_RSA_VERIFY,RSA_R_BAD_SIGNATURE); 209 RSAerr(RSA_F_INT_RSA_VERIFY,RSA_R_BAD_SIGNATURE);
222 goto err; 210 goto err;
223 } 211 }
224 212
@@ -244,15 +232,30 @@ int RSA_verify(int dtype, const unsigned char *m, unsigned int m_len,
244 } 232 }
245 else 233 else
246 { 234 {
247 RSAerr(RSA_F_RSA_VERIFY, 235 RSAerr(RSA_F_INT_RSA_VERIFY,
248 RSA_R_ALGORITHM_MISMATCH); 236 RSA_R_ALGORITHM_MISMATCH);
249 goto err; 237 goto err;
250 } 238 }
251 } 239 }
252 if ( ((unsigned int)sig->digest->length != m_len) || 240 if (rm)
241 {
242 const EVP_MD *md;
243 md = EVP_get_digestbynid(dtype);
244 if (md && (EVP_MD_size(md) != sig->digest->length))
245 RSAerr(RSA_F_INT_RSA_VERIFY,
246 RSA_R_INVALID_DIGEST_LENGTH);
247 else
248 {
249 memcpy(rm, sig->digest->data,
250 sig->digest->length);
251 *prm_len = sig->digest->length;
252 ret = 1;
253 }
254 }
255 else if (((unsigned int)sig->digest->length != m_len) ||
253 (memcmp(m,sig->digest->data,m_len) != 0)) 256 (memcmp(m,sig->digest->data,m_len) != 0))
254 { 257 {
255 RSAerr(RSA_F_RSA_VERIFY,RSA_R_BAD_SIGNATURE); 258 RSAerr(RSA_F_INT_RSA_VERIFY,RSA_R_BAD_SIGNATURE);
256 } 259 }
257 else 260 else
258 ret=1; 261 ret=1;
@@ -267,3 +270,16 @@ err:
267 return(ret); 270 return(ret);
268 } 271 }
269 272
273int RSA_verify(int dtype, const unsigned char *m, unsigned int m_len,
274 const unsigned char *sigbuf, unsigned int siglen,
275 RSA *rsa)
276 {
277
278 if((rsa->flags & RSA_FLAG_SIGN_VER) && rsa->meth->rsa_verify)
279 {
280 return rsa->meth->rsa_verify(dtype, m, m_len,
281 sigbuf, siglen, rsa);
282 }
283
284 return int_rsa_verify(dtype, m, m_len, NULL, NULL, sigbuf, siglen, rsa);
285 }
diff --git a/src/lib/libcrypto/s390xcap.c b/src/lib/libcrypto/s390xcap.c
new file mode 100644
index 0000000000..ffbe0235f9
--- /dev/null
+++ b/src/lib/libcrypto/s390xcap.c
@@ -0,0 +1,37 @@
1#include <stdio.h>
2#include <stdlib.h>
3#include <string.h>
4#include <setjmp.h>
5#include <signal.h>
6
7extern unsigned long OPENSSL_s390xcap_P;
8
9static sigjmp_buf ill_jmp;
10static void ill_handler (int sig) { siglongjmp(ill_jmp,sig); }
11
12unsigned long OPENSSL_s390x_facilities(void);
13
14void OPENSSL_cpuid_setup(void)
15 {
16 sigset_t oset;
17 struct sigaction ill_act,oact;
18
19 if (OPENSSL_s390xcap_P) return;
20
21 memset(&ill_act,0,sizeof(ill_act));
22 ill_act.sa_handler = ill_handler;
23 sigfillset(&ill_act.sa_mask);
24 sigdelset(&ill_act.sa_mask,SIGILL);
25 sigdelset(&ill_act.sa_mask,SIGTRAP);
26 sigprocmask(SIG_SETMASK,&ill_act.sa_mask,&oset);
27 sigaction (SIGILL,&ill_act,&oact);
28
29 /* protection against missing store-facility-list-extended */
30 if (sigsetjmp(ill_jmp,0) == 0)
31 OPENSSL_s390xcap_P = OPENSSL_s390x_facilities();
32 else
33 OPENSSL_s390xcap_P = 1UL<<63;
34
35 sigaction (SIGILL,&oact,NULL);
36 sigprocmask(SIG_SETMASK,&oset,NULL);
37 }
diff --git a/src/lib/libcrypto/s390xcpuid.S b/src/lib/libcrypto/s390xcpuid.S
index 8500133ad0..b053c6a281 100644
--- a/src/lib/libcrypto/s390xcpuid.S
+++ b/src/lib/libcrypto/s390xcpuid.S
@@ -1,12 +1,5 @@
1.text 1.text
2 2
3.globl OPENSSL_cpuid_setup
4.type OPENSSL_cpuid_setup,@function
5.align 16
6OPENSSL_cpuid_setup:
7 br %r14 # reserved for future
8.size OPENSSL_cpuid_setup,.-OPENSSL_cpuid_setup
9
10.globl OPENSSL_s390x_facilities 3.globl OPENSSL_s390x_facilities
11.type OPENSSL_s390x_facilities,@function 4.type OPENSSL_s390x_facilities,@function
12.align 16 5.align 16
@@ -14,6 +7,8 @@ OPENSSL_s390x_facilities:
14 lghi %r0,0 7 lghi %r0,0
15 .long 0xb2b0f010 # stfle 16(%r15) 8 .long 0xb2b0f010 # stfle 16(%r15)
16 lg %r2,16(%r15) 9 lg %r2,16(%r15)
10 larl %r1,OPENSSL_s390xcap_P
11 stg %r2,0(%r1)
17 br %r14 12 br %r14
18.size OPENSSL_s390x_facilities,.-OPENSSL_s390x_facilities 13.size OPENSSL_s390x_facilities,.-OPENSSL_s390x_facilities
19 14
@@ -67,6 +62,8 @@ OPENSSL_cleanse:
67 lghi %r0,0 62 lghi %r0,0
68 clgr %r3,%r4 63 clgr %r3,%r4
69 jh .Lot 64 jh .Lot
65 clgr %r3,%r0
66 bcr 8,%r14
70.Little: 67.Little:
71 stc %r0,0(%r2) 68 stc %r0,0(%r2)
72 la %r2,1(%r2) 69 la %r2,1(%r2)
@@ -88,3 +85,8 @@ OPENSSL_cleanse:
88 jnz .Little 85 jnz .Little
89 br %r14 86 br %r14
90.size OPENSSL_cleanse,.-OPENSSL_cleanse 87.size OPENSSL_cleanse,.-OPENSSL_cleanse
88
89.section .init
90 brasl %r14,OPENSSL_cpuid_setup
91
92.comm OPENSSL_s390xcap_P,8,8
diff --git a/src/lib/libcrypto/sha/asm/sha1-586.pl b/src/lib/libcrypto/sha/asm/sha1-586.pl
index a787dd37da..a1f876281a 100644
--- a/src/lib/libcrypto/sha/asm/sha1-586.pl
+++ b/src/lib/libcrypto/sha/asm/sha1-586.pl
@@ -215,5 +215,6 @@ sub BODY_40_59
215 215
216 &stack_pop(16); 216 &stack_pop(16);
217&function_end("sha1_block_data_order"); 217&function_end("sha1_block_data_order");
218&asciz("SHA1 block transform for x86, CRYPTOGAMS by <appro\@openssl.org>");
218 219
219&asm_finish(); 220&asm_finish();
diff --git a/src/lib/libcrypto/sha/asm/sha1-armv4-large.pl b/src/lib/libcrypto/sha/asm/sha1-armv4-large.pl
new file mode 100644
index 0000000000..88861af641
--- /dev/null
+++ b/src/lib/libcrypto/sha/asm/sha1-armv4-large.pl
@@ -0,0 +1,234 @@
1#!/usr/bin/env perl
2
3# ====================================================================
4# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
5# project. The module is, however, dual licensed under OpenSSL and
6# CRYPTOGAMS licenses depending on where you obtain it. For further
7# details see http://www.openssl.org/~appro/cryptogams/.
8# ====================================================================
9
10# sha1_block procedure for ARMv4.
11#
12# January 2007.
13
14# Size/performance trade-off
15# ====================================================================
16# impl size in bytes comp cycles[*] measured performance
17# ====================================================================
18# thumb 304 3212 4420
19# armv4-small 392/+29% 1958/+64% 2250/+96%
20# armv4-compact 740/+89% 1552/+26% 1840/+22%
21# armv4-large 1420/+92% 1307/+19% 1370/+34%[***]
22# full unroll ~5100/+260% ~1260/+4% ~1300/+5%
23# ====================================================================
24# thumb = same as 'small' but in Thumb instructions[**] and
25# with recurring code in two private functions;
26# small = detached Xload/update, loops are folded;
27# compact = detached Xload/update, 5x unroll;
28# large = interleaved Xload/update, 5x unroll;
29# full unroll = interleaved Xload/update, full unroll, estimated[!];
30#
31# [*] Manually counted instructions in "grand" loop body. Measured
32# performance is affected by prologue and epilogue overhead,
33# i-cache availability, branch penalties, etc.
34# [**] While each Thumb instruction is twice smaller, they are not as
35# diverse as ARM ones: e.g., there are only two arithmetic
36# instructions with 3 arguments, no [fixed] rotate, addressing
37# modes are limited. As result it takes more instructions to do
38# the same job in Thumb, therefore the code is never twice as
39# small and always slower.
40# [***] which is also ~35% better than compiler generated code.
41
42$output=shift;
43open STDOUT,">$output";
44
45$ctx="r0";
46$inp="r1";
47$len="r2";
48$a="r3";
49$b="r4";
50$c="r5";
51$d="r6";
52$e="r7";
53$K="r8";
54$t0="r9";
55$t1="r10";
56$t2="r11";
57$t3="r12";
58$Xi="r14";
59@V=($a,$b,$c,$d,$e);
60
61# One can optimize this for aligned access on big-endian architecture,
62# but code's endian neutrality makes it too pretty:-)
63sub Xload {
64my ($a,$b,$c,$d,$e)=@_;
65$code.=<<___;
66 ldrb $t0,[$inp],#4
67 ldrb $t1,[$inp,#-3]
68 ldrb $t2,[$inp,#-2]
69 ldrb $t3,[$inp,#-1]
70 add $e,$K,$e,ror#2 @ E+=K_00_19
71 orr $t0,$t1,$t0,lsl#8
72 add $e,$e,$a,ror#27 @ E+=ROR(A,27)
73 orr $t0,$t2,$t0,lsl#8
74 eor $t1,$c,$d @ F_xx_xx
75 orr $t0,$t3,$t0,lsl#8
76 add $e,$e,$t0 @ E+=X[i]
77 str $t0,[$Xi,#-4]!
78___
79}
80sub Xupdate {
81my ($a,$b,$c,$d,$e,$flag)=@_;
82$code.=<<___;
83 ldr $t0,[$Xi,#15*4]
84 ldr $t1,[$Xi,#13*4]
85 ldr $t2,[$Xi,#7*4]
86 ldr $t3,[$Xi,#2*4]
87 add $e,$K,$e,ror#2 @ E+=K_xx_xx
88 eor $t0,$t0,$t1
89 eor $t0,$t0,$t2
90 eor $t0,$t0,$t3
91 add $e,$e,$a,ror#27 @ E+=ROR(A,27)
92___
93$code.=<<___ if (!defined($flag));
94 eor $t1,$c,$d @ F_xx_xx, but not in 40_59
95___
96$code.=<<___;
97 mov $t0,$t0,ror#31
98 add $e,$e,$t0 @ E+=X[i]
99 str $t0,[$Xi,#-4]!
100___
101}
102
103sub BODY_00_15 {
104my ($a,$b,$c,$d,$e)=@_;
105 &Xload(@_);
106$code.=<<___;
107 and $t1,$b,$t1,ror#2
108 eor $t1,$t1,$d,ror#2 @ F_00_19(B,C,D)
109 add $e,$e,$t1 @ E+=F_00_19(B,C,D)
110___
111}
112
113sub BODY_16_19 {
114my ($a,$b,$c,$d,$e)=@_;
115 &Xupdate(@_);
116$code.=<<___;
117 and $t1,$b,$t1,ror#2
118 eor $t1,$t1,$d,ror#2 @ F_00_19(B,C,D)
119 add $e,$e,$t1 @ E+=F_00_19(B,C,D)
120___
121}
122
123sub BODY_20_39 {
124my ($a,$b,$c,$d,$e)=@_;
125 &Xupdate(@_);
126$code.=<<___;
127 eor $t1,$b,$t1,ror#2 @ F_20_39(B,C,D)
128 add $e,$e,$t1 @ E+=F_20_39(B,C,D)
129___
130}
131
132sub BODY_40_59 {
133my ($a,$b,$c,$d,$e)=@_;
134 &Xupdate(@_,1);
135$code.=<<___;
136 and $t1,$b,$c,ror#2
137 orr $t2,$b,$c,ror#2
138 and $t2,$t2,$d,ror#2
139 orr $t1,$t1,$t2 @ F_40_59(B,C,D)
140 add $e,$e,$t1 @ E+=F_40_59(B,C,D)
141___
142}
143
144$code=<<___;
145.text
146
147.global sha1_block_data_order
148.type sha1_block_data_order,%function
149
150.align 2
151sha1_block_data_order:
152 stmdb sp!,{r4-r12,lr}
153 add $len,$inp,$len,lsl#6 @ $len to point at the end of $inp
154 ldmia $ctx,{$a,$b,$c,$d,$e}
155.Lloop:
156 ldr $K,.LK_00_19
157 mov $Xi,sp
158 sub sp,sp,#15*4
159 mov $c,$c,ror#30
160 mov $d,$d,ror#30
161 mov $e,$e,ror#30 @ [6]
162.L_00_15:
163___
164for($i=0;$i<5;$i++) {
165 &BODY_00_15(@V); unshift(@V,pop(@V));
166}
167$code.=<<___;
168 teq $Xi,sp
169 bne .L_00_15 @ [((11+4)*5+2)*3]
170___
171 &BODY_00_15(@V); unshift(@V,pop(@V));
172 &BODY_16_19(@V); unshift(@V,pop(@V));
173 &BODY_16_19(@V); unshift(@V,pop(@V));
174 &BODY_16_19(@V); unshift(@V,pop(@V));
175 &BODY_16_19(@V); unshift(@V,pop(@V));
176$code.=<<___;
177
178 ldr $K,.LK_20_39 @ [+15+16*4]
179 sub sp,sp,#25*4
180 cmn sp,#0 @ [+3], clear carry to denote 20_39
181.L_20_39_or_60_79:
182___
183for($i=0;$i<5;$i++) {
184 &BODY_20_39(@V); unshift(@V,pop(@V));
185}
186$code.=<<___;
187 teq $Xi,sp @ preserve carry
188 bne .L_20_39_or_60_79 @ [+((12+3)*5+2)*4]
189 bcs .L_done @ [+((12+3)*5+2)*4], spare 300 bytes
190
191 ldr $K,.LK_40_59
192 sub sp,sp,#20*4 @ [+2]
193.L_40_59:
194___
195for($i=0;$i<5;$i++) {
196 &BODY_40_59(@V); unshift(@V,pop(@V));
197}
198$code.=<<___;
199 teq $Xi,sp
200 bne .L_40_59 @ [+((12+5)*5+2)*4]
201
202 ldr $K,.LK_60_79
203 sub sp,sp,#20*4
204 cmp sp,#0 @ set carry to denote 60_79
205 b .L_20_39_or_60_79 @ [+4], spare 300 bytes
206.L_done:
207 add sp,sp,#80*4 @ "deallocate" stack frame
208 ldmia $ctx,{$K,$t0,$t1,$t2,$t3}
209 add $a,$K,$a
210 add $b,$t0,$b
211 add $c,$t1,$c,ror#2
212 add $d,$t2,$d,ror#2
213 add $e,$t3,$e,ror#2
214 stmia $ctx,{$a,$b,$c,$d,$e}
215 teq $inp,$len
216 bne .Lloop @ [+18], total 1307
217
218 ldmia sp!,{r4-r12,lr}
219 tst lr,#1
220 moveq pc,lr @ be binary compatible with V4, yet
221 bx lr @ interoperable with Thumb ISA:-)
222.align 2
223.LK_00_19: .word 0x5a827999
224.LK_20_39: .word 0x6ed9eba1
225.LK_40_59: .word 0x8f1bbcdc
226.LK_60_79: .word 0xca62c1d6
227.size sha1_block_data_order,.-sha1_block_data_order
228.asciz "SHA1 block transform for ARMv4, CRYPTOGAMS by <appro\@openssl.org>"
229.align 2
230___
231
232$code =~ s/\bbx\s+lr\b/.word\t0xe12fff1e/gm; # make it possible to compile with -march=armv4
233print $code;
234close STDOUT; # enforce flush
diff --git a/src/lib/libcrypto/sha/asm/sha1-ppc.pl b/src/lib/libcrypto/sha/asm/sha1-ppc.pl
new file mode 100755
index 0000000000..dcd0fcdfcf
--- /dev/null
+++ b/src/lib/libcrypto/sha/asm/sha1-ppc.pl
@@ -0,0 +1,319 @@
1#!/usr/bin/env perl
2
3# ====================================================================
4# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
5# project. The module is, however, dual licensed under OpenSSL and
6# CRYPTOGAMS licenses depending on where you obtain it. For further
7# details see http://www.openssl.org/~appro/cryptogams/.
8# ====================================================================
9
10# I let hardware handle unaligned input(*), except on page boundaries
11# (see below for details). Otherwise straightforward implementation
12# with X vector in register bank. The module is big-endian [which is
13# not big deal as there're no little-endian targets left around].
14#
15# (*) this means that this module is inappropriate for PPC403? Does
16# anybody know if pre-POWER3 can sustain unaligned load?
17
18# -m64 -m32
19# ----------------------------------
20# PPC970,gcc-4.0.0 +76% +59%
21# Power6,xlc-7 +68% +33%
22
23$flavour = shift;
24
25if ($flavour =~ /64/) {
26 $SIZE_T =8;
27 $UCMP ="cmpld";
28 $STU ="stdu";
29 $POP ="ld";
30 $PUSH ="std";
31} elsif ($flavour =~ /32/) {
32 $SIZE_T =4;
33 $UCMP ="cmplw";
34 $STU ="stwu";
35 $POP ="lwz";
36 $PUSH ="stw";
37} else { die "nonsense $flavour"; }
38
39$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
40( $xlate="${dir}ppc-xlate.pl" and -f $xlate ) or
41( $xlate="${dir}../../perlasm/ppc-xlate.pl" and -f $xlate) or
42die "can't locate ppc-xlate.pl";
43
44open STDOUT,"| $^X $xlate $flavour ".shift || die "can't call $xlate: $!";
45
46$FRAME=24*$SIZE_T;
47
48$K ="r0";
49$sp ="r1";
50$toc="r2";
51$ctx="r3";
52$inp="r4";
53$num="r5";
54$t0 ="r15";
55$t1 ="r6";
56
57$A ="r7";
58$B ="r8";
59$C ="r9";
60$D ="r10";
61$E ="r11";
62$T ="r12";
63
64@V=($A,$B,$C,$D,$E,$T);
65@X=("r16","r17","r18","r19","r20","r21","r22","r23",
66 "r24","r25","r26","r27","r28","r29","r30","r31");
67
68sub BODY_00_19 {
69my ($i,$a,$b,$c,$d,$e,$f)=@_;
70my $j=$i+1;
71$code.=<<___ if ($i==0);
72 lwz @X[$i],`$i*4`($inp)
73___
74$code.=<<___ if ($i<15);
75 lwz @X[$j],`$j*4`($inp)
76 add $f,$K,$e
77 rotlwi $e,$a,5
78 add $f,$f,@X[$i]
79 and $t0,$c,$b
80 add $f,$f,$e
81 andc $t1,$d,$b
82 rotlwi $b,$b,30
83 or $t0,$t0,$t1
84 add $f,$f,$t0
85___
86$code.=<<___ if ($i>=15);
87 add $f,$K,$e
88 rotlwi $e,$a,5
89 xor @X[$j%16],@X[$j%16],@X[($j+2)%16]
90 add $f,$f,@X[$i%16]
91 and $t0,$c,$b
92 xor @X[$j%16],@X[$j%16],@X[($j+8)%16]
93 add $f,$f,$e
94 andc $t1,$d,$b
95 rotlwi $b,$b,30
96 or $t0,$t0,$t1
97 xor @X[$j%16],@X[$j%16],@X[($j+13)%16]
98 add $f,$f,$t0
99 rotlwi @X[$j%16],@X[$j%16],1
100___
101}
102
103sub BODY_20_39 {
104my ($i,$a,$b,$c,$d,$e,$f)=@_;
105my $j=$i+1;
106$code.=<<___ if ($i<79);
107 add $f,$K,$e
108 rotlwi $e,$a,5
109 xor @X[$j%16],@X[$j%16],@X[($j+2)%16]
110 add $f,$f,@X[$i%16]
111 xor $t0,$b,$c
112 xor @X[$j%16],@X[$j%16],@X[($j+8)%16]
113 add $f,$f,$e
114 rotlwi $b,$b,30
115 xor $t0,$t0,$d
116 xor @X[$j%16],@X[$j%16],@X[($j+13)%16]
117 add $f,$f,$t0
118 rotlwi @X[$j%16],@X[$j%16],1
119___
120$code.=<<___ if ($i==79);
121 add $f,$K,$e
122 rotlwi $e,$a,5
123 lwz r16,0($ctx)
124 add $f,$f,@X[$i%16]
125 xor $t0,$b,$c
126 lwz r17,4($ctx)
127 add $f,$f,$e
128 rotlwi $b,$b,30
129 lwz r18,8($ctx)
130 xor $t0,$t0,$d
131 lwz r19,12($ctx)
132 add $f,$f,$t0
133 lwz r20,16($ctx)
134___
135}
136
137sub BODY_40_59 {
138my ($i,$a,$b,$c,$d,$e,$f)=@_;
139my $j=$i+1;
140$code.=<<___;
141 add $f,$K,$e
142 rotlwi $e,$a,5
143 xor @X[$j%16],@X[$j%16],@X[($j+2)%16]
144 add $f,$f,@X[$i%16]
145 and $t0,$b,$c
146 xor @X[$j%16],@X[$j%16],@X[($j+8)%16]
147 add $f,$f,$e
148 or $t1,$b,$c
149 rotlwi $b,$b,30
150 xor @X[$j%16],@X[$j%16],@X[($j+13)%16]
151 and $t1,$t1,$d
152 or $t0,$t0,$t1
153 rotlwi @X[$j%16],@X[$j%16],1
154 add $f,$f,$t0
155___
156}
157
158$code=<<___;
159.machine "any"
160.text
161
162.globl .sha1_block_data_order
163.align 4
164.sha1_block_data_order:
165 mflr r0
166 $STU $sp,`-($FRAME+64)`($sp)
167 $PUSH r0,`$FRAME-$SIZE_T*18`($sp)
168 $PUSH r15,`$FRAME-$SIZE_T*17`($sp)
169 $PUSH r16,`$FRAME-$SIZE_T*16`($sp)
170 $PUSH r17,`$FRAME-$SIZE_T*15`($sp)
171 $PUSH r18,`$FRAME-$SIZE_T*14`($sp)
172 $PUSH r19,`$FRAME-$SIZE_T*13`($sp)
173 $PUSH r20,`$FRAME-$SIZE_T*12`($sp)
174 $PUSH r21,`$FRAME-$SIZE_T*11`($sp)
175 $PUSH r22,`$FRAME-$SIZE_T*10`($sp)
176 $PUSH r23,`$FRAME-$SIZE_T*9`($sp)
177 $PUSH r24,`$FRAME-$SIZE_T*8`($sp)
178 $PUSH r25,`$FRAME-$SIZE_T*7`($sp)
179 $PUSH r26,`$FRAME-$SIZE_T*6`($sp)
180 $PUSH r27,`$FRAME-$SIZE_T*5`($sp)
181 $PUSH r28,`$FRAME-$SIZE_T*4`($sp)
182 $PUSH r29,`$FRAME-$SIZE_T*3`($sp)
183 $PUSH r30,`$FRAME-$SIZE_T*2`($sp)
184 $PUSH r31,`$FRAME-$SIZE_T*1`($sp)
185 lwz $A,0($ctx)
186 lwz $B,4($ctx)
187 lwz $C,8($ctx)
188 lwz $D,12($ctx)
189 lwz $E,16($ctx)
190 andi. r0,$inp,3
191 bne Lunaligned
192Laligned:
193 mtctr $num
194 bl Lsha1_block_private
195Ldone:
196 $POP r0,`$FRAME-$SIZE_T*18`($sp)
197 $POP r15,`$FRAME-$SIZE_T*17`($sp)
198 $POP r16,`$FRAME-$SIZE_T*16`($sp)
199 $POP r17,`$FRAME-$SIZE_T*15`($sp)
200 $POP r18,`$FRAME-$SIZE_T*14`($sp)
201 $POP r19,`$FRAME-$SIZE_T*13`($sp)
202 $POP r20,`$FRAME-$SIZE_T*12`($sp)
203 $POP r21,`$FRAME-$SIZE_T*11`($sp)
204 $POP r22,`$FRAME-$SIZE_T*10`($sp)
205 $POP r23,`$FRAME-$SIZE_T*9`($sp)
206 $POP r24,`$FRAME-$SIZE_T*8`($sp)
207 $POP r25,`$FRAME-$SIZE_T*7`($sp)
208 $POP r26,`$FRAME-$SIZE_T*6`($sp)
209 $POP r27,`$FRAME-$SIZE_T*5`($sp)
210 $POP r28,`$FRAME-$SIZE_T*4`($sp)
211 $POP r29,`$FRAME-$SIZE_T*3`($sp)
212 $POP r30,`$FRAME-$SIZE_T*2`($sp)
213 $POP r31,`$FRAME-$SIZE_T*1`($sp)
214 mtlr r0
215 addi $sp,$sp,`$FRAME+64`
216 blr
217___
218
219# PowerPC specification allows an implementation to be ill-behaved
220# upon unaligned access which crosses page boundary. "Better safe
221# than sorry" principle makes me treat it specially. But I don't
222# look for particular offending word, but rather for 64-byte input
223# block which crosses the boundary. Once found that block is aligned
224# and hashed separately...
225$code.=<<___;
226.align 4
227Lunaligned:
228 subfic $t1,$inp,4096
229 andi. $t1,$t1,4095 ; distance to closest page boundary
230 srwi. $t1,$t1,6 ; t1/=64
231 beq Lcross_page
232 $UCMP $num,$t1
233 ble- Laligned ; didn't cross the page boundary
234 mtctr $t1
235 subfc $num,$t1,$num
236 bl Lsha1_block_private
237Lcross_page:
238 li $t1,16
239 mtctr $t1
240 addi r20,$sp,$FRAME ; spot below the frame
241Lmemcpy:
242 lbz r16,0($inp)
243 lbz r17,1($inp)
244 lbz r18,2($inp)
245 lbz r19,3($inp)
246 addi $inp,$inp,4
247 stb r16,0(r20)
248 stb r17,1(r20)
249 stb r18,2(r20)
250 stb r19,3(r20)
251 addi r20,r20,4
252 bdnz Lmemcpy
253
254 $PUSH $inp,`$FRAME-$SIZE_T*19`($sp)
255 li $t1,1
256 addi $inp,$sp,$FRAME
257 mtctr $t1
258 bl Lsha1_block_private
259 $POP $inp,`$FRAME-$SIZE_T*19`($sp)
260 addic. $num,$num,-1
261 bne- Lunaligned
262 b Ldone
263___
264
265# This is private block function, which uses tailored calling
266# interface, namely upon entry SHA_CTX is pre-loaded to given
267# registers and counter register contains amount of chunks to
268# digest...
269$code.=<<___;
270.align 4
271Lsha1_block_private:
272___
273$code.=<<___; # load K_00_19
274 lis $K,0x5a82
275 ori $K,$K,0x7999
276___
277for($i=0;$i<20;$i++) { &BODY_00_19($i,@V); unshift(@V,pop(@V)); }
278$code.=<<___; # load K_20_39
279 lis $K,0x6ed9
280 ori $K,$K,0xeba1
281___
282for(;$i<40;$i++) { &BODY_20_39($i,@V); unshift(@V,pop(@V)); }
283$code.=<<___; # load K_40_59
284 lis $K,0x8f1b
285 ori $K,$K,0xbcdc
286___
287for(;$i<60;$i++) { &BODY_40_59($i,@V); unshift(@V,pop(@V)); }
288$code.=<<___; # load K_60_79
289 lis $K,0xca62
290 ori $K,$K,0xc1d6
291___
292for(;$i<80;$i++) { &BODY_20_39($i,@V); unshift(@V,pop(@V)); }
293$code.=<<___;
294 add r16,r16,$E
295 add r17,r17,$T
296 add r18,r18,$A
297 add r19,r19,$B
298 add r20,r20,$C
299 stw r16,0($ctx)
300 mr $A,r16
301 stw r17,4($ctx)
302 mr $B,r17
303 stw r18,8($ctx)
304 mr $C,r18
305 stw r19,12($ctx)
306 mr $D,r19
307 stw r20,16($ctx)
308 mr $E,r20
309 addi $inp,$inp,`16*4`
310 bdnz- Lsha1_block_private
311 blr
312___
313$code.=<<___;
314.asciz "SHA1 block transform for PPC, CRYPTOGAMS by <appro\@fy.chalmers.se>"
315___
316
317$code =~ s/\`([^\`]*)\`/eval $1/gem;
318print $code;
319close STDOUT;
diff --git a/src/lib/libcrypto/sha/asm/sha1-s390x.pl b/src/lib/libcrypto/sha/asm/sha1-s390x.pl
new file mode 100644
index 0000000000..4b17848287
--- /dev/null
+++ b/src/lib/libcrypto/sha/asm/sha1-s390x.pl
@@ -0,0 +1,226 @@
1#!/usr/bin/env perl
2
3# ====================================================================
4# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
5# project. The module is, however, dual licensed under OpenSSL and
6# CRYPTOGAMS licenses depending on where you obtain it. For further
7# details see http://www.openssl.org/~appro/cryptogams/.
8# ====================================================================
9
10# SHA1 block procedure for s390x.
11
12# April 2007.
13#
14# Performance is >30% better than gcc 3.3 generated code. But the real
15# twist is that SHA1 hardware support is detected and utilized. In
16# which case performance can reach further >4.5x for larger chunks.
17
18# January 2009.
19#
20# Optimize Xupdate for amount of memory references and reschedule
21# instructions to favour dual-issue z10 pipeline. On z10 hardware is
22# "only" ~2.3x faster than software.
23
24$kimdfunc=1; # magic function code for kimd instruction
25
26$output=shift;
27open STDOUT,">$output";
28
29$K_00_39="%r0"; $K=$K_00_39;
30$K_40_79="%r1";
31$ctx="%r2"; $prefetch="%r2";
32$inp="%r3";
33$len="%r4";
34
35$A="%r5";
36$B="%r6";
37$C="%r7";
38$D="%r8";
39$E="%r9"; @V=($A,$B,$C,$D,$E);
40$t0="%r10";
41$t1="%r11";
42@X=("%r12","%r13","%r14");
43$sp="%r15";
44
45$frame=160+16*4;
46
47sub Xupdate {
48my $i=shift;
49
50$code.=<<___ if ($i==15);
51 lg $prefetch,160($sp) ### Xupdate(16) warm-up
52 lr $X[0],$X[2]
53___
54return if ($i&1); # Xupdate is vectorized and executed every 2nd cycle
55$code.=<<___ if ($i<16);
56 lg $X[0],`$i*4`($inp) ### Xload($i)
57 rllg $X[1],$X[0],32
58___
59$code.=<<___ if ($i>=16);
60 xgr $X[0],$prefetch ### Xupdate($i)
61 lg $prefetch,`160+4*(($i+2)%16)`($sp)
62 xg $X[0],`160+4*(($i+8)%16)`($sp)
63 xgr $X[0],$prefetch
64 rll $X[0],$X[0],1
65 rllg $X[1],$X[0],32
66 rll $X[1],$X[1],1
67 rllg $X[0],$X[1],32
68 lr $X[2],$X[1] # feedback
69___
70$code.=<<___ if ($i<=70);
71 stg $X[0],`160+4*($i%16)`($sp)
72___
73unshift(@X,pop(@X));
74}
75
76sub BODY_00_19 {
77my ($i,$a,$b,$c,$d,$e)=@_;
78my $xi=$X[1];
79
80 &Xupdate($i);
81$code.=<<___;
82 alr $e,$K ### $i
83 rll $t1,$a,5
84 lr $t0,$d
85 xr $t0,$c
86 alr $e,$t1
87 nr $t0,$b
88 alr $e,$xi
89 xr $t0,$d
90 rll $b,$b,30
91 alr $e,$t0
92___
93}
94
95sub BODY_20_39 {
96my ($i,$a,$b,$c,$d,$e)=@_;
97my $xi=$X[1];
98
99 &Xupdate($i);
100$code.=<<___;
101 alr $e,$K ### $i
102 rll $t1,$a,5
103 lr $t0,$b
104 alr $e,$t1
105 xr $t0,$c
106 alr $e,$xi
107 xr $t0,$d
108 rll $b,$b,30
109 alr $e,$t0
110___
111}
112
113sub BODY_40_59 {
114my ($i,$a,$b,$c,$d,$e)=@_;
115my $xi=$X[1];
116
117 &Xupdate($i);
118$code.=<<___;
119 alr $e,$K ### $i
120 rll $t1,$a,5
121 lr $t0,$b
122 alr $e,$t1
123 or $t0,$c
124 lr $t1,$b
125 nr $t0,$d
126 nr $t1,$c
127 alr $e,$xi
128 or $t0,$t1
129 rll $b,$b,30
130 alr $e,$t0
131___
132}
133
134$code.=<<___;
135.text
136.align 64
137.type Ktable,\@object
138Ktable: .long 0x5a827999,0x6ed9eba1,0x8f1bbcdc,0xca62c1d6
139 .skip 48 #.long 0,0,0,0,0,0,0,0,0,0,0,0
140.size Ktable,.-Ktable
141.globl sha1_block_data_order
142.type sha1_block_data_order,\@function
143sha1_block_data_order:
144___
145$code.=<<___ if ($kimdfunc);
146 larl %r1,OPENSSL_s390xcap_P
147 lg %r0,0(%r1)
148 tmhl %r0,0x4000 # check for message-security assist
149 jz .Lsoftware
150 lghi %r0,0
151 la %r1,16($sp)
152 .long 0xb93e0002 # kimd %r0,%r2
153 lg %r0,16($sp)
154 tmhh %r0,`0x8000>>$kimdfunc`
155 jz .Lsoftware
156 lghi %r0,$kimdfunc
157 lgr %r1,$ctx
158 lgr %r2,$inp
159 sllg %r3,$len,6
160 .long 0xb93e0002 # kimd %r0,%r2
161 brc 1,.-4 # pay attention to "partial completion"
162 br %r14
163.align 16
164.Lsoftware:
165___
166$code.=<<___;
167 lghi %r1,-$frame
168 stg $ctx,16($sp)
169 stmg %r6,%r15,48($sp)
170 lgr %r0,$sp
171 la $sp,0(%r1,$sp)
172 stg %r0,0($sp)
173
174 larl $t0,Ktable
175 llgf $A,0($ctx)
176 llgf $B,4($ctx)
177 llgf $C,8($ctx)
178 llgf $D,12($ctx)
179 llgf $E,16($ctx)
180
181 lg $K_00_39,0($t0)
182 lg $K_40_79,8($t0)
183
184.Lloop:
185 rllg $K_00_39,$K_00_39,32
186___
187for ($i=0;$i<20;$i++) { &BODY_00_19($i,@V); unshift(@V,pop(@V)); }
188$code.=<<___;
189 rllg $K_00_39,$K_00_39,32
190___
191for (;$i<40;$i++) { &BODY_20_39($i,@V); unshift(@V,pop(@V)); }
192$code.=<<___; $K=$K_40_79;
193 rllg $K_40_79,$K_40_79,32
194___
195for (;$i<60;$i++) { &BODY_40_59($i,@V); unshift(@V,pop(@V)); }
196$code.=<<___;
197 rllg $K_40_79,$K_40_79,32
198___
199for (;$i<80;$i++) { &BODY_20_39($i,@V); unshift(@V,pop(@V)); }
200$code.=<<___;
201
202 lg $ctx,`$frame+16`($sp)
203 la $inp,64($inp)
204 al $A,0($ctx)
205 al $B,4($ctx)
206 al $C,8($ctx)
207 al $D,12($ctx)
208 al $E,16($ctx)
209 st $A,0($ctx)
210 st $B,4($ctx)
211 st $C,8($ctx)
212 st $D,12($ctx)
213 st $E,16($ctx)
214 brct $len,.Lloop
215
216 lmg %r6,%r15,`$frame+48`($sp)
217 br %r14
218.size sha1_block_data_order,.-sha1_block_data_order
219.string "SHA1 block transform for s390x, CRYPTOGAMS by <appro\@openssl.org>"
220.comm OPENSSL_s390xcap_P,8,8
221___
222
223$code =~ s/\`([^\`]*)\`/eval $1/gem;
224
225print $code;
226close STDOUT;
diff --git a/src/lib/libcrypto/sha/asm/sha1-sparcv9.pl b/src/lib/libcrypto/sha/asm/sha1-sparcv9.pl
new file mode 100644
index 0000000000..8306fc88cc
--- /dev/null
+++ b/src/lib/libcrypto/sha/asm/sha1-sparcv9.pl
@@ -0,0 +1,283 @@
1#!/usr/bin/env perl
2
3# ====================================================================
4# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
5# project. The module is, however, dual licensed under OpenSSL and
6# CRYPTOGAMS licenses depending on where you obtain it. For further
7# details see http://www.openssl.org/~appro/cryptogams/.
8# ====================================================================
9
10# Performance improvement is not really impressive on pre-T1 CPU: +8%
11# over Sun C and +25% over gcc [3.3]. While on T1, a.k.a. Niagara, it
12# turned to be 40% faster than 64-bit code generated by Sun C 5.8 and
13# >2x than 64-bit code generated by gcc 3.4. And there is a gimmick.
14# X[16] vector is packed to 8 64-bit registers and as result nothing
15# is spilled on stack. In addition input data is loaded in compact
16# instruction sequence, thus minimizing the window when the code is
17# subject to [inter-thread] cache-thrashing hazard. The goal is to
18# ensure scalability on UltraSPARC T1, or rather to avoid decay when
19# amount of active threads exceeds the number of physical cores.
20
21$bits=32;
22for (@ARGV) { $bits=64 if (/\-m64/ || /\-xarch\=v9/); }
23if ($bits==64) { $bias=2047; $frame=192; }
24else { $bias=0; $frame=112; }
25
26$output=shift;
27open STDOUT,">$output";
28
29@X=("%o0","%o1","%o2","%o3","%o4","%o5","%g1","%o7");
30$rot1m="%g2";
31$tmp64="%g3";
32$Xi="%g4";
33$A="%l0";
34$B="%l1";
35$C="%l2";
36$D="%l3";
37$E="%l4";
38@V=($A,$B,$C,$D,$E);
39$K_00_19="%l5";
40$K_20_39="%l6";
41$K_40_59="%l7";
42$K_60_79="%g5";
43@K=($K_00_19,$K_20_39,$K_40_59,$K_60_79);
44
45$ctx="%i0";
46$inp="%i1";
47$len="%i2";
48$tmp0="%i3";
49$tmp1="%i4";
50$tmp2="%i5";
51
52sub BODY_00_15 {
53my ($i,$a,$b,$c,$d,$e)=@_;
54my $xi=($i&1)?@X[($i/2)%8]:$Xi;
55
56$code.=<<___;
57 sll $a,5,$tmp0 !! $i
58 add @K[$i/20],$e,$e
59 srl $a,27,$tmp1
60 add $tmp0,$e,$e
61 and $c,$b,$tmp0
62 add $tmp1,$e,$e
63 sll $b,30,$tmp2
64 andn $d,$b,$tmp1
65 srl $b,2,$b
66 or $tmp1,$tmp0,$tmp1
67 or $tmp2,$b,$b
68 add $xi,$e,$e
69___
70if ($i&1 && $i<15) {
71 $code.=
72 " srlx @X[(($i+1)/2)%8],32,$Xi\n";
73}
74$code.=<<___;
75 add $tmp1,$e,$e
76___
77}
78
79sub Xupdate {
80my ($i,$a,$b,$c,$d,$e)=@_;
81my $j=$i/2;
82
83if ($i&1) {
84$code.=<<___;
85 sll $a,5,$tmp0 !! $i
86 add @K[$i/20],$e,$e
87 srl $a,27,$tmp1
88___
89} else {
90$code.=<<___;
91 sllx @X[($j+6)%8],32,$Xi ! Xupdate($i)
92 xor @X[($j+1)%8],@X[$j%8],@X[$j%8]
93 srlx @X[($j+7)%8],32,$tmp1
94 xor @X[($j+4)%8],@X[$j%8],@X[$j%8]
95 sll $a,5,$tmp0 !! $i
96 or $tmp1,$Xi,$Xi
97 add @K[$i/20],$e,$e !!
98 xor $Xi,@X[$j%8],@X[$j%8]
99 srlx @X[$j%8],31,$Xi
100 add @X[$j%8],@X[$j%8],@X[$j%8]
101 and $Xi,$rot1m,$Xi
102 andn @X[$j%8],$rot1m,@X[$j%8]
103 srl $a,27,$tmp1 !!
104 or $Xi,@X[$j%8],@X[$j%8]
105___
106}
107}
108
109sub BODY_16_19 {
110my ($i,$a,$b,$c,$d,$e)=@_;
111
112 &Xupdate(@_);
113 if ($i&1) {
114 $xi=@X[($i/2)%8];
115 } else {
116 $xi=$Xi;
117 $code.="\tsrlx @X[($i/2)%8],32,$xi\n";
118 }
119$code.=<<___;
120 add $tmp0,$e,$e !!
121 and $c,$b,$tmp0
122 add $tmp1,$e,$e
123 sll $b,30,$tmp2
124 add $xi,$e,$e
125 andn $d,$b,$tmp1
126 srl $b,2,$b
127 or $tmp1,$tmp0,$tmp1
128 or $tmp2,$b,$b
129 add $tmp1,$e,$e
130___
131}
132
133sub BODY_20_39 {
134my ($i,$a,$b,$c,$d,$e)=@_;
135my $xi;
136 &Xupdate(@_);
137 if ($i&1) {
138 $xi=@X[($i/2)%8];
139 } else {
140 $xi=$Xi;
141 $code.="\tsrlx @X[($i/2)%8],32,$xi\n";
142 }
143$code.=<<___;
144 add $tmp0,$e,$e !!
145 xor $c,$b,$tmp0
146 add $tmp1,$e,$e
147 sll $b,30,$tmp2
148 xor $d,$tmp0,$tmp1
149 srl $b,2,$b
150 add $tmp1,$e,$e
151 or $tmp2,$b,$b
152 add $xi,$e,$e
153___
154}
155
156sub BODY_40_59 {
157my ($i,$a,$b,$c,$d,$e)=@_;
158my $xi;
159 &Xupdate(@_);
160 if ($i&1) {
161 $xi=@X[($i/2)%8];
162 } else {
163 $xi=$Xi;
164 $code.="\tsrlx @X[($i/2)%8],32,$xi\n";
165 }
166$code.=<<___;
167 add $tmp0,$e,$e !!
168 and $c,$b,$tmp0
169 add $tmp1,$e,$e
170 sll $b,30,$tmp2
171 or $c,$b,$tmp1
172 srl $b,2,$b
173 and $d,$tmp1,$tmp1
174 add $xi,$e,$e
175 or $tmp1,$tmp0,$tmp1
176 or $tmp2,$b,$b
177 add $tmp1,$e,$e
178___
179}
180
181$code.=<<___ if ($bits==64);
182.register %g2,#scratch
183.register %g3,#scratch
184___
185$code.=<<___;
186.section ".text",#alloc,#execinstr
187
188.align 32
189.globl sha1_block_data_order
190sha1_block_data_order:
191 save %sp,-$frame,%sp
192 sllx $len,6,$len
193 add $inp,$len,$len
194
195 or %g0,1,$rot1m
196 sllx $rot1m,32,$rot1m
197 or $rot1m,1,$rot1m
198
199 ld [$ctx+0],$A
200 ld [$ctx+4],$B
201 ld [$ctx+8],$C
202 ld [$ctx+12],$D
203 ld [$ctx+16],$E
204 andn $inp,7,$tmp0
205
206 sethi %hi(0x5a827999),$K_00_19
207 or $K_00_19,%lo(0x5a827999),$K_00_19
208 sethi %hi(0x6ed9eba1),$K_20_39
209 or $K_20_39,%lo(0x6ed9eba1),$K_20_39
210 sethi %hi(0x8f1bbcdc),$K_40_59
211 or $K_40_59,%lo(0x8f1bbcdc),$K_40_59
212 sethi %hi(0xca62c1d6),$K_60_79
213 or $K_60_79,%lo(0xca62c1d6),$K_60_79
214
215.Lloop:
216 ldx [$tmp0+0],@X[0]
217 ldx [$tmp0+16],@X[2]
218 ldx [$tmp0+32],@X[4]
219 ldx [$tmp0+48],@X[6]
220 and $inp,7,$tmp1
221 ldx [$tmp0+8],@X[1]
222 sll $tmp1,3,$tmp1
223 ldx [$tmp0+24],@X[3]
224 subcc %g0,$tmp1,$tmp2 ! should be 64-$tmp1, but -$tmp1 works too
225 ldx [$tmp0+40],@X[5]
226 bz,pt %icc,.Laligned
227 ldx [$tmp0+56],@X[7]
228
229 sllx @X[0],$tmp1,@X[0]
230 ldx [$tmp0+64],$tmp64
231___
232for($i=0;$i<7;$i++)
233{ $code.=<<___;
234 srlx @X[$i+1],$tmp2,$Xi
235 sllx @X[$i+1],$tmp1,@X[$i+1]
236 or $Xi,@X[$i],@X[$i]
237___
238}
239$code.=<<___;
240 srlx $tmp64,$tmp2,$tmp64
241 or $tmp64,@X[7],@X[7]
242.Laligned:
243 srlx @X[0],32,$Xi
244___
245for ($i=0;$i<16;$i++) { &BODY_00_15($i,@V); unshift(@V,pop(@V)); }
246for (;$i<20;$i++) { &BODY_16_19($i,@V); unshift(@V,pop(@V)); }
247for (;$i<40;$i++) { &BODY_20_39($i,@V); unshift(@V,pop(@V)); }
248for (;$i<60;$i++) { &BODY_40_59($i,@V); unshift(@V,pop(@V)); }
249for (;$i<80;$i++) { &BODY_20_39($i,@V); unshift(@V,pop(@V)); }
250$code.=<<___;
251
252 ld [$ctx+0],@X[0]
253 ld [$ctx+4],@X[1]
254 ld [$ctx+8],@X[2]
255 ld [$ctx+12],@X[3]
256 add $inp,64,$inp
257 ld [$ctx+16],@X[4]
258 cmp $inp,$len
259
260 add $A,@X[0],$A
261 st $A,[$ctx+0]
262 add $B,@X[1],$B
263 st $B,[$ctx+4]
264 add $C,@X[2],$C
265 st $C,[$ctx+8]
266 add $D,@X[3],$D
267 st $D,[$ctx+12]
268 add $E,@X[4],$E
269 st $E,[$ctx+16]
270
271 bne `$bits==64?"%xcc":"%icc"`,.Lloop
272 andn $inp,7,$tmp0
273
274 ret
275 restore
276.type sha1_block_data_order,#function
277.size sha1_block_data_order,(.-sha1_block_data_order)
278.asciz "SHA1 block transform for SPARCv9, CRYPTOGAMS by <appro\@openssl.org>"
279___
280
281$code =~ s/\`([^\`]*)\`/eval $1/gem;
282print $code;
283close STDOUT;
diff --git a/src/lib/libcrypto/sha/asm/sha1-sparcv9a.pl b/src/lib/libcrypto/sha/asm/sha1-sparcv9a.pl
new file mode 100644
index 0000000000..15eb854bad
--- /dev/null
+++ b/src/lib/libcrypto/sha/asm/sha1-sparcv9a.pl
@@ -0,0 +1,600 @@
1#!/usr/bin/env perl
2
3# ====================================================================
4# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
5# project. The module is, however, dual licensed under OpenSSL and
6# CRYPTOGAMS licenses depending on where you obtain it. For further
7# details see http://www.openssl.org/~appro/cryptogams/.
8# ====================================================================
9
10# January 2009
11#
12# Provided that UltraSPARC VIS instructions are pipe-lined(*) and
13# pairable(*) with IALU ones, offloading of Xupdate to the UltraSPARC
14# Graphic Unit would make it possible to achieve higher instruction-
15# level parallelism, ILP, and thus higher performance. It should be
16# explicitly noted that ILP is the keyword, and it means that this
17# code would be unsuitable for cores like UltraSPARC-Tx. The idea is
18# not really novel, Sun had VIS-powered implementation for a while.
19# Unlike Sun's implementation this one can process multiple unaligned
20# input blocks, and as such works as drop-in replacement for OpenSSL
21# sha1_block_data_order. Performance improvement was measured to be
22# 40% over pure IALU sha1-sparcv9.pl on UltraSPARC-IIi, but 12% on
23# UltraSPARC-III. See below for discussion...
24#
25# The module does not present direct interest for OpenSSL, because
26# it doesn't provide better performance on contemporary SPARCv9 CPUs,
27# UltraSPARC-Tx and SPARC64-V[II] to be specific. Those who feel they
28# absolutely must score on UltraSPARC-I-IV can simply replace
29# crypto/sha/asm/sha1-sparcv9.pl with this module.
30#
31# (*) "Pipe-lined" means that even if it takes several cycles to
32# complete, next instruction using same functional unit [but not
33# depending on the result of the current instruction] can start
34# execution without having to wait for the unit. "Pairable"
35# means that two [or more] independent instructions can be
36# issued at the very same time.
37
38$bits=32;
39for (@ARGV) { $bits=64 if (/\-m64/ || /\-xarch\=v9/); }
40if ($bits==64) { $bias=2047; $frame=192; }
41else { $bias=0; $frame=112; }
42
43$output=shift;
44open STDOUT,">$output";
45
46$ctx="%i0";
47$inp="%i1";
48$len="%i2";
49$tmp0="%i3";
50$tmp1="%i4";
51$tmp2="%i5";
52$tmp3="%g5";
53
54$base="%g1";
55$align="%g4";
56$Xfer="%o5";
57$nXfer=$tmp3;
58$Xi="%o7";
59
60$A="%l0";
61$B="%l1";
62$C="%l2";
63$D="%l3";
64$E="%l4";
65@V=($A,$B,$C,$D,$E);
66
67$Actx="%o0";
68$Bctx="%o1";
69$Cctx="%o2";
70$Dctx="%o3";
71$Ectx="%o4";
72
73$fmul="%f32";
74$VK_00_19="%f34";
75$VK_20_39="%f36";
76$VK_40_59="%f38";
77$VK_60_79="%f40";
78@VK=($VK_00_19,$VK_20_39,$VK_40_59,$VK_60_79);
79@X=("%f0", "%f1", "%f2", "%f3", "%f4", "%f5", "%f6", "%f7",
80 "%f8", "%f9","%f10","%f11","%f12","%f13","%f14","%f15","%f16");
81
82# This is reference 2x-parallelized VIS-powered Xupdate procedure. It
83# covers even K_NN_MM addition...
84sub Xupdate {
85my ($i)=@_;
86my $K=@VK[($i+16)/20];
87my $j=($i+16)%16;
88
89# [ provided that GSR.alignaddr_offset is 5, $mul contains
90# 0x100ULL<<32|0x100 value and K_NN_MM are pre-loaded to
91# chosen registers... ]
92$code.=<<___;
93 fxors @X[($j+13)%16],@X[$j],@X[$j] !-1/-1/-1:X[0]^=X[13]
94 fxors @X[($j+14)%16],@X[$j+1],@X[$j+1]! 0/ 0/ 0:X[1]^=X[14]
95 fxor @X[($j+2)%16],@X[($j+8)%16],%f18! 1/ 1/ 1:Tmp=X[2,3]^X[8,9]
96 fxor %f18,@X[$j],@X[$j] ! 2/ 4/ 3:X[0,1]^=X[2,3]^X[8,9]
97 faligndata @X[$j],@X[$j],%f18 ! 3/ 7/ 5:Tmp=X[0,1]>>>24
98 fpadd32 @X[$j],@X[$j],@X[$j] ! 4/ 8/ 6:X[0,1]<<=1
99 fmul8ulx16 %f18,$fmul,%f18 ! 5/10/ 7:Tmp>>=7, Tmp&=1
100 ![fxors %f15,%f2,%f2]
101 for %f18,@X[$j],@X[$j] ! 8/14/10:X[0,1]|=Tmp
102 ![fxors %f0,%f3,%f3] !10/17/12:X[0] dependency
103 fpadd32 $K,@X[$j],%f20
104 std %f20,[$Xfer+`4*$j`]
105___
106# The numbers delimited with slash are the earliest possible dispatch
107# cycles for given instruction assuming 1 cycle latency for simple VIS
108# instructions, such as on UltraSPARC-I&II, 3 cycles latency, such as
109# on UltraSPARC-III&IV, and 2 cycles latency(*), respectively. Being
110# 2x-parallelized the procedure is "worth" 5, 8.5 or 6 ticks per SHA1
111# round. As [long as] FPU/VIS instructions are perfectly pairable with
112# IALU ones, the round timing is defined by the maximum between VIS
113# and IALU timings. The latter varies from round to round and averages
114# out at 6.25 ticks. This means that USI&II should operate at IALU
115# rate, while USIII&IV - at VIS rate. This explains why performance
116# improvement varies among processors. Well, given that pure IALU
117# sha1-sparcv9.pl module exhibits virtually uniform performance of
118# ~9.3 cycles per SHA1 round. Timings mentioned above are theoretical
119# lower limits. Real-life performance was measured to be 6.6 cycles
120# per SHA1 round on USIIi and 8.3 on USIII. The latter is lower than
121# half-round VIS timing, because there are 16 Xupdate-free rounds,
122# which "push down" average theoretical timing to 8 cycles...
123
124# (*) SPARC64-V[II] was originally believed to have 2 cycles VIS
125# latency. Well, it might have, but it doesn't have dedicated
126# VIS-unit. Instead, VIS instructions are executed by other
127# functional units, ones used here - by IALU. This doesn't
128# improve effective ILP...
129}
130
131# The reference Xupdate procedure is then "strained" over *pairs* of
132# BODY_NN_MM and kind of modulo-scheduled in respect to X[n]^=X[n+13]
133# and K_NN_MM addition. It's "running" 15 rounds ahead, which leaves
134# plenty of room to amortize for read-after-write hazard, as well as
135# to fetch and align input for the next spin. The VIS instructions are
136# scheduled for latency of 2 cycles, because there are not enough IALU
137# instructions to schedule for latency of 3, while scheduling for 1
138# would give no gain on USI&II anyway.
139
140sub BODY_00_19 {
141my ($i,$a,$b,$c,$d,$e)=@_;
142my $j=$i&~1;
143my $k=($j+16+2)%16; # ahead reference
144my $l=($j+16-2)%16; # behind reference
145my $K=@VK[($j+16-2)/20];
146
147$j=($j+16)%16;
148
149$code.=<<___ if (!($i&1));
150 sll $a,5,$tmp0 !! $i
151 and $c,$b,$tmp3
152 ld [$Xfer+`4*($i%16)`],$Xi
153 fxors @X[($j+14)%16],@X[$j+1],@X[$j+1]! 0/ 0/ 0:X[1]^=X[14]
154 srl $a,27,$tmp1
155 add $tmp0,$e,$e
156 fxor @X[($j+2)%16],@X[($j+8)%16],%f18! 1/ 1/ 1:Tmp=X[2,3]^X[8,9]
157 sll $b,30,$tmp2
158 add $tmp1,$e,$e
159 andn $d,$b,$tmp1
160 add $Xi,$e,$e
161 fxor %f18,@X[$j],@X[$j] ! 2/ 4/ 3:X[0,1]^=X[2,3]^X[8,9]
162 srl $b,2,$b
163 or $tmp1,$tmp3,$tmp1
164 or $tmp2,$b,$b
165 add $tmp1,$e,$e
166 faligndata @X[$j],@X[$j],%f18 ! 3/ 7/ 5:Tmp=X[0,1]>>>24
167___
168$code.=<<___ if ($i&1);
169 sll $a,5,$tmp0 !! $i
170 and $c,$b,$tmp3
171 ld [$Xfer+`4*($i%16)`],$Xi
172 fpadd32 @X[$j],@X[$j],@X[$j] ! 4/ 8/ 6:X[0,1]<<=1
173 srl $a,27,$tmp1
174 add $tmp0,$e,$e
175 fmul8ulx16 %f18,$fmul,%f18 ! 5/10/ 7:Tmp>>=7, Tmp&=1
176 sll $b,30,$tmp2
177 add $tmp1,$e,$e
178 fpadd32 $K,@X[$l],%f20 !
179 andn $d,$b,$tmp1
180 add $Xi,$e,$e
181 fxors @X[($k+13)%16],@X[$k],@X[$k] !-1/-1/-1:X[0]^=X[13]
182 srl $b,2,$b
183 or $tmp1,$tmp3,$tmp1
184 fxor %f18,@X[$j],@X[$j] ! 8/14/10:X[0,1]|=Tmp
185 or $tmp2,$b,$b
186 add $tmp1,$e,$e
187___
188$code.=<<___ if ($i&1 && $i>=2);
189 std %f20,[$Xfer+`4*$l`] !
190___
191}
192
193sub BODY_20_39 {
194my ($i,$a,$b,$c,$d,$e)=@_;
195my $j=$i&~1;
196my $k=($j+16+2)%16; # ahead reference
197my $l=($j+16-2)%16; # behind reference
198my $K=@VK[($j+16-2)/20];
199
200$j=($j+16)%16;
201
202$code.=<<___ if (!($i&1) && $i<64);
203 sll $a,5,$tmp0 !! $i
204 ld [$Xfer+`4*($i%16)`],$Xi
205 fxors @X[($j+14)%16],@X[$j+1],@X[$j+1]! 0/ 0/ 0:X[1]^=X[14]
206 srl $a,27,$tmp1
207 add $tmp0,$e,$e
208 fxor @X[($j+2)%16],@X[($j+8)%16],%f18! 1/ 1/ 1:Tmp=X[2,3]^X[8,9]
209 xor $c,$b,$tmp0
210 add $tmp1,$e,$e
211 sll $b,30,$tmp2
212 xor $d,$tmp0,$tmp1
213 fxor %f18,@X[$j],@X[$j] ! 2/ 4/ 3:X[0,1]^=X[2,3]^X[8,9]
214 srl $b,2,$b
215 add $tmp1,$e,$e
216 or $tmp2,$b,$b
217 add $Xi,$e,$e
218 faligndata @X[$j],@X[$j],%f18 ! 3/ 7/ 5:Tmp=X[0,1]>>>24
219___
220$code.=<<___ if ($i&1 && $i<64);
221 sll $a,5,$tmp0 !! $i
222 ld [$Xfer+`4*($i%16)`],$Xi
223 fpadd32 @X[$j],@X[$j],@X[$j] ! 4/ 8/ 6:X[0,1]<<=1
224 srl $a,27,$tmp1
225 add $tmp0,$e,$e
226 fmul8ulx16 %f18,$fmul,%f18 ! 5/10/ 7:Tmp>>=7, Tmp&=1
227 xor $c,$b,$tmp0
228 add $tmp1,$e,$e
229 fpadd32 $K,@X[$l],%f20 !
230 sll $b,30,$tmp2
231 xor $d,$tmp0,$tmp1
232 fxors @X[($k+13)%16],@X[$k],@X[$k] !-1/-1/-1:X[0]^=X[13]
233 srl $b,2,$b
234 add $tmp1,$e,$e
235 fxor %f18,@X[$j],@X[$j] ! 8/14/10:X[0,1]|=Tmp
236 or $tmp2,$b,$b
237 add $Xi,$e,$e
238 std %f20,[$Xfer+`4*$l`] !
239___
240$code.=<<___ if ($i==64);
241 sll $a,5,$tmp0 !! $i
242 ld [$Xfer+`4*($i%16)`],$Xi
243 fpadd32 $K,@X[$l],%f20
244 srl $a,27,$tmp1
245 add $tmp0,$e,$e
246 xor $c,$b,$tmp0
247 add $tmp1,$e,$e
248 sll $b,30,$tmp2
249 xor $d,$tmp0,$tmp1
250 std %f20,[$Xfer+`4*$l`]
251 srl $b,2,$b
252 add $tmp1,$e,$e
253 or $tmp2,$b,$b
254 add $Xi,$e,$e
255___
256$code.=<<___ if ($i>64);
257 sll $a,5,$tmp0 !! $i
258 ld [$Xfer+`4*($i%16)`],$Xi
259 srl $a,27,$tmp1
260 add $tmp0,$e,$e
261 xor $c,$b,$tmp0
262 add $tmp1,$e,$e
263 sll $b,30,$tmp2
264 xor $d,$tmp0,$tmp1
265 srl $b,2,$b
266 add $tmp1,$e,$e
267 or $tmp2,$b,$b
268 add $Xi,$e,$e
269___
270}
271
272sub BODY_40_59 {
273my ($i,$a,$b,$c,$d,$e)=@_;
274my $j=$i&~1;
275my $k=($j+16+2)%16; # ahead reference
276my $l=($j+16-2)%16; # behind reference
277my $K=@VK[($j+16-2)/20];
278
279$j=($j+16)%16;
280
281$code.=<<___ if (!($i&1));
282 sll $a,5,$tmp0 !! $i
283 ld [$Xfer+`4*($i%16)`],$Xi
284 fxors @X[($j+14)%16],@X[$j+1],@X[$j+1]! 0/ 0/ 0:X[1]^=X[14]
285 srl $a,27,$tmp1
286 add $tmp0,$e,$e
287 fxor @X[($j+2)%16],@X[($j+8)%16],%f18! 1/ 1/ 1:Tmp=X[2,3]^X[8,9]
288 and $c,$b,$tmp0
289 add $tmp1,$e,$e
290 sll $b,30,$tmp2
291 or $c,$b,$tmp1
292 fxor %f18,@X[$j],@X[$j] ! 2/ 4/ 3:X[0,1]^=X[2,3]^X[8,9]
293 srl $b,2,$b
294 and $d,$tmp1,$tmp1
295 add $Xi,$e,$e
296 or $tmp1,$tmp0,$tmp1
297 faligndata @X[$j],@X[$j],%f18 ! 3/ 7/ 5:Tmp=X[0,1]>>>24
298 or $tmp2,$b,$b
299 add $tmp1,$e,$e
300 fpadd32 @X[$j],@X[$j],@X[$j] ! 4/ 8/ 6:X[0,1]<<=1
301___
302$code.=<<___ if ($i&1);
303 sll $a,5,$tmp0 !! $i
304 ld [$Xfer+`4*($i%16)`],$Xi
305 srl $a,27,$tmp1
306 add $tmp0,$e,$e
307 fmul8ulx16 %f18,$fmul,%f18 ! 5/10/ 7:Tmp>>=7, Tmp&=1
308 and $c,$b,$tmp0
309 add $tmp1,$e,$e
310 fpadd32 $K,@X[$l],%f20 !
311 sll $b,30,$tmp2
312 or $c,$b,$tmp1
313 fxors @X[($k+13)%16],@X[$k],@X[$k] !-1/-1/-1:X[0]^=X[13]
314 srl $b,2,$b
315 and $d,$tmp1,$tmp1
316 fxor %f18,@X[$j],@X[$j] ! 8/14/10:X[0,1]|=Tmp
317 add $Xi,$e,$e
318 or $tmp1,$tmp0,$tmp1
319 or $tmp2,$b,$b
320 add $tmp1,$e,$e
321 std %f20,[$Xfer+`4*$l`] !
322___
323}
324
325# If there is more data to process, then we pre-fetch the data for
326# next iteration in last ten rounds...
327sub BODY_70_79 {
328my ($i,$a,$b,$c,$d,$e)=@_;
329my $j=$i&~1;
330my $m=($i%8)*2;
331
332$j=($j+16)%16;
333
334$code.=<<___ if ($i==70);
335 sll $a,5,$tmp0 !! $i
336 ld [$Xfer+`4*($i%16)`],$Xi
337 srl $a,27,$tmp1
338 add $tmp0,$e,$e
339 ldd [$inp+64],@X[0]
340 xor $c,$b,$tmp0
341 add $tmp1,$e,$e
342 sll $b,30,$tmp2
343 xor $d,$tmp0,$tmp1
344 srl $b,2,$b
345 add $tmp1,$e,$e
346 or $tmp2,$b,$b
347 add $Xi,$e,$e
348
349 and $inp,-64,$nXfer
350 inc 64,$inp
351 and $nXfer,255,$nXfer
352 alignaddr %g0,$align,%g0
353 add $base,$nXfer,$nXfer
354___
355$code.=<<___ if ($i==71);
356 sll $a,5,$tmp0 !! $i
357 ld [$Xfer+`4*($i%16)`],$Xi
358 srl $a,27,$tmp1
359 add $tmp0,$e,$e
360 xor $c,$b,$tmp0
361 add $tmp1,$e,$e
362 sll $b,30,$tmp2
363 xor $d,$tmp0,$tmp1
364 srl $b,2,$b
365 add $tmp1,$e,$e
366 or $tmp2,$b,$b
367 add $Xi,$e,$e
368___
369$code.=<<___ if ($i>=72);
370 faligndata @X[$m],@X[$m+2],@X[$m]
371 sll $a,5,$tmp0 !! $i
372 ld [$Xfer+`4*($i%16)`],$Xi
373 srl $a,27,$tmp1
374 add $tmp0,$e,$e
375 xor $c,$b,$tmp0
376 add $tmp1,$e,$e
377 fpadd32 $VK_00_19,@X[$m],%f20
378 sll $b,30,$tmp2
379 xor $d,$tmp0,$tmp1
380 srl $b,2,$b
381 add $tmp1,$e,$e
382 or $tmp2,$b,$b
383 add $Xi,$e,$e
384___
385$code.=<<___ if ($i<77);
386 ldd [$inp+`8*($i+1-70)`],@X[2*($i+1-70)]
387___
388$code.=<<___ if ($i==77); # redundant if $inp was aligned
389 add $align,63,$tmp0
390 and $tmp0,-8,$tmp0
391 ldd [$inp+$tmp0],@X[16]
392___
393$code.=<<___ if ($i>=72);
394 std %f20,[$nXfer+`4*$m`]
395___
396}
397
398$code.=<<___;
399.section ".text",#alloc,#execinstr
400
401.align 64
402vis_const:
403.long 0x5a827999,0x5a827999 ! K_00_19
404.long 0x6ed9eba1,0x6ed9eba1 ! K_20_39
405.long 0x8f1bbcdc,0x8f1bbcdc ! K_40_59
406.long 0xca62c1d6,0xca62c1d6 ! K_60_79
407.long 0x00000100,0x00000100
408.align 64
409.type vis_const,#object
410.size vis_const,(.-vis_const)
411
412.globl sha1_block_data_order
413sha1_block_data_order:
414 save %sp,-$frame,%sp
415 add %fp,$bias-256,$base
416
4171: call .+8
418 add %o7,vis_const-1b,$tmp0
419
420 ldd [$tmp0+0],$VK_00_19
421 ldd [$tmp0+8],$VK_20_39
422 ldd [$tmp0+16],$VK_40_59
423 ldd [$tmp0+24],$VK_60_79
424 ldd [$tmp0+32],$fmul
425
426 ld [$ctx+0],$Actx
427 and $base,-256,$base
428 ld [$ctx+4],$Bctx
429 sub $base,$bias+$frame,%sp
430 ld [$ctx+8],$Cctx
431 and $inp,7,$align
432 ld [$ctx+12],$Dctx
433 and $inp,-8,$inp
434 ld [$ctx+16],$Ectx
435
436 ! X[16] is maintained in FP register bank
437 alignaddr %g0,$align,%g0
438 ldd [$inp+0],@X[0]
439 sub $inp,-64,$Xfer
440 ldd [$inp+8],@X[2]
441 and $Xfer,-64,$Xfer
442 ldd [$inp+16],@X[4]
443 and $Xfer,255,$Xfer
444 ldd [$inp+24],@X[6]
445 add $base,$Xfer,$Xfer
446 ldd [$inp+32],@X[8]
447 ldd [$inp+40],@X[10]
448 ldd [$inp+48],@X[12]
449 brz,pt $align,.Laligned
450 ldd [$inp+56],@X[14]
451
452 ldd [$inp+64],@X[16]
453 faligndata @X[0],@X[2],@X[0]
454 faligndata @X[2],@X[4],@X[2]
455 faligndata @X[4],@X[6],@X[4]
456 faligndata @X[6],@X[8],@X[6]
457 faligndata @X[8],@X[10],@X[8]
458 faligndata @X[10],@X[12],@X[10]
459 faligndata @X[12],@X[14],@X[12]
460 faligndata @X[14],@X[16],@X[14]
461
462.Laligned:
463 mov 5,$tmp0
464 dec 1,$len
465 alignaddr %g0,$tmp0,%g0
466 fpadd32 $VK_00_19,@X[0],%f16
467 fpadd32 $VK_00_19,@X[2],%f18
468 fpadd32 $VK_00_19,@X[4],%f20
469 fpadd32 $VK_00_19,@X[6],%f22
470 fpadd32 $VK_00_19,@X[8],%f24
471 fpadd32 $VK_00_19,@X[10],%f26
472 fpadd32 $VK_00_19,@X[12],%f28
473 fpadd32 $VK_00_19,@X[14],%f30
474 std %f16,[$Xfer+0]
475 mov $Actx,$A
476 std %f18,[$Xfer+8]
477 mov $Bctx,$B
478 std %f20,[$Xfer+16]
479 mov $Cctx,$C
480 std %f22,[$Xfer+24]
481 mov $Dctx,$D
482 std %f24,[$Xfer+32]
483 mov $Ectx,$E
484 std %f26,[$Xfer+40]
485 fxors @X[13],@X[0],@X[0]
486 std %f28,[$Xfer+48]
487 ba .Loop
488 std %f30,[$Xfer+56]
489.align 32
490.Loop:
491___
492for ($i=0;$i<20;$i++) { &BODY_00_19($i,@V); unshift(@V,pop(@V)); }
493for (;$i<40;$i++) { &BODY_20_39($i,@V); unshift(@V,pop(@V)); }
494for (;$i<60;$i++) { &BODY_40_59($i,@V); unshift(@V,pop(@V)); }
495for (;$i<70;$i++) { &BODY_20_39($i,@V); unshift(@V,pop(@V)); }
496$code.=<<___;
497 tst $len
498 bz,pn `$bits==32?"%icc":"%xcc"`,.Ltail
499 nop
500___
501for (;$i<80;$i++) { &BODY_70_79($i,@V); unshift(@V,pop(@V)); }
502$code.=<<___;
503 add $A,$Actx,$Actx
504 add $B,$Bctx,$Bctx
505 add $C,$Cctx,$Cctx
506 add $D,$Dctx,$Dctx
507 add $E,$Ectx,$Ectx
508 mov 5,$tmp0
509 fxors @X[13],@X[0],@X[0]
510 mov $Actx,$A
511 mov $Bctx,$B
512 mov $Cctx,$C
513 mov $Dctx,$D
514 mov $Ectx,$E
515 alignaddr %g0,$tmp0,%g0
516 dec 1,$len
517 ba .Loop
518 mov $nXfer,$Xfer
519
520.align 32
521.Ltail:
522___
523for($i=70;$i<80;$i++) { &BODY_20_39($i,@V); unshift(@V,pop(@V)); }
524$code.=<<___;
525 add $A,$Actx,$Actx
526 add $B,$Bctx,$Bctx
527 add $C,$Cctx,$Cctx
528 add $D,$Dctx,$Dctx
529 add $E,$Ectx,$Ectx
530
531 st $Actx,[$ctx+0]
532 st $Bctx,[$ctx+4]
533 st $Cctx,[$ctx+8]
534 st $Dctx,[$ctx+12]
535 st $Ectx,[$ctx+16]
536
537 ret
538 restore
539.type sha1_block_data_order,#function
540.size sha1_block_data_order,(.-sha1_block_data_order)
541.asciz "SHA1 block transform for SPARCv9a, CRYPTOGAMS by <appro\@openssl.org>"
542___
543
544# Purpose of these subroutines is to explicitly encode VIS instructions,
545# so that one can compile the module without having to specify VIS
546# extentions on compiler command line, e.g. -xarch=v9 vs. -xarch=v9a.
547# Idea is to reserve for option to produce "universal" binary and let
548# programmer detect if current CPU is VIS capable at run-time.
549sub unvis {
550my ($mnemonic,$rs1,$rs2,$rd)=@_;
551my $ref,$opf;
552my %visopf = ( "fmul8ulx16" => 0x037,
553 "faligndata" => 0x048,
554 "fpadd32" => 0x052,
555 "fxor" => 0x06c,
556 "fxors" => 0x06d );
557
558 $ref = "$mnemonic\t$rs1,$rs2,$rd";
559
560 if ($opf=$visopf{$mnemonic}) {
561 foreach ($rs1,$rs2,$rd) {
562 return $ref if (!/%f([0-9]{1,2})/);
563 $_=$1;
564 if ($1>=32) {
565 return $ref if ($1&1);
566 # re-encode for upper double register addressing
567 $_=($1|$1>>5)&31;
568 }
569 }
570
571 return sprintf ".word\t0x%08x !%s",
572 0x81b00000|$rd<<25|$rs1<<14|$opf<<5|$rs2,
573 $ref;
574 } else {
575 return $ref;
576 }
577}
578sub unalignaddr {
579my ($mnemonic,$rs1,$rs2,$rd)=@_;
580my %bias = ( "g" => 0, "o" => 8, "l" => 16, "i" => 24 );
581my $ref="$mnemonic\t$rs1,$rs2,$rd";
582
583 foreach ($rs1,$rs2,$rd) {
584 if (/%([goli])([0-7])/) { $_=$bias{$1}+$2; }
585 else { return $ref; }
586 }
587 return sprintf ".word\t0x%08x !%s",
588 0x81b00300|$rd<<25|$rs1<<14|$rs2,
589 $ref;
590}
591
592$code =~ s/\`([^\`]*)\`/eval $1/gem;
593$code =~ s/\b(f[^\s]*)\s+(%f[0-9]{1,2}),(%f[0-9]{1,2}),(%f[0-9]{1,2})/
594 &unvis($1,$2,$3,$4)
595 /gem;
596$code =~ s/\b(alignaddr)\s+(%[goli][0-7]),(%[goli][0-7]),(%[goli][0-7])/
597 &unalignaddr($1,$2,$3,$4)
598 /gem;
599print $code;
600close STDOUT;
diff --git a/src/lib/libcrypto/sha/asm/sha1-thumb.pl b/src/lib/libcrypto/sha/asm/sha1-thumb.pl
new file mode 100644
index 0000000000..7c9ea9b029
--- /dev/null
+++ b/src/lib/libcrypto/sha/asm/sha1-thumb.pl
@@ -0,0 +1,259 @@
1#!/usr/bin/env perl
2
3# ====================================================================
4# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
5# project. The module is, however, dual licensed under OpenSSL and
6# CRYPTOGAMS licenses depending on where you obtain it. For further
7# details see http://www.openssl.org/~appro/cryptogams/.
8# ====================================================================
9
10# sha1_block for Thumb.
11#
12# January 2007.
13#
14# The code does not present direct interest to OpenSSL, because of low
15# performance. Its purpose is to establish _size_ benchmark. Pretty
16# useless one I must say, because 30% or 88 bytes larger ARMv4 code
17# [avialable on demand] is almost _twice_ as fast. It should also be
18# noted that in-lining of .Lcommon and .Lrotate improves performance
19# by over 40%, while code increases by only 10% or 32 bytes. But once
20# again, the goal was to establish _size_ benchmark, not performance.
21
22$output=shift;
23open STDOUT,">$output";
24
25$inline=0;
26#$cheat_on_binutils=1;
27
28$t0="r0";
29$t1="r1";
30$t2="r2";
31$a="r3";
32$b="r4";
33$c="r5";
34$d="r6";
35$e="r7";
36$K="r8"; # "upper" registers can be used in add/sub and mov insns
37$ctx="r9";
38$inp="r10";
39$len="r11";
40$Xi="r12";
41
42sub common {
43<<___;
44 sub $t0,#4
45 ldr $t1,[$t0]
46 add $e,$K @ E+=K_xx_xx
47 lsl $t2,$a,#5
48 add $t2,$e
49 lsr $e,$a,#27
50 add $t2,$e @ E+=ROR(A,27)
51 add $t2,$t1 @ E+=X[i]
52___
53}
54sub rotate {
55<<___;
56 mov $e,$d @ E=D
57 mov $d,$c @ D=C
58 lsl $c,$b,#30
59 lsr $b,$b,#2
60 orr $c,$b @ C=ROR(B,2)
61 mov $b,$a @ B=A
62 add $a,$t2,$t1 @ A=E+F_xx_xx(B,C,D)
63___
64}
65
66sub BODY_00_19 {
67$code.=$inline?&common():"\tbl .Lcommon\n";
68$code.=<<___;
69 mov $t1,$c
70 eor $t1,$d
71 and $t1,$b
72 eor $t1,$d @ F_00_19(B,C,D)
73___
74$code.=$inline?&rotate():"\tbl .Lrotate\n";
75}
76
77sub BODY_20_39 {
78$code.=$inline?&common():"\tbl .Lcommon\n";
79$code.=<<___;
80 mov $t1,$b
81 eor $t1,$c
82 eor $t1,$d @ F_20_39(B,C,D)
83___
84$code.=$inline?&rotate():"\tbl .Lrotate\n";
85}
86
87sub BODY_40_59 {
88$code.=$inline?&common():"\tbl .Lcommon\n";
89$code.=<<___;
90 mov $t1,$b
91 and $t1,$c
92 mov $e,$b
93 orr $e,$c
94 and $e,$d
95 orr $t1,$e @ F_40_59(B,C,D)
96___
97$code.=$inline?&rotate():"\tbl .Lrotate\n";
98}
99
100$code=<<___;
101.text
102.code 16
103
104.global sha1_block_data_order
105.type sha1_block_data_order,%function
106
107.align 2
108sha1_block_data_order:
109___
110if ($cheat_on_binutils) {
111$code.=<<___;
112.code 32
113 add r3,pc,#1
114 bx r3 @ switch to Thumb ISA
115.code 16
116___
117}
118$code.=<<___;
119 push {r4-r7}
120 mov r3,r8
121 mov r4,r9
122 mov r5,r10
123 mov r6,r11
124 mov r7,r12
125 push {r3-r7,lr}
126 lsl r2,#6
127 mov $ctx,r0 @ save context
128 mov $inp,r1 @ save inp
129 mov $len,r2 @ save len
130 add $len,$inp @ $len to point at inp end
131
132.Lloop:
133 mov $Xi,sp
134 mov $t2,sp
135 sub $t2,#16*4 @ [3]
136.LXload:
137 ldrb $a,[$t1,#0] @ $t1 is r1 and holds inp
138 ldrb $b,[$t1,#1]
139 ldrb $c,[$t1,#2]
140 ldrb $d,[$t1,#3]
141 lsl $a,#24
142 lsl $b,#16
143 lsl $c,#8
144 orr $a,$b
145 orr $a,$c
146 orr $a,$d
147 add $t1,#4
148 push {$a}
149 cmp sp,$t2
150 bne .LXload @ [+14*16]
151
152 mov $inp,$t1 @ update $inp
153 sub $t2,#32*4
154 sub $t2,#32*4
155 mov $e,#31 @ [+4]
156.LXupdate:
157 ldr $a,[sp,#15*4]
158 ldr $b,[sp,#13*4]
159 ldr $c,[sp,#7*4]
160 ldr $d,[sp,#2*4]
161 eor $a,$b
162 eor $a,$c
163 eor $a,$d
164 ror $a,$e
165 push {$a}
166 cmp sp,$t2
167 bne .LXupdate @ [+(11+1)*64]
168
169 ldmia $t0!,{$a,$b,$c,$d,$e} @ $t0 is r0 and holds ctx
170 mov $t0,$Xi
171
172 ldr $t2,.LK_00_19
173 mov $t1,$t0
174 sub $t1,#20*4
175 mov $Xi,$t1
176 mov $K,$t2 @ [+7+4]
177.L_00_19:
178___
179 &BODY_00_19();
180$code.=<<___;
181 cmp $Xi,$t0
182 bne .L_00_19 @ [+(2+9+4+2+8+2)*20]
183
184 ldr $t2,.LK_20_39
185 mov $t1,$t0
186 sub $t1,#20*4
187 mov $Xi,$t1
188 mov $K,$t2 @ [+5]
189.L_20_39_or_60_79:
190___
191 &BODY_20_39();
192$code.=<<___;
193 cmp $Xi,$t0
194 bne .L_20_39_or_60_79 @ [+(2+9+3+2+8+2)*20*2]
195 cmp sp,$t0
196 beq .Ldone @ [+2]
197
198 ldr $t2,.LK_40_59
199 mov $t1,$t0
200 sub $t1,#20*4
201 mov $Xi,$t1
202 mov $K,$t2 @ [+5]
203.L_40_59:
204___
205 &BODY_40_59();
206$code.=<<___;
207 cmp $Xi,$t0
208 bne .L_40_59 @ [+(2+9+6+2+8+2)*20]
209
210 ldr $t2,.LK_60_79
211 mov $Xi,sp
212 mov $K,$t2
213 b .L_20_39_or_60_79 @ [+4]
214.Ldone:
215 mov $t0,$ctx
216 ldr $t1,[$t0,#0]
217 ldr $t2,[$t0,#4]
218 add $a,$t1
219 ldr $t1,[$t0,#8]
220 add $b,$t2
221 ldr $t2,[$t0,#12]
222 add $c,$t1
223 ldr $t1,[$t0,#16]
224 add $d,$t2
225 add $e,$t1
226 stmia $t0!,{$a,$b,$c,$d,$e} @ [+20]
227
228 add sp,#80*4 @ deallocate stack frame
229 mov $t0,$ctx @ restore ctx
230 mov $t1,$inp @ restore inp
231 cmp $t1,$len
232 beq .Lexit
233 b .Lloop @ [+6] total 3212 cycles
234.Lexit:
235 pop {r2-r7}
236 mov r8,r2
237 mov r9,r3
238 mov r10,r4
239 mov r11,r5
240 mov r12,r6
241 mov lr,r7
242 pop {r4-r7}
243 bx lr
244.align 2
245___
246$code.=".Lcommon:\n".&common()."\tmov pc,lr\n" if (!$inline);
247$code.=".Lrotate:\n".&rotate()."\tmov pc,lr\n" if (!$inline);
248$code.=<<___;
249.align 2
250.LK_00_19: .word 0x5a827999
251.LK_20_39: .word 0x6ed9eba1
252.LK_40_59: .word 0x8f1bbcdc
253.LK_60_79: .word 0xca62c1d6
254.size sha1_block_data_order,.-sha1_block_data_order
255.asciz "SHA1 block transform for Thumb, CRYPTOGAMS by <appro\@openssl.org>"
256___
257
258print $code;
259close STDOUT; # enforce flush
diff --git a/src/lib/libcrypto/sha/asm/sha1-x86_64.pl b/src/lib/libcrypto/sha/asm/sha1-x86_64.pl
index f7ed67a726..4edc5ea9ad 100755
--- a/src/lib/libcrypto/sha/asm/sha1-x86_64.pl
+++ b/src/lib/libcrypto/sha/asm/sha1-x86_64.pl
@@ -29,14 +29,18 @@
29# Xeon P4 +65% +0% 9.9 29# Xeon P4 +65% +0% 9.9
30# Core2 +60% +10% 7.0 30# Core2 +60% +10% 7.0
31 31
32$output=shift; 32$flavour = shift;
33$output = shift;
34if ($flavour =~ /\./) { $output = $flavour; undef $flavour; }
35
36$win64=0; $win64=1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/);
33 37
34$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; 38$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
35( $xlate="${dir}x86_64-xlate.pl" and -f $xlate ) or 39( $xlate="${dir}x86_64-xlate.pl" and -f $xlate ) or
36( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or 40( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or
37die "can't locate x86_64-xlate.pl"; 41die "can't locate x86_64-xlate.pl";
38 42
39open STDOUT,"| $^X $xlate $output"; 43open STDOUT,"| $^X $xlate $flavour $output";
40 44
41$ctx="%rdi"; # 1st arg 45$ctx="%rdi"; # 1st arg
42$inp="%rsi"; # 2nd arg 46$inp="%rsi"; # 2nd arg
@@ -69,13 +73,14 @@ $func:
69 push %rbx 73 push %rbx
70 push %rbp 74 push %rbp
71 push %r12 75 push %r12
72 mov %rsp,%rax 76 mov %rsp,%r11
73 mov %rdi,$ctx # reassigned argument 77 mov %rdi,$ctx # reassigned argument
74 sub \$`8+16*4`,%rsp 78 sub \$`8+16*4`,%rsp
75 mov %rsi,$inp # reassigned argument 79 mov %rsi,$inp # reassigned argument
76 and \$-64,%rsp 80 and \$-64,%rsp
77 mov %rdx,$num # reassigned argument 81 mov %rdx,$num # reassigned argument
78 mov %rax,`16*4`(%rsp) 82 mov %r11,`16*4`(%rsp)
83.Lprologue:
79 84
80 mov 0($ctx),$A 85 mov 0($ctx),$A
81 mov 4($ctx),$B 86 mov 4($ctx),$B
@@ -88,10 +93,12 @@ ___
88sub EPILOGUE { 93sub EPILOGUE {
89my $func=shift; 94my $func=shift;
90$code.=<<___; 95$code.=<<___;
91 mov `16*4`(%rsp),%rsp 96 mov `16*4`(%rsp),%rsi
92 pop %r12 97 mov (%rsi),%r12
93 pop %rbp 98 mov 8(%rsi),%rbp
94 pop %rbx 99 mov 16(%rsi),%rbx
100 lea 24(%rsi),%rsp
101.Lepilogue:
95 ret 102 ret
96.size $func,.-$func 103.size $func,.-$func
97___ 104___
@@ -233,7 +240,109 @@ ___
233&EPILOGUE("sha1_block_data_order"); 240&EPILOGUE("sha1_block_data_order");
234$code.=<<___; 241$code.=<<___;
235.asciz "SHA1 block transform for x86_64, CRYPTOGAMS by <appro\@openssl.org>" 242.asciz "SHA1 block transform for x86_64, CRYPTOGAMS by <appro\@openssl.org>"
243.align 16
244___
245
246# EXCEPTION_DISPOSITION handler (EXCEPTION_RECORD *rec,ULONG64 frame,
247# CONTEXT *context,DISPATCHER_CONTEXT *disp)
248if ($win64) {
249$rec="%rcx";
250$frame="%rdx";
251$context="%r8";
252$disp="%r9";
253
254$code.=<<___;
255.extern __imp_RtlVirtualUnwind
256.type se_handler,\@abi-omnipotent
257.align 16
258se_handler:
259 push %rsi
260 push %rdi
261 push %rbx
262 push %rbp
263 push %r12
264 push %r13
265 push %r14
266 push %r15
267 pushfq
268 sub \$64,%rsp
269
270 mov 120($context),%rax # pull context->Rax
271 mov 248($context),%rbx # pull context->Rip
272
273 lea .Lprologue(%rip),%r10
274 cmp %r10,%rbx # context->Rip<.Lprologue
275 jb .Lin_prologue
276
277 mov 152($context),%rax # pull context->Rsp
278
279 lea .Lepilogue(%rip),%r10
280 cmp %r10,%rbx # context->Rip>=.Lepilogue
281 jae .Lin_prologue
282
283 mov `16*4`(%rax),%rax # pull saved stack pointer
284 lea 24(%rax),%rax
285
286 mov -8(%rax),%rbx
287 mov -16(%rax),%rbp
288 mov -24(%rax),%r12
289 mov %rbx,144($context) # restore context->Rbx
290 mov %rbp,160($context) # restore context->Rbp
291 mov %r12,216($context) # restore context->R12
292
293.Lin_prologue:
294 mov 8(%rax),%rdi
295 mov 16(%rax),%rsi
296 mov %rax,152($context) # restore context->Rsp
297 mov %rsi,168($context) # restore context->Rsi
298 mov %rdi,176($context) # restore context->Rdi
299
300 mov 40($disp),%rdi # disp->ContextRecord
301 mov $context,%rsi # context
302 mov \$154,%ecx # sizeof(CONTEXT)
303 .long 0xa548f3fc # cld; rep movsq
304
305 mov $disp,%rsi
306 xor %rcx,%rcx # arg1, UNW_FLAG_NHANDLER
307 mov 8(%rsi),%rdx # arg2, disp->ImageBase
308 mov 0(%rsi),%r8 # arg3, disp->ControlPc
309 mov 16(%rsi),%r9 # arg4, disp->FunctionEntry
310 mov 40(%rsi),%r10 # disp->ContextRecord
311 lea 56(%rsi),%r11 # &disp->HandlerData
312 lea 24(%rsi),%r12 # &disp->EstablisherFrame
313 mov %r10,32(%rsp) # arg5
314 mov %r11,40(%rsp) # arg6
315 mov %r12,48(%rsp) # arg7
316 mov %rcx,56(%rsp) # arg8, (NULL)
317 call *__imp_RtlVirtualUnwind(%rip)
318
319 mov \$1,%eax # ExceptionContinueSearch
320 add \$64,%rsp
321 popfq
322 pop %r15
323 pop %r14
324 pop %r13
325 pop %r12
326 pop %rbp
327 pop %rbx
328 pop %rdi
329 pop %rsi
330 ret
331.size se_handler,.-se_handler
332
333.section .pdata
334.align 4
335 .rva .LSEH_begin_sha1_block_data_order
336 .rva .LSEH_end_sha1_block_data_order
337 .rva .LSEH_info_sha1_block_data_order
338
339.section .xdata
340.align 8
341.LSEH_info_sha1_block_data_order:
342 .byte 9,0,0,0
343 .rva se_handler
236___ 344___
345}
237 346
238#################################################################### 347####################################################################
239 348
diff --git a/src/lib/libcrypto/sha/asm/sha256-586.pl b/src/lib/libcrypto/sha/asm/sha256-586.pl
new file mode 100644
index 0000000000..ecc8b69c75
--- /dev/null
+++ b/src/lib/libcrypto/sha/asm/sha256-586.pl
@@ -0,0 +1,251 @@
1#!/usr/bin/env perl
2#
3# ====================================================================
4# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
5# project. The module is, however, dual licensed under OpenSSL and
6# CRYPTOGAMS licenses depending on where you obtain it. For further
7# details see http://www.openssl.org/~appro/cryptogams/.
8# ====================================================================
9#
10# SHA256 block transform for x86. September 2007.
11#
12# Performance in clock cycles per processed byte (less is better):
13#
14# Pentium PIII P4 AMD K8 Core2
15# gcc 46 36 41 27 26
16# icc 57 33 38 25 23
17# x86 asm 40 30 35 20 20
18# x86_64 asm(*) - - 21 15.8 16.5
19#
20# (*) x86_64 assembler performance is presented for reference
21# purposes.
22#
23# Performance improvement over compiler generated code varies from
24# 10% to 40% [see above]. Not very impressive on some µ-archs, but
25# it's 5 times smaller and optimizies amount of writes.
26
27$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
28push(@INC,"${dir}","${dir}../../perlasm");
29require "x86asm.pl";
30
31&asm_init($ARGV[0],"sha512-586.pl",$ARGV[$#ARGV] eq "386");
32
33$A="eax";
34$E="edx";
35$T="ebx";
36$Aoff=&DWP(0,"esp");
37$Boff=&DWP(4,"esp");
38$Coff=&DWP(8,"esp");
39$Doff=&DWP(12,"esp");
40$Eoff=&DWP(16,"esp");
41$Foff=&DWP(20,"esp");
42$Goff=&DWP(24,"esp");
43$Hoff=&DWP(28,"esp");
44$Xoff=&DWP(32,"esp");
45$K256="ebp";
46
47sub BODY_00_15() {
48 my $in_16_63=shift;
49
50 &mov ("ecx",$E);
51 &add ($T,&DWP(4*(8+15+16-9),"esp")) if ($in_16_63); # T += X[-7]
52 &ror ("ecx",6);
53 &mov ("edi",$E);
54 &ror ("edi",11);
55 &mov ("esi",$Foff);
56 &xor ("ecx","edi");
57 &ror ("edi",25-11);
58 &mov (&DWP(4*(8+15),"esp"),$T) if ($in_16_63); # save X[0]
59 &xor ("ecx","edi"); # Sigma1(e)
60 &mov ("edi",$Goff);
61 &add ($T,"ecx"); # T += Sigma1(e)
62 &mov ($Eoff,$E); # modulo-scheduled
63
64 &xor ("esi","edi");
65 &mov ("ecx",$A);
66 &and ("esi",$E);
67 &mov ($E,$Doff); # e becomes d, which is e in next iteration
68 &xor ("esi","edi"); # Ch(e,f,g)
69 &mov ("edi",$A);
70 &add ($T,"esi"); # T += Ch(e,f,g)
71
72 &ror ("ecx",2);
73 &add ($T,$Hoff); # T += h
74 &ror ("edi",13);
75 &mov ("esi",$Boff);
76 &xor ("ecx","edi");
77 &ror ("edi",22-13);
78 &add ($E,$T); # d += T
79 &xor ("ecx","edi"); # Sigma0(a)
80 &mov ("edi",$Coff);
81
82 &add ($T,"ecx"); # T += Sigma0(a)
83 &mov ($Aoff,$A); # modulo-scheduled
84
85 &mov ("ecx",$A);
86 &sub ("esp",4);
87 &or ($A,"esi"); # a becomes h, which is a in next iteration
88 &and ("ecx","esi");
89 &and ($A,"edi");
90 &mov ("esi",&DWP(0,$K256));
91 &or ($A,"ecx"); # h=Maj(a,b,c)
92
93 &add ($K256,4);
94 &add ($A,$T); # h += T
95 &mov ($T,&DWP(4*(8+15+16-1),"esp")) if ($in_16_63); # preload T
96 &add ($E,"esi"); # d += K256[i]
97 &add ($A,"esi"); # h += K256[i]
98}
99
100&function_begin("sha256_block_data_order");
101 &mov ("esi",wparam(0)); # ctx
102 &mov ("edi",wparam(1)); # inp
103 &mov ("eax",wparam(2)); # num
104 &mov ("ebx","esp"); # saved sp
105
106 &call (&label("pic_point")); # make it PIC!
107&set_label("pic_point");
108 &blindpop($K256);
109 &lea ($K256,&DWP(&label("K256")."-".&label("pic_point"),$K256));
110
111 &sub ("esp",16);
112 &and ("esp",-64);
113
114 &shl ("eax",6);
115 &add ("eax","edi");
116 &mov (&DWP(0,"esp"),"esi"); # ctx
117 &mov (&DWP(4,"esp"),"edi"); # inp
118 &mov (&DWP(8,"esp"),"eax"); # inp+num*128
119 &mov (&DWP(12,"esp"),"ebx"); # saved sp
120
121&set_label("loop",16);
122 # copy input block to stack reversing byte and dword order
123 for($i=0;$i<4;$i++) {
124 &mov ("eax",&DWP($i*16+0,"edi"));
125 &mov ("ebx",&DWP($i*16+4,"edi"));
126 &mov ("ecx",&DWP($i*16+8,"edi"));
127 &mov ("edx",&DWP($i*16+12,"edi"));
128 &bswap ("eax");
129 &bswap ("ebx");
130 &bswap ("ecx");
131 &bswap ("edx");
132 &push ("eax");
133 &push ("ebx");
134 &push ("ecx");
135 &push ("edx");
136 }
137 &add ("edi",64);
138 &sub ("esp",4*8); # place for A,B,C,D,E,F,G,H
139 &mov (&DWP(4*(8+16)+4,"esp"),"edi");
140
141 # copy ctx->h[0-7] to A,B,C,D,E,F,G,H on stack
142 &mov ($A,&DWP(0,"esi"));
143 &mov ("ebx",&DWP(4,"esi"));
144 &mov ("ecx",&DWP(8,"esi"));
145 &mov ("edi",&DWP(12,"esi"));
146 # &mov ($Aoff,$A);
147 &mov ($Boff,"ebx");
148 &mov ($Coff,"ecx");
149 &mov ($Doff,"edi");
150 &mov ($E,&DWP(16,"esi"));
151 &mov ("ebx",&DWP(20,"esi"));
152 &mov ("ecx",&DWP(24,"esi"));
153 &mov ("edi",&DWP(28,"esi"));
154 # &mov ($Eoff,$E);
155 &mov ($Foff,"ebx");
156 &mov ($Goff,"ecx");
157 &mov ($Hoff,"edi");
158
159&set_label("00_15",16);
160 &mov ($T,&DWP(4*(8+15),"esp"));
161
162 &BODY_00_15();
163
164 &cmp ("esi",0xc19bf174);
165 &jne (&label("00_15"));
166
167 &mov ($T,&DWP(4*(8+15+16-1),"esp")); # preloaded in BODY_00_15(1)
168&set_label("16_63",16);
169 &mov ("esi",$T);
170 &mov ("ecx",&DWP(4*(8+15+16-14),"esp"));
171 &shr ($T,3);
172 &ror ("esi",7);
173 &xor ($T,"esi");
174 &ror ("esi",18-7);
175 &mov ("edi","ecx");
176 &xor ($T,"esi"); # T = sigma0(X[-15])
177
178 &shr ("ecx",10);
179 &mov ("esi",&DWP(4*(8+15+16),"esp"));
180 &ror ("edi",17);
181 &xor ("ecx","edi");
182 &ror ("edi",19-17);
183 &add ($T,"esi"); # T += X[-16]
184 &xor ("edi","ecx") # sigma1(X[-2])
185
186 &add ($T,"edi"); # T += sigma1(X[-2])
187 # &add ($T,&DWP(4*(8+15+16-9),"esp")); # T += X[-7], moved to BODY_00_15(1)
188 # &mov (&DWP(4*(8+15),"esp"),$T); # save X[0]
189
190 &BODY_00_15(1);
191
192 &cmp ("esi",0xc67178f2);
193 &jne (&label("16_63"));
194
195 &mov ("esi",&DWP(4*(8+16+64)+0,"esp"));#ctx
196 # &mov ($A,$Aoff);
197 &mov ("ebx",$Boff);
198 &mov ("ecx",$Coff);
199 &mov ("edi",$Doff);
200 &add ($A,&DWP(0,"esi"));
201 &add ("ebx",&DWP(4,"esi"));
202 &add ("ecx",&DWP(8,"esi"));
203 &add ("edi",&DWP(12,"esi"));
204 &mov (&DWP(0,"esi"),$A);
205 &mov (&DWP(4,"esi"),"ebx");
206 &mov (&DWP(8,"esi"),"ecx");
207 &mov (&DWP(12,"esi"),"edi");
208 # &mov ($E,$Eoff);
209 &mov ("eax",$Foff);
210 &mov ("ebx",$Goff);
211 &mov ("ecx",$Hoff);
212 &mov ("edi",&DWP(4*(8+16+64)+4,"esp"));#inp
213 &add ($E,&DWP(16,"esi"));
214 &add ("eax",&DWP(20,"esi"));
215 &add ("ebx",&DWP(24,"esi"));
216 &add ("ecx",&DWP(28,"esi"));
217 &mov (&DWP(16,"esi"),$E);
218 &mov (&DWP(20,"esi"),"eax");
219 &mov (&DWP(24,"esi"),"ebx");
220 &mov (&DWP(28,"esi"),"ecx");
221
222 &add ("esp",4*(8+16+64)); # destroy frame
223 &sub ($K256,4*64); # rewind K
224
225 &cmp ("edi",&DWP(8,"esp")); # are we done yet?
226 &jb (&label("loop"));
227
228 &mov ("esp",&DWP(12,"esp")); # restore sp
229&function_end_A();
230
231&set_label("K256",64); # Yes! I keep it in the code segment!
232 &data_word(0x428a2f98,0x71374491,0xb5c0fbcf,0xe9b5dba5);
233 &data_word(0x3956c25b,0x59f111f1,0x923f82a4,0xab1c5ed5);
234 &data_word(0xd807aa98,0x12835b01,0x243185be,0x550c7dc3);
235 &data_word(0x72be5d74,0x80deb1fe,0x9bdc06a7,0xc19bf174);
236 &data_word(0xe49b69c1,0xefbe4786,0x0fc19dc6,0x240ca1cc);
237 &data_word(0x2de92c6f,0x4a7484aa,0x5cb0a9dc,0x76f988da);
238 &data_word(0x983e5152,0xa831c66d,0xb00327c8,0xbf597fc7);
239 &data_word(0xc6e00bf3,0xd5a79147,0x06ca6351,0x14292967);
240 &data_word(0x27b70a85,0x2e1b2138,0x4d2c6dfc,0x53380d13);
241 &data_word(0x650a7354,0x766a0abb,0x81c2c92e,0x92722c85);
242 &data_word(0xa2bfe8a1,0xa81a664b,0xc24b8b70,0xc76c51a3);
243 &data_word(0xd192e819,0xd6990624,0xf40e3585,0x106aa070);
244 &data_word(0x19a4c116,0x1e376c08,0x2748774c,0x34b0bcb5);
245 &data_word(0x391c0cb3,0x4ed8aa4a,0x5b9cca4f,0x682e6ff3);
246 &data_word(0x748f82ee,0x78a5636f,0x84c87814,0x8cc70208);
247 &data_word(0x90befffa,0xa4506ceb,0xbef9a3f7,0xc67178f2);
248&function_end_B("sha256_block_data_order");
249&asciz("SHA256 block transform for x86, CRYPTOGAMS by <appro\@openssl.org>");
250
251&asm_finish();
diff --git a/src/lib/libcrypto/sha/asm/sha256-armv4.pl b/src/lib/libcrypto/sha/asm/sha256-armv4.pl
new file mode 100644
index 0000000000..48d846deec
--- /dev/null
+++ b/src/lib/libcrypto/sha/asm/sha256-armv4.pl
@@ -0,0 +1,181 @@
1#!/usr/bin/env perl
2
3# ====================================================================
4# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
5# project. The module is, however, dual licensed under OpenSSL and
6# CRYPTOGAMS licenses depending on where you obtain it. For further
7# details see http://www.openssl.org/~appro/cryptogams/.
8# ====================================================================
9
10# SHA256 block procedure for ARMv4. May 2007.
11
12# Performance is ~2x better than gcc 3.4 generated code and in "abso-
13# lute" terms is ~2250 cycles per 64-byte block or ~35 cycles per
14# byte.
15
16$output=shift;
17open STDOUT,">$output";
18
19$ctx="r0"; $t0="r0";
20$inp="r1";
21$len="r2"; $t1="r2";
22$T1="r3";
23$A="r4";
24$B="r5";
25$C="r6";
26$D="r7";
27$E="r8";
28$F="r9";
29$G="r10";
30$H="r11";
31@V=($A,$B,$C,$D,$E,$F,$G,$H);
32$t2="r12";
33$Ktbl="r14";
34
35@Sigma0=( 2,13,22);
36@Sigma1=( 6,11,25);
37@sigma0=( 7,18, 3);
38@sigma1=(17,19,10);
39
40sub BODY_00_15 {
41my ($i,$a,$b,$c,$d,$e,$f,$g,$h) = @_;
42
43$code.=<<___ if ($i<16);
44 ldrb $T1,[$inp,#3] @ $i
45 ldrb $t2,[$inp,#2]
46 ldrb $t1,[$inp,#1]
47 ldrb $t0,[$inp],#4
48 orr $T1,$T1,$t2,lsl#8
49 orr $T1,$T1,$t1,lsl#16
50 orr $T1,$T1,$t0,lsl#24
51 `"str $inp,[sp,#17*4]" if ($i==15)`
52___
53$code.=<<___;
54 ldr $t2,[$Ktbl],#4 @ *K256++
55 str $T1,[sp,#`$i%16`*4]
56 mov $t0,$e,ror#$Sigma1[0]
57 eor $t0,$t0,$e,ror#$Sigma1[1]
58 eor $t0,$t0,$e,ror#$Sigma1[2] @ Sigma1(e)
59 add $T1,$T1,$t0
60 eor $t1,$f,$g
61 and $t1,$t1,$e
62 eor $t1,$t1,$g @ Ch(e,f,g)
63 add $T1,$T1,$t1
64 add $T1,$T1,$h
65 add $T1,$T1,$t2
66 mov $h,$a,ror#$Sigma0[0]
67 eor $h,$h,$a,ror#$Sigma0[1]
68 eor $h,$h,$a,ror#$Sigma0[2] @ Sigma0(a)
69 orr $t0,$a,$b
70 and $t0,$t0,$c
71 and $t1,$a,$b
72 orr $t0,$t0,$t1 @ Maj(a,b,c)
73 add $h,$h,$t0
74 add $d,$d,$T1
75 add $h,$h,$T1
76___
77}
78
79sub BODY_16_XX {
80my ($i,$a,$b,$c,$d,$e,$f,$g,$h) = @_;
81
82$code.=<<___;
83 ldr $t1,[sp,#`($i+1)%16`*4] @ $i
84 ldr $t2,[sp,#`($i+14)%16`*4]
85 ldr $T1,[sp,#`($i+0)%16`*4]
86 ldr $inp,[sp,#`($i+9)%16`*4]
87 mov $t0,$t1,ror#$sigma0[0]
88 eor $t0,$t0,$t1,ror#$sigma0[1]
89 eor $t0,$t0,$t1,lsr#$sigma0[2] @ sigma0(X[i+1])
90 mov $t1,$t2,ror#$sigma1[0]
91 eor $t1,$t1,$t2,ror#$sigma1[1]
92 eor $t1,$t1,$t2,lsr#$sigma1[2] @ sigma1(X[i+14])
93 add $T1,$T1,$t0
94 add $T1,$T1,$t1
95 add $T1,$T1,$inp
96___
97 &BODY_00_15(@_);
98}
99
100$code=<<___;
101.text
102.code 32
103
104.type K256,%object
105.align 5
106K256:
107.word 0x428a2f98,0x71374491,0xb5c0fbcf,0xe9b5dba5
108.word 0x3956c25b,0x59f111f1,0x923f82a4,0xab1c5ed5
109.word 0xd807aa98,0x12835b01,0x243185be,0x550c7dc3
110.word 0x72be5d74,0x80deb1fe,0x9bdc06a7,0xc19bf174
111.word 0xe49b69c1,0xefbe4786,0x0fc19dc6,0x240ca1cc
112.word 0x2de92c6f,0x4a7484aa,0x5cb0a9dc,0x76f988da
113.word 0x983e5152,0xa831c66d,0xb00327c8,0xbf597fc7
114.word 0xc6e00bf3,0xd5a79147,0x06ca6351,0x14292967
115.word 0x27b70a85,0x2e1b2138,0x4d2c6dfc,0x53380d13
116.word 0x650a7354,0x766a0abb,0x81c2c92e,0x92722c85
117.word 0xa2bfe8a1,0xa81a664b,0xc24b8b70,0xc76c51a3
118.word 0xd192e819,0xd6990624,0xf40e3585,0x106aa070
119.word 0x19a4c116,0x1e376c08,0x2748774c,0x34b0bcb5
120.word 0x391c0cb3,0x4ed8aa4a,0x5b9cca4f,0x682e6ff3
121.word 0x748f82ee,0x78a5636f,0x84c87814,0x8cc70208
122.word 0x90befffa,0xa4506ceb,0xbef9a3f7,0xc67178f2
123.size K256,.-K256
124
125.global sha256_block_data_order
126.type sha256_block_data_order,%function
127sha256_block_data_order:
128 sub r3,pc,#8 @ sha256_block_data_order
129 add $len,$inp,$len,lsl#6 @ len to point at the end of inp
130 stmdb sp!,{$ctx,$inp,$len,r4-r12,lr}
131 ldmia $ctx,{$A,$B,$C,$D,$E,$F,$G,$H}
132 sub $Ktbl,r3,#256 @ K256
133 sub sp,sp,#16*4 @ alloca(X[16])
134.Loop:
135___
136for($i=0;$i<16;$i++) { &BODY_00_15($i,@V); unshift(@V,pop(@V)); }
137$code.=".Lrounds_16_xx:\n";
138for (;$i<32;$i++) { &BODY_16_XX($i,@V); unshift(@V,pop(@V)); }
139$code.=<<___;
140 and $t2,$t2,#0xff
141 cmp $t2,#0xf2
142 bne .Lrounds_16_xx
143
144 ldr $T1,[sp,#16*4] @ pull ctx
145 ldr $t0,[$T1,#0]
146 ldr $t1,[$T1,#4]
147 ldr $t2,[$T1,#8]
148 add $A,$A,$t0
149 ldr $t0,[$T1,#12]
150 add $B,$B,$t1
151 ldr $t1,[$T1,#16]
152 add $C,$C,$t2
153 ldr $t2,[$T1,#20]
154 add $D,$D,$t0
155 ldr $t0,[$T1,#24]
156 add $E,$E,$t1
157 ldr $t1,[$T1,#28]
158 add $F,$F,$t2
159 ldr $inp,[sp,#17*4] @ pull inp
160 ldr $t2,[sp,#18*4] @ pull inp+len
161 add $G,$G,$t0
162 add $H,$H,$t1
163 stmia $T1,{$A,$B,$C,$D,$E,$F,$G,$H}
164 cmp $inp,$t2
165 sub $Ktbl,$Ktbl,#256 @ rewind Ktbl
166 bne .Loop
167
168 add sp,sp,#`16+3`*4 @ destroy frame
169 ldmia sp!,{r4-r12,lr}
170 tst lr,#1
171 moveq pc,lr @ be binary compatible with V4, yet
172 bx lr @ interoperable with Thumb ISA:-)
173.size sha256_block_data_order,.-sha256_block_data_order
174.asciz "SHA256 block transform for ARMv4, CRYPTOGAMS by <appro\@openssl.org>"
175.align 2
176___
177
178$code =~ s/\`([^\`]*)\`/eval $1/gem;
179$code =~ s/\bbx\s+lr\b/.word\t0xe12fff1e/gm; # make it possible to compile with -march=armv4
180print $code;
181close STDOUT; # enforce flush
diff --git a/src/lib/libcrypto/sha/asm/sha512-586.pl b/src/lib/libcrypto/sha/asm/sha512-586.pl
new file mode 100644
index 0000000000..5b9f3337ad
--- /dev/null
+++ b/src/lib/libcrypto/sha/asm/sha512-586.pl
@@ -0,0 +1,644 @@
1#!/usr/bin/env perl
2#
3# ====================================================================
4# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
5# project. The module is, however, dual licensed under OpenSSL and
6# CRYPTOGAMS licenses depending on where you obtain it. For further
7# details see http://www.openssl.org/~appro/cryptogams/.
8# ====================================================================
9#
10# SHA512 block transform for x86. September 2007.
11#
12# Performance in clock cycles per processed byte (less is better):
13#
14# Pentium PIII P4 AMD K8 Core2
15# gcc 100 75 116 54 66
16# icc 97 77 95 55 57
17# x86 asm 61 56 82 36 40
18# SSE2 asm - - 38 24 20
19# x86_64 asm(*) - - 30 10.0 10.5
20#
21# (*) x86_64 assembler performance is presented for reference
22# purposes.
23#
24# IALU code-path is optimized for elder Pentiums. On vanilla Pentium
25# performance improvement over compiler generated code reaches ~60%,
26# while on PIII - ~35%. On newer µ-archs improvement varies from 15%
27# to 50%, but it's less important as they are expected to execute SSE2
28# code-path, which is commonly ~2-3x faster [than compiler generated
29# code]. SSE2 code-path is as fast as original sha512-sse2.pl, even
30# though it does not use 128-bit operations. The latter means that
31# SSE2-aware kernel is no longer required to execute the code. Another
32# difference is that new code optimizes amount of writes, but at the
33# cost of increased data cache "footprint" by 1/2KB.
34
35$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
36push(@INC,"${dir}","${dir}../../perlasm");
37require "x86asm.pl";
38
39&asm_init($ARGV[0],"sha512-586.pl",$ARGV[$#ARGV] eq "386");
40
41$sse2=0;
42for (@ARGV) { $sse2=1 if (/-DOPENSSL_IA32_SSE2/); }
43
44&external_label("OPENSSL_ia32cap_P") if ($sse2);
45
46$Tlo=&DWP(0,"esp"); $Thi=&DWP(4,"esp");
47$Alo=&DWP(8,"esp"); $Ahi=&DWP(8+4,"esp");
48$Blo=&DWP(16,"esp"); $Bhi=&DWP(16+4,"esp");
49$Clo=&DWP(24,"esp"); $Chi=&DWP(24+4,"esp");
50$Dlo=&DWP(32,"esp"); $Dhi=&DWP(32+4,"esp");
51$Elo=&DWP(40,"esp"); $Ehi=&DWP(40+4,"esp");
52$Flo=&DWP(48,"esp"); $Fhi=&DWP(48+4,"esp");
53$Glo=&DWP(56,"esp"); $Ghi=&DWP(56+4,"esp");
54$Hlo=&DWP(64,"esp"); $Hhi=&DWP(64+4,"esp");
55$K512="ebp";
56
57$Asse2=&QWP(0,"esp");
58$Bsse2=&QWP(8,"esp");
59$Csse2=&QWP(16,"esp");
60$Dsse2=&QWP(24,"esp");
61$Esse2=&QWP(32,"esp");
62$Fsse2=&QWP(40,"esp");
63$Gsse2=&QWP(48,"esp");
64$Hsse2=&QWP(56,"esp");
65
66$A="mm0"; # B-D and
67$E="mm4"; # F-H are commonly loaded to respectively mm1-mm3 and
68 # mm5-mm7, but it's done on on-demand basis...
69
70sub BODY_00_15_sse2 {
71 my $prefetch=shift;
72
73 &movq ("mm5",$Fsse2); # load f
74 &movq ("mm6",$Gsse2); # load g
75 &movq ("mm7",$Hsse2); # load h
76
77 &movq ("mm1",$E); # %mm1 is sliding right
78 &movq ("mm2",$E); # %mm2 is sliding left
79 &psrlq ("mm1",14);
80 &movq ($Esse2,$E); # modulo-scheduled save e
81 &psllq ("mm2",23);
82 &movq ("mm3","mm1"); # %mm3 is T1
83 &psrlq ("mm1",4);
84 &pxor ("mm3","mm2");
85 &psllq ("mm2",23);
86 &pxor ("mm3","mm1");
87 &psrlq ("mm1",23);
88 &pxor ("mm3","mm2");
89 &psllq ("mm2",4);
90 &pxor ("mm3","mm1");
91 &paddq ("mm7",QWP(0,$K512)); # h+=K512[i]
92 &pxor ("mm3","mm2"); # T1=Sigma1_512(e)
93
94 &pxor ("mm5","mm6"); # f^=g
95 &movq ("mm1",$Bsse2); # load b
96 &pand ("mm5",$E); # f&=e
97 &movq ("mm2",$Csse2); # load c
98 &pxor ("mm5","mm6"); # f^=g
99 &movq ($E,$Dsse2); # e = load d
100 &paddq ("mm3","mm5"); # T1+=Ch(e,f,g)
101 &movq (&QWP(0,"esp"),$A); # modulo-scheduled save a
102 &paddq ("mm3","mm7"); # T1+=h
103
104 &movq ("mm5",$A); # %mm5 is sliding right
105 &movq ("mm6",$A); # %mm6 is sliding left
106 &paddq ("mm3",&QWP(8*9,"esp")); # T1+=X[0]
107 &psrlq ("mm5",28);
108 &paddq ($E,"mm3"); # e += T1
109 &psllq ("mm6",25);
110 &movq ("mm7","mm5"); # %mm7 is T2
111 &psrlq ("mm5",6);
112 &pxor ("mm7","mm6");
113 &psllq ("mm6",5);
114 &pxor ("mm7","mm5");
115 &psrlq ("mm5",5);
116 &pxor ("mm7","mm6");
117 &psllq ("mm6",6);
118 &pxor ("mm7","mm5");
119 &sub ("esp",8);
120 &pxor ("mm7","mm6"); # T2=Sigma0_512(a)
121
122 &movq ("mm5",$A); # %mm5=a
123 &por ($A,"mm2"); # a=a|c
124 &movq ("mm6",&QWP(8*(9+16-14),"esp")) if ($prefetch);
125 &pand ("mm5","mm2"); # %mm5=a&c
126 &pand ($A,"mm1"); # a=(a|c)&b
127 &movq ("mm2",&QWP(8*(9+16-1),"esp")) if ($prefetch);
128 &por ("mm5",$A); # %mm5=(a&c)|((a|c)&b)
129 &paddq ("mm7","mm5"); # T2+=Maj(a,b,c)
130 &movq ($A,"mm3"); # a=T1
131
132 &mov (&LB("edx"),&BP(0,$K512));
133 &paddq ($A,"mm7"); # a+=T2
134 &add ($K512,8);
135}
136
137sub BODY_00_15_x86 {
138 #define Sigma1(x) (ROTR((x),14) ^ ROTR((x),18) ^ ROTR((x),41))
139 # LO lo>>14^hi<<18 ^ lo>>18^hi<<14 ^ hi>>9^lo<<23
140 # HI hi>>14^lo<<18 ^ hi>>18^lo<<14 ^ lo>>9^hi<<23
141 &mov ("ecx",$Elo);
142 &mov ("edx",$Ehi);
143 &mov ("esi","ecx");
144
145 &shr ("ecx",9) # lo>>9
146 &mov ("edi","edx");
147 &shr ("edx",9) # hi>>9
148 &mov ("ebx","ecx");
149 &shl ("esi",14); # lo<<14
150 &mov ("eax","edx");
151 &shl ("edi",14); # hi<<14
152 &xor ("ebx","esi");
153
154 &shr ("ecx",14-9); # lo>>14
155 &xor ("eax","edi");
156 &shr ("edx",14-9); # hi>>14
157 &xor ("eax","ecx");
158 &shl ("esi",18-14); # lo<<18
159 &xor ("ebx","edx");
160 &shl ("edi",18-14); # hi<<18
161 &xor ("ebx","esi");
162
163 &shr ("ecx",18-14); # lo>>18
164 &xor ("eax","edi");
165 &shr ("edx",18-14); # hi>>18
166 &xor ("eax","ecx");
167 &shl ("esi",23-18); # lo<<23
168 &xor ("ebx","edx");
169 &shl ("edi",23-18); # hi<<23
170 &xor ("eax","esi");
171 &xor ("ebx","edi"); # T1 = Sigma1(e)
172
173 &mov ("ecx",$Flo);
174 &mov ("edx",$Fhi);
175 &mov ("esi",$Glo);
176 &mov ("edi",$Ghi);
177 &add ("eax",$Hlo);
178 &adc ("ebx",$Hhi); # T1 += h
179 &xor ("ecx","esi");
180 &xor ("edx","edi");
181 &and ("ecx",$Elo);
182 &and ("edx",$Ehi);
183 &add ("eax",&DWP(8*(9+15)+0,"esp"));
184 &adc ("ebx",&DWP(8*(9+15)+4,"esp")); # T1 += X[0]
185 &xor ("ecx","esi");
186 &xor ("edx","edi"); # Ch(e,f,g) = (f^g)&e)^g
187
188 &mov ("esi",&DWP(0,$K512));
189 &mov ("edi",&DWP(4,$K512)); # K[i]
190 &add ("eax","ecx");
191 &adc ("ebx","edx"); # T1 += Ch(e,f,g)
192 &mov ("ecx",$Dlo);
193 &mov ("edx",$Dhi);
194 &add ("eax","esi");
195 &adc ("ebx","edi"); # T1 += K[i]
196 &mov ($Tlo,"eax");
197 &mov ($Thi,"ebx"); # put T1 away
198 &add ("eax","ecx");
199 &adc ("ebx","edx"); # d += T1
200
201 #define Sigma0(x) (ROTR((x),28) ^ ROTR((x),34) ^ ROTR((x),39))
202 # LO lo>>28^hi<<4 ^ hi>>2^lo<<30 ^ hi>>7^lo<<25
203 # HI hi>>28^lo<<4 ^ lo>>2^hi<<30 ^ lo>>7^hi<<25
204 &mov ("ecx",$Alo);
205 &mov ("edx",$Ahi);
206 &mov ($Dlo,"eax");
207 &mov ($Dhi,"ebx");
208 &mov ("esi","ecx");
209
210 &shr ("ecx",2) # lo>>2
211 &mov ("edi","edx");
212 &shr ("edx",2) # hi>>2
213 &mov ("ebx","ecx");
214 &shl ("esi",4); # lo<<4
215 &mov ("eax","edx");
216 &shl ("edi",4); # hi<<4
217 &xor ("ebx","esi");
218
219 &shr ("ecx",7-2); # lo>>7
220 &xor ("eax","edi");
221 &shr ("edx",7-2); # hi>>7
222 &xor ("ebx","ecx");
223 &shl ("esi",25-4); # lo<<25
224 &xor ("eax","edx");
225 &shl ("edi",25-4); # hi<<25
226 &xor ("eax","esi");
227
228 &shr ("ecx",28-7); # lo>>28
229 &xor ("ebx","edi");
230 &shr ("edx",28-7); # hi>>28
231 &xor ("eax","ecx");
232 &shl ("esi",30-25); # lo<<30
233 &xor ("ebx","edx");
234 &shl ("edi",30-25); # hi<<30
235 &xor ("eax","esi");
236 &xor ("ebx","edi"); # Sigma0(a)
237
238 &mov ("ecx",$Alo);
239 &mov ("edx",$Ahi);
240 &mov ("esi",$Blo);
241 &mov ("edi",$Bhi);
242 &add ("eax",$Tlo);
243 &adc ("ebx",$Thi); # T1 = Sigma0(a)+T1
244 &or ("ecx","esi");
245 &or ("edx","edi");
246 &and ("ecx",$Clo);
247 &and ("edx",$Chi);
248 &and ("esi",$Alo);
249 &and ("edi",$Ahi);
250 &or ("ecx","esi");
251 &or ("edx","edi"); # Maj(a,b,c) = ((a|b)&c)|(a&b)
252
253 &add ("eax","ecx");
254 &adc ("ebx","edx"); # T1 += Maj(a,b,c)
255 &mov ($Tlo,"eax");
256 &mov ($Thi,"ebx");
257
258 &mov (&LB("edx"),&BP(0,$K512)); # pre-fetch LSB of *K
259 &sub ("esp",8);
260 &lea ($K512,&DWP(8,$K512)); # K++
261}
262
263
264&function_begin("sha512_block_data_order");
265 &mov ("esi",wparam(0)); # ctx
266 &mov ("edi",wparam(1)); # inp
267 &mov ("eax",wparam(2)); # num
268 &mov ("ebx","esp"); # saved sp
269
270 &call (&label("pic_point")); # make it PIC!
271&set_label("pic_point");
272 &blindpop($K512);
273 &lea ($K512,&DWP(&label("K512")."-".&label("pic_point"),$K512));
274
275 &sub ("esp",16);
276 &and ("esp",-64);
277
278 &shl ("eax",7);
279 &add ("eax","edi");
280 &mov (&DWP(0,"esp"),"esi"); # ctx
281 &mov (&DWP(4,"esp"),"edi"); # inp
282 &mov (&DWP(8,"esp"),"eax"); # inp+num*128
283 &mov (&DWP(12,"esp"),"ebx"); # saved sp
284
285if ($sse2) {
286 &picmeup("edx","OPENSSL_ia32cap_P",$K512,&label("K512"));
287 &bt (&DWP(0,"edx"),26);
288 &jnc (&label("loop_x86"));
289
290 # load ctx->h[0-7]
291 &movq ($A,&QWP(0,"esi"));
292 &movq ("mm1",&QWP(8,"esi"));
293 &movq ("mm2",&QWP(16,"esi"));
294 &movq ("mm3",&QWP(24,"esi"));
295 &movq ($E,&QWP(32,"esi"));
296 &movq ("mm5",&QWP(40,"esi"));
297 &movq ("mm6",&QWP(48,"esi"));
298 &movq ("mm7",&QWP(56,"esi"));
299 &sub ("esp",8*10);
300
301&set_label("loop_sse2",16);
302 # &movq ($Asse2,$A);
303 &movq ($Bsse2,"mm1");
304 &movq ($Csse2,"mm2");
305 &movq ($Dsse2,"mm3");
306 # &movq ($Esse2,$E);
307 &movq ($Fsse2,"mm5");
308 &movq ($Gsse2,"mm6");
309 &movq ($Hsse2,"mm7");
310
311 &mov ("ecx",&DWP(0,"edi"));
312 &mov ("edx",&DWP(4,"edi"));
313 &add ("edi",8);
314 &bswap ("ecx");
315 &bswap ("edx");
316 &mov (&DWP(8*9+4,"esp"),"ecx");
317 &mov (&DWP(8*9+0,"esp"),"edx");
318
319&set_label("00_14_sse2",16);
320 &mov ("eax",&DWP(0,"edi"));
321 &mov ("ebx",&DWP(4,"edi"));
322 &add ("edi",8);
323 &bswap ("eax");
324 &bswap ("ebx");
325 &mov (&DWP(8*8+4,"esp"),"eax");
326 &mov (&DWP(8*8+0,"esp"),"ebx");
327
328 &BODY_00_15_sse2();
329
330 &cmp (&LB("edx"),0x35);
331 &jne (&label("00_14_sse2"));
332
333 &BODY_00_15_sse2(1);
334
335&set_label("16_79_sse2",16);
336 #&movq ("mm2",&QWP(8*(9+16-1),"esp")); #prefetched in BODY_00_15
337 #&movq ("mm6",&QWP(8*(9+16-14),"esp"));
338 &movq ("mm1","mm2");
339
340 &psrlq ("mm2",1);
341 &movq ("mm7","mm6");
342 &psrlq ("mm6",6);
343 &movq ("mm3","mm2");
344
345 &psrlq ("mm2",7-1);
346 &movq ("mm5","mm6");
347 &psrlq ("mm6",19-6);
348 &pxor ("mm3","mm2");
349
350 &psrlq ("mm2",8-7);
351 &pxor ("mm5","mm6");
352 &psrlq ("mm6",61-19);
353 &pxor ("mm3","mm2");
354
355 &movq ("mm2",&QWP(8*(9+16),"esp"));
356
357 &psllq ("mm1",56);
358 &pxor ("mm5","mm6");
359 &psllq ("mm7",3);
360 &pxor ("mm3","mm1");
361
362 &paddq ("mm2",&QWP(8*(9+16-9),"esp"));
363
364 &psllq ("mm1",63-56);
365 &pxor ("mm5","mm7");
366 &psllq ("mm7",45-3);
367 &pxor ("mm3","mm1");
368 &pxor ("mm5","mm7");
369
370 &paddq ("mm3","mm5");
371 &paddq ("mm3","mm2");
372 &movq (&QWP(8*9,"esp"),"mm3");
373
374 &BODY_00_15_sse2(1);
375
376 &cmp (&LB("edx"),0x17);
377 &jne (&label("16_79_sse2"));
378
379 # &movq ($A,$Asse2);
380 &movq ("mm1",$Bsse2);
381 &movq ("mm2",$Csse2);
382 &movq ("mm3",$Dsse2);
383 # &movq ($E,$Esse2);
384 &movq ("mm5",$Fsse2);
385 &movq ("mm6",$Gsse2);
386 &movq ("mm7",$Hsse2);
387
388 &paddq ($A,&QWP(0,"esi"));
389 &paddq ("mm1",&QWP(8,"esi"));
390 &paddq ("mm2",&QWP(16,"esi"));
391 &paddq ("mm3",&QWP(24,"esi"));
392 &paddq ($E,&QWP(32,"esi"));
393 &paddq ("mm5",&QWP(40,"esi"));
394 &paddq ("mm6",&QWP(48,"esi"));
395 &paddq ("mm7",&QWP(56,"esi"));
396
397 &movq (&QWP(0,"esi"),$A);
398 &movq (&QWP(8,"esi"),"mm1");
399 &movq (&QWP(16,"esi"),"mm2");
400 &movq (&QWP(24,"esi"),"mm3");
401 &movq (&QWP(32,"esi"),$E);
402 &movq (&QWP(40,"esi"),"mm5");
403 &movq (&QWP(48,"esi"),"mm6");
404 &movq (&QWP(56,"esi"),"mm7");
405
406 &add ("esp",8*80); # destroy frame
407 &sub ($K512,8*80); # rewind K
408
409 &cmp ("edi",&DWP(8*10+8,"esp")); # are we done yet?
410 &jb (&label("loop_sse2"));
411
412 &emms ();
413 &mov ("esp",&DWP(8*10+12,"esp")); # restore sp
414&function_end_A();
415}
416&set_label("loop_x86",16);
417 # copy input block to stack reversing byte and qword order
418 for ($i=0;$i<8;$i++) {
419 &mov ("eax",&DWP($i*16+0,"edi"));
420 &mov ("ebx",&DWP($i*16+4,"edi"));
421 &mov ("ecx",&DWP($i*16+8,"edi"));
422 &mov ("edx",&DWP($i*16+12,"edi"));
423 &bswap ("eax");
424 &bswap ("ebx");
425 &bswap ("ecx");
426 &bswap ("edx");
427 &push ("eax");
428 &push ("ebx");
429 &push ("ecx");
430 &push ("edx");
431 }
432 &add ("edi",128);
433 &sub ("esp",9*8); # place for T,A,B,C,D,E,F,G,H
434 &mov (&DWP(8*(9+16)+4,"esp"),"edi");
435
436 # copy ctx->h[0-7] to A,B,C,D,E,F,G,H on stack
437 &lea ("edi",&DWP(8,"esp"));
438 &mov ("ecx",16);
439 &data_word(0xA5F3F689); # rep movsd
440
441&set_label("00_15_x86",16);
442 &BODY_00_15_x86();
443
444 &cmp (&LB("edx"),0x94);
445 &jne (&label("00_15_x86"));
446
447&set_label("16_79_x86",16);
448 #define sigma0(x) (ROTR((x),1) ^ ROTR((x),8) ^ ((x)>>7))
449 # LO lo>>1^hi<<31 ^ lo>>8^hi<<24 ^ lo>>7^hi<<25
450 # HI hi>>1^lo<<31 ^ hi>>8^lo<<24 ^ hi>>7
451 &mov ("ecx",&DWP(8*(9+15+16-1)+0,"esp"));
452 &mov ("edx",&DWP(8*(9+15+16-1)+4,"esp"));
453 &mov ("esi","ecx");
454
455 &shr ("ecx",1) # lo>>1
456 &mov ("edi","edx");
457 &shr ("edx",1) # hi>>1
458 &mov ("eax","ecx");
459 &shl ("esi",24); # lo<<24
460 &mov ("ebx","edx");
461 &shl ("edi",24); # hi<<24
462 &xor ("ebx","esi");
463
464 &shr ("ecx",7-1); # lo>>7
465 &xor ("eax","edi");
466 &shr ("edx",7-1); # hi>>7
467 &xor ("eax","ecx");
468 &shl ("esi",31-24); # lo<<31
469 &xor ("ebx","edx");
470 &shl ("edi",25-24); # hi<<25
471 &xor ("ebx","esi");
472
473 &shr ("ecx",8-7); # lo>>8
474 &xor ("eax","edi");
475 &shr ("edx",8-7); # hi>>8
476 &xor ("eax","ecx");
477 &shl ("edi",31-25); # hi<<31
478 &xor ("ebx","edx");
479 &xor ("eax","edi"); # T1 = sigma0(X[-15])
480
481 &mov (&DWP(0,"esp"),"eax");
482 &mov (&DWP(4,"esp"),"ebx"); # put T1 away
483
484 #define sigma1(x) (ROTR((x),19) ^ ROTR((x),61) ^ ((x)>>6))
485 # LO lo>>19^hi<<13 ^ hi>>29^lo<<3 ^ lo>>6^hi<<26
486 # HI hi>>19^lo<<13 ^ lo>>29^hi<<3 ^ hi>>6
487 &mov ("ecx",&DWP(8*(9+15+16-14)+0,"esp"));
488 &mov ("edx",&DWP(8*(9+15+16-14)+4,"esp"));
489 &mov ("esi","ecx");
490
491 &shr ("ecx",6) # lo>>6
492 &mov ("edi","edx");
493 &shr ("edx",6) # hi>>6
494 &mov ("eax","ecx");
495 &shl ("esi",3); # lo<<3
496 &mov ("ebx","edx");
497 &shl ("edi",3); # hi<<3
498 &xor ("eax","esi");
499
500 &shr ("ecx",19-6); # lo>>19
501 &xor ("ebx","edi");
502 &shr ("edx",19-6); # hi>>19
503 &xor ("eax","ecx");
504 &shl ("esi",13-3); # lo<<13
505 &xor ("ebx","edx");
506 &shl ("edi",13-3); # hi<<13
507 &xor ("ebx","esi");
508
509 &shr ("ecx",29-19); # lo>>29
510 &xor ("eax","edi");
511 &shr ("edx",29-19); # hi>>29
512 &xor ("ebx","ecx");
513 &shl ("edi",26-13); # hi<<26
514 &xor ("eax","edx");
515 &xor ("eax","edi"); # sigma1(X[-2])
516
517 &mov ("ecx",&DWP(8*(9+15+16)+0,"esp"));
518 &mov ("edx",&DWP(8*(9+15+16)+4,"esp"));
519 &add ("eax",&DWP(0,"esp"));
520 &adc ("ebx",&DWP(4,"esp")); # T1 = sigma1(X[-2])+T1
521 &mov ("esi",&DWP(8*(9+15+16-9)+0,"esp"));
522 &mov ("edi",&DWP(8*(9+15+16-9)+4,"esp"));
523 &add ("eax","ecx");
524 &adc ("ebx","edx"); # T1 += X[-16]
525 &add ("eax","esi");
526 &adc ("ebx","edi"); # T1 += X[-7]
527 &mov (&DWP(8*(9+15)+0,"esp"),"eax");
528 &mov (&DWP(8*(9+15)+4,"esp"),"ebx"); # save X[0]
529
530 &BODY_00_15_x86();
531
532 &cmp (&LB("edx"),0x17);
533 &jne (&label("16_79_x86"));
534
535 &mov ("esi",&DWP(8*(9+16+80)+0,"esp"));# ctx
536 &mov ("edi",&DWP(8*(9+16+80)+4,"esp"));# inp
537 for($i=0;$i<4;$i++) {
538 &mov ("eax",&DWP($i*16+0,"esi"));
539 &mov ("ebx",&DWP($i*16+4,"esi"));
540 &mov ("ecx",&DWP($i*16+8,"esi"));
541 &mov ("edx",&DWP($i*16+12,"esi"));
542 &add ("eax",&DWP(8+($i*16)+0,"esp"));
543 &adc ("ebx",&DWP(8+($i*16)+4,"esp"));
544 &mov (&DWP($i*16+0,"esi"),"eax");
545 &mov (&DWP($i*16+4,"esi"),"ebx");
546 &add ("ecx",&DWP(8+($i*16)+8,"esp"));
547 &adc ("edx",&DWP(8+($i*16)+12,"esp"));
548 &mov (&DWP($i*16+8,"esi"),"ecx");
549 &mov (&DWP($i*16+12,"esi"),"edx");
550 }
551 &add ("esp",8*(9+16+80)); # destroy frame
552 &sub ($K512,8*80); # rewind K
553
554 &cmp ("edi",&DWP(8,"esp")); # are we done yet?
555 &jb (&label("loop_x86"));
556
557 &mov ("esp",&DWP(12,"esp")); # restore sp
558&function_end_A();
559
560&set_label("K512",64); # Yes! I keep it in the code segment!
561 &data_word(0xd728ae22,0x428a2f98); # u64
562 &data_word(0x23ef65cd,0x71374491); # u64
563 &data_word(0xec4d3b2f,0xb5c0fbcf); # u64
564 &data_word(0x8189dbbc,0xe9b5dba5); # u64
565 &data_word(0xf348b538,0x3956c25b); # u64
566 &data_word(0xb605d019,0x59f111f1); # u64
567 &data_word(0xaf194f9b,0x923f82a4); # u64
568 &data_word(0xda6d8118,0xab1c5ed5); # u64
569 &data_word(0xa3030242,0xd807aa98); # u64
570 &data_word(0x45706fbe,0x12835b01); # u64
571 &data_word(0x4ee4b28c,0x243185be); # u64
572 &data_word(0xd5ffb4e2,0x550c7dc3); # u64
573 &data_word(0xf27b896f,0x72be5d74); # u64
574 &data_word(0x3b1696b1,0x80deb1fe); # u64
575 &data_word(0x25c71235,0x9bdc06a7); # u64
576 &data_word(0xcf692694,0xc19bf174); # u64
577 &data_word(0x9ef14ad2,0xe49b69c1); # u64
578 &data_word(0x384f25e3,0xefbe4786); # u64
579 &data_word(0x8b8cd5b5,0x0fc19dc6); # u64
580 &data_word(0x77ac9c65,0x240ca1cc); # u64
581 &data_word(0x592b0275,0x2de92c6f); # u64
582 &data_word(0x6ea6e483,0x4a7484aa); # u64
583 &data_word(0xbd41fbd4,0x5cb0a9dc); # u64
584 &data_word(0x831153b5,0x76f988da); # u64
585 &data_word(0xee66dfab,0x983e5152); # u64
586 &data_word(0x2db43210,0xa831c66d); # u64
587 &data_word(0x98fb213f,0xb00327c8); # u64
588 &data_word(0xbeef0ee4,0xbf597fc7); # u64
589 &data_word(0x3da88fc2,0xc6e00bf3); # u64
590 &data_word(0x930aa725,0xd5a79147); # u64
591 &data_word(0xe003826f,0x06ca6351); # u64
592 &data_word(0x0a0e6e70,0x14292967); # u64
593 &data_word(0x46d22ffc,0x27b70a85); # u64
594 &data_word(0x5c26c926,0x2e1b2138); # u64
595 &data_word(0x5ac42aed,0x4d2c6dfc); # u64
596 &data_word(0x9d95b3df,0x53380d13); # u64
597 &data_word(0x8baf63de,0x650a7354); # u64
598 &data_word(0x3c77b2a8,0x766a0abb); # u64
599 &data_word(0x47edaee6,0x81c2c92e); # u64
600 &data_word(0x1482353b,0x92722c85); # u64
601 &data_word(0x4cf10364,0xa2bfe8a1); # u64
602 &data_word(0xbc423001,0xa81a664b); # u64
603 &data_word(0xd0f89791,0xc24b8b70); # u64
604 &data_word(0x0654be30,0xc76c51a3); # u64
605 &data_word(0xd6ef5218,0xd192e819); # u64
606 &data_word(0x5565a910,0xd6990624); # u64
607 &data_word(0x5771202a,0xf40e3585); # u64
608 &data_word(0x32bbd1b8,0x106aa070); # u64
609 &data_word(0xb8d2d0c8,0x19a4c116); # u64
610 &data_word(0x5141ab53,0x1e376c08); # u64
611 &data_word(0xdf8eeb99,0x2748774c); # u64
612 &data_word(0xe19b48a8,0x34b0bcb5); # u64
613 &data_word(0xc5c95a63,0x391c0cb3); # u64
614 &data_word(0xe3418acb,0x4ed8aa4a); # u64
615 &data_word(0x7763e373,0x5b9cca4f); # u64
616 &data_word(0xd6b2b8a3,0x682e6ff3); # u64
617 &data_word(0x5defb2fc,0x748f82ee); # u64
618 &data_word(0x43172f60,0x78a5636f); # u64
619 &data_word(0xa1f0ab72,0x84c87814); # u64
620 &data_word(0x1a6439ec,0x8cc70208); # u64
621 &data_word(0x23631e28,0x90befffa); # u64
622 &data_word(0xde82bde9,0xa4506ceb); # u64
623 &data_word(0xb2c67915,0xbef9a3f7); # u64
624 &data_word(0xe372532b,0xc67178f2); # u64
625 &data_word(0xea26619c,0xca273ece); # u64
626 &data_word(0x21c0c207,0xd186b8c7); # u64
627 &data_word(0xcde0eb1e,0xeada7dd6); # u64
628 &data_word(0xee6ed178,0xf57d4f7f); # u64
629 &data_word(0x72176fba,0x06f067aa); # u64
630 &data_word(0xa2c898a6,0x0a637dc5); # u64
631 &data_word(0xbef90dae,0x113f9804); # u64
632 &data_word(0x131c471b,0x1b710b35); # u64
633 &data_word(0x23047d84,0x28db77f5); # u64
634 &data_word(0x40c72493,0x32caab7b); # u64
635 &data_word(0x15c9bebc,0x3c9ebe0a); # u64
636 &data_word(0x9c100d4c,0x431d67c4); # u64
637 &data_word(0xcb3e42b6,0x4cc5d4be); # u64
638 &data_word(0xfc657e2a,0x597f299c); # u64
639 &data_word(0x3ad6faec,0x5fcb6fab); # u64
640 &data_word(0x4a475817,0x6c44198c); # u64
641&function_end_B("sha512_block_data_order");
642&asciz("SHA512 block transform for x86, CRYPTOGAMS by <appro\@openssl.org>");
643
644&asm_finish();
diff --git a/src/lib/libcrypto/sha/asm/sha512-armv4.pl b/src/lib/libcrypto/sha/asm/sha512-armv4.pl
new file mode 100644
index 0000000000..4fbb94a914
--- /dev/null
+++ b/src/lib/libcrypto/sha/asm/sha512-armv4.pl
@@ -0,0 +1,399 @@
1#!/usr/bin/env perl
2
3# ====================================================================
4# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
5# project. The module is, however, dual licensed under OpenSSL and
6# CRYPTOGAMS licenses depending on where you obtain it. For further
7# details see http://www.openssl.org/~appro/cryptogams/.
8# ====================================================================
9
10# SHA512 block procedure for ARMv4. September 2007.
11
12# This code is ~4.5 (four and a half) times faster than code generated
13# by gcc 3.4 and it spends ~72 clock cycles per byte.
14
15# Byte order [in]dependence. =========================================
16#
17# Caller is expected to maintain specific *dword* order in h[0-7],
18# namely with most significant dword at *lower* address, which is
19# reflected in below two parameters. *Byte* order within these dwords
20# in turn is whatever *native* byte order on current platform.
21$hi=0;
22$lo=4;
23# ====================================================================
24
25$output=shift;
26open STDOUT,">$output";
27
28$ctx="r0";
29$inp="r1";
30$len="r2";
31$Tlo="r3";
32$Thi="r4";
33$Alo="r5";
34$Ahi="r6";
35$Elo="r7";
36$Ehi="r8";
37$t0="r9";
38$t1="r10";
39$t2="r11";
40$t3="r12";
41############ r13 is stack pointer
42$Ktbl="r14";
43############ r15 is program counter
44
45$Aoff=8*0;
46$Boff=8*1;
47$Coff=8*2;
48$Doff=8*3;
49$Eoff=8*4;
50$Foff=8*5;
51$Goff=8*6;
52$Hoff=8*7;
53$Xoff=8*8;
54
55sub BODY_00_15() {
56my $magic = shift;
57$code.=<<___;
58 ldr $t2,[sp,#$Hoff+0] @ h.lo
59 ldr $t3,[sp,#$Hoff+4] @ h.hi
60 @ Sigma1(x) (ROTR((x),14) ^ ROTR((x),18) ^ ROTR((x),41))
61 @ LO lo>>14^hi<<18 ^ lo>>18^hi<<14 ^ hi>>9^lo<<23
62 @ HI hi>>14^lo<<18 ^ hi>>18^lo<<14 ^ lo>>9^hi<<23
63 mov $t0,$Elo,lsr#14
64 mov $t1,$Ehi,lsr#14
65 eor $t0,$t0,$Ehi,lsl#18
66 eor $t1,$t1,$Elo,lsl#18
67 eor $t0,$t0,$Elo,lsr#18
68 eor $t1,$t1,$Ehi,lsr#18
69 eor $t0,$t0,$Ehi,lsl#14
70 eor $t1,$t1,$Elo,lsl#14
71 eor $t0,$t0,$Ehi,lsr#9
72 eor $t1,$t1,$Elo,lsr#9
73 eor $t0,$t0,$Elo,lsl#23
74 eor $t1,$t1,$Ehi,lsl#23 @ Sigma1(e)
75 adds $Tlo,$Tlo,$t0
76 adc $Thi,$Thi,$t1 @ T += Sigma1(e)
77 adds $Tlo,$Tlo,$t2
78 adc $Thi,$Thi,$t3 @ T += h
79
80 ldr $t0,[sp,#$Foff+0] @ f.lo
81 ldr $t1,[sp,#$Foff+4] @ f.hi
82 ldr $t2,[sp,#$Goff+0] @ g.lo
83 ldr $t3,[sp,#$Goff+4] @ g.hi
84 str $Elo,[sp,#$Eoff+0]
85 str $Ehi,[sp,#$Eoff+4]
86 str $Alo,[sp,#$Aoff+0]
87 str $Ahi,[sp,#$Aoff+4]
88
89 eor $t0,$t0,$t2
90 eor $t1,$t1,$t3
91 and $t0,$t0,$Elo
92 and $t1,$t1,$Ehi
93 eor $t0,$t0,$t2
94 eor $t1,$t1,$t3 @ Ch(e,f,g)
95
96 ldr $t2,[$Ktbl,#4] @ K[i].lo
97 ldr $t3,[$Ktbl,#0] @ K[i].hi
98 ldr $Elo,[sp,#$Doff+0] @ d.lo
99 ldr $Ehi,[sp,#$Doff+4] @ d.hi
100
101 adds $Tlo,$Tlo,$t0
102 adc $Thi,$Thi,$t1 @ T += Ch(e,f,g)
103 adds $Tlo,$Tlo,$t2
104 adc $Thi,$Thi,$t3 @ T += K[i]
105 adds $Elo,$Elo,$Tlo
106 adc $Ehi,$Ehi,$Thi @ d += T
107
108 and $t0,$t2,#0xff
109 teq $t0,#$magic
110 orreq $Ktbl,$Ktbl,#1
111
112 ldr $t2,[sp,#$Boff+0] @ b.lo
113 ldr $t3,[sp,#$Coff+0] @ c.lo
114 @ Sigma0(x) (ROTR((x),28) ^ ROTR((x),34) ^ ROTR((x),39))
115 @ LO lo>>28^hi<<4 ^ hi>>2^lo<<30 ^ hi>>7^lo<<25
116 @ HI hi>>28^lo<<4 ^ lo>>2^hi<<30 ^ lo>>7^hi<<25
117 mov $t0,$Alo,lsr#28
118 mov $t1,$Ahi,lsr#28
119 eor $t0,$t0,$Ahi,lsl#4
120 eor $t1,$t1,$Alo,lsl#4
121 eor $t0,$t0,$Ahi,lsr#2
122 eor $t1,$t1,$Alo,lsr#2
123 eor $t0,$t0,$Alo,lsl#30
124 eor $t1,$t1,$Ahi,lsl#30
125 eor $t0,$t0,$Ahi,lsr#7
126 eor $t1,$t1,$Alo,lsr#7
127 eor $t0,$t0,$Alo,lsl#25
128 eor $t1,$t1,$Ahi,lsl#25 @ Sigma0(a)
129 adds $Tlo,$Tlo,$t0
130 adc $Thi,$Thi,$t1 @ T += Sigma0(a)
131
132 and $t0,$Alo,$t2
133 orr $Alo,$Alo,$t2
134 ldr $t1,[sp,#$Boff+4] @ b.hi
135 ldr $t2,[sp,#$Coff+4] @ c.hi
136 and $Alo,$Alo,$t3
137 orr $Alo,$Alo,$t0 @ Maj(a,b,c).lo
138 and $t3,$Ahi,$t1
139 orr $Ahi,$Ahi,$t1
140 and $Ahi,$Ahi,$t2
141 orr $Ahi,$Ahi,$t3 @ Maj(a,b,c).hi
142 adds $Alo,$Alo,$Tlo
143 adc $Ahi,$Ahi,$Thi @ h += T
144
145 sub sp,sp,#8
146 add $Ktbl,$Ktbl,#8
147___
148}
149$code=<<___;
150.text
151.code 32
152.type K512,%object
153.align 5
154K512:
155.word 0x428a2f98,0xd728ae22, 0x71374491,0x23ef65cd
156.word 0xb5c0fbcf,0xec4d3b2f, 0xe9b5dba5,0x8189dbbc
157.word 0x3956c25b,0xf348b538, 0x59f111f1,0xb605d019
158.word 0x923f82a4,0xaf194f9b, 0xab1c5ed5,0xda6d8118
159.word 0xd807aa98,0xa3030242, 0x12835b01,0x45706fbe
160.word 0x243185be,0x4ee4b28c, 0x550c7dc3,0xd5ffb4e2
161.word 0x72be5d74,0xf27b896f, 0x80deb1fe,0x3b1696b1
162.word 0x9bdc06a7,0x25c71235, 0xc19bf174,0xcf692694
163.word 0xe49b69c1,0x9ef14ad2, 0xefbe4786,0x384f25e3
164.word 0x0fc19dc6,0x8b8cd5b5, 0x240ca1cc,0x77ac9c65
165.word 0x2de92c6f,0x592b0275, 0x4a7484aa,0x6ea6e483
166.word 0x5cb0a9dc,0xbd41fbd4, 0x76f988da,0x831153b5
167.word 0x983e5152,0xee66dfab, 0xa831c66d,0x2db43210
168.word 0xb00327c8,0x98fb213f, 0xbf597fc7,0xbeef0ee4
169.word 0xc6e00bf3,0x3da88fc2, 0xd5a79147,0x930aa725
170.word 0x06ca6351,0xe003826f, 0x14292967,0x0a0e6e70
171.word 0x27b70a85,0x46d22ffc, 0x2e1b2138,0x5c26c926
172.word 0x4d2c6dfc,0x5ac42aed, 0x53380d13,0x9d95b3df
173.word 0x650a7354,0x8baf63de, 0x766a0abb,0x3c77b2a8
174.word 0x81c2c92e,0x47edaee6, 0x92722c85,0x1482353b
175.word 0xa2bfe8a1,0x4cf10364, 0xa81a664b,0xbc423001
176.word 0xc24b8b70,0xd0f89791, 0xc76c51a3,0x0654be30
177.word 0xd192e819,0xd6ef5218, 0xd6990624,0x5565a910
178.word 0xf40e3585,0x5771202a, 0x106aa070,0x32bbd1b8
179.word 0x19a4c116,0xb8d2d0c8, 0x1e376c08,0x5141ab53
180.word 0x2748774c,0xdf8eeb99, 0x34b0bcb5,0xe19b48a8
181.word 0x391c0cb3,0xc5c95a63, 0x4ed8aa4a,0xe3418acb
182.word 0x5b9cca4f,0x7763e373, 0x682e6ff3,0xd6b2b8a3
183.word 0x748f82ee,0x5defb2fc, 0x78a5636f,0x43172f60
184.word 0x84c87814,0xa1f0ab72, 0x8cc70208,0x1a6439ec
185.word 0x90befffa,0x23631e28, 0xa4506ceb,0xde82bde9
186.word 0xbef9a3f7,0xb2c67915, 0xc67178f2,0xe372532b
187.word 0xca273ece,0xea26619c, 0xd186b8c7,0x21c0c207
188.word 0xeada7dd6,0xcde0eb1e, 0xf57d4f7f,0xee6ed178
189.word 0x06f067aa,0x72176fba, 0x0a637dc5,0xa2c898a6
190.word 0x113f9804,0xbef90dae, 0x1b710b35,0x131c471b
191.word 0x28db77f5,0x23047d84, 0x32caab7b,0x40c72493
192.word 0x3c9ebe0a,0x15c9bebc, 0x431d67c4,0x9c100d4c
193.word 0x4cc5d4be,0xcb3e42b6, 0x597f299c,0xfc657e2a
194.word 0x5fcb6fab,0x3ad6faec, 0x6c44198c,0x4a475817
195.size K512,.-K512
196
197.global sha512_block_data_order
198.type sha512_block_data_order,%function
199sha512_block_data_order:
200 sub r3,pc,#8 @ sha512_block_data_order
201 add $len,$inp,$len,lsl#7 @ len to point at the end of inp
202 stmdb sp!,{r4-r12,lr}
203 sub $Ktbl,r3,#640 @ K512
204 sub sp,sp,#9*8
205
206 ldr $Elo,[$ctx,#$Eoff+$lo]
207 ldr $Ehi,[$ctx,#$Eoff+$hi]
208 ldr $t0, [$ctx,#$Goff+$lo]
209 ldr $t1, [$ctx,#$Goff+$hi]
210 ldr $t2, [$ctx,#$Hoff+$lo]
211 ldr $t3, [$ctx,#$Hoff+$hi]
212.Loop:
213 str $t0, [sp,#$Goff+0]
214 str $t1, [sp,#$Goff+4]
215 str $t2, [sp,#$Hoff+0]
216 str $t3, [sp,#$Hoff+4]
217 ldr $Alo,[$ctx,#$Aoff+$lo]
218 ldr $Ahi,[$ctx,#$Aoff+$hi]
219 ldr $Tlo,[$ctx,#$Boff+$lo]
220 ldr $Thi,[$ctx,#$Boff+$hi]
221 ldr $t0, [$ctx,#$Coff+$lo]
222 ldr $t1, [$ctx,#$Coff+$hi]
223 ldr $t2, [$ctx,#$Doff+$lo]
224 ldr $t3, [$ctx,#$Doff+$hi]
225 str $Tlo,[sp,#$Boff+0]
226 str $Thi,[sp,#$Boff+4]
227 str $t0, [sp,#$Coff+0]
228 str $t1, [sp,#$Coff+4]
229 str $t2, [sp,#$Doff+0]
230 str $t3, [sp,#$Doff+4]
231 ldr $Tlo,[$ctx,#$Foff+$lo]
232 ldr $Thi,[$ctx,#$Foff+$hi]
233 str $Tlo,[sp,#$Foff+0]
234 str $Thi,[sp,#$Foff+4]
235
236.L00_15:
237 ldrb $Tlo,[$inp,#7]
238 ldrb $t0, [$inp,#6]
239 ldrb $t1, [$inp,#5]
240 ldrb $t2, [$inp,#4]
241 ldrb $Thi,[$inp,#3]
242 ldrb $t3, [$inp,#2]
243 orr $Tlo,$Tlo,$t0,lsl#8
244 ldrb $t0, [$inp,#1]
245 orr $Tlo,$Tlo,$t1,lsl#16
246 ldrb $t1, [$inp],#8
247 orr $Tlo,$Tlo,$t2,lsl#24
248 orr $Thi,$Thi,$t3,lsl#8
249 orr $Thi,$Thi,$t0,lsl#16
250 orr $Thi,$Thi,$t1,lsl#24
251 str $Tlo,[sp,#$Xoff+0]
252 str $Thi,[sp,#$Xoff+4]
253___
254 &BODY_00_15(0x94);
255$code.=<<___;
256 tst $Ktbl,#1
257 beq .L00_15
258 bic $Ktbl,$Ktbl,#1
259
260.L16_79:
261 ldr $t0,[sp,#`$Xoff+8*(16-1)`+0]
262 ldr $t1,[sp,#`$Xoff+8*(16-1)`+4]
263 ldr $t2,[sp,#`$Xoff+8*(16-14)`+0]
264 ldr $t3,[sp,#`$Xoff+8*(16-14)`+4]
265
266 @ sigma0(x) (ROTR((x),1) ^ ROTR((x),8) ^ ((x)>>7))
267 @ LO lo>>1^hi<<31 ^ lo>>8^hi<<24 ^ lo>>7^hi<<25
268 @ HI hi>>1^lo<<31 ^ hi>>8^lo<<24 ^ hi>>7
269 mov $Tlo,$t0,lsr#1
270 mov $Thi,$t1,lsr#1
271 eor $Tlo,$Tlo,$t1,lsl#31
272 eor $Thi,$Thi,$t0,lsl#31
273 eor $Tlo,$Tlo,$t0,lsr#8
274 eor $Thi,$Thi,$t1,lsr#8
275 eor $Tlo,$Tlo,$t1,lsl#24
276 eor $Thi,$Thi,$t0,lsl#24
277 eor $Tlo,$Tlo,$t0,lsr#7
278 eor $Thi,$Thi,$t1,lsr#7
279 eor $Tlo,$Tlo,$t1,lsl#25
280
281 @ sigma1(x) (ROTR((x),19) ^ ROTR((x),61) ^ ((x)>>6))
282 @ LO lo>>19^hi<<13 ^ hi>>29^lo<<3 ^ lo>>6^hi<<26
283 @ HI hi>>19^lo<<13 ^ lo>>29^hi<<3 ^ hi>>6
284 mov $t0,$t2,lsr#19
285 mov $t1,$t3,lsr#19
286 eor $t0,$t0,$t3,lsl#13
287 eor $t1,$t1,$t2,lsl#13
288 eor $t0,$t0,$t3,lsr#29
289 eor $t1,$t1,$t2,lsr#29
290 eor $t0,$t0,$t2,lsl#3
291 eor $t1,$t1,$t3,lsl#3
292 eor $t0,$t0,$t2,lsr#6
293 eor $t1,$t1,$t3,lsr#6
294 eor $t0,$t0,$t3,lsl#26
295
296 ldr $t2,[sp,#`$Xoff+8*(16-9)`+0]
297 ldr $t3,[sp,#`$Xoff+8*(16-9)`+4]
298 adds $Tlo,$Tlo,$t0
299 adc $Thi,$Thi,$t1
300
301 ldr $t0,[sp,#`$Xoff+8*16`+0]
302 ldr $t1,[sp,#`$Xoff+8*16`+4]
303 adds $Tlo,$Tlo,$t2
304 adc $Thi,$Thi,$t3
305 adds $Tlo,$Tlo,$t0
306 adc $Thi,$Thi,$t1
307 str $Tlo,[sp,#$Xoff+0]
308 str $Thi,[sp,#$Xoff+4]
309___
310 &BODY_00_15(0x17);
311$code.=<<___;
312 tst $Ktbl,#1
313 beq .L16_79
314 bic $Ktbl,$Ktbl,#1
315
316 ldr $Tlo,[sp,#$Boff+0]
317 ldr $Thi,[sp,#$Boff+4]
318 ldr $t0, [$ctx,#$Aoff+$lo]
319 ldr $t1, [$ctx,#$Aoff+$hi]
320 ldr $t2, [$ctx,#$Boff+$lo]
321 ldr $t3, [$ctx,#$Boff+$hi]
322 adds $t0,$Alo,$t0
323 adc $t1,$Ahi,$t1
324 adds $t2,$Tlo,$t2
325 adc $t3,$Thi,$t3
326 str $t0, [$ctx,#$Aoff+$lo]
327 str $t1, [$ctx,#$Aoff+$hi]
328 str $t2, [$ctx,#$Boff+$lo]
329 str $t3, [$ctx,#$Boff+$hi]
330
331 ldr $Alo,[sp,#$Coff+0]
332 ldr $Ahi,[sp,#$Coff+4]
333 ldr $Tlo,[sp,#$Doff+0]
334 ldr $Thi,[sp,#$Doff+4]
335 ldr $t0, [$ctx,#$Coff+$lo]
336 ldr $t1, [$ctx,#$Coff+$hi]
337 ldr $t2, [$ctx,#$Doff+$lo]
338 ldr $t3, [$ctx,#$Doff+$hi]
339 adds $t0,$Alo,$t0
340 adc $t1,$Ahi,$t1
341 adds $t2,$Tlo,$t2
342 adc $t3,$Thi,$t3
343 str $t0, [$ctx,#$Coff+$lo]
344 str $t1, [$ctx,#$Coff+$hi]
345 str $t2, [$ctx,#$Doff+$lo]
346 str $t3, [$ctx,#$Doff+$hi]
347
348 ldr $Tlo,[sp,#$Foff+0]
349 ldr $Thi,[sp,#$Foff+4]
350 ldr $t0, [$ctx,#$Eoff+$lo]
351 ldr $t1, [$ctx,#$Eoff+$hi]
352 ldr $t2, [$ctx,#$Foff+$lo]
353 ldr $t3, [$ctx,#$Foff+$hi]
354 adds $Elo,$Elo,$t0
355 adc $Ehi,$Ehi,$t1
356 adds $t2,$Tlo,$t2
357 adc $t3,$Thi,$t3
358 str $Elo,[$ctx,#$Eoff+$lo]
359 str $Ehi,[$ctx,#$Eoff+$hi]
360 str $t2, [$ctx,#$Foff+$lo]
361 str $t3, [$ctx,#$Foff+$hi]
362
363 ldr $Alo,[sp,#$Goff+0]
364 ldr $Ahi,[sp,#$Goff+4]
365 ldr $Tlo,[sp,#$Hoff+0]
366 ldr $Thi,[sp,#$Hoff+4]
367 ldr $t0, [$ctx,#$Goff+$lo]
368 ldr $t1, [$ctx,#$Goff+$hi]
369 ldr $t2, [$ctx,#$Hoff+$lo]
370 ldr $t3, [$ctx,#$Hoff+$hi]
371 adds $t0,$Alo,$t0
372 adc $t1,$Ahi,$t1
373 adds $t2,$Tlo,$t2
374 adc $t3,$Thi,$t3
375 str $t0, [$ctx,#$Goff+$lo]
376 str $t1, [$ctx,#$Goff+$hi]
377 str $t2, [$ctx,#$Hoff+$lo]
378 str $t3, [$ctx,#$Hoff+$hi]
379
380 add sp,sp,#640
381 sub $Ktbl,$Ktbl,#640
382
383 teq $inp,$len
384 bne .Loop
385
386 add sp,sp,#8*9 @ destroy frame
387 ldmia sp!,{r4-r12,lr}
388 tst lr,#1
389 moveq pc,lr @ be binary compatible with V4, yet
390 bx lr @ interoperable with Thumb ISA:-)
391.size sha512_block_data_order,.-sha512_block_data_order
392.asciz "SHA512 block transform for ARMv4, CRYPTOGAMS by <appro\@openssl.org>"
393.align 2
394___
395
396$code =~ s/\`([^\`]*)\`/eval $1/gem;
397$code =~ s/\bbx\s+lr\b/.word\t0xe12fff1e/gm; # make it possible to compile with -march=armv4
398print $code;
399close STDOUT; # enforce flush
diff --git a/src/lib/libcrypto/sha/asm/sha512-ppc.pl b/src/lib/libcrypto/sha/asm/sha512-ppc.pl
new file mode 100755
index 0000000000..768a6a6fad
--- /dev/null
+++ b/src/lib/libcrypto/sha/asm/sha512-ppc.pl
@@ -0,0 +1,462 @@
1#!/usr/bin/env perl
2
3# ====================================================================
4# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
5# project. The module is, however, dual licensed under OpenSSL and
6# CRYPTOGAMS licenses depending on where you obtain it. For further
7# details see http://www.openssl.org/~appro/cryptogams/.
8# ====================================================================
9
10# I let hardware handle unaligned input, except on page boundaries
11# (see below for details). Otherwise straightforward implementation
12# with X vector in register bank. The module is big-endian [which is
13# not big deal as there're no little-endian targets left around].
14
15# sha256 | sha512
16# -m64 -m32 | -m64 -m32
17# --------------------------------------+-----------------------
18# PPC970,gcc-4.0.0 +50% +38% | +40% +410%(*)
19# Power6,xlc-7 +150% +90% | +100% +430%(*)
20#
21# (*) 64-bit code in 32-bit application context, which actually is
22# on TODO list. It should be noted that for safe deployment in
23# 32-bit *mutli-threaded* context asyncronous signals should be
24# blocked upon entry to SHA512 block routine. This is because
25# 32-bit signaling procedure invalidates upper halves of GPRs.
26# Context switch procedure preserves them, but not signaling:-(
27
28# Second version is true multi-thread safe. Trouble with the original
29# version was that it was using thread local storage pointer register.
30# Well, it scrupulously preserved it, but the problem would arise the
31# moment asynchronous signal was delivered and signal handler would
32# dereference the TLS pointer. While it's never the case in openssl
33# application or test suite, we have to respect this scenario and not
34# use TLS pointer register. Alternative would be to require caller to
35# block signals prior calling this routine. For the record, in 32-bit
36# context R2 serves as TLS pointer, while in 64-bit context - R13.
37
38$flavour=shift;
39$output =shift;
40
41if ($flavour =~ /64/) {
42 $SIZE_T=8;
43 $STU="stdu";
44 $UCMP="cmpld";
45 $SHL="sldi";
46 $POP="ld";
47 $PUSH="std";
48} elsif ($flavour =~ /32/) {
49 $SIZE_T=4;
50 $STU="stwu";
51 $UCMP="cmplw";
52 $SHL="slwi";
53 $POP="lwz";
54 $PUSH="stw";
55} else { die "nonsense $flavour"; }
56
57$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
58( $xlate="${dir}ppc-xlate.pl" and -f $xlate ) or
59( $xlate="${dir}../../perlasm/ppc-xlate.pl" and -f $xlate) or
60die "can't locate ppc-xlate.pl";
61
62open STDOUT,"| $^X $xlate $flavour $output" || die "can't call $xlate: $!";
63
64if ($output =~ /512/) {
65 $func="sha512_block_data_order";
66 $SZ=8;
67 @Sigma0=(28,34,39);
68 @Sigma1=(14,18,41);
69 @sigma0=(1, 8, 7);
70 @sigma1=(19,61, 6);
71 $rounds=80;
72 $LD="ld";
73 $ST="std";
74 $ROR="rotrdi";
75 $SHR="srdi";
76} else {
77 $func="sha256_block_data_order";
78 $SZ=4;
79 @Sigma0=( 2,13,22);
80 @Sigma1=( 6,11,25);
81 @sigma0=( 7,18, 3);
82 @sigma1=(17,19,10);
83 $rounds=64;
84 $LD="lwz";
85 $ST="stw";
86 $ROR="rotrwi";
87 $SHR="srwi";
88}
89
90$FRAME=32*$SIZE_T;
91
92$sp ="r1";
93$toc="r2";
94$ctx="r3"; # zapped by $a0
95$inp="r4"; # zapped by $a1
96$num="r5"; # zapped by $t0
97
98$T ="r0";
99$a0 ="r3";
100$a1 ="r4";
101$t0 ="r5";
102$t1 ="r6";
103$Tbl="r7";
104
105$A ="r8";
106$B ="r9";
107$C ="r10";
108$D ="r11";
109$E ="r12";
110$F ="r13"; $F="r2" if ($SIZE_T==8);# reassigned to exempt TLS pointer
111$G ="r14";
112$H ="r15";
113
114@V=($A,$B,$C,$D,$E,$F,$G,$H);
115@X=("r16","r17","r18","r19","r20","r21","r22","r23",
116 "r24","r25","r26","r27","r28","r29","r30","r31");
117
118$inp="r31"; # reassigned $inp! aliases with @X[15]
119
120sub ROUND_00_15 {
121my ($i,$a,$b,$c,$d,$e,$f,$g,$h)=@_;
122$code.=<<___;
123 $LD $T,`$i*$SZ`($Tbl)
124 $ROR $a0,$e,$Sigma1[0]
125 $ROR $a1,$e,$Sigma1[1]
126 and $t0,$f,$e
127 andc $t1,$g,$e
128 add $T,$T,$h
129 xor $a0,$a0,$a1
130 $ROR $a1,$a1,`$Sigma1[2]-$Sigma1[1]`
131 or $t0,$t0,$t1 ; Ch(e,f,g)
132 add $T,$T,@X[$i]
133 xor $a0,$a0,$a1 ; Sigma1(e)
134 add $T,$T,$t0
135 add $T,$T,$a0
136
137 $ROR $a0,$a,$Sigma0[0]
138 $ROR $a1,$a,$Sigma0[1]
139 and $t0,$a,$b
140 and $t1,$a,$c
141 xor $a0,$a0,$a1
142 $ROR $a1,$a1,`$Sigma0[2]-$Sigma0[1]`
143 xor $t0,$t0,$t1
144 and $t1,$b,$c
145 xor $a0,$a0,$a1 ; Sigma0(a)
146 add $d,$d,$T
147 xor $t0,$t0,$t1 ; Maj(a,b,c)
148 add $h,$T,$a0
149 add $h,$h,$t0
150
151___
152}
153
154sub ROUND_16_xx {
155my ($i,$a,$b,$c,$d,$e,$f,$g,$h)=@_;
156$i-=16;
157$code.=<<___;
158 $ROR $a0,@X[($i+1)%16],$sigma0[0]
159 $ROR $a1,@X[($i+1)%16],$sigma0[1]
160 $ROR $t0,@X[($i+14)%16],$sigma1[0]
161 $ROR $t1,@X[($i+14)%16],$sigma1[1]
162 xor $a0,$a0,$a1
163 $SHR $a1,@X[($i+1)%16],$sigma0[2]
164 xor $t0,$t0,$t1
165 $SHR $t1,@X[($i+14)%16],$sigma1[2]
166 add @X[$i],@X[$i],@X[($i+9)%16]
167 xor $a0,$a0,$a1 ; sigma0(X[(i+1)&0x0f])
168 xor $t0,$t0,$t1 ; sigma1(X[(i+14)&0x0f])
169 add @X[$i],@X[$i],$a0
170 add @X[$i],@X[$i],$t0
171___
172&ROUND_00_15($i,$a,$b,$c,$d,$e,$f,$g,$h);
173}
174
175$code=<<___;
176.machine "any"
177.text
178
179.globl $func
180.align 6
181$func:
182 mflr r0
183 $STU $sp,`-($FRAME+16*$SZ)`($sp)
184 $SHL $num,$num,`log(16*$SZ)/log(2)`
185
186 $PUSH $ctx,`$FRAME-$SIZE_T*22`($sp)
187
188 $PUSH r0,`$FRAME-$SIZE_T*21`($sp)
189 $PUSH $toc,`$FRAME-$SIZE_T*20`($sp)
190 $PUSH r13,`$FRAME-$SIZE_T*19`($sp)
191 $PUSH r14,`$FRAME-$SIZE_T*18`($sp)
192 $PUSH r15,`$FRAME-$SIZE_T*17`($sp)
193 $PUSH r16,`$FRAME-$SIZE_T*16`($sp)
194 $PUSH r17,`$FRAME-$SIZE_T*15`($sp)
195 $PUSH r18,`$FRAME-$SIZE_T*14`($sp)
196 $PUSH r19,`$FRAME-$SIZE_T*13`($sp)
197 $PUSH r20,`$FRAME-$SIZE_T*12`($sp)
198 $PUSH r21,`$FRAME-$SIZE_T*11`($sp)
199 $PUSH r22,`$FRAME-$SIZE_T*10`($sp)
200 $PUSH r23,`$FRAME-$SIZE_T*9`($sp)
201 $PUSH r24,`$FRAME-$SIZE_T*8`($sp)
202 $PUSH r25,`$FRAME-$SIZE_T*7`($sp)
203 $PUSH r26,`$FRAME-$SIZE_T*6`($sp)
204 $PUSH r27,`$FRAME-$SIZE_T*5`($sp)
205 $PUSH r28,`$FRAME-$SIZE_T*4`($sp)
206 $PUSH r29,`$FRAME-$SIZE_T*3`($sp)
207 $PUSH r30,`$FRAME-$SIZE_T*2`($sp)
208 $PUSH r31,`$FRAME-$SIZE_T*1`($sp)
209
210 $LD $A,`0*$SZ`($ctx)
211 mr $inp,r4 ; incarnate $inp
212 $LD $B,`1*$SZ`($ctx)
213 $LD $C,`2*$SZ`($ctx)
214 $LD $D,`3*$SZ`($ctx)
215 $LD $E,`4*$SZ`($ctx)
216 $LD $F,`5*$SZ`($ctx)
217 $LD $G,`6*$SZ`($ctx)
218 $LD $H,`7*$SZ`($ctx)
219
220 b LPICmeup
221LPICedup:
222 andi. r0,$inp,3
223 bne Lunaligned
224Laligned:
225 add $num,$inp,$num
226 $PUSH $num,`$FRAME-$SIZE_T*24`($sp) ; end pointer
227 $PUSH $inp,`$FRAME-$SIZE_T*23`($sp) ; inp pointer
228 bl Lsha2_block_private
229Ldone:
230 $POP r0,`$FRAME-$SIZE_T*21`($sp)
231 $POP $toc,`$FRAME-$SIZE_T*20`($sp)
232 $POP r13,`$FRAME-$SIZE_T*19`($sp)
233 $POP r14,`$FRAME-$SIZE_T*18`($sp)
234 $POP r15,`$FRAME-$SIZE_T*17`($sp)
235 $POP r16,`$FRAME-$SIZE_T*16`($sp)
236 $POP r17,`$FRAME-$SIZE_T*15`($sp)
237 $POP r18,`$FRAME-$SIZE_T*14`($sp)
238 $POP r19,`$FRAME-$SIZE_T*13`($sp)
239 $POP r20,`$FRAME-$SIZE_T*12`($sp)
240 $POP r21,`$FRAME-$SIZE_T*11`($sp)
241 $POP r22,`$FRAME-$SIZE_T*10`($sp)
242 $POP r23,`$FRAME-$SIZE_T*9`($sp)
243 $POP r24,`$FRAME-$SIZE_T*8`($sp)
244 $POP r25,`$FRAME-$SIZE_T*7`($sp)
245 $POP r26,`$FRAME-$SIZE_T*6`($sp)
246 $POP r27,`$FRAME-$SIZE_T*5`($sp)
247 $POP r28,`$FRAME-$SIZE_T*4`($sp)
248 $POP r29,`$FRAME-$SIZE_T*3`($sp)
249 $POP r30,`$FRAME-$SIZE_T*2`($sp)
250 $POP r31,`$FRAME-$SIZE_T*1`($sp)
251 mtlr r0
252 addi $sp,$sp,`$FRAME+16*$SZ`
253 blr
254___
255
256# PowerPC specification allows an implementation to be ill-behaved
257# upon unaligned access which crosses page boundary. "Better safe
258# than sorry" principle makes me treat it specially. But I don't
259# look for particular offending word, but rather for the input
260# block which crosses the boundary. Once found that block is aligned
261# and hashed separately...
262$code.=<<___;
263.align 4
264Lunaligned:
265 subfic $t1,$inp,4096
266 andi. $t1,$t1,`4096-16*$SZ` ; distance to closest page boundary
267 beq Lcross_page
268 $UCMP $num,$t1
269 ble- Laligned ; didn't cross the page boundary
270 subfc $num,$t1,$num
271 add $t1,$inp,$t1
272 $PUSH $num,`$FRAME-$SIZE_T*25`($sp) ; save real remaining num
273 $PUSH $t1,`$FRAME-$SIZE_T*24`($sp) ; intermediate end pointer
274 $PUSH $inp,`$FRAME-$SIZE_T*23`($sp) ; inp pointer
275 bl Lsha2_block_private
276 ; $inp equals to the intermediate end pointer here
277 $POP $num,`$FRAME-$SIZE_T*25`($sp) ; restore real remaining num
278Lcross_page:
279 li $t1,`16*$SZ/4`
280 mtctr $t1
281 addi r20,$sp,$FRAME ; aligned spot below the frame
282Lmemcpy:
283 lbz r16,0($inp)
284 lbz r17,1($inp)
285 lbz r18,2($inp)
286 lbz r19,3($inp)
287 addi $inp,$inp,4
288 stb r16,0(r20)
289 stb r17,1(r20)
290 stb r18,2(r20)
291 stb r19,3(r20)
292 addi r20,r20,4
293 bdnz Lmemcpy
294
295 $PUSH $inp,`$FRAME-$SIZE_T*26`($sp) ; save real inp
296 addi $t1,$sp,`$FRAME+16*$SZ` ; fictitious end pointer
297 addi $inp,$sp,$FRAME ; fictitious inp pointer
298 $PUSH $num,`$FRAME-$SIZE_T*25`($sp) ; save real num
299 $PUSH $t1,`$FRAME-$SIZE_T*24`($sp) ; end pointer
300 $PUSH $inp,`$FRAME-$SIZE_T*23`($sp) ; inp pointer
301 bl Lsha2_block_private
302 $POP $inp,`$FRAME-$SIZE_T*26`($sp) ; restore real inp
303 $POP $num,`$FRAME-$SIZE_T*25`($sp) ; restore real num
304 addic. $num,$num,`-16*$SZ` ; num--
305 bne- Lunaligned
306 b Ldone
307___
308
309$code.=<<___;
310.align 4
311Lsha2_block_private:
312___
313for($i=0;$i<16;$i++) {
314$code.=<<___ if ($SZ==4);
315 lwz @X[$i],`$i*$SZ`($inp)
316___
317# 64-bit loads are split to 2x32-bit ones, as CPU can't handle
318# unaligned 64-bit loads, only 32-bit ones...
319$code.=<<___ if ($SZ==8);
320 lwz $t0,`$i*$SZ`($inp)
321 lwz @X[$i],`$i*$SZ+4`($inp)
322 insrdi @X[$i],$t0,32,0
323___
324 &ROUND_00_15($i,@V);
325 unshift(@V,pop(@V));
326}
327$code.=<<___;
328 li $T,`$rounds/16-1`
329 mtctr $T
330.align 4
331Lrounds:
332 addi $Tbl,$Tbl,`16*$SZ`
333___
334for(;$i<32;$i++) {
335 &ROUND_16_xx($i,@V);
336 unshift(@V,pop(@V));
337}
338$code.=<<___;
339 bdnz- Lrounds
340
341 $POP $ctx,`$FRAME-$SIZE_T*22`($sp)
342 $POP $inp,`$FRAME-$SIZE_T*23`($sp) ; inp pointer
343 $POP $num,`$FRAME-$SIZE_T*24`($sp) ; end pointer
344 subi $Tbl,$Tbl,`($rounds-16)*$SZ` ; rewind Tbl
345
346 $LD r16,`0*$SZ`($ctx)
347 $LD r17,`1*$SZ`($ctx)
348 $LD r18,`2*$SZ`($ctx)
349 $LD r19,`3*$SZ`($ctx)
350 $LD r20,`4*$SZ`($ctx)
351 $LD r21,`5*$SZ`($ctx)
352 $LD r22,`6*$SZ`($ctx)
353 addi $inp,$inp,`16*$SZ` ; advance inp
354 $LD r23,`7*$SZ`($ctx)
355 add $A,$A,r16
356 add $B,$B,r17
357 $PUSH $inp,`$FRAME-$SIZE_T*23`($sp)
358 add $C,$C,r18
359 $ST $A,`0*$SZ`($ctx)
360 add $D,$D,r19
361 $ST $B,`1*$SZ`($ctx)
362 add $E,$E,r20
363 $ST $C,`2*$SZ`($ctx)
364 add $F,$F,r21
365 $ST $D,`3*$SZ`($ctx)
366 add $G,$G,r22
367 $ST $E,`4*$SZ`($ctx)
368 add $H,$H,r23
369 $ST $F,`5*$SZ`($ctx)
370 $ST $G,`6*$SZ`($ctx)
371 $UCMP $inp,$num
372 $ST $H,`7*$SZ`($ctx)
373 bne Lsha2_block_private
374 blr
375___
376
377# Ugly hack here, because PPC assembler syntax seem to vary too
378# much from platforms to platform...
379$code.=<<___;
380.align 6
381LPICmeup:
382 bl LPIC
383 addi $Tbl,$Tbl,`64-4` ; "distance" between . and last nop
384 b LPICedup
385 nop
386 nop
387 nop
388 nop
389 nop
390LPIC: mflr $Tbl
391 blr
392 nop
393 nop
394 nop
395 nop
396 nop
397 nop
398___
399$code.=<<___ if ($SZ==8);
400 .long 0x428a2f98,0xd728ae22,0x71374491,0x23ef65cd
401 .long 0xb5c0fbcf,0xec4d3b2f,0xe9b5dba5,0x8189dbbc
402 .long 0x3956c25b,0xf348b538,0x59f111f1,0xb605d019
403 .long 0x923f82a4,0xaf194f9b,0xab1c5ed5,0xda6d8118
404 .long 0xd807aa98,0xa3030242,0x12835b01,0x45706fbe
405 .long 0x243185be,0x4ee4b28c,0x550c7dc3,0xd5ffb4e2
406 .long 0x72be5d74,0xf27b896f,0x80deb1fe,0x3b1696b1
407 .long 0x9bdc06a7,0x25c71235,0xc19bf174,0xcf692694
408 .long 0xe49b69c1,0x9ef14ad2,0xefbe4786,0x384f25e3
409 .long 0x0fc19dc6,0x8b8cd5b5,0x240ca1cc,0x77ac9c65
410 .long 0x2de92c6f,0x592b0275,0x4a7484aa,0x6ea6e483
411 .long 0x5cb0a9dc,0xbd41fbd4,0x76f988da,0x831153b5
412 .long 0x983e5152,0xee66dfab,0xa831c66d,0x2db43210
413 .long 0xb00327c8,0x98fb213f,0xbf597fc7,0xbeef0ee4
414 .long 0xc6e00bf3,0x3da88fc2,0xd5a79147,0x930aa725
415 .long 0x06ca6351,0xe003826f,0x14292967,0x0a0e6e70
416 .long 0x27b70a85,0x46d22ffc,0x2e1b2138,0x5c26c926
417 .long 0x4d2c6dfc,0x5ac42aed,0x53380d13,0x9d95b3df
418 .long 0x650a7354,0x8baf63de,0x766a0abb,0x3c77b2a8
419 .long 0x81c2c92e,0x47edaee6,0x92722c85,0x1482353b
420 .long 0xa2bfe8a1,0x4cf10364,0xa81a664b,0xbc423001
421 .long 0xc24b8b70,0xd0f89791,0xc76c51a3,0x0654be30
422 .long 0xd192e819,0xd6ef5218,0xd6990624,0x5565a910
423 .long 0xf40e3585,0x5771202a,0x106aa070,0x32bbd1b8
424 .long 0x19a4c116,0xb8d2d0c8,0x1e376c08,0x5141ab53
425 .long 0x2748774c,0xdf8eeb99,0x34b0bcb5,0xe19b48a8
426 .long 0x391c0cb3,0xc5c95a63,0x4ed8aa4a,0xe3418acb
427 .long 0x5b9cca4f,0x7763e373,0x682e6ff3,0xd6b2b8a3
428 .long 0x748f82ee,0x5defb2fc,0x78a5636f,0x43172f60
429 .long 0x84c87814,0xa1f0ab72,0x8cc70208,0x1a6439ec
430 .long 0x90befffa,0x23631e28,0xa4506ceb,0xde82bde9
431 .long 0xbef9a3f7,0xb2c67915,0xc67178f2,0xe372532b
432 .long 0xca273ece,0xea26619c,0xd186b8c7,0x21c0c207
433 .long 0xeada7dd6,0xcde0eb1e,0xf57d4f7f,0xee6ed178
434 .long 0x06f067aa,0x72176fba,0x0a637dc5,0xa2c898a6
435 .long 0x113f9804,0xbef90dae,0x1b710b35,0x131c471b
436 .long 0x28db77f5,0x23047d84,0x32caab7b,0x40c72493
437 .long 0x3c9ebe0a,0x15c9bebc,0x431d67c4,0x9c100d4c
438 .long 0x4cc5d4be,0xcb3e42b6,0x597f299c,0xfc657e2a
439 .long 0x5fcb6fab,0x3ad6faec,0x6c44198c,0x4a475817
440___
441$code.=<<___ if ($SZ==4);
442 .long 0x428a2f98,0x71374491,0xb5c0fbcf,0xe9b5dba5
443 .long 0x3956c25b,0x59f111f1,0x923f82a4,0xab1c5ed5
444 .long 0xd807aa98,0x12835b01,0x243185be,0x550c7dc3
445 .long 0x72be5d74,0x80deb1fe,0x9bdc06a7,0xc19bf174
446 .long 0xe49b69c1,0xefbe4786,0x0fc19dc6,0x240ca1cc
447 .long 0x2de92c6f,0x4a7484aa,0x5cb0a9dc,0x76f988da
448 .long 0x983e5152,0xa831c66d,0xb00327c8,0xbf597fc7
449 .long 0xc6e00bf3,0xd5a79147,0x06ca6351,0x14292967
450 .long 0x27b70a85,0x2e1b2138,0x4d2c6dfc,0x53380d13
451 .long 0x650a7354,0x766a0abb,0x81c2c92e,0x92722c85
452 .long 0xa2bfe8a1,0xa81a664b,0xc24b8b70,0xc76c51a3
453 .long 0xd192e819,0xd6990624,0xf40e3585,0x106aa070
454 .long 0x19a4c116,0x1e376c08,0x2748774c,0x34b0bcb5
455 .long 0x391c0cb3,0x4ed8aa4a,0x5b9cca4f,0x682e6ff3
456 .long 0x748f82ee,0x78a5636f,0x84c87814,0x8cc70208
457 .long 0x90befffa,0xa4506ceb,0xbef9a3f7,0xc67178f2
458___
459
460$code =~ s/\`([^\`]*)\`/eval $1/gem;
461print $code;
462close STDOUT;
diff --git a/src/lib/libcrypto/sha/asm/sha512-s390x.pl b/src/lib/libcrypto/sha/asm/sha512-s390x.pl
new file mode 100644
index 0000000000..e7ef2d5a9f
--- /dev/null
+++ b/src/lib/libcrypto/sha/asm/sha512-s390x.pl
@@ -0,0 +1,301 @@
1#!/usr/bin/env perl
2
3# ====================================================================
4# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
5# project. The module is, however, dual licensed under OpenSSL and
6# CRYPTOGAMS licenses depending on where you obtain it. For further
7# details see http://www.openssl.org/~appro/cryptogams/.
8# ====================================================================
9
10# SHA256/512 block procedures for s390x.
11
12# April 2007.
13#
14# sha256_block_data_order is reportedly >3 times faster than gcc 3.3
15# generated code (must be a bug in compiler, as improvement is
16# "pathologically" high, in particular in comparison to other SHA
17# modules). But the real twist is that it detects if hardware support
18# for SHA256 is available and in such case utilizes it. Then the
19# performance can reach >6.5x of assembler one for larger chunks.
20#
21# sha512_block_data_order is ~70% faster than gcc 3.3 generated code.
22
23# January 2009.
24#
25# Add support for hardware SHA512 and reschedule instructions to
26# favour dual-issue z10 pipeline. Hardware SHA256/512 is ~4.7x faster
27# than software.
28
29$t0="%r0";
30$t1="%r1";
31$ctx="%r2"; $t2="%r2";
32$inp="%r3";
33$len="%r4"; # used as index in inner loop
34
35$A="%r5";
36$B="%r6";
37$C="%r7";
38$D="%r8";
39$E="%r9";
40$F="%r10";
41$G="%r11";
42$H="%r12"; @V=($A,$B,$C,$D,$E,$F,$G,$H);
43$tbl="%r13";
44$T1="%r14";
45$sp="%r15";
46
47$output=shift;
48open STDOUT,">$output";
49
50if ($output =~ /512/) {
51 $label="512";
52 $SZ=8;
53 $LD="lg"; # load from memory
54 $ST="stg"; # store to memory
55 $ADD="alg"; # add with memory operand
56 $ROT="rllg"; # rotate left
57 $SHR="srlg"; # logical right shift [see even at the end]
58 @Sigma0=(25,30,36);
59 @Sigma1=(23,46,50);
60 @sigma0=(56,63, 7);
61 @sigma1=( 3,45, 6);
62 $rounds=80;
63 $kimdfunc=3; # 0 means unknown/unsupported/unimplemented/disabled
64} else {
65 $label="256";
66 $SZ=4;
67 $LD="llgf"; # load from memory
68 $ST="st"; # store to memory
69 $ADD="al"; # add with memory operand
70 $ROT="rll"; # rotate left
71 $SHR="srl"; # logical right shift
72 @Sigma0=(10,19,30);
73 @Sigma1=( 7,21,26);
74 @sigma0=(14,25, 3);
75 @sigma1=(13,15,10);
76 $rounds=64;
77 $kimdfunc=2; # magic function code for kimd instruction
78}
79$Func="sha${label}_block_data_order";
80$Table="K${label}";
81$frame=160+16*$SZ;
82
83sub BODY_00_15 {
84my ($i,$a,$b,$c,$d,$e,$f,$g,$h) = @_;
85
86$code.=<<___ if ($i<16);
87 $LD $T1,`$i*$SZ`($inp) ### $i
88___
89$code.=<<___;
90 $ROT $t0,$e,$Sigma1[0]
91 $ROT $t1,$e,$Sigma1[1]
92 lgr $t2,$f
93 xgr $t0,$t1
94 $ROT $t1,$t1,`$Sigma1[2]-$Sigma1[1]`
95 xgr $t2,$g
96 $ST $T1,`160+$SZ*($i%16)`($sp)
97 xgr $t0,$t1 # Sigma1(e)
98 la $T1,0($T1,$h) # T1+=h
99 ngr $t2,$e
100 lgr $t1,$a
101 algr $T1,$t0 # T1+=Sigma1(e)
102 $ROT $h,$a,$Sigma0[0]
103 xgr $t2,$g # Ch(e,f,g)
104 $ADD $T1,`$i*$SZ`($len,$tbl) # T1+=K[i]
105 $ROT $t0,$a,$Sigma0[1]
106 algr $T1,$t2 # T1+=Ch(e,f,g)
107 ogr $t1,$b
108 xgr $h,$t0
109 lgr $t2,$a
110 ngr $t1,$c
111 $ROT $t0,$t0,`$Sigma0[2]-$Sigma0[1]`
112 xgr $h,$t0 # h=Sigma0(a)
113 ngr $t2,$b
114 algr $h,$T1 # h+=T1
115 ogr $t2,$t1 # Maj(a,b,c)
116 la $d,0($d,$T1) # d+=T1
117 algr $h,$t2 # h+=Maj(a,b,c)
118___
119}
120
121sub BODY_16_XX {
122my ($i,$a,$b,$c,$d,$e,$f,$g,$h) = @_;
123
124$code.=<<___;
125 $LD $T1,`160+$SZ*(($i+1)%16)`($sp) ### $i
126 $LD $t1,`160+$SZ*(($i+14)%16)`($sp)
127 $ROT $t0,$T1,$sigma0[0]
128 $SHR $T1,$sigma0[2]
129 $ROT $t2,$t0,`$sigma0[1]-$sigma0[0]`
130 xgr $T1,$t0
131 $ROT $t0,$t1,$sigma1[0]
132 xgr $T1,$t2 # sigma0(X[i+1])
133 $SHR $t1,$sigma1[2]
134 $ADD $T1,`160+$SZ*($i%16)`($sp) # +=X[i]
135 xgr $t1,$t0
136 $ROT $t0,$t0,`$sigma1[1]-$sigma1[0]`
137 $ADD $T1,`160+$SZ*(($i+9)%16)`($sp) # +=X[i+9]
138 xgr $t1,$t0 # sigma1(X[i+14])
139 algr $T1,$t1 # +=sigma1(X[i+14])
140___
141 &BODY_00_15(@_);
142}
143
144$code.=<<___;
145.text
146.align 64
147.type $Table,\@object
148$Table:
149___
150$code.=<<___ if ($SZ==4);
151 .long 0x428a2f98,0x71374491,0xb5c0fbcf,0xe9b5dba5
152 .long 0x3956c25b,0x59f111f1,0x923f82a4,0xab1c5ed5
153 .long 0xd807aa98,0x12835b01,0x243185be,0x550c7dc3
154 .long 0x72be5d74,0x80deb1fe,0x9bdc06a7,0xc19bf174
155 .long 0xe49b69c1,0xefbe4786,0x0fc19dc6,0x240ca1cc
156 .long 0x2de92c6f,0x4a7484aa,0x5cb0a9dc,0x76f988da
157 .long 0x983e5152,0xa831c66d,0xb00327c8,0xbf597fc7
158 .long 0xc6e00bf3,0xd5a79147,0x06ca6351,0x14292967
159 .long 0x27b70a85,0x2e1b2138,0x4d2c6dfc,0x53380d13
160 .long 0x650a7354,0x766a0abb,0x81c2c92e,0x92722c85
161 .long 0xa2bfe8a1,0xa81a664b,0xc24b8b70,0xc76c51a3
162 .long 0xd192e819,0xd6990624,0xf40e3585,0x106aa070
163 .long 0x19a4c116,0x1e376c08,0x2748774c,0x34b0bcb5
164 .long 0x391c0cb3,0x4ed8aa4a,0x5b9cca4f,0x682e6ff3
165 .long 0x748f82ee,0x78a5636f,0x84c87814,0x8cc70208
166 .long 0x90befffa,0xa4506ceb,0xbef9a3f7,0xc67178f2
167___
168$code.=<<___ if ($SZ==8);
169 .quad 0x428a2f98d728ae22,0x7137449123ef65cd
170 .quad 0xb5c0fbcfec4d3b2f,0xe9b5dba58189dbbc
171 .quad 0x3956c25bf348b538,0x59f111f1b605d019
172 .quad 0x923f82a4af194f9b,0xab1c5ed5da6d8118
173 .quad 0xd807aa98a3030242,0x12835b0145706fbe
174 .quad 0x243185be4ee4b28c,0x550c7dc3d5ffb4e2
175 .quad 0x72be5d74f27b896f,0x80deb1fe3b1696b1
176 .quad 0x9bdc06a725c71235,0xc19bf174cf692694
177 .quad 0xe49b69c19ef14ad2,0xefbe4786384f25e3
178 .quad 0x0fc19dc68b8cd5b5,0x240ca1cc77ac9c65
179 .quad 0x2de92c6f592b0275,0x4a7484aa6ea6e483
180 .quad 0x5cb0a9dcbd41fbd4,0x76f988da831153b5
181 .quad 0x983e5152ee66dfab,0xa831c66d2db43210
182 .quad 0xb00327c898fb213f,0xbf597fc7beef0ee4
183 .quad 0xc6e00bf33da88fc2,0xd5a79147930aa725
184 .quad 0x06ca6351e003826f,0x142929670a0e6e70
185 .quad 0x27b70a8546d22ffc,0x2e1b21385c26c926
186 .quad 0x4d2c6dfc5ac42aed,0x53380d139d95b3df
187 .quad 0x650a73548baf63de,0x766a0abb3c77b2a8
188 .quad 0x81c2c92e47edaee6,0x92722c851482353b
189 .quad 0xa2bfe8a14cf10364,0xa81a664bbc423001
190 .quad 0xc24b8b70d0f89791,0xc76c51a30654be30
191 .quad 0xd192e819d6ef5218,0xd69906245565a910
192 .quad 0xf40e35855771202a,0x106aa07032bbd1b8
193 .quad 0x19a4c116b8d2d0c8,0x1e376c085141ab53
194 .quad 0x2748774cdf8eeb99,0x34b0bcb5e19b48a8
195 .quad 0x391c0cb3c5c95a63,0x4ed8aa4ae3418acb
196 .quad 0x5b9cca4f7763e373,0x682e6ff3d6b2b8a3
197 .quad 0x748f82ee5defb2fc,0x78a5636f43172f60
198 .quad 0x84c87814a1f0ab72,0x8cc702081a6439ec
199 .quad 0x90befffa23631e28,0xa4506cebde82bde9
200 .quad 0xbef9a3f7b2c67915,0xc67178f2e372532b
201 .quad 0xca273eceea26619c,0xd186b8c721c0c207
202 .quad 0xeada7dd6cde0eb1e,0xf57d4f7fee6ed178
203 .quad 0x06f067aa72176fba,0x0a637dc5a2c898a6
204 .quad 0x113f9804bef90dae,0x1b710b35131c471b
205 .quad 0x28db77f523047d84,0x32caab7b40c72493
206 .quad 0x3c9ebe0a15c9bebc,0x431d67c49c100d4c
207 .quad 0x4cc5d4becb3e42b6,0x597f299cfc657e2a
208 .quad 0x5fcb6fab3ad6faec,0x6c44198c4a475817
209___
210$code.=<<___;
211.size $Table,.-$Table
212.globl $Func
213.type $Func,\@function
214$Func:
215___
216$code.=<<___ if ($kimdfunc);
217 larl %r1,OPENSSL_s390xcap_P
218 lg %r0,0(%r1)
219 tmhl %r0,0x4000 # check for message-security assist
220 jz .Lsoftware
221 lghi %r0,0
222 la %r1,16($sp)
223 .long 0xb93e0002 # kimd %r0,%r2
224 lg %r0,16($sp)
225 tmhh %r0,`0x8000>>$kimdfunc`
226 jz .Lsoftware
227 lghi %r0,$kimdfunc
228 lgr %r1,$ctx
229 lgr %r2,$inp
230 sllg %r3,$len,`log(16*$SZ)/log(2)`
231 .long 0xb93e0002 # kimd %r0,%r2
232 brc 1,.-4 # pay attention to "partial completion"
233 br %r14
234.align 16
235.Lsoftware:
236___
237$code.=<<___;
238 sllg $len,$len,`log(16*$SZ)/log(2)`
239 lghi %r1,-$frame
240 agr $len,$inp
241 stmg $ctx,%r15,16($sp)
242 lgr %r0,$sp
243 la $sp,0(%r1,$sp)
244 stg %r0,0($sp)
245
246 larl $tbl,$Table
247 $LD $A,`0*$SZ`($ctx)
248 $LD $B,`1*$SZ`($ctx)
249 $LD $C,`2*$SZ`($ctx)
250 $LD $D,`3*$SZ`($ctx)
251 $LD $E,`4*$SZ`($ctx)
252 $LD $F,`5*$SZ`($ctx)
253 $LD $G,`6*$SZ`($ctx)
254 $LD $H,`7*$SZ`($ctx)
255
256.Lloop:
257 lghi $len,0
258___
259for ($i=0;$i<16;$i++) { &BODY_00_15($i,@V); unshift(@V,pop(@V)); }
260$code.=".Lrounds_16_xx:\n";
261for (;$i<32;$i++) { &BODY_16_XX($i,@V); unshift(@V,pop(@V)); }
262$code.=<<___;
263 aghi $len,`16*$SZ`
264 lghi $t0,`($rounds-16)*$SZ`
265 clgr $len,$t0
266 jne .Lrounds_16_xx
267
268 lg $ctx,`$frame+16`($sp)
269 la $inp,`16*$SZ`($inp)
270 $ADD $A,`0*$SZ`($ctx)
271 $ADD $B,`1*$SZ`($ctx)
272 $ADD $C,`2*$SZ`($ctx)
273 $ADD $D,`3*$SZ`($ctx)
274 $ADD $E,`4*$SZ`($ctx)
275 $ADD $F,`5*$SZ`($ctx)
276 $ADD $G,`6*$SZ`($ctx)
277 $ADD $H,`7*$SZ`($ctx)
278 $ST $A,`0*$SZ`($ctx)
279 $ST $B,`1*$SZ`($ctx)
280 $ST $C,`2*$SZ`($ctx)
281 $ST $D,`3*$SZ`($ctx)
282 $ST $E,`4*$SZ`($ctx)
283 $ST $F,`5*$SZ`($ctx)
284 $ST $G,`6*$SZ`($ctx)
285 $ST $H,`7*$SZ`($ctx)
286 clg $inp,`$frame+32`($sp)
287 jne .Lloop
288
289 lmg %r6,%r15,`$frame+48`($sp)
290 br %r14
291.size $Func,.-$Func
292.string "SHA${label} block transform for s390x, CRYPTOGAMS by <appro\@openssl.org>"
293.comm OPENSSL_s390xcap_P,8,8
294___
295
296$code =~ s/\`([^\`]*)\`/eval $1/gem;
297# unlike 32-bit shift 64-bit one takes three arguments
298$code =~ s/(srlg\s+)(%r[0-9]+),/$1$2,$2,/gm;
299
300print $code;
301close STDOUT;
diff --git a/src/lib/libcrypto/sha/asm/sha512-sparcv9.pl b/src/lib/libcrypto/sha/asm/sha512-sparcv9.pl
new file mode 100644
index 0000000000..54241aab50
--- /dev/null
+++ b/src/lib/libcrypto/sha/asm/sha512-sparcv9.pl
@@ -0,0 +1,593 @@
1#!/usr/bin/env perl
2
3# ====================================================================
4# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
5# project. The module is, however, dual licensed under OpenSSL and
6# CRYPTOGAMS licenses depending on where you obtain it. For further
7# details see http://www.openssl.org/~appro/cryptogams/.
8# ====================================================================
9
10# SHA256 performance improvement over compiler generated code varies
11# from 40% for Sun C [32-bit build] to 70% for gcc [3.3, 64-bit
12# build]. Just like in SHA1 module I aim to ensure scalability on
13# UltraSPARC T1 by packing X[16] to 8 64-bit registers.
14
15# SHA512 on pre-T1 UltraSPARC.
16#
17# Performance is >75% better than 64-bit code generated by Sun C and
18# over 2x than 32-bit code. X[16] resides on stack, but access to it
19# is scheduled for L2 latency and staged through 32 least significant
20# bits of %l0-%l7. The latter is done to achieve 32-/64-bit ABI
21# duality. Nevetheless it's ~40% faster than SHA256, which is pretty
22# good [optimal coefficient is 50%].
23#
24# SHA512 on UltraSPARC T1.
25#
26# It's not any faster than 64-bit code generated by Sun C 5.8. This is
27# because 64-bit code generator has the advantage of using 64-bit
28# loads(*) to access X[16], which I consciously traded for 32-/64-bit
29# ABI duality [as per above]. But it surpasses 32-bit Sun C generated
30# code by 60%, not to mention that it doesn't suffer from severe decay
31# when running 4 times physical cores threads and that it leaves gcc
32# [3.4] behind by over 4x factor! If compared to SHA256, single thread
33# performance is only 10% better, but overall throughput for maximum
34# amount of threads for given CPU exceeds corresponding one of SHA256
35# by 30% [again, optimal coefficient is 50%].
36#
37# (*) Unlike pre-T1 UltraSPARC loads on T1 are executed strictly
38# in-order, i.e. load instruction has to complete prior next
39# instruction in given thread is executed, even if the latter is
40# not dependent on load result! This means that on T1 two 32-bit
41# loads are always slower than one 64-bit load. Once again this
42# is unlike pre-T1 UltraSPARC, where, if scheduled appropriately,
43# 2x32-bit loads can be as fast as 1x64-bit ones.
44
45$bits=32;
46for (@ARGV) { $bits=64 if (/\-m64/ || /\-xarch\=v9/); }
47if ($bits==64) { $bias=2047; $frame=192; }
48else { $bias=0; $frame=112; }
49
50$output=shift;
51open STDOUT,">$output";
52
53if ($output =~ /512/) {
54 $label="512";
55 $SZ=8;
56 $LD="ldx"; # load from memory
57 $ST="stx"; # store to memory
58 $SLL="sllx"; # shift left logical
59 $SRL="srlx"; # shift right logical
60 @Sigma0=(28,34,39);
61 @Sigma1=(14,18,41);
62 @sigma0=( 7, 1, 8); # right shift first
63 @sigma1=( 6,19,61); # right shift first
64 $lastK=0x817;
65 $rounds=80;
66 $align=4;
67
68 $locals=16*$SZ; # X[16]
69
70 $A="%o0";
71 $B="%o1";
72 $C="%o2";
73 $D="%o3";
74 $E="%o4";
75 $F="%o5";
76 $G="%g1";
77 $H="%o7";
78 @V=($A,$B,$C,$D,$E,$F,$G,$H);
79} else {
80 $label="256";
81 $SZ=4;
82 $LD="ld"; # load from memory
83 $ST="st"; # store to memory
84 $SLL="sll"; # shift left logical
85 $SRL="srl"; # shift right logical
86 @Sigma0=( 2,13,22);
87 @Sigma1=( 6,11,25);
88 @sigma0=( 3, 7,18); # right shift first
89 @sigma1=(10,17,19); # right shift first
90 $lastK=0x8f2;
91 $rounds=64;
92 $align=8;
93
94 $locals=0; # X[16] is register resident
95 @X=("%o0","%o1","%o2","%o3","%o4","%o5","%g1","%o7");
96
97 $A="%l0";
98 $B="%l1";
99 $C="%l2";
100 $D="%l3";
101 $E="%l4";
102 $F="%l5";
103 $G="%l6";
104 $H="%l7";
105 @V=($A,$B,$C,$D,$E,$F,$G,$H);
106}
107$T1="%g2";
108$tmp0="%g3";
109$tmp1="%g4";
110$tmp2="%g5";
111
112$ctx="%i0";
113$inp="%i1";
114$len="%i2";
115$Ktbl="%i3";
116$tmp31="%i4";
117$tmp32="%i5";
118
119########### SHA256
120$Xload = sub {
121my ($i,$a,$b,$c,$d,$e,$f,$g,$h)=@_;
122
123 if ($i==0) {
124$code.=<<___;
125 ldx [$inp+0],@X[0]
126 ldx [$inp+16],@X[2]
127 ldx [$inp+32],@X[4]
128 ldx [$inp+48],@X[6]
129 ldx [$inp+8],@X[1]
130 ldx [$inp+24],@X[3]
131 subcc %g0,$tmp31,$tmp32 ! should be 64-$tmp31, but -$tmp31 works too
132 ldx [$inp+40],@X[5]
133 bz,pt %icc,.Laligned
134 ldx [$inp+56],@X[7]
135
136 sllx @X[0],$tmp31,@X[0]
137 ldx [$inp+64],$T1
138___
139for($j=0;$j<7;$j++)
140{ $code.=<<___;
141 srlx @X[$j+1],$tmp32,$tmp1
142 sllx @X[$j+1],$tmp31,@X[$j+1]
143 or $tmp1,@X[$j],@X[$j]
144___
145}
146$code.=<<___;
147 srlx $T1,$tmp32,$T1
148 or $T1,@X[7],@X[7]
149.Laligned:
150___
151 }
152
153 if ($i&1) {
154 $code.="\tadd @X[$i/2],$h,$T1\n";
155 } else {
156 $code.="\tsrlx @X[$i/2],32,$T1\n\tadd $h,$T1,$T1\n";
157 }
158} if ($SZ==4);
159
160########### SHA512
161$Xload = sub {
162my ($i,$a,$b,$c,$d,$e,$f,$g,$h)=@_;
163my @pair=("%l".eval(($i*2)%8),"%l".eval(($i*2)%8+1),"%l".eval((($i+1)*2)%8));
164
165$code.=<<___ if ($i==0);
166 ld [$inp+0],%l0
167 ld [$inp+4],%l1
168 ld [$inp+8],%l2
169 ld [$inp+12],%l3
170 ld [$inp+16],%l4
171 ld [$inp+20],%l5
172 ld [$inp+24],%l6
173 ld [$inp+28],%l7
174___
175$code.=<<___ if ($i<15);
176 sllx @pair[1],$tmp31,$tmp2 ! Xload($i)
177 add $tmp31,32,$tmp0
178 sllx @pair[0],$tmp0,$tmp1
179 `"ld [$inp+".eval(32+0+$i*8)."],@pair[0]" if ($i<12)`
180 srlx @pair[2],$tmp32,@pair[1]
181 or $tmp1,$tmp2,$tmp2
182 or @pair[1],$tmp2,$tmp2
183 `"ld [$inp+".eval(32+4+$i*8)."],@pair[1]" if ($i<12)`
184 add $h,$tmp2,$T1
185 $ST $tmp2,[%sp+`$bias+$frame+$i*$SZ`]
186___
187$code.=<<___ if ($i==12);
188 brnz,a $tmp31,.+8
189 ld [$inp+128],%l0
190___
191$code.=<<___ if ($i==15);
192 ld [%sp+`$bias+$frame+(($i+1+1)%16)*$SZ+0`],%l2
193 sllx @pair[1],$tmp31,$tmp2 ! Xload($i)
194 add $tmp31,32,$tmp0
195 ld [%sp+`$bias+$frame+(($i+1+1)%16)*$SZ+4`],%l3
196 sllx @pair[0],$tmp0,$tmp1
197 ld [%sp+`$bias+$frame+(($i+1+9)%16)*$SZ+0`],%l4
198 srlx @pair[2],$tmp32,@pair[1]
199 or $tmp1,$tmp2,$tmp2
200 ld [%sp+`$bias+$frame+(($i+1+9)%16)*$SZ+4`],%l5
201 or @pair[1],$tmp2,$tmp2
202 ld [%sp+`$bias+$frame+(($i+1+14)%16)*$SZ+0`],%l6
203 add $h,$tmp2,$T1
204 $ST $tmp2,[%sp+`$bias+$frame+$i*$SZ`]
205 ld [%sp+`$bias+$frame+(($i+1+14)%16)*$SZ+4`],%l7
206 ld [%sp+`$bias+$frame+(($i+1+0)%16)*$SZ+0`],%l0
207 ld [%sp+`$bias+$frame+(($i+1+0)%16)*$SZ+4`],%l1
208___
209} if ($SZ==8);
210
211########### common
212sub BODY_00_15 {
213my ($i,$a,$b,$c,$d,$e,$f,$g,$h)=@_;
214
215 if ($i<16) {
216 &$Xload(@_);
217 } else {
218 $code.="\tadd $h,$T1,$T1\n";
219 }
220
221$code.=<<___;
222 $SRL $e,@Sigma1[0],$h !! $i
223 xor $f,$g,$tmp2
224 $SLL $e,`$SZ*8-@Sigma1[2]`,$tmp1
225 and $e,$tmp2,$tmp2
226 $SRL $e,@Sigma1[1],$tmp0
227 xor $tmp1,$h,$h
228 $SLL $e,`$SZ*8-@Sigma1[1]`,$tmp1
229 xor $tmp0,$h,$h
230 $SRL $e,@Sigma1[2],$tmp0
231 xor $tmp1,$h,$h
232 $SLL $e,`$SZ*8-@Sigma1[0]`,$tmp1
233 xor $tmp0,$h,$h
234 xor $g,$tmp2,$tmp2 ! Ch(e,f,g)
235 xor $tmp1,$h,$tmp0 ! Sigma1(e)
236
237 $SRL $a,@Sigma0[0],$h
238 add $tmp2,$T1,$T1
239 $LD [$Ktbl+`$i*$SZ`],$tmp2 ! K[$i]
240 $SLL $a,`$SZ*8-@Sigma0[2]`,$tmp1
241 add $tmp0,$T1,$T1
242 $SRL $a,@Sigma0[1],$tmp0
243 xor $tmp1,$h,$h
244 $SLL $a,`$SZ*8-@Sigma0[1]`,$tmp1
245 xor $tmp0,$h,$h
246 $SRL $a,@Sigma0[2],$tmp0
247 xor $tmp1,$h,$h
248 $SLL $a,`$SZ*8-@Sigma0[0]`,$tmp1
249 xor $tmp0,$h,$h
250 xor $tmp1,$h,$h ! Sigma0(a)
251
252 or $a,$b,$tmp0
253 and $a,$b,$tmp1
254 and $c,$tmp0,$tmp0
255 or $tmp0,$tmp1,$tmp1 ! Maj(a,b,c)
256 add $tmp2,$T1,$T1 ! +=K[$i]
257 add $tmp1,$h,$h
258
259 add $T1,$d,$d
260 add $T1,$h,$h
261___
262}
263
264########### SHA256
265$BODY_16_XX = sub {
266my $i=@_[0];
267my $xi;
268
269 if ($i&1) {
270 $xi=$tmp32;
271 $code.="\tsrlx @X[(($i+1)/2)%8],32,$xi\n";
272 } else {
273 $xi=@X[(($i+1)/2)%8];
274 }
275$code.=<<___;
276 srl $xi,@sigma0[0],$T1 !! Xupdate($i)
277 sll $xi,`32-@sigma0[2]`,$tmp1
278 srl $xi,@sigma0[1],$tmp0
279 xor $tmp1,$T1,$T1
280 sll $tmp1,`@sigma0[2]-@sigma0[1]`,$tmp1
281 xor $tmp0,$T1,$T1
282 srl $xi,@sigma0[2],$tmp0
283 xor $tmp1,$T1,$T1
284___
285 if ($i&1) {
286 $xi=@X[(($i+14)/2)%8];
287 } else {
288 $xi=$tmp32;
289 $code.="\tsrlx @X[(($i+14)/2)%8],32,$xi\n";
290 }
291$code.=<<___;
292 srl $xi,@sigma1[0],$tmp2
293 xor $tmp0,$T1,$T1 ! T1=sigma0(X[i+1])
294 sll $xi,`32-@sigma1[2]`,$tmp1
295 srl $xi,@sigma1[1],$tmp0
296 xor $tmp1,$tmp2,$tmp2
297 sll $tmp1,`@sigma1[2]-@sigma1[1]`,$tmp1
298 xor $tmp0,$tmp2,$tmp2
299 srl $xi,@sigma1[2],$tmp0
300 xor $tmp1,$tmp2,$tmp2
301___
302 if ($i&1) {
303 $xi=@X[($i/2)%8];
304$code.=<<___;
305 srlx @X[(($i+9)/2)%8],32,$tmp1 ! X[i+9]
306 xor $tmp0,$tmp2,$tmp2 ! sigma1(X[i+14])
307 srl @X[($i/2)%8],0,$tmp0
308 add $xi,$T1,$T1 ! +=X[i]
309 xor $tmp0,@X[($i/2)%8],@X[($i/2)%8]
310 add $tmp2,$T1,$T1
311 add $tmp1,$T1,$T1
312
313 srl $T1,0,$T1
314 or $T1,@X[($i/2)%8],@X[($i/2)%8]
315___
316 } else {
317 $xi=@X[(($i+9)/2)%8];
318$code.=<<___;
319 srlx @X[($i/2)%8],32,$tmp1 ! X[i]
320 xor $tmp0,$tmp2,$tmp2 ! sigma1(X[i+14])
321 srl @X[($i/2)%8],0,@X[($i/2)%8]
322 add $xi,$T1,$T1 ! +=X[i+9]
323 add $tmp2,$T1,$T1
324 add $tmp1,$T1,$T1
325
326 sllx $T1,32,$tmp0
327 or $tmp0,@X[($i/2)%8],@X[($i/2)%8]
328___
329 }
330 &BODY_00_15(@_);
331} if ($SZ==4);
332
333########### SHA512
334$BODY_16_XX = sub {
335my $i=@_[0];
336my @pair=("%l".eval(($i*2)%8),"%l".eval(($i*2)%8+1));
337
338$code.=<<___;
339 sllx %l2,32,$tmp0 !! Xupdate($i)
340 or %l3,$tmp0,$tmp0
341
342 srlx $tmp0,@sigma0[0],$T1
343 ld [%sp+`$bias+$frame+(($i+1+1)%16)*$SZ+0`],%l2
344 sllx $tmp0,`64-@sigma0[2]`,$tmp1
345 ld [%sp+`$bias+$frame+(($i+1+1)%16)*$SZ+4`],%l3
346 srlx $tmp0,@sigma0[1],$tmp0
347 xor $tmp1,$T1,$T1
348 sllx $tmp1,`@sigma0[2]-@sigma0[1]`,$tmp1
349 xor $tmp0,$T1,$T1
350 srlx $tmp0,`@sigma0[2]-@sigma0[1]`,$tmp0
351 xor $tmp1,$T1,$T1
352 sllx %l6,32,$tmp2
353 xor $tmp0,$T1,$T1 ! sigma0(X[$i+1])
354 or %l7,$tmp2,$tmp2
355
356 srlx $tmp2,@sigma1[0],$tmp1
357 ld [%sp+`$bias+$frame+(($i+1+14)%16)*$SZ+0`],%l6
358 sllx $tmp2,`64-@sigma1[2]`,$tmp0
359 ld [%sp+`$bias+$frame+(($i+1+14)%16)*$SZ+4`],%l7
360 srlx $tmp2,@sigma1[1],$tmp2
361 xor $tmp0,$tmp1,$tmp1
362 sllx $tmp0,`@sigma1[2]-@sigma1[1]`,$tmp0
363 xor $tmp2,$tmp1,$tmp1
364 srlx $tmp2,`@sigma1[2]-@sigma1[1]`,$tmp2
365 xor $tmp0,$tmp1,$tmp1
366 sllx %l4,32,$tmp0
367 xor $tmp2,$tmp1,$tmp1 ! sigma1(X[$i+14])
368 ld [%sp+`$bias+$frame+(($i+1+9)%16)*$SZ+0`],%l4
369 or %l5,$tmp0,$tmp0
370 ld [%sp+`$bias+$frame+(($i+1+9)%16)*$SZ+4`],%l5
371
372 sllx %l0,32,$tmp2
373 add $tmp1,$T1,$T1
374 ld [%sp+`$bias+$frame+(($i+1+0)%16)*$SZ+0`],%l0
375 or %l1,$tmp2,$tmp2
376 add $tmp0,$T1,$T1 ! +=X[$i+9]
377 ld [%sp+`$bias+$frame+(($i+1+0)%16)*$SZ+4`],%l1
378 add $tmp2,$T1,$T1 ! +=X[$i]
379 $ST $T1,[%sp+`$bias+$frame+($i%16)*$SZ`]
380___
381 &BODY_00_15(@_);
382} if ($SZ==8);
383
384$code.=<<___ if ($bits==64);
385.register %g2,#scratch
386.register %g3,#scratch
387___
388$code.=<<___;
389.section ".text",#alloc,#execinstr
390
391.align 64
392K${label}:
393.type K${label},#object
394___
395if ($SZ==4) {
396$code.=<<___;
397 .long 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5
398 .long 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5
399 .long 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3
400 .long 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174
401 .long 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc
402 .long 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da
403 .long 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7
404 .long 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967
405 .long 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13
406 .long 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85
407 .long 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3
408 .long 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070
409 .long 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5
410 .long 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3
411 .long 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208
412 .long 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
413___
414} else {
415$code.=<<___;
416 .long 0x428a2f98,0xd728ae22, 0x71374491,0x23ef65cd
417 .long 0xb5c0fbcf,0xec4d3b2f, 0xe9b5dba5,0x8189dbbc
418 .long 0x3956c25b,0xf348b538, 0x59f111f1,0xb605d019
419 .long 0x923f82a4,0xaf194f9b, 0xab1c5ed5,0xda6d8118
420 .long 0xd807aa98,0xa3030242, 0x12835b01,0x45706fbe
421 .long 0x243185be,0x4ee4b28c, 0x550c7dc3,0xd5ffb4e2
422 .long 0x72be5d74,0xf27b896f, 0x80deb1fe,0x3b1696b1
423 .long 0x9bdc06a7,0x25c71235, 0xc19bf174,0xcf692694
424 .long 0xe49b69c1,0x9ef14ad2, 0xefbe4786,0x384f25e3
425 .long 0x0fc19dc6,0x8b8cd5b5, 0x240ca1cc,0x77ac9c65
426 .long 0x2de92c6f,0x592b0275, 0x4a7484aa,0x6ea6e483
427 .long 0x5cb0a9dc,0xbd41fbd4, 0x76f988da,0x831153b5
428 .long 0x983e5152,0xee66dfab, 0xa831c66d,0x2db43210
429 .long 0xb00327c8,0x98fb213f, 0xbf597fc7,0xbeef0ee4
430 .long 0xc6e00bf3,0x3da88fc2, 0xd5a79147,0x930aa725
431 .long 0x06ca6351,0xe003826f, 0x14292967,0x0a0e6e70
432 .long 0x27b70a85,0x46d22ffc, 0x2e1b2138,0x5c26c926
433 .long 0x4d2c6dfc,0x5ac42aed, 0x53380d13,0x9d95b3df
434 .long 0x650a7354,0x8baf63de, 0x766a0abb,0x3c77b2a8
435 .long 0x81c2c92e,0x47edaee6, 0x92722c85,0x1482353b
436 .long 0xa2bfe8a1,0x4cf10364, 0xa81a664b,0xbc423001
437 .long 0xc24b8b70,0xd0f89791, 0xc76c51a3,0x0654be30
438 .long 0xd192e819,0xd6ef5218, 0xd6990624,0x5565a910
439 .long 0xf40e3585,0x5771202a, 0x106aa070,0x32bbd1b8
440 .long 0x19a4c116,0xb8d2d0c8, 0x1e376c08,0x5141ab53
441 .long 0x2748774c,0xdf8eeb99, 0x34b0bcb5,0xe19b48a8
442 .long 0x391c0cb3,0xc5c95a63, 0x4ed8aa4a,0xe3418acb
443 .long 0x5b9cca4f,0x7763e373, 0x682e6ff3,0xd6b2b8a3
444 .long 0x748f82ee,0x5defb2fc, 0x78a5636f,0x43172f60
445 .long 0x84c87814,0xa1f0ab72, 0x8cc70208,0x1a6439ec
446 .long 0x90befffa,0x23631e28, 0xa4506ceb,0xde82bde9
447 .long 0xbef9a3f7,0xb2c67915, 0xc67178f2,0xe372532b
448 .long 0xca273ece,0xea26619c, 0xd186b8c7,0x21c0c207
449 .long 0xeada7dd6,0xcde0eb1e, 0xf57d4f7f,0xee6ed178
450 .long 0x06f067aa,0x72176fba, 0x0a637dc5,0xa2c898a6
451 .long 0x113f9804,0xbef90dae, 0x1b710b35,0x131c471b
452 .long 0x28db77f5,0x23047d84, 0x32caab7b,0x40c72493
453 .long 0x3c9ebe0a,0x15c9bebc, 0x431d67c4,0x9c100d4c
454 .long 0x4cc5d4be,0xcb3e42b6, 0x597f299c,0xfc657e2a
455 .long 0x5fcb6fab,0x3ad6faec, 0x6c44198c,0x4a475817
456___
457}
458$code.=<<___;
459.size K${label},.-K${label}
460.globl sha${label}_block_data_order
461sha${label}_block_data_order:
462 save %sp,`-$frame-$locals`,%sp
463 and $inp,`$align-1`,$tmp31
464 sllx $len,`log(16*$SZ)/log(2)`,$len
465 andn $inp,`$align-1`,$inp
466 sll $tmp31,3,$tmp31
467 add $inp,$len,$len
468___
469$code.=<<___ if ($SZ==8); # SHA512
470 mov 32,$tmp32
471 sub $tmp32,$tmp31,$tmp32
472___
473$code.=<<___;
474.Lpic: call .+8
475 add %o7,K${label}-.Lpic,$Ktbl
476
477 $LD [$ctx+`0*$SZ`],$A
478 $LD [$ctx+`1*$SZ`],$B
479 $LD [$ctx+`2*$SZ`],$C
480 $LD [$ctx+`3*$SZ`],$D
481 $LD [$ctx+`4*$SZ`],$E
482 $LD [$ctx+`5*$SZ`],$F
483 $LD [$ctx+`6*$SZ`],$G
484 $LD [$ctx+`7*$SZ`],$H
485
486.Lloop:
487___
488for ($i=0;$i<16;$i++) { &BODY_00_15($i,@V); unshift(@V,pop(@V)); }
489$code.=".L16_xx:\n";
490for (;$i<32;$i++) { &$BODY_16_XX($i,@V); unshift(@V,pop(@V)); }
491$code.=<<___;
492 and $tmp2,0xfff,$tmp2
493 cmp $tmp2,$lastK
494 bne .L16_xx
495 add $Ktbl,`16*$SZ`,$Ktbl ! Ktbl+=16
496
497___
498$code.=<<___ if ($SZ==4); # SHA256
499 $LD [$ctx+`0*$SZ`],@X[0]
500 $LD [$ctx+`1*$SZ`],@X[1]
501 $LD [$ctx+`2*$SZ`],@X[2]
502 $LD [$ctx+`3*$SZ`],@X[3]
503 $LD [$ctx+`4*$SZ`],@X[4]
504 $LD [$ctx+`5*$SZ`],@X[5]
505 $LD [$ctx+`6*$SZ`],@X[6]
506 $LD [$ctx+`7*$SZ`],@X[7]
507
508 add $A,@X[0],$A
509 $ST $A,[$ctx+`0*$SZ`]
510 add $B,@X[1],$B
511 $ST $B,[$ctx+`1*$SZ`]
512 add $C,@X[2],$C
513 $ST $C,[$ctx+`2*$SZ`]
514 add $D,@X[3],$D
515 $ST $D,[$ctx+`3*$SZ`]
516 add $E,@X[4],$E
517 $ST $E,[$ctx+`4*$SZ`]
518 add $F,@X[5],$F
519 $ST $F,[$ctx+`5*$SZ`]
520 add $G,@X[6],$G
521 $ST $G,[$ctx+`6*$SZ`]
522 add $H,@X[7],$H
523 $ST $H,[$ctx+`7*$SZ`]
524___
525$code.=<<___ if ($SZ==8); # SHA512
526 ld [$ctx+`0*$SZ+0`],%l0
527 ld [$ctx+`0*$SZ+4`],%l1
528 ld [$ctx+`1*$SZ+0`],%l2
529 ld [$ctx+`1*$SZ+4`],%l3
530 ld [$ctx+`2*$SZ+0`],%l4
531 ld [$ctx+`2*$SZ+4`],%l5
532 ld [$ctx+`3*$SZ+0`],%l6
533
534 sllx %l0,32,$tmp0
535 ld [$ctx+`3*$SZ+4`],%l7
536 sllx %l2,32,$tmp1
537 or %l1,$tmp0,$tmp0
538 or %l3,$tmp1,$tmp1
539 add $tmp0,$A,$A
540 add $tmp1,$B,$B
541 $ST $A,[$ctx+`0*$SZ`]
542 sllx %l4,32,$tmp2
543 $ST $B,[$ctx+`1*$SZ`]
544 sllx %l6,32,$T1
545 or %l5,$tmp2,$tmp2
546 or %l7,$T1,$T1
547 add $tmp2,$C,$C
548 $ST $C,[$ctx+`2*$SZ`]
549 add $T1,$D,$D
550 $ST $D,[$ctx+`3*$SZ`]
551
552 ld [$ctx+`4*$SZ+0`],%l0
553 ld [$ctx+`4*$SZ+4`],%l1
554 ld [$ctx+`5*$SZ+0`],%l2
555 ld [$ctx+`5*$SZ+4`],%l3
556 ld [$ctx+`6*$SZ+0`],%l4
557 ld [$ctx+`6*$SZ+4`],%l5
558 ld [$ctx+`7*$SZ+0`],%l6
559
560 sllx %l0,32,$tmp0
561 ld [$ctx+`7*$SZ+4`],%l7
562 sllx %l2,32,$tmp1
563 or %l1,$tmp0,$tmp0
564 or %l3,$tmp1,$tmp1
565 add $tmp0,$E,$E
566 add $tmp1,$F,$F
567 $ST $E,[$ctx+`4*$SZ`]
568 sllx %l4,32,$tmp2
569 $ST $F,[$ctx+`5*$SZ`]
570 sllx %l6,32,$T1
571 or %l5,$tmp2,$tmp2
572 or %l7,$T1,$T1
573 add $tmp2,$G,$G
574 $ST $G,[$ctx+`6*$SZ`]
575 add $T1,$H,$H
576 $ST $H,[$ctx+`7*$SZ`]
577___
578$code.=<<___;
579 add $inp,`16*$SZ`,$inp ! advance inp
580 cmp $inp,$len
581 bne `$bits==64?"%xcc":"%icc"`,.Lloop
582 sub $Ktbl,`($rounds-16)*$SZ`,$Ktbl ! rewind Ktbl
583
584 ret
585 restore
586.type sha${label}_block_data_order,#function
587.size sha${label}_block_data_order,(.-sha${label}_block_data_order)
588.asciz "SHA${label} block transform for SPARCv9, CRYPTOGAMS by <appro\@openssl.org>"
589___
590
591$code =~ s/\`([^\`]*)\`/eval $1/gem;
592print $code;
593close STDOUT;
diff --git a/src/lib/libcrypto/sha/asm/sha512-x86_64.pl b/src/lib/libcrypto/sha/asm/sha512-x86_64.pl
index b6252d31ec..e6643f8cf6 100755
--- a/src/lib/libcrypto/sha/asm/sha512-x86_64.pl
+++ b/src/lib/libcrypto/sha/asm/sha512-x86_64.pl
@@ -40,14 +40,18 @@
40# sha256_block:-( This is presumably because 64-bit shifts/rotates 40# sha256_block:-( This is presumably because 64-bit shifts/rotates
41# apparently are not atomic instructions, but implemented in microcode. 41# apparently are not atomic instructions, but implemented in microcode.
42 42
43$output=shift; 43$flavour = shift;
44$output = shift;
45if ($flavour =~ /\./) { $output = $flavour; undef $flavour; }
46
47$win64=0; $win64=1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/);
44 48
45$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; 49$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
46( $xlate="${dir}x86_64-xlate.pl" and -f $xlate ) or 50( $xlate="${dir}x86_64-xlate.pl" and -f $xlate ) or
47( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or 51( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or
48die "can't locate x86_64-xlate.pl"; 52die "can't locate x86_64-xlate.pl";
49 53
50open STDOUT,"| $^X $xlate $output"; 54open STDOUT,"| $^X $xlate $flavour $output";
51 55
52if ($output =~ /512/) { 56if ($output =~ /512/) {
53 $func="sha512_block_data_order"; 57 $func="sha512_block_data_order";
@@ -186,7 +190,7 @@ $func:
186 push %r13 190 push %r13
187 push %r14 191 push %r14
188 push %r15 192 push %r15
189 mov %rsp,%rbp # copy %rsp 193 mov %rsp,%r11 # copy %rsp
190 shl \$4,%rdx # num*16 194 shl \$4,%rdx # num*16
191 sub \$$framesz,%rsp 195 sub \$$framesz,%rsp
192 lea ($inp,%rdx,$SZ),%rdx # inp+num*16*$SZ 196 lea ($inp,%rdx,$SZ),%rdx # inp+num*16*$SZ
@@ -194,10 +198,10 @@ $func:
194 mov $ctx,$_ctx # save ctx, 1st arg 198 mov $ctx,$_ctx # save ctx, 1st arg
195 mov $inp,$_inp # save inp, 2nd arh 199 mov $inp,$_inp # save inp, 2nd arh
196 mov %rdx,$_end # save end pointer, "3rd" arg 200 mov %rdx,$_end # save end pointer, "3rd" arg
197 mov %rbp,$_rsp # save copy of %rsp 201 mov %r11,$_rsp # save copy of %rsp
202.Lprologue:
198 203
199 .picmeup $Tbl 204 lea $TABLE(%rip),$Tbl
200 lea $TABLE-.($Tbl),$Tbl
201 205
202 mov $SZ*0($ctx),$A 206 mov $SZ*0($ctx),$A
203 mov $SZ*1($ctx),$B 207 mov $SZ*1($ctx),$B
@@ -257,14 +261,15 @@ $code.=<<___;
257 mov $H,$SZ*7($ctx) 261 mov $H,$SZ*7($ctx)
258 jb .Lloop 262 jb .Lloop
259 263
260 mov $_rsp,%rsp 264 mov $_rsp,%rsi
261 pop %r15 265 mov (%rsi),%r15
262 pop %r14 266 mov 8(%rsi),%r14
263 pop %r13 267 mov 16(%rsi),%r13
264 pop %r12 268 mov 24(%rsi),%r12
265 pop %rbp 269 mov 32(%rsi),%rbp
266 pop %rbx 270 mov 40(%rsi),%rbx
267 271 lea 48(%rsi),%rsp
272.Lepilogue:
268 ret 273 ret
269.size $func,.-$func 274.size $func,.-$func
270___ 275___
@@ -339,6 +344,113 @@ $TABLE:
339___ 344___
340} 345}
341 346
347# EXCEPTION_DISPOSITION handler (EXCEPTION_RECORD *rec,ULONG64 frame,
348# CONTEXT *context,DISPATCHER_CONTEXT *disp)
349if ($win64) {
350$rec="%rcx";
351$frame="%rdx";
352$context="%r8";
353$disp="%r9";
354
355$code.=<<___;
356.extern __imp_RtlVirtualUnwind
357.type se_handler,\@abi-omnipotent
358.align 16
359se_handler:
360 push %rsi
361 push %rdi
362 push %rbx
363 push %rbp
364 push %r12
365 push %r13
366 push %r14
367 push %r15
368 pushfq
369 sub \$64,%rsp
370
371 mov 120($context),%rax # pull context->Rax
372 mov 248($context),%rbx # pull context->Rip
373
374 lea .Lprologue(%rip),%r10
375 cmp %r10,%rbx # context->Rip<.Lprologue
376 jb .Lin_prologue
377
378 mov 152($context),%rax # pull context->Rsp
379
380 lea .Lepilogue(%rip),%r10
381 cmp %r10,%rbx # context->Rip>=.Lepilogue
382 jae .Lin_prologue
383
384 mov 16*$SZ+3*8(%rax),%rax # pull $_rsp
385 lea 48(%rax),%rax
386
387 mov -8(%rax),%rbx
388 mov -16(%rax),%rbp
389 mov -24(%rax),%r12
390 mov -32(%rax),%r13
391 mov -40(%rax),%r14
392 mov -48(%rax),%r15
393 mov %rbx,144($context) # restore context->Rbx
394 mov %rbp,160($context) # restore context->Rbp
395 mov %r12,216($context) # restore context->R12
396 mov %r13,224($context) # restore context->R13
397 mov %r14,232($context) # restore context->R14
398 mov %r15,240($context) # restore context->R15
399
400.Lin_prologue:
401 mov 8(%rax),%rdi
402 mov 16(%rax),%rsi
403 mov %rax,152($context) # restore context->Rsp
404 mov %rsi,168($context) # restore context->Rsi
405 mov %rdi,176($context) # restore context->Rdi
406
407 mov 40($disp),%rdi # disp->ContextRecord
408 mov $context,%rsi # context
409 mov \$154,%ecx # sizeof(CONTEXT)
410 .long 0xa548f3fc # cld; rep movsq
411
412 mov $disp,%rsi
413 xor %rcx,%rcx # arg1, UNW_FLAG_NHANDLER
414 mov 8(%rsi),%rdx # arg2, disp->ImageBase
415 mov 0(%rsi),%r8 # arg3, disp->ControlPc
416 mov 16(%rsi),%r9 # arg4, disp->FunctionEntry
417 mov 40(%rsi),%r10 # disp->ContextRecord
418 lea 56(%rsi),%r11 # &disp->HandlerData
419 lea 24(%rsi),%r12 # &disp->EstablisherFrame
420 mov %r10,32(%rsp) # arg5
421 mov %r11,40(%rsp) # arg6
422 mov %r12,48(%rsp) # arg7
423 mov %rcx,56(%rsp) # arg8, (NULL)
424 call *__imp_RtlVirtualUnwind(%rip)
425
426 mov \$1,%eax # ExceptionContinueSearch
427 add \$64,%rsp
428 popfq
429 pop %r15
430 pop %r14
431 pop %r13
432 pop %r12
433 pop %rbp
434 pop %rbx
435 pop %rdi
436 pop %rsi
437 ret
438.size se_handler,.-se_handler
439
440.section .pdata
441.align 4
442 .rva .LSEH_begin_$func
443 .rva .LSEH_end_$func
444 .rva .LSEH_info_$func
445
446.section .xdata
447.align 8
448.LSEH_info_$func:
449 .byte 9,0,0,0
450 .rva se_handler
451___
452}
453
342$code =~ s/\`([^\`]*)\`/eval $1/gem; 454$code =~ s/\`([^\`]*)\`/eval $1/gem;
343print $code; 455print $code;
344close STDOUT; 456close STDOUT;
diff --git a/src/lib/libcrypto/sha/sha.h b/src/lib/libcrypto/sha/sha.h
index 47a2c29f66..16cacf9fc0 100644
--- a/src/lib/libcrypto/sha/sha.h
+++ b/src/lib/libcrypto/sha/sha.h
@@ -81,7 +81,7 @@ extern "C" {
81 * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 81 * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
82 */ 82 */
83 83
84#if defined(OPENSSL_SYS_WIN16) || defined(__LP32__) 84#if defined(__LP32__)
85#define SHA_LONG unsigned long 85#define SHA_LONG unsigned long
86#elif defined(OPENSSL_SYS_CRAY) || defined(__ILP64__) 86#elif defined(OPENSSL_SYS_CRAY) || defined(__ILP64__)
87#define SHA_LONG unsigned long 87#define SHA_LONG unsigned long
@@ -106,9 +106,6 @@ typedef struct SHAstate_st
106 } SHA_CTX; 106 } SHA_CTX;
107 107
108#ifndef OPENSSL_NO_SHA0 108#ifndef OPENSSL_NO_SHA0
109#ifdef OPENSSL_FIPS
110int private_SHA_Init(SHA_CTX *c);
111#endif
112int SHA_Init(SHA_CTX *c); 109int SHA_Init(SHA_CTX *c);
113int SHA_Update(SHA_CTX *c, const void *data, size_t len); 110int SHA_Update(SHA_CTX *c, const void *data, size_t len);
114int SHA_Final(unsigned char *md, SHA_CTX *c); 111int 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 4831174198..7c65b60276 100644
--- a/src/lib/libcrypto/sha/sha1_one.c
+++ b/src/lib/libcrypto/sha/sha1_one.c
@@ -61,7 +61,7 @@
61#include <openssl/sha.h> 61#include <openssl/sha.h>
62#include <openssl/crypto.h> 62#include <openssl/crypto.h>
63 63
64#if !defined(OPENSSL_NO_SHA1) 64#ifndef OPENSSL_NO_SHA1
65unsigned char *SHA1(const unsigned char *d, size_t n, unsigned char *md) 65unsigned char *SHA1(const unsigned char *d, size_t n, unsigned char *md)
66 { 66 {
67 SHA_CTX c; 67 SHA_CTX c;
diff --git a/src/lib/libcrypto/sha/sha1dgst.c b/src/lib/libcrypto/sha/sha1dgst.c
index d31f0781a0..50d1925cde 100644
--- a/src/lib/libcrypto/sha/sha1dgst.c
+++ b/src/lib/libcrypto/sha/sha1dgst.c
@@ -63,10 +63,6 @@
63#define SHA_1 63#define SHA_1
64 64
65#include <openssl/opensslv.h> 65#include <openssl/opensslv.h>
66#ifdef OPENSSL_FIPS
67#include <openssl/fips.h>
68#endif
69
70 66
71const char SHA1_version[]="SHA1" OPENSSL_VERSION_PTEXT; 67const char SHA1_version[]="SHA1" OPENSSL_VERSION_PTEXT;
72 68
diff --git a/src/lib/libcrypto/sha/sha256.c b/src/lib/libcrypto/sha/sha256.c
index 3256a83e98..8952d87673 100644
--- a/src/lib/libcrypto/sha/sha256.c
+++ b/src/lib/libcrypto/sha/sha256.c
@@ -12,39 +12,29 @@
12 12
13#include <openssl/crypto.h> 13#include <openssl/crypto.h>
14#include <openssl/sha.h> 14#include <openssl/sha.h>
15#ifdef OPENSSL_FIPS
16#include <openssl/fips.h>
17#endif
18
19#include <openssl/opensslv.h> 15#include <openssl/opensslv.h>
20 16
21const char SHA256_version[]="SHA-256" OPENSSL_VERSION_PTEXT; 17const char SHA256_version[]="SHA-256" OPENSSL_VERSION_PTEXT;
22 18
23int SHA224_Init (SHA256_CTX *c) 19int SHA224_Init (SHA256_CTX *c)
24 { 20 {
25#ifdef OPENSSL_FIPS 21 memset (c,0,sizeof(*c));
26 FIPS_selftest_check();
27#endif
28 c->h[0]=0xc1059ed8UL; c->h[1]=0x367cd507UL; 22 c->h[0]=0xc1059ed8UL; c->h[1]=0x367cd507UL;
29 c->h[2]=0x3070dd17UL; c->h[3]=0xf70e5939UL; 23 c->h[2]=0x3070dd17UL; c->h[3]=0xf70e5939UL;
30 c->h[4]=0xffc00b31UL; c->h[5]=0x68581511UL; 24 c->h[4]=0xffc00b31UL; c->h[5]=0x68581511UL;
31 c->h[6]=0x64f98fa7UL; c->h[7]=0xbefa4fa4UL; 25 c->h[6]=0x64f98fa7UL; c->h[7]=0xbefa4fa4UL;
32 c->Nl=0; c->Nh=0; 26 c->md_len=SHA224_DIGEST_LENGTH;
33 c->num=0; c->md_len=SHA224_DIGEST_LENGTH;
34 return 1; 27 return 1;
35 } 28 }
36 29
37int SHA256_Init (SHA256_CTX *c) 30int SHA256_Init (SHA256_CTX *c)
38 { 31 {
39#ifdef OPENSSL_FIPS 32 memset (c,0,sizeof(*c));
40 FIPS_selftest_check();
41#endif
42 c->h[0]=0x6a09e667UL; c->h[1]=0xbb67ae85UL; 33 c->h[0]=0x6a09e667UL; c->h[1]=0xbb67ae85UL;
43 c->h[2]=0x3c6ef372UL; c->h[3]=0xa54ff53aUL; 34 c->h[2]=0x3c6ef372UL; c->h[3]=0xa54ff53aUL;
44 c->h[4]=0x510e527fUL; c->h[5]=0x9b05688cUL; 35 c->h[4]=0x510e527fUL; c->h[5]=0x9b05688cUL;
45 c->h[6]=0x1f83d9abUL; c->h[7]=0x5be0cd19UL; 36 c->h[6]=0x1f83d9abUL; c->h[7]=0x5be0cd19UL;
46 c->Nl=0; c->Nh=0; 37 c->md_len=SHA256_DIGEST_LENGTH;
47 c->num=0; c->md_len=SHA256_DIGEST_LENGTH;
48 return 1; 38 return 1;
49 } 39 }
50 40
@@ -94,21 +84,21 @@ int SHA224_Final (unsigned char *md, SHA256_CTX *c)
94 */ 84 */
95#define HASH_MAKE_STRING(c,s) do { \ 85#define HASH_MAKE_STRING(c,s) do { \
96 unsigned long ll; \ 86 unsigned long ll; \
97 unsigned int xn; \ 87 unsigned int nn; \
98 switch ((c)->md_len) \ 88 switch ((c)->md_len) \
99 { case SHA224_DIGEST_LENGTH: \ 89 { case SHA224_DIGEST_LENGTH: \
100 for (xn=0;xn<SHA224_DIGEST_LENGTH/4;xn++) \ 90 for (nn=0;nn<SHA224_DIGEST_LENGTH/4;nn++) \
101 { ll=(c)->h[xn]; HOST_l2c(ll,(s)); } \ 91 { ll=(c)->h[nn]; HOST_l2c(ll,(s)); } \
102 break; \ 92 break; \
103 case SHA256_DIGEST_LENGTH: \ 93 case SHA256_DIGEST_LENGTH: \
104 for (xn=0;xn<SHA256_DIGEST_LENGTH/4;xn++) \ 94 for (nn=0;nn<SHA256_DIGEST_LENGTH/4;nn++) \
105 { ll=(c)->h[xn]; HOST_l2c(ll,(s)); } \ 95 { ll=(c)->h[nn]; HOST_l2c(ll,(s)); } \
106 break; \ 96 break; \
107 default: \ 97 default: \
108 if ((c)->md_len > SHA256_DIGEST_LENGTH) \ 98 if ((c)->md_len > SHA256_DIGEST_LENGTH) \
109 return 0; \ 99 return 0; \
110 for (xn=0;xn<(c)->md_len/4;xn++) \ 100 for (nn=0;nn<(c)->md_len/4;nn++) \
111 { ll=(c)->h[xn]; HOST_l2c(ll,(s)); } \ 101 { ll=(c)->h[nn]; HOST_l2c(ll,(s)); } \
112 break; \ 102 break; \
113 } \ 103 } \
114 } while (0) 104 } while (0)
diff --git a/src/lib/libcrypto/sha/sha512.c b/src/lib/libcrypto/sha/sha512.c
index f5ed468b85..cbc0e58c48 100644
--- a/src/lib/libcrypto/sha/sha512.c
+++ b/src/lib/libcrypto/sha/sha512.c
@@ -5,10 +5,6 @@
5 * ==================================================================== 5 * ====================================================================
6 */ 6 */
7#include <openssl/opensslconf.h> 7#include <openssl/opensslconf.h>
8#ifdef OPENSSL_FIPS
9#include <openssl/fips.h>
10#endif
11
12#if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_SHA512) 8#if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_SHA512)
13/* 9/*
14 * IMPLEMENTATION NOTES. 10 * IMPLEMENTATION NOTES.
@@ -65,9 +61,19 @@ const char SHA512_version[]="SHA-512" OPENSSL_VERSION_PTEXT;
65 61
66int SHA384_Init (SHA512_CTX *c) 62int SHA384_Init (SHA512_CTX *c)
67 { 63 {
68#ifdef OPENSSL_FIPS 64#if defined(SHA512_ASM) && (defined(__arm__) || defined(__arm))
69 FIPS_selftest_check(); 65 /* maintain dword order required by assembler module */
70#endif 66 unsigned int *h = (unsigned int *)c->h;
67
68 h[0] = 0xcbbb9d5d; h[1] = 0xc1059ed8;
69 h[2] = 0x629a292a; h[3] = 0x367cd507;
70 h[4] = 0x9159015a; h[5] = 0x3070dd17;
71 h[6] = 0x152fecd8; h[7] = 0xf70e5939;
72 h[8] = 0x67332667; h[9] = 0xffc00b31;
73 h[10] = 0x8eb44a87; h[11] = 0x68581511;
74 h[12] = 0xdb0c2e0d; h[13] = 0x64f98fa7;
75 h[14] = 0x47b5481d; h[15] = 0xbefa4fa4;
76#else
71 c->h[0]=U64(0xcbbb9d5dc1059ed8); 77 c->h[0]=U64(0xcbbb9d5dc1059ed8);
72 c->h[1]=U64(0x629a292a367cd507); 78 c->h[1]=U64(0x629a292a367cd507);
73 c->h[2]=U64(0x9159015a3070dd17); 79 c->h[2]=U64(0x9159015a3070dd17);
@@ -76,6 +82,7 @@ int SHA384_Init (SHA512_CTX *c)
76 c->h[5]=U64(0x8eb44a8768581511); 82 c->h[5]=U64(0x8eb44a8768581511);
77 c->h[6]=U64(0xdb0c2e0d64f98fa7); 83 c->h[6]=U64(0xdb0c2e0d64f98fa7);
78 c->h[7]=U64(0x47b5481dbefa4fa4); 84 c->h[7]=U64(0x47b5481dbefa4fa4);
85#endif
79 c->Nl=0; c->Nh=0; 86 c->Nl=0; c->Nh=0;
80 c->num=0; c->md_len=SHA384_DIGEST_LENGTH; 87 c->num=0; c->md_len=SHA384_DIGEST_LENGTH;
81 return 1; 88 return 1;
@@ -83,9 +90,19 @@ int SHA384_Init (SHA512_CTX *c)
83 90
84int SHA512_Init (SHA512_CTX *c) 91int SHA512_Init (SHA512_CTX *c)
85 { 92 {
86#ifdef OPENSSL_FIPS 93#if defined(SHA512_ASM) && (defined(__arm__) || defined(__arm))
87 FIPS_selftest_check(); 94 /* maintain dword order required by assembler module */
88#endif 95 unsigned int *h = (unsigned int *)c->h;
96
97 h[0] = 0x6a09e667; h[1] = 0xf3bcc908;
98 h[2] = 0xbb67ae85; h[3] = 0x84caa73b;
99 h[4] = 0x3c6ef372; h[5] = 0xfe94f82b;
100 h[6] = 0xa54ff53a; h[7] = 0x5f1d36f1;
101 h[8] = 0x510e527f; h[9] = 0xade682d1;
102 h[10] = 0x9b05688c; h[11] = 0x2b3e6c1f;
103 h[12] = 0x1f83d9ab; h[13] = 0xfb41bd6b;
104 h[14] = 0x5be0cd19; h[15] = 0x137e2179;
105#else
89 c->h[0]=U64(0x6a09e667f3bcc908); 106 c->h[0]=U64(0x6a09e667f3bcc908);
90 c->h[1]=U64(0xbb67ae8584caa73b); 107 c->h[1]=U64(0xbb67ae8584caa73b);
91 c->h[2]=U64(0x3c6ef372fe94f82b); 108 c->h[2]=U64(0x3c6ef372fe94f82b);
@@ -94,6 +111,7 @@ int SHA512_Init (SHA512_CTX *c)
94 c->h[5]=U64(0x9b05688c2b3e6c1f); 111 c->h[5]=U64(0x9b05688c2b3e6c1f);
95 c->h[6]=U64(0x1f83d9abfb41bd6b); 112 c->h[6]=U64(0x1f83d9abfb41bd6b);
96 c->h[7]=U64(0x5be0cd19137e2179); 113 c->h[7]=U64(0x5be0cd19137e2179);
114#endif
97 c->Nl=0; c->Nh=0; 115 c->Nl=0; c->Nh=0;
98 c->num=0; c->md_len=SHA512_DIGEST_LENGTH; 116 c->num=0; c->md_len=SHA512_DIGEST_LENGTH;
99 return 1; 117 return 1;
@@ -142,6 +160,24 @@ int SHA512_Final (unsigned char *md, SHA512_CTX *c)
142 160
143 if (md==0) return 0; 161 if (md==0) return 0;
144 162
163#if defined(SHA512_ASM) && (defined(__arm__) || defined(__arm))
164 /* recall assembler dword order... */
165 n = c->md_len;
166 if (n == SHA384_DIGEST_LENGTH || n == SHA512_DIGEST_LENGTH)
167 {
168 unsigned int *h = (unsigned int *)c->h, t;
169
170 for (n/=4;n;n--)
171 {
172 t = *(h++);
173 *(md++) = (unsigned char)(t>>24);
174 *(md++) = (unsigned char)(t>>16);
175 *(md++) = (unsigned char)(t>>8);
176 *(md++) = (unsigned char)(t);
177 }
178 }
179 else return 0;
180#else
145 switch (c->md_len) 181 switch (c->md_len)
146 { 182 {
147 /* Let compiler decide if it's appropriate to unroll... */ 183 /* Let compiler decide if it's appropriate to unroll... */
@@ -178,7 +214,7 @@ int SHA512_Final (unsigned char *md, SHA512_CTX *c)
178 /* ... as well as make sure md_len is not abused. */ 214 /* ... as well as make sure md_len is not abused. */
179 default: return 0; 215 default: return 0;
180 } 216 }
181 217#endif
182 return 1; 218 return 1;
183 } 219 }
184 220
@@ -204,7 +240,7 @@ int SHA512_Update (SHA512_CTX *c, const void *_data, size_t len)
204 240
205 if (len < n) 241 if (len < n)
206 { 242 {
207 memcpy (p+c->num,data,len), c->num += len; 243 memcpy (p+c->num,data,len), c->num += (unsigned int)len;
208 return 1; 244 return 1;
209 } 245 }
210 else { 246 else {
@@ -314,7 +350,7 @@ static const SHA_LONG64 K512[80] = {
314#ifndef PEDANTIC 350#ifndef PEDANTIC
315# if defined(__GNUC__) && __GNUC__>=2 && !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM) 351# if defined(__GNUC__) && __GNUC__>=2 && !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM)
316# if defined(__x86_64) || defined(__x86_64__) 352# if defined(__x86_64) || defined(__x86_64__)
317# define ROTR(a,n) ({ unsigned long ret; \ 353# define ROTR(a,n) ({ SHA_LONG64 ret; \
318 asm ("rorq %1,%0" \ 354 asm ("rorq %1,%0" \
319 : "=r"(ret) \ 355 : "=r"(ret) \
320 : "J"(n),"0"(a) \ 356 : "J"(n),"0"(a) \
@@ -337,20 +373,21 @@ static const SHA_LONG64 K512[80] = {
337 ((SHA_LONG64)hi)<<32|lo; }) 373 ((SHA_LONG64)hi)<<32|lo; })
338# else 374# else
339# define PULL64(x) ({ const unsigned int *p=(const unsigned int *)(&(x));\ 375# define PULL64(x) ({ const unsigned int *p=(const unsigned int *)(&(x));\
340 unsigned int hi=p[0],lo=p[1]; \ 376 unsigned int hi=p[0],lo=p[1]; \
341 asm ("bswapl %0; bswapl %1;" \ 377 asm ("bswapl %0; bswapl %1;" \
342 : "=r"(lo),"=r"(hi) \ 378 : "=r"(lo),"=r"(hi) \
343 : "0"(lo),"1"(hi)); \ 379 : "0"(lo),"1"(hi)); \
344 ((SHA_LONG64)hi)<<32|lo; }) 380 ((SHA_LONG64)hi)<<32|lo; })
345# endif 381# endif
346# elif (defined(_ARCH_PPC) && defined(__64BIT__)) || defined(_ARCH_PPC64) 382# elif (defined(_ARCH_PPC) && defined(__64BIT__)) || defined(_ARCH_PPC64)
347# define ROTR(a,n) ({ unsigned long ret; \ 383# define ROTR(a,n) ({ SHA_LONG64 ret; \
348 asm ("rotrdi %0,%1,%2" \ 384 asm ("rotrdi %0,%1,%2" \
349 : "=r"(ret) \ 385 : "=r"(ret) \
350 : "r"(a),"K"(n)); ret; }) 386 : "r"(a),"K"(n)); ret; })
351# endif 387# endif
352# elif defined(_MSC_VER) 388# elif defined(_MSC_VER)
353# if defined(_WIN64) /* applies to both IA-64 and AMD64 */ 389# if defined(_WIN64) /* applies to both IA-64 and AMD64 */
390# pragma intrinsic(_rotr64)
354# define ROTR(a,n) _rotr64((a),n) 391# define ROTR(a,n) _rotr64((a),n)
355# endif 392# endif
356# if defined(_M_IX86) && !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM) 393# if defined(_M_IX86) && !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM)
@@ -398,15 +435,66 @@ static const SHA_LONG64 K512[80] = {
398#define Ch(x,y,z) (((x) & (y)) ^ ((~(x)) & (z))) 435#define Ch(x,y,z) (((x) & (y)) ^ ((~(x)) & (z)))
399#define Maj(x,y,z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z))) 436#define Maj(x,y,z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z)))
400 437
401#if defined(OPENSSL_IA32_SSE2) && !defined(OPENSSL_NO_ASM) && !defined(I386_ONLY) 438
402#define GO_FOR_SSE2(ctx,in,num) do { \ 439#if defined(__i386) || defined(__i386__) || defined(_M_IX86)
403 void sha512_block_sse2(void *,const void *,size_t); \ 440/*
404 if (!(OPENSSL_ia32cap_P & (1<<26))) break; \ 441 * This code should give better results on 32-bit CPU with less than
405 sha512_block_sse2(ctx->h,in,num); return; \ 442 * ~24 registers, both size and performance wise...
406 } while (0) 443 */
444static void sha512_block_data_order (SHA512_CTX *ctx, const void *in, size_t num)
445 {
446 const SHA_LONG64 *W=in;
447 SHA_LONG64 A,E,T;
448 SHA_LONG64 X[9+80],*F;
449 int i;
450
451 while (num--) {
452
453 F = X+80;
454 A = ctx->h[0]; F[1] = ctx->h[1];
455 F[2] = ctx->h[2]; F[3] = ctx->h[3];
456 E = ctx->h[4]; F[5] = ctx->h[5];
457 F[6] = ctx->h[6]; F[7] = ctx->h[7];
458
459 for (i=0;i<16;i++,F--)
460 {
461#ifdef B_ENDIAN
462 T = W[i];
463#else
464 T = PULL64(W[i]);
407#endif 465#endif
466 F[0] = A;
467 F[4] = E;
468 F[8] = T;
469 T += F[7] + Sigma1(E) + Ch(E,F[5],F[6]) + K512[i];
470 E = F[3] + T;
471 A = T + Sigma0(A) + Maj(A,F[1],F[2]);
472 }
473
474 for (;i<80;i++,F--)
475 {
476 T = sigma0(F[8+16-1]);
477 T += sigma1(F[8+16-14]);
478 T += F[8+16] + F[8+16-9];
479
480 F[0] = A;
481 F[4] = E;
482 F[8] = T;
483 T += F[7] + Sigma1(E) + Ch(E,F[5],F[6]) + K512[i];
484 E = F[3] + T;
485 A = T + Sigma0(A) + Maj(A,F[1],F[2]);
486 }
408 487
409#ifdef OPENSSL_SMALL_FOOTPRINT 488 ctx->h[0] += A; ctx->h[1] += F[1];
489 ctx->h[2] += F[2]; ctx->h[3] += F[3];
490 ctx->h[4] += E; ctx->h[5] += F[5];
491 ctx->h[6] += F[6]; ctx->h[7] += F[7];
492
493 W+=SHA_LBLOCK;
494 }
495 }
496
497#elif defined(OPENSSL_SMALL_FOOTPRINT)
410 498
411static void sha512_block_data_order (SHA512_CTX *ctx, const void *in, size_t num) 499static void sha512_block_data_order (SHA512_CTX *ctx, const void *in, size_t num)
412 { 500 {
@@ -415,10 +503,6 @@ static void sha512_block_data_order (SHA512_CTX *ctx, const void *in, size_t num
415 SHA_LONG64 X[16]; 503 SHA_LONG64 X[16];
416 int i; 504 int i;
417 505
418#ifdef GO_FOR_SSE2
419 GO_FOR_SSE2(ctx,in,num);
420#endif
421
422 while (num--) { 506 while (num--) {
423 507
424 a = ctx->h[0]; b = ctx->h[1]; c = ctx->h[2]; d = ctx->h[3]; 508 a = ctx->h[0]; b = ctx->h[1]; c = ctx->h[2]; d = ctx->h[3];
@@ -463,11 +547,11 @@ static void sha512_block_data_order (SHA512_CTX *ctx, const void *in, size_t num
463 h = Sigma0(a) + Maj(a,b,c); \ 547 h = Sigma0(a) + Maj(a,b,c); \
464 d += T1; h += T1; } while (0) 548 d += T1; h += T1; } while (0)
465 549
466#define ROUND_16_80(i,a,b,c,d,e,f,g,h,X) do { \ 550#define ROUND_16_80(i,j,a,b,c,d,e,f,g,h,X) do { \
467 s0 = X[(i+1)&0x0f]; s0 = sigma0(s0); \ 551 s0 = X[(j+1)&0x0f]; s0 = sigma0(s0); \
468 s1 = X[(i+14)&0x0f]; s1 = sigma1(s1); \ 552 s1 = X[(j+14)&0x0f]; s1 = sigma1(s1); \
469 T1 = X[(i)&0x0f] += s0 + s1 + X[(i+9)&0x0f]; \ 553 T1 = X[(j)&0x0f] += s0 + s1 + X[(j+9)&0x0f]; \
470 ROUND_00_15(i,a,b,c,d,e,f,g,h); } while (0) 554 ROUND_00_15(i+j,a,b,c,d,e,f,g,h); } while (0)
471 555
472static void sha512_block_data_order (SHA512_CTX *ctx, const void *in, size_t num) 556static void sha512_block_data_order (SHA512_CTX *ctx, const void *in, size_t num)
473 { 557 {
@@ -476,10 +560,6 @@ static void sha512_block_data_order (SHA512_CTX *ctx, const void *in, size_t num
476 SHA_LONG64 X[16]; 560 SHA_LONG64 X[16];
477 int i; 561 int i;
478 562
479#ifdef GO_FOR_SSE2
480 GO_FOR_SSE2(ctx,in,num);
481#endif
482
483 while (num--) { 563 while (num--) {
484 564
485 a = ctx->h[0]; b = ctx->h[1]; c = ctx->h[2]; d = ctx->h[3]; 565 a = ctx->h[0]; b = ctx->h[1]; c = ctx->h[2]; d = ctx->h[3];
@@ -521,16 +601,24 @@ static void sha512_block_data_order (SHA512_CTX *ctx, const void *in, size_t num
521 T1 = X[15] = PULL64(W[15]); ROUND_00_15(15,b,c,d,e,f,g,h,a); 601 T1 = X[15] = PULL64(W[15]); ROUND_00_15(15,b,c,d,e,f,g,h,a);
522#endif 602#endif
523 603
524 for (i=16;i<80;i+=8) 604 for (i=16;i<80;i+=16)
525 { 605 {
526 ROUND_16_80(i+0,a,b,c,d,e,f,g,h,X); 606 ROUND_16_80(i, 0,a,b,c,d,e,f,g,h,X);
527 ROUND_16_80(i+1,h,a,b,c,d,e,f,g,X); 607 ROUND_16_80(i, 1,h,a,b,c,d,e,f,g,X);
528 ROUND_16_80(i+2,g,h,a,b,c,d,e,f,X); 608 ROUND_16_80(i, 2,g,h,a,b,c,d,e,f,X);
529 ROUND_16_80(i+3,f,g,h,a,b,c,d,e,X); 609 ROUND_16_80(i, 3,f,g,h,a,b,c,d,e,X);
530 ROUND_16_80(i+4,e,f,g,h,a,b,c,d,X); 610 ROUND_16_80(i, 4,e,f,g,h,a,b,c,d,X);
531 ROUND_16_80(i+5,d,e,f,g,h,a,b,c,X); 611 ROUND_16_80(i, 5,d,e,f,g,h,a,b,c,X);
532 ROUND_16_80(i+6,c,d,e,f,g,h,a,b,X); 612 ROUND_16_80(i, 6,c,d,e,f,g,h,a,b,X);
533 ROUND_16_80(i+7,b,c,d,e,f,g,h,a,X); 613 ROUND_16_80(i, 7,b,c,d,e,f,g,h,a,X);
614 ROUND_16_80(i, 8,a,b,c,d,e,f,g,h,X);
615 ROUND_16_80(i, 9,h,a,b,c,d,e,f,g,X);
616 ROUND_16_80(i,10,g,h,a,b,c,d,e,f,X);
617 ROUND_16_80(i,11,f,g,h,a,b,c,d,e,X);
618 ROUND_16_80(i,12,e,f,g,h,a,b,c,d,X);
619 ROUND_16_80(i,13,d,e,f,g,h,a,b,c,X);
620 ROUND_16_80(i,14,c,d,e,f,g,h,a,b,X);
621 ROUND_16_80(i,15,b,c,d,e,f,g,h,a,X);
534 } 622 }
535 623
536 ctx->h[0] += a; ctx->h[1] += b; ctx->h[2] += c; ctx->h[3] += d; 624 ctx->h[0] += a; ctx->h[1] += b; ctx->h[2] += c; ctx->h[3] += d;
@@ -544,4 +632,10 @@ static void sha512_block_data_order (SHA512_CTX *ctx, const void *in, size_t num
544 632
545#endif /* SHA512_ASM */ 633#endif /* SHA512_ASM */
546 634
547#endif /* OPENSSL_NO_SHA512 */ 635#else /* !OPENSSL_NO_SHA512 */
636
637#if defined(PEDANTIC) || defined(__DECC) || defined(OPENSSL_SYS_MACOSX)
638static void *dummy=&dummy;
639#endif
640
641#endif /* !OPENSSL_NO_SHA512 */
diff --git a/src/lib/libcrypto/sha/sha_locl.h b/src/lib/libcrypto/sha/sha_locl.h
index da46ddfe79..672c26eee1 100644
--- a/src/lib/libcrypto/sha/sha_locl.h
+++ b/src/lib/libcrypto/sha/sha_locl.h
@@ -122,23 +122,14 @@ void sha1_block_data_order (SHA_CTX *c, const void *p,size_t num);
122#define INIT_DATA_h3 0x10325476UL 122#define INIT_DATA_h3 0x10325476UL
123#define INIT_DATA_h4 0xc3d2e1f0UL 123#define INIT_DATA_h4 0xc3d2e1f0UL
124 124
125#if defined(SHA_0) && defined(OPENSSL_FIPS)
126FIPS_NON_FIPS_MD_Init(SHA)
127#else
128int HASH_INIT (SHA_CTX *c) 125int HASH_INIT (SHA_CTX *c)
129#endif
130 { 126 {
131#if defined(SHA_1) && defined(OPENSSL_FIPS) 127 memset (c,0,sizeof(*c));
132 FIPS_selftest_check();
133#endif
134 c->h0=INIT_DATA_h0; 128 c->h0=INIT_DATA_h0;
135 c->h1=INIT_DATA_h1; 129 c->h1=INIT_DATA_h1;
136 c->h2=INIT_DATA_h2; 130 c->h2=INIT_DATA_h2;
137 c->h3=INIT_DATA_h3; 131 c->h3=INIT_DATA_h3;
138 c->h4=INIT_DATA_h4; 132 c->h4=INIT_DATA_h4;
139 c->Nl=0;
140 c->Nh=0;
141 c->num=0;
142 return 1; 133 return 1;
143 } 134 }
144 135
diff --git a/src/lib/libcrypto/sparccpuid.S b/src/lib/libcrypto/sparccpuid.S
index c17350fc89..aa8b11efc9 100644
--- a/src/lib/libcrypto/sparccpuid.S
+++ b/src/lib/libcrypto/sparccpuid.S
@@ -34,7 +34,8 @@ OPENSSL_wipe_cpu:
34 nop 34 nop
35 call .PIC.zero.up 35 call .PIC.zero.up
36 mov .zero-(.-4),%o0 36 mov .zero-(.-4),%o0
37 ldd [%o0],%f0 37 ld [%o0],%f0
38 ld [%o0],%f1
38 39
39 subcc %g0,1,%o0 40 subcc %g0,1,%o0
40 ! Following is V9 "rd %ccr,%o0" instruction. However! V8 41 ! Following is V9 "rd %ccr,%o0" instruction. However! V8
@@ -166,6 +167,7 @@ walk_reg_wins:
166 167
167.global OPENSSL_atomic_add 168.global OPENSSL_atomic_add
168.type OPENSSL_atomic_add,#function 169.type OPENSSL_atomic_add,#function
170.align 32
169OPENSSL_atomic_add: 171OPENSSL_atomic_add:
170#ifndef ABI64 172#ifndef ABI64
171 subcc %g0,1,%o2 173 subcc %g0,1,%o2
@@ -177,7 +179,7 @@ OPENSSL_atomic_add:
177 ba .enter 179 ba .enter
178 nop 180 nop
179#ifdef __sun 181#ifdef __sun
180! Note that you don't have to link with libthread to call thr_yield, 182! Note that you do not have to link with libthread to call thr_yield,
181! as libc provides a stub, which is overloaded the moment you link 183! as libc provides a stub, which is overloaded the moment you link
182! with *either* libpthread or libthread... 184! with *either* libpthread or libthread...
183#define YIELD_CPU thr_yield 185#define YIELD_CPU thr_yield
@@ -213,27 +215,106 @@ OPENSSL_atomic_add:
213 sra %o0,%g0,%o0 ! we return signed int, remember? 215 sra %o0,%g0,%o0 ! we return signed int, remember?
214.size OPENSSL_atomic_add,.-OPENSSL_atomic_add 216.size OPENSSL_atomic_add,.-OPENSSL_atomic_add
215 217
216.global OPENSSL_rdtsc 218.global _sparcv9_rdtick
219.align 32
220_sparcv9_rdtick:
217 subcc %g0,1,%o0 221 subcc %g0,1,%o0
218 .word 0x91408000 !rd %ccr,%o0 222 .word 0x91408000 !rd %ccr,%o0
219 cmp %o0,0x99 223 cmp %o0,0x99
220 bne .notsc 224 bne .notick
221 xor %o0,%o0,%o0 225 xor %o0,%o0,%o0
222 save %sp,FRAME-16,%sp 226 .word 0x91410000 !rd %tick,%o0
223 mov 513,%o0 !SI_PLATFORM 227 retl
224 add %sp,BIAS+16,%o1 228 .word 0x93323020 !srlx %o2,32,%o1
225 call sysinfo 229.notick:
226 mov 256,%o2 230 retl
231 xor %o1,%o1,%o1
232.type _sparcv9_rdtick,#function
233.size _sparcv9_rdtick,.-_sparcv9_rdtick
227 234
228 add %sp,BIAS-16,%o1 235.global OPENSSL_cleanse
229 ld [%o1],%l0 236.align 32
230 ld [%o1+4],%l1 237OPENSSL_cleanse:
231 ld [%o1+8],%l2 238 cmp %o1,14
232 mov %lo('SUNW'),%l3 239 nop
233 ret 240#ifdef ABI64
234 restore 241 bgu %xcc,.Lot
235.notsc: 242#else
243 bgu .Lot
244#endif
245 cmp %o1,0
246 bne .Little
247 nop
248 retl
249 nop
250
251.Little:
252 stb %g0,[%o0]
253 subcc %o1,1,%o1
254 bnz .Little
255 add %o0,1,%o0
256 retl
257 nop
258.align 32
259.Lot:
260#ifndef ABI64
261 subcc %g0,1,%g1
262 ! see above for explanation
263 .word 0x83408000 !rd %ccr,%g1
264 cmp %g1,0x99
265 bne .v8lot
266 nop
267#endif
268
269.v9lot: andcc %o0,7,%g0
270 bz .v9aligned
271 nop
272 stb %g0,[%o0]
273 sub %o1,1,%o1
274 ba .v9lot
275 add %o0,1,%o0
276.align 16,0x01000000
277.v9aligned:
278 .word 0xc0720000 !stx %g0,[%o0]
279 sub %o1,8,%o1
280 andcc %o1,-8,%g0
281#ifdef ABI64
282 .word 0x126ffffd !bnz %xcc,.v9aligned
283#else
284 .word 0x124ffffd !bnz %icc,.v9aligned
285#endif
286 add %o0,8,%o0
287
288 cmp %o1,0
289 bne .Little
290 nop
236 retl 291 retl
237 nop 292 nop
238.type OPENSSL_rdtsc,#function 293#ifndef ABI64
239.size OPENSSL_rdtsc,.-OPENSSL_atomic_add 294.v8lot: andcc %o0,3,%g0
295 bz .v8aligned
296 nop
297 stb %g0,[%o0]
298 sub %o1,1,%o1
299 ba .v8lot
300 add %o0,1,%o0
301 nop
302.v8aligned:
303 st %g0,[%o0]
304 sub %o1,4,%o1
305 andcc %o1,-4,%g0
306 bnz .v8aligned
307 add %o0,4,%o0
308
309 cmp %o1,0
310 bne .Little
311 nop
312 retl
313 nop
314#endif
315.type OPENSSL_cleanse,#function
316.size OPENSSL_cleanse,.-OPENSSL_cleanse
317
318.section ".init",#alloc,#execinstr
319 call OPENSSL_cpuid_setup
320 nop
diff --git a/src/lib/libcrypto/stack/safestack.h b/src/lib/libcrypto/stack/safestack.h
index 40b17902e0..891cb84a51 100644
--- a/src/lib/libcrypto/stack/safestack.h
+++ b/src/lib/libcrypto/stack/safestack.h
@@ -57,18 +57,27 @@
57 57
58#include <openssl/stack.h> 58#include <openssl/stack.h>
59 59
60#ifdef DEBUG_SAFESTACK
61
62#ifndef CHECKED_PTR_OF 60#ifndef CHECKED_PTR_OF
63#define CHECKED_PTR_OF(type, p) \ 61#define CHECKED_PTR_OF(type, p) \
64 ((void*) (1 ? p : (type*)0)) 62 ((void*) (1 ? p : (type*)0))
65#endif 63#endif
66 64
65/* In C++ we get problems because an explicit cast is needed from (void *)
66 * we use CHECKED_STACK_OF to ensure the correct type is passed in the macros
67 * below.
68 */
69
70#define CHECKED_STACK_OF(type, p) \
71 ((_STACK*) (1 ? p : (STACK_OF(type)*)0))
72
67#define CHECKED_SK_FREE_FUNC(type, p) \ 73#define CHECKED_SK_FREE_FUNC(type, p) \
68 ((void (*)(void *)) ((1 ? p : (void (*)(type *))0))) 74 ((void (*)(void *)) ((1 ? p : (void (*)(type *))0)))
69 75
76#define CHECKED_SK_FREE_FUNC2(type, p) \
77 ((void (*)(void *)) ((1 ? p : (void (*)(type))0)))
78
70#define CHECKED_SK_CMP_FUNC(type, p) \ 79#define CHECKED_SK_CMP_FUNC(type, p) \
71 ((int (*)(const char * const *, const char * const *)) \ 80 ((int (*)(const void *, const void *)) \
72 ((1 ? p : (int (*)(const type * const *, const type * const *))0))) 81 ((1 ? p : (int (*)(const type * const *, const type * const *))0)))
73 82
74#define STACK_OF(type) struct stack_st_##type 83#define STACK_OF(type) struct stack_st_##type
@@ -77,11 +86,51 @@
77#define DECLARE_STACK_OF(type) \ 86#define DECLARE_STACK_OF(type) \
78STACK_OF(type) \ 87STACK_OF(type) \
79 { \ 88 { \
80 STACK stack; \ 89 _STACK stack; \
90 };
91#define DECLARE_SPECIAL_STACK_OF(type, type2) \
92STACK_OF(type) \
93 { \
94 _STACK stack; \
81 }; 95 };
82 96
83#define IMPLEMENT_STACK_OF(type) /* nada (obsolete in new safestack approach)*/ 97#define IMPLEMENT_STACK_OF(type) /* nada (obsolete in new safestack approach)*/
84 98
99
100/* Strings are special: normally an lhash entry will point to a single
101 * (somewhat) mutable object. In the case of strings:
102 *
103 * a) Instead of a single char, there is an array of chars, NUL-terminated.
104 * b) The string may have be immutable.
105 *
106 * So, they need their own declarations. Especially important for
107 * type-checking tools, such as Deputy.
108 *
109o * In practice, however, it appears to be hard to have a const
110 * string. For now, I'm settling for dealing with the fact it is a
111 * string at all.
112 */
113typedef char *OPENSSL_STRING;
114
115typedef const char *OPENSSL_CSTRING;
116
117/* Confusingly, LHASH_OF(STRING) deals with char ** throughout, but
118 * STACK_OF(STRING) is really more like STACK_OF(char), only, as
119 * mentioned above, instead of a single char each entry is a
120 * NUL-terminated array of chars. So, we have to implement STRING
121 * specially for STACK_OF. This is dealt with in the autogenerated
122 * macros below.
123 */
124
125DECLARE_SPECIAL_STACK_OF(OPENSSL_STRING, char)
126
127/* Similarly, we sometimes use a block of characters, NOT
128 * nul-terminated. These should also be distinguished from "normal"
129 * stacks. */
130
131typedef void *OPENSSL_BLOCK;
132DECLARE_SPECIAL_STACK_OF(OPENSSL_BLOCK, void)
133
85/* SKM_sk_... stack macros are internal to safestack.h: 134/* SKM_sk_... stack macros are internal to safestack.h:
86 * never use them directly, use sk_<type>_... instead */ 135 * never use them directly, use sk_<type>_... instead */
87#define SKM_sk_new(type, cmp) \ 136#define SKM_sk_new(type, cmp) \
@@ -89,52 +138,55 @@ STACK_OF(type) \
89#define SKM_sk_new_null(type) \ 138#define SKM_sk_new_null(type) \
90 ((STACK_OF(type) *)sk_new_null()) 139 ((STACK_OF(type) *)sk_new_null())
91#define SKM_sk_free(type, st) \ 140#define SKM_sk_free(type, st) \
92 sk_free(CHECKED_PTR_OF(STACK_OF(type), st)) 141 sk_free(CHECKED_STACK_OF(type, st))
93#define SKM_sk_num(type, st) \ 142#define SKM_sk_num(type, st) \
94 sk_num(CHECKED_PTR_OF(STACK_OF(type), st)) 143 sk_num(CHECKED_STACK_OF(type, st))
95#define SKM_sk_value(type, st,i) \ 144#define SKM_sk_value(type, st,i) \
96 ((type *)sk_value(CHECKED_PTR_OF(STACK_OF(type), st), i)) 145 ((type *)sk_value(CHECKED_STACK_OF(type, st), i))
97#define SKM_sk_set(type, st,i,val) \ 146#define SKM_sk_set(type, st,i,val) \
98 sk_set(CHECKED_PTR_OF(STACK_OF(type), st), i, CHECKED_PTR_OF(type, val)) 147 sk_set(CHECKED_STACK_OF(type, st), i, CHECKED_PTR_OF(type, val))
99#define SKM_sk_zero(type, st) \ 148#define SKM_sk_zero(type, st) \
100 sk_zero(CHECKED_PTR_OF(STACK_OF(type), st)) 149 sk_zero(CHECKED_STACK_OF(type, st))
101#define SKM_sk_push(type, st,val) \ 150#define SKM_sk_push(type, st, val) \
102 sk_push(CHECKED_PTR_OF(STACK_OF(type), st), CHECKED_PTR_OF(type, val)) 151 sk_push(CHECKED_STACK_OF(type, st), CHECKED_PTR_OF(type, val))
103#define SKM_sk_unshift(type, st,val) \ 152#define SKM_sk_unshift(type, st, val) \
104 sk_unshift(CHECKED_PTR_OF(STACK_OF(type), st), CHECKED_PTR_OF(type, val)) 153 sk_unshift(CHECKED_STACK_OF(type, st), CHECKED_PTR_OF(type, val))
105#define SKM_sk_find(type, st,val) \ 154#define SKM_sk_find(type, st, val) \
106 sk_find(CHECKED_PTR_OF(STACK_OF(type), st), CHECKED_PTR_OF(type, val)) 155 sk_find(CHECKED_STACK_OF(type, st), CHECKED_PTR_OF(type, val))
107#define SKM_sk_delete(type, st,i) \ 156#define SKM_sk_find_ex(type, st, val) \
108 (type *)sk_delete(CHECKED_PTR_OF(STACK_OF(type), st), i) 157 sk_find_ex(CHECKED_STACK_OF(type, st), \
109#define SKM_sk_delete_ptr(type, st,ptr) \ 158 CHECKED_PTR_OF(type, val))
110 (type *)sk_delete_ptr(CHECKED_PTR_OF(STACK_OF(type), st), CHECKED_PTR_OF(type, ptr)) 159#define SKM_sk_delete(type, st, i) \
111#define SKM_sk_insert(type, st,val,i) \ 160 (type *)sk_delete(CHECKED_STACK_OF(type, st), i)
112 sk_insert(CHECKED_PTR_OF(STACK_OF(type), st), CHECKED_PTR_OF(type, val), i) 161#define SKM_sk_delete_ptr(type, st, ptr) \
113#define SKM_sk_set_cmp_func(type, st,cmp) \ 162 (type *)sk_delete_ptr(CHECKED_STACK_OF(type, st), CHECKED_PTR_OF(type, ptr))
163#define SKM_sk_insert(type, st,val, i) \
164 sk_insert(CHECKED_STACK_OF(type, st), CHECKED_PTR_OF(type, val), i)
165#define SKM_sk_set_cmp_func(type, st, cmp) \
114 ((int (*)(const type * const *,const type * const *)) \ 166 ((int (*)(const type * const *,const type * const *)) \
115 sk_set_cmp_func(CHECKED_PTR_OF(STACK_OF(type), st), CHECKED_SK_CMP_FUNC(type, cmp))) 167 sk_set_cmp_func(CHECKED_STACK_OF(type, st), CHECKED_SK_CMP_FUNC(type, cmp)))
116#define SKM_sk_dup(type, st) \ 168#define SKM_sk_dup(type, st) \
117 (STACK_OF(type) *)sk_dup(CHECKED_PTR_OF(STACK_OF(type), st)) 169 (STACK_OF(type) *)sk_dup(CHECKED_STACK_OF(type, st))
118#define SKM_sk_pop_free(type, st,free_func) \ 170#define SKM_sk_pop_free(type, st, free_func) \
119 sk_pop_free(CHECKED_PTR_OF(STACK_OF(type), st), CHECKED_SK_FREE_FUNC(type, free_func)) 171 sk_pop_free(CHECKED_STACK_OF(type, st), CHECKED_SK_FREE_FUNC(type, free_func))
120#define SKM_sk_shift(type, st) \ 172#define SKM_sk_shift(type, st) \
121 (type *)sk_shift(CHECKED_PTR_OF(STACK_OF(type), st)) 173 (type *)sk_shift(CHECKED_STACK_OF(type, st))
122#define SKM_sk_pop(type, st) \ 174#define SKM_sk_pop(type, st) \
123 (type *)sk_pop(CHECKED_PTR_OF(STACK_OF(type), st)) 175 (type *)sk_pop(CHECKED_STACK_OF(type, st))
124#define SKM_sk_sort(type, st) \ 176#define SKM_sk_sort(type, st) \
125 sk_sort(CHECKED_PTR_OF(STACK_OF(type), st)) 177 sk_sort(CHECKED_STACK_OF(type, st))
126#define SKM_sk_is_sorted(type, st) \ 178#define SKM_sk_is_sorted(type, st) \
127 sk_is_sorted(CHECKED_PTR_OF(STACK_OF(type), st)) 179 sk_is_sorted(CHECKED_STACK_OF(type, st))
128 180
129#define SKM_ASN1_SET_OF_d2i(type, st, pp, length, d2i_func, free_func, ex_tag, ex_class) \ 181#define SKM_ASN1_SET_OF_d2i(type, st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
130 (STACK_OF(type) *)d2i_ASN1_SET(CHECKED_PTR_OF(STACK_OF(type), st), \ 182 (STACK_OF(type) *)d2i_ASN1_SET((STACK_OF(OPENSSL_BLOCK) **)CHECKED_STACK_OF(type, st), \
131 pp, length, \ 183 pp, length, \
132 CHECKED_D2I_OF(type, d2i_func), \ 184 CHECKED_D2I_OF(type, d2i_func), \
133 CHECKED_SK_FREE_FUNC(type, free_func), \ 185 CHECKED_SK_FREE_FUNC(type, free_func), \
134 ex_tag, ex_class) 186 ex_tag, ex_class)
135 187
136#define SKM_ASN1_SET_OF_i2d(type, st, pp, i2d_func, ex_tag, ex_class, is_set) \ 188#define SKM_ASN1_SET_OF_i2d(type, st, pp, i2d_func, ex_tag, ex_class, is_set) \
137 i2d_ASN1_SET(CHECKED_PTR_OF(STACK_OF(type), st), pp, \ 189 i2d_ASN1_SET((STACK_OF(OPENSSL_BLOCK) *)CHECKED_STACK_OF(type, st), pp, \
138 CHECKED_I2D_OF(type, i2d_func), \ 190 CHECKED_I2D_OF(type, i2d_func), \
139 ex_tag, ex_class, is_set) 191 ex_tag, ex_class, is_set)
140 192
@@ -151,72 +203,8 @@ STACK_OF(type) \
151 CHECKED_SK_FREE_FUNC(type, free_func), \ 203 CHECKED_SK_FREE_FUNC(type, free_func), \
152 pass, passlen, oct, seq) 204 pass, passlen, oct, seq)
153 205
154#else
155
156#define STACK_OF(type) STACK
157#define PREDECLARE_STACK_OF(type) /* nada */
158#define DECLARE_STACK_OF(type) /* nada */
159#define IMPLEMENT_STACK_OF(type) /* nada */
160
161#define SKM_sk_new(type, cmp) \
162 sk_new((int (*)(const char * const *, const char * const *))(cmp))
163#define SKM_sk_new_null(type) \
164 sk_new_null()
165#define SKM_sk_free(type, st) \
166 sk_free(st)
167#define SKM_sk_num(type, st) \
168 sk_num(st)
169#define SKM_sk_value(type, st,i) \
170 ((type *)sk_value(st, i))
171#define SKM_sk_set(type, st,i,val) \
172 ((type *)sk_set(st, i,(char *)val))
173#define SKM_sk_zero(type, st) \
174 sk_zero(st)
175#define SKM_sk_push(type, st,val) \
176 sk_push(st, (char *)val)
177#define SKM_sk_unshift(type, st,val) \
178 sk_unshift(st, (char *)val)
179#define SKM_sk_find(type, st,val) \
180 sk_find(st, (char *)val)
181#define SKM_sk_delete(type, st,i) \
182 ((type *)sk_delete(st, i))
183#define SKM_sk_delete_ptr(type, st,ptr) \
184 ((type *)sk_delete_ptr(st,(char *)ptr))
185#define SKM_sk_insert(type, st,val,i) \
186 sk_insert(st, (char *)val, i)
187#define SKM_sk_set_cmp_func(type, st,cmp) \
188 ((int (*)(const type * const *,const type * const *)) \
189 sk_set_cmp_func(st, (int (*)(const char * const *, const char * const *))(cmp)))
190#define SKM_sk_dup(type, st) \
191 sk_dup(st)
192#define SKM_sk_pop_free(type, st,free_func) \
193 sk_pop_free(st, (void (*)(void *))free_func)
194#define SKM_sk_shift(type, st) \
195 ((type *)sk_shift(st))
196#define SKM_sk_pop(type, st) \
197 ((type *)sk_pop(st))
198#define SKM_sk_sort(type, st) \
199 sk_sort(st)
200#define SKM_sk_is_sorted(type, st) \
201 sk_is_sorted(st)
202
203#define SKM_ASN1_SET_OF_d2i(type, st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
204 d2i_ASN1_SET(st,pp,length, (void *(*)(void ** ,const unsigned char ** ,long))d2i_func, (void (*)(void *))free_func, ex_tag,ex_class)
205#define SKM_ASN1_SET_OF_i2d(type, st, pp, i2d_func, ex_tag, ex_class, is_set) \
206 i2d_ASN1_SET(st,pp,(int (*)(void *, unsigned char **))i2d_func,ex_tag,ex_class,is_set)
207
208#define SKM_ASN1_seq_pack(type, st, i2d_func, buf, len) \
209 ASN1_seq_pack(st, (int (*)(void *, unsigned char **))i2d_func, buf, len)
210#define SKM_ASN1_seq_unpack(type, buf, len, d2i_func, free_func) \
211 ASN1_seq_unpack(buf,len,(void *(*)(void **,const unsigned char **,long))d2i_func, (void(*)(void *))free_func)
212
213#define SKM_PKCS12_decrypt_d2i(type, algor, d2i_func, free_func, pass, passlen, oct, seq) \
214 ((STACK *)PKCS12_decrypt_d2i(algor,(char *(*)())d2i_func, (void(*)(void *))free_func,pass,passlen,oct,seq))
215
216#endif
217
218/* This block of defines is updated by util/mkstack.pl, please do not touch! */ 206/* This block of defines is updated by util/mkstack.pl, please do not touch! */
219#define sk_ACCESS_DESCRIPTION_new(st) SKM_sk_new(ACCESS_DESCRIPTION, (st)) 207#define sk_ACCESS_DESCRIPTION_new(cmp) SKM_sk_new(ACCESS_DESCRIPTION, (cmp))
220#define sk_ACCESS_DESCRIPTION_new_null() SKM_sk_new_null(ACCESS_DESCRIPTION) 208#define sk_ACCESS_DESCRIPTION_new_null() SKM_sk_new_null(ACCESS_DESCRIPTION)
221#define sk_ACCESS_DESCRIPTION_free(st) SKM_sk_free(ACCESS_DESCRIPTION, (st)) 209#define sk_ACCESS_DESCRIPTION_free(st) SKM_sk_free(ACCESS_DESCRIPTION, (st))
222#define sk_ACCESS_DESCRIPTION_num(st) SKM_sk_num(ACCESS_DESCRIPTION, (st)) 210#define sk_ACCESS_DESCRIPTION_num(st) SKM_sk_num(ACCESS_DESCRIPTION, (st))
@@ -238,7 +226,7 @@ STACK_OF(type) \
238#define sk_ACCESS_DESCRIPTION_sort(st) SKM_sk_sort(ACCESS_DESCRIPTION, (st)) 226#define sk_ACCESS_DESCRIPTION_sort(st) SKM_sk_sort(ACCESS_DESCRIPTION, (st))
239#define sk_ACCESS_DESCRIPTION_is_sorted(st) SKM_sk_is_sorted(ACCESS_DESCRIPTION, (st)) 227#define sk_ACCESS_DESCRIPTION_is_sorted(st) SKM_sk_is_sorted(ACCESS_DESCRIPTION, (st))
240 228
241#define sk_ASIdOrRange_new(st) SKM_sk_new(ASIdOrRange, (st)) 229#define sk_ASIdOrRange_new(cmp) SKM_sk_new(ASIdOrRange, (cmp))
242#define sk_ASIdOrRange_new_null() SKM_sk_new_null(ASIdOrRange) 230#define sk_ASIdOrRange_new_null() SKM_sk_new_null(ASIdOrRange)
243#define sk_ASIdOrRange_free(st) SKM_sk_free(ASIdOrRange, (st)) 231#define sk_ASIdOrRange_free(st) SKM_sk_free(ASIdOrRange, (st))
244#define sk_ASIdOrRange_num(st) SKM_sk_num(ASIdOrRange, (st)) 232#define sk_ASIdOrRange_num(st) SKM_sk_num(ASIdOrRange, (st))
@@ -260,7 +248,7 @@ STACK_OF(type) \
260#define sk_ASIdOrRange_sort(st) SKM_sk_sort(ASIdOrRange, (st)) 248#define sk_ASIdOrRange_sort(st) SKM_sk_sort(ASIdOrRange, (st))
261#define sk_ASIdOrRange_is_sorted(st) SKM_sk_is_sorted(ASIdOrRange, (st)) 249#define sk_ASIdOrRange_is_sorted(st) SKM_sk_is_sorted(ASIdOrRange, (st))
262 250
263#define sk_ASN1_GENERALSTRING_new(st) SKM_sk_new(ASN1_GENERALSTRING, (st)) 251#define sk_ASN1_GENERALSTRING_new(cmp) SKM_sk_new(ASN1_GENERALSTRING, (cmp))
264#define sk_ASN1_GENERALSTRING_new_null() SKM_sk_new_null(ASN1_GENERALSTRING) 252#define sk_ASN1_GENERALSTRING_new_null() SKM_sk_new_null(ASN1_GENERALSTRING)
265#define sk_ASN1_GENERALSTRING_free(st) SKM_sk_free(ASN1_GENERALSTRING, (st)) 253#define sk_ASN1_GENERALSTRING_free(st) SKM_sk_free(ASN1_GENERALSTRING, (st))
266#define sk_ASN1_GENERALSTRING_num(st) SKM_sk_num(ASN1_GENERALSTRING, (st)) 254#define sk_ASN1_GENERALSTRING_num(st) SKM_sk_num(ASN1_GENERALSTRING, (st))
@@ -282,7 +270,7 @@ STACK_OF(type) \
282#define sk_ASN1_GENERALSTRING_sort(st) SKM_sk_sort(ASN1_GENERALSTRING, (st)) 270#define sk_ASN1_GENERALSTRING_sort(st) SKM_sk_sort(ASN1_GENERALSTRING, (st))
283#define sk_ASN1_GENERALSTRING_is_sorted(st) SKM_sk_is_sorted(ASN1_GENERALSTRING, (st)) 271#define sk_ASN1_GENERALSTRING_is_sorted(st) SKM_sk_is_sorted(ASN1_GENERALSTRING, (st))
284 272
285#define sk_ASN1_INTEGER_new(st) SKM_sk_new(ASN1_INTEGER, (st)) 273#define sk_ASN1_INTEGER_new(cmp) SKM_sk_new(ASN1_INTEGER, (cmp))
286#define sk_ASN1_INTEGER_new_null() SKM_sk_new_null(ASN1_INTEGER) 274#define sk_ASN1_INTEGER_new_null() SKM_sk_new_null(ASN1_INTEGER)
287#define sk_ASN1_INTEGER_free(st) SKM_sk_free(ASN1_INTEGER, (st)) 275#define sk_ASN1_INTEGER_free(st) SKM_sk_free(ASN1_INTEGER, (st))
288#define sk_ASN1_INTEGER_num(st) SKM_sk_num(ASN1_INTEGER, (st)) 276#define sk_ASN1_INTEGER_num(st) SKM_sk_num(ASN1_INTEGER, (st))
@@ -304,7 +292,7 @@ STACK_OF(type) \
304#define sk_ASN1_INTEGER_sort(st) SKM_sk_sort(ASN1_INTEGER, (st)) 292#define sk_ASN1_INTEGER_sort(st) SKM_sk_sort(ASN1_INTEGER, (st))
305#define sk_ASN1_INTEGER_is_sorted(st) SKM_sk_is_sorted(ASN1_INTEGER, (st)) 293#define sk_ASN1_INTEGER_is_sorted(st) SKM_sk_is_sorted(ASN1_INTEGER, (st))
306 294
307#define sk_ASN1_OBJECT_new(st) SKM_sk_new(ASN1_OBJECT, (st)) 295#define sk_ASN1_OBJECT_new(cmp) SKM_sk_new(ASN1_OBJECT, (cmp))
308#define sk_ASN1_OBJECT_new_null() SKM_sk_new_null(ASN1_OBJECT) 296#define sk_ASN1_OBJECT_new_null() SKM_sk_new_null(ASN1_OBJECT)
309#define sk_ASN1_OBJECT_free(st) SKM_sk_free(ASN1_OBJECT, (st)) 297#define sk_ASN1_OBJECT_free(st) SKM_sk_free(ASN1_OBJECT, (st))
310#define sk_ASN1_OBJECT_num(st) SKM_sk_num(ASN1_OBJECT, (st)) 298#define sk_ASN1_OBJECT_num(st) SKM_sk_num(ASN1_OBJECT, (st))
@@ -326,7 +314,7 @@ STACK_OF(type) \
326#define sk_ASN1_OBJECT_sort(st) SKM_sk_sort(ASN1_OBJECT, (st)) 314#define sk_ASN1_OBJECT_sort(st) SKM_sk_sort(ASN1_OBJECT, (st))
327#define sk_ASN1_OBJECT_is_sorted(st) SKM_sk_is_sorted(ASN1_OBJECT, (st)) 315#define sk_ASN1_OBJECT_is_sorted(st) SKM_sk_is_sorted(ASN1_OBJECT, (st))
328 316
329#define sk_ASN1_STRING_TABLE_new(st) SKM_sk_new(ASN1_STRING_TABLE, (st)) 317#define sk_ASN1_STRING_TABLE_new(cmp) SKM_sk_new(ASN1_STRING_TABLE, (cmp))
330#define sk_ASN1_STRING_TABLE_new_null() SKM_sk_new_null(ASN1_STRING_TABLE) 318#define sk_ASN1_STRING_TABLE_new_null() SKM_sk_new_null(ASN1_STRING_TABLE)
331#define sk_ASN1_STRING_TABLE_free(st) SKM_sk_free(ASN1_STRING_TABLE, (st)) 319#define sk_ASN1_STRING_TABLE_free(st) SKM_sk_free(ASN1_STRING_TABLE, (st))
332#define sk_ASN1_STRING_TABLE_num(st) SKM_sk_num(ASN1_STRING_TABLE, (st)) 320#define sk_ASN1_STRING_TABLE_num(st) SKM_sk_num(ASN1_STRING_TABLE, (st))
@@ -348,7 +336,7 @@ STACK_OF(type) \
348#define sk_ASN1_STRING_TABLE_sort(st) SKM_sk_sort(ASN1_STRING_TABLE, (st)) 336#define sk_ASN1_STRING_TABLE_sort(st) SKM_sk_sort(ASN1_STRING_TABLE, (st))
349#define sk_ASN1_STRING_TABLE_is_sorted(st) SKM_sk_is_sorted(ASN1_STRING_TABLE, (st)) 337#define sk_ASN1_STRING_TABLE_is_sorted(st) SKM_sk_is_sorted(ASN1_STRING_TABLE, (st))
350 338
351#define sk_ASN1_TYPE_new(st) SKM_sk_new(ASN1_TYPE, (st)) 339#define sk_ASN1_TYPE_new(cmp) SKM_sk_new(ASN1_TYPE, (cmp))
352#define sk_ASN1_TYPE_new_null() SKM_sk_new_null(ASN1_TYPE) 340#define sk_ASN1_TYPE_new_null() SKM_sk_new_null(ASN1_TYPE)
353#define sk_ASN1_TYPE_free(st) SKM_sk_free(ASN1_TYPE, (st)) 341#define sk_ASN1_TYPE_free(st) SKM_sk_free(ASN1_TYPE, (st))
354#define sk_ASN1_TYPE_num(st) SKM_sk_num(ASN1_TYPE, (st)) 342#define sk_ASN1_TYPE_num(st) SKM_sk_num(ASN1_TYPE, (st))
@@ -370,7 +358,29 @@ STACK_OF(type) \
370#define sk_ASN1_TYPE_sort(st) SKM_sk_sort(ASN1_TYPE, (st)) 358#define sk_ASN1_TYPE_sort(st) SKM_sk_sort(ASN1_TYPE, (st))
371#define sk_ASN1_TYPE_is_sorted(st) SKM_sk_is_sorted(ASN1_TYPE, (st)) 359#define sk_ASN1_TYPE_is_sorted(st) SKM_sk_is_sorted(ASN1_TYPE, (st))
372 360
373#define sk_ASN1_VALUE_new(st) SKM_sk_new(ASN1_VALUE, (st)) 361#define sk_ASN1_UTF8STRING_new(cmp) SKM_sk_new(ASN1_UTF8STRING, (cmp))
362#define sk_ASN1_UTF8STRING_new_null() SKM_sk_new_null(ASN1_UTF8STRING)
363#define sk_ASN1_UTF8STRING_free(st) SKM_sk_free(ASN1_UTF8STRING, (st))
364#define sk_ASN1_UTF8STRING_num(st) SKM_sk_num(ASN1_UTF8STRING, (st))
365#define sk_ASN1_UTF8STRING_value(st, i) SKM_sk_value(ASN1_UTF8STRING, (st), (i))
366#define sk_ASN1_UTF8STRING_set(st, i, val) SKM_sk_set(ASN1_UTF8STRING, (st), (i), (val))
367#define sk_ASN1_UTF8STRING_zero(st) SKM_sk_zero(ASN1_UTF8STRING, (st))
368#define sk_ASN1_UTF8STRING_push(st, val) SKM_sk_push(ASN1_UTF8STRING, (st), (val))
369#define sk_ASN1_UTF8STRING_unshift(st, val) SKM_sk_unshift(ASN1_UTF8STRING, (st), (val))
370#define sk_ASN1_UTF8STRING_find(st, val) SKM_sk_find(ASN1_UTF8STRING, (st), (val))
371#define sk_ASN1_UTF8STRING_find_ex(st, val) SKM_sk_find_ex(ASN1_UTF8STRING, (st), (val))
372#define sk_ASN1_UTF8STRING_delete(st, i) SKM_sk_delete(ASN1_UTF8STRING, (st), (i))
373#define sk_ASN1_UTF8STRING_delete_ptr(st, ptr) SKM_sk_delete_ptr(ASN1_UTF8STRING, (st), (ptr))
374#define sk_ASN1_UTF8STRING_insert(st, val, i) SKM_sk_insert(ASN1_UTF8STRING, (st), (val), (i))
375#define sk_ASN1_UTF8STRING_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ASN1_UTF8STRING, (st), (cmp))
376#define sk_ASN1_UTF8STRING_dup(st) SKM_sk_dup(ASN1_UTF8STRING, st)
377#define sk_ASN1_UTF8STRING_pop_free(st, free_func) SKM_sk_pop_free(ASN1_UTF8STRING, (st), (free_func))
378#define sk_ASN1_UTF8STRING_shift(st) SKM_sk_shift(ASN1_UTF8STRING, (st))
379#define sk_ASN1_UTF8STRING_pop(st) SKM_sk_pop(ASN1_UTF8STRING, (st))
380#define sk_ASN1_UTF8STRING_sort(st) SKM_sk_sort(ASN1_UTF8STRING, (st))
381#define sk_ASN1_UTF8STRING_is_sorted(st) SKM_sk_is_sorted(ASN1_UTF8STRING, (st))
382
383#define sk_ASN1_VALUE_new(cmp) SKM_sk_new(ASN1_VALUE, (cmp))
374#define sk_ASN1_VALUE_new_null() SKM_sk_new_null(ASN1_VALUE) 384#define sk_ASN1_VALUE_new_null() SKM_sk_new_null(ASN1_VALUE)
375#define sk_ASN1_VALUE_free(st) SKM_sk_free(ASN1_VALUE, (st)) 385#define sk_ASN1_VALUE_free(st) SKM_sk_free(ASN1_VALUE, (st))
376#define sk_ASN1_VALUE_num(st) SKM_sk_num(ASN1_VALUE, (st)) 386#define sk_ASN1_VALUE_num(st) SKM_sk_num(ASN1_VALUE, (st))
@@ -392,7 +402,7 @@ STACK_OF(type) \
392#define sk_ASN1_VALUE_sort(st) SKM_sk_sort(ASN1_VALUE, (st)) 402#define sk_ASN1_VALUE_sort(st) SKM_sk_sort(ASN1_VALUE, (st))
393#define sk_ASN1_VALUE_is_sorted(st) SKM_sk_is_sorted(ASN1_VALUE, (st)) 403#define sk_ASN1_VALUE_is_sorted(st) SKM_sk_is_sorted(ASN1_VALUE, (st))
394 404
395#define sk_BIO_new(st) SKM_sk_new(BIO, (st)) 405#define sk_BIO_new(cmp) SKM_sk_new(BIO, (cmp))
396#define sk_BIO_new_null() SKM_sk_new_null(BIO) 406#define sk_BIO_new_null() SKM_sk_new_null(BIO)
397#define sk_BIO_free(st) SKM_sk_free(BIO, (st)) 407#define sk_BIO_free(st) SKM_sk_free(BIO, (st))
398#define sk_BIO_num(st) SKM_sk_num(BIO, (st)) 408#define sk_BIO_num(st) SKM_sk_num(BIO, (st))
@@ -414,7 +424,51 @@ STACK_OF(type) \
414#define sk_BIO_sort(st) SKM_sk_sort(BIO, (st)) 424#define sk_BIO_sort(st) SKM_sk_sort(BIO, (st))
415#define sk_BIO_is_sorted(st) SKM_sk_is_sorted(BIO, (st)) 425#define sk_BIO_is_sorted(st) SKM_sk_is_sorted(BIO, (st))
416 426
417#define sk_CMS_CertificateChoices_new(st) SKM_sk_new(CMS_CertificateChoices, (st)) 427#define sk_BY_DIR_ENTRY_new(cmp) SKM_sk_new(BY_DIR_ENTRY, (cmp))
428#define sk_BY_DIR_ENTRY_new_null() SKM_sk_new_null(BY_DIR_ENTRY)
429#define sk_BY_DIR_ENTRY_free(st) SKM_sk_free(BY_DIR_ENTRY, (st))
430#define sk_BY_DIR_ENTRY_num(st) SKM_sk_num(BY_DIR_ENTRY, (st))
431#define sk_BY_DIR_ENTRY_value(st, i) SKM_sk_value(BY_DIR_ENTRY, (st), (i))
432#define sk_BY_DIR_ENTRY_set(st, i, val) SKM_sk_set(BY_DIR_ENTRY, (st), (i), (val))
433#define sk_BY_DIR_ENTRY_zero(st) SKM_sk_zero(BY_DIR_ENTRY, (st))
434#define sk_BY_DIR_ENTRY_push(st, val) SKM_sk_push(BY_DIR_ENTRY, (st), (val))
435#define sk_BY_DIR_ENTRY_unshift(st, val) SKM_sk_unshift(BY_DIR_ENTRY, (st), (val))
436#define sk_BY_DIR_ENTRY_find(st, val) SKM_sk_find(BY_DIR_ENTRY, (st), (val))
437#define sk_BY_DIR_ENTRY_find_ex(st, val) SKM_sk_find_ex(BY_DIR_ENTRY, (st), (val))
438#define sk_BY_DIR_ENTRY_delete(st, i) SKM_sk_delete(BY_DIR_ENTRY, (st), (i))
439#define sk_BY_DIR_ENTRY_delete_ptr(st, ptr) SKM_sk_delete_ptr(BY_DIR_ENTRY, (st), (ptr))
440#define sk_BY_DIR_ENTRY_insert(st, val, i) SKM_sk_insert(BY_DIR_ENTRY, (st), (val), (i))
441#define sk_BY_DIR_ENTRY_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(BY_DIR_ENTRY, (st), (cmp))
442#define sk_BY_DIR_ENTRY_dup(st) SKM_sk_dup(BY_DIR_ENTRY, st)
443#define sk_BY_DIR_ENTRY_pop_free(st, free_func) SKM_sk_pop_free(BY_DIR_ENTRY, (st), (free_func))
444#define sk_BY_DIR_ENTRY_shift(st) SKM_sk_shift(BY_DIR_ENTRY, (st))
445#define sk_BY_DIR_ENTRY_pop(st) SKM_sk_pop(BY_DIR_ENTRY, (st))
446#define sk_BY_DIR_ENTRY_sort(st) SKM_sk_sort(BY_DIR_ENTRY, (st))
447#define sk_BY_DIR_ENTRY_is_sorted(st) SKM_sk_is_sorted(BY_DIR_ENTRY, (st))
448
449#define sk_BY_DIR_HASH_new(cmp) SKM_sk_new(BY_DIR_HASH, (cmp))
450#define sk_BY_DIR_HASH_new_null() SKM_sk_new_null(BY_DIR_HASH)
451#define sk_BY_DIR_HASH_free(st) SKM_sk_free(BY_DIR_HASH, (st))
452#define sk_BY_DIR_HASH_num(st) SKM_sk_num(BY_DIR_HASH, (st))
453#define sk_BY_DIR_HASH_value(st, i) SKM_sk_value(BY_DIR_HASH, (st), (i))
454#define sk_BY_DIR_HASH_set(st, i, val) SKM_sk_set(BY_DIR_HASH, (st), (i), (val))
455#define sk_BY_DIR_HASH_zero(st) SKM_sk_zero(BY_DIR_HASH, (st))
456#define sk_BY_DIR_HASH_push(st, val) SKM_sk_push(BY_DIR_HASH, (st), (val))
457#define sk_BY_DIR_HASH_unshift(st, val) SKM_sk_unshift(BY_DIR_HASH, (st), (val))
458#define sk_BY_DIR_HASH_find(st, val) SKM_sk_find(BY_DIR_HASH, (st), (val))
459#define sk_BY_DIR_HASH_find_ex(st, val) SKM_sk_find_ex(BY_DIR_HASH, (st), (val))
460#define sk_BY_DIR_HASH_delete(st, i) SKM_sk_delete(BY_DIR_HASH, (st), (i))
461#define sk_BY_DIR_HASH_delete_ptr(st, ptr) SKM_sk_delete_ptr(BY_DIR_HASH, (st), (ptr))
462#define sk_BY_DIR_HASH_insert(st, val, i) SKM_sk_insert(BY_DIR_HASH, (st), (val), (i))
463#define sk_BY_DIR_HASH_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(BY_DIR_HASH, (st), (cmp))
464#define sk_BY_DIR_HASH_dup(st) SKM_sk_dup(BY_DIR_HASH, st)
465#define sk_BY_DIR_HASH_pop_free(st, free_func) SKM_sk_pop_free(BY_DIR_HASH, (st), (free_func))
466#define sk_BY_DIR_HASH_shift(st) SKM_sk_shift(BY_DIR_HASH, (st))
467#define sk_BY_DIR_HASH_pop(st) SKM_sk_pop(BY_DIR_HASH, (st))
468#define sk_BY_DIR_HASH_sort(st) SKM_sk_sort(BY_DIR_HASH, (st))
469#define sk_BY_DIR_HASH_is_sorted(st) SKM_sk_is_sorted(BY_DIR_HASH, (st))
470
471#define sk_CMS_CertificateChoices_new(cmp) SKM_sk_new(CMS_CertificateChoices, (cmp))
418#define sk_CMS_CertificateChoices_new_null() SKM_sk_new_null(CMS_CertificateChoices) 472#define sk_CMS_CertificateChoices_new_null() SKM_sk_new_null(CMS_CertificateChoices)
419#define sk_CMS_CertificateChoices_free(st) SKM_sk_free(CMS_CertificateChoices, (st)) 473#define sk_CMS_CertificateChoices_free(st) SKM_sk_free(CMS_CertificateChoices, (st))
420#define sk_CMS_CertificateChoices_num(st) SKM_sk_num(CMS_CertificateChoices, (st)) 474#define sk_CMS_CertificateChoices_num(st) SKM_sk_num(CMS_CertificateChoices, (st))
@@ -436,7 +490,7 @@ STACK_OF(type) \
436#define sk_CMS_CertificateChoices_sort(st) SKM_sk_sort(CMS_CertificateChoices, (st)) 490#define sk_CMS_CertificateChoices_sort(st) SKM_sk_sort(CMS_CertificateChoices, (st))
437#define sk_CMS_CertificateChoices_is_sorted(st) SKM_sk_is_sorted(CMS_CertificateChoices, (st)) 491#define sk_CMS_CertificateChoices_is_sorted(st) SKM_sk_is_sorted(CMS_CertificateChoices, (st))
438 492
439#define sk_CMS_RecipientInfo_new(st) SKM_sk_new(CMS_RecipientInfo, (st)) 493#define sk_CMS_RecipientInfo_new(cmp) SKM_sk_new(CMS_RecipientInfo, (cmp))
440#define sk_CMS_RecipientInfo_new_null() SKM_sk_new_null(CMS_RecipientInfo) 494#define sk_CMS_RecipientInfo_new_null() SKM_sk_new_null(CMS_RecipientInfo)
441#define sk_CMS_RecipientInfo_free(st) SKM_sk_free(CMS_RecipientInfo, (st)) 495#define sk_CMS_RecipientInfo_free(st) SKM_sk_free(CMS_RecipientInfo, (st))
442#define sk_CMS_RecipientInfo_num(st) SKM_sk_num(CMS_RecipientInfo, (st)) 496#define sk_CMS_RecipientInfo_num(st) SKM_sk_num(CMS_RecipientInfo, (st))
@@ -458,7 +512,7 @@ STACK_OF(type) \
458#define sk_CMS_RecipientInfo_sort(st) SKM_sk_sort(CMS_RecipientInfo, (st)) 512#define sk_CMS_RecipientInfo_sort(st) SKM_sk_sort(CMS_RecipientInfo, (st))
459#define sk_CMS_RecipientInfo_is_sorted(st) SKM_sk_is_sorted(CMS_RecipientInfo, (st)) 513#define sk_CMS_RecipientInfo_is_sorted(st) SKM_sk_is_sorted(CMS_RecipientInfo, (st))
460 514
461#define sk_CMS_RevocationInfoChoice_new(st) SKM_sk_new(CMS_RevocationInfoChoice, (st)) 515#define sk_CMS_RevocationInfoChoice_new(cmp) SKM_sk_new(CMS_RevocationInfoChoice, (cmp))
462#define sk_CMS_RevocationInfoChoice_new_null() SKM_sk_new_null(CMS_RevocationInfoChoice) 516#define sk_CMS_RevocationInfoChoice_new_null() SKM_sk_new_null(CMS_RevocationInfoChoice)
463#define sk_CMS_RevocationInfoChoice_free(st) SKM_sk_free(CMS_RevocationInfoChoice, (st)) 517#define sk_CMS_RevocationInfoChoice_free(st) SKM_sk_free(CMS_RevocationInfoChoice, (st))
464#define sk_CMS_RevocationInfoChoice_num(st) SKM_sk_num(CMS_RevocationInfoChoice, (st)) 518#define sk_CMS_RevocationInfoChoice_num(st) SKM_sk_num(CMS_RevocationInfoChoice, (st))
@@ -480,7 +534,7 @@ STACK_OF(type) \
480#define sk_CMS_RevocationInfoChoice_sort(st) SKM_sk_sort(CMS_RevocationInfoChoice, (st)) 534#define sk_CMS_RevocationInfoChoice_sort(st) SKM_sk_sort(CMS_RevocationInfoChoice, (st))
481#define sk_CMS_RevocationInfoChoice_is_sorted(st) SKM_sk_is_sorted(CMS_RevocationInfoChoice, (st)) 535#define sk_CMS_RevocationInfoChoice_is_sorted(st) SKM_sk_is_sorted(CMS_RevocationInfoChoice, (st))
482 536
483#define sk_CMS_SignerInfo_new(st) SKM_sk_new(CMS_SignerInfo, (st)) 537#define sk_CMS_SignerInfo_new(cmp) SKM_sk_new(CMS_SignerInfo, (cmp))
484#define sk_CMS_SignerInfo_new_null() SKM_sk_new_null(CMS_SignerInfo) 538#define sk_CMS_SignerInfo_new_null() SKM_sk_new_null(CMS_SignerInfo)
485#define sk_CMS_SignerInfo_free(st) SKM_sk_free(CMS_SignerInfo, (st)) 539#define sk_CMS_SignerInfo_free(st) SKM_sk_free(CMS_SignerInfo, (st))
486#define sk_CMS_SignerInfo_num(st) SKM_sk_num(CMS_SignerInfo, (st)) 540#define sk_CMS_SignerInfo_num(st) SKM_sk_num(CMS_SignerInfo, (st))
@@ -502,7 +556,7 @@ STACK_OF(type) \
502#define sk_CMS_SignerInfo_sort(st) SKM_sk_sort(CMS_SignerInfo, (st)) 556#define sk_CMS_SignerInfo_sort(st) SKM_sk_sort(CMS_SignerInfo, (st))
503#define sk_CMS_SignerInfo_is_sorted(st) SKM_sk_is_sorted(CMS_SignerInfo, (st)) 557#define sk_CMS_SignerInfo_is_sorted(st) SKM_sk_is_sorted(CMS_SignerInfo, (st))
504 558
505#define sk_CONF_IMODULE_new(st) SKM_sk_new(CONF_IMODULE, (st)) 559#define sk_CONF_IMODULE_new(cmp) SKM_sk_new(CONF_IMODULE, (cmp))
506#define sk_CONF_IMODULE_new_null() SKM_sk_new_null(CONF_IMODULE) 560#define sk_CONF_IMODULE_new_null() SKM_sk_new_null(CONF_IMODULE)
507#define sk_CONF_IMODULE_free(st) SKM_sk_free(CONF_IMODULE, (st)) 561#define sk_CONF_IMODULE_free(st) SKM_sk_free(CONF_IMODULE, (st))
508#define sk_CONF_IMODULE_num(st) SKM_sk_num(CONF_IMODULE, (st)) 562#define sk_CONF_IMODULE_num(st) SKM_sk_num(CONF_IMODULE, (st))
@@ -524,7 +578,7 @@ STACK_OF(type) \
524#define sk_CONF_IMODULE_sort(st) SKM_sk_sort(CONF_IMODULE, (st)) 578#define sk_CONF_IMODULE_sort(st) SKM_sk_sort(CONF_IMODULE, (st))
525#define sk_CONF_IMODULE_is_sorted(st) SKM_sk_is_sorted(CONF_IMODULE, (st)) 579#define sk_CONF_IMODULE_is_sorted(st) SKM_sk_is_sorted(CONF_IMODULE, (st))
526 580
527#define sk_CONF_MODULE_new(st) SKM_sk_new(CONF_MODULE, (st)) 581#define sk_CONF_MODULE_new(cmp) SKM_sk_new(CONF_MODULE, (cmp))
528#define sk_CONF_MODULE_new_null() SKM_sk_new_null(CONF_MODULE) 582#define sk_CONF_MODULE_new_null() SKM_sk_new_null(CONF_MODULE)
529#define sk_CONF_MODULE_free(st) SKM_sk_free(CONF_MODULE, (st)) 583#define sk_CONF_MODULE_free(st) SKM_sk_free(CONF_MODULE, (st))
530#define sk_CONF_MODULE_num(st) SKM_sk_num(CONF_MODULE, (st)) 584#define sk_CONF_MODULE_num(st) SKM_sk_num(CONF_MODULE, (st))
@@ -546,7 +600,7 @@ STACK_OF(type) \
546#define sk_CONF_MODULE_sort(st) SKM_sk_sort(CONF_MODULE, (st)) 600#define sk_CONF_MODULE_sort(st) SKM_sk_sort(CONF_MODULE, (st))
547#define sk_CONF_MODULE_is_sorted(st) SKM_sk_is_sorted(CONF_MODULE, (st)) 601#define sk_CONF_MODULE_is_sorted(st) SKM_sk_is_sorted(CONF_MODULE, (st))
548 602
549#define sk_CONF_VALUE_new(st) SKM_sk_new(CONF_VALUE, (st)) 603#define sk_CONF_VALUE_new(cmp) SKM_sk_new(CONF_VALUE, (cmp))
550#define sk_CONF_VALUE_new_null() SKM_sk_new_null(CONF_VALUE) 604#define sk_CONF_VALUE_new_null() SKM_sk_new_null(CONF_VALUE)
551#define sk_CONF_VALUE_free(st) SKM_sk_free(CONF_VALUE, (st)) 605#define sk_CONF_VALUE_free(st) SKM_sk_free(CONF_VALUE, (st))
552#define sk_CONF_VALUE_num(st) SKM_sk_num(CONF_VALUE, (st)) 606#define sk_CONF_VALUE_num(st) SKM_sk_num(CONF_VALUE, (st))
@@ -568,7 +622,7 @@ STACK_OF(type) \
568#define sk_CONF_VALUE_sort(st) SKM_sk_sort(CONF_VALUE, (st)) 622#define sk_CONF_VALUE_sort(st) SKM_sk_sort(CONF_VALUE, (st))
569#define sk_CONF_VALUE_is_sorted(st) SKM_sk_is_sorted(CONF_VALUE, (st)) 623#define sk_CONF_VALUE_is_sorted(st) SKM_sk_is_sorted(CONF_VALUE, (st))
570 624
571#define sk_CRYPTO_EX_DATA_FUNCS_new(st) SKM_sk_new(CRYPTO_EX_DATA_FUNCS, (st)) 625#define sk_CRYPTO_EX_DATA_FUNCS_new(cmp) SKM_sk_new(CRYPTO_EX_DATA_FUNCS, (cmp))
572#define sk_CRYPTO_EX_DATA_FUNCS_new_null() SKM_sk_new_null(CRYPTO_EX_DATA_FUNCS) 626#define sk_CRYPTO_EX_DATA_FUNCS_new_null() SKM_sk_new_null(CRYPTO_EX_DATA_FUNCS)
573#define sk_CRYPTO_EX_DATA_FUNCS_free(st) SKM_sk_free(CRYPTO_EX_DATA_FUNCS, (st)) 627#define sk_CRYPTO_EX_DATA_FUNCS_free(st) SKM_sk_free(CRYPTO_EX_DATA_FUNCS, (st))
574#define sk_CRYPTO_EX_DATA_FUNCS_num(st) SKM_sk_num(CRYPTO_EX_DATA_FUNCS, (st)) 628#define sk_CRYPTO_EX_DATA_FUNCS_num(st) SKM_sk_num(CRYPTO_EX_DATA_FUNCS, (st))
@@ -590,7 +644,7 @@ STACK_OF(type) \
590#define sk_CRYPTO_EX_DATA_FUNCS_sort(st) SKM_sk_sort(CRYPTO_EX_DATA_FUNCS, (st)) 644#define sk_CRYPTO_EX_DATA_FUNCS_sort(st) SKM_sk_sort(CRYPTO_EX_DATA_FUNCS, (st))
591#define sk_CRYPTO_EX_DATA_FUNCS_is_sorted(st) SKM_sk_is_sorted(CRYPTO_EX_DATA_FUNCS, (st)) 645#define sk_CRYPTO_EX_DATA_FUNCS_is_sorted(st) SKM_sk_is_sorted(CRYPTO_EX_DATA_FUNCS, (st))
592 646
593#define sk_CRYPTO_dynlock_new(st) SKM_sk_new(CRYPTO_dynlock, (st)) 647#define sk_CRYPTO_dynlock_new(cmp) SKM_sk_new(CRYPTO_dynlock, (cmp))
594#define sk_CRYPTO_dynlock_new_null() SKM_sk_new_null(CRYPTO_dynlock) 648#define sk_CRYPTO_dynlock_new_null() SKM_sk_new_null(CRYPTO_dynlock)
595#define sk_CRYPTO_dynlock_free(st) SKM_sk_free(CRYPTO_dynlock, (st)) 649#define sk_CRYPTO_dynlock_free(st) SKM_sk_free(CRYPTO_dynlock, (st))
596#define sk_CRYPTO_dynlock_num(st) SKM_sk_num(CRYPTO_dynlock, (st)) 650#define sk_CRYPTO_dynlock_num(st) SKM_sk_num(CRYPTO_dynlock, (st))
@@ -612,7 +666,7 @@ STACK_OF(type) \
612#define sk_CRYPTO_dynlock_sort(st) SKM_sk_sort(CRYPTO_dynlock, (st)) 666#define sk_CRYPTO_dynlock_sort(st) SKM_sk_sort(CRYPTO_dynlock, (st))
613#define sk_CRYPTO_dynlock_is_sorted(st) SKM_sk_is_sorted(CRYPTO_dynlock, (st)) 667#define sk_CRYPTO_dynlock_is_sorted(st) SKM_sk_is_sorted(CRYPTO_dynlock, (st))
614 668
615#define sk_DIST_POINT_new(st) SKM_sk_new(DIST_POINT, (st)) 669#define sk_DIST_POINT_new(cmp) SKM_sk_new(DIST_POINT, (cmp))
616#define sk_DIST_POINT_new_null() SKM_sk_new_null(DIST_POINT) 670#define sk_DIST_POINT_new_null() SKM_sk_new_null(DIST_POINT)
617#define sk_DIST_POINT_free(st) SKM_sk_free(DIST_POINT, (st)) 671#define sk_DIST_POINT_free(st) SKM_sk_free(DIST_POINT, (st))
618#define sk_DIST_POINT_num(st) SKM_sk_num(DIST_POINT, (st)) 672#define sk_DIST_POINT_num(st) SKM_sk_num(DIST_POINT, (st))
@@ -634,7 +688,7 @@ STACK_OF(type) \
634#define sk_DIST_POINT_sort(st) SKM_sk_sort(DIST_POINT, (st)) 688#define sk_DIST_POINT_sort(st) SKM_sk_sort(DIST_POINT, (st))
635#define sk_DIST_POINT_is_sorted(st) SKM_sk_is_sorted(DIST_POINT, (st)) 689#define sk_DIST_POINT_is_sorted(st) SKM_sk_is_sorted(DIST_POINT, (st))
636 690
637#define sk_ENGINE_new(st) SKM_sk_new(ENGINE, (st)) 691#define sk_ENGINE_new(cmp) SKM_sk_new(ENGINE, (cmp))
638#define sk_ENGINE_new_null() SKM_sk_new_null(ENGINE) 692#define sk_ENGINE_new_null() SKM_sk_new_null(ENGINE)
639#define sk_ENGINE_free(st) SKM_sk_free(ENGINE, (st)) 693#define sk_ENGINE_free(st) SKM_sk_free(ENGINE, (st))
640#define sk_ENGINE_num(st) SKM_sk_num(ENGINE, (st)) 694#define sk_ENGINE_num(st) SKM_sk_num(ENGINE, (st))
@@ -656,7 +710,7 @@ STACK_OF(type) \
656#define sk_ENGINE_sort(st) SKM_sk_sort(ENGINE, (st)) 710#define sk_ENGINE_sort(st) SKM_sk_sort(ENGINE, (st))
657#define sk_ENGINE_is_sorted(st) SKM_sk_is_sorted(ENGINE, (st)) 711#define sk_ENGINE_is_sorted(st) SKM_sk_is_sorted(ENGINE, (st))
658 712
659#define sk_ENGINE_CLEANUP_ITEM_new(st) SKM_sk_new(ENGINE_CLEANUP_ITEM, (st)) 713#define sk_ENGINE_CLEANUP_ITEM_new(cmp) SKM_sk_new(ENGINE_CLEANUP_ITEM, (cmp))
660#define sk_ENGINE_CLEANUP_ITEM_new_null() SKM_sk_new_null(ENGINE_CLEANUP_ITEM) 714#define sk_ENGINE_CLEANUP_ITEM_new_null() SKM_sk_new_null(ENGINE_CLEANUP_ITEM)
661#define sk_ENGINE_CLEANUP_ITEM_free(st) SKM_sk_free(ENGINE_CLEANUP_ITEM, (st)) 715#define sk_ENGINE_CLEANUP_ITEM_free(st) SKM_sk_free(ENGINE_CLEANUP_ITEM, (st))
662#define sk_ENGINE_CLEANUP_ITEM_num(st) SKM_sk_num(ENGINE_CLEANUP_ITEM, (st)) 716#define sk_ENGINE_CLEANUP_ITEM_num(st) SKM_sk_num(ENGINE_CLEANUP_ITEM, (st))
@@ -678,7 +732,117 @@ STACK_OF(type) \
678#define sk_ENGINE_CLEANUP_ITEM_sort(st) SKM_sk_sort(ENGINE_CLEANUP_ITEM, (st)) 732#define sk_ENGINE_CLEANUP_ITEM_sort(st) SKM_sk_sort(ENGINE_CLEANUP_ITEM, (st))
679#define sk_ENGINE_CLEANUP_ITEM_is_sorted(st) SKM_sk_is_sorted(ENGINE_CLEANUP_ITEM, (st)) 733#define sk_ENGINE_CLEANUP_ITEM_is_sorted(st) SKM_sk_is_sorted(ENGINE_CLEANUP_ITEM, (st))
680 734
681#define sk_GENERAL_NAME_new(st) SKM_sk_new(GENERAL_NAME, (st)) 735#define sk_ESS_CERT_ID_new(cmp) SKM_sk_new(ESS_CERT_ID, (cmp))
736#define sk_ESS_CERT_ID_new_null() SKM_sk_new_null(ESS_CERT_ID)
737#define sk_ESS_CERT_ID_free(st) SKM_sk_free(ESS_CERT_ID, (st))
738#define sk_ESS_CERT_ID_num(st) SKM_sk_num(ESS_CERT_ID, (st))
739#define sk_ESS_CERT_ID_value(st, i) SKM_sk_value(ESS_CERT_ID, (st), (i))
740#define sk_ESS_CERT_ID_set(st, i, val) SKM_sk_set(ESS_CERT_ID, (st), (i), (val))
741#define sk_ESS_CERT_ID_zero(st) SKM_sk_zero(ESS_CERT_ID, (st))
742#define sk_ESS_CERT_ID_push(st, val) SKM_sk_push(ESS_CERT_ID, (st), (val))
743#define sk_ESS_CERT_ID_unshift(st, val) SKM_sk_unshift(ESS_CERT_ID, (st), (val))
744#define sk_ESS_CERT_ID_find(st, val) SKM_sk_find(ESS_CERT_ID, (st), (val))
745#define sk_ESS_CERT_ID_find_ex(st, val) SKM_sk_find_ex(ESS_CERT_ID, (st), (val))
746#define sk_ESS_CERT_ID_delete(st, i) SKM_sk_delete(ESS_CERT_ID, (st), (i))
747#define sk_ESS_CERT_ID_delete_ptr(st, ptr) SKM_sk_delete_ptr(ESS_CERT_ID, (st), (ptr))
748#define sk_ESS_CERT_ID_insert(st, val, i) SKM_sk_insert(ESS_CERT_ID, (st), (val), (i))
749#define sk_ESS_CERT_ID_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ESS_CERT_ID, (st), (cmp))
750#define sk_ESS_CERT_ID_dup(st) SKM_sk_dup(ESS_CERT_ID, st)
751#define sk_ESS_CERT_ID_pop_free(st, free_func) SKM_sk_pop_free(ESS_CERT_ID, (st), (free_func))
752#define sk_ESS_CERT_ID_shift(st) SKM_sk_shift(ESS_CERT_ID, (st))
753#define sk_ESS_CERT_ID_pop(st) SKM_sk_pop(ESS_CERT_ID, (st))
754#define sk_ESS_CERT_ID_sort(st) SKM_sk_sort(ESS_CERT_ID, (st))
755#define sk_ESS_CERT_ID_is_sorted(st) SKM_sk_is_sorted(ESS_CERT_ID, (st))
756
757#define sk_EVP_MD_new(cmp) SKM_sk_new(EVP_MD, (cmp))
758#define sk_EVP_MD_new_null() SKM_sk_new_null(EVP_MD)
759#define sk_EVP_MD_free(st) SKM_sk_free(EVP_MD, (st))
760#define sk_EVP_MD_num(st) SKM_sk_num(EVP_MD, (st))
761#define sk_EVP_MD_value(st, i) SKM_sk_value(EVP_MD, (st), (i))
762#define sk_EVP_MD_set(st, i, val) SKM_sk_set(EVP_MD, (st), (i), (val))
763#define sk_EVP_MD_zero(st) SKM_sk_zero(EVP_MD, (st))
764#define sk_EVP_MD_push(st, val) SKM_sk_push(EVP_MD, (st), (val))
765#define sk_EVP_MD_unshift(st, val) SKM_sk_unshift(EVP_MD, (st), (val))
766#define sk_EVP_MD_find(st, val) SKM_sk_find(EVP_MD, (st), (val))
767#define sk_EVP_MD_find_ex(st, val) SKM_sk_find_ex(EVP_MD, (st), (val))
768#define sk_EVP_MD_delete(st, i) SKM_sk_delete(EVP_MD, (st), (i))
769#define sk_EVP_MD_delete_ptr(st, ptr) SKM_sk_delete_ptr(EVP_MD, (st), (ptr))
770#define sk_EVP_MD_insert(st, val, i) SKM_sk_insert(EVP_MD, (st), (val), (i))
771#define sk_EVP_MD_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(EVP_MD, (st), (cmp))
772#define sk_EVP_MD_dup(st) SKM_sk_dup(EVP_MD, st)
773#define sk_EVP_MD_pop_free(st, free_func) SKM_sk_pop_free(EVP_MD, (st), (free_func))
774#define sk_EVP_MD_shift(st) SKM_sk_shift(EVP_MD, (st))
775#define sk_EVP_MD_pop(st) SKM_sk_pop(EVP_MD, (st))
776#define sk_EVP_MD_sort(st) SKM_sk_sort(EVP_MD, (st))
777#define sk_EVP_MD_is_sorted(st) SKM_sk_is_sorted(EVP_MD, (st))
778
779#define sk_EVP_PBE_CTL_new(cmp) SKM_sk_new(EVP_PBE_CTL, (cmp))
780#define sk_EVP_PBE_CTL_new_null() SKM_sk_new_null(EVP_PBE_CTL)
781#define sk_EVP_PBE_CTL_free(st) SKM_sk_free(EVP_PBE_CTL, (st))
782#define sk_EVP_PBE_CTL_num(st) SKM_sk_num(EVP_PBE_CTL, (st))
783#define sk_EVP_PBE_CTL_value(st, i) SKM_sk_value(EVP_PBE_CTL, (st), (i))
784#define sk_EVP_PBE_CTL_set(st, i, val) SKM_sk_set(EVP_PBE_CTL, (st), (i), (val))
785#define sk_EVP_PBE_CTL_zero(st) SKM_sk_zero(EVP_PBE_CTL, (st))
786#define sk_EVP_PBE_CTL_push(st, val) SKM_sk_push(EVP_PBE_CTL, (st), (val))
787#define sk_EVP_PBE_CTL_unshift(st, val) SKM_sk_unshift(EVP_PBE_CTL, (st), (val))
788#define sk_EVP_PBE_CTL_find(st, val) SKM_sk_find(EVP_PBE_CTL, (st), (val))
789#define sk_EVP_PBE_CTL_find_ex(st, val) SKM_sk_find_ex(EVP_PBE_CTL, (st), (val))
790#define sk_EVP_PBE_CTL_delete(st, i) SKM_sk_delete(EVP_PBE_CTL, (st), (i))
791#define sk_EVP_PBE_CTL_delete_ptr(st, ptr) SKM_sk_delete_ptr(EVP_PBE_CTL, (st), (ptr))
792#define sk_EVP_PBE_CTL_insert(st, val, i) SKM_sk_insert(EVP_PBE_CTL, (st), (val), (i))
793#define sk_EVP_PBE_CTL_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(EVP_PBE_CTL, (st), (cmp))
794#define sk_EVP_PBE_CTL_dup(st) SKM_sk_dup(EVP_PBE_CTL, st)
795#define sk_EVP_PBE_CTL_pop_free(st, free_func) SKM_sk_pop_free(EVP_PBE_CTL, (st), (free_func))
796#define sk_EVP_PBE_CTL_shift(st) SKM_sk_shift(EVP_PBE_CTL, (st))
797#define sk_EVP_PBE_CTL_pop(st) SKM_sk_pop(EVP_PBE_CTL, (st))
798#define sk_EVP_PBE_CTL_sort(st) SKM_sk_sort(EVP_PBE_CTL, (st))
799#define sk_EVP_PBE_CTL_is_sorted(st) SKM_sk_is_sorted(EVP_PBE_CTL, (st))
800
801#define sk_EVP_PKEY_ASN1_METHOD_new(cmp) SKM_sk_new(EVP_PKEY_ASN1_METHOD, (cmp))
802#define sk_EVP_PKEY_ASN1_METHOD_new_null() SKM_sk_new_null(EVP_PKEY_ASN1_METHOD)
803#define sk_EVP_PKEY_ASN1_METHOD_free(st) SKM_sk_free(EVP_PKEY_ASN1_METHOD, (st))
804#define sk_EVP_PKEY_ASN1_METHOD_num(st) SKM_sk_num(EVP_PKEY_ASN1_METHOD, (st))
805#define sk_EVP_PKEY_ASN1_METHOD_value(st, i) SKM_sk_value(EVP_PKEY_ASN1_METHOD, (st), (i))
806#define sk_EVP_PKEY_ASN1_METHOD_set(st, i, val) SKM_sk_set(EVP_PKEY_ASN1_METHOD, (st), (i), (val))
807#define sk_EVP_PKEY_ASN1_METHOD_zero(st) SKM_sk_zero(EVP_PKEY_ASN1_METHOD, (st))
808#define sk_EVP_PKEY_ASN1_METHOD_push(st, val) SKM_sk_push(EVP_PKEY_ASN1_METHOD, (st), (val))
809#define sk_EVP_PKEY_ASN1_METHOD_unshift(st, val) SKM_sk_unshift(EVP_PKEY_ASN1_METHOD, (st), (val))
810#define sk_EVP_PKEY_ASN1_METHOD_find(st, val) SKM_sk_find(EVP_PKEY_ASN1_METHOD, (st), (val))
811#define sk_EVP_PKEY_ASN1_METHOD_find_ex(st, val) SKM_sk_find_ex(EVP_PKEY_ASN1_METHOD, (st), (val))
812#define sk_EVP_PKEY_ASN1_METHOD_delete(st, i) SKM_sk_delete(EVP_PKEY_ASN1_METHOD, (st), (i))
813#define sk_EVP_PKEY_ASN1_METHOD_delete_ptr(st, ptr) SKM_sk_delete_ptr(EVP_PKEY_ASN1_METHOD, (st), (ptr))
814#define sk_EVP_PKEY_ASN1_METHOD_insert(st, val, i) SKM_sk_insert(EVP_PKEY_ASN1_METHOD, (st), (val), (i))
815#define sk_EVP_PKEY_ASN1_METHOD_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(EVP_PKEY_ASN1_METHOD, (st), (cmp))
816#define sk_EVP_PKEY_ASN1_METHOD_dup(st) SKM_sk_dup(EVP_PKEY_ASN1_METHOD, st)
817#define sk_EVP_PKEY_ASN1_METHOD_pop_free(st, free_func) SKM_sk_pop_free(EVP_PKEY_ASN1_METHOD, (st), (free_func))
818#define sk_EVP_PKEY_ASN1_METHOD_shift(st) SKM_sk_shift(EVP_PKEY_ASN1_METHOD, (st))
819#define sk_EVP_PKEY_ASN1_METHOD_pop(st) SKM_sk_pop(EVP_PKEY_ASN1_METHOD, (st))
820#define sk_EVP_PKEY_ASN1_METHOD_sort(st) SKM_sk_sort(EVP_PKEY_ASN1_METHOD, (st))
821#define sk_EVP_PKEY_ASN1_METHOD_is_sorted(st) SKM_sk_is_sorted(EVP_PKEY_ASN1_METHOD, (st))
822
823#define sk_EVP_PKEY_METHOD_new(cmp) SKM_sk_new(EVP_PKEY_METHOD, (cmp))
824#define sk_EVP_PKEY_METHOD_new_null() SKM_sk_new_null(EVP_PKEY_METHOD)
825#define sk_EVP_PKEY_METHOD_free(st) SKM_sk_free(EVP_PKEY_METHOD, (st))
826#define sk_EVP_PKEY_METHOD_num(st) SKM_sk_num(EVP_PKEY_METHOD, (st))
827#define sk_EVP_PKEY_METHOD_value(st, i) SKM_sk_value(EVP_PKEY_METHOD, (st), (i))
828#define sk_EVP_PKEY_METHOD_set(st, i, val) SKM_sk_set(EVP_PKEY_METHOD, (st), (i), (val))
829#define sk_EVP_PKEY_METHOD_zero(st) SKM_sk_zero(EVP_PKEY_METHOD, (st))
830#define sk_EVP_PKEY_METHOD_push(st, val) SKM_sk_push(EVP_PKEY_METHOD, (st), (val))
831#define sk_EVP_PKEY_METHOD_unshift(st, val) SKM_sk_unshift(EVP_PKEY_METHOD, (st), (val))
832#define sk_EVP_PKEY_METHOD_find(st, val) SKM_sk_find(EVP_PKEY_METHOD, (st), (val))
833#define sk_EVP_PKEY_METHOD_find_ex(st, val) SKM_sk_find_ex(EVP_PKEY_METHOD, (st), (val))
834#define sk_EVP_PKEY_METHOD_delete(st, i) SKM_sk_delete(EVP_PKEY_METHOD, (st), (i))
835#define sk_EVP_PKEY_METHOD_delete_ptr(st, ptr) SKM_sk_delete_ptr(EVP_PKEY_METHOD, (st), (ptr))
836#define sk_EVP_PKEY_METHOD_insert(st, val, i) SKM_sk_insert(EVP_PKEY_METHOD, (st), (val), (i))
837#define sk_EVP_PKEY_METHOD_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(EVP_PKEY_METHOD, (st), (cmp))
838#define sk_EVP_PKEY_METHOD_dup(st) SKM_sk_dup(EVP_PKEY_METHOD, st)
839#define sk_EVP_PKEY_METHOD_pop_free(st, free_func) SKM_sk_pop_free(EVP_PKEY_METHOD, (st), (free_func))
840#define sk_EVP_PKEY_METHOD_shift(st) SKM_sk_shift(EVP_PKEY_METHOD, (st))
841#define sk_EVP_PKEY_METHOD_pop(st) SKM_sk_pop(EVP_PKEY_METHOD, (st))
842#define sk_EVP_PKEY_METHOD_sort(st) SKM_sk_sort(EVP_PKEY_METHOD, (st))
843#define sk_EVP_PKEY_METHOD_is_sorted(st) SKM_sk_is_sorted(EVP_PKEY_METHOD, (st))
844
845#define sk_GENERAL_NAME_new(cmp) SKM_sk_new(GENERAL_NAME, (cmp))
682#define sk_GENERAL_NAME_new_null() SKM_sk_new_null(GENERAL_NAME) 846#define sk_GENERAL_NAME_new_null() SKM_sk_new_null(GENERAL_NAME)
683#define sk_GENERAL_NAME_free(st) SKM_sk_free(GENERAL_NAME, (st)) 847#define sk_GENERAL_NAME_free(st) SKM_sk_free(GENERAL_NAME, (st))
684#define sk_GENERAL_NAME_num(st) SKM_sk_num(GENERAL_NAME, (st)) 848#define sk_GENERAL_NAME_num(st) SKM_sk_num(GENERAL_NAME, (st))
@@ -700,7 +864,7 @@ STACK_OF(type) \
700#define sk_GENERAL_NAME_sort(st) SKM_sk_sort(GENERAL_NAME, (st)) 864#define sk_GENERAL_NAME_sort(st) SKM_sk_sort(GENERAL_NAME, (st))
701#define sk_GENERAL_NAME_is_sorted(st) SKM_sk_is_sorted(GENERAL_NAME, (st)) 865#define sk_GENERAL_NAME_is_sorted(st) SKM_sk_is_sorted(GENERAL_NAME, (st))
702 866
703#define sk_GENERAL_NAMES_new(st) SKM_sk_new(GENERAL_NAMES, (st)) 867#define sk_GENERAL_NAMES_new(cmp) SKM_sk_new(GENERAL_NAMES, (cmp))
704#define sk_GENERAL_NAMES_new_null() SKM_sk_new_null(GENERAL_NAMES) 868#define sk_GENERAL_NAMES_new_null() SKM_sk_new_null(GENERAL_NAMES)
705#define sk_GENERAL_NAMES_free(st) SKM_sk_free(GENERAL_NAMES, (st)) 869#define sk_GENERAL_NAMES_free(st) SKM_sk_free(GENERAL_NAMES, (st))
706#define sk_GENERAL_NAMES_num(st) SKM_sk_num(GENERAL_NAMES, (st)) 870#define sk_GENERAL_NAMES_num(st) SKM_sk_num(GENERAL_NAMES, (st))
@@ -722,7 +886,7 @@ STACK_OF(type) \
722#define sk_GENERAL_NAMES_sort(st) SKM_sk_sort(GENERAL_NAMES, (st)) 886#define sk_GENERAL_NAMES_sort(st) SKM_sk_sort(GENERAL_NAMES, (st))
723#define sk_GENERAL_NAMES_is_sorted(st) SKM_sk_is_sorted(GENERAL_NAMES, (st)) 887#define sk_GENERAL_NAMES_is_sorted(st) SKM_sk_is_sorted(GENERAL_NAMES, (st))
724 888
725#define sk_GENERAL_SUBTREE_new(st) SKM_sk_new(GENERAL_SUBTREE, (st)) 889#define sk_GENERAL_SUBTREE_new(cmp) SKM_sk_new(GENERAL_SUBTREE, (cmp))
726#define sk_GENERAL_SUBTREE_new_null() SKM_sk_new_null(GENERAL_SUBTREE) 890#define sk_GENERAL_SUBTREE_new_null() SKM_sk_new_null(GENERAL_SUBTREE)
727#define sk_GENERAL_SUBTREE_free(st) SKM_sk_free(GENERAL_SUBTREE, (st)) 891#define sk_GENERAL_SUBTREE_free(st) SKM_sk_free(GENERAL_SUBTREE, (st))
728#define sk_GENERAL_SUBTREE_num(st) SKM_sk_num(GENERAL_SUBTREE, (st)) 892#define sk_GENERAL_SUBTREE_num(st) SKM_sk_num(GENERAL_SUBTREE, (st))
@@ -744,7 +908,7 @@ STACK_OF(type) \
744#define sk_GENERAL_SUBTREE_sort(st) SKM_sk_sort(GENERAL_SUBTREE, (st)) 908#define sk_GENERAL_SUBTREE_sort(st) SKM_sk_sort(GENERAL_SUBTREE, (st))
745#define sk_GENERAL_SUBTREE_is_sorted(st) SKM_sk_is_sorted(GENERAL_SUBTREE, (st)) 909#define sk_GENERAL_SUBTREE_is_sorted(st) SKM_sk_is_sorted(GENERAL_SUBTREE, (st))
746 910
747#define sk_IPAddressFamily_new(st) SKM_sk_new(IPAddressFamily, (st)) 911#define sk_IPAddressFamily_new(cmp) SKM_sk_new(IPAddressFamily, (cmp))
748#define sk_IPAddressFamily_new_null() SKM_sk_new_null(IPAddressFamily) 912#define sk_IPAddressFamily_new_null() SKM_sk_new_null(IPAddressFamily)
749#define sk_IPAddressFamily_free(st) SKM_sk_free(IPAddressFamily, (st)) 913#define sk_IPAddressFamily_free(st) SKM_sk_free(IPAddressFamily, (st))
750#define sk_IPAddressFamily_num(st) SKM_sk_num(IPAddressFamily, (st)) 914#define sk_IPAddressFamily_num(st) SKM_sk_num(IPAddressFamily, (st))
@@ -766,7 +930,7 @@ STACK_OF(type) \
766#define sk_IPAddressFamily_sort(st) SKM_sk_sort(IPAddressFamily, (st)) 930#define sk_IPAddressFamily_sort(st) SKM_sk_sort(IPAddressFamily, (st))
767#define sk_IPAddressFamily_is_sorted(st) SKM_sk_is_sorted(IPAddressFamily, (st)) 931#define sk_IPAddressFamily_is_sorted(st) SKM_sk_is_sorted(IPAddressFamily, (st))
768 932
769#define sk_IPAddressOrRange_new(st) SKM_sk_new(IPAddressOrRange, (st)) 933#define sk_IPAddressOrRange_new(cmp) SKM_sk_new(IPAddressOrRange, (cmp))
770#define sk_IPAddressOrRange_new_null() SKM_sk_new_null(IPAddressOrRange) 934#define sk_IPAddressOrRange_new_null() SKM_sk_new_null(IPAddressOrRange)
771#define sk_IPAddressOrRange_free(st) SKM_sk_free(IPAddressOrRange, (st)) 935#define sk_IPAddressOrRange_free(st) SKM_sk_free(IPAddressOrRange, (st))
772#define sk_IPAddressOrRange_num(st) SKM_sk_num(IPAddressOrRange, (st)) 936#define sk_IPAddressOrRange_num(st) SKM_sk_num(IPAddressOrRange, (st))
@@ -788,7 +952,7 @@ STACK_OF(type) \
788#define sk_IPAddressOrRange_sort(st) SKM_sk_sort(IPAddressOrRange, (st)) 952#define sk_IPAddressOrRange_sort(st) SKM_sk_sort(IPAddressOrRange, (st))
789#define sk_IPAddressOrRange_is_sorted(st) SKM_sk_is_sorted(IPAddressOrRange, (st)) 953#define sk_IPAddressOrRange_is_sorted(st) SKM_sk_is_sorted(IPAddressOrRange, (st))
790 954
791#define sk_KRB5_APREQBODY_new(st) SKM_sk_new(KRB5_APREQBODY, (st)) 955#define sk_KRB5_APREQBODY_new(cmp) SKM_sk_new(KRB5_APREQBODY, (cmp))
792#define sk_KRB5_APREQBODY_new_null() SKM_sk_new_null(KRB5_APREQBODY) 956#define sk_KRB5_APREQBODY_new_null() SKM_sk_new_null(KRB5_APREQBODY)
793#define sk_KRB5_APREQBODY_free(st) SKM_sk_free(KRB5_APREQBODY, (st)) 957#define sk_KRB5_APREQBODY_free(st) SKM_sk_free(KRB5_APREQBODY, (st))
794#define sk_KRB5_APREQBODY_num(st) SKM_sk_num(KRB5_APREQBODY, (st)) 958#define sk_KRB5_APREQBODY_num(st) SKM_sk_num(KRB5_APREQBODY, (st))
@@ -810,7 +974,7 @@ STACK_OF(type) \
810#define sk_KRB5_APREQBODY_sort(st) SKM_sk_sort(KRB5_APREQBODY, (st)) 974#define sk_KRB5_APREQBODY_sort(st) SKM_sk_sort(KRB5_APREQBODY, (st))
811#define sk_KRB5_APREQBODY_is_sorted(st) SKM_sk_is_sorted(KRB5_APREQBODY, (st)) 975#define sk_KRB5_APREQBODY_is_sorted(st) SKM_sk_is_sorted(KRB5_APREQBODY, (st))
812 976
813#define sk_KRB5_AUTHDATA_new(st) SKM_sk_new(KRB5_AUTHDATA, (st)) 977#define sk_KRB5_AUTHDATA_new(cmp) SKM_sk_new(KRB5_AUTHDATA, (cmp))
814#define sk_KRB5_AUTHDATA_new_null() SKM_sk_new_null(KRB5_AUTHDATA) 978#define sk_KRB5_AUTHDATA_new_null() SKM_sk_new_null(KRB5_AUTHDATA)
815#define sk_KRB5_AUTHDATA_free(st) SKM_sk_free(KRB5_AUTHDATA, (st)) 979#define sk_KRB5_AUTHDATA_free(st) SKM_sk_free(KRB5_AUTHDATA, (st))
816#define sk_KRB5_AUTHDATA_num(st) SKM_sk_num(KRB5_AUTHDATA, (st)) 980#define sk_KRB5_AUTHDATA_num(st) SKM_sk_num(KRB5_AUTHDATA, (st))
@@ -832,7 +996,7 @@ STACK_OF(type) \
832#define sk_KRB5_AUTHDATA_sort(st) SKM_sk_sort(KRB5_AUTHDATA, (st)) 996#define sk_KRB5_AUTHDATA_sort(st) SKM_sk_sort(KRB5_AUTHDATA, (st))
833#define sk_KRB5_AUTHDATA_is_sorted(st) SKM_sk_is_sorted(KRB5_AUTHDATA, (st)) 997#define sk_KRB5_AUTHDATA_is_sorted(st) SKM_sk_is_sorted(KRB5_AUTHDATA, (st))
834 998
835#define sk_KRB5_AUTHENTBODY_new(st) SKM_sk_new(KRB5_AUTHENTBODY, (st)) 999#define sk_KRB5_AUTHENTBODY_new(cmp) SKM_sk_new(KRB5_AUTHENTBODY, (cmp))
836#define sk_KRB5_AUTHENTBODY_new_null() SKM_sk_new_null(KRB5_AUTHENTBODY) 1000#define sk_KRB5_AUTHENTBODY_new_null() SKM_sk_new_null(KRB5_AUTHENTBODY)
837#define sk_KRB5_AUTHENTBODY_free(st) SKM_sk_free(KRB5_AUTHENTBODY, (st)) 1001#define sk_KRB5_AUTHENTBODY_free(st) SKM_sk_free(KRB5_AUTHENTBODY, (st))
838#define sk_KRB5_AUTHENTBODY_num(st) SKM_sk_num(KRB5_AUTHENTBODY, (st)) 1002#define sk_KRB5_AUTHENTBODY_num(st) SKM_sk_num(KRB5_AUTHENTBODY, (st))
@@ -854,7 +1018,7 @@ STACK_OF(type) \
854#define sk_KRB5_AUTHENTBODY_sort(st) SKM_sk_sort(KRB5_AUTHENTBODY, (st)) 1018#define sk_KRB5_AUTHENTBODY_sort(st) SKM_sk_sort(KRB5_AUTHENTBODY, (st))
855#define sk_KRB5_AUTHENTBODY_is_sorted(st) SKM_sk_is_sorted(KRB5_AUTHENTBODY, (st)) 1019#define sk_KRB5_AUTHENTBODY_is_sorted(st) SKM_sk_is_sorted(KRB5_AUTHENTBODY, (st))
856 1020
857#define sk_KRB5_CHECKSUM_new(st) SKM_sk_new(KRB5_CHECKSUM, (st)) 1021#define sk_KRB5_CHECKSUM_new(cmp) SKM_sk_new(KRB5_CHECKSUM, (cmp))
858#define sk_KRB5_CHECKSUM_new_null() SKM_sk_new_null(KRB5_CHECKSUM) 1022#define sk_KRB5_CHECKSUM_new_null() SKM_sk_new_null(KRB5_CHECKSUM)
859#define sk_KRB5_CHECKSUM_free(st) SKM_sk_free(KRB5_CHECKSUM, (st)) 1023#define sk_KRB5_CHECKSUM_free(st) SKM_sk_free(KRB5_CHECKSUM, (st))
860#define sk_KRB5_CHECKSUM_num(st) SKM_sk_num(KRB5_CHECKSUM, (st)) 1024#define sk_KRB5_CHECKSUM_num(st) SKM_sk_num(KRB5_CHECKSUM, (st))
@@ -876,7 +1040,7 @@ STACK_OF(type) \
876#define sk_KRB5_CHECKSUM_sort(st) SKM_sk_sort(KRB5_CHECKSUM, (st)) 1040#define sk_KRB5_CHECKSUM_sort(st) SKM_sk_sort(KRB5_CHECKSUM, (st))
877#define sk_KRB5_CHECKSUM_is_sorted(st) SKM_sk_is_sorted(KRB5_CHECKSUM, (st)) 1041#define sk_KRB5_CHECKSUM_is_sorted(st) SKM_sk_is_sorted(KRB5_CHECKSUM, (st))
878 1042
879#define sk_KRB5_ENCDATA_new(st) SKM_sk_new(KRB5_ENCDATA, (st)) 1043#define sk_KRB5_ENCDATA_new(cmp) SKM_sk_new(KRB5_ENCDATA, (cmp))
880#define sk_KRB5_ENCDATA_new_null() SKM_sk_new_null(KRB5_ENCDATA) 1044#define sk_KRB5_ENCDATA_new_null() SKM_sk_new_null(KRB5_ENCDATA)
881#define sk_KRB5_ENCDATA_free(st) SKM_sk_free(KRB5_ENCDATA, (st)) 1045#define sk_KRB5_ENCDATA_free(st) SKM_sk_free(KRB5_ENCDATA, (st))
882#define sk_KRB5_ENCDATA_num(st) SKM_sk_num(KRB5_ENCDATA, (st)) 1046#define sk_KRB5_ENCDATA_num(st) SKM_sk_num(KRB5_ENCDATA, (st))
@@ -898,7 +1062,7 @@ STACK_OF(type) \
898#define sk_KRB5_ENCDATA_sort(st) SKM_sk_sort(KRB5_ENCDATA, (st)) 1062#define sk_KRB5_ENCDATA_sort(st) SKM_sk_sort(KRB5_ENCDATA, (st))
899#define sk_KRB5_ENCDATA_is_sorted(st) SKM_sk_is_sorted(KRB5_ENCDATA, (st)) 1063#define sk_KRB5_ENCDATA_is_sorted(st) SKM_sk_is_sorted(KRB5_ENCDATA, (st))
900 1064
901#define sk_KRB5_ENCKEY_new(st) SKM_sk_new(KRB5_ENCKEY, (st)) 1065#define sk_KRB5_ENCKEY_new(cmp) SKM_sk_new(KRB5_ENCKEY, (cmp))
902#define sk_KRB5_ENCKEY_new_null() SKM_sk_new_null(KRB5_ENCKEY) 1066#define sk_KRB5_ENCKEY_new_null() SKM_sk_new_null(KRB5_ENCKEY)
903#define sk_KRB5_ENCKEY_free(st) SKM_sk_free(KRB5_ENCKEY, (st)) 1067#define sk_KRB5_ENCKEY_free(st) SKM_sk_free(KRB5_ENCKEY, (st))
904#define sk_KRB5_ENCKEY_num(st) SKM_sk_num(KRB5_ENCKEY, (st)) 1068#define sk_KRB5_ENCKEY_num(st) SKM_sk_num(KRB5_ENCKEY, (st))
@@ -920,7 +1084,7 @@ STACK_OF(type) \
920#define sk_KRB5_ENCKEY_sort(st) SKM_sk_sort(KRB5_ENCKEY, (st)) 1084#define sk_KRB5_ENCKEY_sort(st) SKM_sk_sort(KRB5_ENCKEY, (st))
921#define sk_KRB5_ENCKEY_is_sorted(st) SKM_sk_is_sorted(KRB5_ENCKEY, (st)) 1085#define sk_KRB5_ENCKEY_is_sorted(st) SKM_sk_is_sorted(KRB5_ENCKEY, (st))
922 1086
923#define sk_KRB5_PRINCNAME_new(st) SKM_sk_new(KRB5_PRINCNAME, (st)) 1087#define sk_KRB5_PRINCNAME_new(cmp) SKM_sk_new(KRB5_PRINCNAME, (cmp))
924#define sk_KRB5_PRINCNAME_new_null() SKM_sk_new_null(KRB5_PRINCNAME) 1088#define sk_KRB5_PRINCNAME_new_null() SKM_sk_new_null(KRB5_PRINCNAME)
925#define sk_KRB5_PRINCNAME_free(st) SKM_sk_free(KRB5_PRINCNAME, (st)) 1089#define sk_KRB5_PRINCNAME_free(st) SKM_sk_free(KRB5_PRINCNAME, (st))
926#define sk_KRB5_PRINCNAME_num(st) SKM_sk_num(KRB5_PRINCNAME, (st)) 1090#define sk_KRB5_PRINCNAME_num(st) SKM_sk_num(KRB5_PRINCNAME, (st))
@@ -942,7 +1106,7 @@ STACK_OF(type) \
942#define sk_KRB5_PRINCNAME_sort(st) SKM_sk_sort(KRB5_PRINCNAME, (st)) 1106#define sk_KRB5_PRINCNAME_sort(st) SKM_sk_sort(KRB5_PRINCNAME, (st))
943#define sk_KRB5_PRINCNAME_is_sorted(st) SKM_sk_is_sorted(KRB5_PRINCNAME, (st)) 1107#define sk_KRB5_PRINCNAME_is_sorted(st) SKM_sk_is_sorted(KRB5_PRINCNAME, (st))
944 1108
945#define sk_KRB5_TKTBODY_new(st) SKM_sk_new(KRB5_TKTBODY, (st)) 1109#define sk_KRB5_TKTBODY_new(cmp) SKM_sk_new(KRB5_TKTBODY, (cmp))
946#define sk_KRB5_TKTBODY_new_null() SKM_sk_new_null(KRB5_TKTBODY) 1110#define sk_KRB5_TKTBODY_new_null() SKM_sk_new_null(KRB5_TKTBODY)
947#define sk_KRB5_TKTBODY_free(st) SKM_sk_free(KRB5_TKTBODY, (st)) 1111#define sk_KRB5_TKTBODY_free(st) SKM_sk_free(KRB5_TKTBODY, (st))
948#define sk_KRB5_TKTBODY_num(st) SKM_sk_num(KRB5_TKTBODY, (st)) 1112#define sk_KRB5_TKTBODY_num(st) SKM_sk_num(KRB5_TKTBODY, (st))
@@ -964,7 +1128,29 @@ STACK_OF(type) \
964#define sk_KRB5_TKTBODY_sort(st) SKM_sk_sort(KRB5_TKTBODY, (st)) 1128#define sk_KRB5_TKTBODY_sort(st) SKM_sk_sort(KRB5_TKTBODY, (st))
965#define sk_KRB5_TKTBODY_is_sorted(st) SKM_sk_is_sorted(KRB5_TKTBODY, (st)) 1129#define sk_KRB5_TKTBODY_is_sorted(st) SKM_sk_is_sorted(KRB5_TKTBODY, (st))
966 1130
967#define sk_MIME_HEADER_new(st) SKM_sk_new(MIME_HEADER, (st)) 1131#define sk_MEM_OBJECT_DATA_new(cmp) SKM_sk_new(MEM_OBJECT_DATA, (cmp))
1132#define sk_MEM_OBJECT_DATA_new_null() SKM_sk_new_null(MEM_OBJECT_DATA)
1133#define sk_MEM_OBJECT_DATA_free(st) SKM_sk_free(MEM_OBJECT_DATA, (st))
1134#define sk_MEM_OBJECT_DATA_num(st) SKM_sk_num(MEM_OBJECT_DATA, (st))
1135#define sk_MEM_OBJECT_DATA_value(st, i) SKM_sk_value(MEM_OBJECT_DATA, (st), (i))
1136#define sk_MEM_OBJECT_DATA_set(st, i, val) SKM_sk_set(MEM_OBJECT_DATA, (st), (i), (val))
1137#define sk_MEM_OBJECT_DATA_zero(st) SKM_sk_zero(MEM_OBJECT_DATA, (st))
1138#define sk_MEM_OBJECT_DATA_push(st, val) SKM_sk_push(MEM_OBJECT_DATA, (st), (val))
1139#define sk_MEM_OBJECT_DATA_unshift(st, val) SKM_sk_unshift(MEM_OBJECT_DATA, (st), (val))
1140#define sk_MEM_OBJECT_DATA_find(st, val) SKM_sk_find(MEM_OBJECT_DATA, (st), (val))
1141#define sk_MEM_OBJECT_DATA_find_ex(st, val) SKM_sk_find_ex(MEM_OBJECT_DATA, (st), (val))
1142#define sk_MEM_OBJECT_DATA_delete(st, i) SKM_sk_delete(MEM_OBJECT_DATA, (st), (i))
1143#define sk_MEM_OBJECT_DATA_delete_ptr(st, ptr) SKM_sk_delete_ptr(MEM_OBJECT_DATA, (st), (ptr))
1144#define sk_MEM_OBJECT_DATA_insert(st, val, i) SKM_sk_insert(MEM_OBJECT_DATA, (st), (val), (i))
1145#define sk_MEM_OBJECT_DATA_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(MEM_OBJECT_DATA, (st), (cmp))
1146#define sk_MEM_OBJECT_DATA_dup(st) SKM_sk_dup(MEM_OBJECT_DATA, st)
1147#define sk_MEM_OBJECT_DATA_pop_free(st, free_func) SKM_sk_pop_free(MEM_OBJECT_DATA, (st), (free_func))
1148#define sk_MEM_OBJECT_DATA_shift(st) SKM_sk_shift(MEM_OBJECT_DATA, (st))
1149#define sk_MEM_OBJECT_DATA_pop(st) SKM_sk_pop(MEM_OBJECT_DATA, (st))
1150#define sk_MEM_OBJECT_DATA_sort(st) SKM_sk_sort(MEM_OBJECT_DATA, (st))
1151#define sk_MEM_OBJECT_DATA_is_sorted(st) SKM_sk_is_sorted(MEM_OBJECT_DATA, (st))
1152
1153#define sk_MIME_HEADER_new(cmp) SKM_sk_new(MIME_HEADER, (cmp))
968#define sk_MIME_HEADER_new_null() SKM_sk_new_null(MIME_HEADER) 1154#define sk_MIME_HEADER_new_null() SKM_sk_new_null(MIME_HEADER)
969#define sk_MIME_HEADER_free(st) SKM_sk_free(MIME_HEADER, (st)) 1155#define sk_MIME_HEADER_free(st) SKM_sk_free(MIME_HEADER, (st))
970#define sk_MIME_HEADER_num(st) SKM_sk_num(MIME_HEADER, (st)) 1156#define sk_MIME_HEADER_num(st) SKM_sk_num(MIME_HEADER, (st))
@@ -986,51 +1172,7 @@ STACK_OF(type) \
986#define sk_MIME_HEADER_sort(st) SKM_sk_sort(MIME_HEADER, (st)) 1172#define sk_MIME_HEADER_sort(st) SKM_sk_sort(MIME_HEADER, (st))
987#define sk_MIME_HEADER_is_sorted(st) SKM_sk_is_sorted(MIME_HEADER, (st)) 1173#define sk_MIME_HEADER_is_sorted(st) SKM_sk_is_sorted(MIME_HEADER, (st))
988 1174
989#define sk_MIME_HEADER_new(st) SKM_sk_new(MIME_HEADER, (st)) 1175#define sk_MIME_PARAM_new(cmp) SKM_sk_new(MIME_PARAM, (cmp))
990#define sk_MIME_HEADER_new_null() SKM_sk_new_null(MIME_HEADER)
991#define sk_MIME_HEADER_free(st) SKM_sk_free(MIME_HEADER, (st))
992#define sk_MIME_HEADER_num(st) SKM_sk_num(MIME_HEADER, (st))
993#define sk_MIME_HEADER_value(st, i) SKM_sk_value(MIME_HEADER, (st), (i))
994#define sk_MIME_HEADER_set(st, i, val) SKM_sk_set(MIME_HEADER, (st), (i), (val))
995#define sk_MIME_HEADER_zero(st) SKM_sk_zero(MIME_HEADER, (st))
996#define sk_MIME_HEADER_push(st, val) SKM_sk_push(MIME_HEADER, (st), (val))
997#define sk_MIME_HEADER_unshift(st, val) SKM_sk_unshift(MIME_HEADER, (st), (val))
998#define sk_MIME_HEADER_find(st, val) SKM_sk_find(MIME_HEADER, (st), (val))
999#define sk_MIME_HEADER_find_ex(st, val) SKM_sk_find_ex(MIME_HEADER, (st), (val))
1000#define sk_MIME_HEADER_delete(st, i) SKM_sk_delete(MIME_HEADER, (st), (i))
1001#define sk_MIME_HEADER_delete_ptr(st, ptr) SKM_sk_delete_ptr(MIME_HEADER, (st), (ptr))
1002#define sk_MIME_HEADER_insert(st, val, i) SKM_sk_insert(MIME_HEADER, (st), (val), (i))
1003#define sk_MIME_HEADER_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(MIME_HEADER, (st), (cmp))
1004#define sk_MIME_HEADER_dup(st) SKM_sk_dup(MIME_HEADER, st)
1005#define sk_MIME_HEADER_pop_free(st, free_func) SKM_sk_pop_free(MIME_HEADER, (st), (free_func))
1006#define sk_MIME_HEADER_shift(st) SKM_sk_shift(MIME_HEADER, (st))
1007#define sk_MIME_HEADER_pop(st) SKM_sk_pop(MIME_HEADER, (st))
1008#define sk_MIME_HEADER_sort(st) SKM_sk_sort(MIME_HEADER, (st))
1009#define sk_MIME_HEADER_is_sorted(st) SKM_sk_is_sorted(MIME_HEADER, (st))
1010
1011#define sk_MIME_PARAM_new(st) SKM_sk_new(MIME_PARAM, (st))
1012#define sk_MIME_PARAM_new_null() SKM_sk_new_null(MIME_PARAM)
1013#define sk_MIME_PARAM_free(st) SKM_sk_free(MIME_PARAM, (st))
1014#define sk_MIME_PARAM_num(st) SKM_sk_num(MIME_PARAM, (st))
1015#define sk_MIME_PARAM_value(st, i) SKM_sk_value(MIME_PARAM, (st), (i))
1016#define sk_MIME_PARAM_set(st, i, val) SKM_sk_set(MIME_PARAM, (st), (i), (val))
1017#define sk_MIME_PARAM_zero(st) SKM_sk_zero(MIME_PARAM, (st))
1018#define sk_MIME_PARAM_push(st, val) SKM_sk_push(MIME_PARAM, (st), (val))
1019#define sk_MIME_PARAM_unshift(st, val) SKM_sk_unshift(MIME_PARAM, (st), (val))
1020#define sk_MIME_PARAM_find(st, val) SKM_sk_find(MIME_PARAM, (st), (val))
1021#define sk_MIME_PARAM_find_ex(st, val) SKM_sk_find_ex(MIME_PARAM, (st), (val))
1022#define sk_MIME_PARAM_delete(st, i) SKM_sk_delete(MIME_PARAM, (st), (i))
1023#define sk_MIME_PARAM_delete_ptr(st, ptr) SKM_sk_delete_ptr(MIME_PARAM, (st), (ptr))
1024#define sk_MIME_PARAM_insert(st, val, i) SKM_sk_insert(MIME_PARAM, (st), (val), (i))
1025#define sk_MIME_PARAM_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(MIME_PARAM, (st), (cmp))
1026#define sk_MIME_PARAM_dup(st) SKM_sk_dup(MIME_PARAM, st)
1027#define sk_MIME_PARAM_pop_free(st, free_func) SKM_sk_pop_free(MIME_PARAM, (st), (free_func))
1028#define sk_MIME_PARAM_shift(st) SKM_sk_shift(MIME_PARAM, (st))
1029#define sk_MIME_PARAM_pop(st) SKM_sk_pop(MIME_PARAM, (st))
1030#define sk_MIME_PARAM_sort(st) SKM_sk_sort(MIME_PARAM, (st))
1031#define sk_MIME_PARAM_is_sorted(st) SKM_sk_is_sorted(MIME_PARAM, (st))
1032
1033#define sk_MIME_PARAM_new(st) SKM_sk_new(MIME_PARAM, (st))
1034#define sk_MIME_PARAM_new_null() SKM_sk_new_null(MIME_PARAM) 1176#define sk_MIME_PARAM_new_null() SKM_sk_new_null(MIME_PARAM)
1035#define sk_MIME_PARAM_free(st) SKM_sk_free(MIME_PARAM, (st)) 1177#define sk_MIME_PARAM_free(st) SKM_sk_free(MIME_PARAM, (st))
1036#define sk_MIME_PARAM_num(st) SKM_sk_num(MIME_PARAM, (st)) 1178#define sk_MIME_PARAM_num(st) SKM_sk_num(MIME_PARAM, (st))
@@ -1052,7 +1194,7 @@ STACK_OF(type) \
1052#define sk_MIME_PARAM_sort(st) SKM_sk_sort(MIME_PARAM, (st)) 1194#define sk_MIME_PARAM_sort(st) SKM_sk_sort(MIME_PARAM, (st))
1053#define sk_MIME_PARAM_is_sorted(st) SKM_sk_is_sorted(MIME_PARAM, (st)) 1195#define sk_MIME_PARAM_is_sorted(st) SKM_sk_is_sorted(MIME_PARAM, (st))
1054 1196
1055#define sk_NAME_FUNCS_new(st) SKM_sk_new(NAME_FUNCS, (st)) 1197#define sk_NAME_FUNCS_new(cmp) SKM_sk_new(NAME_FUNCS, (cmp))
1056#define sk_NAME_FUNCS_new_null() SKM_sk_new_null(NAME_FUNCS) 1198#define sk_NAME_FUNCS_new_null() SKM_sk_new_null(NAME_FUNCS)
1057#define sk_NAME_FUNCS_free(st) SKM_sk_free(NAME_FUNCS, (st)) 1199#define sk_NAME_FUNCS_free(st) SKM_sk_free(NAME_FUNCS, (st))
1058#define sk_NAME_FUNCS_num(st) SKM_sk_num(NAME_FUNCS, (st)) 1200#define sk_NAME_FUNCS_num(st) SKM_sk_num(NAME_FUNCS, (st))
@@ -1074,7 +1216,7 @@ STACK_OF(type) \
1074#define sk_NAME_FUNCS_sort(st) SKM_sk_sort(NAME_FUNCS, (st)) 1216#define sk_NAME_FUNCS_sort(st) SKM_sk_sort(NAME_FUNCS, (st))
1075#define sk_NAME_FUNCS_is_sorted(st) SKM_sk_is_sorted(NAME_FUNCS, (st)) 1217#define sk_NAME_FUNCS_is_sorted(st) SKM_sk_is_sorted(NAME_FUNCS, (st))
1076 1218
1077#define sk_OCSP_CERTID_new(st) SKM_sk_new(OCSP_CERTID, (st)) 1219#define sk_OCSP_CERTID_new(cmp) SKM_sk_new(OCSP_CERTID, (cmp))
1078#define sk_OCSP_CERTID_new_null() SKM_sk_new_null(OCSP_CERTID) 1220#define sk_OCSP_CERTID_new_null() SKM_sk_new_null(OCSP_CERTID)
1079#define sk_OCSP_CERTID_free(st) SKM_sk_free(OCSP_CERTID, (st)) 1221#define sk_OCSP_CERTID_free(st) SKM_sk_free(OCSP_CERTID, (st))
1080#define sk_OCSP_CERTID_num(st) SKM_sk_num(OCSP_CERTID, (st)) 1222#define sk_OCSP_CERTID_num(st) SKM_sk_num(OCSP_CERTID, (st))
@@ -1096,7 +1238,7 @@ STACK_OF(type) \
1096#define sk_OCSP_CERTID_sort(st) SKM_sk_sort(OCSP_CERTID, (st)) 1238#define sk_OCSP_CERTID_sort(st) SKM_sk_sort(OCSP_CERTID, (st))
1097#define sk_OCSP_CERTID_is_sorted(st) SKM_sk_is_sorted(OCSP_CERTID, (st)) 1239#define sk_OCSP_CERTID_is_sorted(st) SKM_sk_is_sorted(OCSP_CERTID, (st))
1098 1240
1099#define sk_OCSP_ONEREQ_new(st) SKM_sk_new(OCSP_ONEREQ, (st)) 1241#define sk_OCSP_ONEREQ_new(cmp) SKM_sk_new(OCSP_ONEREQ, (cmp))
1100#define sk_OCSP_ONEREQ_new_null() SKM_sk_new_null(OCSP_ONEREQ) 1242#define sk_OCSP_ONEREQ_new_null() SKM_sk_new_null(OCSP_ONEREQ)
1101#define sk_OCSP_ONEREQ_free(st) SKM_sk_free(OCSP_ONEREQ, (st)) 1243#define sk_OCSP_ONEREQ_free(st) SKM_sk_free(OCSP_ONEREQ, (st))
1102#define sk_OCSP_ONEREQ_num(st) SKM_sk_num(OCSP_ONEREQ, (st)) 1244#define sk_OCSP_ONEREQ_num(st) SKM_sk_num(OCSP_ONEREQ, (st))
@@ -1118,7 +1260,7 @@ STACK_OF(type) \
1118#define sk_OCSP_ONEREQ_sort(st) SKM_sk_sort(OCSP_ONEREQ, (st)) 1260#define sk_OCSP_ONEREQ_sort(st) SKM_sk_sort(OCSP_ONEREQ, (st))
1119#define sk_OCSP_ONEREQ_is_sorted(st) SKM_sk_is_sorted(OCSP_ONEREQ, (st)) 1261#define sk_OCSP_ONEREQ_is_sorted(st) SKM_sk_is_sorted(OCSP_ONEREQ, (st))
1120 1262
1121#define sk_OCSP_RESPID_new(st) SKM_sk_new(OCSP_RESPID, (st)) 1263#define sk_OCSP_RESPID_new(cmp) SKM_sk_new(OCSP_RESPID, (cmp))
1122#define sk_OCSP_RESPID_new_null() SKM_sk_new_null(OCSP_RESPID) 1264#define sk_OCSP_RESPID_new_null() SKM_sk_new_null(OCSP_RESPID)
1123#define sk_OCSP_RESPID_free(st) SKM_sk_free(OCSP_RESPID, (st)) 1265#define sk_OCSP_RESPID_free(st) SKM_sk_free(OCSP_RESPID, (st))
1124#define sk_OCSP_RESPID_num(st) SKM_sk_num(OCSP_RESPID, (st)) 1266#define sk_OCSP_RESPID_num(st) SKM_sk_num(OCSP_RESPID, (st))
@@ -1140,7 +1282,7 @@ STACK_OF(type) \
1140#define sk_OCSP_RESPID_sort(st) SKM_sk_sort(OCSP_RESPID, (st)) 1282#define sk_OCSP_RESPID_sort(st) SKM_sk_sort(OCSP_RESPID, (st))
1141#define sk_OCSP_RESPID_is_sorted(st) SKM_sk_is_sorted(OCSP_RESPID, (st)) 1283#define sk_OCSP_RESPID_is_sorted(st) SKM_sk_is_sorted(OCSP_RESPID, (st))
1142 1284
1143#define sk_OCSP_SINGLERESP_new(st) SKM_sk_new(OCSP_SINGLERESP, (st)) 1285#define sk_OCSP_SINGLERESP_new(cmp) SKM_sk_new(OCSP_SINGLERESP, (cmp))
1144#define sk_OCSP_SINGLERESP_new_null() SKM_sk_new_null(OCSP_SINGLERESP) 1286#define sk_OCSP_SINGLERESP_new_null() SKM_sk_new_null(OCSP_SINGLERESP)
1145#define sk_OCSP_SINGLERESP_free(st) SKM_sk_free(OCSP_SINGLERESP, (st)) 1287#define sk_OCSP_SINGLERESP_free(st) SKM_sk_free(OCSP_SINGLERESP, (st))
1146#define sk_OCSP_SINGLERESP_num(st) SKM_sk_num(OCSP_SINGLERESP, (st)) 1288#define sk_OCSP_SINGLERESP_num(st) SKM_sk_num(OCSP_SINGLERESP, (st))
@@ -1162,7 +1304,7 @@ STACK_OF(type) \
1162#define sk_OCSP_SINGLERESP_sort(st) SKM_sk_sort(OCSP_SINGLERESP, (st)) 1304#define sk_OCSP_SINGLERESP_sort(st) SKM_sk_sort(OCSP_SINGLERESP, (st))
1163#define sk_OCSP_SINGLERESP_is_sorted(st) SKM_sk_is_sorted(OCSP_SINGLERESP, (st)) 1305#define sk_OCSP_SINGLERESP_is_sorted(st) SKM_sk_is_sorted(OCSP_SINGLERESP, (st))
1164 1306
1165#define sk_PKCS12_SAFEBAG_new(st) SKM_sk_new(PKCS12_SAFEBAG, (st)) 1307#define sk_PKCS12_SAFEBAG_new(cmp) SKM_sk_new(PKCS12_SAFEBAG, (cmp))
1166#define sk_PKCS12_SAFEBAG_new_null() SKM_sk_new_null(PKCS12_SAFEBAG) 1308#define sk_PKCS12_SAFEBAG_new_null() SKM_sk_new_null(PKCS12_SAFEBAG)
1167#define sk_PKCS12_SAFEBAG_free(st) SKM_sk_free(PKCS12_SAFEBAG, (st)) 1309#define sk_PKCS12_SAFEBAG_free(st) SKM_sk_free(PKCS12_SAFEBAG, (st))
1168#define sk_PKCS12_SAFEBAG_num(st) SKM_sk_num(PKCS12_SAFEBAG, (st)) 1310#define sk_PKCS12_SAFEBAG_num(st) SKM_sk_num(PKCS12_SAFEBAG, (st))
@@ -1184,7 +1326,7 @@ STACK_OF(type) \
1184#define sk_PKCS12_SAFEBAG_sort(st) SKM_sk_sort(PKCS12_SAFEBAG, (st)) 1326#define sk_PKCS12_SAFEBAG_sort(st) SKM_sk_sort(PKCS12_SAFEBAG, (st))
1185#define sk_PKCS12_SAFEBAG_is_sorted(st) SKM_sk_is_sorted(PKCS12_SAFEBAG, (st)) 1327#define sk_PKCS12_SAFEBAG_is_sorted(st) SKM_sk_is_sorted(PKCS12_SAFEBAG, (st))
1186 1328
1187#define sk_PKCS7_new(st) SKM_sk_new(PKCS7, (st)) 1329#define sk_PKCS7_new(cmp) SKM_sk_new(PKCS7, (cmp))
1188#define sk_PKCS7_new_null() SKM_sk_new_null(PKCS7) 1330#define sk_PKCS7_new_null() SKM_sk_new_null(PKCS7)
1189#define sk_PKCS7_free(st) SKM_sk_free(PKCS7, (st)) 1331#define sk_PKCS7_free(st) SKM_sk_free(PKCS7, (st))
1190#define sk_PKCS7_num(st) SKM_sk_num(PKCS7, (st)) 1332#define sk_PKCS7_num(st) SKM_sk_num(PKCS7, (st))
@@ -1206,7 +1348,7 @@ STACK_OF(type) \
1206#define sk_PKCS7_sort(st) SKM_sk_sort(PKCS7, (st)) 1348#define sk_PKCS7_sort(st) SKM_sk_sort(PKCS7, (st))
1207#define sk_PKCS7_is_sorted(st) SKM_sk_is_sorted(PKCS7, (st)) 1349#define sk_PKCS7_is_sorted(st) SKM_sk_is_sorted(PKCS7, (st))
1208 1350
1209#define sk_PKCS7_RECIP_INFO_new(st) SKM_sk_new(PKCS7_RECIP_INFO, (st)) 1351#define sk_PKCS7_RECIP_INFO_new(cmp) SKM_sk_new(PKCS7_RECIP_INFO, (cmp))
1210#define sk_PKCS7_RECIP_INFO_new_null() SKM_sk_new_null(PKCS7_RECIP_INFO) 1352#define sk_PKCS7_RECIP_INFO_new_null() SKM_sk_new_null(PKCS7_RECIP_INFO)
1211#define sk_PKCS7_RECIP_INFO_free(st) SKM_sk_free(PKCS7_RECIP_INFO, (st)) 1353#define sk_PKCS7_RECIP_INFO_free(st) SKM_sk_free(PKCS7_RECIP_INFO, (st))
1212#define sk_PKCS7_RECIP_INFO_num(st) SKM_sk_num(PKCS7_RECIP_INFO, (st)) 1354#define sk_PKCS7_RECIP_INFO_num(st) SKM_sk_num(PKCS7_RECIP_INFO, (st))
@@ -1228,7 +1370,7 @@ STACK_OF(type) \
1228#define sk_PKCS7_RECIP_INFO_sort(st) SKM_sk_sort(PKCS7_RECIP_INFO, (st)) 1370#define sk_PKCS7_RECIP_INFO_sort(st) SKM_sk_sort(PKCS7_RECIP_INFO, (st))
1229#define sk_PKCS7_RECIP_INFO_is_sorted(st) SKM_sk_is_sorted(PKCS7_RECIP_INFO, (st)) 1371#define sk_PKCS7_RECIP_INFO_is_sorted(st) SKM_sk_is_sorted(PKCS7_RECIP_INFO, (st))
1230 1372
1231#define sk_PKCS7_SIGNER_INFO_new(st) SKM_sk_new(PKCS7_SIGNER_INFO, (st)) 1373#define sk_PKCS7_SIGNER_INFO_new(cmp) SKM_sk_new(PKCS7_SIGNER_INFO, (cmp))
1232#define sk_PKCS7_SIGNER_INFO_new_null() SKM_sk_new_null(PKCS7_SIGNER_INFO) 1374#define sk_PKCS7_SIGNER_INFO_new_null() SKM_sk_new_null(PKCS7_SIGNER_INFO)
1233#define sk_PKCS7_SIGNER_INFO_free(st) SKM_sk_free(PKCS7_SIGNER_INFO, (st)) 1375#define sk_PKCS7_SIGNER_INFO_free(st) SKM_sk_free(PKCS7_SIGNER_INFO, (st))
1234#define sk_PKCS7_SIGNER_INFO_num(st) SKM_sk_num(PKCS7_SIGNER_INFO, (st)) 1376#define sk_PKCS7_SIGNER_INFO_num(st) SKM_sk_num(PKCS7_SIGNER_INFO, (st))
@@ -1250,7 +1392,7 @@ STACK_OF(type) \
1250#define sk_PKCS7_SIGNER_INFO_sort(st) SKM_sk_sort(PKCS7_SIGNER_INFO, (st)) 1392#define sk_PKCS7_SIGNER_INFO_sort(st) SKM_sk_sort(PKCS7_SIGNER_INFO, (st))
1251#define sk_PKCS7_SIGNER_INFO_is_sorted(st) SKM_sk_is_sorted(PKCS7_SIGNER_INFO, (st)) 1393#define sk_PKCS7_SIGNER_INFO_is_sorted(st) SKM_sk_is_sorted(PKCS7_SIGNER_INFO, (st))
1252 1394
1253#define sk_POLICYINFO_new(st) SKM_sk_new(POLICYINFO, (st)) 1395#define sk_POLICYINFO_new(cmp) SKM_sk_new(POLICYINFO, (cmp))
1254#define sk_POLICYINFO_new_null() SKM_sk_new_null(POLICYINFO) 1396#define sk_POLICYINFO_new_null() SKM_sk_new_null(POLICYINFO)
1255#define sk_POLICYINFO_free(st) SKM_sk_free(POLICYINFO, (st)) 1397#define sk_POLICYINFO_free(st) SKM_sk_free(POLICYINFO, (st))
1256#define sk_POLICYINFO_num(st) SKM_sk_num(POLICYINFO, (st)) 1398#define sk_POLICYINFO_num(st) SKM_sk_num(POLICYINFO, (st))
@@ -1272,7 +1414,7 @@ STACK_OF(type) \
1272#define sk_POLICYINFO_sort(st) SKM_sk_sort(POLICYINFO, (st)) 1414#define sk_POLICYINFO_sort(st) SKM_sk_sort(POLICYINFO, (st))
1273#define sk_POLICYINFO_is_sorted(st) SKM_sk_is_sorted(POLICYINFO, (st)) 1415#define sk_POLICYINFO_is_sorted(st) SKM_sk_is_sorted(POLICYINFO, (st))
1274 1416
1275#define sk_POLICYQUALINFO_new(st) SKM_sk_new(POLICYQUALINFO, (st)) 1417#define sk_POLICYQUALINFO_new(cmp) SKM_sk_new(POLICYQUALINFO, (cmp))
1276#define sk_POLICYQUALINFO_new_null() SKM_sk_new_null(POLICYQUALINFO) 1418#define sk_POLICYQUALINFO_new_null() SKM_sk_new_null(POLICYQUALINFO)
1277#define sk_POLICYQUALINFO_free(st) SKM_sk_free(POLICYQUALINFO, (st)) 1419#define sk_POLICYQUALINFO_free(st) SKM_sk_free(POLICYQUALINFO, (st))
1278#define sk_POLICYQUALINFO_num(st) SKM_sk_num(POLICYQUALINFO, (st)) 1420#define sk_POLICYQUALINFO_num(st) SKM_sk_num(POLICYQUALINFO, (st))
@@ -1294,7 +1436,7 @@ STACK_OF(type) \
1294#define sk_POLICYQUALINFO_sort(st) SKM_sk_sort(POLICYQUALINFO, (st)) 1436#define sk_POLICYQUALINFO_sort(st) SKM_sk_sort(POLICYQUALINFO, (st))
1295#define sk_POLICYQUALINFO_is_sorted(st) SKM_sk_is_sorted(POLICYQUALINFO, (st)) 1437#define sk_POLICYQUALINFO_is_sorted(st) SKM_sk_is_sorted(POLICYQUALINFO, (st))
1296 1438
1297#define sk_POLICY_MAPPING_new(st) SKM_sk_new(POLICY_MAPPING, (st)) 1439#define sk_POLICY_MAPPING_new(cmp) SKM_sk_new(POLICY_MAPPING, (cmp))
1298#define sk_POLICY_MAPPING_new_null() SKM_sk_new_null(POLICY_MAPPING) 1440#define sk_POLICY_MAPPING_new_null() SKM_sk_new_null(POLICY_MAPPING)
1299#define sk_POLICY_MAPPING_free(st) SKM_sk_free(POLICY_MAPPING, (st)) 1441#define sk_POLICY_MAPPING_free(st) SKM_sk_free(POLICY_MAPPING, (st))
1300#define sk_POLICY_MAPPING_num(st) SKM_sk_num(POLICY_MAPPING, (st)) 1442#define sk_POLICY_MAPPING_num(st) SKM_sk_num(POLICY_MAPPING, (st))
@@ -1316,7 +1458,7 @@ STACK_OF(type) \
1316#define sk_POLICY_MAPPING_sort(st) SKM_sk_sort(POLICY_MAPPING, (st)) 1458#define sk_POLICY_MAPPING_sort(st) SKM_sk_sort(POLICY_MAPPING, (st))
1317#define sk_POLICY_MAPPING_is_sorted(st) SKM_sk_is_sorted(POLICY_MAPPING, (st)) 1459#define sk_POLICY_MAPPING_is_sorted(st) SKM_sk_is_sorted(POLICY_MAPPING, (st))
1318 1460
1319#define sk_SSL_CIPHER_new(st) SKM_sk_new(SSL_CIPHER, (st)) 1461#define sk_SSL_CIPHER_new(cmp) SKM_sk_new(SSL_CIPHER, (cmp))
1320#define sk_SSL_CIPHER_new_null() SKM_sk_new_null(SSL_CIPHER) 1462#define sk_SSL_CIPHER_new_null() SKM_sk_new_null(SSL_CIPHER)
1321#define sk_SSL_CIPHER_free(st) SKM_sk_free(SSL_CIPHER, (st)) 1463#define sk_SSL_CIPHER_free(st) SKM_sk_free(SSL_CIPHER, (st))
1322#define sk_SSL_CIPHER_num(st) SKM_sk_num(SSL_CIPHER, (st)) 1464#define sk_SSL_CIPHER_num(st) SKM_sk_num(SSL_CIPHER, (st))
@@ -1338,7 +1480,7 @@ STACK_OF(type) \
1338#define sk_SSL_CIPHER_sort(st) SKM_sk_sort(SSL_CIPHER, (st)) 1480#define sk_SSL_CIPHER_sort(st) SKM_sk_sort(SSL_CIPHER, (st))
1339#define sk_SSL_CIPHER_is_sorted(st) SKM_sk_is_sorted(SSL_CIPHER, (st)) 1481#define sk_SSL_CIPHER_is_sorted(st) SKM_sk_is_sorted(SSL_CIPHER, (st))
1340 1482
1341#define sk_SSL_COMP_new(st) SKM_sk_new(SSL_COMP, (st)) 1483#define sk_SSL_COMP_new(cmp) SKM_sk_new(SSL_COMP, (cmp))
1342#define sk_SSL_COMP_new_null() SKM_sk_new_null(SSL_COMP) 1484#define sk_SSL_COMP_new_null() SKM_sk_new_null(SSL_COMP)
1343#define sk_SSL_COMP_free(st) SKM_sk_free(SSL_COMP, (st)) 1485#define sk_SSL_COMP_free(st) SKM_sk_free(SSL_COMP, (st))
1344#define sk_SSL_COMP_num(st) SKM_sk_num(SSL_COMP, (st)) 1486#define sk_SSL_COMP_num(st) SKM_sk_num(SSL_COMP, (st))
@@ -1360,7 +1502,51 @@ STACK_OF(type) \
1360#define sk_SSL_COMP_sort(st) SKM_sk_sort(SSL_COMP, (st)) 1502#define sk_SSL_COMP_sort(st) SKM_sk_sort(SSL_COMP, (st))
1361#define sk_SSL_COMP_is_sorted(st) SKM_sk_is_sorted(SSL_COMP, (st)) 1503#define sk_SSL_COMP_is_sorted(st) SKM_sk_is_sorted(SSL_COMP, (st))
1362 1504
1363#define sk_STORE_OBJECT_new(st) SKM_sk_new(STORE_OBJECT, (st)) 1505#define sk_STACK_OF_X509_NAME_ENTRY_new(cmp) SKM_sk_new(STACK_OF_X509_NAME_ENTRY, (cmp))
1506#define sk_STACK_OF_X509_NAME_ENTRY_new_null() SKM_sk_new_null(STACK_OF_X509_NAME_ENTRY)
1507#define sk_STACK_OF_X509_NAME_ENTRY_free(st) SKM_sk_free(STACK_OF_X509_NAME_ENTRY, (st))
1508#define sk_STACK_OF_X509_NAME_ENTRY_num(st) SKM_sk_num(STACK_OF_X509_NAME_ENTRY, (st))
1509#define sk_STACK_OF_X509_NAME_ENTRY_value(st, i) SKM_sk_value(STACK_OF_X509_NAME_ENTRY, (st), (i))
1510#define sk_STACK_OF_X509_NAME_ENTRY_set(st, i, val) SKM_sk_set(STACK_OF_X509_NAME_ENTRY, (st), (i), (val))
1511#define sk_STACK_OF_X509_NAME_ENTRY_zero(st) SKM_sk_zero(STACK_OF_X509_NAME_ENTRY, (st))
1512#define sk_STACK_OF_X509_NAME_ENTRY_push(st, val) SKM_sk_push(STACK_OF_X509_NAME_ENTRY, (st), (val))
1513#define sk_STACK_OF_X509_NAME_ENTRY_unshift(st, val) SKM_sk_unshift(STACK_OF_X509_NAME_ENTRY, (st), (val))
1514#define sk_STACK_OF_X509_NAME_ENTRY_find(st, val) SKM_sk_find(STACK_OF_X509_NAME_ENTRY, (st), (val))
1515#define sk_STACK_OF_X509_NAME_ENTRY_find_ex(st, val) SKM_sk_find_ex(STACK_OF_X509_NAME_ENTRY, (st), (val))
1516#define sk_STACK_OF_X509_NAME_ENTRY_delete(st, i) SKM_sk_delete(STACK_OF_X509_NAME_ENTRY, (st), (i))
1517#define sk_STACK_OF_X509_NAME_ENTRY_delete_ptr(st, ptr) SKM_sk_delete_ptr(STACK_OF_X509_NAME_ENTRY, (st), (ptr))
1518#define sk_STACK_OF_X509_NAME_ENTRY_insert(st, val, i) SKM_sk_insert(STACK_OF_X509_NAME_ENTRY, (st), (val), (i))
1519#define sk_STACK_OF_X509_NAME_ENTRY_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(STACK_OF_X509_NAME_ENTRY, (st), (cmp))
1520#define sk_STACK_OF_X509_NAME_ENTRY_dup(st) SKM_sk_dup(STACK_OF_X509_NAME_ENTRY, st)
1521#define sk_STACK_OF_X509_NAME_ENTRY_pop_free(st, free_func) SKM_sk_pop_free(STACK_OF_X509_NAME_ENTRY, (st), (free_func))
1522#define sk_STACK_OF_X509_NAME_ENTRY_shift(st) SKM_sk_shift(STACK_OF_X509_NAME_ENTRY, (st))
1523#define sk_STACK_OF_X509_NAME_ENTRY_pop(st) SKM_sk_pop(STACK_OF_X509_NAME_ENTRY, (st))
1524#define sk_STACK_OF_X509_NAME_ENTRY_sort(st) SKM_sk_sort(STACK_OF_X509_NAME_ENTRY, (st))
1525#define sk_STACK_OF_X509_NAME_ENTRY_is_sorted(st) SKM_sk_is_sorted(STACK_OF_X509_NAME_ENTRY, (st))
1526
1527#define sk_STORE_ATTR_INFO_new(cmp) SKM_sk_new(STORE_ATTR_INFO, (cmp))
1528#define sk_STORE_ATTR_INFO_new_null() SKM_sk_new_null(STORE_ATTR_INFO)
1529#define sk_STORE_ATTR_INFO_free(st) SKM_sk_free(STORE_ATTR_INFO, (st))
1530#define sk_STORE_ATTR_INFO_num(st) SKM_sk_num(STORE_ATTR_INFO, (st))
1531#define sk_STORE_ATTR_INFO_value(st, i) SKM_sk_value(STORE_ATTR_INFO, (st), (i))
1532#define sk_STORE_ATTR_INFO_set(st, i, val) SKM_sk_set(STORE_ATTR_INFO, (st), (i), (val))
1533#define sk_STORE_ATTR_INFO_zero(st) SKM_sk_zero(STORE_ATTR_INFO, (st))
1534#define sk_STORE_ATTR_INFO_push(st, val) SKM_sk_push(STORE_ATTR_INFO, (st), (val))
1535#define sk_STORE_ATTR_INFO_unshift(st, val) SKM_sk_unshift(STORE_ATTR_INFO, (st), (val))
1536#define sk_STORE_ATTR_INFO_find(st, val) SKM_sk_find(STORE_ATTR_INFO, (st), (val))
1537#define sk_STORE_ATTR_INFO_find_ex(st, val) SKM_sk_find_ex(STORE_ATTR_INFO, (st), (val))
1538#define sk_STORE_ATTR_INFO_delete(st, i) SKM_sk_delete(STORE_ATTR_INFO, (st), (i))
1539#define sk_STORE_ATTR_INFO_delete_ptr(st, ptr) SKM_sk_delete_ptr(STORE_ATTR_INFO, (st), (ptr))
1540#define sk_STORE_ATTR_INFO_insert(st, val, i) SKM_sk_insert(STORE_ATTR_INFO, (st), (val), (i))
1541#define sk_STORE_ATTR_INFO_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(STORE_ATTR_INFO, (st), (cmp))
1542#define sk_STORE_ATTR_INFO_dup(st) SKM_sk_dup(STORE_ATTR_INFO, st)
1543#define sk_STORE_ATTR_INFO_pop_free(st, free_func) SKM_sk_pop_free(STORE_ATTR_INFO, (st), (free_func))
1544#define sk_STORE_ATTR_INFO_shift(st) SKM_sk_shift(STORE_ATTR_INFO, (st))
1545#define sk_STORE_ATTR_INFO_pop(st) SKM_sk_pop(STORE_ATTR_INFO, (st))
1546#define sk_STORE_ATTR_INFO_sort(st) SKM_sk_sort(STORE_ATTR_INFO, (st))
1547#define sk_STORE_ATTR_INFO_is_sorted(st) SKM_sk_is_sorted(STORE_ATTR_INFO, (st))
1548
1549#define sk_STORE_OBJECT_new(cmp) SKM_sk_new(STORE_OBJECT, (cmp))
1364#define sk_STORE_OBJECT_new_null() SKM_sk_new_null(STORE_OBJECT) 1550#define sk_STORE_OBJECT_new_null() SKM_sk_new_null(STORE_OBJECT)
1365#define sk_STORE_OBJECT_free(st) SKM_sk_free(STORE_OBJECT, (st)) 1551#define sk_STORE_OBJECT_free(st) SKM_sk_free(STORE_OBJECT, (st))
1366#define sk_STORE_OBJECT_num(st) SKM_sk_num(STORE_OBJECT, (st)) 1552#define sk_STORE_OBJECT_num(st) SKM_sk_num(STORE_OBJECT, (st))
@@ -1382,7 +1568,7 @@ STACK_OF(type) \
1382#define sk_STORE_OBJECT_sort(st) SKM_sk_sort(STORE_OBJECT, (st)) 1568#define sk_STORE_OBJECT_sort(st) SKM_sk_sort(STORE_OBJECT, (st))
1383#define sk_STORE_OBJECT_is_sorted(st) SKM_sk_is_sorted(STORE_OBJECT, (st)) 1569#define sk_STORE_OBJECT_is_sorted(st) SKM_sk_is_sorted(STORE_OBJECT, (st))
1384 1570
1385#define sk_SXNETID_new(st) SKM_sk_new(SXNETID, (st)) 1571#define sk_SXNETID_new(cmp) SKM_sk_new(SXNETID, (cmp))
1386#define sk_SXNETID_new_null() SKM_sk_new_null(SXNETID) 1572#define sk_SXNETID_new_null() SKM_sk_new_null(SXNETID)
1387#define sk_SXNETID_free(st) SKM_sk_free(SXNETID, (st)) 1573#define sk_SXNETID_free(st) SKM_sk_free(SXNETID, (st))
1388#define sk_SXNETID_num(st) SKM_sk_num(SXNETID, (st)) 1574#define sk_SXNETID_num(st) SKM_sk_num(SXNETID, (st))
@@ -1404,7 +1590,7 @@ STACK_OF(type) \
1404#define sk_SXNETID_sort(st) SKM_sk_sort(SXNETID, (st)) 1590#define sk_SXNETID_sort(st) SKM_sk_sort(SXNETID, (st))
1405#define sk_SXNETID_is_sorted(st) SKM_sk_is_sorted(SXNETID, (st)) 1591#define sk_SXNETID_is_sorted(st) SKM_sk_is_sorted(SXNETID, (st))
1406 1592
1407#define sk_UI_STRING_new(st) SKM_sk_new(UI_STRING, (st)) 1593#define sk_UI_STRING_new(cmp) SKM_sk_new(UI_STRING, (cmp))
1408#define sk_UI_STRING_new_null() SKM_sk_new_null(UI_STRING) 1594#define sk_UI_STRING_new_null() SKM_sk_new_null(UI_STRING)
1409#define sk_UI_STRING_free(st) SKM_sk_free(UI_STRING, (st)) 1595#define sk_UI_STRING_free(st) SKM_sk_free(UI_STRING, (st))
1410#define sk_UI_STRING_num(st) SKM_sk_num(UI_STRING, (st)) 1596#define sk_UI_STRING_num(st) SKM_sk_num(UI_STRING, (st))
@@ -1426,7 +1612,7 @@ STACK_OF(type) \
1426#define sk_UI_STRING_sort(st) SKM_sk_sort(UI_STRING, (st)) 1612#define sk_UI_STRING_sort(st) SKM_sk_sort(UI_STRING, (st))
1427#define sk_UI_STRING_is_sorted(st) SKM_sk_is_sorted(UI_STRING, (st)) 1613#define sk_UI_STRING_is_sorted(st) SKM_sk_is_sorted(UI_STRING, (st))
1428 1614
1429#define sk_X509_new(st) SKM_sk_new(X509, (st)) 1615#define sk_X509_new(cmp) SKM_sk_new(X509, (cmp))
1430#define sk_X509_new_null() SKM_sk_new_null(X509) 1616#define sk_X509_new_null() SKM_sk_new_null(X509)
1431#define sk_X509_free(st) SKM_sk_free(X509, (st)) 1617#define sk_X509_free(st) SKM_sk_free(X509, (st))
1432#define sk_X509_num(st) SKM_sk_num(X509, (st)) 1618#define sk_X509_num(st) SKM_sk_num(X509, (st))
@@ -1448,7 +1634,7 @@ STACK_OF(type) \
1448#define sk_X509_sort(st) SKM_sk_sort(X509, (st)) 1634#define sk_X509_sort(st) SKM_sk_sort(X509, (st))
1449#define sk_X509_is_sorted(st) SKM_sk_is_sorted(X509, (st)) 1635#define sk_X509_is_sorted(st) SKM_sk_is_sorted(X509, (st))
1450 1636
1451#define sk_X509V3_EXT_METHOD_new(st) SKM_sk_new(X509V3_EXT_METHOD, (st)) 1637#define sk_X509V3_EXT_METHOD_new(cmp) SKM_sk_new(X509V3_EXT_METHOD, (cmp))
1452#define sk_X509V3_EXT_METHOD_new_null() SKM_sk_new_null(X509V3_EXT_METHOD) 1638#define sk_X509V3_EXT_METHOD_new_null() SKM_sk_new_null(X509V3_EXT_METHOD)
1453#define sk_X509V3_EXT_METHOD_free(st) SKM_sk_free(X509V3_EXT_METHOD, (st)) 1639#define sk_X509V3_EXT_METHOD_free(st) SKM_sk_free(X509V3_EXT_METHOD, (st))
1454#define sk_X509V3_EXT_METHOD_num(st) SKM_sk_num(X509V3_EXT_METHOD, (st)) 1640#define sk_X509V3_EXT_METHOD_num(st) SKM_sk_num(X509V3_EXT_METHOD, (st))
@@ -1470,7 +1656,7 @@ STACK_OF(type) \
1470#define sk_X509V3_EXT_METHOD_sort(st) SKM_sk_sort(X509V3_EXT_METHOD, (st)) 1656#define sk_X509V3_EXT_METHOD_sort(st) SKM_sk_sort(X509V3_EXT_METHOD, (st))
1471#define sk_X509V3_EXT_METHOD_is_sorted(st) SKM_sk_is_sorted(X509V3_EXT_METHOD, (st)) 1657#define sk_X509V3_EXT_METHOD_is_sorted(st) SKM_sk_is_sorted(X509V3_EXT_METHOD, (st))
1472 1658
1473#define sk_X509_ALGOR_new(st) SKM_sk_new(X509_ALGOR, (st)) 1659#define sk_X509_ALGOR_new(cmp) SKM_sk_new(X509_ALGOR, (cmp))
1474#define sk_X509_ALGOR_new_null() SKM_sk_new_null(X509_ALGOR) 1660#define sk_X509_ALGOR_new_null() SKM_sk_new_null(X509_ALGOR)
1475#define sk_X509_ALGOR_free(st) SKM_sk_free(X509_ALGOR, (st)) 1661#define sk_X509_ALGOR_free(st) SKM_sk_free(X509_ALGOR, (st))
1476#define sk_X509_ALGOR_num(st) SKM_sk_num(X509_ALGOR, (st)) 1662#define sk_X509_ALGOR_num(st) SKM_sk_num(X509_ALGOR, (st))
@@ -1492,7 +1678,7 @@ STACK_OF(type) \
1492#define sk_X509_ALGOR_sort(st) SKM_sk_sort(X509_ALGOR, (st)) 1678#define sk_X509_ALGOR_sort(st) SKM_sk_sort(X509_ALGOR, (st))
1493#define sk_X509_ALGOR_is_sorted(st) SKM_sk_is_sorted(X509_ALGOR, (st)) 1679#define sk_X509_ALGOR_is_sorted(st) SKM_sk_is_sorted(X509_ALGOR, (st))
1494 1680
1495#define sk_X509_ATTRIBUTE_new(st) SKM_sk_new(X509_ATTRIBUTE, (st)) 1681#define sk_X509_ATTRIBUTE_new(cmp) SKM_sk_new(X509_ATTRIBUTE, (cmp))
1496#define sk_X509_ATTRIBUTE_new_null() SKM_sk_new_null(X509_ATTRIBUTE) 1682#define sk_X509_ATTRIBUTE_new_null() SKM_sk_new_null(X509_ATTRIBUTE)
1497#define sk_X509_ATTRIBUTE_free(st) SKM_sk_free(X509_ATTRIBUTE, (st)) 1683#define sk_X509_ATTRIBUTE_free(st) SKM_sk_free(X509_ATTRIBUTE, (st))
1498#define sk_X509_ATTRIBUTE_num(st) SKM_sk_num(X509_ATTRIBUTE, (st)) 1684#define sk_X509_ATTRIBUTE_num(st) SKM_sk_num(X509_ATTRIBUTE, (st))
@@ -1514,7 +1700,7 @@ STACK_OF(type) \
1514#define sk_X509_ATTRIBUTE_sort(st) SKM_sk_sort(X509_ATTRIBUTE, (st)) 1700#define sk_X509_ATTRIBUTE_sort(st) SKM_sk_sort(X509_ATTRIBUTE, (st))
1515#define sk_X509_ATTRIBUTE_is_sorted(st) SKM_sk_is_sorted(X509_ATTRIBUTE, (st)) 1701#define sk_X509_ATTRIBUTE_is_sorted(st) SKM_sk_is_sorted(X509_ATTRIBUTE, (st))
1516 1702
1517#define sk_X509_CRL_new(st) SKM_sk_new(X509_CRL, (st)) 1703#define sk_X509_CRL_new(cmp) SKM_sk_new(X509_CRL, (cmp))
1518#define sk_X509_CRL_new_null() SKM_sk_new_null(X509_CRL) 1704#define sk_X509_CRL_new_null() SKM_sk_new_null(X509_CRL)
1519#define sk_X509_CRL_free(st) SKM_sk_free(X509_CRL, (st)) 1705#define sk_X509_CRL_free(st) SKM_sk_free(X509_CRL, (st))
1520#define sk_X509_CRL_num(st) SKM_sk_num(X509_CRL, (st)) 1706#define sk_X509_CRL_num(st) SKM_sk_num(X509_CRL, (st))
@@ -1536,7 +1722,7 @@ STACK_OF(type) \
1536#define sk_X509_CRL_sort(st) SKM_sk_sort(X509_CRL, (st)) 1722#define sk_X509_CRL_sort(st) SKM_sk_sort(X509_CRL, (st))
1537#define sk_X509_CRL_is_sorted(st) SKM_sk_is_sorted(X509_CRL, (st)) 1723#define sk_X509_CRL_is_sorted(st) SKM_sk_is_sorted(X509_CRL, (st))
1538 1724
1539#define sk_X509_EXTENSION_new(st) SKM_sk_new(X509_EXTENSION, (st)) 1725#define sk_X509_EXTENSION_new(cmp) SKM_sk_new(X509_EXTENSION, (cmp))
1540#define sk_X509_EXTENSION_new_null() SKM_sk_new_null(X509_EXTENSION) 1726#define sk_X509_EXTENSION_new_null() SKM_sk_new_null(X509_EXTENSION)
1541#define sk_X509_EXTENSION_free(st) SKM_sk_free(X509_EXTENSION, (st)) 1727#define sk_X509_EXTENSION_free(st) SKM_sk_free(X509_EXTENSION, (st))
1542#define sk_X509_EXTENSION_num(st) SKM_sk_num(X509_EXTENSION, (st)) 1728#define sk_X509_EXTENSION_num(st) SKM_sk_num(X509_EXTENSION, (st))
@@ -1558,7 +1744,7 @@ STACK_OF(type) \
1558#define sk_X509_EXTENSION_sort(st) SKM_sk_sort(X509_EXTENSION, (st)) 1744#define sk_X509_EXTENSION_sort(st) SKM_sk_sort(X509_EXTENSION, (st))
1559#define sk_X509_EXTENSION_is_sorted(st) SKM_sk_is_sorted(X509_EXTENSION, (st)) 1745#define sk_X509_EXTENSION_is_sorted(st) SKM_sk_is_sorted(X509_EXTENSION, (st))
1560 1746
1561#define sk_X509_INFO_new(st) SKM_sk_new(X509_INFO, (st)) 1747#define sk_X509_INFO_new(cmp) SKM_sk_new(X509_INFO, (cmp))
1562#define sk_X509_INFO_new_null() SKM_sk_new_null(X509_INFO) 1748#define sk_X509_INFO_new_null() SKM_sk_new_null(X509_INFO)
1563#define sk_X509_INFO_free(st) SKM_sk_free(X509_INFO, (st)) 1749#define sk_X509_INFO_free(st) SKM_sk_free(X509_INFO, (st))
1564#define sk_X509_INFO_num(st) SKM_sk_num(X509_INFO, (st)) 1750#define sk_X509_INFO_num(st) SKM_sk_num(X509_INFO, (st))
@@ -1580,7 +1766,7 @@ STACK_OF(type) \
1580#define sk_X509_INFO_sort(st) SKM_sk_sort(X509_INFO, (st)) 1766#define sk_X509_INFO_sort(st) SKM_sk_sort(X509_INFO, (st))
1581#define sk_X509_INFO_is_sorted(st) SKM_sk_is_sorted(X509_INFO, (st)) 1767#define sk_X509_INFO_is_sorted(st) SKM_sk_is_sorted(X509_INFO, (st))
1582 1768
1583#define sk_X509_LOOKUP_new(st) SKM_sk_new(X509_LOOKUP, (st)) 1769#define sk_X509_LOOKUP_new(cmp) SKM_sk_new(X509_LOOKUP, (cmp))
1584#define sk_X509_LOOKUP_new_null() SKM_sk_new_null(X509_LOOKUP) 1770#define sk_X509_LOOKUP_new_null() SKM_sk_new_null(X509_LOOKUP)
1585#define sk_X509_LOOKUP_free(st) SKM_sk_free(X509_LOOKUP, (st)) 1771#define sk_X509_LOOKUP_free(st) SKM_sk_free(X509_LOOKUP, (st))
1586#define sk_X509_LOOKUP_num(st) SKM_sk_num(X509_LOOKUP, (st)) 1772#define sk_X509_LOOKUP_num(st) SKM_sk_num(X509_LOOKUP, (st))
@@ -1602,7 +1788,7 @@ STACK_OF(type) \
1602#define sk_X509_LOOKUP_sort(st) SKM_sk_sort(X509_LOOKUP, (st)) 1788#define sk_X509_LOOKUP_sort(st) SKM_sk_sort(X509_LOOKUP, (st))
1603#define sk_X509_LOOKUP_is_sorted(st) SKM_sk_is_sorted(X509_LOOKUP, (st)) 1789#define sk_X509_LOOKUP_is_sorted(st) SKM_sk_is_sorted(X509_LOOKUP, (st))
1604 1790
1605#define sk_X509_NAME_new(st) SKM_sk_new(X509_NAME, (st)) 1791#define sk_X509_NAME_new(cmp) SKM_sk_new(X509_NAME, (cmp))
1606#define sk_X509_NAME_new_null() SKM_sk_new_null(X509_NAME) 1792#define sk_X509_NAME_new_null() SKM_sk_new_null(X509_NAME)
1607#define sk_X509_NAME_free(st) SKM_sk_free(X509_NAME, (st)) 1793#define sk_X509_NAME_free(st) SKM_sk_free(X509_NAME, (st))
1608#define sk_X509_NAME_num(st) SKM_sk_num(X509_NAME, (st)) 1794#define sk_X509_NAME_num(st) SKM_sk_num(X509_NAME, (st))
@@ -1624,7 +1810,7 @@ STACK_OF(type) \
1624#define sk_X509_NAME_sort(st) SKM_sk_sort(X509_NAME, (st)) 1810#define sk_X509_NAME_sort(st) SKM_sk_sort(X509_NAME, (st))
1625#define sk_X509_NAME_is_sorted(st) SKM_sk_is_sorted(X509_NAME, (st)) 1811#define sk_X509_NAME_is_sorted(st) SKM_sk_is_sorted(X509_NAME, (st))
1626 1812
1627#define sk_X509_NAME_ENTRY_new(st) SKM_sk_new(X509_NAME_ENTRY, (st)) 1813#define sk_X509_NAME_ENTRY_new(cmp) SKM_sk_new(X509_NAME_ENTRY, (cmp))
1628#define sk_X509_NAME_ENTRY_new_null() SKM_sk_new_null(X509_NAME_ENTRY) 1814#define sk_X509_NAME_ENTRY_new_null() SKM_sk_new_null(X509_NAME_ENTRY)
1629#define sk_X509_NAME_ENTRY_free(st) SKM_sk_free(X509_NAME_ENTRY, (st)) 1815#define sk_X509_NAME_ENTRY_free(st) SKM_sk_free(X509_NAME_ENTRY, (st))
1630#define sk_X509_NAME_ENTRY_num(st) SKM_sk_num(X509_NAME_ENTRY, (st)) 1816#define sk_X509_NAME_ENTRY_num(st) SKM_sk_num(X509_NAME_ENTRY, (st))
@@ -1646,7 +1832,7 @@ STACK_OF(type) \
1646#define sk_X509_NAME_ENTRY_sort(st) SKM_sk_sort(X509_NAME_ENTRY, (st)) 1832#define sk_X509_NAME_ENTRY_sort(st) SKM_sk_sort(X509_NAME_ENTRY, (st))
1647#define sk_X509_NAME_ENTRY_is_sorted(st) SKM_sk_is_sorted(X509_NAME_ENTRY, (st)) 1833#define sk_X509_NAME_ENTRY_is_sorted(st) SKM_sk_is_sorted(X509_NAME_ENTRY, (st))
1648 1834
1649#define sk_X509_OBJECT_new(st) SKM_sk_new(X509_OBJECT, (st)) 1835#define sk_X509_OBJECT_new(cmp) SKM_sk_new(X509_OBJECT, (cmp))
1650#define sk_X509_OBJECT_new_null() SKM_sk_new_null(X509_OBJECT) 1836#define sk_X509_OBJECT_new_null() SKM_sk_new_null(X509_OBJECT)
1651#define sk_X509_OBJECT_free(st) SKM_sk_free(X509_OBJECT, (st)) 1837#define sk_X509_OBJECT_free(st) SKM_sk_free(X509_OBJECT, (st))
1652#define sk_X509_OBJECT_num(st) SKM_sk_num(X509_OBJECT, (st)) 1838#define sk_X509_OBJECT_num(st) SKM_sk_num(X509_OBJECT, (st))
@@ -1668,7 +1854,7 @@ STACK_OF(type) \
1668#define sk_X509_OBJECT_sort(st) SKM_sk_sort(X509_OBJECT, (st)) 1854#define sk_X509_OBJECT_sort(st) SKM_sk_sort(X509_OBJECT, (st))
1669#define sk_X509_OBJECT_is_sorted(st) SKM_sk_is_sorted(X509_OBJECT, (st)) 1855#define sk_X509_OBJECT_is_sorted(st) SKM_sk_is_sorted(X509_OBJECT, (st))
1670 1856
1671#define sk_X509_POLICY_DATA_new(st) SKM_sk_new(X509_POLICY_DATA, (st)) 1857#define sk_X509_POLICY_DATA_new(cmp) SKM_sk_new(X509_POLICY_DATA, (cmp))
1672#define sk_X509_POLICY_DATA_new_null() SKM_sk_new_null(X509_POLICY_DATA) 1858#define sk_X509_POLICY_DATA_new_null() SKM_sk_new_null(X509_POLICY_DATA)
1673#define sk_X509_POLICY_DATA_free(st) SKM_sk_free(X509_POLICY_DATA, (st)) 1859#define sk_X509_POLICY_DATA_free(st) SKM_sk_free(X509_POLICY_DATA, (st))
1674#define sk_X509_POLICY_DATA_num(st) SKM_sk_num(X509_POLICY_DATA, (st)) 1860#define sk_X509_POLICY_DATA_num(st) SKM_sk_num(X509_POLICY_DATA, (st))
@@ -1690,7 +1876,7 @@ STACK_OF(type) \
1690#define sk_X509_POLICY_DATA_sort(st) SKM_sk_sort(X509_POLICY_DATA, (st)) 1876#define sk_X509_POLICY_DATA_sort(st) SKM_sk_sort(X509_POLICY_DATA, (st))
1691#define sk_X509_POLICY_DATA_is_sorted(st) SKM_sk_is_sorted(X509_POLICY_DATA, (st)) 1877#define sk_X509_POLICY_DATA_is_sorted(st) SKM_sk_is_sorted(X509_POLICY_DATA, (st))
1692 1878
1693#define sk_X509_POLICY_NODE_new(st) SKM_sk_new(X509_POLICY_NODE, (st)) 1879#define sk_X509_POLICY_NODE_new(cmp) SKM_sk_new(X509_POLICY_NODE, (cmp))
1694#define sk_X509_POLICY_NODE_new_null() SKM_sk_new_null(X509_POLICY_NODE) 1880#define sk_X509_POLICY_NODE_new_null() SKM_sk_new_null(X509_POLICY_NODE)
1695#define sk_X509_POLICY_NODE_free(st) SKM_sk_free(X509_POLICY_NODE, (st)) 1881#define sk_X509_POLICY_NODE_free(st) SKM_sk_free(X509_POLICY_NODE, (st))
1696#define sk_X509_POLICY_NODE_num(st) SKM_sk_num(X509_POLICY_NODE, (st)) 1882#define sk_X509_POLICY_NODE_num(st) SKM_sk_num(X509_POLICY_NODE, (st))
@@ -1712,29 +1898,7 @@ STACK_OF(type) \
1712#define sk_X509_POLICY_NODE_sort(st) SKM_sk_sort(X509_POLICY_NODE, (st)) 1898#define sk_X509_POLICY_NODE_sort(st) SKM_sk_sort(X509_POLICY_NODE, (st))
1713#define sk_X509_POLICY_NODE_is_sorted(st) SKM_sk_is_sorted(X509_POLICY_NODE, (st)) 1899#define sk_X509_POLICY_NODE_is_sorted(st) SKM_sk_is_sorted(X509_POLICY_NODE, (st))
1714 1900
1715#define sk_X509_POLICY_REF_new(st) SKM_sk_new(X509_POLICY_REF, (st)) 1901#define sk_X509_PURPOSE_new(cmp) SKM_sk_new(X509_PURPOSE, (cmp))
1716#define sk_X509_POLICY_REF_new_null() SKM_sk_new_null(X509_POLICY_REF)
1717#define sk_X509_POLICY_REF_free(st) SKM_sk_free(X509_POLICY_REF, (st))
1718#define sk_X509_POLICY_REF_num(st) SKM_sk_num(X509_POLICY_REF, (st))
1719#define sk_X509_POLICY_REF_value(st, i) SKM_sk_value(X509_POLICY_REF, (st), (i))
1720#define sk_X509_POLICY_REF_set(st, i, val) SKM_sk_set(X509_POLICY_REF, (st), (i), (val))
1721#define sk_X509_POLICY_REF_zero(st) SKM_sk_zero(X509_POLICY_REF, (st))
1722#define sk_X509_POLICY_REF_push(st, val) SKM_sk_push(X509_POLICY_REF, (st), (val))
1723#define sk_X509_POLICY_REF_unshift(st, val) SKM_sk_unshift(X509_POLICY_REF, (st), (val))
1724#define sk_X509_POLICY_REF_find(st, val) SKM_sk_find(X509_POLICY_REF, (st), (val))
1725#define sk_X509_POLICY_REF_find_ex(st, val) SKM_sk_find_ex(X509_POLICY_REF, (st), (val))
1726#define sk_X509_POLICY_REF_delete(st, i) SKM_sk_delete(X509_POLICY_REF, (st), (i))
1727#define sk_X509_POLICY_REF_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_POLICY_REF, (st), (ptr))
1728#define sk_X509_POLICY_REF_insert(st, val, i) SKM_sk_insert(X509_POLICY_REF, (st), (val), (i))
1729#define sk_X509_POLICY_REF_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_POLICY_REF, (st), (cmp))
1730#define sk_X509_POLICY_REF_dup(st) SKM_sk_dup(X509_POLICY_REF, st)
1731#define sk_X509_POLICY_REF_pop_free(st, free_func) SKM_sk_pop_free(X509_POLICY_REF, (st), (free_func))
1732#define sk_X509_POLICY_REF_shift(st) SKM_sk_shift(X509_POLICY_REF, (st))
1733#define sk_X509_POLICY_REF_pop(st) SKM_sk_pop(X509_POLICY_REF, (st))
1734#define sk_X509_POLICY_REF_sort(st) SKM_sk_sort(X509_POLICY_REF, (st))
1735#define sk_X509_POLICY_REF_is_sorted(st) SKM_sk_is_sorted(X509_POLICY_REF, (st))
1736
1737#define sk_X509_PURPOSE_new(st) SKM_sk_new(X509_PURPOSE, (st))
1738#define sk_X509_PURPOSE_new_null() SKM_sk_new_null(X509_PURPOSE) 1902#define sk_X509_PURPOSE_new_null() SKM_sk_new_null(X509_PURPOSE)
1739#define sk_X509_PURPOSE_free(st) SKM_sk_free(X509_PURPOSE, (st)) 1903#define sk_X509_PURPOSE_free(st) SKM_sk_free(X509_PURPOSE, (st))
1740#define sk_X509_PURPOSE_num(st) SKM_sk_num(X509_PURPOSE, (st)) 1904#define sk_X509_PURPOSE_num(st) SKM_sk_num(X509_PURPOSE, (st))
@@ -1756,7 +1920,7 @@ STACK_OF(type) \
1756#define sk_X509_PURPOSE_sort(st) SKM_sk_sort(X509_PURPOSE, (st)) 1920#define sk_X509_PURPOSE_sort(st) SKM_sk_sort(X509_PURPOSE, (st))
1757#define sk_X509_PURPOSE_is_sorted(st) SKM_sk_is_sorted(X509_PURPOSE, (st)) 1921#define sk_X509_PURPOSE_is_sorted(st) SKM_sk_is_sorted(X509_PURPOSE, (st))
1758 1922
1759#define sk_X509_REVOKED_new(st) SKM_sk_new(X509_REVOKED, (st)) 1923#define sk_X509_REVOKED_new(cmp) SKM_sk_new(X509_REVOKED, (cmp))
1760#define sk_X509_REVOKED_new_null() SKM_sk_new_null(X509_REVOKED) 1924#define sk_X509_REVOKED_new_null() SKM_sk_new_null(X509_REVOKED)
1761#define sk_X509_REVOKED_free(st) SKM_sk_free(X509_REVOKED, (st)) 1925#define sk_X509_REVOKED_free(st) SKM_sk_free(X509_REVOKED, (st))
1762#define sk_X509_REVOKED_num(st) SKM_sk_num(X509_REVOKED, (st)) 1926#define sk_X509_REVOKED_num(st) SKM_sk_num(X509_REVOKED, (st))
@@ -1778,7 +1942,7 @@ STACK_OF(type) \
1778#define sk_X509_REVOKED_sort(st) SKM_sk_sort(X509_REVOKED, (st)) 1942#define sk_X509_REVOKED_sort(st) SKM_sk_sort(X509_REVOKED, (st))
1779#define sk_X509_REVOKED_is_sorted(st) SKM_sk_is_sorted(X509_REVOKED, (st)) 1943#define sk_X509_REVOKED_is_sorted(st) SKM_sk_is_sorted(X509_REVOKED, (st))
1780 1944
1781#define sk_X509_TRUST_new(st) SKM_sk_new(X509_TRUST, (st)) 1945#define sk_X509_TRUST_new(cmp) SKM_sk_new(X509_TRUST, (cmp))
1782#define sk_X509_TRUST_new_null() SKM_sk_new_null(X509_TRUST) 1946#define sk_X509_TRUST_new_null() SKM_sk_new_null(X509_TRUST)
1783#define sk_X509_TRUST_free(st) SKM_sk_free(X509_TRUST, (st)) 1947#define sk_X509_TRUST_free(st) SKM_sk_free(X509_TRUST, (st))
1784#define sk_X509_TRUST_num(st) SKM_sk_num(X509_TRUST, (st)) 1948#define sk_X509_TRUST_num(st) SKM_sk_num(X509_TRUST, (st))
@@ -1800,7 +1964,7 @@ STACK_OF(type) \
1800#define sk_X509_TRUST_sort(st) SKM_sk_sort(X509_TRUST, (st)) 1964#define sk_X509_TRUST_sort(st) SKM_sk_sort(X509_TRUST, (st))
1801#define sk_X509_TRUST_is_sorted(st) SKM_sk_is_sorted(X509_TRUST, (st)) 1965#define sk_X509_TRUST_is_sorted(st) SKM_sk_is_sorted(X509_TRUST, (st))
1802 1966
1803#define sk_X509_VERIFY_PARAM_new(st) SKM_sk_new(X509_VERIFY_PARAM, (st)) 1967#define sk_X509_VERIFY_PARAM_new(cmp) SKM_sk_new(X509_VERIFY_PARAM, (cmp))
1804#define sk_X509_VERIFY_PARAM_new_null() SKM_sk_new_null(X509_VERIFY_PARAM) 1968#define sk_X509_VERIFY_PARAM_new_null() SKM_sk_new_null(X509_VERIFY_PARAM)
1805#define sk_X509_VERIFY_PARAM_free(st) SKM_sk_free(X509_VERIFY_PARAM, (st)) 1969#define sk_X509_VERIFY_PARAM_free(st) SKM_sk_free(X509_VERIFY_PARAM, (st))
1806#define sk_X509_VERIFY_PARAM_num(st) SKM_sk_num(X509_VERIFY_PARAM, (st)) 1970#define sk_X509_VERIFY_PARAM_num(st) SKM_sk_num(X509_VERIFY_PARAM, (st))
@@ -1822,6 +1986,125 @@ STACK_OF(type) \
1822#define sk_X509_VERIFY_PARAM_sort(st) SKM_sk_sort(X509_VERIFY_PARAM, (st)) 1986#define sk_X509_VERIFY_PARAM_sort(st) SKM_sk_sort(X509_VERIFY_PARAM, (st))
1823#define sk_X509_VERIFY_PARAM_is_sorted(st) SKM_sk_is_sorted(X509_VERIFY_PARAM, (st)) 1987#define sk_X509_VERIFY_PARAM_is_sorted(st) SKM_sk_is_sorted(X509_VERIFY_PARAM, (st))
1824 1988
1989#define sk_nid_triple_new(cmp) SKM_sk_new(nid_triple, (cmp))
1990#define sk_nid_triple_new_null() SKM_sk_new_null(nid_triple)
1991#define sk_nid_triple_free(st) SKM_sk_free(nid_triple, (st))
1992#define sk_nid_triple_num(st) SKM_sk_num(nid_triple, (st))
1993#define sk_nid_triple_value(st, i) SKM_sk_value(nid_triple, (st), (i))
1994#define sk_nid_triple_set(st, i, val) SKM_sk_set(nid_triple, (st), (i), (val))
1995#define sk_nid_triple_zero(st) SKM_sk_zero(nid_triple, (st))
1996#define sk_nid_triple_push(st, val) SKM_sk_push(nid_triple, (st), (val))
1997#define sk_nid_triple_unshift(st, val) SKM_sk_unshift(nid_triple, (st), (val))
1998#define sk_nid_triple_find(st, val) SKM_sk_find(nid_triple, (st), (val))
1999#define sk_nid_triple_find_ex(st, val) SKM_sk_find_ex(nid_triple, (st), (val))
2000#define sk_nid_triple_delete(st, i) SKM_sk_delete(nid_triple, (st), (i))
2001#define sk_nid_triple_delete_ptr(st, ptr) SKM_sk_delete_ptr(nid_triple, (st), (ptr))
2002#define sk_nid_triple_insert(st, val, i) SKM_sk_insert(nid_triple, (st), (val), (i))
2003#define sk_nid_triple_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(nid_triple, (st), (cmp))
2004#define sk_nid_triple_dup(st) SKM_sk_dup(nid_triple, st)
2005#define sk_nid_triple_pop_free(st, free_func) SKM_sk_pop_free(nid_triple, (st), (free_func))
2006#define sk_nid_triple_shift(st) SKM_sk_shift(nid_triple, (st))
2007#define sk_nid_triple_pop(st) SKM_sk_pop(nid_triple, (st))
2008#define sk_nid_triple_sort(st) SKM_sk_sort(nid_triple, (st))
2009#define sk_nid_triple_is_sorted(st) SKM_sk_is_sorted(nid_triple, (st))
2010
2011#define sk_void_new(cmp) SKM_sk_new(void, (cmp))
2012#define sk_void_new_null() SKM_sk_new_null(void)
2013#define sk_void_free(st) SKM_sk_free(void, (st))
2014#define sk_void_num(st) SKM_sk_num(void, (st))
2015#define sk_void_value(st, i) SKM_sk_value(void, (st), (i))
2016#define sk_void_set(st, i, val) SKM_sk_set(void, (st), (i), (val))
2017#define sk_void_zero(st) SKM_sk_zero(void, (st))
2018#define sk_void_push(st, val) SKM_sk_push(void, (st), (val))
2019#define sk_void_unshift(st, val) SKM_sk_unshift(void, (st), (val))
2020#define sk_void_find(st, val) SKM_sk_find(void, (st), (val))
2021#define sk_void_find_ex(st, val) SKM_sk_find_ex(void, (st), (val))
2022#define sk_void_delete(st, i) SKM_sk_delete(void, (st), (i))
2023#define sk_void_delete_ptr(st, ptr) SKM_sk_delete_ptr(void, (st), (ptr))
2024#define sk_void_insert(st, val, i) SKM_sk_insert(void, (st), (val), (i))
2025#define sk_void_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(void, (st), (cmp))
2026#define sk_void_dup(st) SKM_sk_dup(void, st)
2027#define sk_void_pop_free(st, free_func) SKM_sk_pop_free(void, (st), (free_func))
2028#define sk_void_shift(st) SKM_sk_shift(void, (st))
2029#define sk_void_pop(st) SKM_sk_pop(void, (st))
2030#define sk_void_sort(st) SKM_sk_sort(void, (st))
2031#define sk_void_is_sorted(st) SKM_sk_is_sorted(void, (st))
2032
2033#define sk_OPENSSL_BLOCK_new(cmp) ((STACK_OF(OPENSSL_BLOCK) *)sk_new(CHECKED_SK_CMP_FUNC(void, cmp)))
2034#define sk_OPENSSL_BLOCK_new_null() ((STACK_OF(OPENSSL_BLOCK) *)sk_new_null())
2035#define sk_OPENSSL_BLOCK_push(st, val) sk_push(CHECKED_PTR_OF(STACK_OF(OPENSSL_BLOCK), st), CHECKED_PTR_OF(void, val))
2036#define sk_OPENSSL_BLOCK_find(st, val) sk_find(CHECKED_PTR_OF(STACK_OF(OPENSSL_BLOCK), st), CHECKED_PTR_OF(void, val))
2037#define sk_OPENSSL_BLOCK_value(st, i) ((OPENSSL_BLOCK)sk_value(CHECKED_PTR_OF(STACK_OF(OPENSSL_BLOCK), st), i))
2038#define sk_OPENSSL_BLOCK_num(st) SKM_sk_num(OPENSSL_BLOCK, st)
2039#define sk_OPENSSL_BLOCK_pop_free(st, free_func) sk_pop_free(CHECKED_PTR_OF(STACK_OF(OPENSSL_BLOCK), st), CHECKED_SK_FREE_FUNC2(OPENSSL_BLOCK, free_func))
2040#define sk_OPENSSL_BLOCK_insert(st, val, i) sk_insert(CHECKED_PTR_OF(STACK_OF(OPENSSL_BLOCK), st), CHECKED_PTR_OF(void, val), i)
2041#define sk_OPENSSL_BLOCK_free(st) SKM_sk_free(OPENSSL_BLOCK, st)
2042#define sk_OPENSSL_BLOCK_set(st, i, val) sk_set((_STACK *)CHECKED_PTR_OF(STACK_OF(OPENSSL_BLOCK), st), i, CHECKED_PTR_OF(void, val))
2043#define sk_OPENSSL_BLOCK_zero(st) SKM_sk_zero(OPENSSL_BLOCK, (st))
2044#define sk_OPENSSL_BLOCK_unshift(st, val) sk_unshift((_STACK *)CHECKED_PTR_OF(STACK_OF(OPENSSL_BLOCK), st), CHECKED_PTR_OF(void, val))
2045#define sk_OPENSSL_BLOCK_find_ex(st, val) sk_find_ex((_STACK *)CHECKED_CONST_PTR_OF(STACK_OF(OPENSSL_BLOCK), st), CHECKED_CONST_PTR_OF(void, val))
2046#define sk_OPENSSL_BLOCK_delete(st, i) SKM_sk_delete(OPENSSL_BLOCK, (st), (i))
2047#define sk_OPENSSL_BLOCK_delete_ptr(st, ptr) (OPENSSL_BLOCK *)sk_delete_ptr((_STACK *)CHECKED_PTR_OF(STACK_OF(OPENSSL_BLOCK), st), CHECKED_PTR_OF(void, ptr))
2048#define sk_OPENSSL_BLOCK_set_cmp_func(st, cmp) \
2049 ((int (*)(const void * const *,const void * const *)) \
2050 sk_set_cmp_func((_STACK *)CHECKED_PTR_OF(STACK_OF(OPENSSL_BLOCK), st), CHECKED_SK_CMP_FUNC(void, cmp)))
2051#define sk_OPENSSL_BLOCK_dup(st) SKM_sk_dup(OPENSSL_BLOCK, st)
2052#define sk_OPENSSL_BLOCK_shift(st) SKM_sk_shift(OPENSSL_BLOCK, (st))
2053#define sk_OPENSSL_BLOCK_pop(st) (void *)sk_pop((_STACK *)CHECKED_PTR_OF(STACK_OF(OPENSSL_BLOCK), st))
2054#define sk_OPENSSL_BLOCK_sort(st) SKM_sk_sort(OPENSSL_BLOCK, (st))
2055#define sk_OPENSSL_BLOCK_is_sorted(st) SKM_sk_is_sorted(OPENSSL_BLOCK, (st))
2056
2057
2058#define sk_OPENSSL_PSTRING_new(cmp) ((STACK_OF(OPENSSL_PSTRING) *)sk_new(CHECKED_SK_CMP_FUNC(OPENSSL_STRING, cmp)))
2059#define sk_OPENSSL_PSTRING_new_null() ((STACK_OF(OPENSSL_PSTRING) *)sk_new_null())
2060#define sk_OPENSSL_PSTRING_push(st, val) sk_push(CHECKED_PTR_OF(STACK_OF(OPENSSL_PSTRING), st), CHECKED_PTR_OF(OPENSSL_STRING, val))
2061#define sk_OPENSSL_PSTRING_find(st, val) sk_find(CHECKED_PTR_OF(STACK_OF(OPENSSL_PSTRING), st), CHECKED_PTR_OF(OPENSSL_STRING, val))
2062#define sk_OPENSSL_PSTRING_value(st, i) ((OPENSSL_PSTRING)sk_value(CHECKED_PTR_OF(STACK_OF(OPENSSL_PSTRING), st), i))
2063#define sk_OPENSSL_PSTRING_num(st) SKM_sk_num(OPENSSL_PSTRING, st)
2064#define sk_OPENSSL_PSTRING_pop_free(st, free_func) sk_pop_free(CHECKED_PTR_OF(STACK_OF(OPENSSL_PSTRING), st), CHECKED_SK_FREE_FUNC2(OPENSSL_PSTRING, free_func))
2065#define sk_OPENSSL_PSTRING_insert(st, val, i) sk_insert(CHECKED_PTR_OF(STACK_OF(OPENSSL_PSTRING), st), CHECKED_PTR_OF(OPENSSL_STRING, val), i)
2066#define sk_OPENSSL_PSTRING_free(st) SKM_sk_free(OPENSSL_PSTRING, st)
2067#define sk_OPENSSL_PSTRING_set(st, i, val) sk_set((_STACK *)CHECKED_PTR_OF(STACK_OF(OPENSSL_PSTRING), st), i, CHECKED_PTR_OF(OPENSSL_STRING, val))
2068#define sk_OPENSSL_PSTRING_zero(st) SKM_sk_zero(OPENSSL_PSTRING, (st))
2069#define sk_OPENSSL_PSTRING_unshift(st, val) sk_unshift((_STACK *)CHECKED_PTR_OF(STACK_OF(OPENSSL_PSTRING), st), CHECKED_PTR_OF(OPENSSL_STRING, val))
2070#define sk_OPENSSL_PSTRING_find_ex(st, val) sk_find_ex((_STACK *)CHECKED_CONST_PTR_OF(STACK_OF(OPENSSL_PSTRING), st), CHECKED_CONST_PTR_OF(OPENSSL_STRING, val))
2071#define sk_OPENSSL_PSTRING_delete(st, i) SKM_sk_delete(OPENSSL_PSTRING, (st), (i))
2072#define sk_OPENSSL_PSTRING_delete_ptr(st, ptr) (OPENSSL_PSTRING *)sk_delete_ptr((_STACK *)CHECKED_PTR_OF(STACK_OF(OPENSSL_PSTRING), st), CHECKED_PTR_OF(OPENSSL_STRING, ptr))
2073#define sk_OPENSSL_PSTRING_set_cmp_func(st, cmp) \
2074 ((int (*)(const OPENSSL_STRING * const *,const OPENSSL_STRING * const *)) \
2075 sk_set_cmp_func((_STACK *)CHECKED_PTR_OF(STACK_OF(OPENSSL_PSTRING), st), CHECKED_SK_CMP_FUNC(OPENSSL_STRING, cmp)))
2076#define sk_OPENSSL_PSTRING_dup(st) SKM_sk_dup(OPENSSL_PSTRING, st)
2077#define sk_OPENSSL_PSTRING_shift(st) SKM_sk_shift(OPENSSL_PSTRING, (st))
2078#define sk_OPENSSL_PSTRING_pop(st) (OPENSSL_STRING *)sk_pop((_STACK *)CHECKED_PTR_OF(STACK_OF(OPENSSL_PSTRING), st))
2079#define sk_OPENSSL_PSTRING_sort(st) SKM_sk_sort(OPENSSL_PSTRING, (st))
2080#define sk_OPENSSL_PSTRING_is_sorted(st) SKM_sk_is_sorted(OPENSSL_PSTRING, (st))
2081
2082
2083#define sk_OPENSSL_STRING_new(cmp) ((STACK_OF(OPENSSL_STRING) *)sk_new(CHECKED_SK_CMP_FUNC(char, cmp)))
2084#define sk_OPENSSL_STRING_new_null() ((STACK_OF(OPENSSL_STRING) *)sk_new_null())
2085#define sk_OPENSSL_STRING_push(st, val) sk_push(CHECKED_PTR_OF(STACK_OF(OPENSSL_STRING), st), CHECKED_PTR_OF(char, val))
2086#define sk_OPENSSL_STRING_find(st, val) sk_find(CHECKED_PTR_OF(STACK_OF(OPENSSL_STRING), st), CHECKED_PTR_OF(char, val))
2087#define sk_OPENSSL_STRING_value(st, i) ((OPENSSL_STRING)sk_value(CHECKED_PTR_OF(STACK_OF(OPENSSL_STRING), st), i))
2088#define sk_OPENSSL_STRING_num(st) SKM_sk_num(OPENSSL_STRING, st)
2089#define sk_OPENSSL_STRING_pop_free(st, free_func) sk_pop_free(CHECKED_PTR_OF(STACK_OF(OPENSSL_STRING), st), CHECKED_SK_FREE_FUNC2(OPENSSL_STRING, free_func))
2090#define sk_OPENSSL_STRING_insert(st, val, i) sk_insert(CHECKED_PTR_OF(STACK_OF(OPENSSL_STRING), st), CHECKED_PTR_OF(char, val), i)
2091#define sk_OPENSSL_STRING_free(st) SKM_sk_free(OPENSSL_STRING, st)
2092#define sk_OPENSSL_STRING_set(st, i, val) sk_set((_STACK *)CHECKED_PTR_OF(STACK_OF(OPENSSL_STRING), st), i, CHECKED_PTR_OF(char, val))
2093#define sk_OPENSSL_STRING_zero(st) SKM_sk_zero(OPENSSL_STRING, (st))
2094#define sk_OPENSSL_STRING_unshift(st, val) sk_unshift((_STACK *)CHECKED_PTR_OF(STACK_OF(OPENSSL_STRING), st), CHECKED_PTR_OF(char, val))
2095#define sk_OPENSSL_STRING_find_ex(st, val) sk_find_ex((_STACK *)CHECKED_CONST_PTR_OF(STACK_OF(OPENSSL_STRING), st), CHECKED_CONST_PTR_OF(char, val))
2096#define sk_OPENSSL_STRING_delete(st, i) SKM_sk_delete(OPENSSL_STRING, (st), (i))
2097#define sk_OPENSSL_STRING_delete_ptr(st, ptr) (OPENSSL_STRING *)sk_delete_ptr((_STACK *)CHECKED_PTR_OF(STACK_OF(OPENSSL_STRING), st), CHECKED_PTR_OF(char, ptr))
2098#define sk_OPENSSL_STRING_set_cmp_func(st, cmp) \
2099 ((int (*)(const char * const *,const char * const *)) \
2100 sk_set_cmp_func((_STACK *)CHECKED_PTR_OF(STACK_OF(OPENSSL_STRING), st), CHECKED_SK_CMP_FUNC(char, cmp)))
2101#define sk_OPENSSL_STRING_dup(st) SKM_sk_dup(OPENSSL_STRING, st)
2102#define sk_OPENSSL_STRING_shift(st) SKM_sk_shift(OPENSSL_STRING, (st))
2103#define sk_OPENSSL_STRING_pop(st) (char *)sk_pop((_STACK *)CHECKED_PTR_OF(STACK_OF(OPENSSL_STRING), st))
2104#define sk_OPENSSL_STRING_sort(st) SKM_sk_sort(OPENSSL_STRING, (st))
2105#define sk_OPENSSL_STRING_is_sorted(st) SKM_sk_is_sorted(OPENSSL_STRING, (st))
2106
2107
1825#define d2i_ASN1_SET_OF_ACCESS_DESCRIPTION(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \ 2108#define d2i_ASN1_SET_OF_ACCESS_DESCRIPTION(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
1826 SKM_ASN1_SET_OF_d2i(ACCESS_DESCRIPTION, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) 2109 SKM_ASN1_SET_OF_d2i(ACCESS_DESCRIPTION, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class))
1827#define i2d_ASN1_SET_OF_ACCESS_DESCRIPTION(st, pp, i2d_func, ex_tag, ex_class, is_set) \ 2110#define i2d_ASN1_SET_OF_ACCESS_DESCRIPTION(st, pp, i2d_func, ex_tag, ex_class, is_set) \
@@ -1858,6 +2141,15 @@ STACK_OF(type) \
1858#define ASN1_seq_unpack_ASN1_TYPE(buf, len, d2i_func, free_func) \ 2141#define ASN1_seq_unpack_ASN1_TYPE(buf, len, d2i_func, free_func) \
1859 SKM_ASN1_seq_unpack(ASN1_TYPE, (buf), (len), (d2i_func), (free_func)) 2142 SKM_ASN1_seq_unpack(ASN1_TYPE, (buf), (len), (d2i_func), (free_func))
1860 2143
2144#define d2i_ASN1_SET_OF_ASN1_UTF8STRING(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
2145 SKM_ASN1_SET_OF_d2i(ASN1_UTF8STRING, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class))
2146#define i2d_ASN1_SET_OF_ASN1_UTF8STRING(st, pp, i2d_func, ex_tag, ex_class, is_set) \
2147 SKM_ASN1_SET_OF_i2d(ASN1_UTF8STRING, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
2148#define ASN1_seq_pack_ASN1_UTF8STRING(st, i2d_func, buf, len) \
2149 SKM_ASN1_seq_pack(ASN1_UTF8STRING, (st), (i2d_func), (buf), (len))
2150#define ASN1_seq_unpack_ASN1_UTF8STRING(buf, len, d2i_func, free_func) \
2151 SKM_ASN1_seq_unpack(ASN1_UTF8STRING, (buf), (len), (d2i_func), (free_func))
2152
1861#define d2i_ASN1_SET_OF_DIST_POINT(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \ 2153#define d2i_ASN1_SET_OF_DIST_POINT(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
1862 SKM_ASN1_SET_OF_d2i(DIST_POINT, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) 2154 SKM_ASN1_SET_OF_d2i(DIST_POINT, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class))
1863#define i2d_ASN1_SET_OF_DIST_POINT(st, pp, i2d_func, ex_tag, ex_class, is_set) \ 2155#define i2d_ASN1_SET_OF_DIST_POINT(st, pp, i2d_func, ex_tag, ex_class, is_set) \
@@ -1867,6 +2159,24 @@ STACK_OF(type) \
1867#define ASN1_seq_unpack_DIST_POINT(buf, len, d2i_func, free_func) \ 2159#define ASN1_seq_unpack_DIST_POINT(buf, len, d2i_func, free_func) \
1868 SKM_ASN1_seq_unpack(DIST_POINT, (buf), (len), (d2i_func), (free_func)) 2160 SKM_ASN1_seq_unpack(DIST_POINT, (buf), (len), (d2i_func), (free_func))
1869 2161
2162#define d2i_ASN1_SET_OF_ESS_CERT_ID(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
2163 SKM_ASN1_SET_OF_d2i(ESS_CERT_ID, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class))
2164#define i2d_ASN1_SET_OF_ESS_CERT_ID(st, pp, i2d_func, ex_tag, ex_class, is_set) \
2165 SKM_ASN1_SET_OF_i2d(ESS_CERT_ID, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
2166#define ASN1_seq_pack_ESS_CERT_ID(st, i2d_func, buf, len) \
2167 SKM_ASN1_seq_pack(ESS_CERT_ID, (st), (i2d_func), (buf), (len))
2168#define ASN1_seq_unpack_ESS_CERT_ID(buf, len, d2i_func, free_func) \
2169 SKM_ASN1_seq_unpack(ESS_CERT_ID, (buf), (len), (d2i_func), (free_func))
2170
2171#define d2i_ASN1_SET_OF_EVP_MD(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
2172 SKM_ASN1_SET_OF_d2i(EVP_MD, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class))
2173#define i2d_ASN1_SET_OF_EVP_MD(st, pp, i2d_func, ex_tag, ex_class, is_set) \
2174 SKM_ASN1_SET_OF_i2d(EVP_MD, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
2175#define ASN1_seq_pack_EVP_MD(st, i2d_func, buf, len) \
2176 SKM_ASN1_seq_pack(EVP_MD, (st), (i2d_func), (buf), (len))
2177#define ASN1_seq_unpack_EVP_MD(buf, len, d2i_func, free_func) \
2178 SKM_ASN1_seq_unpack(EVP_MD, (buf), (len), (d2i_func), (free_func))
2179
1870#define d2i_ASN1_SET_OF_GENERAL_NAME(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \ 2180#define d2i_ASN1_SET_OF_GENERAL_NAME(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
1871 SKM_ASN1_SET_OF_d2i(GENERAL_NAME, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) 2181 SKM_ASN1_SET_OF_d2i(GENERAL_NAME, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class))
1872#define i2d_ASN1_SET_OF_GENERAL_NAME(st, pp, i2d_func, ex_tag, ex_class, is_set) \ 2182#define i2d_ASN1_SET_OF_GENERAL_NAME(st, pp, i2d_func, ex_tag, ex_class, is_set) \
@@ -2025,6 +2335,240 @@ STACK_OF(type) \
2025 2335
2026#define PKCS12_decrypt_d2i_PKCS7(algor, d2i_func, free_func, pass, passlen, oct, seq) \ 2336#define PKCS12_decrypt_d2i_PKCS7(algor, d2i_func, free_func, pass, passlen, oct, seq) \
2027 SKM_PKCS12_decrypt_d2i(PKCS7, (algor), (d2i_func), (free_func), (pass), (passlen), (oct), (seq)) 2337 SKM_PKCS12_decrypt_d2i(PKCS7, (algor), (d2i_func), (free_func), (pass), (passlen), (oct), (seq))
2338
2339#define lh_ADDED_OBJ_new() LHM_lh_new(ADDED_OBJ,added_obj)
2340#define lh_ADDED_OBJ_insert(lh,inst) LHM_lh_insert(ADDED_OBJ,lh,inst)
2341#define lh_ADDED_OBJ_retrieve(lh,inst) LHM_lh_retrieve(ADDED_OBJ,lh,inst)
2342#define lh_ADDED_OBJ_delete(lh,inst) LHM_lh_delete(ADDED_OBJ,lh,inst)
2343#define lh_ADDED_OBJ_doall(lh,fn) LHM_lh_doall(ADDED_OBJ,lh,fn)
2344#define lh_ADDED_OBJ_doall_arg(lh,fn,arg_type,arg) \
2345 LHM_lh_doall_arg(ADDED_OBJ,lh,fn,arg_type,arg)
2346#define lh_ADDED_OBJ_error(lh) LHM_lh_error(ADDED_OBJ,lh)
2347#define lh_ADDED_OBJ_num_items(lh) LHM_lh_num_items(ADDED_OBJ,lh)
2348#define lh_ADDED_OBJ_down_load(lh) LHM_lh_down_load(ADDED_OBJ,lh)
2349#define lh_ADDED_OBJ_node_stats_bio(lh,out) \
2350 LHM_lh_node_stats_bio(ADDED_OBJ,lh,out)
2351#define lh_ADDED_OBJ_node_usage_stats_bio(lh,out) \
2352 LHM_lh_node_usage_stats_bio(ADDED_OBJ,lh,out)
2353#define lh_ADDED_OBJ_stats_bio(lh,out) \
2354 LHM_lh_stats_bio(ADDED_OBJ,lh,out)
2355#define lh_ADDED_OBJ_free(lh) LHM_lh_free(ADDED_OBJ,lh)
2356
2357#define lh_APP_INFO_new() LHM_lh_new(APP_INFO,app_info)
2358#define lh_APP_INFO_insert(lh,inst) LHM_lh_insert(APP_INFO,lh,inst)
2359#define lh_APP_INFO_retrieve(lh,inst) LHM_lh_retrieve(APP_INFO,lh,inst)
2360#define lh_APP_INFO_delete(lh,inst) LHM_lh_delete(APP_INFO,lh,inst)
2361#define lh_APP_INFO_doall(lh,fn) LHM_lh_doall(APP_INFO,lh,fn)
2362#define lh_APP_INFO_doall_arg(lh,fn,arg_type,arg) \
2363 LHM_lh_doall_arg(APP_INFO,lh,fn,arg_type,arg)
2364#define lh_APP_INFO_error(lh) LHM_lh_error(APP_INFO,lh)
2365#define lh_APP_INFO_num_items(lh) LHM_lh_num_items(APP_INFO,lh)
2366#define lh_APP_INFO_down_load(lh) LHM_lh_down_load(APP_INFO,lh)
2367#define lh_APP_INFO_node_stats_bio(lh,out) \
2368 LHM_lh_node_stats_bio(APP_INFO,lh,out)
2369#define lh_APP_INFO_node_usage_stats_bio(lh,out) \
2370 LHM_lh_node_usage_stats_bio(APP_INFO,lh,out)
2371#define lh_APP_INFO_stats_bio(lh,out) \
2372 LHM_lh_stats_bio(APP_INFO,lh,out)
2373#define lh_APP_INFO_free(lh) LHM_lh_free(APP_INFO,lh)
2374
2375#define lh_CONF_VALUE_new() LHM_lh_new(CONF_VALUE,conf_value)
2376#define lh_CONF_VALUE_insert(lh,inst) LHM_lh_insert(CONF_VALUE,lh,inst)
2377#define lh_CONF_VALUE_retrieve(lh,inst) LHM_lh_retrieve(CONF_VALUE,lh,inst)
2378#define lh_CONF_VALUE_delete(lh,inst) LHM_lh_delete(CONF_VALUE,lh,inst)
2379#define lh_CONF_VALUE_doall(lh,fn) LHM_lh_doall(CONF_VALUE,lh,fn)
2380#define lh_CONF_VALUE_doall_arg(lh,fn,arg_type,arg) \
2381 LHM_lh_doall_arg(CONF_VALUE,lh,fn,arg_type,arg)
2382#define lh_CONF_VALUE_error(lh) LHM_lh_error(CONF_VALUE,lh)
2383#define lh_CONF_VALUE_num_items(lh) LHM_lh_num_items(CONF_VALUE,lh)
2384#define lh_CONF_VALUE_down_load(lh) LHM_lh_down_load(CONF_VALUE,lh)
2385#define lh_CONF_VALUE_node_stats_bio(lh,out) \
2386 LHM_lh_node_stats_bio(CONF_VALUE,lh,out)
2387#define lh_CONF_VALUE_node_usage_stats_bio(lh,out) \
2388 LHM_lh_node_usage_stats_bio(CONF_VALUE,lh,out)
2389#define lh_CONF_VALUE_stats_bio(lh,out) \
2390 LHM_lh_stats_bio(CONF_VALUE,lh,out)
2391#define lh_CONF_VALUE_free(lh) LHM_lh_free(CONF_VALUE,lh)
2392
2393#define lh_ENGINE_PILE_new() LHM_lh_new(ENGINE_PILE,engine_pile)
2394#define lh_ENGINE_PILE_insert(lh,inst) LHM_lh_insert(ENGINE_PILE,lh,inst)
2395#define lh_ENGINE_PILE_retrieve(lh,inst) LHM_lh_retrieve(ENGINE_PILE,lh,inst)
2396#define lh_ENGINE_PILE_delete(lh,inst) LHM_lh_delete(ENGINE_PILE,lh,inst)
2397#define lh_ENGINE_PILE_doall(lh,fn) LHM_lh_doall(ENGINE_PILE,lh,fn)
2398#define lh_ENGINE_PILE_doall_arg(lh,fn,arg_type,arg) \
2399 LHM_lh_doall_arg(ENGINE_PILE,lh,fn,arg_type,arg)
2400#define lh_ENGINE_PILE_error(lh) LHM_lh_error(ENGINE_PILE,lh)
2401#define lh_ENGINE_PILE_num_items(lh) LHM_lh_num_items(ENGINE_PILE,lh)
2402#define lh_ENGINE_PILE_down_load(lh) LHM_lh_down_load(ENGINE_PILE,lh)
2403#define lh_ENGINE_PILE_node_stats_bio(lh,out) \
2404 LHM_lh_node_stats_bio(ENGINE_PILE,lh,out)
2405#define lh_ENGINE_PILE_node_usage_stats_bio(lh,out) \
2406 LHM_lh_node_usage_stats_bio(ENGINE_PILE,lh,out)
2407#define lh_ENGINE_PILE_stats_bio(lh,out) \
2408 LHM_lh_stats_bio(ENGINE_PILE,lh,out)
2409#define lh_ENGINE_PILE_free(lh) LHM_lh_free(ENGINE_PILE,lh)
2410
2411#define lh_ERR_STATE_new() LHM_lh_new(ERR_STATE,err_state)
2412#define lh_ERR_STATE_insert(lh,inst) LHM_lh_insert(ERR_STATE,lh,inst)
2413#define lh_ERR_STATE_retrieve(lh,inst) LHM_lh_retrieve(ERR_STATE,lh,inst)
2414#define lh_ERR_STATE_delete(lh,inst) LHM_lh_delete(ERR_STATE,lh,inst)
2415#define lh_ERR_STATE_doall(lh,fn) LHM_lh_doall(ERR_STATE,lh,fn)
2416#define lh_ERR_STATE_doall_arg(lh,fn,arg_type,arg) \
2417 LHM_lh_doall_arg(ERR_STATE,lh,fn,arg_type,arg)
2418#define lh_ERR_STATE_error(lh) LHM_lh_error(ERR_STATE,lh)
2419#define lh_ERR_STATE_num_items(lh) LHM_lh_num_items(ERR_STATE,lh)
2420#define lh_ERR_STATE_down_load(lh) LHM_lh_down_load(ERR_STATE,lh)
2421#define lh_ERR_STATE_node_stats_bio(lh,out) \
2422 LHM_lh_node_stats_bio(ERR_STATE,lh,out)
2423#define lh_ERR_STATE_node_usage_stats_bio(lh,out) \
2424 LHM_lh_node_usage_stats_bio(ERR_STATE,lh,out)
2425#define lh_ERR_STATE_stats_bio(lh,out) \
2426 LHM_lh_stats_bio(ERR_STATE,lh,out)
2427#define lh_ERR_STATE_free(lh) LHM_lh_free(ERR_STATE,lh)
2428
2429#define lh_ERR_STRING_DATA_new() LHM_lh_new(ERR_STRING_DATA,err_string_data)
2430#define lh_ERR_STRING_DATA_insert(lh,inst) LHM_lh_insert(ERR_STRING_DATA,lh,inst)
2431#define lh_ERR_STRING_DATA_retrieve(lh,inst) LHM_lh_retrieve(ERR_STRING_DATA,lh,inst)
2432#define lh_ERR_STRING_DATA_delete(lh,inst) LHM_lh_delete(ERR_STRING_DATA,lh,inst)
2433#define lh_ERR_STRING_DATA_doall(lh,fn) LHM_lh_doall(ERR_STRING_DATA,lh,fn)
2434#define lh_ERR_STRING_DATA_doall_arg(lh,fn,arg_type,arg) \
2435 LHM_lh_doall_arg(ERR_STRING_DATA,lh,fn,arg_type,arg)
2436#define lh_ERR_STRING_DATA_error(lh) LHM_lh_error(ERR_STRING_DATA,lh)
2437#define lh_ERR_STRING_DATA_num_items(lh) LHM_lh_num_items(ERR_STRING_DATA,lh)
2438#define lh_ERR_STRING_DATA_down_load(lh) LHM_lh_down_load(ERR_STRING_DATA,lh)
2439#define lh_ERR_STRING_DATA_node_stats_bio(lh,out) \
2440 LHM_lh_node_stats_bio(ERR_STRING_DATA,lh,out)
2441#define lh_ERR_STRING_DATA_node_usage_stats_bio(lh,out) \
2442 LHM_lh_node_usage_stats_bio(ERR_STRING_DATA,lh,out)
2443#define lh_ERR_STRING_DATA_stats_bio(lh,out) \
2444 LHM_lh_stats_bio(ERR_STRING_DATA,lh,out)
2445#define lh_ERR_STRING_DATA_free(lh) LHM_lh_free(ERR_STRING_DATA,lh)
2446
2447#define lh_EX_CLASS_ITEM_new() LHM_lh_new(EX_CLASS_ITEM,ex_class_item)
2448#define lh_EX_CLASS_ITEM_insert(lh,inst) LHM_lh_insert(EX_CLASS_ITEM,lh,inst)
2449#define lh_EX_CLASS_ITEM_retrieve(lh,inst) LHM_lh_retrieve(EX_CLASS_ITEM,lh,inst)
2450#define lh_EX_CLASS_ITEM_delete(lh,inst) LHM_lh_delete(EX_CLASS_ITEM,lh,inst)
2451#define lh_EX_CLASS_ITEM_doall(lh,fn) LHM_lh_doall(EX_CLASS_ITEM,lh,fn)
2452#define lh_EX_CLASS_ITEM_doall_arg(lh,fn,arg_type,arg) \
2453 LHM_lh_doall_arg(EX_CLASS_ITEM,lh,fn,arg_type,arg)
2454#define lh_EX_CLASS_ITEM_error(lh) LHM_lh_error(EX_CLASS_ITEM,lh)
2455#define lh_EX_CLASS_ITEM_num_items(lh) LHM_lh_num_items(EX_CLASS_ITEM,lh)
2456#define lh_EX_CLASS_ITEM_down_load(lh) LHM_lh_down_load(EX_CLASS_ITEM,lh)
2457#define lh_EX_CLASS_ITEM_node_stats_bio(lh,out) \
2458 LHM_lh_node_stats_bio(EX_CLASS_ITEM,lh,out)
2459#define lh_EX_CLASS_ITEM_node_usage_stats_bio(lh,out) \
2460 LHM_lh_node_usage_stats_bio(EX_CLASS_ITEM,lh,out)
2461#define lh_EX_CLASS_ITEM_stats_bio(lh,out) \
2462 LHM_lh_stats_bio(EX_CLASS_ITEM,lh,out)
2463#define lh_EX_CLASS_ITEM_free(lh) LHM_lh_free(EX_CLASS_ITEM,lh)
2464
2465#define lh_FUNCTION_new() LHM_lh_new(FUNCTION,function)
2466#define lh_FUNCTION_insert(lh,inst) LHM_lh_insert(FUNCTION,lh,inst)
2467#define lh_FUNCTION_retrieve(lh,inst) LHM_lh_retrieve(FUNCTION,lh,inst)
2468#define lh_FUNCTION_delete(lh,inst) LHM_lh_delete(FUNCTION,lh,inst)
2469#define lh_FUNCTION_doall(lh,fn) LHM_lh_doall(FUNCTION,lh,fn)
2470#define lh_FUNCTION_doall_arg(lh,fn,arg_type,arg) \
2471 LHM_lh_doall_arg(FUNCTION,lh,fn,arg_type,arg)
2472#define lh_FUNCTION_error(lh) LHM_lh_error(FUNCTION,lh)
2473#define lh_FUNCTION_num_items(lh) LHM_lh_num_items(FUNCTION,lh)
2474#define lh_FUNCTION_down_load(lh) LHM_lh_down_load(FUNCTION,lh)
2475#define lh_FUNCTION_node_stats_bio(lh,out) \
2476 LHM_lh_node_stats_bio(FUNCTION,lh,out)
2477#define lh_FUNCTION_node_usage_stats_bio(lh,out) \
2478 LHM_lh_node_usage_stats_bio(FUNCTION,lh,out)
2479#define lh_FUNCTION_stats_bio(lh,out) \
2480 LHM_lh_stats_bio(FUNCTION,lh,out)
2481#define lh_FUNCTION_free(lh) LHM_lh_free(FUNCTION,lh)
2482
2483#define lh_MEM_new() LHM_lh_new(MEM,mem)
2484#define lh_MEM_insert(lh,inst) LHM_lh_insert(MEM,lh,inst)
2485#define lh_MEM_retrieve(lh,inst) LHM_lh_retrieve(MEM,lh,inst)
2486#define lh_MEM_delete(lh,inst) LHM_lh_delete(MEM,lh,inst)
2487#define lh_MEM_doall(lh,fn) LHM_lh_doall(MEM,lh,fn)
2488#define lh_MEM_doall_arg(lh,fn,arg_type,arg) \
2489 LHM_lh_doall_arg(MEM,lh,fn,arg_type,arg)
2490#define lh_MEM_error(lh) LHM_lh_error(MEM,lh)
2491#define lh_MEM_num_items(lh) LHM_lh_num_items(MEM,lh)
2492#define lh_MEM_down_load(lh) LHM_lh_down_load(MEM,lh)
2493#define lh_MEM_node_stats_bio(lh,out) \
2494 LHM_lh_node_stats_bio(MEM,lh,out)
2495#define lh_MEM_node_usage_stats_bio(lh,out) \
2496 LHM_lh_node_usage_stats_bio(MEM,lh,out)
2497#define lh_MEM_stats_bio(lh,out) \
2498 LHM_lh_stats_bio(MEM,lh,out)
2499#define lh_MEM_free(lh) LHM_lh_free(MEM,lh)
2500
2501#define lh_OBJ_NAME_new() LHM_lh_new(OBJ_NAME,obj_name)
2502#define lh_OBJ_NAME_insert(lh,inst) LHM_lh_insert(OBJ_NAME,lh,inst)
2503#define lh_OBJ_NAME_retrieve(lh,inst) LHM_lh_retrieve(OBJ_NAME,lh,inst)
2504#define lh_OBJ_NAME_delete(lh,inst) LHM_lh_delete(OBJ_NAME,lh,inst)
2505#define lh_OBJ_NAME_doall(lh,fn) LHM_lh_doall(OBJ_NAME,lh,fn)
2506#define lh_OBJ_NAME_doall_arg(lh,fn,arg_type,arg) \
2507 LHM_lh_doall_arg(OBJ_NAME,lh,fn,arg_type,arg)
2508#define lh_OBJ_NAME_error(lh) LHM_lh_error(OBJ_NAME,lh)
2509#define lh_OBJ_NAME_num_items(lh) LHM_lh_num_items(OBJ_NAME,lh)
2510#define lh_OBJ_NAME_down_load(lh) LHM_lh_down_load(OBJ_NAME,lh)
2511#define lh_OBJ_NAME_node_stats_bio(lh,out) \
2512 LHM_lh_node_stats_bio(OBJ_NAME,lh,out)
2513#define lh_OBJ_NAME_node_usage_stats_bio(lh,out) \
2514 LHM_lh_node_usage_stats_bio(OBJ_NAME,lh,out)
2515#define lh_OBJ_NAME_stats_bio(lh,out) \
2516 LHM_lh_stats_bio(OBJ_NAME,lh,out)
2517#define lh_OBJ_NAME_free(lh) LHM_lh_free(OBJ_NAME,lh)
2518
2519#define lh_OPENSSL_CSTRING_new() LHM_lh_new(OPENSSL_CSTRING,openssl_cstring)
2520#define lh_OPENSSL_CSTRING_insert(lh,inst) LHM_lh_insert(OPENSSL_CSTRING,lh,inst)
2521#define lh_OPENSSL_CSTRING_retrieve(lh,inst) LHM_lh_retrieve(OPENSSL_CSTRING,lh,inst)
2522#define lh_OPENSSL_CSTRING_delete(lh,inst) LHM_lh_delete(OPENSSL_CSTRING,lh,inst)
2523#define lh_OPENSSL_CSTRING_doall(lh,fn) LHM_lh_doall(OPENSSL_CSTRING,lh,fn)
2524#define lh_OPENSSL_CSTRING_doall_arg(lh,fn,arg_type,arg) \
2525 LHM_lh_doall_arg(OPENSSL_CSTRING,lh,fn,arg_type,arg)
2526#define lh_OPENSSL_CSTRING_error(lh) LHM_lh_error(OPENSSL_CSTRING,lh)
2527#define lh_OPENSSL_CSTRING_num_items(lh) LHM_lh_num_items(OPENSSL_CSTRING,lh)
2528#define lh_OPENSSL_CSTRING_down_load(lh) LHM_lh_down_load(OPENSSL_CSTRING,lh)
2529#define lh_OPENSSL_CSTRING_node_stats_bio(lh,out) \
2530 LHM_lh_node_stats_bio(OPENSSL_CSTRING,lh,out)
2531#define lh_OPENSSL_CSTRING_node_usage_stats_bio(lh,out) \
2532 LHM_lh_node_usage_stats_bio(OPENSSL_CSTRING,lh,out)
2533#define lh_OPENSSL_CSTRING_stats_bio(lh,out) \
2534 LHM_lh_stats_bio(OPENSSL_CSTRING,lh,out)
2535#define lh_OPENSSL_CSTRING_free(lh) LHM_lh_free(OPENSSL_CSTRING,lh)
2536
2537#define lh_OPENSSL_STRING_new() LHM_lh_new(OPENSSL_STRING,openssl_string)
2538#define lh_OPENSSL_STRING_insert(lh,inst) LHM_lh_insert(OPENSSL_STRING,lh,inst)
2539#define lh_OPENSSL_STRING_retrieve(lh,inst) LHM_lh_retrieve(OPENSSL_STRING,lh,inst)
2540#define lh_OPENSSL_STRING_delete(lh,inst) LHM_lh_delete(OPENSSL_STRING,lh,inst)
2541#define lh_OPENSSL_STRING_doall(lh,fn) LHM_lh_doall(OPENSSL_STRING,lh,fn)
2542#define lh_OPENSSL_STRING_doall_arg(lh,fn,arg_type,arg) \
2543 LHM_lh_doall_arg(OPENSSL_STRING,lh,fn,arg_type,arg)
2544#define lh_OPENSSL_STRING_error(lh) LHM_lh_error(OPENSSL_STRING,lh)
2545#define lh_OPENSSL_STRING_num_items(lh) LHM_lh_num_items(OPENSSL_STRING,lh)
2546#define lh_OPENSSL_STRING_down_load(lh) LHM_lh_down_load(OPENSSL_STRING,lh)
2547#define lh_OPENSSL_STRING_node_stats_bio(lh,out) \
2548 LHM_lh_node_stats_bio(OPENSSL_STRING,lh,out)
2549#define lh_OPENSSL_STRING_node_usage_stats_bio(lh,out) \
2550 LHM_lh_node_usage_stats_bio(OPENSSL_STRING,lh,out)
2551#define lh_OPENSSL_STRING_stats_bio(lh,out) \
2552 LHM_lh_stats_bio(OPENSSL_STRING,lh,out)
2553#define lh_OPENSSL_STRING_free(lh) LHM_lh_free(OPENSSL_STRING,lh)
2554
2555#define lh_SSL_SESSION_new() LHM_lh_new(SSL_SESSION,ssl_session)
2556#define lh_SSL_SESSION_insert(lh,inst) LHM_lh_insert(SSL_SESSION,lh,inst)
2557#define lh_SSL_SESSION_retrieve(lh,inst) LHM_lh_retrieve(SSL_SESSION,lh,inst)
2558#define lh_SSL_SESSION_delete(lh,inst) LHM_lh_delete(SSL_SESSION,lh,inst)
2559#define lh_SSL_SESSION_doall(lh,fn) LHM_lh_doall(SSL_SESSION,lh,fn)
2560#define lh_SSL_SESSION_doall_arg(lh,fn,arg_type,arg) \
2561 LHM_lh_doall_arg(SSL_SESSION,lh,fn,arg_type,arg)
2562#define lh_SSL_SESSION_error(lh) LHM_lh_error(SSL_SESSION,lh)
2563#define lh_SSL_SESSION_num_items(lh) LHM_lh_num_items(SSL_SESSION,lh)
2564#define lh_SSL_SESSION_down_load(lh) LHM_lh_down_load(SSL_SESSION,lh)
2565#define lh_SSL_SESSION_node_stats_bio(lh,out) \
2566 LHM_lh_node_stats_bio(SSL_SESSION,lh,out)
2567#define lh_SSL_SESSION_node_usage_stats_bio(lh,out) \
2568 LHM_lh_node_usage_stats_bio(SSL_SESSION,lh,out)
2569#define lh_SSL_SESSION_stats_bio(lh,out) \
2570 LHM_lh_stats_bio(SSL_SESSION,lh,out)
2571#define lh_SSL_SESSION_free(lh) LHM_lh_free(SSL_SESSION,lh)
2028/* End of util/mkstack.pl block, you may now edit :-) */ 2572/* End of util/mkstack.pl block, you may now edit :-) */
2029 2573
2030#endif /* !defined HEADER_SAFESTACK_H */ 2574#endif /* !defined HEADER_SAFESTACK_H */
diff --git a/src/lib/libcrypto/stack/stack.c b/src/lib/libcrypto/stack/stack.c
index 378bd7c796..76cf1a1168 100644
--- a/src/lib/libcrypto/stack/stack.c
+++ b/src/lib/libcrypto/stack/stack.c
@@ -77,10 +77,10 @@ const char STACK_version[]="Stack" OPENSSL_VERSION_PTEXT;
77 77
78#include <errno.h> 78#include <errno.h>
79 79
80int (*sk_set_cmp_func(STACK *sk, int (*c)(const char * const *,const char * const *))) 80int (*sk_set_cmp_func(_STACK *sk, int (*c)(const void *, const void *)))
81 (const char * const *, const char * const *) 81 (const void *, const void *)
82 { 82 {
83 int (*old)(const char * const *,const char * const *)=sk->comp; 83 int (*old)(const void *,const void *)=sk->comp;
84 84
85 if (sk->comp != c) 85 if (sk->comp != c)
86 sk->sorted=0; 86 sk->sorted=0;
@@ -89,9 +89,9 @@ int (*sk_set_cmp_func(STACK *sk, int (*c)(const char * const *,const char * cons
89 return old; 89 return old;
90 } 90 }
91 91
92STACK *sk_dup(STACK *sk) 92_STACK *sk_dup(_STACK *sk)
93 { 93 {
94 STACK *ret; 94 _STACK *ret;
95 char **s; 95 char **s;
96 96
97 if ((ret=sk_new(sk->comp)) == NULL) goto err; 97 if ((ret=sk_new(sk->comp)) == NULL) goto err;
@@ -112,19 +112,19 @@ err:
112 return(NULL); 112 return(NULL);
113 } 113 }
114 114
115STACK *sk_new_null(void) 115_STACK *sk_new_null(void)
116 { 116 {
117 return sk_new((int (*)(const char * const *, const char * const *))0); 117 return sk_new((int (*)(const void *, const void *))0);
118 } 118 }
119 119
120STACK *sk_new(int (*c)(const char * const *, const char * const *)) 120_STACK *sk_new(int (*c)(const void *, const void *))
121 { 121 {
122 STACK *ret; 122 _STACK *ret;
123 int i; 123 int i;
124 124
125 if ((ret=(STACK *)OPENSSL_malloc(sizeof(STACK))) == NULL) 125 if ((ret=OPENSSL_malloc(sizeof(_STACK))) == NULL)
126 goto err; 126 goto err;
127 if ((ret->data=(char **)OPENSSL_malloc(sizeof(char *)*MIN_NODES)) == NULL) 127 if ((ret->data=OPENSSL_malloc(sizeof(char *)*MIN_NODES)) == NULL)
128 goto err; 128 goto err;
129 for (i=0; i<MIN_NODES; i++) 129 for (i=0; i<MIN_NODES; i++)
130 ret->data[i]=NULL; 130 ret->data[i]=NULL;
@@ -139,14 +139,14 @@ err:
139 return(NULL); 139 return(NULL);
140 } 140 }
141 141
142int sk_insert(STACK *st, char *data, int loc) 142int sk_insert(_STACK *st, void *data, int loc)
143 { 143 {
144 char **s; 144 char **s;
145 145
146 if(st == NULL) return 0; 146 if(st == NULL) return 0;
147 if (st->num_alloc <= st->num+1) 147 if (st->num_alloc <= st->num+1)
148 { 148 {
149 s=(char **)OPENSSL_realloc((char *)st->data, 149 s=OPENSSL_realloc((char *)st->data,
150 (unsigned int)sizeof(char *)*st->num_alloc*2); 150 (unsigned int)sizeof(char *)*st->num_alloc*2);
151 if (s == NULL) 151 if (s == NULL)
152 return(0); 152 return(0);
@@ -160,14 +160,14 @@ int sk_insert(STACK *st, char *data, int loc)
160 int i; 160 int i;
161 char **f,**t; 161 char **f,**t;
162 162
163 f=(char **)st->data; 163 f=st->data;
164 t=(char **)&(st->data[1]); 164 t=&(st->data[1]);
165 for (i=st->num; i>=loc; i--) 165 for (i=st->num; i>=loc; i--)
166 t[i]=f[i]; 166 t[i]=f[i];
167 167
168#ifdef undef /* no memmove on sunos :-( */ 168#ifdef undef /* no memmove on sunos :-( */
169 memmove( (char *)&(st->data[loc+1]), 169 memmove(&(st->data[loc+1]),
170 (char *)&(st->data[loc]), 170 &(st->data[loc]),
171 sizeof(char *)*(st->num-loc)); 171 sizeof(char *)*(st->num-loc));
172#endif 172#endif
173 st->data[loc]=data; 173 st->data[loc]=data;
@@ -177,7 +177,7 @@ int sk_insert(STACK *st, char *data, int loc)
177 return(st->num); 177 return(st->num);
178 } 178 }
179 179
180char *sk_delete_ptr(STACK *st, char *p) 180void *sk_delete_ptr(_STACK *st, void *p)
181 { 181 {
182 int i; 182 int i;
183 183
@@ -187,7 +187,7 @@ char *sk_delete_ptr(STACK *st, char *p)
187 return(NULL); 187 return(NULL);
188 } 188 }
189 189
190char *sk_delete(STACK *st, int loc) 190void *sk_delete(_STACK *st, int loc)
191 { 191 {
192 char *ret; 192 char *ret;
193 int i,j; 193 int i,j;
@@ -210,11 +210,11 @@ char *sk_delete(STACK *st, int loc)
210 return(ret); 210 return(ret);
211 } 211 }
212 212
213static int internal_find(STACK *st, char *data, int ret_val_options) 213static int internal_find(_STACK *st, void *data, int ret_val_options)
214 { 214 {
215 char **r; 215 const void * const *r;
216 int i; 216 int i;
217 int (*comp_func)(const void *,const void *); 217
218 if(st == NULL) return -1; 218 if(st == NULL) return -1;
219 219
220 if (st->comp == NULL) 220 if (st->comp == NULL)
@@ -226,53 +226,46 @@ static int internal_find(STACK *st, char *data, int ret_val_options)
226 } 226 }
227 sk_sort(st); 227 sk_sort(st);
228 if (data == NULL) return(-1); 228 if (data == NULL) return(-1);
229 /* This (and the "qsort" below) are the two places in OpenSSL 229 r=OBJ_bsearch_ex_(&data,st->data,st->num,sizeof(void *),st->comp,
230 * where we need to convert from our standard (type **,type **) 230 ret_val_options);
231 * compare callback type to the (void *,void *) type required by
232 * bsearch. However, the "data" it is being called(back) with are
233 * not (type *) pointers, but the *pointers* to (type *) pointers,
234 * so we get our extra level of pointer dereferencing that way. */
235 comp_func=(int (*)(const void *,const void *))(st->comp);
236 r=(char **)OBJ_bsearch_ex((char *)&data,(char *)st->data,
237 st->num,sizeof(char *),comp_func,ret_val_options);
238 if (r == NULL) return(-1); 231 if (r == NULL) return(-1);
239 return((int)(r-st->data)); 232 return (int)((char **)r-st->data);
240 } 233 }
241 234
242int sk_find(STACK *st, char *data) 235int sk_find(_STACK *st, void *data)
243 { 236 {
244 return internal_find(st, data, OBJ_BSEARCH_FIRST_VALUE_ON_MATCH); 237 return internal_find(st, data, OBJ_BSEARCH_FIRST_VALUE_ON_MATCH);
245 } 238 }
246int sk_find_ex(STACK *st, char *data) 239int sk_find_ex(_STACK *st, void *data)
247 { 240 {
248 return internal_find(st, data, OBJ_BSEARCH_VALUE_ON_NOMATCH); 241 return internal_find(st, data, OBJ_BSEARCH_VALUE_ON_NOMATCH);
249 } 242 }
250 243
251int sk_push(STACK *st, char *data) 244int sk_push(_STACK *st, void *data)
252 { 245 {
253 return(sk_insert(st,data,st->num)); 246 return(sk_insert(st,data,st->num));
254 } 247 }
255 248
256int sk_unshift(STACK *st, char *data) 249int sk_unshift(_STACK *st, void *data)
257 { 250 {
258 return(sk_insert(st,data,0)); 251 return(sk_insert(st,data,0));
259 } 252 }
260 253
261char *sk_shift(STACK *st) 254void *sk_shift(_STACK *st)
262 { 255 {
263 if (st == NULL) return(NULL); 256 if (st == NULL) return(NULL);
264 if (st->num <= 0) return(NULL); 257 if (st->num <= 0) return(NULL);
265 return(sk_delete(st,0)); 258 return(sk_delete(st,0));
266 } 259 }
267 260
268char *sk_pop(STACK *st) 261void *sk_pop(_STACK *st)
269 { 262 {
270 if (st == NULL) return(NULL); 263 if (st == NULL) return(NULL);
271 if (st->num <= 0) return(NULL); 264 if (st->num <= 0) return(NULL);
272 return(sk_delete(st,st->num-1)); 265 return(sk_delete(st,st->num-1));
273 } 266 }
274 267
275void sk_zero(STACK *st) 268void sk_zero(_STACK *st)
276 { 269 {
277 if (st == NULL) return; 270 if (st == NULL) return;
278 if (st->num <= 0) return; 271 if (st->num <= 0) return;
@@ -280,7 +273,7 @@ void sk_zero(STACK *st)
280 st->num=0; 273 st->num=0;
281 } 274 }
282 275
283void sk_pop_free(STACK *st, void (*func)(void *)) 276void sk_pop_free(_STACK *st, void (*func)(void *))
284 { 277 {
285 int i; 278 int i;
286 279
@@ -291,32 +284,32 @@ void sk_pop_free(STACK *st, void (*func)(void *))
291 sk_free(st); 284 sk_free(st);
292 } 285 }
293 286
294void sk_free(STACK *st) 287void sk_free(_STACK *st)
295 { 288 {
296 if (st == NULL) return; 289 if (st == NULL) return;
297 if (st->data != NULL) OPENSSL_free(st->data); 290 if (st->data != NULL) OPENSSL_free(st->data);
298 OPENSSL_free(st); 291 OPENSSL_free(st);
299 } 292 }
300 293
301int sk_num(const STACK *st) 294int sk_num(const _STACK *st)
302{ 295{
303 if(st == NULL) return -1; 296 if(st == NULL) return -1;
304 return st->num; 297 return st->num;
305} 298}
306 299
307char *sk_value(const STACK *st, int i) 300void *sk_value(const _STACK *st, int i)
308{ 301{
309 if(!st || (i < 0) || (i >= st->num)) return NULL; 302 if(!st || (i < 0) || (i >= st->num)) return NULL;
310 return st->data[i]; 303 return st->data[i];
311} 304}
312 305
313char *sk_set(STACK *st, int i, char *value) 306void *sk_set(_STACK *st, int i, void *value)
314{ 307{
315 if(!st || (i < 0) || (i >= st->num)) return NULL; 308 if(!st || (i < 0) || (i >= st->num)) return NULL;
316 return (st->data[i] = value); 309 return (st->data[i] = value);
317} 310}
318 311
319void sk_sort(STACK *st) 312void sk_sort(_STACK *st)
320 { 313 {
321 if (st && !st->sorted) 314 if (st && !st->sorted)
322 { 315 {
@@ -333,7 +326,7 @@ void sk_sort(STACK *st)
333 } 326 }
334 } 327 }
335 328
336int sk_is_sorted(const STACK *st) 329int sk_is_sorted(const _STACK *st)
337 { 330 {
338 if (!st) 331 if (!st)
339 return 1; 332 return 1;
diff --git a/src/lib/libcrypto/stack/stack.h b/src/lib/libcrypto/stack/stack.h
index 5cbb116a8b..ce35e554eb 100644
--- a/src/lib/libcrypto/stack/stack.h
+++ b/src/lib/libcrypto/stack/stack.h
@@ -70,37 +70,36 @@ typedef struct stack_st
70 int sorted; 70 int sorted;
71 71
72 int num_alloc; 72 int num_alloc;
73 int (*comp)(const char * const *, const char * const *); 73 int (*comp)(const void *, const void *);
74 } STACK; 74 } _STACK; /* Use STACK_OF(...) instead */
75 75
76#define M_sk_num(sk) ((sk) ? (sk)->num:-1) 76#define M_sk_num(sk) ((sk) ? (sk)->num:-1)
77#define M_sk_value(sk,n) ((sk) ? (sk)->data[n] : NULL) 77#define M_sk_value(sk,n) ((sk) ? (sk)->data[n] : NULL)
78 78
79int sk_num(const STACK *); 79int sk_num(const _STACK *);
80char *sk_value(const STACK *, int); 80void *sk_value(const _STACK *, int);
81 81
82char *sk_set(STACK *, int, char *); 82void *sk_set(_STACK *, int, void *);
83 83
84STACK *sk_new(int (*cmp)(const char * const *, const char * const *)); 84_STACK *sk_new(int (*cmp)(const void *, const void *));
85STACK *sk_new_null(void); 85_STACK *sk_new_null(void);
86void sk_free(STACK *); 86void sk_free(_STACK *);
87void sk_pop_free(STACK *st, void (*func)(void *)); 87void sk_pop_free(_STACK *st, void (*func)(void *));
88int sk_insert(STACK *sk,char *data,int where); 88int sk_insert(_STACK *sk, void *data, int where);
89char *sk_delete(STACK *st,int loc); 89void *sk_delete(_STACK *st, int loc);
90char *sk_delete_ptr(STACK *st, char *p); 90void *sk_delete_ptr(_STACK *st, void *p);
91int sk_find(STACK *st,char *data); 91int sk_find(_STACK *st, void *data);
92int sk_find_ex(STACK *st,char *data); 92int sk_find_ex(_STACK *st, void *data);
93int sk_push(STACK *st,char *data); 93int sk_push(_STACK *st, void *data);
94int sk_unshift(STACK *st,char *data); 94int sk_unshift(_STACK *st, void *data);
95char *sk_shift(STACK *st); 95void *sk_shift(_STACK *st);
96char *sk_pop(STACK *st); 96void *sk_pop(_STACK *st);
97void sk_zero(STACK *st); 97void sk_zero(_STACK *st);
98int (*sk_set_cmp_func(STACK *sk, int (*c)(const char * const *, 98int (*sk_set_cmp_func(_STACK *sk, int (*c)(const void *, const void *)))
99 const char * const *))) 99 (const void *, const void *);
100 (const char * const *, const char * const *); 100_STACK *sk_dup(_STACK *st);
101STACK *sk_dup(STACK *st); 101void sk_sort(_STACK *st);
102void sk_sort(STACK *st); 102int sk_is_sorted(const _STACK *st);
103int sk_is_sorted(const STACK *st);
104 103
105#ifdef __cplusplus 104#ifdef __cplusplus
106} 105}
diff --git a/src/lib/libcrypto/ts/ts.h b/src/lib/libcrypto/ts/ts.h
new file mode 100644
index 0000000000..190e8a1bf2
--- /dev/null
+++ b/src/lib/libcrypto/ts/ts.h
@@ -0,0 +1,861 @@
1/* crypto/ts/ts.h */
2/* Written by Zoltan Glozik (zglozik@opentsa.org) for the OpenSSL
3 * project 2002, 2003, 2004.
4 */
5/* ====================================================================
6 * Copyright (c) 2006 The OpenSSL Project. All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 *
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 *
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in
17 * the documentation and/or other materials provided with the
18 * distribution.
19 *
20 * 3. All advertising materials mentioning features or use of this
21 * software must display the following acknowledgment:
22 * "This product includes software developed by the OpenSSL Project
23 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
24 *
25 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
26 * endorse or promote products derived from this software without
27 * prior written permission. For written permission, please contact
28 * licensing@OpenSSL.org.
29 *
30 * 5. Products derived from this software may not be called "OpenSSL"
31 * nor may "OpenSSL" appear in their names without prior written
32 * permission of the OpenSSL Project.
33 *
34 * 6. Redistributions of any form whatsoever must retain the following
35 * acknowledgment:
36 * "This product includes software developed by the OpenSSL Project
37 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
38 *
39 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
40 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
43 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
50 * OF THE POSSIBILITY OF SUCH DAMAGE.
51 * ====================================================================
52 *
53 * This product includes cryptographic software written by Eric Young
54 * (eay@cryptsoft.com). This product includes software written by Tim
55 * Hudson (tjh@cryptsoft.com).
56 *
57 */
58
59#ifndef HEADER_TS_H
60#define HEADER_TS_H
61
62#include <openssl/opensslconf.h>
63#include <openssl/symhacks.h>
64#ifndef OPENSSL_NO_BUFFER
65#include <openssl/buffer.h>
66#endif
67#ifndef OPENSSL_NO_EVP
68#include <openssl/evp.h>
69#endif
70#ifndef OPENSSL_NO_BIO
71#include <openssl/bio.h>
72#endif
73#include <openssl/stack.h>
74#include <openssl/asn1.h>
75#include <openssl/safestack.h>
76
77#ifndef OPENSSL_NO_RSA
78#include <openssl/rsa.h>
79#endif
80
81#ifndef OPENSSL_NO_DSA
82#include <openssl/dsa.h>
83#endif
84
85#ifndef OPENSSL_NO_DH
86#include <openssl/dh.h>
87#endif
88
89#include <openssl/evp.h>
90
91
92#ifdef __cplusplus
93extern "C" {
94#endif
95
96#ifdef WIN32
97/* Under Win32 this is defined in wincrypt.h */
98#undef X509_NAME
99#endif
100
101#include <openssl/x509.h>
102#include <openssl/x509v3.h>
103
104/*
105MessageImprint ::= SEQUENCE {
106 hashAlgorithm AlgorithmIdentifier,
107 hashedMessage OCTET STRING }
108*/
109
110typedef struct TS_msg_imprint_st
111 {
112 X509_ALGOR *hash_algo;
113 ASN1_OCTET_STRING *hashed_msg;
114 } TS_MSG_IMPRINT;
115
116/*
117TimeStampReq ::= SEQUENCE {
118 version INTEGER { v1(1) },
119 messageImprint MessageImprint,
120 --a hash algorithm OID and the hash value of the data to be
121 --time-stamped
122 reqPolicy TSAPolicyId OPTIONAL,
123 nonce INTEGER OPTIONAL,
124 certReq BOOLEAN DEFAULT FALSE,
125 extensions [0] IMPLICIT Extensions OPTIONAL }
126*/
127
128typedef struct TS_req_st
129 {
130 ASN1_INTEGER *version;
131 TS_MSG_IMPRINT *msg_imprint;
132 ASN1_OBJECT *policy_id; /* OPTIONAL */
133 ASN1_INTEGER *nonce; /* OPTIONAL */
134 ASN1_BOOLEAN cert_req; /* DEFAULT FALSE */
135 STACK_OF(X509_EXTENSION) *extensions; /* [0] OPTIONAL */
136 } TS_REQ;
137
138/*
139Accuracy ::= SEQUENCE {
140 seconds INTEGER OPTIONAL,
141 millis [0] INTEGER (1..999) OPTIONAL,
142 micros [1] INTEGER (1..999) OPTIONAL }
143*/
144
145typedef struct TS_accuracy_st
146 {
147 ASN1_INTEGER *seconds;
148 ASN1_INTEGER *millis;
149 ASN1_INTEGER *micros;
150 } TS_ACCURACY;
151
152/*
153TSTInfo ::= SEQUENCE {
154 version INTEGER { v1(1) },
155 policy TSAPolicyId,
156 messageImprint MessageImprint,
157 -- MUST have the same value as the similar field in
158 -- TimeStampReq
159 serialNumber INTEGER,
160 -- Time-Stamping users MUST be ready to accommodate integers
161 -- up to 160 bits.
162 genTime GeneralizedTime,
163 accuracy Accuracy OPTIONAL,
164 ordering BOOLEAN DEFAULT FALSE,
165 nonce INTEGER OPTIONAL,
166 -- MUST be present if the similar field was present
167 -- in TimeStampReq. In that case it MUST have the same value.
168 tsa [0] GeneralName OPTIONAL,
169 extensions [1] IMPLICIT Extensions OPTIONAL }
170*/
171
172typedef struct TS_tst_info_st
173 {
174 ASN1_INTEGER *version;
175 ASN1_OBJECT *policy_id;
176 TS_MSG_IMPRINT *msg_imprint;
177 ASN1_INTEGER *serial;
178 ASN1_GENERALIZEDTIME *time;
179 TS_ACCURACY *accuracy;
180 ASN1_BOOLEAN ordering;
181 ASN1_INTEGER *nonce;
182 GENERAL_NAME *tsa;
183 STACK_OF(X509_EXTENSION) *extensions;
184 } TS_TST_INFO;
185
186/*
187PKIStatusInfo ::= SEQUENCE {
188 status PKIStatus,
189 statusString PKIFreeText OPTIONAL,
190 failInfo PKIFailureInfo OPTIONAL }
191
192From RFC 1510 - section 3.1.1:
193PKIFreeText ::= SEQUENCE SIZE (1..MAX) OF UTF8String
194 -- text encoded as UTF-8 String (note: each UTF8String SHOULD
195 -- include an RFC 1766 language tag to indicate the language
196 -- of the contained text)
197*/
198
199/* Possible values for status. See ts_resp_print.c && ts_resp_verify.c. */
200
201#define TS_STATUS_GRANTED 0
202#define TS_STATUS_GRANTED_WITH_MODS 1
203#define TS_STATUS_REJECTION 2
204#define TS_STATUS_WAITING 3
205#define TS_STATUS_REVOCATION_WARNING 4
206#define TS_STATUS_REVOCATION_NOTIFICATION 5
207
208/* Possible values for failure_info. See ts_resp_print.c && ts_resp_verify.c */
209
210#define TS_INFO_BAD_ALG 0
211#define TS_INFO_BAD_REQUEST 2
212#define TS_INFO_BAD_DATA_FORMAT 5
213#define TS_INFO_TIME_NOT_AVAILABLE 14
214#define TS_INFO_UNACCEPTED_POLICY 15
215#define TS_INFO_UNACCEPTED_EXTENSION 16
216#define TS_INFO_ADD_INFO_NOT_AVAILABLE 17
217#define TS_INFO_SYSTEM_FAILURE 25
218
219typedef struct TS_status_info_st
220 {
221 ASN1_INTEGER *status;
222 STACK_OF(ASN1_UTF8STRING) *text;
223 ASN1_BIT_STRING *failure_info;
224 } TS_STATUS_INFO;
225
226DECLARE_STACK_OF(ASN1_UTF8STRING)
227DECLARE_ASN1_SET_OF(ASN1_UTF8STRING)
228
229/*
230TimeStampResp ::= SEQUENCE {
231 status PKIStatusInfo,
232 timeStampToken TimeStampToken OPTIONAL }
233*/
234
235typedef struct TS_resp_st
236 {
237 TS_STATUS_INFO *status_info;
238 PKCS7 *token;
239 TS_TST_INFO *tst_info;
240 } TS_RESP;
241
242/* The structure below would belong to the ESS component. */
243
244/*
245IssuerSerial ::= SEQUENCE {
246 issuer GeneralNames,
247 serialNumber CertificateSerialNumber
248 }
249*/
250
251typedef struct ESS_issuer_serial
252 {
253 STACK_OF(GENERAL_NAME) *issuer;
254 ASN1_INTEGER *serial;
255 } ESS_ISSUER_SERIAL;
256
257/*
258ESSCertID ::= SEQUENCE {
259 certHash Hash,
260 issuerSerial IssuerSerial OPTIONAL
261}
262*/
263
264typedef struct ESS_cert_id
265 {
266 ASN1_OCTET_STRING *hash; /* Always SHA-1 digest. */
267 ESS_ISSUER_SERIAL *issuer_serial;
268 } ESS_CERT_ID;
269
270DECLARE_STACK_OF(ESS_CERT_ID)
271DECLARE_ASN1_SET_OF(ESS_CERT_ID)
272
273/*
274SigningCertificate ::= SEQUENCE {
275 certs SEQUENCE OF ESSCertID,
276 policies SEQUENCE OF PolicyInformation OPTIONAL
277}
278*/
279
280typedef struct ESS_signing_cert
281 {
282 STACK_OF(ESS_CERT_ID) *cert_ids;
283 STACK_OF(POLICYINFO) *policy_info;
284 } ESS_SIGNING_CERT;
285
286
287TS_REQ *TS_REQ_new(void);
288void TS_REQ_free(TS_REQ *a);
289int i2d_TS_REQ(const TS_REQ *a, unsigned char **pp);
290TS_REQ *d2i_TS_REQ(TS_REQ **a, const unsigned char **pp, long length);
291
292TS_REQ *TS_REQ_dup(TS_REQ *a);
293
294TS_REQ *d2i_TS_REQ_fp(FILE *fp, TS_REQ **a);
295int i2d_TS_REQ_fp(FILE *fp, TS_REQ *a);
296TS_REQ *d2i_TS_REQ_bio(BIO *fp, TS_REQ **a);
297int i2d_TS_REQ_bio(BIO *fp, TS_REQ *a);
298
299TS_MSG_IMPRINT *TS_MSG_IMPRINT_new(void);
300void TS_MSG_IMPRINT_free(TS_MSG_IMPRINT *a);
301int i2d_TS_MSG_IMPRINT(const TS_MSG_IMPRINT *a, unsigned char **pp);
302TS_MSG_IMPRINT *d2i_TS_MSG_IMPRINT(TS_MSG_IMPRINT **a,
303 const unsigned char **pp, long length);
304
305TS_MSG_IMPRINT *TS_MSG_IMPRINT_dup(TS_MSG_IMPRINT *a);
306
307TS_MSG_IMPRINT *d2i_TS_MSG_IMPRINT_fp(FILE *fp, TS_MSG_IMPRINT **a);
308int i2d_TS_MSG_IMPRINT_fp(FILE *fp, TS_MSG_IMPRINT *a);
309TS_MSG_IMPRINT *d2i_TS_MSG_IMPRINT_bio(BIO *fp, TS_MSG_IMPRINT **a);
310int i2d_TS_MSG_IMPRINT_bio(BIO *fp, TS_MSG_IMPRINT *a);
311
312TS_RESP *TS_RESP_new(void);
313void TS_RESP_free(TS_RESP *a);
314int i2d_TS_RESP(const TS_RESP *a, unsigned char **pp);
315TS_RESP *d2i_TS_RESP(TS_RESP **a, const unsigned char **pp, long length);
316TS_TST_INFO *PKCS7_to_TS_TST_INFO(PKCS7 *token);
317TS_RESP *TS_RESP_dup(TS_RESP *a);
318
319TS_RESP *d2i_TS_RESP_fp(FILE *fp, TS_RESP **a);
320int i2d_TS_RESP_fp(FILE *fp, TS_RESP *a);
321TS_RESP *d2i_TS_RESP_bio(BIO *fp, TS_RESP **a);
322int i2d_TS_RESP_bio(BIO *fp, TS_RESP *a);
323
324TS_STATUS_INFO *TS_STATUS_INFO_new(void);
325void TS_STATUS_INFO_free(TS_STATUS_INFO *a);
326int i2d_TS_STATUS_INFO(const TS_STATUS_INFO *a, unsigned char **pp);
327TS_STATUS_INFO *d2i_TS_STATUS_INFO(TS_STATUS_INFO **a,
328 const unsigned char **pp, long length);
329TS_STATUS_INFO *TS_STATUS_INFO_dup(TS_STATUS_INFO *a);
330
331TS_TST_INFO *TS_TST_INFO_new(void);
332void TS_TST_INFO_free(TS_TST_INFO *a);
333int i2d_TS_TST_INFO(const TS_TST_INFO *a, unsigned char **pp);
334TS_TST_INFO *d2i_TS_TST_INFO(TS_TST_INFO **a, const unsigned char **pp,
335 long length);
336TS_TST_INFO *TS_TST_INFO_dup(TS_TST_INFO *a);
337
338TS_TST_INFO *d2i_TS_TST_INFO_fp(FILE *fp, TS_TST_INFO **a);
339int i2d_TS_TST_INFO_fp(FILE *fp, TS_TST_INFO *a);
340TS_TST_INFO *d2i_TS_TST_INFO_bio(BIO *fp, TS_TST_INFO **a);
341int i2d_TS_TST_INFO_bio(BIO *fp, TS_TST_INFO *a);
342
343TS_ACCURACY *TS_ACCURACY_new(void);
344void TS_ACCURACY_free(TS_ACCURACY *a);
345int i2d_TS_ACCURACY(const TS_ACCURACY *a, unsigned char **pp);
346TS_ACCURACY *d2i_TS_ACCURACY(TS_ACCURACY **a, const unsigned char **pp,
347 long length);
348TS_ACCURACY *TS_ACCURACY_dup(TS_ACCURACY *a);
349
350ESS_ISSUER_SERIAL *ESS_ISSUER_SERIAL_new(void);
351void ESS_ISSUER_SERIAL_free(ESS_ISSUER_SERIAL *a);
352int i2d_ESS_ISSUER_SERIAL(const ESS_ISSUER_SERIAL *a,
353 unsigned char **pp);
354ESS_ISSUER_SERIAL *d2i_ESS_ISSUER_SERIAL(ESS_ISSUER_SERIAL **a,
355 const unsigned char **pp, long length);
356ESS_ISSUER_SERIAL *ESS_ISSUER_SERIAL_dup(ESS_ISSUER_SERIAL *a);
357
358ESS_CERT_ID *ESS_CERT_ID_new(void);
359void ESS_CERT_ID_free(ESS_CERT_ID *a);
360int i2d_ESS_CERT_ID(const ESS_CERT_ID *a, unsigned char **pp);
361ESS_CERT_ID *d2i_ESS_CERT_ID(ESS_CERT_ID **a, const unsigned char **pp,
362 long length);
363ESS_CERT_ID *ESS_CERT_ID_dup(ESS_CERT_ID *a);
364
365ESS_SIGNING_CERT *ESS_SIGNING_CERT_new(void);
366void ESS_SIGNING_CERT_free(ESS_SIGNING_CERT *a);
367int i2d_ESS_SIGNING_CERT(const ESS_SIGNING_CERT *a,
368 unsigned char **pp);
369ESS_SIGNING_CERT *d2i_ESS_SIGNING_CERT(ESS_SIGNING_CERT **a,
370 const unsigned char **pp, long length);
371ESS_SIGNING_CERT *ESS_SIGNING_CERT_dup(ESS_SIGNING_CERT *a);
372
373void ERR_load_TS_strings(void);
374
375int TS_REQ_set_version(TS_REQ *a, long version);
376long TS_REQ_get_version(const TS_REQ *a);
377
378int TS_REQ_set_msg_imprint(TS_REQ *a, TS_MSG_IMPRINT *msg_imprint);
379TS_MSG_IMPRINT *TS_REQ_get_msg_imprint(TS_REQ *a);
380
381int TS_MSG_IMPRINT_set_algo(TS_MSG_IMPRINT *a, X509_ALGOR *alg);
382X509_ALGOR *TS_MSG_IMPRINT_get_algo(TS_MSG_IMPRINT *a);
383
384int TS_MSG_IMPRINT_set_msg(TS_MSG_IMPRINT *a, unsigned char *d, int len);
385ASN1_OCTET_STRING *TS_MSG_IMPRINT_get_msg(TS_MSG_IMPRINT *a);
386
387int TS_REQ_set_policy_id(TS_REQ *a, ASN1_OBJECT *policy);
388ASN1_OBJECT *TS_REQ_get_policy_id(TS_REQ *a);
389
390int TS_REQ_set_nonce(TS_REQ *a, const ASN1_INTEGER *nonce);
391const ASN1_INTEGER *TS_REQ_get_nonce(const TS_REQ *a);
392
393int TS_REQ_set_cert_req(TS_REQ *a, int cert_req);
394int TS_REQ_get_cert_req(const TS_REQ *a);
395
396STACK_OF(X509_EXTENSION) *TS_REQ_get_exts(TS_REQ *a);
397void TS_REQ_ext_free(TS_REQ *a);
398int TS_REQ_get_ext_count(TS_REQ *a);
399int TS_REQ_get_ext_by_NID(TS_REQ *a, int nid, int lastpos);
400int TS_REQ_get_ext_by_OBJ(TS_REQ *a, ASN1_OBJECT *obj, int lastpos);
401int TS_REQ_get_ext_by_critical(TS_REQ *a, int crit, int lastpos);
402X509_EXTENSION *TS_REQ_get_ext(TS_REQ *a, int loc);
403X509_EXTENSION *TS_REQ_delete_ext(TS_REQ *a, int loc);
404int TS_REQ_add_ext(TS_REQ *a, X509_EXTENSION *ex, int loc);
405void *TS_REQ_get_ext_d2i(TS_REQ *a, int nid, int *crit, int *idx);
406
407/* Function declarations for TS_REQ defined in ts/ts_req_print.c */
408
409int TS_REQ_print_bio(BIO *bio, TS_REQ *a);
410
411/* Function declarations for TS_RESP defined in ts/ts_resp_utils.c */
412
413int TS_RESP_set_status_info(TS_RESP *a, TS_STATUS_INFO *info);
414TS_STATUS_INFO *TS_RESP_get_status_info(TS_RESP *a);
415
416/* Caller loses ownership of PKCS7 and TS_TST_INFO objects. */
417void TS_RESP_set_tst_info(TS_RESP *a, PKCS7 *p7, TS_TST_INFO *tst_info);
418PKCS7 *TS_RESP_get_token(TS_RESP *a);
419TS_TST_INFO *TS_RESP_get_tst_info(TS_RESP *a);
420
421int TS_TST_INFO_set_version(TS_TST_INFO *a, long version);
422long TS_TST_INFO_get_version(const TS_TST_INFO *a);
423
424int TS_TST_INFO_set_policy_id(TS_TST_INFO *a, ASN1_OBJECT *policy_id);
425ASN1_OBJECT *TS_TST_INFO_get_policy_id(TS_TST_INFO *a);
426
427int TS_TST_INFO_set_msg_imprint(TS_TST_INFO *a, TS_MSG_IMPRINT *msg_imprint);
428TS_MSG_IMPRINT *TS_TST_INFO_get_msg_imprint(TS_TST_INFO *a);
429
430int TS_TST_INFO_set_serial(TS_TST_INFO *a, const ASN1_INTEGER *serial);
431const ASN1_INTEGER *TS_TST_INFO_get_serial(const TS_TST_INFO *a);
432
433int TS_TST_INFO_set_time(TS_TST_INFO *a, const ASN1_GENERALIZEDTIME *gtime);
434const ASN1_GENERALIZEDTIME *TS_TST_INFO_get_time(const TS_TST_INFO *a);
435
436int TS_TST_INFO_set_accuracy(TS_TST_INFO *a, TS_ACCURACY *accuracy);
437TS_ACCURACY *TS_TST_INFO_get_accuracy(TS_TST_INFO *a);
438
439int TS_ACCURACY_set_seconds(TS_ACCURACY *a, const ASN1_INTEGER *seconds);
440const ASN1_INTEGER *TS_ACCURACY_get_seconds(const TS_ACCURACY *a);
441
442int TS_ACCURACY_set_millis(TS_ACCURACY *a, const ASN1_INTEGER *millis);
443const ASN1_INTEGER *TS_ACCURACY_get_millis(const TS_ACCURACY *a);
444
445int TS_ACCURACY_set_micros(TS_ACCURACY *a, const ASN1_INTEGER *micros);
446const ASN1_INTEGER *TS_ACCURACY_get_micros(const TS_ACCURACY *a);
447
448int TS_TST_INFO_set_ordering(TS_TST_INFO *a, int ordering);
449int TS_TST_INFO_get_ordering(const TS_TST_INFO *a);
450
451int TS_TST_INFO_set_nonce(TS_TST_INFO *a, const ASN1_INTEGER *nonce);
452const ASN1_INTEGER *TS_TST_INFO_get_nonce(const TS_TST_INFO *a);
453
454int TS_TST_INFO_set_tsa(TS_TST_INFO *a, GENERAL_NAME *tsa);
455GENERAL_NAME *TS_TST_INFO_get_tsa(TS_TST_INFO *a);
456
457STACK_OF(X509_EXTENSION) *TS_TST_INFO_get_exts(TS_TST_INFO *a);
458void TS_TST_INFO_ext_free(TS_TST_INFO *a);
459int TS_TST_INFO_get_ext_count(TS_TST_INFO *a);
460int TS_TST_INFO_get_ext_by_NID(TS_TST_INFO *a, int nid, int lastpos);
461int TS_TST_INFO_get_ext_by_OBJ(TS_TST_INFO *a, ASN1_OBJECT *obj, int lastpos);
462int TS_TST_INFO_get_ext_by_critical(TS_TST_INFO *a, int crit, int lastpos);
463X509_EXTENSION *TS_TST_INFO_get_ext(TS_TST_INFO *a, int loc);
464X509_EXTENSION *TS_TST_INFO_delete_ext(TS_TST_INFO *a, int loc);
465int TS_TST_INFO_add_ext(TS_TST_INFO *a, X509_EXTENSION *ex, int loc);
466void *TS_TST_INFO_get_ext_d2i(TS_TST_INFO *a, int nid, int *crit, int *idx);
467
468/* Declarations related to response generation, defined in ts/ts_resp_sign.c. */
469
470/* Optional flags for response generation. */
471
472/* Don't include the TSA name in response. */
473#define TS_TSA_NAME 0x01
474
475/* Set ordering to true in response. */
476#define TS_ORDERING 0x02
477
478/*
479 * Include the signer certificate and the other specified certificates in
480 * the ESS signing certificate attribute beside the PKCS7 signed data.
481 * Only the signer certificates is included by default.
482 */
483#define TS_ESS_CERT_ID_CHAIN 0x04
484
485/* Forward declaration. */
486struct TS_resp_ctx;
487
488/* This must return a unique number less than 160 bits long. */
489typedef ASN1_INTEGER *(*TS_serial_cb)(struct TS_resp_ctx *, void *);
490
491/* This must return the seconds and microseconds since Jan 1, 1970 in
492 the sec and usec variables allocated by the caller.
493 Return non-zero for success and zero for failure. */
494typedef int (*TS_time_cb)(struct TS_resp_ctx *, void *, long *sec, long *usec);
495
496/* This must process the given extension.
497 * It can modify the TS_TST_INFO object of the context.
498 * Return values: !0 (processed), 0 (error, it must set the
499 * status info/failure info of the response).
500 */
501typedef int (*TS_extension_cb)(struct TS_resp_ctx *, X509_EXTENSION *, void *);
502
503typedef struct TS_resp_ctx
504 {
505 X509 *signer_cert;
506 EVP_PKEY *signer_key;
507 STACK_OF(X509) *certs; /* Certs to include in signed data. */
508 STACK_OF(ASN1_OBJECT) *policies; /* Acceptable policies. */
509 ASN1_OBJECT *default_policy; /* It may appear in policies, too. */
510 STACK_OF(EVP_MD) *mds; /* Acceptable message digests. */
511 ASN1_INTEGER *seconds; /* accuracy, 0 means not specified. */
512 ASN1_INTEGER *millis; /* accuracy, 0 means not specified. */
513 ASN1_INTEGER *micros; /* accuracy, 0 means not specified. */
514 unsigned clock_precision_digits; /* fraction of seconds in
515 time stamp token. */
516 unsigned flags; /* Optional info, see values above. */
517
518 /* Callback functions. */
519 TS_serial_cb serial_cb;
520 void *serial_cb_data; /* User data for serial_cb. */
521
522 TS_time_cb time_cb;
523 void *time_cb_data; /* User data for time_cb. */
524
525 TS_extension_cb extension_cb;
526 void *extension_cb_data; /* User data for extension_cb. */
527
528 /* These members are used only while creating the response. */
529 TS_REQ *request;
530 TS_RESP *response;
531 TS_TST_INFO *tst_info;
532 } TS_RESP_CTX;
533
534DECLARE_STACK_OF(EVP_MD)
535DECLARE_ASN1_SET_OF(EVP_MD)
536
537/* Creates a response context that can be used for generating responses. */
538TS_RESP_CTX *TS_RESP_CTX_new(void);
539void TS_RESP_CTX_free(TS_RESP_CTX *ctx);
540
541/* This parameter must be set. */
542int TS_RESP_CTX_set_signer_cert(TS_RESP_CTX *ctx, X509 *signer);
543
544/* This parameter must be set. */
545int TS_RESP_CTX_set_signer_key(TS_RESP_CTX *ctx, EVP_PKEY *key);
546
547/* This parameter must be set. */
548int TS_RESP_CTX_set_def_policy(TS_RESP_CTX *ctx, ASN1_OBJECT *def_policy);
549
550/* No additional certs are included in the response by default. */
551int TS_RESP_CTX_set_certs(TS_RESP_CTX *ctx, STACK_OF(X509) *certs);
552
553/* Adds a new acceptable policy, only the default policy
554 is accepted by default. */
555int TS_RESP_CTX_add_policy(TS_RESP_CTX *ctx, ASN1_OBJECT *policy);
556
557/* Adds a new acceptable message digest. Note that no message digests
558 are accepted by default. The md argument is shared with the caller. */
559int TS_RESP_CTX_add_md(TS_RESP_CTX *ctx, const EVP_MD *md);
560
561/* Accuracy is not included by default. */
562int TS_RESP_CTX_set_accuracy(TS_RESP_CTX *ctx,
563 int secs, int millis, int micros);
564
565/* Clock precision digits, i.e. the number of decimal digits:
566 '0' means sec, '3' msec, '6' usec, and so on. Default is 0. */
567int TS_RESP_CTX_set_clock_precision_digits(TS_RESP_CTX *ctx,
568 unsigned clock_precision_digits);
569/* At most we accept usec precision. */
570#define TS_MAX_CLOCK_PRECISION_DIGITS 6
571
572/* No flags are set by default. */
573void TS_RESP_CTX_add_flags(TS_RESP_CTX *ctx, int flags);
574
575/* Default callback always returns a constant. */
576void TS_RESP_CTX_set_serial_cb(TS_RESP_CTX *ctx, TS_serial_cb cb, void *data);
577
578/* Default callback uses the gettimeofday() and gmtime() system calls. */
579void TS_RESP_CTX_set_time_cb(TS_RESP_CTX *ctx, TS_time_cb cb, void *data);
580
581/* Default callback rejects all extensions. The extension callback is called
582 * when the TS_TST_INFO object is already set up and not signed yet. */
583/* FIXME: extension handling is not tested yet. */
584void TS_RESP_CTX_set_extension_cb(TS_RESP_CTX *ctx,
585 TS_extension_cb cb, void *data);
586
587/* The following methods can be used in the callbacks. */
588int TS_RESP_CTX_set_status_info(TS_RESP_CTX *ctx,
589 int status, const char *text);
590
591/* Sets the status info only if it is still TS_STATUS_GRANTED. */
592int TS_RESP_CTX_set_status_info_cond(TS_RESP_CTX *ctx,
593 int status, const char *text);
594
595int TS_RESP_CTX_add_failure_info(TS_RESP_CTX *ctx, int failure);
596
597/* The get methods below can be used in the extension callback. */
598TS_REQ *TS_RESP_CTX_get_request(TS_RESP_CTX *ctx);
599
600TS_TST_INFO *TS_RESP_CTX_get_tst_info(TS_RESP_CTX *ctx);
601
602/*
603 * Creates the signed TS_TST_INFO and puts it in TS_RESP.
604 * In case of errors it sets the status info properly.
605 * Returns NULL only in case of memory allocation/fatal error.
606 */
607TS_RESP *TS_RESP_create_response(TS_RESP_CTX *ctx, BIO *req_bio);
608
609/*
610 * Declarations related to response verification,
611 * they are defined in ts/ts_resp_verify.c.
612 */
613
614int TS_RESP_verify_signature(PKCS7 *token, STACK_OF(X509) *certs,
615 X509_STORE *store, X509 **signer_out);
616
617/* Context structure for the generic verify method. */
618
619/* Verify the signer's certificate and the signature of the response. */
620#define TS_VFY_SIGNATURE (1u << 0)
621/* Verify the version number of the response. */
622#define TS_VFY_VERSION (1u << 1)
623/* Verify if the policy supplied by the user matches the policy of the TSA. */
624#define TS_VFY_POLICY (1u << 2)
625/* Verify the message imprint provided by the user. This flag should not be
626 specified with TS_VFY_DATA. */
627#define TS_VFY_IMPRINT (1u << 3)
628/* Verify the message imprint computed by the verify method from the user
629 provided data and the MD algorithm of the response. This flag should not be
630 specified with TS_VFY_IMPRINT. */
631#define TS_VFY_DATA (1u << 4)
632/* Verify the nonce value. */
633#define TS_VFY_NONCE (1u << 5)
634/* Verify if the TSA name field matches the signer certificate. */
635#define TS_VFY_SIGNER (1u << 6)
636/* Verify if the TSA name field equals to the user provided name. */
637#define TS_VFY_TSA_NAME (1u << 7)
638
639/* You can use the following convenience constants. */
640#define TS_VFY_ALL_IMPRINT (TS_VFY_SIGNATURE \
641 | TS_VFY_VERSION \
642 | TS_VFY_POLICY \
643 | TS_VFY_IMPRINT \
644 | TS_VFY_NONCE \
645 | TS_VFY_SIGNER \
646 | TS_VFY_TSA_NAME)
647#define TS_VFY_ALL_DATA (TS_VFY_SIGNATURE \
648 | TS_VFY_VERSION \
649 | TS_VFY_POLICY \
650 | TS_VFY_DATA \
651 | TS_VFY_NONCE \
652 | TS_VFY_SIGNER \
653 | TS_VFY_TSA_NAME)
654
655typedef struct TS_verify_ctx
656 {
657 /* Set this to the union of TS_VFY_... flags you want to carry out. */
658 unsigned flags;
659
660 /* Must be set only with TS_VFY_SIGNATURE. certs is optional. */
661 X509_STORE *store;
662 STACK_OF(X509) *certs;
663
664 /* Must be set only with TS_VFY_POLICY. */
665 ASN1_OBJECT *policy;
666
667 /* Must be set only with TS_VFY_IMPRINT. If md_alg is NULL,
668 the algorithm from the response is used. */
669 X509_ALGOR *md_alg;
670 unsigned char *imprint;
671 unsigned imprint_len;
672
673 /* Must be set only with TS_VFY_DATA. */
674 BIO *data;
675
676 /* Must be set only with TS_VFY_TSA_NAME. */
677 ASN1_INTEGER *nonce;
678
679 /* Must be set only with TS_VFY_TSA_NAME. */
680 GENERAL_NAME *tsa_name;
681 } TS_VERIFY_CTX;
682
683int TS_RESP_verify_response(TS_VERIFY_CTX *ctx, TS_RESP *response);
684int TS_RESP_verify_token(TS_VERIFY_CTX *ctx, PKCS7 *token);
685
686/*
687 * Declarations related to response verification context,
688 * they are defined in ts/ts_verify_ctx.c.
689 */
690
691/* Set all fields to zero. */
692TS_VERIFY_CTX *TS_VERIFY_CTX_new(void);
693void TS_VERIFY_CTX_init(TS_VERIFY_CTX *ctx);
694void TS_VERIFY_CTX_free(TS_VERIFY_CTX *ctx);
695void TS_VERIFY_CTX_cleanup(TS_VERIFY_CTX *ctx);
696
697/*
698 * If ctx is NULL, it allocates and returns a new object, otherwise
699 * it returns ctx. It initialises all the members as follows:
700 * flags = TS_VFY_ALL_IMPRINT & ~(TS_VFY_TSA_NAME | TS_VFY_SIGNATURE)
701 * certs = NULL
702 * store = NULL
703 * policy = policy from the request or NULL if absent (in this case
704 * TS_VFY_POLICY is cleared from flags as well)
705 * md_alg = MD algorithm from request
706 * imprint, imprint_len = imprint from request
707 * data = NULL
708 * nonce, nonce_len = nonce from the request or NULL if absent (in this case
709 * TS_VFY_NONCE is cleared from flags as well)
710 * tsa_name = NULL
711 * Important: after calling this method TS_VFY_SIGNATURE should be added!
712 */
713TS_VERIFY_CTX *TS_REQ_to_TS_VERIFY_CTX(TS_REQ *req, TS_VERIFY_CTX *ctx);
714
715/* Function declarations for TS_RESP defined in ts/ts_resp_print.c */
716
717int TS_RESP_print_bio(BIO *bio, TS_RESP *a);
718int TS_STATUS_INFO_print_bio(BIO *bio, TS_STATUS_INFO *a);
719int TS_TST_INFO_print_bio(BIO *bio, TS_TST_INFO *a);
720
721/* Common utility functions defined in ts/ts_lib.c */
722
723int TS_ASN1_INTEGER_print_bio(BIO *bio, const ASN1_INTEGER *num);
724int TS_OBJ_print_bio(BIO *bio, const ASN1_OBJECT *obj);
725int TS_ext_print_bio(BIO *bio, const STACK_OF(X509_EXTENSION) *extensions);
726int TS_X509_ALGOR_print_bio(BIO *bio, const X509_ALGOR *alg);
727int TS_MSG_IMPRINT_print_bio(BIO *bio, TS_MSG_IMPRINT *msg);
728
729/* Function declarations for handling configuration options,
730 defined in ts/ts_conf.c */
731
732X509 *TS_CONF_load_cert(const char *file);
733STACK_OF(X509) *TS_CONF_load_certs(const char *file);
734EVP_PKEY *TS_CONF_load_key(const char *file, const char *pass);
735const char *TS_CONF_get_tsa_section(CONF *conf, const char *section);
736int TS_CONF_set_serial(CONF *conf, const char *section, TS_serial_cb cb,
737 TS_RESP_CTX *ctx);
738int TS_CONF_set_crypto_device(CONF *conf, const char *section,
739 const char *device);
740int TS_CONF_set_default_engine(const char *name);
741int TS_CONF_set_signer_cert(CONF *conf, const char *section,
742 const char *cert, TS_RESP_CTX *ctx);
743int TS_CONF_set_certs(CONF *conf, const char *section, const char *certs,
744 TS_RESP_CTX *ctx);
745int TS_CONF_set_signer_key(CONF *conf, const char *section,
746 const char *key, const char *pass, TS_RESP_CTX *ctx);
747int TS_CONF_set_def_policy(CONF *conf, const char *section,
748 const char *policy, TS_RESP_CTX *ctx);
749int TS_CONF_set_policies(CONF *conf, const char *section, TS_RESP_CTX *ctx);
750int TS_CONF_set_digests(CONF *conf, const char *section, TS_RESP_CTX *ctx);
751int TS_CONF_set_accuracy(CONF *conf, const char *section, TS_RESP_CTX *ctx);
752int TS_CONF_set_clock_precision_digits(CONF *conf, const char *section,
753 TS_RESP_CTX *ctx);
754int TS_CONF_set_ordering(CONF *conf, const char *section, TS_RESP_CTX *ctx);
755int TS_CONF_set_tsa_name(CONF *conf, const char *section, TS_RESP_CTX *ctx);
756int TS_CONF_set_ess_cert_id_chain(CONF *conf, const char *section,
757 TS_RESP_CTX *ctx);
758
759/* -------------------------------------------------- */
760/* BEGIN ERROR CODES */
761/* The following lines are auto generated by the script mkerr.pl. Any changes
762 * made after this point may be overwritten when the script is next run.
763 */
764void ERR_load_TS_strings(void);
765
766/* Error codes for the TS functions. */
767
768/* Function codes. */
769#define TS_F_D2I_TS_RESP 147
770#define TS_F_DEF_SERIAL_CB 110
771#define TS_F_DEF_TIME_CB 111
772#define TS_F_ESS_ADD_SIGNING_CERT 112
773#define TS_F_ESS_CERT_ID_NEW_INIT 113
774#define TS_F_ESS_SIGNING_CERT_NEW_INIT 114
775#define TS_F_INT_TS_RESP_VERIFY_TOKEN 149
776#define TS_F_PKCS7_TO_TS_TST_INFO 148
777#define TS_F_TS_ACCURACY_SET_MICROS 115
778#define TS_F_TS_ACCURACY_SET_MILLIS 116
779#define TS_F_TS_ACCURACY_SET_SECONDS 117
780#define TS_F_TS_CHECK_IMPRINTS 100
781#define TS_F_TS_CHECK_NONCES 101
782#define TS_F_TS_CHECK_POLICY 102
783#define TS_F_TS_CHECK_SIGNING_CERTS 103
784#define TS_F_TS_CHECK_STATUS_INFO 104
785#define TS_F_TS_COMPUTE_IMPRINT 145
786#define TS_F_TS_CONF_SET_DEFAULT_ENGINE 146
787#define TS_F_TS_GET_STATUS_TEXT 105
788#define TS_F_TS_MSG_IMPRINT_SET_ALGO 118
789#define TS_F_TS_REQ_SET_MSG_IMPRINT 119
790#define TS_F_TS_REQ_SET_NONCE 120
791#define TS_F_TS_REQ_SET_POLICY_ID 121
792#define TS_F_TS_RESP_CREATE_RESPONSE 122
793#define TS_F_TS_RESP_CREATE_TST_INFO 123
794#define TS_F_TS_RESP_CTX_ADD_FAILURE_INFO 124
795#define TS_F_TS_RESP_CTX_ADD_MD 125
796#define TS_F_TS_RESP_CTX_ADD_POLICY 126
797#define TS_F_TS_RESP_CTX_NEW 127
798#define TS_F_TS_RESP_CTX_SET_ACCURACY 128
799#define TS_F_TS_RESP_CTX_SET_CERTS 129
800#define TS_F_TS_RESP_CTX_SET_DEF_POLICY 130
801#define TS_F_TS_RESP_CTX_SET_SIGNER_CERT 131
802#define TS_F_TS_RESP_CTX_SET_STATUS_INFO 132
803#define TS_F_TS_RESP_GET_POLICY 133
804#define TS_F_TS_RESP_SET_GENTIME_WITH_PRECISION 134
805#define TS_F_TS_RESP_SET_STATUS_INFO 135
806#define TS_F_TS_RESP_SET_TST_INFO 150
807#define TS_F_TS_RESP_SIGN 136
808#define TS_F_TS_RESP_VERIFY_SIGNATURE 106
809#define TS_F_TS_RESP_VERIFY_TOKEN 107
810#define TS_F_TS_TST_INFO_SET_ACCURACY 137
811#define TS_F_TS_TST_INFO_SET_MSG_IMPRINT 138
812#define TS_F_TS_TST_INFO_SET_NONCE 139
813#define TS_F_TS_TST_INFO_SET_POLICY_ID 140
814#define TS_F_TS_TST_INFO_SET_SERIAL 141
815#define TS_F_TS_TST_INFO_SET_TIME 142
816#define TS_F_TS_TST_INFO_SET_TSA 143
817#define TS_F_TS_VERIFY 108
818#define TS_F_TS_VERIFY_CERT 109
819#define TS_F_TS_VERIFY_CTX_NEW 144
820
821/* Reason codes. */
822#define TS_R_BAD_PKCS7_TYPE 132
823#define TS_R_BAD_TYPE 133
824#define TS_R_CERTIFICATE_VERIFY_ERROR 100
825#define TS_R_COULD_NOT_SET_ENGINE 127
826#define TS_R_COULD_NOT_SET_TIME 115
827#define TS_R_D2I_TS_RESP_INT_FAILED 128
828#define TS_R_DETACHED_CONTENT 134
829#define TS_R_ESS_ADD_SIGNING_CERT_ERROR 116
830#define TS_R_ESS_SIGNING_CERTIFICATE_ERROR 101
831#define TS_R_INVALID_NULL_POINTER 102
832#define TS_R_INVALID_SIGNER_CERTIFICATE_PURPOSE 117
833#define TS_R_MESSAGE_IMPRINT_MISMATCH 103
834#define TS_R_NONCE_MISMATCH 104
835#define TS_R_NONCE_NOT_RETURNED 105
836#define TS_R_NO_CONTENT 106
837#define TS_R_NO_TIME_STAMP_TOKEN 107
838#define TS_R_PKCS7_ADD_SIGNATURE_ERROR 118
839#define TS_R_PKCS7_ADD_SIGNED_ATTR_ERROR 119
840#define TS_R_PKCS7_TO_TS_TST_INFO_FAILED 129
841#define TS_R_POLICY_MISMATCH 108
842#define TS_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE 120
843#define TS_R_RESPONSE_SETUP_ERROR 121
844#define TS_R_SIGNATURE_FAILURE 109
845#define TS_R_THERE_MUST_BE_ONE_SIGNER 110
846#define TS_R_TIME_SYSCALL_ERROR 122
847#define TS_R_TOKEN_NOT_PRESENT 130
848#define TS_R_TOKEN_PRESENT 131
849#define TS_R_TSA_NAME_MISMATCH 111
850#define TS_R_TSA_UNTRUSTED 112
851#define TS_R_TST_INFO_SETUP_ERROR 123
852#define TS_R_TS_DATASIGN 124
853#define TS_R_UNACCEPTABLE_POLICY 125
854#define TS_R_UNSUPPORTED_MD_ALGORITHM 126
855#define TS_R_UNSUPPORTED_VERSION 113
856#define TS_R_WRONG_CONTENT_TYPE 114
857
858#ifdef __cplusplus
859}
860#endif
861#endif
diff --git a/src/lib/libcrypto/ts/ts_asn1.c b/src/lib/libcrypto/ts/ts_asn1.c
new file mode 100644
index 0000000000..40b730c5e2
--- /dev/null
+++ b/src/lib/libcrypto/ts/ts_asn1.c
@@ -0,0 +1,322 @@
1/* crypto/ts/ts_asn1.c */
2/* Written by Nils Larsch for the OpenSSL project 2004.
3 */
4/* ====================================================================
5 * Copyright (c) 2006 The OpenSSL Project. All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 *
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 *
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in
16 * the documentation and/or other materials provided with the
17 * distribution.
18 *
19 * 3. All advertising materials mentioning features or use of this
20 * software must display the following acknowledgment:
21 * "This product includes software developed by the OpenSSL Project
22 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
23 *
24 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
25 * endorse or promote products derived from this software without
26 * prior written permission. For written permission, please contact
27 * licensing@OpenSSL.org.
28 *
29 * 5. Products derived from this software may not be called "OpenSSL"
30 * nor may "OpenSSL" appear in their names without prior written
31 * permission of the OpenSSL Project.
32 *
33 * 6. Redistributions of any form whatsoever must retain the following
34 * acknowledgment:
35 * "This product includes software developed by the OpenSSL Project
36 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
37 *
38 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
39 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
40 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
41 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
42 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
43 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
44 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
45 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
46 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
47 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
48 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
49 * OF THE POSSIBILITY OF SUCH DAMAGE.
50 * ====================================================================
51 *
52 * This product includes cryptographic software written by Eric Young
53 * (eay@cryptsoft.com). This product includes software written by Tim
54 * Hudson (tjh@cryptsoft.com).
55 *
56 */
57
58#include <openssl/ts.h>
59#include <openssl/err.h>
60#include <openssl/asn1t.h>
61
62ASN1_SEQUENCE(TS_MSG_IMPRINT) = {
63 ASN1_SIMPLE(TS_MSG_IMPRINT, hash_algo, X509_ALGOR),
64 ASN1_SIMPLE(TS_MSG_IMPRINT, hashed_msg, ASN1_OCTET_STRING)
65} ASN1_SEQUENCE_END(TS_MSG_IMPRINT)
66
67IMPLEMENT_ASN1_FUNCTIONS_const(TS_MSG_IMPRINT)
68IMPLEMENT_ASN1_DUP_FUNCTION(TS_MSG_IMPRINT)
69#ifndef OPENSSL_NO_BIO
70TS_MSG_IMPRINT *d2i_TS_MSG_IMPRINT_bio(BIO *bp, TS_MSG_IMPRINT **a)
71 {
72 return ASN1_d2i_bio_of(TS_MSG_IMPRINT, TS_MSG_IMPRINT_new, d2i_TS_MSG_IMPRINT, bp, a);
73 }
74
75int i2d_TS_MSG_IMPRINT_bio(BIO *bp, TS_MSG_IMPRINT *a)
76{
77 return ASN1_i2d_bio_of_const(TS_MSG_IMPRINT, i2d_TS_MSG_IMPRINT, bp, a);
78}
79#endif
80#ifndef OPENSSL_NO_FP_API
81TS_MSG_IMPRINT *d2i_TS_MSG_IMPRINT_fp(FILE *fp, TS_MSG_IMPRINT **a)
82 {
83 return ASN1_d2i_fp_of(TS_MSG_IMPRINT, TS_MSG_IMPRINT_new, d2i_TS_MSG_IMPRINT, fp, a);
84 }
85
86int i2d_TS_MSG_IMPRINT_fp(FILE *fp, TS_MSG_IMPRINT *a)
87 {
88 return ASN1_i2d_fp_of_const(TS_MSG_IMPRINT, i2d_TS_MSG_IMPRINT, fp, a);
89 }
90#endif
91
92ASN1_SEQUENCE(TS_REQ) = {
93 ASN1_SIMPLE(TS_REQ, version, ASN1_INTEGER),
94 ASN1_SIMPLE(TS_REQ, msg_imprint, TS_MSG_IMPRINT),
95 ASN1_OPT(TS_REQ, policy_id, ASN1_OBJECT),
96 ASN1_OPT(TS_REQ, nonce, ASN1_INTEGER),
97 ASN1_OPT(TS_REQ, cert_req, ASN1_FBOOLEAN),
98 ASN1_IMP_SEQUENCE_OF_OPT(TS_REQ, extensions, X509_EXTENSION, 0)
99} ASN1_SEQUENCE_END(TS_REQ)
100
101IMPLEMENT_ASN1_FUNCTIONS_const(TS_REQ)
102IMPLEMENT_ASN1_DUP_FUNCTION(TS_REQ)
103#ifndef OPENSSL_NO_BIO
104TS_REQ *d2i_TS_REQ_bio(BIO *bp, TS_REQ **a)
105 {
106 return ASN1_d2i_bio_of(TS_REQ, TS_REQ_new, d2i_TS_REQ, bp, a);
107 }
108
109int i2d_TS_REQ_bio(BIO *bp, TS_REQ *a)
110 {
111 return ASN1_i2d_bio_of_const(TS_REQ, i2d_TS_REQ, bp, a);
112 }
113#endif
114#ifndef OPENSSL_NO_FP_API
115TS_REQ *d2i_TS_REQ_fp(FILE *fp, TS_REQ **a)
116 {
117 return ASN1_d2i_fp_of(TS_REQ, TS_REQ_new, d2i_TS_REQ, fp, a);
118 }
119
120int i2d_TS_REQ_fp(FILE *fp, TS_REQ *a)
121 {
122 return ASN1_i2d_fp_of_const(TS_REQ, i2d_TS_REQ, fp, a);
123 }
124#endif
125
126ASN1_SEQUENCE(TS_ACCURACY) = {
127 ASN1_OPT(TS_ACCURACY, seconds, ASN1_INTEGER),
128 ASN1_IMP_OPT(TS_ACCURACY, millis, ASN1_INTEGER, 0),
129 ASN1_IMP_OPT(TS_ACCURACY, micros, ASN1_INTEGER, 1)
130} ASN1_SEQUENCE_END(TS_ACCURACY)
131
132IMPLEMENT_ASN1_FUNCTIONS_const(TS_ACCURACY)
133IMPLEMENT_ASN1_DUP_FUNCTION(TS_ACCURACY)
134
135ASN1_SEQUENCE(TS_TST_INFO) = {
136 ASN1_SIMPLE(TS_TST_INFO, version, ASN1_INTEGER),
137 ASN1_SIMPLE(TS_TST_INFO, policy_id, ASN1_OBJECT),
138 ASN1_SIMPLE(TS_TST_INFO, msg_imprint, TS_MSG_IMPRINT),
139 ASN1_SIMPLE(TS_TST_INFO, serial, ASN1_INTEGER),
140 ASN1_SIMPLE(TS_TST_INFO, time, ASN1_GENERALIZEDTIME),
141 ASN1_OPT(TS_TST_INFO, accuracy, TS_ACCURACY),
142 ASN1_OPT(TS_TST_INFO, ordering, ASN1_FBOOLEAN),
143 ASN1_OPT(TS_TST_INFO, nonce, ASN1_INTEGER),
144 ASN1_EXP_OPT(TS_TST_INFO, tsa, GENERAL_NAME, 0),
145 ASN1_IMP_SEQUENCE_OF_OPT(TS_TST_INFO, extensions, X509_EXTENSION, 1)
146} ASN1_SEQUENCE_END(TS_TST_INFO)
147
148IMPLEMENT_ASN1_FUNCTIONS_const(TS_TST_INFO)
149IMPLEMENT_ASN1_DUP_FUNCTION(TS_TST_INFO)
150#ifndef OPENSSL_NO_BIO
151TS_TST_INFO *d2i_TS_TST_INFO_bio(BIO *bp, TS_TST_INFO **a)
152 {
153 return ASN1_d2i_bio_of(TS_TST_INFO, TS_TST_INFO_new, d2i_TS_TST_INFO, bp, a);
154 }
155
156int i2d_TS_TST_INFO_bio(BIO *bp, TS_TST_INFO *a)
157 {
158 return ASN1_i2d_bio_of_const(TS_TST_INFO, i2d_TS_TST_INFO, bp, a);
159 }
160#endif
161#ifndef OPENSSL_NO_FP_API
162TS_TST_INFO *d2i_TS_TST_INFO_fp(FILE *fp, TS_TST_INFO **a)
163 {
164 return ASN1_d2i_fp_of(TS_TST_INFO, TS_TST_INFO_new, d2i_TS_TST_INFO, fp, a);
165 }
166
167int i2d_TS_TST_INFO_fp(FILE *fp, TS_TST_INFO *a)
168 {
169 return ASN1_i2d_fp_of_const(TS_TST_INFO, i2d_TS_TST_INFO, fp, a);
170 }
171#endif
172
173ASN1_SEQUENCE(TS_STATUS_INFO) = {
174 ASN1_SIMPLE(TS_STATUS_INFO, status, ASN1_INTEGER),
175 ASN1_SEQUENCE_OF_OPT(TS_STATUS_INFO, text, ASN1_UTF8STRING),
176 ASN1_OPT(TS_STATUS_INFO, failure_info, ASN1_BIT_STRING)
177} ASN1_SEQUENCE_END(TS_STATUS_INFO)
178
179IMPLEMENT_ASN1_FUNCTIONS_const(TS_STATUS_INFO)
180IMPLEMENT_ASN1_DUP_FUNCTION(TS_STATUS_INFO)
181
182static int ts_resp_set_tst_info(TS_RESP *a)
183{
184 long status;
185
186 status = ASN1_INTEGER_get(a->status_info->status);
187
188 if (a->token) {
189 if (status != 0 && status != 1) {
190 TSerr(TS_F_TS_RESP_SET_TST_INFO, TS_R_TOKEN_PRESENT);
191 return 0;
192 }
193 if (a->tst_info != NULL)
194 TS_TST_INFO_free(a->tst_info);
195 a->tst_info = PKCS7_to_TS_TST_INFO(a->token);
196 if (!a->tst_info) {
197 TSerr(TS_F_TS_RESP_SET_TST_INFO, TS_R_PKCS7_TO_TS_TST_INFO_FAILED);
198 return 0;
199 }
200 } else if (status == 0 || status == 1) {
201 TSerr(TS_F_TS_RESP_SET_TST_INFO, TS_R_TOKEN_NOT_PRESENT);
202 return 0;
203 }
204
205 return 1;
206}
207
208static int ts_resp_cb(int op, ASN1_VALUE **pval, const ASN1_ITEM *it,
209 void *exarg)
210{
211 TS_RESP *ts_resp = (TS_RESP *)*pval;
212 if (op == ASN1_OP_NEW_POST) {
213 ts_resp->tst_info = NULL;
214 } else if (op == ASN1_OP_FREE_POST) {
215 if (ts_resp->tst_info != NULL)
216 TS_TST_INFO_free(ts_resp->tst_info);
217 } else if (op == ASN1_OP_D2I_POST) {
218 if (ts_resp_set_tst_info(ts_resp) == 0)
219 return 0;
220 }
221 return 1;
222}
223
224ASN1_SEQUENCE_cb(TS_RESP, ts_resp_cb) = {
225 ASN1_SIMPLE(TS_RESP, status_info, TS_STATUS_INFO),
226 ASN1_OPT(TS_RESP, token, PKCS7),
227} ASN1_SEQUENCE_END_cb(TS_RESP, TS_RESP)
228
229IMPLEMENT_ASN1_FUNCTIONS_const(TS_RESP)
230IMPLEMENT_ASN1_DUP_FUNCTION(TS_RESP)
231#ifndef OPENSSL_NO_BIO
232TS_RESP *d2i_TS_RESP_bio(BIO *bp, TS_RESP **a)
233 {
234 return ASN1_d2i_bio_of(TS_RESP, TS_RESP_new, d2i_TS_RESP, bp, a);
235 }
236
237int i2d_TS_RESP_bio(BIO *bp, TS_RESP *a)
238 {
239 return ASN1_i2d_bio_of_const(TS_RESP, i2d_TS_RESP, bp, a);
240 }
241#endif
242#ifndef OPENSSL_NO_FP_API
243TS_RESP *d2i_TS_RESP_fp(FILE *fp, TS_RESP **a)
244 {
245 return ASN1_d2i_fp_of(TS_RESP, TS_RESP_new, d2i_TS_RESP, fp, a);
246 }
247
248int i2d_TS_RESP_fp(FILE *fp, TS_RESP *a)
249 {
250 return ASN1_i2d_fp_of_const(TS_RESP, i2d_TS_RESP, fp, a);
251 }
252#endif
253
254ASN1_SEQUENCE(ESS_ISSUER_SERIAL) = {
255 ASN1_SEQUENCE_OF(ESS_ISSUER_SERIAL, issuer, GENERAL_NAME),
256 ASN1_SIMPLE(ESS_ISSUER_SERIAL, serial, ASN1_INTEGER)
257} ASN1_SEQUENCE_END(ESS_ISSUER_SERIAL)
258
259IMPLEMENT_ASN1_FUNCTIONS_const(ESS_ISSUER_SERIAL)
260IMPLEMENT_ASN1_DUP_FUNCTION(ESS_ISSUER_SERIAL)
261
262ASN1_SEQUENCE(ESS_CERT_ID) = {
263 ASN1_SIMPLE(ESS_CERT_ID, hash, ASN1_OCTET_STRING),
264 ASN1_OPT(ESS_CERT_ID, issuer_serial, ESS_ISSUER_SERIAL)
265} ASN1_SEQUENCE_END(ESS_CERT_ID)
266
267IMPLEMENT_ASN1_FUNCTIONS_const(ESS_CERT_ID)
268IMPLEMENT_ASN1_DUP_FUNCTION(ESS_CERT_ID)
269
270ASN1_SEQUENCE(ESS_SIGNING_CERT) = {
271 ASN1_SEQUENCE_OF(ESS_SIGNING_CERT, cert_ids, ESS_CERT_ID),
272 ASN1_SEQUENCE_OF_OPT(ESS_SIGNING_CERT, policy_info, POLICYINFO)
273} ASN1_SEQUENCE_END(ESS_SIGNING_CERT)
274
275IMPLEMENT_ASN1_FUNCTIONS_const(ESS_SIGNING_CERT)
276IMPLEMENT_ASN1_DUP_FUNCTION(ESS_SIGNING_CERT)
277
278/* Getting encapsulated TS_TST_INFO object from PKCS7. */
279TS_TST_INFO *PKCS7_to_TS_TST_INFO(PKCS7 *token)
280{
281 PKCS7_SIGNED *pkcs7_signed;
282 PKCS7 *enveloped;
283 ASN1_TYPE *tst_info_wrapper;
284 ASN1_OCTET_STRING *tst_info_der;
285 const unsigned char *p;
286
287 if (!PKCS7_type_is_signed(token))
288 {
289 TSerr(TS_F_PKCS7_TO_TS_TST_INFO, TS_R_BAD_PKCS7_TYPE);
290 return NULL;
291 }
292
293 /* Content must be present. */
294 if (PKCS7_get_detached(token))
295 {
296 TSerr(TS_F_PKCS7_TO_TS_TST_INFO, TS_R_DETACHED_CONTENT);
297 return NULL;
298 }
299
300 /* We have a signed data with content. */
301 pkcs7_signed = token->d.sign;
302 enveloped = pkcs7_signed->contents;
303 if (OBJ_obj2nid(enveloped->type) != NID_id_smime_ct_TSTInfo)
304 {
305 TSerr(TS_F_PKCS7_TO_TS_TST_INFO, TS_R_BAD_PKCS7_TYPE);
306 return NULL;
307 }
308
309 /* We have a DER encoded TST_INFO as the signed data. */
310 tst_info_wrapper = enveloped->d.other;
311 if (tst_info_wrapper->type != V_ASN1_OCTET_STRING)
312 {
313 TSerr(TS_F_PKCS7_TO_TS_TST_INFO, TS_R_BAD_TYPE);
314 return NULL;
315 }
316
317 /* We have the correct ASN1_OCTET_STRING type. */
318 tst_info_der = tst_info_wrapper->value.octet_string;
319 /* At last, decode the TST_INFO. */
320 p = tst_info_der->data;
321 return d2i_TS_TST_INFO(NULL, &p, tst_info_der->length);
322}
diff --git a/src/lib/libcrypto/ts/ts_conf.c b/src/lib/libcrypto/ts/ts_conf.c
new file mode 100644
index 0000000000..c39be76f28
--- /dev/null
+++ b/src/lib/libcrypto/ts/ts_conf.c
@@ -0,0 +1,507 @@
1/* crypto/ts/ts_conf.c */
2/* Written by Zoltan Glozik (zglozik@stones.com) for the OpenSSL
3 * project 2002.
4 */
5/* ====================================================================
6 * Copyright (c) 2006 The OpenSSL Project. All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 *
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 *
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in
17 * the documentation and/or other materials provided with the
18 * distribution.
19 *
20 * 3. All advertising materials mentioning features or use of this
21 * software must display the following acknowledgment:
22 * "This product includes software developed by the OpenSSL Project
23 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
24 *
25 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
26 * endorse or promote products derived from this software without
27 * prior written permission. For written permission, please contact
28 * licensing@OpenSSL.org.
29 *
30 * 5. Products derived from this software may not be called "OpenSSL"
31 * nor may "OpenSSL" appear in their names without prior written
32 * permission of the OpenSSL Project.
33 *
34 * 6. Redistributions of any form whatsoever must retain the following
35 * acknowledgment:
36 * "This product includes software developed by the OpenSSL Project
37 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
38 *
39 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
40 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
43 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
50 * OF THE POSSIBILITY OF SUCH DAMAGE.
51 * ====================================================================
52 *
53 * This product includes cryptographic software written by Eric Young
54 * (eay@cryptsoft.com). This product includes software written by Tim
55 * Hudson (tjh@cryptsoft.com).
56 *
57 */
58
59#include <string.h>
60
61#include <openssl/crypto.h>
62#include "cryptlib.h"
63#include <openssl/pem.h>
64#ifndef OPENSSL_NO_ENGINE
65#include <openssl/engine.h>
66#endif
67#include <openssl/ts.h>
68
69/* Macro definitions for the configuration file. */
70
71#define BASE_SECTION "tsa"
72#define ENV_DEFAULT_TSA "default_tsa"
73#define ENV_SERIAL "serial"
74#define ENV_CRYPTO_DEVICE "crypto_device"
75#define ENV_SIGNER_CERT "signer_cert"
76#define ENV_CERTS "certs"
77#define ENV_SIGNER_KEY "signer_key"
78#define ENV_DEFAULT_POLICY "default_policy"
79#define ENV_OTHER_POLICIES "other_policies"
80#define ENV_DIGESTS "digests"
81#define ENV_ACCURACY "accuracy"
82#define ENV_ORDERING "ordering"
83#define ENV_TSA_NAME "tsa_name"
84#define ENV_ESS_CERT_ID_CHAIN "ess_cert_id_chain"
85#define ENV_VALUE_SECS "secs"
86#define ENV_VALUE_MILLISECS "millisecs"
87#define ENV_VALUE_MICROSECS "microsecs"
88#define ENV_CLOCK_PRECISION_DIGITS "clock_precision_digits"
89#define ENV_VALUE_YES "yes"
90#define ENV_VALUE_NO "no"
91
92/* Function definitions for certificate and key loading. */
93
94X509 *TS_CONF_load_cert(const char *file)
95 {
96 BIO *cert = NULL;
97 X509 *x = NULL;
98
99 if ((cert = BIO_new_file(file, "r")) == NULL) goto end;
100 x = PEM_read_bio_X509_AUX(cert, NULL, NULL, NULL);
101end:
102 if (x == NULL)
103 fprintf(stderr, "unable to load certificate: %s\n", file);
104 BIO_free(cert);
105 return x;
106 }
107
108STACK_OF(X509) *TS_CONF_load_certs(const char *file)
109 {
110 BIO *certs = NULL;
111 STACK_OF(X509) *othercerts = NULL;
112 STACK_OF(X509_INFO) *allcerts = NULL;
113 int i;
114
115 if (!(certs = BIO_new_file(file, "r"))) goto end;
116
117 if (!(othercerts = sk_X509_new_null())) goto end;
118 allcerts = PEM_X509_INFO_read_bio(certs, NULL, NULL, NULL);
119 for(i = 0; i < sk_X509_INFO_num(allcerts); i++)
120 {
121 X509_INFO *xi = sk_X509_INFO_value(allcerts, i);
122 if (xi->x509)
123 {
124 sk_X509_push(othercerts, xi->x509);
125 xi->x509 = NULL;
126 }
127 }
128end:
129 if (othercerts == NULL)
130 fprintf(stderr, "unable to load certificates: %s\n", file);
131 sk_X509_INFO_pop_free(allcerts, X509_INFO_free);
132 BIO_free(certs);
133 return othercerts;
134 }
135
136EVP_PKEY *TS_CONF_load_key(const char *file, const char *pass)
137 {
138 BIO *key = NULL;
139 EVP_PKEY *pkey = NULL;
140
141 if (!(key = BIO_new_file(file, "r"))) goto end;
142 pkey = PEM_read_bio_PrivateKey(key, NULL, NULL, (char *) pass);
143 end:
144 if (pkey == NULL)
145 fprintf(stderr, "unable to load private key: %s\n", file);
146 BIO_free(key);
147 return pkey;
148 }
149
150/* Function definitions for handling configuration options. */
151
152static void TS_CONF_lookup_fail(const char *name, const char *tag)
153 {
154 fprintf(stderr, "variable lookup failed for %s::%s\n", name, tag);
155 }
156
157static void TS_CONF_invalid(const char *name, const char *tag)
158 {
159 fprintf(stderr, "invalid variable value for %s::%s\n", name, tag);
160 }
161
162const char *TS_CONF_get_tsa_section(CONF *conf, const char *section)
163 {
164 if (!section)
165 {
166 section = NCONF_get_string(conf, BASE_SECTION, ENV_DEFAULT_TSA);
167 if (!section)
168 TS_CONF_lookup_fail(BASE_SECTION, ENV_DEFAULT_TSA);
169 }
170 return section;
171 }
172
173int TS_CONF_set_serial(CONF *conf, const char *section, TS_serial_cb cb,
174 TS_RESP_CTX *ctx)
175 {
176 int ret = 0;
177 char *serial = NCONF_get_string(conf, section, ENV_SERIAL);
178 if (!serial)
179 {
180 TS_CONF_lookup_fail(section, ENV_SERIAL);
181 goto err;
182 }
183 TS_RESP_CTX_set_serial_cb(ctx, cb, serial);
184
185 ret = 1;
186 err:
187 return ret;
188 }
189
190#ifndef OPENSSL_NO_ENGINE
191
192int TS_CONF_set_crypto_device(CONF *conf, const char *section,
193 const char *device)
194 {
195 int ret = 0;
196
197 if (!device)
198 device = NCONF_get_string(conf, section,
199 ENV_CRYPTO_DEVICE);
200
201 if (device && !TS_CONF_set_default_engine(device))
202 {
203 TS_CONF_invalid(section, ENV_CRYPTO_DEVICE);
204 goto err;
205 }
206 ret = 1;
207 err:
208 return ret;
209 }
210
211int TS_CONF_set_default_engine(const char *name)
212 {
213 ENGINE *e = NULL;
214 int ret = 0;
215
216 /* Leave the default if builtin specified. */
217 if (strcmp(name, "builtin") == 0) return 1;
218
219 if (!(e = ENGINE_by_id(name))) goto err;
220 /* Enable the use of the NCipher HSM for forked children. */
221 if (strcmp(name, "chil") == 0)
222 ENGINE_ctrl(e, ENGINE_CTRL_CHIL_SET_FORKCHECK, 1, 0, 0);
223 /* All the operations are going to be carried out by the engine. */
224 if (!ENGINE_set_default(e, ENGINE_METHOD_ALL)) goto err;
225 ret = 1;
226 err:
227 if (!ret)
228 {
229 TSerr(TS_F_TS_CONF_SET_DEFAULT_ENGINE,
230 TS_R_COULD_NOT_SET_ENGINE);
231 ERR_add_error_data(2, "engine:", name);
232 }
233 if (e) ENGINE_free(e);
234 return ret;
235 }
236
237#endif
238
239int TS_CONF_set_signer_cert(CONF *conf, const char *section,
240 const char *cert, TS_RESP_CTX *ctx)
241 {
242 int ret = 0;
243 X509 *cert_obj = NULL;
244 if (!cert)
245 cert = NCONF_get_string(conf, section, ENV_SIGNER_CERT);
246 if (!cert)
247 {
248 TS_CONF_lookup_fail(section, ENV_SIGNER_CERT);
249 goto err;
250 }
251 if (!(cert_obj = TS_CONF_load_cert(cert)))
252 goto err;
253 if (!TS_RESP_CTX_set_signer_cert(ctx, cert_obj))
254 goto err;
255
256 ret = 1;
257 err:
258 X509_free(cert_obj);
259 return ret;
260 }
261
262int TS_CONF_set_certs(CONF *conf, const char *section, const char *certs,
263 TS_RESP_CTX *ctx)
264 {
265 int ret = 0;
266 STACK_OF(X509) *certs_obj = NULL;
267 if (!certs)
268 certs = NCONF_get_string(conf, section, ENV_CERTS);
269 /* Certificate chain is optional. */
270 if (!certs) goto end;
271 if (!(certs_obj = TS_CONF_load_certs(certs))) goto err;
272 if (!TS_RESP_CTX_set_certs(ctx, certs_obj)) goto err;
273 end:
274 ret = 1;
275 err:
276 sk_X509_pop_free(certs_obj, X509_free);
277 return ret;
278 }
279
280int TS_CONF_set_signer_key(CONF *conf, const char *section,
281 const char *key, const char *pass,
282 TS_RESP_CTX *ctx)
283 {
284 int ret = 0;
285 EVP_PKEY *key_obj = NULL;
286 if (!key)
287 key = NCONF_get_string(conf, section, ENV_SIGNER_KEY);
288 if (!key)
289 {
290 TS_CONF_lookup_fail(section, ENV_SIGNER_KEY);
291 goto err;
292 }
293 if (!(key_obj = TS_CONF_load_key(key, pass))) goto err;
294 if (!TS_RESP_CTX_set_signer_key(ctx, key_obj)) goto err;
295
296 ret = 1;
297 err:
298 EVP_PKEY_free(key_obj);
299 return ret;
300 }
301
302int TS_CONF_set_def_policy(CONF *conf, const char *section,
303 const char *policy, TS_RESP_CTX *ctx)
304 {
305 int ret = 0;
306 ASN1_OBJECT *policy_obj = NULL;
307 if (!policy)
308 policy = NCONF_get_string(conf, section,
309 ENV_DEFAULT_POLICY);
310 if (!policy)
311 {
312 TS_CONF_lookup_fail(section, ENV_DEFAULT_POLICY);
313 goto err;
314 }
315 if (!(policy_obj = OBJ_txt2obj(policy, 0)))
316 {
317 TS_CONF_invalid(section, ENV_DEFAULT_POLICY);
318 goto err;
319 }
320 if (!TS_RESP_CTX_set_def_policy(ctx, policy_obj))
321 goto err;
322
323 ret = 1;
324 err:
325 ASN1_OBJECT_free(policy_obj);
326 return ret;
327 }
328
329int TS_CONF_set_policies(CONF *conf, const char *section,
330 TS_RESP_CTX *ctx)
331 {
332 int ret = 0;
333 int i;
334 STACK_OF(CONF_VALUE) *list = NULL;
335 char *policies = NCONF_get_string(conf, section,
336 ENV_OTHER_POLICIES);
337 /* If no other policy is specified, that's fine. */
338 if (policies && !(list = X509V3_parse_list(policies)))
339 {
340 TS_CONF_invalid(section, ENV_OTHER_POLICIES);
341 goto err;
342 }
343 for (i = 0; i < sk_CONF_VALUE_num(list); ++i)
344 {
345 CONF_VALUE *val = sk_CONF_VALUE_value(list, i);
346 const char *extval = val->value ? val->value : val->name;
347 ASN1_OBJECT *objtmp;
348 if (!(objtmp = OBJ_txt2obj(extval, 0)))
349 {
350 TS_CONF_invalid(section, ENV_OTHER_POLICIES);
351 goto err;
352 }
353 if (!TS_RESP_CTX_add_policy(ctx, objtmp))
354 goto err;
355 ASN1_OBJECT_free(objtmp);
356 }
357
358 ret = 1;
359 err:
360 sk_CONF_VALUE_pop_free(list, X509V3_conf_free);
361 return ret;
362 }
363
364int TS_CONF_set_digests(CONF *conf, const char *section,
365 TS_RESP_CTX *ctx)
366 {
367 int ret = 0;
368 int i;
369 STACK_OF(CONF_VALUE) *list = NULL;
370 char *digests = NCONF_get_string(conf, section, ENV_DIGESTS);
371 if (!digests)
372 {
373 TS_CONF_lookup_fail(section, ENV_DIGESTS);
374 goto err;
375 }
376 if (!(list = X509V3_parse_list(digests)))
377 {
378 TS_CONF_invalid(section, ENV_DIGESTS);
379 goto err;
380 }
381 if (sk_CONF_VALUE_num(list) == 0)
382 {
383 TS_CONF_invalid(section, ENV_DIGESTS);
384 goto err;
385 }
386 for (i = 0; i < sk_CONF_VALUE_num(list); ++i)
387 {
388 CONF_VALUE *val = sk_CONF_VALUE_value(list, i);
389 const char *extval = val->value ? val->value : val->name;
390 const EVP_MD *md;
391 if (!(md = EVP_get_digestbyname(extval)))
392 {
393 TS_CONF_invalid(section, ENV_DIGESTS);
394 goto err;
395 }
396 if (!TS_RESP_CTX_add_md(ctx, md))
397 goto err;
398 }
399
400 ret = 1;
401 err:
402 sk_CONF_VALUE_pop_free(list, X509V3_conf_free);
403 return ret;
404 }
405
406int TS_CONF_set_accuracy(CONF *conf, const char *section, TS_RESP_CTX *ctx)
407 {
408 int ret = 0;
409 int i;
410 int secs = 0, millis = 0, micros = 0;
411 STACK_OF(CONF_VALUE) *list = NULL;
412 char *accuracy = NCONF_get_string(conf, section, ENV_ACCURACY);
413
414 if (accuracy && !(list = X509V3_parse_list(accuracy)))
415 {
416 TS_CONF_invalid(section, ENV_ACCURACY);
417 goto err;
418 }
419 for (i = 0; i < sk_CONF_VALUE_num(list); ++i)
420 {
421 CONF_VALUE *val = sk_CONF_VALUE_value(list, i);
422 if (strcmp(val->name, ENV_VALUE_SECS) == 0)
423 {
424 if (val->value) secs = atoi(val->value);
425 }
426 else if (strcmp(val->name, ENV_VALUE_MILLISECS) == 0)
427 {
428 if (val->value) millis = atoi(val->value);
429 }
430 else if (strcmp(val->name, ENV_VALUE_MICROSECS) == 0)
431 {
432 if (val->value) micros = atoi(val->value);
433 }
434 else
435 {
436 TS_CONF_invalid(section, ENV_ACCURACY);
437 goto err;
438 }
439 }
440 if (!TS_RESP_CTX_set_accuracy(ctx, secs, millis, micros))
441 goto err;
442
443 ret = 1;
444 err:
445 sk_CONF_VALUE_pop_free(list, X509V3_conf_free);
446 return ret;
447 }
448
449int TS_CONF_set_clock_precision_digits(CONF *conf, const char *section,
450 TS_RESP_CTX *ctx)
451 {
452 int ret = 0;
453 long digits = 0;
454
455 /* If not specified, set the default value to 0, i.e. sec precision */
456 if (!NCONF_get_number_e(conf, section, ENV_CLOCK_PRECISION_DIGITS,
457 &digits))
458 digits = 0;
459 if (digits < 0 || digits > TS_MAX_CLOCK_PRECISION_DIGITS)
460 {
461 TS_CONF_invalid(section, ENV_CLOCK_PRECISION_DIGITS);
462 goto err;
463 }
464
465 if (!TS_RESP_CTX_set_clock_precision_digits(ctx, digits))
466 goto err;
467
468 return 1;
469 err:
470 return ret;
471 }
472
473static int TS_CONF_add_flag(CONF *conf, const char *section, const char *field,
474 int flag, TS_RESP_CTX *ctx)
475 {
476 /* Default is false. */
477 const char *value = NCONF_get_string(conf, section, field);
478 if (value)
479 {
480 if (strcmp(value, ENV_VALUE_YES) == 0)
481 TS_RESP_CTX_add_flags(ctx, flag);
482 else if (strcmp(value, ENV_VALUE_NO) != 0)
483 {
484 TS_CONF_invalid(section, field);
485 return 0;
486 }
487 }
488
489 return 1;
490 }
491
492int TS_CONF_set_ordering(CONF *conf, const char *section, TS_RESP_CTX *ctx)
493 {
494 return TS_CONF_add_flag(conf, section, ENV_ORDERING, TS_ORDERING, ctx);
495 }
496
497int TS_CONF_set_tsa_name(CONF *conf, const char *section, TS_RESP_CTX *ctx)
498 {
499 return TS_CONF_add_flag(conf, section, ENV_TSA_NAME, TS_TSA_NAME, ctx);
500 }
501
502int TS_CONF_set_ess_cert_id_chain(CONF *conf, const char *section,
503 TS_RESP_CTX *ctx)
504 {
505 return TS_CONF_add_flag(conf, section, ENV_ESS_CERT_ID_CHAIN,
506 TS_ESS_CERT_ID_CHAIN, ctx);
507 }
diff --git a/src/lib/libcrypto/ts/ts_err.c b/src/lib/libcrypto/ts/ts_err.c
new file mode 100644
index 0000000000..a08b0ffa23
--- /dev/null
+++ b/src/lib/libcrypto/ts/ts_err.c
@@ -0,0 +1,179 @@
1/* crypto/ts/ts_err.c */
2/* ====================================================================
3 * Copyright (c) 1999-2007 The OpenSSL Project. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 *
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in
14 * the documentation and/or other materials provided with the
15 * distribution.
16 *
17 * 3. All advertising materials mentioning features or use of this
18 * software must display the following acknowledgment:
19 * "This product includes software developed by the OpenSSL Project
20 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
21 *
22 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
23 * endorse or promote products derived from this software without
24 * prior written permission. For written permission, please contact
25 * openssl-core@OpenSSL.org.
26 *
27 * 5. Products derived from this software may not be called "OpenSSL"
28 * nor may "OpenSSL" appear in their names without prior written
29 * permission of the OpenSSL Project.
30 *
31 * 6. Redistributions of any form whatsoever must retain the following
32 * acknowledgment:
33 * "This product includes software developed by the OpenSSL Project
34 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
35 *
36 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
37 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
38 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
39 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
40 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
42 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
43 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
44 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
45 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
46 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
47 * OF THE POSSIBILITY OF SUCH DAMAGE.
48 * ====================================================================
49 *
50 * This product includes cryptographic software written by Eric Young
51 * (eay@cryptsoft.com). This product includes software written by Tim
52 * Hudson (tjh@cryptsoft.com).
53 *
54 */
55
56/* NOTE: this file was auto generated by the mkerr.pl script: any changes
57 * made to it will be overwritten when the script next updates this file,
58 * only reason strings will be preserved.
59 */
60
61#include <stdio.h>
62#include <openssl/err.h>
63#include <openssl/ts.h>
64
65/* BEGIN ERROR CODES */
66#ifndef OPENSSL_NO_ERR
67
68#define ERR_FUNC(func) ERR_PACK(ERR_LIB_TS,func,0)
69#define ERR_REASON(reason) ERR_PACK(ERR_LIB_TS,0,reason)
70
71static ERR_STRING_DATA TS_str_functs[]=
72 {
73{ERR_FUNC(TS_F_D2I_TS_RESP), "d2i_TS_RESP"},
74{ERR_FUNC(TS_F_DEF_SERIAL_CB), "DEF_SERIAL_CB"},
75{ERR_FUNC(TS_F_DEF_TIME_CB), "DEF_TIME_CB"},
76{ERR_FUNC(TS_F_ESS_ADD_SIGNING_CERT), "ESS_ADD_SIGNING_CERT"},
77{ERR_FUNC(TS_F_ESS_CERT_ID_NEW_INIT), "ESS_CERT_ID_NEW_INIT"},
78{ERR_FUNC(TS_F_ESS_SIGNING_CERT_NEW_INIT), "ESS_SIGNING_CERT_NEW_INIT"},
79{ERR_FUNC(TS_F_INT_TS_RESP_VERIFY_TOKEN), "INT_TS_RESP_VERIFY_TOKEN"},
80{ERR_FUNC(TS_F_PKCS7_TO_TS_TST_INFO), "PKCS7_to_TS_TST_INFO"},
81{ERR_FUNC(TS_F_TS_ACCURACY_SET_MICROS), "TS_ACCURACY_set_micros"},
82{ERR_FUNC(TS_F_TS_ACCURACY_SET_MILLIS), "TS_ACCURACY_set_millis"},
83{ERR_FUNC(TS_F_TS_ACCURACY_SET_SECONDS), "TS_ACCURACY_set_seconds"},
84{ERR_FUNC(TS_F_TS_CHECK_IMPRINTS), "TS_CHECK_IMPRINTS"},
85{ERR_FUNC(TS_F_TS_CHECK_NONCES), "TS_CHECK_NONCES"},
86{ERR_FUNC(TS_F_TS_CHECK_POLICY), "TS_CHECK_POLICY"},
87{ERR_FUNC(TS_F_TS_CHECK_SIGNING_CERTS), "TS_CHECK_SIGNING_CERTS"},
88{ERR_FUNC(TS_F_TS_CHECK_STATUS_INFO), "TS_CHECK_STATUS_INFO"},
89{ERR_FUNC(TS_F_TS_COMPUTE_IMPRINT), "TS_COMPUTE_IMPRINT"},
90{ERR_FUNC(TS_F_TS_CONF_SET_DEFAULT_ENGINE), "TS_CONF_set_default_engine"},
91{ERR_FUNC(TS_F_TS_GET_STATUS_TEXT), "TS_GET_STATUS_TEXT"},
92{ERR_FUNC(TS_F_TS_MSG_IMPRINT_SET_ALGO), "TS_MSG_IMPRINT_set_algo"},
93{ERR_FUNC(TS_F_TS_REQ_SET_MSG_IMPRINT), "TS_REQ_set_msg_imprint"},
94{ERR_FUNC(TS_F_TS_REQ_SET_NONCE), "TS_REQ_set_nonce"},
95{ERR_FUNC(TS_F_TS_REQ_SET_POLICY_ID), "TS_REQ_set_policy_id"},
96{ERR_FUNC(TS_F_TS_RESP_CREATE_RESPONSE), "TS_RESP_create_response"},
97{ERR_FUNC(TS_F_TS_RESP_CREATE_TST_INFO), "TS_RESP_CREATE_TST_INFO"},
98{ERR_FUNC(TS_F_TS_RESP_CTX_ADD_FAILURE_INFO), "TS_RESP_CTX_add_failure_info"},
99{ERR_FUNC(TS_F_TS_RESP_CTX_ADD_MD), "TS_RESP_CTX_add_md"},
100{ERR_FUNC(TS_F_TS_RESP_CTX_ADD_POLICY), "TS_RESP_CTX_add_policy"},
101{ERR_FUNC(TS_F_TS_RESP_CTX_NEW), "TS_RESP_CTX_new"},
102{ERR_FUNC(TS_F_TS_RESP_CTX_SET_ACCURACY), "TS_RESP_CTX_set_accuracy"},
103{ERR_FUNC(TS_F_TS_RESP_CTX_SET_CERTS), "TS_RESP_CTX_set_certs"},
104{ERR_FUNC(TS_F_TS_RESP_CTX_SET_DEF_POLICY), "TS_RESP_CTX_set_def_policy"},
105{ERR_FUNC(TS_F_TS_RESP_CTX_SET_SIGNER_CERT), "TS_RESP_CTX_set_signer_cert"},
106{ERR_FUNC(TS_F_TS_RESP_CTX_SET_STATUS_INFO), "TS_RESP_CTX_set_status_info"},
107{ERR_FUNC(TS_F_TS_RESP_GET_POLICY), "TS_RESP_GET_POLICY"},
108{ERR_FUNC(TS_F_TS_RESP_SET_GENTIME_WITH_PRECISION), "TS_RESP_SET_GENTIME_WITH_PRECISION"},
109{ERR_FUNC(TS_F_TS_RESP_SET_STATUS_INFO), "TS_RESP_set_status_info"},
110{ERR_FUNC(TS_F_TS_RESP_SET_TST_INFO), "TS_RESP_set_tst_info"},
111{ERR_FUNC(TS_F_TS_RESP_SIGN), "TS_RESP_SIGN"},
112{ERR_FUNC(TS_F_TS_RESP_VERIFY_SIGNATURE), "TS_RESP_verify_signature"},
113{ERR_FUNC(TS_F_TS_RESP_VERIFY_TOKEN), "TS_RESP_verify_token"},
114{ERR_FUNC(TS_F_TS_TST_INFO_SET_ACCURACY), "TS_TST_INFO_set_accuracy"},
115{ERR_FUNC(TS_F_TS_TST_INFO_SET_MSG_IMPRINT), "TS_TST_INFO_set_msg_imprint"},
116{ERR_FUNC(TS_F_TS_TST_INFO_SET_NONCE), "TS_TST_INFO_set_nonce"},
117{ERR_FUNC(TS_F_TS_TST_INFO_SET_POLICY_ID), "TS_TST_INFO_set_policy_id"},
118{ERR_FUNC(TS_F_TS_TST_INFO_SET_SERIAL), "TS_TST_INFO_set_serial"},
119{ERR_FUNC(TS_F_TS_TST_INFO_SET_TIME), "TS_TST_INFO_set_time"},
120{ERR_FUNC(TS_F_TS_TST_INFO_SET_TSA), "TS_TST_INFO_set_tsa"},
121{ERR_FUNC(TS_F_TS_VERIFY), "TS_VERIFY"},
122{ERR_FUNC(TS_F_TS_VERIFY_CERT), "TS_VERIFY_CERT"},
123{ERR_FUNC(TS_F_TS_VERIFY_CTX_NEW), "TS_VERIFY_CTX_new"},
124{0,NULL}
125 };
126
127static ERR_STRING_DATA TS_str_reasons[]=
128 {
129{ERR_REASON(TS_R_BAD_PKCS7_TYPE) ,"bad pkcs7 type"},
130{ERR_REASON(TS_R_BAD_TYPE) ,"bad type"},
131{ERR_REASON(TS_R_CERTIFICATE_VERIFY_ERROR),"certificate verify error"},
132{ERR_REASON(TS_R_COULD_NOT_SET_ENGINE) ,"could not set engine"},
133{ERR_REASON(TS_R_COULD_NOT_SET_TIME) ,"could not set time"},
134{ERR_REASON(TS_R_D2I_TS_RESP_INT_FAILED) ,"d2i ts resp int failed"},
135{ERR_REASON(TS_R_DETACHED_CONTENT) ,"detached content"},
136{ERR_REASON(TS_R_ESS_ADD_SIGNING_CERT_ERROR),"ess add signing cert error"},
137{ERR_REASON(TS_R_ESS_SIGNING_CERTIFICATE_ERROR),"ess signing certificate error"},
138{ERR_REASON(TS_R_INVALID_NULL_POINTER) ,"invalid null pointer"},
139{ERR_REASON(TS_R_INVALID_SIGNER_CERTIFICATE_PURPOSE),"invalid signer certificate purpose"},
140{ERR_REASON(TS_R_MESSAGE_IMPRINT_MISMATCH),"message imprint mismatch"},
141{ERR_REASON(TS_R_NONCE_MISMATCH) ,"nonce mismatch"},
142{ERR_REASON(TS_R_NONCE_NOT_RETURNED) ,"nonce not returned"},
143{ERR_REASON(TS_R_NO_CONTENT) ,"no content"},
144{ERR_REASON(TS_R_NO_TIME_STAMP_TOKEN) ,"no time stamp token"},
145{ERR_REASON(TS_R_PKCS7_ADD_SIGNATURE_ERROR),"pkcs7 add signature error"},
146{ERR_REASON(TS_R_PKCS7_ADD_SIGNED_ATTR_ERROR),"pkcs7 add signed attr error"},
147{ERR_REASON(TS_R_PKCS7_TO_TS_TST_INFO_FAILED),"pkcs7 to ts tst info failed"},
148{ERR_REASON(TS_R_POLICY_MISMATCH) ,"policy mismatch"},
149{ERR_REASON(TS_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE),"private key does not match certificate"},
150{ERR_REASON(TS_R_RESPONSE_SETUP_ERROR) ,"response setup error"},
151{ERR_REASON(TS_R_SIGNATURE_FAILURE) ,"signature failure"},
152{ERR_REASON(TS_R_THERE_MUST_BE_ONE_SIGNER),"there must be one signer"},
153{ERR_REASON(TS_R_TIME_SYSCALL_ERROR) ,"time syscall error"},
154{ERR_REASON(TS_R_TOKEN_NOT_PRESENT) ,"token not present"},
155{ERR_REASON(TS_R_TOKEN_PRESENT) ,"token present"},
156{ERR_REASON(TS_R_TSA_NAME_MISMATCH) ,"tsa name mismatch"},
157{ERR_REASON(TS_R_TSA_UNTRUSTED) ,"tsa untrusted"},
158{ERR_REASON(TS_R_TST_INFO_SETUP_ERROR) ,"tst info setup error"},
159{ERR_REASON(TS_R_TS_DATASIGN) ,"ts datasign"},
160{ERR_REASON(TS_R_UNACCEPTABLE_POLICY) ,"unacceptable policy"},
161{ERR_REASON(TS_R_UNSUPPORTED_MD_ALGORITHM),"unsupported md algorithm"},
162{ERR_REASON(TS_R_UNSUPPORTED_VERSION) ,"unsupported version"},
163{ERR_REASON(TS_R_WRONG_CONTENT_TYPE) ,"wrong content type"},
164{0,NULL}
165 };
166
167#endif
168
169void ERR_load_TS_strings(void)
170 {
171#ifndef OPENSSL_NO_ERR
172
173 if (ERR_func_error_string(TS_str_functs[0].error) == NULL)
174 {
175 ERR_load_strings(0,TS_str_functs);
176 ERR_load_strings(0,TS_str_reasons);
177 }
178#endif
179 }
diff --git a/src/lib/libcrypto/ts/ts_lib.c b/src/lib/libcrypto/ts/ts_lib.c
new file mode 100644
index 0000000000..e8608dbf71
--- /dev/null
+++ b/src/lib/libcrypto/ts/ts_lib.c
@@ -0,0 +1,145 @@
1/* crypto/ts/ts_lib.c */
2/* Written by Zoltan Glozik (zglozik@stones.com) for the OpenSSL
3 * project 2002.
4 */
5/* ====================================================================
6 * Copyright (c) 2006 The OpenSSL Project. All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 *
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 *
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in
17 * the documentation and/or other materials provided with the
18 * distribution.
19 *
20 * 3. All advertising materials mentioning features or use of this
21 * software must display the following acknowledgment:
22 * "This product includes software developed by the OpenSSL Project
23 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
24 *
25 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
26 * endorse or promote products derived from this software without
27 * prior written permission. For written permission, please contact
28 * licensing@OpenSSL.org.
29 *
30 * 5. Products derived from this software may not be called "OpenSSL"
31 * nor may "OpenSSL" appear in their names without prior written
32 * permission of the OpenSSL Project.
33 *
34 * 6. Redistributions of any form whatsoever must retain the following
35 * acknowledgment:
36 * "This product includes software developed by the OpenSSL Project
37 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
38 *
39 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
40 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
43 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
50 * OF THE POSSIBILITY OF SUCH DAMAGE.
51 * ====================================================================
52 *
53 * This product includes cryptographic software written by Eric Young
54 * (eay@cryptsoft.com). This product includes software written by Tim
55 * Hudson (tjh@cryptsoft.com).
56 *
57 */
58
59#include <stdio.h>
60#include "cryptlib.h"
61#include <openssl/objects.h>
62#include <openssl/bn.h>
63#include <openssl/x509v3.h>
64#include "ts.h"
65
66/* Local function declarations. */
67
68/* Function definitions. */
69
70int TS_ASN1_INTEGER_print_bio(BIO *bio, const ASN1_INTEGER *num)
71 {
72 BIGNUM num_bn;
73 int result = 0;
74 char *hex;
75
76 BN_init(&num_bn);
77 ASN1_INTEGER_to_BN(num, &num_bn);
78 if ((hex = BN_bn2hex(&num_bn)))
79 {
80 result = BIO_write(bio, "0x", 2) > 0;
81 result = result && BIO_write(bio, hex, strlen(hex)) > 0;
82 OPENSSL_free(hex);
83 }
84 BN_free(&num_bn);
85
86 return result;
87 }
88
89int TS_OBJ_print_bio(BIO *bio, const ASN1_OBJECT *obj)
90 {
91 char obj_txt[128];
92
93 int len = OBJ_obj2txt(obj_txt, sizeof(obj_txt), obj, 0);
94 BIO_write(bio, obj_txt, len);
95 BIO_write(bio, "\n", 1);
96
97 return 1;
98 }
99
100int TS_ext_print_bio(BIO *bio, const STACK_OF(X509_EXTENSION) *extensions)
101 {
102 int i, critical, n;
103 X509_EXTENSION *ex;
104 ASN1_OBJECT *obj;
105
106 BIO_printf(bio, "Extensions:\n");
107 n = X509v3_get_ext_count(extensions);
108 for (i = 0; i < n; i++)
109 {
110 ex = X509v3_get_ext(extensions, i);
111 obj = X509_EXTENSION_get_object(ex);
112 i2a_ASN1_OBJECT(bio, obj);
113 critical = X509_EXTENSION_get_critical(ex);
114 BIO_printf(bio, ": %s\n", critical ? "critical" : "");
115 if (!X509V3_EXT_print(bio, ex, 0, 4))
116 {
117 BIO_printf(bio, "%4s", "");
118 M_ASN1_OCTET_STRING_print(bio, ex->value);
119 }
120 BIO_write(bio, "\n", 1);
121 }
122
123 return 1;
124 }
125
126int TS_X509_ALGOR_print_bio(BIO *bio, const X509_ALGOR *alg)
127 {
128 int i = OBJ_obj2nid(alg->algorithm);
129 return BIO_printf(bio, "Hash Algorithm: %s\n",
130 (i == NID_undef) ? "UNKNOWN" : OBJ_nid2ln(i));
131 }
132
133int TS_MSG_IMPRINT_print_bio(BIO *bio, TS_MSG_IMPRINT *a)
134 {
135 const ASN1_OCTET_STRING *msg;
136
137 TS_X509_ALGOR_print_bio(bio, TS_MSG_IMPRINT_get_algo(a));
138
139 BIO_printf(bio, "Message data:\n");
140 msg = TS_MSG_IMPRINT_get_msg(a);
141 BIO_dump_indent(bio, (const char *)M_ASN1_STRING_data(msg),
142 M_ASN1_STRING_length(msg), 4);
143
144 return 1;
145 }
diff --git a/src/lib/libcrypto/ts/ts_req_print.c b/src/lib/libcrypto/ts/ts_req_print.c
new file mode 100644
index 0000000000..eba12c3824
--- /dev/null
+++ b/src/lib/libcrypto/ts/ts_req_print.c
@@ -0,0 +1,102 @@
1/* crypto/ts/ts_req_print.c */
2/* Written by Zoltan Glozik (zglozik@stones.com) for the OpenSSL
3 * project 2002.
4 */
5/* ====================================================================
6 * Copyright (c) 2006 The OpenSSL Project. All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 *
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 *
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in
17 * the documentation and/or other materials provided with the
18 * distribution.
19 *
20 * 3. All advertising materials mentioning features or use of this
21 * software must display the following acknowledgment:
22 * "This product includes software developed by the OpenSSL Project
23 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
24 *
25 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
26 * endorse or promote products derived from this software without
27 * prior written permission. For written permission, please contact
28 * licensing@OpenSSL.org.
29 *
30 * 5. Products derived from this software may not be called "OpenSSL"
31 * nor may "OpenSSL" appear in their names without prior written
32 * permission of the OpenSSL Project.
33 *
34 * 6. Redistributions of any form whatsoever must retain the following
35 * acknowledgment:
36 * "This product includes software developed by the OpenSSL Project
37 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
38 *
39 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
40 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
43 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
50 * OF THE POSSIBILITY OF SUCH DAMAGE.
51 * ====================================================================
52 *
53 * This product includes cryptographic software written by Eric Young
54 * (eay@cryptsoft.com). This product includes software written by Tim
55 * Hudson (tjh@cryptsoft.com).
56 *
57 */
58
59#include <stdio.h>
60#include "cryptlib.h"
61#include <openssl/objects.h>
62#include <openssl/bn.h>
63#include <openssl/x509v3.h>
64#include <openssl/ts.h>
65
66/* Function definitions. */
67
68int TS_REQ_print_bio(BIO *bio, TS_REQ *a)
69 {
70 int v;
71 ASN1_OBJECT *policy_id;
72 const ASN1_INTEGER *nonce;
73
74 if (a == NULL) return 0;
75
76 v = TS_REQ_get_version(a);
77 BIO_printf(bio, "Version: %d\n", v);
78
79 TS_MSG_IMPRINT_print_bio(bio, TS_REQ_get_msg_imprint(a));
80
81 BIO_printf(bio, "Policy OID: ");
82 policy_id = TS_REQ_get_policy_id(a);
83 if (policy_id == NULL)
84 BIO_printf(bio, "unspecified\n");
85 else
86 TS_OBJ_print_bio(bio, policy_id);
87
88 BIO_printf(bio, "Nonce: ");
89 nonce = TS_REQ_get_nonce(a);
90 if (nonce == NULL)
91 BIO_printf(bio, "unspecified");
92 else
93 TS_ASN1_INTEGER_print_bio(bio, nonce);
94 BIO_write(bio, "\n", 1);
95
96 BIO_printf(bio, "Certificate required: %s\n",
97 TS_REQ_get_cert_req(a) ? "yes" : "no");
98
99 TS_ext_print_bio(bio, TS_REQ_get_exts(a));
100
101 return 1;
102 }
diff --git a/src/lib/libcrypto/ts/ts_req_utils.c b/src/lib/libcrypto/ts/ts_req_utils.c
new file mode 100644
index 0000000000..43280c1587
--- /dev/null
+++ b/src/lib/libcrypto/ts/ts_req_utils.c
@@ -0,0 +1,234 @@
1/* crypto/ts/ts_req_utils.c */
2/* Written by Zoltan Glozik (zglozik@stones.com) for the OpenSSL
3 * project 2002.
4 */
5/* ====================================================================
6 * Copyright (c) 2006 The OpenSSL Project. All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 *
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 *
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in
17 * the documentation and/or other materials provided with the
18 * distribution.
19 *
20 * 3. All advertising materials mentioning features or use of this
21 * software must display the following acknowledgment:
22 * "This product includes software developed by the OpenSSL Project
23 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
24 *
25 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
26 * endorse or promote products derived from this software without
27 * prior written permission. For written permission, please contact
28 * licensing@OpenSSL.org.
29 *
30 * 5. Products derived from this software may not be called "OpenSSL"
31 * nor may "OpenSSL" appear in their names without prior written
32 * permission of the OpenSSL Project.
33 *
34 * 6. Redistributions of any form whatsoever must retain the following
35 * acknowledgment:
36 * "This product includes software developed by the OpenSSL Project
37 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
38 *
39 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
40 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
43 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
50 * OF THE POSSIBILITY OF SUCH DAMAGE.
51 * ====================================================================
52 *
53 * This product includes cryptographic software written by Eric Young
54 * (eay@cryptsoft.com). This product includes software written by Tim
55 * Hudson (tjh@cryptsoft.com).
56 *
57 */
58
59#include <stdio.h>
60#include "cryptlib.h"
61#include <openssl/objects.h>
62#include <openssl/x509v3.h>
63#include <openssl/ts.h>
64
65int TS_REQ_set_version(TS_REQ *a, long version)
66 {
67 return ASN1_INTEGER_set(a->version, version);
68 }
69
70long TS_REQ_get_version(const TS_REQ *a)
71 {
72 return ASN1_INTEGER_get(a->version);
73 }
74
75int TS_REQ_set_msg_imprint(TS_REQ *a, TS_MSG_IMPRINT *msg_imprint)
76 {
77 TS_MSG_IMPRINT *new_msg_imprint;
78
79 if (a->msg_imprint == msg_imprint)
80 return 1;
81 new_msg_imprint = TS_MSG_IMPRINT_dup(msg_imprint);
82 if (new_msg_imprint == NULL)
83 {
84 TSerr(TS_F_TS_REQ_SET_MSG_IMPRINT, ERR_R_MALLOC_FAILURE);
85 return 0;
86 }
87 TS_MSG_IMPRINT_free(a->msg_imprint);
88 a->msg_imprint = new_msg_imprint;
89 return 1;
90 }
91
92TS_MSG_IMPRINT *TS_REQ_get_msg_imprint(TS_REQ *a)
93 {
94 return a->msg_imprint;
95 }
96
97int TS_MSG_IMPRINT_set_algo(TS_MSG_IMPRINT *a, X509_ALGOR *alg)
98 {
99 X509_ALGOR *new_alg;
100
101 if (a->hash_algo == alg)
102 return 1;
103 new_alg = X509_ALGOR_dup(alg);
104 if (new_alg == NULL)
105 {
106 TSerr(TS_F_TS_MSG_IMPRINT_SET_ALGO, ERR_R_MALLOC_FAILURE);
107 return 0;
108 }
109 X509_ALGOR_free(a->hash_algo);
110 a->hash_algo = new_alg;
111 return 1;
112 }
113
114X509_ALGOR *TS_MSG_IMPRINT_get_algo(TS_MSG_IMPRINT *a)
115 {
116 return a->hash_algo;
117 }
118
119int TS_MSG_IMPRINT_set_msg(TS_MSG_IMPRINT *a, unsigned char *d, int len)
120 {
121 return ASN1_OCTET_STRING_set(a->hashed_msg, d, len);
122 }
123
124ASN1_OCTET_STRING *TS_MSG_IMPRINT_get_msg(TS_MSG_IMPRINT *a)
125 {
126 return a->hashed_msg;
127 }
128
129int TS_REQ_set_policy_id(TS_REQ *a, ASN1_OBJECT *policy)
130 {
131 ASN1_OBJECT *new_policy;
132
133 if (a->policy_id == policy)
134 return 1;
135 new_policy = OBJ_dup(policy);
136 if (new_policy == NULL)
137 {
138 TSerr(TS_F_TS_REQ_SET_POLICY_ID, ERR_R_MALLOC_FAILURE);
139 return 0;
140 }
141 ASN1_OBJECT_free(a->policy_id);
142 a->policy_id = new_policy;
143 return 1;
144 }
145
146ASN1_OBJECT *TS_REQ_get_policy_id(TS_REQ *a)
147 {
148 return a->policy_id;
149 }
150
151int TS_REQ_set_nonce(TS_REQ *a, const ASN1_INTEGER *nonce)
152 {
153 ASN1_INTEGER *new_nonce;
154
155 if (a->nonce == nonce)
156 return 1;
157 new_nonce = ASN1_INTEGER_dup(nonce);
158 if (new_nonce == NULL)
159 {
160 TSerr(TS_F_TS_REQ_SET_NONCE, ERR_R_MALLOC_FAILURE);
161 return 0;
162 }
163 ASN1_INTEGER_free(a->nonce);
164 a->nonce = new_nonce;
165 return 1;
166 }
167
168const ASN1_INTEGER *TS_REQ_get_nonce(const TS_REQ *a)
169 {
170 return a->nonce;
171 }
172
173int TS_REQ_set_cert_req(TS_REQ *a, int cert_req)
174 {
175 a->cert_req = cert_req ? 0xFF : 0x00;
176 return 1;
177 }
178
179int TS_REQ_get_cert_req(const TS_REQ *a)
180 {
181 return a->cert_req ? 1 : 0;
182 }
183
184STACK_OF(X509_EXTENSION) *TS_REQ_get_exts(TS_REQ *a)
185 {
186 return a->extensions;
187 }
188
189void TS_REQ_ext_free(TS_REQ *a)
190 {
191 if (!a) return;
192 sk_X509_EXTENSION_pop_free(a->extensions, X509_EXTENSION_free);
193 a->extensions = NULL;
194 }
195
196int TS_REQ_get_ext_count(TS_REQ *a)
197 {
198 return X509v3_get_ext_count(a->extensions);
199 }
200
201int TS_REQ_get_ext_by_NID(TS_REQ *a, int nid, int lastpos)
202 {
203 return X509v3_get_ext_by_NID(a->extensions, nid, lastpos);
204 }
205
206int TS_REQ_get_ext_by_OBJ(TS_REQ *a, ASN1_OBJECT *obj, int lastpos)
207 {
208 return X509v3_get_ext_by_OBJ(a->extensions, obj, lastpos);
209 }
210
211int TS_REQ_get_ext_by_critical(TS_REQ *a, int crit, int lastpos)
212 {
213 return X509v3_get_ext_by_critical(a->extensions, crit, lastpos);
214 }
215
216X509_EXTENSION *TS_REQ_get_ext(TS_REQ *a, int loc)
217 {
218 return X509v3_get_ext(a->extensions,loc);
219 }
220
221X509_EXTENSION *TS_REQ_delete_ext(TS_REQ *a, int loc)
222 {
223 return X509v3_delete_ext(a->extensions,loc);
224 }
225
226int TS_REQ_add_ext(TS_REQ *a, X509_EXTENSION *ex, int loc)
227 {
228 return X509v3_add_ext(&a->extensions,ex,loc) != NULL;
229 }
230
231void *TS_REQ_get_ext_d2i(TS_REQ *a, int nid, int *crit, int *idx)
232 {
233 return X509V3_get_d2i(a->extensions, nid, crit, idx);
234 }
diff --git a/src/lib/libcrypto/ts/ts_rsp_print.c b/src/lib/libcrypto/ts/ts_rsp_print.c
new file mode 100644
index 0000000000..21062517ba
--- /dev/null
+++ b/src/lib/libcrypto/ts/ts_rsp_print.c
@@ -0,0 +1,287 @@
1/* crypto/ts/ts_resp_print.c */
2/* Written by Zoltan Glozik (zglozik@stones.com) for the OpenSSL
3 * project 2002.
4 */
5/* ====================================================================
6 * Copyright (c) 2006 The OpenSSL Project. All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 *
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 *
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in
17 * the documentation and/or other materials provided with the
18 * distribution.
19 *
20 * 3. All advertising materials mentioning features or use of this
21 * software must display the following acknowledgment:
22 * "This product includes software developed by the OpenSSL Project
23 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
24 *
25 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
26 * endorse or promote products derived from this software without
27 * prior written permission. For written permission, please contact
28 * licensing@OpenSSL.org.
29 *
30 * 5. Products derived from this software may not be called "OpenSSL"
31 * nor may "OpenSSL" appear in their names without prior written
32 * permission of the OpenSSL Project.
33 *
34 * 6. Redistributions of any form whatsoever must retain the following
35 * acknowledgment:
36 * "This product includes software developed by the OpenSSL Project
37 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
38 *
39 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
40 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
43 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
50 * OF THE POSSIBILITY OF SUCH DAMAGE.
51 * ====================================================================
52 *
53 * This product includes cryptographic software written by Eric Young
54 * (eay@cryptsoft.com). This product includes software written by Tim
55 * Hudson (tjh@cryptsoft.com).
56 *
57 */
58
59#include <stdio.h>
60#include "cryptlib.h"
61#include <openssl/objects.h>
62#include <openssl/bn.h>
63#include <openssl/x509v3.h>
64#include "ts.h"
65
66struct status_map_st
67 {
68 int bit;
69 const char *text;
70 };
71
72/* Local function declarations. */
73
74static int TS_status_map_print(BIO *bio, struct status_map_st *a,
75 ASN1_BIT_STRING *v);
76static int TS_ACCURACY_print_bio(BIO *bio, const TS_ACCURACY *accuracy);
77
78/* Function definitions. */
79
80int TS_RESP_print_bio(BIO *bio, TS_RESP *a)
81 {
82 TS_TST_INFO *tst_info;
83
84 BIO_printf(bio, "Status info:\n");
85 TS_STATUS_INFO_print_bio(bio, TS_RESP_get_status_info(a));
86
87 BIO_printf(bio, "\nTST info:\n");
88 tst_info = TS_RESP_get_tst_info(a);
89 if (tst_info != NULL)
90 TS_TST_INFO_print_bio(bio, TS_RESP_get_tst_info(a));
91 else
92 BIO_printf(bio, "Not included.\n");
93
94 return 1;
95 }
96
97int TS_STATUS_INFO_print_bio(BIO *bio, TS_STATUS_INFO *a)
98 {
99 static const char *status_map[] =
100 {
101 "Granted.",
102 "Granted with modifications.",
103 "Rejected.",
104 "Waiting.",
105 "Revocation warning.",
106 "Revoked."
107 };
108 static struct status_map_st failure_map[] =
109 {
110 { TS_INFO_BAD_ALG,
111 "unrecognized or unsupported algorithm identifier" },
112 { TS_INFO_BAD_REQUEST,
113 "transaction not permitted or supported" },
114 { TS_INFO_BAD_DATA_FORMAT,
115 "the data submitted has the wrong format" },
116 { TS_INFO_TIME_NOT_AVAILABLE,
117 "the TSA's time source is not available" },
118 { TS_INFO_UNACCEPTED_POLICY,
119 "the requested TSA policy is not supported by the TSA" },
120 { TS_INFO_UNACCEPTED_EXTENSION,
121 "the requested extension is not supported by the TSA" },
122 { TS_INFO_ADD_INFO_NOT_AVAILABLE,
123 "the additional information requested could not be understood "
124 "or is not available" },
125 { TS_INFO_SYSTEM_FAILURE,
126 "the request cannot be handled due to system failure" },
127 { -1, NULL }
128 };
129 long status;
130 int i, lines = 0;
131
132 /* Printing status code. */
133 BIO_printf(bio, "Status: ");
134 status = ASN1_INTEGER_get(a->status);
135 if (0 <= status && status < (long)(sizeof(status_map)/sizeof(status_map[0])))
136 BIO_printf(bio, "%s\n", status_map[status]);
137 else
138 BIO_printf(bio, "out of bounds\n");
139
140 /* Printing status description. */
141 BIO_printf(bio, "Status description: ");
142 for (i = 0; i < sk_ASN1_UTF8STRING_num(a->text); ++i)
143 {
144 if (i > 0)
145 BIO_puts(bio, "\t");
146 ASN1_STRING_print_ex(bio, sk_ASN1_UTF8STRING_value(a->text, i),
147 0);
148 BIO_puts(bio, "\n");
149 }
150 if (i == 0)
151 BIO_printf(bio, "unspecified\n");
152
153 /* Printing failure information. */
154 BIO_printf(bio, "Failure info: ");
155 if (a->failure_info != NULL)
156 lines = TS_status_map_print(bio, failure_map,
157 a->failure_info);
158 if (lines == 0)
159 BIO_printf(bio, "unspecified");
160 BIO_printf(bio, "\n");
161
162 return 1;
163 }
164
165static int TS_status_map_print(BIO *bio, struct status_map_st *a,
166 ASN1_BIT_STRING *v)
167 {
168 int lines = 0;
169
170 for (; a->bit >= 0; ++a)
171 {
172 if (ASN1_BIT_STRING_get_bit(v, a->bit))
173 {
174 if (++lines > 1)
175 BIO_printf(bio, ", ");
176 BIO_printf(bio, "%s", a->text);
177 }
178 }
179
180 return lines;
181 }
182
183int TS_TST_INFO_print_bio(BIO *bio, TS_TST_INFO *a)
184 {
185 int v;
186 ASN1_OBJECT *policy_id;
187 const ASN1_INTEGER *serial;
188 const ASN1_GENERALIZEDTIME *gtime;
189 TS_ACCURACY *accuracy;
190 const ASN1_INTEGER *nonce;
191 GENERAL_NAME *tsa_name;
192
193 if (a == NULL) return 0;
194
195 /* Print version. */
196 v = TS_TST_INFO_get_version(a);
197 BIO_printf(bio, "Version: %d\n", v);
198
199 /* Print policy id. */
200 BIO_printf(bio, "Policy OID: ");
201 policy_id = TS_TST_INFO_get_policy_id(a);
202 TS_OBJ_print_bio(bio, policy_id);
203
204 /* Print message imprint. */
205 TS_MSG_IMPRINT_print_bio(bio, TS_TST_INFO_get_msg_imprint(a));
206
207 /* Print serial number. */
208 BIO_printf(bio, "Serial number: ");
209 serial = TS_TST_INFO_get_serial(a);
210 if (serial == NULL)
211 BIO_printf(bio, "unspecified");
212 else
213 TS_ASN1_INTEGER_print_bio(bio, serial);
214 BIO_write(bio, "\n", 1);
215
216 /* Print time stamp. */
217 BIO_printf(bio, "Time stamp: ");
218 gtime = TS_TST_INFO_get_time(a);
219 ASN1_GENERALIZEDTIME_print(bio, gtime);
220 BIO_write(bio, "\n", 1);
221
222 /* Print accuracy. */
223 BIO_printf(bio, "Accuracy: ");
224 accuracy = TS_TST_INFO_get_accuracy(a);
225 if (accuracy == NULL)
226 BIO_printf(bio, "unspecified");
227 else
228 TS_ACCURACY_print_bio(bio, accuracy);
229 BIO_write(bio, "\n", 1);
230
231 /* Print ordering. */
232 BIO_printf(bio, "Ordering: %s\n",
233 TS_TST_INFO_get_ordering(a) ? "yes" : "no");
234
235 /* Print nonce. */
236 BIO_printf(bio, "Nonce: ");
237 nonce = TS_TST_INFO_get_nonce(a);
238 if (nonce == NULL)
239 BIO_printf(bio, "unspecified");
240 else
241 TS_ASN1_INTEGER_print_bio(bio, nonce);
242 BIO_write(bio, "\n", 1);
243
244 /* Print TSA name. */
245 BIO_printf(bio, "TSA: ");
246 tsa_name = TS_TST_INFO_get_tsa(a);
247 if (tsa_name == NULL)
248 BIO_printf(bio, "unspecified");
249 else
250 {
251 STACK_OF(CONF_VALUE) *nval;
252 if ((nval = i2v_GENERAL_NAME(NULL, tsa_name, NULL)))
253 X509V3_EXT_val_prn(bio, nval, 0, 0);
254 sk_CONF_VALUE_pop_free(nval, X509V3_conf_free);
255 }
256 BIO_write(bio, "\n", 1);
257
258 /* Print extensions. */
259 TS_ext_print_bio(bio, TS_TST_INFO_get_exts(a));
260
261 return 1;
262 }
263
264static int TS_ACCURACY_print_bio(BIO *bio, const TS_ACCURACY *accuracy)
265 {
266 const ASN1_INTEGER *seconds = TS_ACCURACY_get_seconds(accuracy);
267 const ASN1_INTEGER *millis = TS_ACCURACY_get_millis(accuracy);
268 const ASN1_INTEGER *micros = TS_ACCURACY_get_micros(accuracy);
269
270 if (seconds != NULL)
271 TS_ASN1_INTEGER_print_bio(bio, seconds);
272 else
273 BIO_printf(bio, "unspecified");
274 BIO_printf(bio, " seconds, ");
275 if (millis != NULL)
276 TS_ASN1_INTEGER_print_bio(bio, millis);
277 else
278 BIO_printf(bio, "unspecified");
279 BIO_printf(bio, " millis, ");
280 if (micros != NULL)
281 TS_ASN1_INTEGER_print_bio(bio, micros);
282 else
283 BIO_printf(bio, "unspecified");
284 BIO_printf(bio, " micros");
285
286 return 1;
287 }
diff --git a/src/lib/libcrypto/ts/ts_rsp_sign.c b/src/lib/libcrypto/ts/ts_rsp_sign.c
new file mode 100644
index 0000000000..b0f023c9d2
--- /dev/null
+++ b/src/lib/libcrypto/ts/ts_rsp_sign.c
@@ -0,0 +1,1020 @@
1/* crypto/ts/ts_resp_sign.c */
2/* Written by Zoltan Glozik (zglozik@stones.com) for the OpenSSL
3 * project 2002.
4 */
5/* ====================================================================
6 * Copyright (c) 2006 The OpenSSL Project. All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 *
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 *
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in
17 * the documentation and/or other materials provided with the
18 * distribution.
19 *
20 * 3. All advertising materials mentioning features or use of this
21 * software must display the following acknowledgment:
22 * "This product includes software developed by the OpenSSL Project
23 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
24 *
25 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
26 * endorse or promote products derived from this software without
27 * prior written permission. For written permission, please contact
28 * licensing@OpenSSL.org.
29 *
30 * 5. Products derived from this software may not be called "OpenSSL"
31 * nor may "OpenSSL" appear in their names without prior written
32 * permission of the OpenSSL Project.
33 *
34 * 6. Redistributions of any form whatsoever must retain the following
35 * acknowledgment:
36 * "This product includes software developed by the OpenSSL Project
37 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
38 *
39 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
40 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
43 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
50 * OF THE POSSIBILITY OF SUCH DAMAGE.
51 * ====================================================================
52 *
53 * This product includes cryptographic software written by Eric Young
54 * (eay@cryptsoft.com). This product includes software written by Tim
55 * Hudson (tjh@cryptsoft.com).
56 *
57 */
58
59#include "cryptlib.h"
60
61#if defined(OPENSSL_SYS_UNIX)
62#include <sys/time.h>
63#endif
64
65#include <openssl/objects.h>
66#include <openssl/ts.h>
67#include <openssl/pkcs7.h>
68
69/* Private function declarations. */
70
71static ASN1_INTEGER *def_serial_cb(struct TS_resp_ctx *, void *);
72static int def_time_cb(struct TS_resp_ctx *, void *, long *sec, long *usec);
73static int def_extension_cb(struct TS_resp_ctx *, X509_EXTENSION *, void *);
74
75static void TS_RESP_CTX_init(TS_RESP_CTX *ctx);
76static void TS_RESP_CTX_cleanup(TS_RESP_CTX *ctx);
77static int TS_RESP_check_request(TS_RESP_CTX *ctx);
78static ASN1_OBJECT *TS_RESP_get_policy(TS_RESP_CTX *ctx);
79static TS_TST_INFO *TS_RESP_create_tst_info(TS_RESP_CTX *ctx,
80 ASN1_OBJECT *policy);
81static int TS_RESP_process_extensions(TS_RESP_CTX *ctx);
82static int TS_RESP_sign(TS_RESP_CTX *ctx);
83
84static ESS_SIGNING_CERT *ESS_SIGNING_CERT_new_init(X509 *signcert,
85 STACK_OF(X509) *certs);
86static ESS_CERT_ID *ESS_CERT_ID_new_init(X509 *cert, int issuer_needed);
87static int TS_TST_INFO_content_new(PKCS7 *p7);
88static int ESS_add_signing_cert(PKCS7_SIGNER_INFO *si, ESS_SIGNING_CERT *sc);
89
90static ASN1_GENERALIZEDTIME *TS_RESP_set_genTime_with_precision(
91 ASN1_GENERALIZEDTIME *, long, long, unsigned);
92
93/* Default callbacks for response generation. */
94
95static ASN1_INTEGER *def_serial_cb(struct TS_resp_ctx *ctx, void *data)
96 {
97 ASN1_INTEGER *serial = ASN1_INTEGER_new();
98 if (!serial) goto err;
99 if (!ASN1_INTEGER_set(serial, 1)) goto err;
100 return serial;
101 err:
102 TSerr(TS_F_DEF_SERIAL_CB, ERR_R_MALLOC_FAILURE);
103 TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION,
104 "Error during serial number generation.");
105 return NULL;
106 }
107
108#if defined(OPENSSL_SYS_UNIX)
109
110/* Use the gettimeofday function call. */
111static int def_time_cb(struct TS_resp_ctx *ctx, void *data,
112 long *sec, long *usec)
113 {
114 struct timeval tv;
115 if (gettimeofday(&tv, NULL) != 0)
116 {
117 TSerr(TS_F_DEF_TIME_CB, TS_R_TIME_SYSCALL_ERROR);
118 TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION,
119 "Time is not available.");
120 TS_RESP_CTX_add_failure_info(ctx, TS_INFO_TIME_NOT_AVAILABLE);
121 return 0;
122 }
123 /* Return time to caller. */
124 *sec = tv.tv_sec;
125 *usec = tv.tv_usec;
126
127 return 1;
128 }
129
130#else
131
132/* Use the time function call that provides only seconds precision. */
133static int def_time_cb(struct TS_resp_ctx *ctx, void *data,
134 long *sec, long *usec)
135 {
136 time_t t;
137 if (time(&t) == (time_t) -1)
138 {
139 TSerr(TS_F_DEF_TIME_CB, TS_R_TIME_SYSCALL_ERROR);
140 TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION,
141 "Time is not available.");
142 TS_RESP_CTX_add_failure_info(ctx, TS_INFO_TIME_NOT_AVAILABLE);
143 return 0;
144 }
145 /* Return time to caller, only second precision. */
146 *sec = (long) t;
147 *usec = 0;
148
149 return 1;
150 }
151
152#endif
153
154static int def_extension_cb(struct TS_resp_ctx *ctx, X509_EXTENSION *ext,
155 void *data)
156 {
157 /* No extensions are processed here. */
158 TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION,
159 "Unsupported extension.");
160 TS_RESP_CTX_add_failure_info(ctx, TS_INFO_UNACCEPTED_EXTENSION);
161 return 0;
162 }
163
164/* TS_RESP_CTX management functions. */
165
166TS_RESP_CTX *TS_RESP_CTX_new()
167 {
168 TS_RESP_CTX *ctx;
169
170 if (!(ctx = (TS_RESP_CTX *) OPENSSL_malloc(sizeof(TS_RESP_CTX))))
171 {
172 TSerr(TS_F_TS_RESP_CTX_NEW, ERR_R_MALLOC_FAILURE);
173 return NULL;
174 }
175 memset(ctx, 0, sizeof(TS_RESP_CTX));
176
177 /* Setting default callbacks. */
178 ctx->serial_cb = def_serial_cb;
179 ctx->time_cb = def_time_cb;
180 ctx->extension_cb = def_extension_cb;
181
182 return ctx;
183 }
184
185void TS_RESP_CTX_free(TS_RESP_CTX *ctx)
186 {
187 if (!ctx) return;
188
189 X509_free(ctx->signer_cert);
190 EVP_PKEY_free(ctx->signer_key);
191 sk_X509_pop_free(ctx->certs, X509_free);
192 sk_ASN1_OBJECT_pop_free(ctx->policies, ASN1_OBJECT_free);
193 ASN1_OBJECT_free(ctx->default_policy);
194 sk_EVP_MD_free(ctx->mds); /* No EVP_MD_free method exists. */
195 ASN1_INTEGER_free(ctx->seconds);
196 ASN1_INTEGER_free(ctx->millis);
197 ASN1_INTEGER_free(ctx->micros);
198 OPENSSL_free(ctx);
199 }
200
201int TS_RESP_CTX_set_signer_cert(TS_RESP_CTX *ctx, X509 *signer)
202 {
203 if (X509_check_purpose(signer, X509_PURPOSE_TIMESTAMP_SIGN, 0) != 1)
204 {
205 TSerr(TS_F_TS_RESP_CTX_SET_SIGNER_CERT,
206 TS_R_INVALID_SIGNER_CERTIFICATE_PURPOSE);
207 return 0;
208 }
209 if (ctx->signer_cert) X509_free(ctx->signer_cert);
210 ctx->signer_cert = signer;
211 CRYPTO_add(&ctx->signer_cert->references, +1, CRYPTO_LOCK_X509);
212 return 1;
213 }
214
215int TS_RESP_CTX_set_signer_key(TS_RESP_CTX *ctx, EVP_PKEY *key)
216 {
217 if (ctx->signer_key) EVP_PKEY_free(ctx->signer_key);
218 ctx->signer_key = key;
219 CRYPTO_add(&ctx->signer_key->references, +1, CRYPTO_LOCK_EVP_PKEY);
220
221 return 1;
222 }
223
224int TS_RESP_CTX_set_def_policy(TS_RESP_CTX *ctx, ASN1_OBJECT *def_policy)
225 {
226 if (ctx->default_policy) ASN1_OBJECT_free(ctx->default_policy);
227 if (!(ctx->default_policy = OBJ_dup(def_policy))) goto err;
228 return 1;
229 err:
230 TSerr(TS_F_TS_RESP_CTX_SET_DEF_POLICY, ERR_R_MALLOC_FAILURE);
231 return 0;
232 }
233
234int TS_RESP_CTX_set_certs(TS_RESP_CTX *ctx, STACK_OF(X509) *certs)
235 {
236 int i;
237
238 if (ctx->certs)
239 {
240 sk_X509_pop_free(ctx->certs, X509_free);
241 ctx->certs = NULL;
242 }
243 if (!certs) return 1;
244 if (!(ctx->certs = sk_X509_dup(certs)))
245 {
246 TSerr(TS_F_TS_RESP_CTX_SET_CERTS, ERR_R_MALLOC_FAILURE);
247 return 0;
248 }
249 for (i = 0; i < sk_X509_num(ctx->certs); ++i)
250 {
251 X509 *cert = sk_X509_value(ctx->certs, i);
252 CRYPTO_add(&cert->references, +1, CRYPTO_LOCK_X509);
253 }
254
255 return 1;
256 }
257
258int TS_RESP_CTX_add_policy(TS_RESP_CTX *ctx, ASN1_OBJECT *policy)
259 {
260 ASN1_OBJECT *copy = NULL;
261
262 /* Create new policy stack if necessary. */
263 if (!ctx->policies && !(ctx->policies = sk_ASN1_OBJECT_new_null()))
264 goto err;
265 if (!(copy = OBJ_dup(policy))) goto err;
266 if (!sk_ASN1_OBJECT_push(ctx->policies, copy)) goto err;
267
268 return 1;
269 err:
270 TSerr(TS_F_TS_RESP_CTX_ADD_POLICY, ERR_R_MALLOC_FAILURE);
271 ASN1_OBJECT_free(copy);
272 return 0;
273 }
274
275int TS_RESP_CTX_add_md(TS_RESP_CTX *ctx, const EVP_MD *md)
276 {
277 /* Create new md stack if necessary. */
278 if (!ctx->mds && !(ctx->mds = sk_EVP_MD_new_null()))
279 goto err;
280 /* Add the shared md, no copy needed. */
281 if (!sk_EVP_MD_push(ctx->mds, (EVP_MD *)md)) goto err;
282
283 return 1;
284 err:
285 TSerr(TS_F_TS_RESP_CTX_ADD_MD, ERR_R_MALLOC_FAILURE);
286 return 0;
287 }
288
289#define TS_RESP_CTX_accuracy_free(ctx) \
290 ASN1_INTEGER_free(ctx->seconds); \
291 ctx->seconds = NULL; \
292 ASN1_INTEGER_free(ctx->millis); \
293 ctx->millis = NULL; \
294 ASN1_INTEGER_free(ctx->micros); \
295 ctx->micros = NULL;
296
297int TS_RESP_CTX_set_accuracy(TS_RESP_CTX *ctx,
298 int secs, int millis, int micros)
299 {
300
301 TS_RESP_CTX_accuracy_free(ctx);
302 if (secs && (!(ctx->seconds = ASN1_INTEGER_new())
303 || !ASN1_INTEGER_set(ctx->seconds, secs)))
304 goto err;
305 if (millis && (!(ctx->millis = ASN1_INTEGER_new())
306 || !ASN1_INTEGER_set(ctx->millis, millis)))
307 goto err;
308 if (micros && (!(ctx->micros = ASN1_INTEGER_new())
309 || !ASN1_INTEGER_set(ctx->micros, micros)))
310 goto err;
311
312 return 1;
313 err:
314 TS_RESP_CTX_accuracy_free(ctx);
315 TSerr(TS_F_TS_RESP_CTX_SET_ACCURACY, ERR_R_MALLOC_FAILURE);
316 return 0;
317 }
318
319void TS_RESP_CTX_add_flags(TS_RESP_CTX *ctx, int flags)
320 {
321 ctx->flags |= flags;
322 }
323
324void TS_RESP_CTX_set_serial_cb(TS_RESP_CTX *ctx, TS_serial_cb cb, void *data)
325 {
326 ctx->serial_cb = cb;
327 ctx->serial_cb_data = data;
328 }
329
330void TS_RESP_CTX_set_time_cb(TS_RESP_CTX *ctx, TS_time_cb cb, void *data)
331 {
332 ctx->time_cb = cb;
333 ctx->time_cb_data = data;
334 }
335
336void TS_RESP_CTX_set_extension_cb(TS_RESP_CTX *ctx,
337 TS_extension_cb cb, void *data)
338 {
339 ctx->extension_cb = cb;
340 ctx->extension_cb_data = data;
341 }
342
343int TS_RESP_CTX_set_status_info(TS_RESP_CTX *ctx,
344 int status, const char *text)
345 {
346 TS_STATUS_INFO *si = NULL;
347 ASN1_UTF8STRING *utf8_text = NULL;
348 int ret = 0;
349
350 if (!(si = TS_STATUS_INFO_new())) goto err;
351 if (!ASN1_INTEGER_set(si->status, status)) goto err;
352 if (text)
353 {
354 if (!(utf8_text = ASN1_UTF8STRING_new())
355 || !ASN1_STRING_set(utf8_text, text, strlen(text)))
356 goto err;
357 if (!si->text && !(si->text = sk_ASN1_UTF8STRING_new_null()))
358 goto err;
359 if (!sk_ASN1_UTF8STRING_push(si->text, utf8_text)) goto err;
360 utf8_text = NULL; /* Ownership is lost. */
361 }
362 if (!TS_RESP_set_status_info(ctx->response, si)) goto err;
363 ret = 1;
364 err:
365 if (!ret)
366 TSerr(TS_F_TS_RESP_CTX_SET_STATUS_INFO, ERR_R_MALLOC_FAILURE);
367 TS_STATUS_INFO_free(si);
368 ASN1_UTF8STRING_free(utf8_text);
369 return ret;
370 }
371
372int TS_RESP_CTX_set_status_info_cond(TS_RESP_CTX *ctx,
373 int status, const char *text)
374 {
375 int ret = 1;
376 TS_STATUS_INFO *si = TS_RESP_get_status_info(ctx->response);
377
378 if (ASN1_INTEGER_get(si->status) == TS_STATUS_GRANTED)
379 {
380 /* Status has not been set, set it now. */
381 ret = TS_RESP_CTX_set_status_info(ctx, status, text);
382 }
383 return ret;
384 }
385
386int TS_RESP_CTX_add_failure_info(TS_RESP_CTX *ctx, int failure)
387 {
388 TS_STATUS_INFO *si = TS_RESP_get_status_info(ctx->response);
389 if (!si->failure_info && !(si->failure_info = ASN1_BIT_STRING_new()))
390 goto err;
391 if (!ASN1_BIT_STRING_set_bit(si->failure_info, failure, 1))
392 goto err;
393 return 1;
394 err:
395 TSerr(TS_F_TS_RESP_CTX_ADD_FAILURE_INFO, ERR_R_MALLOC_FAILURE);
396 return 0;
397 }
398
399TS_REQ *TS_RESP_CTX_get_request(TS_RESP_CTX *ctx)
400 {
401 return ctx->request;
402 }
403
404TS_TST_INFO *TS_RESP_CTX_get_tst_info(TS_RESP_CTX *ctx)
405 {
406 return ctx->tst_info;
407 }
408
409int TS_RESP_CTX_set_clock_precision_digits(TS_RESP_CTX *ctx, unsigned precision)
410 {
411 if (precision > TS_MAX_CLOCK_PRECISION_DIGITS)
412 return 0;
413 ctx->clock_precision_digits = precision;
414 return 1;
415 }
416
417/* Main entry method of the response generation. */
418TS_RESP *TS_RESP_create_response(TS_RESP_CTX *ctx, BIO *req_bio)
419 {
420 ASN1_OBJECT *policy;
421 TS_RESP *response;
422 int result = 0;
423
424 TS_RESP_CTX_init(ctx);
425
426 /* Creating the response object. */
427 if (!(ctx->response = TS_RESP_new()))
428 {
429 TSerr(TS_F_TS_RESP_CREATE_RESPONSE, ERR_R_MALLOC_FAILURE);
430 goto end;
431 }
432
433 /* Parsing DER request. */
434 if (!(ctx->request = d2i_TS_REQ_bio(req_bio, NULL)))
435 {
436 TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION,
437 "Bad request format or "
438 "system error.");
439 TS_RESP_CTX_add_failure_info(ctx, TS_INFO_BAD_DATA_FORMAT);
440 goto end;
441 }
442
443 /* Setting default status info. */
444 if (!TS_RESP_CTX_set_status_info(ctx, TS_STATUS_GRANTED, NULL))
445 goto end;
446
447 /* Checking the request format. */
448 if (!TS_RESP_check_request(ctx)) goto end;
449
450 /* Checking acceptable policies. */
451 if (!(policy = TS_RESP_get_policy(ctx))) goto end;
452
453 /* Creating the TS_TST_INFO object. */
454 if (!(ctx->tst_info = TS_RESP_create_tst_info(ctx, policy)))
455 goto end;
456
457 /* Processing extensions. */
458 if (!TS_RESP_process_extensions(ctx)) goto end;
459
460 /* Generating the signature. */
461 if (!TS_RESP_sign(ctx)) goto end;
462
463 /* Everything was successful. */
464 result = 1;
465 end:
466 if (!result)
467 {
468 TSerr(TS_F_TS_RESP_CREATE_RESPONSE, TS_R_RESPONSE_SETUP_ERROR);
469 if (ctx->response != NULL)
470 {
471 if (TS_RESP_CTX_set_status_info_cond(ctx,
472 TS_STATUS_REJECTION, "Error during response "
473 "generation.") == 0)
474 {
475 TS_RESP_free(ctx->response);
476 ctx->response = NULL;
477 }
478 }
479 }
480 response = ctx->response;
481 ctx->response = NULL; /* Ownership will be returned to caller. */
482 TS_RESP_CTX_cleanup(ctx);
483 return response;
484 }
485
486/* Initializes the variable part of the context. */
487static void TS_RESP_CTX_init(TS_RESP_CTX *ctx)
488 {
489 ctx->request = NULL;
490 ctx->response = NULL;
491 ctx->tst_info = NULL;
492 }
493
494/* Cleans up the variable part of the context. */
495static void TS_RESP_CTX_cleanup(TS_RESP_CTX *ctx)
496 {
497 TS_REQ_free(ctx->request);
498 ctx->request = NULL;
499 TS_RESP_free(ctx->response);
500 ctx->response = NULL;
501 TS_TST_INFO_free(ctx->tst_info);
502 ctx->tst_info = NULL;
503 }
504
505/* Checks the format and content of the request. */
506static int TS_RESP_check_request(TS_RESP_CTX *ctx)
507 {
508 TS_REQ *request = ctx->request;
509 TS_MSG_IMPRINT *msg_imprint;
510 X509_ALGOR *md_alg;
511 int md_alg_id;
512 const ASN1_OCTET_STRING *digest;
513 EVP_MD *md = NULL;
514 int i;
515
516 /* Checking request version. */
517 if (TS_REQ_get_version(request) != 1)
518 {
519 TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION,
520 "Bad request version.");
521 TS_RESP_CTX_add_failure_info(ctx, TS_INFO_BAD_REQUEST);
522 return 0;
523 }
524
525 /* Checking message digest algorithm. */
526 msg_imprint = TS_REQ_get_msg_imprint(request);
527 md_alg = TS_MSG_IMPRINT_get_algo(msg_imprint);
528 md_alg_id = OBJ_obj2nid(md_alg->algorithm);
529 for (i = 0; !md && i < sk_EVP_MD_num(ctx->mds); ++i)
530 {
531 EVP_MD *current_md = sk_EVP_MD_value(ctx->mds, i);
532 if (md_alg_id == EVP_MD_type(current_md))
533 md = current_md;
534 }
535 if (!md)
536 {
537 TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION,
538 "Message digest algorithm is "
539 "not supported.");
540 TS_RESP_CTX_add_failure_info(ctx, TS_INFO_BAD_ALG);
541 return 0;
542 }
543
544 /* No message digest takes parameter. */
545 if (md_alg->parameter
546 && ASN1_TYPE_get(md_alg->parameter) != V_ASN1_NULL)
547 {
548 TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION,
549 "Superfluous message digest "
550 "parameter.");
551 TS_RESP_CTX_add_failure_info(ctx, TS_INFO_BAD_ALG);
552 return 0;
553 }
554 /* Checking message digest size. */
555 digest = TS_MSG_IMPRINT_get_msg(msg_imprint);
556 if (digest->length != EVP_MD_size(md))
557 {
558 TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION,
559 "Bad message digest.");
560 TS_RESP_CTX_add_failure_info(ctx, TS_INFO_BAD_DATA_FORMAT);
561 return 0;
562 }
563
564 return 1;
565 }
566
567/* Returns the TSA policy based on the requested and acceptable policies. */
568static ASN1_OBJECT *TS_RESP_get_policy(TS_RESP_CTX *ctx)
569 {
570 ASN1_OBJECT *requested = TS_REQ_get_policy_id(ctx->request);
571 ASN1_OBJECT *policy = NULL;
572 int i;
573
574 if (ctx->default_policy == NULL)
575 {
576 TSerr(TS_F_TS_RESP_GET_POLICY, TS_R_INVALID_NULL_POINTER);
577 return NULL;
578 }
579 /* Return the default policy if none is requested or the default is
580 requested. */
581 if (!requested || !OBJ_cmp(requested, ctx->default_policy))
582 policy = ctx->default_policy;
583
584 /* Check if the policy is acceptable. */
585 for (i = 0; !policy && i < sk_ASN1_OBJECT_num(ctx->policies); ++i)
586 {
587 ASN1_OBJECT *current = sk_ASN1_OBJECT_value(ctx->policies, i);
588 if (!OBJ_cmp(requested, current))
589 policy = current;
590 }
591 if (!policy)
592 {
593 TSerr(TS_F_TS_RESP_GET_POLICY, TS_R_UNACCEPTABLE_POLICY);
594 TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION,
595 "Requested policy is not "
596 "supported.");
597 TS_RESP_CTX_add_failure_info(ctx, TS_INFO_UNACCEPTED_POLICY);
598 }
599 return policy;
600 }
601
602/* Creates the TS_TST_INFO object based on the settings of the context. */
603static TS_TST_INFO *TS_RESP_create_tst_info(TS_RESP_CTX *ctx,
604 ASN1_OBJECT *policy)
605 {
606 int result = 0;
607 TS_TST_INFO *tst_info = NULL;
608 ASN1_INTEGER *serial = NULL;
609 ASN1_GENERALIZEDTIME *asn1_time = NULL;
610 long sec, usec;
611 TS_ACCURACY *accuracy = NULL;
612 const ASN1_INTEGER *nonce;
613 GENERAL_NAME *tsa_name = NULL;
614
615 if (!(tst_info = TS_TST_INFO_new())) goto end;
616 if (!TS_TST_INFO_set_version(tst_info, 1)) goto end;
617 if (!TS_TST_INFO_set_policy_id(tst_info, policy)) goto end;
618 if (!TS_TST_INFO_set_msg_imprint(tst_info, ctx->request->msg_imprint))
619 goto end;
620 if (!(serial = (*ctx->serial_cb)(ctx, ctx->serial_cb_data))
621 || !TS_TST_INFO_set_serial(tst_info, serial))
622 goto end;
623 if (!(*ctx->time_cb)(ctx, ctx->time_cb_data, &sec, &usec)
624 || !(asn1_time = TS_RESP_set_genTime_with_precision(NULL,
625 sec, usec,
626 ctx->clock_precision_digits))
627 || !TS_TST_INFO_set_time(tst_info, asn1_time))
628 goto end;
629
630 /* Setting accuracy if needed. */
631 if ((ctx->seconds || ctx->millis || ctx->micros)
632 && !(accuracy = TS_ACCURACY_new()))
633 goto end;
634
635 if (ctx->seconds && !TS_ACCURACY_set_seconds(accuracy, ctx->seconds))
636 goto end;
637 if (ctx->millis && !TS_ACCURACY_set_millis(accuracy, ctx->millis))
638 goto end;
639 if (ctx->micros && !TS_ACCURACY_set_micros(accuracy, ctx->micros))
640 goto end;
641 if (accuracy && !TS_TST_INFO_set_accuracy(tst_info, accuracy))
642 goto end;
643
644 /* Setting ordering. */
645 if ((ctx->flags & TS_ORDERING)
646 && !TS_TST_INFO_set_ordering(tst_info, 1))
647 goto end;
648
649 /* Setting nonce if needed. */
650 if ((nonce = TS_REQ_get_nonce(ctx->request)) != NULL
651 && !TS_TST_INFO_set_nonce(tst_info, nonce))
652 goto end;
653
654 /* Setting TSA name to subject of signer certificate. */
655 if (ctx->flags & TS_TSA_NAME)
656 {
657 if (!(tsa_name = GENERAL_NAME_new())) goto end;
658 tsa_name->type = GEN_DIRNAME;
659 tsa_name->d.dirn =
660 X509_NAME_dup(ctx->signer_cert->cert_info->subject);
661 if (!tsa_name->d.dirn) goto end;
662 if (!TS_TST_INFO_set_tsa(tst_info, tsa_name)) goto end;
663 }
664
665 result = 1;
666 end:
667 if (!result)
668 {
669 TS_TST_INFO_free(tst_info);
670 tst_info = NULL;
671 TSerr(TS_F_TS_RESP_CREATE_TST_INFO, TS_R_TST_INFO_SETUP_ERROR);
672 TS_RESP_CTX_set_status_info_cond(ctx, TS_STATUS_REJECTION,
673 "Error during TSTInfo "
674 "generation.");
675 }
676 GENERAL_NAME_free(tsa_name);
677 TS_ACCURACY_free(accuracy);
678 ASN1_GENERALIZEDTIME_free(asn1_time);
679 ASN1_INTEGER_free(serial);
680
681 return tst_info;
682 }
683
684/* Processing the extensions of the request. */
685static int TS_RESP_process_extensions(TS_RESP_CTX *ctx)
686 {
687 STACK_OF(X509_EXTENSION) *exts = TS_REQ_get_exts(ctx->request);
688 int i;
689 int ok = 1;
690
691 for (i = 0; ok && i < sk_X509_EXTENSION_num(exts); ++i)
692 {
693 X509_EXTENSION *ext = sk_X509_EXTENSION_value(exts, i);
694 /* XXXXX The last argument was previously
695 (void *)ctx->extension_cb, but ISO C doesn't permit
696 converting a function pointer to void *. For lack of
697 better information, I'm placing a NULL there instead.
698 The callback can pick its own address out from the ctx
699 anyway...
700 */
701 ok = (*ctx->extension_cb)(ctx, ext, NULL);
702 }
703
704 return ok;
705 }
706
707/* Functions for signing the TS_TST_INFO structure of the context. */
708static int TS_RESP_sign(TS_RESP_CTX *ctx)
709 {
710 int ret = 0;
711 PKCS7 *p7 = NULL;
712 PKCS7_SIGNER_INFO *si;
713 STACK_OF(X509) *certs; /* Certificates to include in sc. */
714 ESS_SIGNING_CERT *sc = NULL;
715 ASN1_OBJECT *oid;
716 BIO *p7bio = NULL;
717 int i;
718
719 /* Check if signcert and pkey match. */
720 if (!X509_check_private_key(ctx->signer_cert, ctx->signer_key)) {
721 TSerr(TS_F_TS_RESP_SIGN,
722 TS_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE);
723 goto err;
724 }
725
726 /* Create a new PKCS7 signed object. */
727 if (!(p7 = PKCS7_new())) {
728 TSerr(TS_F_TS_RESP_SIGN, ERR_R_MALLOC_FAILURE);
729 goto err;
730 }
731 if (!PKCS7_set_type(p7, NID_pkcs7_signed)) goto err;
732
733 /* Force SignedData version to be 3 instead of the default 1. */
734 if (!ASN1_INTEGER_set(p7->d.sign->version, 3)) goto err;
735
736 /* Add signer certificate and optional certificate chain. */
737 if (TS_REQ_get_cert_req(ctx->request))
738 {
739 PKCS7_add_certificate(p7, ctx->signer_cert);
740 if (ctx->certs)
741 {
742 for(i = 0; i < sk_X509_num(ctx->certs); ++i)
743 {
744 X509 *cert = sk_X509_value(ctx->certs, i);
745 PKCS7_add_certificate(p7, cert);
746 }
747 }
748 }
749
750 /* Add a new signer info. */
751 if (!(si = PKCS7_add_signature(p7, ctx->signer_cert,
752 ctx->signer_key, EVP_sha1())))
753 {
754 TSerr(TS_F_TS_RESP_SIGN, TS_R_PKCS7_ADD_SIGNATURE_ERROR);
755 goto err;
756 }
757
758 /* Add content type signed attribute to the signer info. */
759 oid = OBJ_nid2obj(NID_id_smime_ct_TSTInfo);
760 if (!PKCS7_add_signed_attribute(si, NID_pkcs9_contentType,
761 V_ASN1_OBJECT, oid))
762 {
763 TSerr(TS_F_TS_RESP_SIGN, TS_R_PKCS7_ADD_SIGNED_ATTR_ERROR);
764 goto err;
765 }
766
767 /* Create the ESS SigningCertificate attribute which contains
768 the signer certificate id and optionally the certificate chain. */
769 certs = ctx->flags & TS_ESS_CERT_ID_CHAIN ? ctx->certs : NULL;
770 if (!(sc = ESS_SIGNING_CERT_new_init(ctx->signer_cert, certs)))
771 goto err;
772
773 /* Add SigningCertificate signed attribute to the signer info. */
774 if (!ESS_add_signing_cert(si, sc))
775 {
776 TSerr(TS_F_TS_RESP_SIGN, TS_R_ESS_ADD_SIGNING_CERT_ERROR);
777 goto err;
778 }
779
780 /* Add a new empty NID_id_smime_ct_TSTInfo encapsulated content. */
781 if (!TS_TST_INFO_content_new(p7)) goto err;
782
783 /* Add the DER encoded tst_info to the PKCS7 structure. */
784 if (!(p7bio = PKCS7_dataInit(p7, NULL))) {
785 TSerr(TS_F_TS_RESP_SIGN, ERR_R_MALLOC_FAILURE);
786 goto err;
787 }
788
789 /* Convert tst_info to DER. */
790 if (!i2d_TS_TST_INFO_bio(p7bio, ctx->tst_info))
791 {
792 TSerr(TS_F_TS_RESP_SIGN, TS_R_TS_DATASIGN);
793 goto err;
794 }
795
796 /* Create the signature and add it to the signer info. */
797 if (!PKCS7_dataFinal(p7, p7bio))
798 {
799 TSerr(TS_F_TS_RESP_SIGN, TS_R_TS_DATASIGN);
800 goto err;
801 }
802
803 /* Set new PKCS7 and TST_INFO objects. */
804 TS_RESP_set_tst_info(ctx->response, p7, ctx->tst_info);
805 p7 = NULL; /* Ownership is lost. */
806 ctx->tst_info = NULL; /* Ownership is lost. */
807
808 ret = 1;
809 err:
810 if (!ret)
811 TS_RESP_CTX_set_status_info_cond(ctx, TS_STATUS_REJECTION,
812 "Error during signature "
813 "generation.");
814 BIO_free_all(p7bio);
815 ESS_SIGNING_CERT_free(sc);
816 PKCS7_free(p7);
817 return ret;
818 }
819
820static ESS_SIGNING_CERT *ESS_SIGNING_CERT_new_init(X509 *signcert,
821 STACK_OF(X509) *certs)
822 {
823 ESS_CERT_ID *cid;
824 ESS_SIGNING_CERT *sc = NULL;
825 int i;
826
827 /* Creating the ESS_CERT_ID stack. */
828 if (!(sc = ESS_SIGNING_CERT_new())) goto err;
829 if (!sc->cert_ids && !(sc->cert_ids = sk_ESS_CERT_ID_new_null()))
830 goto err;
831
832 /* Adding the signing certificate id. */
833 if (!(cid = ESS_CERT_ID_new_init(signcert, 0))
834 || !sk_ESS_CERT_ID_push(sc->cert_ids, cid))
835 goto err;
836 /* Adding the certificate chain ids. */
837 for (i = 0; i < sk_X509_num(certs); ++i)
838 {
839 X509 *cert = sk_X509_value(certs, i);
840 if (!(cid = ESS_CERT_ID_new_init(cert, 1))
841 || !sk_ESS_CERT_ID_push(sc->cert_ids, cid))
842 goto err;
843 }
844
845 return sc;
846err:
847 ESS_SIGNING_CERT_free(sc);
848 TSerr(TS_F_ESS_SIGNING_CERT_NEW_INIT, ERR_R_MALLOC_FAILURE);
849 return NULL;
850 }
851
852static ESS_CERT_ID *ESS_CERT_ID_new_init(X509 *cert, int issuer_needed)
853 {
854 ESS_CERT_ID *cid = NULL;
855 GENERAL_NAME *name = NULL;
856
857 /* Recompute SHA1 hash of certificate if necessary (side effect). */
858 X509_check_purpose(cert, -1, 0);
859
860 if (!(cid = ESS_CERT_ID_new())) goto err;
861 if (!ASN1_OCTET_STRING_set(cid->hash, cert->sha1_hash,
862 sizeof(cert->sha1_hash)))
863 goto err;
864
865 /* Setting the issuer/serial if requested. */
866 if (issuer_needed)
867 {
868 /* Creating issuer/serial structure. */
869 if (!cid->issuer_serial
870 && !(cid->issuer_serial = ESS_ISSUER_SERIAL_new()))
871 goto err;
872 /* Creating general name from the certificate issuer. */
873 if (!(name = GENERAL_NAME_new())) goto err;
874 name->type = GEN_DIRNAME;
875 if (!(name->d.dirn = X509_NAME_dup(cert->cert_info->issuer)))
876 goto err;
877 if (!sk_GENERAL_NAME_push(cid->issuer_serial->issuer, name))
878 goto err;
879 name = NULL; /* Ownership is lost. */
880 /* Setting the serial number. */
881 ASN1_INTEGER_free(cid->issuer_serial->serial);
882 if (!(cid->issuer_serial->serial =
883 ASN1_INTEGER_dup(cert->cert_info->serialNumber)))
884 goto err;
885 }
886
887 return cid;
888err:
889 GENERAL_NAME_free(name);
890 ESS_CERT_ID_free(cid);
891 TSerr(TS_F_ESS_CERT_ID_NEW_INIT, ERR_R_MALLOC_FAILURE);
892 return NULL;
893 }
894
895static int TS_TST_INFO_content_new(PKCS7 *p7)
896 {
897 PKCS7 *ret = NULL;
898 ASN1_OCTET_STRING *octet_string = NULL;
899
900 /* Create new encapsulated NID_id_smime_ct_TSTInfo content. */
901 if (!(ret = PKCS7_new())) goto err;
902 if (!(ret->d.other = ASN1_TYPE_new())) goto err;
903 ret->type = OBJ_nid2obj(NID_id_smime_ct_TSTInfo);
904 if (!(octet_string = ASN1_OCTET_STRING_new())) goto err;
905 ASN1_TYPE_set(ret->d.other, V_ASN1_OCTET_STRING, octet_string);
906 octet_string = NULL;
907
908 /* Add encapsulated content to signed PKCS7 structure. */
909 if (!PKCS7_set_content(p7, ret)) goto err;
910
911 return 1;
912 err:
913 ASN1_OCTET_STRING_free(octet_string);
914 PKCS7_free(ret);
915 return 0;
916 }
917
918static int ESS_add_signing_cert(PKCS7_SIGNER_INFO *si, ESS_SIGNING_CERT *sc)
919 {
920 ASN1_STRING *seq = NULL;
921 unsigned char *p, *pp = NULL;
922 int len;
923
924 len = i2d_ESS_SIGNING_CERT(sc, NULL);
925 if (!(pp = (unsigned char *) OPENSSL_malloc(len)))
926 {
927 TSerr(TS_F_ESS_ADD_SIGNING_CERT, ERR_R_MALLOC_FAILURE);
928 goto err;
929 }
930 p = pp;
931 i2d_ESS_SIGNING_CERT(sc, &p);
932 if (!(seq = ASN1_STRING_new()) || !ASN1_STRING_set(seq, pp, len))
933 {
934 TSerr(TS_F_ESS_ADD_SIGNING_CERT, ERR_R_MALLOC_FAILURE);
935 goto err;
936 }
937 OPENSSL_free(pp); pp = NULL;
938 return PKCS7_add_signed_attribute(si,
939 NID_id_smime_aa_signingCertificate,
940 V_ASN1_SEQUENCE, seq);
941 err:
942 ASN1_STRING_free(seq);
943 OPENSSL_free(pp);
944
945 return 0;
946 }
947
948
949static ASN1_GENERALIZEDTIME *
950TS_RESP_set_genTime_with_precision(ASN1_GENERALIZEDTIME *asn1_time,
951 long sec, long usec, unsigned precision)
952 {
953 time_t time_sec = (time_t) sec;
954 struct tm *tm = NULL;
955 char genTime_str[17 + TS_MAX_CLOCK_PRECISION_DIGITS];
956 char *p = genTime_str;
957 char *p_end = genTime_str + sizeof(genTime_str);
958
959 if (precision > TS_MAX_CLOCK_PRECISION_DIGITS)
960 goto err;
961
962
963 if (!(tm = gmtime(&time_sec)))
964 goto err;
965
966 /*
967 * Put "genTime_str" in GeneralizedTime format. We work around the
968 * restrictions imposed by rfc3280 (i.e. "GeneralizedTime values MUST
969 * NOT include fractional seconds") and OpenSSL related functions to
970 * meet the rfc3161 requirement: "GeneralizedTime syntax can include
971 * fraction-of-second details".
972 */
973 p += BIO_snprintf(p, p_end - p,
974 "%04d%02d%02d%02d%02d%02d",
975 tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
976 tm->tm_hour, tm->tm_min, tm->tm_sec);
977 if (precision > 0)
978 {
979 /* Add fraction of seconds (leave space for dot and null). */
980 BIO_snprintf(p, 2 + precision, ".%ld", usec);
981 /* We cannot use the snprintf return value,
982 because it might have been truncated. */
983 p += strlen(p);
984
985 /* To make things a bit harder, X.690 | ISO/IEC 8825-1 provides
986 the following restrictions for a DER-encoding, which OpenSSL
987 (specifically ASN1_GENERALIZEDTIME_check() function) doesn't
988 support:
989 "The encoding MUST terminate with a "Z" (which means "Zulu"
990 time). The decimal point element, if present, MUST be the
991 point option ".". The fractional-seconds elements,
992 if present, MUST omit all trailing 0's;
993 if the elements correspond to 0, they MUST be wholly
994 omitted, and the decimal point element also MUST be
995 omitted." */
996 /* Remove trailing zeros. The dot guarantees the exit
997 condition of this loop even if all the digits are zero. */
998 while (*--p == '0')
999 /* empty */;
1000 /* p points to either the dot or the last non-zero digit. */
1001 if (*p != '.') ++p;
1002 }
1003 /* Add the trailing Z and the terminating null. */
1004 *p++ = 'Z';
1005 *p++ = '\0';
1006
1007 /* Now call OpenSSL to check and set our genTime value */
1008 if (!asn1_time && !(asn1_time = M_ASN1_GENERALIZEDTIME_new()))
1009 goto err;
1010 if (!ASN1_GENERALIZEDTIME_set_string(asn1_time, genTime_str))
1011 {
1012 ASN1_GENERALIZEDTIME_free(asn1_time);
1013 goto err;
1014 }
1015
1016 return asn1_time;
1017 err:
1018 TSerr(TS_F_TS_RESP_SET_GENTIME_WITH_PRECISION, TS_R_COULD_NOT_SET_TIME);
1019 return NULL;
1020 }
diff --git a/src/lib/libcrypto/ts/ts_rsp_utils.c b/src/lib/libcrypto/ts/ts_rsp_utils.c
new file mode 100644
index 0000000000..401c1fdc51
--- /dev/null
+++ b/src/lib/libcrypto/ts/ts_rsp_utils.c
@@ -0,0 +1,409 @@
1/* crypto/ts/ts_resp_utils.c */
2/* Written by Zoltan Glozik (zglozik@stones.com) for the OpenSSL
3 * project 2002.
4 */
5/* ====================================================================
6 * Copyright (c) 2006 The OpenSSL Project. All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 *
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 *
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in
17 * the documentation and/or other materials provided with the
18 * distribution.
19 *
20 * 3. All advertising materials mentioning features or use of this
21 * software must display the following acknowledgment:
22 * "This product includes software developed by the OpenSSL Project
23 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
24 *
25 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
26 * endorse or promote products derived from this software without
27 * prior written permission. For written permission, please contact
28 * licensing@OpenSSL.org.
29 *
30 * 5. Products derived from this software may not be called "OpenSSL"
31 * nor may "OpenSSL" appear in their names without prior written
32 * permission of the OpenSSL Project.
33 *
34 * 6. Redistributions of any form whatsoever must retain the following
35 * acknowledgment:
36 * "This product includes software developed by the OpenSSL Project
37 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
38 *
39 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
40 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
43 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
50 * OF THE POSSIBILITY OF SUCH DAMAGE.
51 * ====================================================================
52 *
53 * This product includes cryptographic software written by Eric Young
54 * (eay@cryptsoft.com). This product includes software written by Tim
55 * Hudson (tjh@cryptsoft.com).
56 *
57 */
58
59#include <stdio.h>
60#include "cryptlib.h"
61#include <openssl/objects.h>
62#include <openssl/ts.h>
63#include <openssl/pkcs7.h>
64
65/* Function definitions. */
66
67int TS_RESP_set_status_info(TS_RESP *a, TS_STATUS_INFO *status_info)
68 {
69 TS_STATUS_INFO *new_status_info;
70
71 if (a->status_info == status_info)
72 return 1;
73 new_status_info = TS_STATUS_INFO_dup(status_info);
74 if (new_status_info == NULL)
75 {
76 TSerr(TS_F_TS_RESP_SET_STATUS_INFO, ERR_R_MALLOC_FAILURE);
77 return 0;
78 }
79 TS_STATUS_INFO_free(a->status_info);
80 a->status_info = new_status_info;
81
82 return 1;
83 }
84
85TS_STATUS_INFO *TS_RESP_get_status_info(TS_RESP *a)
86 {
87 return a->status_info;
88 }
89
90/* Caller loses ownership of PKCS7 and TS_TST_INFO objects. */
91void TS_RESP_set_tst_info(TS_RESP *a, PKCS7 *p7, TS_TST_INFO *tst_info)
92 {
93 /* Set new PKCS7 and TST_INFO objects. */
94 PKCS7_free(a->token);
95 a->token = p7;
96 TS_TST_INFO_free(a->tst_info);
97 a->tst_info = tst_info;
98 }
99
100PKCS7 *TS_RESP_get_token(TS_RESP *a)
101 {
102 return a->token;
103 }
104
105TS_TST_INFO *TS_RESP_get_tst_info(TS_RESP *a)
106 {
107 return a->tst_info;
108 }
109
110int TS_TST_INFO_set_version(TS_TST_INFO *a, long version)
111 {
112 return ASN1_INTEGER_set(a->version, version);
113 }
114
115long TS_TST_INFO_get_version(const TS_TST_INFO *a)
116 {
117 return ASN1_INTEGER_get(a->version);
118 }
119
120int TS_TST_INFO_set_policy_id(TS_TST_INFO *a, ASN1_OBJECT *policy)
121 {
122 ASN1_OBJECT *new_policy;
123
124 if (a->policy_id == policy)
125 return 1;
126 new_policy = OBJ_dup(policy);
127 if (new_policy == NULL)
128 {
129 TSerr(TS_F_TS_TST_INFO_SET_POLICY_ID, ERR_R_MALLOC_FAILURE);
130 return 0;
131 }
132 ASN1_OBJECT_free(a->policy_id);
133 a->policy_id = new_policy;
134 return 1;
135 }
136
137ASN1_OBJECT *TS_TST_INFO_get_policy_id(TS_TST_INFO *a)
138 {
139 return a->policy_id;
140 }
141
142int TS_TST_INFO_set_msg_imprint(TS_TST_INFO *a, TS_MSG_IMPRINT *msg_imprint)
143 {
144 TS_MSG_IMPRINT *new_msg_imprint;
145
146 if (a->msg_imprint == msg_imprint)
147 return 1;
148 new_msg_imprint = TS_MSG_IMPRINT_dup(msg_imprint);
149 if (new_msg_imprint == NULL)
150 {
151 TSerr(TS_F_TS_TST_INFO_SET_MSG_IMPRINT, ERR_R_MALLOC_FAILURE);
152 return 0;
153 }
154 TS_MSG_IMPRINT_free(a->msg_imprint);
155 a->msg_imprint = new_msg_imprint;
156 return 1;
157 }
158
159TS_MSG_IMPRINT *TS_TST_INFO_get_msg_imprint(TS_TST_INFO *a)
160 {
161 return a->msg_imprint;
162 }
163
164int TS_TST_INFO_set_serial(TS_TST_INFO *a, const ASN1_INTEGER *serial)
165 {
166 ASN1_INTEGER *new_serial;
167
168 if (a->serial == serial)
169 return 1;
170 new_serial = ASN1_INTEGER_dup(serial);
171 if (new_serial == NULL)
172 {
173 TSerr(TS_F_TS_TST_INFO_SET_SERIAL, ERR_R_MALLOC_FAILURE);
174 return 0;
175 }
176 ASN1_INTEGER_free(a->serial);
177 a->serial = new_serial;
178 return 1;
179 }
180
181const ASN1_INTEGER *TS_TST_INFO_get_serial(const TS_TST_INFO *a)
182 {
183 return a->serial;
184 }
185
186int TS_TST_INFO_set_time(TS_TST_INFO *a, const ASN1_GENERALIZEDTIME *gtime)
187 {
188 ASN1_GENERALIZEDTIME *new_time;
189
190 if (a->time == gtime)
191 return 1;
192 new_time = M_ASN1_GENERALIZEDTIME_dup(gtime);
193 if (new_time == NULL)
194 {
195 TSerr(TS_F_TS_TST_INFO_SET_TIME, ERR_R_MALLOC_FAILURE);
196 return 0;
197 }
198 ASN1_GENERALIZEDTIME_free(a->time);
199 a->time = new_time;
200 return 1;
201 }
202
203const ASN1_GENERALIZEDTIME *TS_TST_INFO_get_time(const TS_TST_INFO *a)
204 {
205 return a->time;
206 }
207
208int TS_TST_INFO_set_accuracy(TS_TST_INFO *a, TS_ACCURACY *accuracy)
209 {
210 TS_ACCURACY *new_accuracy;
211
212 if (a->accuracy == accuracy)
213 return 1;
214 new_accuracy = TS_ACCURACY_dup(accuracy);
215 if (new_accuracy == NULL)
216 {
217 TSerr(TS_F_TS_TST_INFO_SET_ACCURACY, ERR_R_MALLOC_FAILURE);
218 return 0;
219 }
220 TS_ACCURACY_free(a->accuracy);
221 a->accuracy = new_accuracy;
222 return 1;
223 }
224
225TS_ACCURACY *TS_TST_INFO_get_accuracy(TS_TST_INFO *a)
226 {
227 return a->accuracy;
228 }
229
230int TS_ACCURACY_set_seconds(TS_ACCURACY *a, const ASN1_INTEGER *seconds)
231 {
232 ASN1_INTEGER *new_seconds;
233
234 if (a->seconds == seconds)
235 return 1;
236 new_seconds = ASN1_INTEGER_dup(seconds);
237 if (new_seconds == NULL)
238 {
239 TSerr(TS_F_TS_ACCURACY_SET_SECONDS, ERR_R_MALLOC_FAILURE);
240 return 0;
241 }
242 ASN1_INTEGER_free(a->seconds);
243 a->seconds = new_seconds;
244 return 1;
245 }
246
247const ASN1_INTEGER *TS_ACCURACY_get_seconds(const TS_ACCURACY *a)
248 {
249 return a->seconds;
250 }
251
252int TS_ACCURACY_set_millis(TS_ACCURACY *a, const ASN1_INTEGER *millis)
253 {
254 ASN1_INTEGER *new_millis = NULL;
255
256 if (a->millis == millis)
257 return 1;
258 if (millis != NULL)
259 {
260 new_millis = ASN1_INTEGER_dup(millis);
261 if (new_millis == NULL)
262 {
263 TSerr(TS_F_TS_ACCURACY_SET_MILLIS,
264 ERR_R_MALLOC_FAILURE);
265 return 0;
266 }
267 }
268 ASN1_INTEGER_free(a->millis);
269 a->millis = new_millis;
270 return 1;
271 }
272
273const ASN1_INTEGER *TS_ACCURACY_get_millis(const TS_ACCURACY *a)
274 {
275 return a->millis;
276 }
277
278int TS_ACCURACY_set_micros(TS_ACCURACY *a, const ASN1_INTEGER *micros)
279 {
280 ASN1_INTEGER *new_micros = NULL;
281
282 if (a->micros == micros)
283 return 1;
284 if (micros != NULL)
285 {
286 new_micros = ASN1_INTEGER_dup(micros);
287 if (new_micros == NULL)
288 {
289 TSerr(TS_F_TS_ACCURACY_SET_MICROS,
290 ERR_R_MALLOC_FAILURE);
291 return 0;
292 }
293 }
294 ASN1_INTEGER_free(a->micros);
295 a->micros = new_micros;
296 return 1;
297 }
298
299const ASN1_INTEGER *TS_ACCURACY_get_micros(const TS_ACCURACY *a)
300 {
301 return a->micros;
302 }
303
304int TS_TST_INFO_set_ordering(TS_TST_INFO *a, int ordering)
305 {
306 a->ordering = ordering ? 0xFF : 0x00;
307 return 1;
308 }
309
310int TS_TST_INFO_get_ordering(const TS_TST_INFO *a)
311 {
312 return a->ordering ? 1 : 0;
313 }
314
315int TS_TST_INFO_set_nonce(TS_TST_INFO *a, const ASN1_INTEGER *nonce)
316 {
317 ASN1_INTEGER *new_nonce;
318
319 if (a->nonce == nonce)
320 return 1;
321 new_nonce = ASN1_INTEGER_dup(nonce);
322 if (new_nonce == NULL)
323 {
324 TSerr(TS_F_TS_TST_INFO_SET_NONCE, ERR_R_MALLOC_FAILURE);
325 return 0;
326 }
327 ASN1_INTEGER_free(a->nonce);
328 a->nonce = new_nonce;
329 return 1;
330 }
331
332const ASN1_INTEGER *TS_TST_INFO_get_nonce(const TS_TST_INFO *a)
333 {
334 return a->nonce;
335 }
336
337int TS_TST_INFO_set_tsa(TS_TST_INFO *a, GENERAL_NAME *tsa)
338 {
339 GENERAL_NAME *new_tsa;
340
341 if (a->tsa == tsa)
342 return 1;
343 new_tsa = GENERAL_NAME_dup(tsa);
344 if (new_tsa == NULL)
345 {
346 TSerr(TS_F_TS_TST_INFO_SET_TSA, ERR_R_MALLOC_FAILURE);
347 return 0;
348 }
349 GENERAL_NAME_free(a->tsa);
350 a->tsa = new_tsa;
351 return 1;
352 }
353
354GENERAL_NAME *TS_TST_INFO_get_tsa(TS_TST_INFO *a)
355 {
356 return a->tsa;
357 }
358
359STACK_OF(X509_EXTENSION) *TS_TST_INFO_get_exts(TS_TST_INFO *a)
360 {
361 return a->extensions;
362 }
363
364void TS_TST_INFO_ext_free(TS_TST_INFO *a)
365 {
366 if (!a) return;
367 sk_X509_EXTENSION_pop_free(a->extensions, X509_EXTENSION_free);
368 a->extensions = NULL;
369 }
370
371int TS_TST_INFO_get_ext_count(TS_TST_INFO *a)
372 {
373 return X509v3_get_ext_count(a->extensions);
374 }
375
376int TS_TST_INFO_get_ext_by_NID(TS_TST_INFO *a, int nid, int lastpos)
377 {
378 return X509v3_get_ext_by_NID(a->extensions, nid, lastpos);
379 }
380
381int TS_TST_INFO_get_ext_by_OBJ(TS_TST_INFO *a, ASN1_OBJECT *obj, int lastpos)
382 {
383 return X509v3_get_ext_by_OBJ(a->extensions, obj, lastpos);
384 }
385
386int TS_TST_INFO_get_ext_by_critical(TS_TST_INFO *a, int crit, int lastpos)
387 {
388 return X509v3_get_ext_by_critical(a->extensions, crit, lastpos);
389 }
390
391X509_EXTENSION *TS_TST_INFO_get_ext(TS_TST_INFO *a, int loc)
392 {
393 return X509v3_get_ext(a->extensions,loc);
394 }
395
396X509_EXTENSION *TS_TST_INFO_delete_ext(TS_TST_INFO *a, int loc)
397 {
398 return X509v3_delete_ext(a->extensions,loc);
399 }
400
401int TS_TST_INFO_add_ext(TS_TST_INFO *a, X509_EXTENSION *ex, int loc)
402 {
403 return X509v3_add_ext(&a->extensions,ex,loc) != NULL;
404 }
405
406void *TS_TST_INFO_get_ext_d2i(TS_TST_INFO *a, int nid, int *crit, int *idx)
407 {
408 return X509V3_get_d2i(a->extensions, nid, crit, idx);
409 }
diff --git a/src/lib/libcrypto/ts/ts_rsp_verify.c b/src/lib/libcrypto/ts/ts_rsp_verify.c
new file mode 100644
index 0000000000..e1f3b534af
--- /dev/null
+++ b/src/lib/libcrypto/ts/ts_rsp_verify.c
@@ -0,0 +1,725 @@
1/* crypto/ts/ts_resp_verify.c */
2/* Written by Zoltan Glozik (zglozik@stones.com) for the OpenSSL
3 * project 2002.
4 */
5/* ====================================================================
6 * Copyright (c) 2006 The OpenSSL Project. All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 *
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 *
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in
17 * the documentation and/or other materials provided with the
18 * distribution.
19 *
20 * 3. All advertising materials mentioning features or use of this
21 * software must display the following acknowledgment:
22 * "This product includes software developed by the OpenSSL Project
23 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
24 *
25 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
26 * endorse or promote products derived from this software without
27 * prior written permission. For written permission, please contact
28 * licensing@OpenSSL.org.
29 *
30 * 5. Products derived from this software may not be called "OpenSSL"
31 * nor may "OpenSSL" appear in their names without prior written
32 * permission of the OpenSSL Project.
33 *
34 * 6. Redistributions of any form whatsoever must retain the following
35 * acknowledgment:
36 * "This product includes software developed by the OpenSSL Project
37 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
38 *
39 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
40 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
43 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
50 * OF THE POSSIBILITY OF SUCH DAMAGE.
51 * ====================================================================
52 *
53 * This product includes cryptographic software written by Eric Young
54 * (eay@cryptsoft.com). This product includes software written by Tim
55 * Hudson (tjh@cryptsoft.com).
56 *
57 */
58
59#include <stdio.h>
60#include "cryptlib.h"
61#include <openssl/objects.h>
62#include <openssl/ts.h>
63#include <openssl/pkcs7.h>
64
65/* Private function declarations. */
66
67static int TS_verify_cert(X509_STORE *store, STACK_OF(X509) *untrusted,
68 X509 *signer, STACK_OF(X509) **chain);
69static int TS_check_signing_certs(PKCS7_SIGNER_INFO *si, STACK_OF(X509) *chain);
70static ESS_SIGNING_CERT *ESS_get_signing_cert(PKCS7_SIGNER_INFO *si);
71static int TS_find_cert(STACK_OF(ESS_CERT_ID) *cert_ids, X509 *cert);
72static int TS_issuer_serial_cmp(ESS_ISSUER_SERIAL *is, X509_CINF *cinfo);
73static int int_TS_RESP_verify_token(TS_VERIFY_CTX *ctx,
74 PKCS7 *token, TS_TST_INFO *tst_info);
75static int TS_check_status_info(TS_RESP *response);
76static char *TS_get_status_text(STACK_OF(ASN1_UTF8STRING) *text);
77static int TS_check_policy(ASN1_OBJECT *req_oid, TS_TST_INFO *tst_info);
78static int TS_compute_imprint(BIO *data, TS_TST_INFO *tst_info,
79 X509_ALGOR **md_alg,
80 unsigned char **imprint, unsigned *imprint_len);
81static int TS_check_imprints(X509_ALGOR *algor_a,
82 unsigned char *imprint_a, unsigned len_a,
83 TS_TST_INFO *tst_info);
84static int TS_check_nonces(const ASN1_INTEGER *a, TS_TST_INFO *tst_info);
85static int TS_check_signer_name(GENERAL_NAME *tsa_name, X509 *signer);
86static int TS_find_name(STACK_OF(GENERAL_NAME) *gen_names, GENERAL_NAME *name);
87
88/*
89 * Local mapping between response codes and descriptions.
90 * Don't forget to change TS_STATUS_BUF_SIZE when modifying
91 * the elements of this array.
92 */
93static const char *TS_status_text[] =
94 { "granted",
95 "grantedWithMods",
96 "rejection",
97 "waiting",
98 "revocationWarning",
99 "revocationNotification" };
100
101#define TS_STATUS_TEXT_SIZE (sizeof(TS_status_text)/sizeof(*TS_status_text))
102
103/*
104 * This must be greater or equal to the sum of the strings in TS_status_text
105 * plus the number of its elements.
106 */
107#define TS_STATUS_BUF_SIZE 256
108
109static struct
110 {
111 int code;
112 const char *text;
113 } TS_failure_info[] =
114 { { TS_INFO_BAD_ALG, "badAlg" },
115 { TS_INFO_BAD_REQUEST, "badRequest" },
116 { TS_INFO_BAD_DATA_FORMAT, "badDataFormat" },
117 { TS_INFO_TIME_NOT_AVAILABLE, "timeNotAvailable" },
118 { TS_INFO_UNACCEPTED_POLICY, "unacceptedPolicy" },
119 { TS_INFO_UNACCEPTED_EXTENSION, "unacceptedExtension" },
120 { TS_INFO_ADD_INFO_NOT_AVAILABLE, "addInfoNotAvailable" },
121 { TS_INFO_SYSTEM_FAILURE, "systemFailure" } };
122
123#define TS_FAILURE_INFO_SIZE (sizeof(TS_failure_info) / \
124 sizeof(*TS_failure_info))
125
126/* Functions for verifying a signed TS_TST_INFO structure. */
127
128/*
129 * This function carries out the following tasks:
130 * - Checks if there is one and only one signer.
131 * - Search for the signing certificate in 'certs' and in the response.
132 * - Check the extended key usage and key usage fields of the signer
133 * certificate (done by the path validation).
134 * - Build and validate the certificate path.
135 * - Check if the certificate path meets the requirements of the
136 * SigningCertificate ESS signed attribute.
137 * - Verify the signature value.
138 * - Returns the signer certificate in 'signer', if 'signer' is not NULL.
139 */
140int TS_RESP_verify_signature(PKCS7 *token, STACK_OF(X509) *certs,
141 X509_STORE *store, X509 **signer_out)
142 {
143 STACK_OF(PKCS7_SIGNER_INFO) *sinfos = NULL;
144 PKCS7_SIGNER_INFO *si;
145 STACK_OF(X509) *signers = NULL;
146 X509 *signer;
147 STACK_OF(X509) *chain = NULL;
148 char buf[4096];
149 int i, j = 0, ret = 0;
150 BIO *p7bio = NULL;
151
152 /* Some sanity checks first. */
153 if (!token)
154 {
155 TSerr(TS_F_TS_RESP_VERIFY_SIGNATURE, TS_R_INVALID_NULL_POINTER);
156 goto err;
157 }
158
159 /* Check for the correct content type */
160 if(!PKCS7_type_is_signed(token))
161 {
162 TSerr(TS_F_TS_RESP_VERIFY_SIGNATURE, TS_R_WRONG_CONTENT_TYPE);
163 goto err;
164 }
165
166 /* Check if there is one and only one signer. */
167 sinfos = PKCS7_get_signer_info(token);
168 if (!sinfos || sk_PKCS7_SIGNER_INFO_num(sinfos) != 1)
169 {
170 TSerr(TS_F_TS_RESP_VERIFY_SIGNATURE,
171 TS_R_THERE_MUST_BE_ONE_SIGNER);
172 goto err;
173 }
174 si = sk_PKCS7_SIGNER_INFO_value(sinfos, 0);
175
176 /* Check for no content: no data to verify signature. */
177 if (PKCS7_get_detached(token))
178 {
179 TSerr(TS_F_TS_RESP_VERIFY_SIGNATURE, TS_R_NO_CONTENT);
180 goto err;
181 }
182
183 /* Get hold of the signer certificate, search only internal
184 certificates if it was requested. */
185 signers = PKCS7_get0_signers(token, certs, 0);
186 if (!signers || sk_X509_num(signers) != 1) goto err;
187 signer = sk_X509_value(signers, 0);
188
189 /* Now verify the certificate. */
190 if (!TS_verify_cert(store, certs, signer, &chain)) goto err;
191
192 /* Check if the signer certificate is consistent with the
193 ESS extension. */
194 if (!TS_check_signing_certs(si, chain)) goto err;
195
196 /* Creating the message digest. */
197 p7bio = PKCS7_dataInit(token, NULL);
198
199 /* We now have to 'read' from p7bio to calculate digests etc. */
200 while ((i = BIO_read(p7bio,buf,sizeof(buf))) > 0);
201
202 /* Verifying the signature. */
203 j = PKCS7_signatureVerify(p7bio, token, si, signer);
204 if (j <= 0)
205 {
206 TSerr(TS_F_TS_RESP_VERIFY_SIGNATURE, TS_R_SIGNATURE_FAILURE);
207 goto err;
208 }
209
210 /* Return the signer certificate if needed. */
211 if (signer_out)
212 {
213 *signer_out = signer;
214 CRYPTO_add(&signer->references, 1, CRYPTO_LOCK_X509);
215 }
216
217 ret = 1;
218
219 err:
220 BIO_free_all(p7bio);
221 sk_X509_pop_free(chain, X509_free);
222 sk_X509_free(signers);
223
224 return ret;
225 }
226
227/*
228 * The certificate chain is returned in chain. Caller is responsible for
229 * freeing the vector.
230 */
231static int TS_verify_cert(X509_STORE *store, STACK_OF(X509) *untrusted,
232 X509 *signer, STACK_OF(X509) **chain)
233 {
234 X509_STORE_CTX cert_ctx;
235 int i;
236 int ret = 1;
237
238 /* chain is an out argument. */
239 *chain = NULL;
240 X509_STORE_CTX_init(&cert_ctx, store, signer, untrusted);
241 X509_STORE_CTX_set_purpose(&cert_ctx, X509_PURPOSE_TIMESTAMP_SIGN);
242 i = X509_verify_cert(&cert_ctx);
243 if (i <= 0)
244 {
245 int j = X509_STORE_CTX_get_error(&cert_ctx);
246 TSerr(TS_F_TS_VERIFY_CERT, TS_R_CERTIFICATE_VERIFY_ERROR);
247 ERR_add_error_data(2, "Verify error:",
248 X509_verify_cert_error_string(j));
249 ret = 0;
250 }
251 else
252 {
253 /* Get a copy of the certificate chain. */
254 *chain = X509_STORE_CTX_get1_chain(&cert_ctx);
255 }
256
257 X509_STORE_CTX_cleanup(&cert_ctx);
258
259 return ret;
260 }
261
262static int TS_check_signing_certs(PKCS7_SIGNER_INFO *si, STACK_OF(X509) *chain)
263 {
264 ESS_SIGNING_CERT *ss = ESS_get_signing_cert(si);
265 STACK_OF(ESS_CERT_ID) *cert_ids = NULL;
266 X509 *cert;
267 int i = 0;
268 int ret = 0;
269
270 if (!ss) goto err;
271 cert_ids = ss->cert_ids;
272 /* The signer certificate must be the first in cert_ids. */
273 cert = sk_X509_value(chain, 0);
274 if (TS_find_cert(cert_ids, cert) != 0) goto err;
275
276 /* Check the other certificates of the chain if there are more
277 than one certificate ids in cert_ids. */
278 if (sk_ESS_CERT_ID_num(cert_ids) > 1)
279 {
280 /* All the certificates of the chain must be in cert_ids. */
281 for (i = 1; i < sk_X509_num(chain); ++i)
282 {
283 cert = sk_X509_value(chain, i);
284 if (TS_find_cert(cert_ids, cert) < 0) goto err;
285 }
286 }
287 ret = 1;
288 err:
289 if (!ret)
290 TSerr(TS_F_TS_CHECK_SIGNING_CERTS,
291 TS_R_ESS_SIGNING_CERTIFICATE_ERROR);
292 ESS_SIGNING_CERT_free(ss);
293 return ret;
294 }
295
296static ESS_SIGNING_CERT *ESS_get_signing_cert(PKCS7_SIGNER_INFO *si)
297 {
298 ASN1_TYPE *attr;
299 const unsigned char *p;
300 attr = PKCS7_get_signed_attribute(si,
301 NID_id_smime_aa_signingCertificate);
302 if (!attr) return NULL;
303 p = attr->value.sequence->data;
304 return d2i_ESS_SIGNING_CERT(NULL, &p, attr->value.sequence->length);
305 }
306
307/* Returns < 0 if certificate is not found, certificate index otherwise. */
308static int TS_find_cert(STACK_OF(ESS_CERT_ID) *cert_ids, X509 *cert)
309 {
310 int i;
311
312 if (!cert_ids || !cert) return -1;
313
314 /* Recompute SHA1 hash of certificate if necessary (side effect). */
315 X509_check_purpose(cert, -1, 0);
316
317 /* Look for cert in the cert_ids vector. */
318 for (i = 0; i < sk_ESS_CERT_ID_num(cert_ids); ++i)
319 {
320 ESS_CERT_ID *cid = sk_ESS_CERT_ID_value(cert_ids, i);
321
322 /* Check the SHA-1 hash first. */
323 if (cid->hash->length == sizeof(cert->sha1_hash)
324 && !memcmp(cid->hash->data, cert->sha1_hash,
325 sizeof(cert->sha1_hash)))
326 {
327 /* Check the issuer/serial as well if specified. */
328 ESS_ISSUER_SERIAL *is = cid->issuer_serial;
329 if (!is || !TS_issuer_serial_cmp(is, cert->cert_info))
330 return i;
331 }
332 }
333
334 return -1;
335 }
336
337static int TS_issuer_serial_cmp(ESS_ISSUER_SERIAL *is, X509_CINF *cinfo)
338 {
339 GENERAL_NAME *issuer;
340
341 if (!is || !cinfo || sk_GENERAL_NAME_num(is->issuer) != 1) return -1;
342
343 /* Check the issuer first. It must be a directory name. */
344 issuer = sk_GENERAL_NAME_value(is->issuer, 0);
345 if (issuer->type != GEN_DIRNAME
346 || X509_NAME_cmp(issuer->d.dirn, cinfo->issuer))
347 return -1;
348
349 /* Check the serial number, too. */
350 if (ASN1_INTEGER_cmp(is->serial, cinfo->serialNumber))
351 return -1;
352
353 return 0;
354 }
355
356/*
357 * Verifies whether 'response' contains a valid response with regards
358 * to the settings of the context:
359 * - Gives an error message if the TS_TST_INFO is not present.
360 * - Calls _TS_RESP_verify_token to verify the token content.
361 */
362int TS_RESP_verify_response(TS_VERIFY_CTX *ctx, TS_RESP *response)
363 {
364 PKCS7 *token = TS_RESP_get_token(response);
365 TS_TST_INFO *tst_info = TS_RESP_get_tst_info(response);
366 int ret = 0;
367
368 /* Check if we have a successful TS_TST_INFO object in place. */
369 if (!TS_check_status_info(response)) goto err;
370
371 /* Check the contents of the time stamp token. */
372 if (!int_TS_RESP_verify_token(ctx, token, tst_info))
373 goto err;
374
375 ret = 1;
376 err:
377 return ret;
378 }
379
380/*
381 * Tries to extract a TS_TST_INFO structure from the PKCS7 token and
382 * calls the internal int_TS_RESP_verify_token function for verifying it.
383 */
384int TS_RESP_verify_token(TS_VERIFY_CTX *ctx, PKCS7 *token)
385 {
386 TS_TST_INFO *tst_info = PKCS7_to_TS_TST_INFO(token);
387 int ret = 0;
388 if (tst_info)
389 {
390 ret = int_TS_RESP_verify_token(ctx, token, tst_info);
391 TS_TST_INFO_free(tst_info);
392 }
393 return ret;
394 }
395
396/*
397 * Verifies whether the 'token' contains a valid time stamp token
398 * with regards to the settings of the context. Only those checks are
399 * carried out that are specified in the context:
400 * - Verifies the signature of the TS_TST_INFO.
401 * - Checks the version number of the response.
402 * - Check if the requested and returned policies math.
403 * - Check if the message imprints are the same.
404 * - Check if the nonces are the same.
405 * - Check if the TSA name matches the signer.
406 * - Check if the TSA name is the expected TSA.
407 */
408static int int_TS_RESP_verify_token(TS_VERIFY_CTX *ctx,
409 PKCS7 *token, TS_TST_INFO *tst_info)
410 {
411 X509 *signer = NULL;
412 GENERAL_NAME *tsa_name = TS_TST_INFO_get_tsa(tst_info);
413 X509_ALGOR *md_alg = NULL;
414 unsigned char *imprint = NULL;
415 unsigned imprint_len = 0;
416 int ret = 0;
417
418 /* Verify the signature. */
419 if ((ctx->flags & TS_VFY_SIGNATURE)
420 && !TS_RESP_verify_signature(token, ctx->certs, ctx->store,
421 &signer))
422 goto err;
423
424 /* Check version number of response. */
425 if ((ctx->flags & TS_VFY_VERSION)
426 && TS_TST_INFO_get_version(tst_info) != 1)
427 {
428 TSerr(TS_F_INT_TS_RESP_VERIFY_TOKEN, TS_R_UNSUPPORTED_VERSION);
429 goto err;
430 }
431
432 /* Check policies. */
433 if ((ctx->flags & TS_VFY_POLICY)
434 && !TS_check_policy(ctx->policy, tst_info))
435 goto err;
436
437 /* Check message imprints. */
438 if ((ctx->flags & TS_VFY_IMPRINT)
439 && !TS_check_imprints(ctx->md_alg, ctx->imprint, ctx->imprint_len,
440 tst_info))
441 goto err;
442
443 /* Compute and check message imprints. */
444 if ((ctx->flags & TS_VFY_DATA)
445 && (!TS_compute_imprint(ctx->data, tst_info,
446 &md_alg, &imprint, &imprint_len)
447 || !TS_check_imprints(md_alg, imprint, imprint_len, tst_info)))
448 goto err;
449
450 /* Check nonces. */
451 if ((ctx->flags & TS_VFY_NONCE)
452 && !TS_check_nonces(ctx->nonce, tst_info))
453 goto err;
454
455 /* Check whether TSA name and signer certificate match. */
456 if ((ctx->flags & TS_VFY_SIGNER)
457 && tsa_name && !TS_check_signer_name(tsa_name, signer))
458 {
459 TSerr(TS_F_INT_TS_RESP_VERIFY_TOKEN, TS_R_TSA_NAME_MISMATCH);
460 goto err;
461 }
462
463 /* Check whether the TSA is the expected one. */
464 if ((ctx->flags & TS_VFY_TSA_NAME)
465 && !TS_check_signer_name(ctx->tsa_name, signer))
466 {
467 TSerr(TS_F_INT_TS_RESP_VERIFY_TOKEN, TS_R_TSA_UNTRUSTED);
468 goto err;
469 }
470
471 ret = 1;
472 err:
473 X509_free(signer);
474 X509_ALGOR_free(md_alg);
475 OPENSSL_free(imprint);
476 return ret;
477 }
478
479static int TS_check_status_info(TS_RESP *response)
480 {
481 TS_STATUS_INFO *info = TS_RESP_get_status_info(response);
482 long status = ASN1_INTEGER_get(info->status);
483 const char *status_text = NULL;
484 char *embedded_status_text = NULL;
485 char failure_text[TS_STATUS_BUF_SIZE] = "";
486
487 /* Check if everything went fine. */
488 if (status == 0 || status == 1) return 1;
489
490 /* There was an error, get the description in status_text. */
491 if (0 <= status && status < (long)TS_STATUS_TEXT_SIZE)
492 status_text = TS_status_text[status];
493 else
494 status_text = "unknown code";
495
496 /* Set the embedded_status_text to the returned description. */
497 if (sk_ASN1_UTF8STRING_num(info->text) > 0
498 && !(embedded_status_text = TS_get_status_text(info->text)))
499 return 0;
500
501 /* Filling in failure_text with the failure information. */
502 if (info->failure_info)
503 {
504 int i;
505 int first = 1;
506 for (i = 0; i < (int)TS_FAILURE_INFO_SIZE; ++i)
507 {
508 if (ASN1_BIT_STRING_get_bit(info->failure_info,
509 TS_failure_info[i].code))
510 {
511 if (!first)
512 strcpy(failure_text, ",");
513 else
514 first = 0;
515 strcat(failure_text, TS_failure_info[i].text);
516 }
517 }
518 }
519 if (failure_text[0] == '\0')
520 strcpy(failure_text, "unspecified");
521
522 /* Making up the error string. */
523 TSerr(TS_F_TS_CHECK_STATUS_INFO, TS_R_NO_TIME_STAMP_TOKEN);
524 ERR_add_error_data(6,
525 "status code: ", status_text,
526 ", status text: ", embedded_status_text ?
527 embedded_status_text : "unspecified",
528 ", failure codes: ", failure_text);
529 OPENSSL_free(embedded_status_text);
530
531 return 0;
532 }
533
534static char *TS_get_status_text(STACK_OF(ASN1_UTF8STRING) *text)
535 {
536 int i;
537 unsigned int length = 0;
538 char *result = NULL;
539 char *p;
540
541 /* Determine length first. */
542 for (i = 0; i < sk_ASN1_UTF8STRING_num(text); ++i)
543 {
544 ASN1_UTF8STRING *current = sk_ASN1_UTF8STRING_value(text, i);
545 length += ASN1_STRING_length(current);
546 length += 1; /* separator character */
547 }
548 /* Allocate memory (closing '\0' included). */
549 if (!(result = OPENSSL_malloc(length)))
550 {
551 TSerr(TS_F_TS_GET_STATUS_TEXT, ERR_R_MALLOC_FAILURE);
552 return NULL;
553 }
554 /* Concatenate the descriptions. */
555 for (i = 0, p = result; i < sk_ASN1_UTF8STRING_num(text); ++i)
556 {
557 ASN1_UTF8STRING *current = sk_ASN1_UTF8STRING_value(text, i);
558 length = ASN1_STRING_length(current);
559 if (i > 0) *p++ = '/';
560 strncpy(p, (const char *)ASN1_STRING_data(current), length);
561 p += length;
562 }
563 /* We do have space for this, too. */
564 *p = '\0';
565
566 return result;
567 }
568
569static int TS_check_policy(ASN1_OBJECT *req_oid, TS_TST_INFO *tst_info)
570 {
571 ASN1_OBJECT *resp_oid = TS_TST_INFO_get_policy_id(tst_info);
572
573 if (OBJ_cmp(req_oid, resp_oid) != 0)
574 {
575 TSerr(TS_F_TS_CHECK_POLICY, TS_R_POLICY_MISMATCH);
576 return 0;
577 }
578
579 return 1;
580 }
581
582static int TS_compute_imprint(BIO *data, TS_TST_INFO *tst_info,
583 X509_ALGOR **md_alg,
584 unsigned char **imprint, unsigned *imprint_len)
585 {
586 TS_MSG_IMPRINT *msg_imprint = TS_TST_INFO_get_msg_imprint(tst_info);
587 X509_ALGOR *md_alg_resp = TS_MSG_IMPRINT_get_algo(msg_imprint);
588 const EVP_MD *md;
589 EVP_MD_CTX md_ctx;
590 unsigned char buffer[4096];
591 int length;
592
593 *md_alg = NULL;
594 *imprint = NULL;
595
596 /* Return the MD algorithm of the response. */
597 if (!(*md_alg = X509_ALGOR_dup(md_alg_resp))) goto err;
598
599 /* Getting the MD object. */
600 if (!(md = EVP_get_digestbyobj((*md_alg)->algorithm)))
601 {
602 TSerr(TS_F_TS_COMPUTE_IMPRINT, TS_R_UNSUPPORTED_MD_ALGORITHM);
603 goto err;
604 }
605
606 /* Compute message digest. */
607 length = EVP_MD_size(md);
608 if (length < 0)
609 goto err;
610 *imprint_len = length;
611 if (!(*imprint = OPENSSL_malloc(*imprint_len)))
612 {
613 TSerr(TS_F_TS_COMPUTE_IMPRINT, ERR_R_MALLOC_FAILURE);
614 goto err;
615 }
616
617 EVP_DigestInit(&md_ctx, md);
618 while ((length = BIO_read(data, buffer, sizeof(buffer))) > 0)
619 {
620 EVP_DigestUpdate(&md_ctx, buffer, length);
621 }
622 EVP_DigestFinal(&md_ctx, *imprint, NULL);
623
624 return 1;
625 err:
626 X509_ALGOR_free(*md_alg);
627 OPENSSL_free(*imprint);
628 *imprint_len = 0;
629 return 0;
630 }
631
632static int TS_check_imprints(X509_ALGOR *algor_a,
633 unsigned char *imprint_a, unsigned len_a,
634 TS_TST_INFO *tst_info)
635 {
636 TS_MSG_IMPRINT *b = TS_TST_INFO_get_msg_imprint(tst_info);
637 X509_ALGOR *algor_b = TS_MSG_IMPRINT_get_algo(b);
638 int ret = 0;
639
640 /* algor_a is optional. */
641 if (algor_a)
642 {
643 /* Compare algorithm OIDs. */
644 if (OBJ_cmp(algor_a->algorithm, algor_b->algorithm)) goto err;
645
646 /* The parameter must be NULL in both. */
647 if ((algor_a->parameter
648 && ASN1_TYPE_get(algor_a->parameter) != V_ASN1_NULL)
649 || (algor_b->parameter
650 && ASN1_TYPE_get(algor_b->parameter) != V_ASN1_NULL))
651 goto err;
652 }
653
654 /* Compare octet strings. */
655 ret = len_a == (unsigned) ASN1_STRING_length(b->hashed_msg) &&
656 memcmp(imprint_a, ASN1_STRING_data(b->hashed_msg), len_a) == 0;
657 err:
658 if (!ret)
659 TSerr(TS_F_TS_CHECK_IMPRINTS, TS_R_MESSAGE_IMPRINT_MISMATCH);
660 return ret;
661 }
662
663static int TS_check_nonces(const ASN1_INTEGER *a, TS_TST_INFO *tst_info)
664 {
665 const ASN1_INTEGER *b = TS_TST_INFO_get_nonce(tst_info);
666
667 /* Error if nonce is missing. */
668 if (!b)
669 {
670 TSerr(TS_F_TS_CHECK_NONCES, TS_R_NONCE_NOT_RETURNED);
671 return 0;
672 }
673
674 /* No error if a nonce is returned without being requested. */
675 if (ASN1_INTEGER_cmp(a, b) != 0)
676 {
677 TSerr(TS_F_TS_CHECK_NONCES, TS_R_NONCE_MISMATCH);
678 return 0;
679 }
680
681 return 1;
682 }
683
684/* Check if the specified TSA name matches either the subject
685 or one of the subject alternative names of the TSA certificate. */
686static int TS_check_signer_name(GENERAL_NAME *tsa_name, X509 *signer)
687 {
688 STACK_OF(GENERAL_NAME) *gen_names = NULL;
689 int idx = -1;
690 int found = 0;
691
692 /* Check the subject name first. */
693 if (tsa_name->type == GEN_DIRNAME
694 && X509_name_cmp(tsa_name->d.dirn, signer->cert_info->subject) == 0)
695 return 1;
696
697 /* Check all the alternative names. */
698 gen_names = X509_get_ext_d2i(signer, NID_subject_alt_name,
699 NULL, &idx);
700 while (gen_names != NULL
701 && !(found = TS_find_name(gen_names, tsa_name) >= 0))
702 {
703 /* Get the next subject alternative name,
704 although there should be no more than one. */
705 GENERAL_NAMES_free(gen_names);
706 gen_names = X509_get_ext_d2i(signer, NID_subject_alt_name,
707 NULL, &idx);
708 }
709 if (gen_names) GENERAL_NAMES_free(gen_names);
710
711 return found;
712 }
713
714/* Returns 1 if name is in gen_names, 0 otherwise. */
715static int TS_find_name(STACK_OF(GENERAL_NAME) *gen_names, GENERAL_NAME *name)
716 {
717 int i, found;
718 for (i = 0, found = 0; !found && i < sk_GENERAL_NAME_num(gen_names);
719 ++i)
720 {
721 GENERAL_NAME *current = sk_GENERAL_NAME_value(gen_names, i);
722 found = GENERAL_NAME_cmp(current, name) == 0;
723 }
724 return found ? i - 1 : -1;
725 }
diff --git a/src/lib/libcrypto/ts/ts_verify_ctx.c b/src/lib/libcrypto/ts/ts_verify_ctx.c
new file mode 100644
index 0000000000..b079b50fc3
--- /dev/null
+++ b/src/lib/libcrypto/ts/ts_verify_ctx.c
@@ -0,0 +1,160 @@
1/* crypto/ts/ts_verify_ctx.c */
2/* Written by Zoltan Glozik (zglozik@stones.com) for the OpenSSL
3 * project 2003.
4 */
5/* ====================================================================
6 * Copyright (c) 2006 The OpenSSL Project. All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 *
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 *
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in
17 * the documentation and/or other materials provided with the
18 * distribution.
19 *
20 * 3. All advertising materials mentioning features or use of this
21 * software must display the following acknowledgment:
22 * "This product includes software developed by the OpenSSL Project
23 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
24 *
25 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
26 * endorse or promote products derived from this software without
27 * prior written permission. For written permission, please contact
28 * licensing@OpenSSL.org.
29 *
30 * 5. Products derived from this software may not be called "OpenSSL"
31 * nor may "OpenSSL" appear in their names without prior written
32 * permission of the OpenSSL Project.
33 *
34 * 6. Redistributions of any form whatsoever must retain the following
35 * acknowledgment:
36 * "This product includes software developed by the OpenSSL Project
37 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
38 *
39 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
40 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
43 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
50 * OF THE POSSIBILITY OF SUCH DAMAGE.
51 * ====================================================================
52 *
53 * This product includes cryptographic software written by Eric Young
54 * (eay@cryptsoft.com). This product includes software written by Tim
55 * Hudson (tjh@cryptsoft.com).
56 *
57 */
58
59#include <assert.h>
60#include "cryptlib.h"
61#include <openssl/objects.h>
62#include <openssl/ts.h>
63
64TS_VERIFY_CTX *TS_VERIFY_CTX_new(void)
65 {
66 TS_VERIFY_CTX *ctx =
67 (TS_VERIFY_CTX *) OPENSSL_malloc(sizeof(TS_VERIFY_CTX));
68 if (ctx)
69 memset(ctx, 0, sizeof(TS_VERIFY_CTX));
70 else
71 TSerr(TS_F_TS_VERIFY_CTX_NEW, ERR_R_MALLOC_FAILURE);
72 return ctx;
73 }
74
75void TS_VERIFY_CTX_init(TS_VERIFY_CTX *ctx)
76 {
77 assert(ctx != NULL);
78 memset(ctx, 0, sizeof(TS_VERIFY_CTX));
79 }
80
81void TS_VERIFY_CTX_free(TS_VERIFY_CTX *ctx)
82 {
83 if (!ctx) return;
84
85 TS_VERIFY_CTX_cleanup(ctx);
86 OPENSSL_free(ctx);
87 }
88
89void TS_VERIFY_CTX_cleanup(TS_VERIFY_CTX *ctx)
90 {
91 if (!ctx) return;
92
93 X509_STORE_free(ctx->store);
94 sk_X509_pop_free(ctx->certs, X509_free);
95
96 ASN1_OBJECT_free(ctx->policy);
97
98 X509_ALGOR_free(ctx->md_alg);
99 OPENSSL_free(ctx->imprint);
100
101 BIO_free_all(ctx->data);
102
103 ASN1_INTEGER_free(ctx->nonce);
104
105 GENERAL_NAME_free(ctx->tsa_name);
106
107 TS_VERIFY_CTX_init(ctx);
108 }
109
110TS_VERIFY_CTX *TS_REQ_to_TS_VERIFY_CTX(TS_REQ *req, TS_VERIFY_CTX *ctx)
111 {
112 TS_VERIFY_CTX *ret = ctx;
113 ASN1_OBJECT *policy;
114 TS_MSG_IMPRINT *imprint;
115 X509_ALGOR *md_alg;
116 ASN1_OCTET_STRING *msg;
117 const ASN1_INTEGER *nonce;
118
119 assert(req != NULL);
120 if (ret)
121 TS_VERIFY_CTX_cleanup(ret);
122 else
123 if (!(ret = TS_VERIFY_CTX_new())) return NULL;
124
125 /* Setting flags. */
126 ret->flags = TS_VFY_ALL_IMPRINT & ~(TS_VFY_TSA_NAME | TS_VFY_SIGNATURE);
127
128 /* Setting policy. */
129 if ((policy = TS_REQ_get_policy_id(req)) != NULL)
130 {
131 if (!(ret->policy = OBJ_dup(policy))) goto err;
132 }
133 else
134 ret->flags &= ~TS_VFY_POLICY;
135
136 /* Setting md_alg, imprint and imprint_len. */
137 imprint = TS_REQ_get_msg_imprint(req);
138 md_alg = TS_MSG_IMPRINT_get_algo(imprint);
139 if (!(ret->md_alg = X509_ALGOR_dup(md_alg))) goto err;
140 msg = TS_MSG_IMPRINT_get_msg(imprint);
141 ret->imprint_len = ASN1_STRING_length(msg);
142 if (!(ret->imprint = OPENSSL_malloc(ret->imprint_len))) goto err;
143 memcpy(ret->imprint, ASN1_STRING_data(msg), ret->imprint_len);
144
145 /* Setting nonce. */
146 if ((nonce = TS_REQ_get_nonce(req)) != NULL)
147 {
148 if (!(ret->nonce = ASN1_INTEGER_dup(nonce))) goto err;
149 }
150 else
151 ret->flags &= ~TS_VFY_NONCE;
152
153 return ret;
154 err:
155 if (ctx)
156 TS_VERIFY_CTX_cleanup(ctx);
157 else
158 TS_VERIFY_CTX_free(ret);
159 return NULL;
160 }
diff --git a/src/lib/libcrypto/txt_db/txt_db.c b/src/lib/libcrypto/txt_db/txt_db.c
index 3ed5f72ee9..6f2ce3b5a4 100644
--- a/src/lib/libcrypto/txt_db/txt_db.c
+++ b/src/lib/libcrypto/txt_db/txt_db.c
@@ -77,22 +77,23 @@ TXT_DB *TXT_DB_read(BIO *in, int num)
77 int i,add,n; 77 int i,add,n;
78 int size=BUFSIZE; 78 int size=BUFSIZE;
79 int offset=0; 79 int offset=0;
80 char *p,**pp,*f; 80 char *p,*f;
81 OPENSSL_STRING *pp;
81 BUF_MEM *buf=NULL; 82 BUF_MEM *buf=NULL;
82 83
83 if ((buf=BUF_MEM_new()) == NULL) goto err; 84 if ((buf=BUF_MEM_new()) == NULL) goto err;
84 if (!BUF_MEM_grow(buf,size)) goto err; 85 if (!BUF_MEM_grow(buf,size)) goto err;
85 86
86 if ((ret=(TXT_DB *)OPENSSL_malloc(sizeof(TXT_DB))) == NULL) 87 if ((ret=OPENSSL_malloc(sizeof(TXT_DB))) == NULL)
87 goto err; 88 goto err;
88 ret->num_fields=num; 89 ret->num_fields=num;
89 ret->index=NULL; 90 ret->index=NULL;
90 ret->qual=NULL; 91 ret->qual=NULL;
91 if ((ret->data=sk_new_null()) == NULL) 92 if ((ret->data=sk_OPENSSL_PSTRING_new_null()) == NULL)
92 goto err; 93 goto err;
93 if ((ret->index=(LHASH **)OPENSSL_malloc(sizeof(LHASH *)*num)) == NULL) 94 if ((ret->index=OPENSSL_malloc(sizeof(*ret->index)*num)) == NULL)
94 goto err; 95 goto err;
95 if ((ret->qual=(int (**)(char **))OPENSSL_malloc(sizeof(int (**)(char **))*num)) == NULL) 96 if ((ret->qual=OPENSSL_malloc(sizeof(*(ret->qual))*num)) == NULL)
96 goto err; 97 goto err;
97 for (i=0; i<num; i++) 98 for (i=0; i<num; i++)
98 { 99 {
@@ -122,7 +123,7 @@ TXT_DB *TXT_DB_read(BIO *in, int num)
122 else 123 else
123 { 124 {
124 buf->data[offset-1]='\0'; /* blat the '\n' */ 125 buf->data[offset-1]='\0'; /* blat the '\n' */
125 if (!(p=(char *)OPENSSL_malloc(add+offset))) goto err; 126 if (!(p=OPENSSL_malloc(add+offset))) goto err;
126 offset=0; 127 offset=0;
127 } 128 }
128 pp=(char **)p; 129 pp=(char **)p;
@@ -155,16 +156,16 @@ TXT_DB *TXT_DB_read(BIO *in, int num)
155 *(p++)='\0'; 156 *(p++)='\0';
156 if ((n != num) || (*f != '\0')) 157 if ((n != num) || (*f != '\0'))
157 { 158 {
158#if !defined(OPENSSL_NO_STDIO) && !defined(OPENSSL_SYS_WIN16) /* temporaty fix :-( */ 159#if !defined(OPENSSL_NO_STDIO) && !defined(OPENSSL_SYS_WIN16) /* temporary fix :-( */
159 fprintf(stderr,"wrong number of fields on line %ld (looking for field %d, got %d, '%s' left)\n",ln,num,n,f); 160 fprintf(stderr,"wrong number of fields on line %ld (looking for field %d, got %d, '%s' left)\n",ln,num,n,f);
160#endif 161#endif
161 er=2; 162 er=2;
162 goto err; 163 goto err;
163 } 164 }
164 pp[n]=p; 165 pp[n]=p;
165 if (!sk_push(ret->data,(char *)pp)) 166 if (!sk_OPENSSL_PSTRING_push(ret->data,pp))
166 { 167 {
167#if !defined(OPENSSL_NO_STDIO) && !defined(OPENSSL_SYS_WIN16) /* temporaty fix :-( */ 168#if !defined(OPENSSL_NO_STDIO) && !defined(OPENSSL_SYS_WIN16) /* temporary fix :-( */
168 fprintf(stderr,"failure in sk_push\n"); 169 fprintf(stderr,"failure in sk_push\n");
169#endif 170#endif
170 er=2; 171 er=2;
@@ -181,7 +182,7 @@ err:
181#endif 182#endif
182 if (ret != NULL) 183 if (ret != NULL)
183 { 184 {
184 if (ret->data != NULL) sk_free(ret->data); 185 if (ret->data != NULL) sk_OPENSSL_PSTRING_free(ret->data);
185 if (ret->index != NULL) OPENSSL_free(ret->index); 186 if (ret->index != NULL) OPENSSL_free(ret->index);
186 if (ret->qual != NULL) OPENSSL_free(ret->qual); 187 if (ret->qual != NULL) OPENSSL_free(ret->qual);
187 if (ret != NULL) OPENSSL_free(ret); 188 if (ret != NULL) OPENSSL_free(ret);
@@ -192,10 +193,10 @@ err:
192 return(ret); 193 return(ret);
193 } 194 }
194 195
195char **TXT_DB_get_by_index(TXT_DB *db, int idx, char **value) 196OPENSSL_STRING *TXT_DB_get_by_index(TXT_DB *db, int idx, OPENSSL_STRING *value)
196 { 197 {
197 char **ret; 198 OPENSSL_STRING *ret;
198 LHASH *lh; 199 LHASH_OF(OPENSSL_STRING) *lh;
199 200
200 if (idx >= db->num_fields) 201 if (idx >= db->num_fields)
201 { 202 {
@@ -208,16 +209,16 @@ char **TXT_DB_get_by_index(TXT_DB *db, int idx, char **value)
208 db->error=DB_ERROR_NO_INDEX; 209 db->error=DB_ERROR_NO_INDEX;
209 return(NULL); 210 return(NULL);
210 } 211 }
211 ret=(char **)lh_retrieve(lh,value); 212 ret=lh_OPENSSL_STRING_retrieve(lh,value);
212 db->error=DB_ERROR_OK; 213 db->error=DB_ERROR_OK;
213 return(ret); 214 return(ret);
214 } 215 }
215 216
216int TXT_DB_create_index(TXT_DB *db, int field, int (*qual)(char **), 217int TXT_DB_create_index(TXT_DB *db, int field, int (*qual)(OPENSSL_STRING *),
217 LHASH_HASH_FN_TYPE hash, LHASH_COMP_FN_TYPE cmp) 218 LHASH_HASH_FN_TYPE hash, LHASH_COMP_FN_TYPE cmp)
218 { 219 {
219 LHASH *idx; 220 LHASH_OF(OPENSSL_STRING) *idx;
220 char **r; 221 OPENSSL_STRING *r;
221 int i,n; 222 int i,n;
222 223
223 if (field >= db->num_fields) 224 if (field >= db->num_fields)
@@ -225,26 +226,27 @@ int TXT_DB_create_index(TXT_DB *db, int field, int (*qual)(char **),
225 db->error=DB_ERROR_INDEX_OUT_OF_RANGE; 226 db->error=DB_ERROR_INDEX_OUT_OF_RANGE;
226 return(0); 227 return(0);
227 } 228 }
228 if ((idx=lh_new(hash,cmp)) == NULL) 229 /* FIXME: we lose type checking at this point */
230 if ((idx=(LHASH_OF(OPENSSL_STRING) *)lh_new(hash,cmp)) == NULL)
229 { 231 {
230 db->error=DB_ERROR_MALLOC; 232 db->error=DB_ERROR_MALLOC;
231 return(0); 233 return(0);
232 } 234 }
233 n=sk_num(db->data); 235 n=sk_OPENSSL_PSTRING_num(db->data);
234 for (i=0; i<n; i++) 236 for (i=0; i<n; i++)
235 { 237 {
236 r=(char **)sk_value(db->data,i); 238 r=sk_OPENSSL_PSTRING_value(db->data,i);
237 if ((qual != NULL) && (qual(r) == 0)) continue; 239 if ((qual != NULL) && (qual(r) == 0)) continue;
238 if ((r=lh_insert(idx,r)) != NULL) 240 if ((r=lh_OPENSSL_STRING_insert(idx,r)) != NULL)
239 { 241 {
240 db->error=DB_ERROR_INDEX_CLASH; 242 db->error=DB_ERROR_INDEX_CLASH;
241 db->arg1=sk_find(db->data,(char *)r); 243 db->arg1=sk_OPENSSL_PSTRING_find(db->data,r);
242 db->arg2=i; 244 db->arg2=i;
243 lh_free(idx); 245 lh_OPENSSL_STRING_free(idx);
244 return(0); 246 return(0);
245 } 247 }
246 } 248 }
247 if (db->index[field] != NULL) lh_free(db->index[field]); 249 if (db->index[field] != NULL) lh_OPENSSL_STRING_free(db->index[field]);
248 db->index[field]=idx; 250 db->index[field]=idx;
249 db->qual[field]=qual; 251 db->qual[field]=qual;
250 return(1); 252 return(1);
@@ -259,11 +261,11 @@ long TXT_DB_write(BIO *out, TXT_DB *db)
259 261
260 if ((buf=BUF_MEM_new()) == NULL) 262 if ((buf=BUF_MEM_new()) == NULL)
261 goto err; 263 goto err;
262 n=sk_num(db->data); 264 n=sk_OPENSSL_PSTRING_num(db->data);
263 nn=db->num_fields; 265 nn=db->num_fields;
264 for (i=0; i<n; i++) 266 for (i=0; i<n; i++)
265 { 267 {
266 pp=(char **)sk_value(db->data,i); 268 pp=sk_OPENSSL_PSTRING_value(db->data,i);
267 269
268 l=0; 270 l=0;
269 for (j=0; j<nn; j++) 271 for (j=0; j<nn; j++)
@@ -298,10 +300,10 @@ err:
298 return(ret); 300 return(ret);
299 } 301 }
300 302
301int TXT_DB_insert(TXT_DB *db, char **row) 303int TXT_DB_insert(TXT_DB *db, OPENSSL_STRING *row)
302 { 304 {
303 int i; 305 int i;
304 char **r; 306 OPENSSL_STRING *r;
305 307
306 for (i=0; i<db->num_fields; i++) 308 for (i=0; i<db->num_fields; i++)
307 { 309 {
@@ -309,7 +311,7 @@ int TXT_DB_insert(TXT_DB *db, char **row)
309 { 311 {
310 if ((db->qual[i] != NULL) && 312 if ((db->qual[i] != NULL) &&
311 (db->qual[i](row) == 0)) continue; 313 (db->qual[i](row) == 0)) continue;
312 r=(char **)lh_retrieve(db->index[i],row); 314 r=lh_OPENSSL_STRING_retrieve(db->index[i],row);
313 if (r != NULL) 315 if (r != NULL)
314 { 316 {
315 db->error=DB_ERROR_INDEX_CLASH; 317 db->error=DB_ERROR_INDEX_CLASH;
@@ -320,7 +322,7 @@ int TXT_DB_insert(TXT_DB *db, char **row)
320 } 322 }
321 } 323 }
322 /* We have passed the index checks, now just append and insert */ 324 /* We have passed the index checks, now just append and insert */
323 if (!sk_push(db->data,(char *)row)) 325 if (!sk_OPENSSL_PSTRING_push(db->data,row))
324 { 326 {
325 db->error=DB_ERROR_MALLOC; 327 db->error=DB_ERROR_MALLOC;
326 goto err; 328 goto err;
@@ -332,7 +334,7 @@ int TXT_DB_insert(TXT_DB *db, char **row)
332 { 334 {
333 if ((db->qual[i] != NULL) && 335 if ((db->qual[i] != NULL) &&
334 (db->qual[i](row) == 0)) continue; 336 (db->qual[i](row) == 0)) continue;
335 lh_insert(db->index[i],row); 337 (void)lh_OPENSSL_STRING_insert(db->index[i],row);
336 } 338 }
337 } 339 }
338 return(1); 340 return(1);
@@ -351,18 +353,18 @@ void TXT_DB_free(TXT_DB *db)
351 if (db->index != NULL) 353 if (db->index != NULL)
352 { 354 {
353 for (i=db->num_fields-1; i>=0; i--) 355 for (i=db->num_fields-1; i>=0; i--)
354 if (db->index[i] != NULL) lh_free(db->index[i]); 356 if (db->index[i] != NULL) lh_OPENSSL_STRING_free(db->index[i]);
355 OPENSSL_free(db->index); 357 OPENSSL_free(db->index);
356 } 358 }
357 if (db->qual != NULL) 359 if (db->qual != NULL)
358 OPENSSL_free(db->qual); 360 OPENSSL_free(db->qual);
359 if (db->data != NULL) 361 if (db->data != NULL)
360 { 362 {
361 for (i=sk_num(db->data)-1; i>=0; i--) 363 for (i=sk_OPENSSL_PSTRING_num(db->data)-1; i>=0; i--)
362 { 364 {
363 /* check if any 'fields' have been allocated 365 /* check if any 'fields' have been allocated
364 * from outside of the initial block */ 366 * from outside of the initial block */
365 p=(char **)sk_value(db->data,i); 367 p=sk_OPENSSL_PSTRING_value(db->data,i);
366 max=p[db->num_fields]; /* last address */ 368 max=p[db->num_fields]; /* last address */
367 if (max == NULL) /* new row */ 369 if (max == NULL) /* new row */
368 { 370 {
@@ -378,9 +380,9 @@ void TXT_DB_free(TXT_DB *db)
378 OPENSSL_free(p[n]); 380 OPENSSL_free(p[n]);
379 } 381 }
380 } 382 }
381 OPENSSL_free(sk_value(db->data,i)); 383 OPENSSL_free(sk_OPENSSL_PSTRING_value(db->data,i));
382 } 384 }
383 sk_free(db->data); 385 sk_OPENSSL_PSTRING_free(db->data);
384 } 386 }
385 OPENSSL_free(db); 387 OPENSSL_free(db);
386 } 388 }
diff --git a/src/lib/libcrypto/txt_db/txt_db.h b/src/lib/libcrypto/txt_db/txt_db.h
index 307e1ba23f..6abe435bc8 100644
--- a/src/lib/libcrypto/txt_db/txt_db.h
+++ b/src/lib/libcrypto/txt_db/txt_db.h
@@ -77,16 +77,19 @@
77extern "C" { 77extern "C" {
78#endif 78#endif
79 79
80typedef OPENSSL_STRING *OPENSSL_PSTRING;
81DECLARE_SPECIAL_STACK_OF(OPENSSL_PSTRING, OPENSSL_STRING)
82
80typedef struct txt_db_st 83typedef struct txt_db_st
81 { 84 {
82 int num_fields; 85 int num_fields;
83 STACK /* char ** */ *data; 86 STACK_OF(OPENSSL_PSTRING) *data;
84 LHASH **index; 87 LHASH_OF(OPENSSL_STRING) **index;
85 int (**qual)(char **); 88 int (**qual)(OPENSSL_STRING *);
86 long error; 89 long error;
87 long arg1; 90 long arg1;
88 long arg2; 91 long arg2;
89 char **arg_row; 92 OPENSSL_STRING *arg_row;
90 } TXT_DB; 93 } TXT_DB;
91 94
92#ifndef OPENSSL_NO_BIO 95#ifndef OPENSSL_NO_BIO
@@ -96,11 +99,11 @@ long TXT_DB_write(BIO *out, TXT_DB *db);
96TXT_DB *TXT_DB_read(char *in, int num); 99TXT_DB *TXT_DB_read(char *in, int num);
97long TXT_DB_write(char *out, TXT_DB *db); 100long TXT_DB_write(char *out, TXT_DB *db);
98#endif 101#endif
99int TXT_DB_create_index(TXT_DB *db,int field,int (*qual)(char **), 102int TXT_DB_create_index(TXT_DB *db,int field,int (*qual)(OPENSSL_STRING *),
100 LHASH_HASH_FN_TYPE hash, LHASH_COMP_FN_TYPE cmp); 103 LHASH_HASH_FN_TYPE hash, LHASH_COMP_FN_TYPE cmp);
101void TXT_DB_free(TXT_DB *db); 104void TXT_DB_free(TXT_DB *db);
102char **TXT_DB_get_by_index(TXT_DB *db, int idx, char **value); 105OPENSSL_STRING *TXT_DB_get_by_index(TXT_DB *db, int idx, OPENSSL_STRING *value);
103int TXT_DB_insert(TXT_DB *db,char **value); 106int TXT_DB_insert(TXT_DB *db, OPENSSL_STRING *value);
104 107
105#ifdef __cplusplus 108#ifdef __cplusplus
106} 109}
diff --git a/src/lib/libcrypto/ui/ui.h b/src/lib/libcrypto/ui/ui.h
index 018296412b..2b1cfa2289 100644
--- a/src/lib/libcrypto/ui/ui.h
+++ b/src/lib/libcrypto/ui/ui.h
@@ -287,8 +287,8 @@ UI_METHOD *UI_OpenSSL(void);
287/* The UI_STRING type is the data structure that contains all the needed info 287/* The UI_STRING type is the data structure that contains all the needed info
288 about a string or a prompt, including test data for a verification prompt. 288 about a string or a prompt, including test data for a verification prompt.
289*/ 289*/
290DECLARE_STACK_OF(UI_STRING)
291typedef struct ui_string_st UI_STRING; 290typedef struct ui_string_st UI_STRING;
291DECLARE_STACK_OF(UI_STRING)
292 292
293/* The different types of strings that are currently supported. 293/* The different types of strings that are currently supported.
294 This is only needed by method authors. */ 294 This is only needed by method authors. */
@@ -310,11 +310,13 @@ int UI_method_set_writer(UI_METHOD *method, int (*writer)(UI *ui, UI_STRING *uis
310int UI_method_set_flusher(UI_METHOD *method, int (*flusher)(UI *ui)); 310int UI_method_set_flusher(UI_METHOD *method, int (*flusher)(UI *ui));
311int UI_method_set_reader(UI_METHOD *method, int (*reader)(UI *ui, UI_STRING *uis)); 311int UI_method_set_reader(UI_METHOD *method, int (*reader)(UI *ui, UI_STRING *uis));
312int UI_method_set_closer(UI_METHOD *method, int (*closer)(UI *ui)); 312int UI_method_set_closer(UI_METHOD *method, int (*closer)(UI *ui));
313int UI_method_set_prompt_constructor(UI_METHOD *method, char *(*prompt_constructor)(UI* ui, const char* object_desc, const char* object_name));
313int (*UI_method_get_opener(UI_METHOD *method))(UI*); 314int (*UI_method_get_opener(UI_METHOD *method))(UI*);
314int (*UI_method_get_writer(UI_METHOD *method))(UI*,UI_STRING*); 315int (*UI_method_get_writer(UI_METHOD *method))(UI*,UI_STRING*);
315int (*UI_method_get_flusher(UI_METHOD *method))(UI*); 316int (*UI_method_get_flusher(UI_METHOD *method))(UI*);
316int (*UI_method_get_reader(UI_METHOD *method))(UI*,UI_STRING*); 317int (*UI_method_get_reader(UI_METHOD *method))(UI*,UI_STRING*);
317int (*UI_method_get_closer(UI_METHOD *method))(UI*); 318int (*UI_method_get_closer(UI_METHOD *method))(UI*);
319char* (*UI_method_get_prompt_constructor(UI_METHOD *method))(UI*, const char*, const char*);
318 320
319/* The following functions are helpers for method writers to access relevant 321/* The following functions are helpers for method writers to access relevant
320 data from a UI_STRING. */ 322 data from a UI_STRING. */
diff --git a/src/lib/libcrypto/ui/ui_err.c b/src/lib/libcrypto/ui/ui_err.c
index 786bd0dbc3..a6b96299a0 100644
--- a/src/lib/libcrypto/ui/ui_err.c
+++ b/src/lib/libcrypto/ui/ui_err.c
@@ -1,6 +1,6 @@
1/* crypto/ui/ui_err.c */ 1/* crypto/ui/ui_err.c */
2/* ==================================================================== 2/* ====================================================================
3 * Copyright (c) 1999-2005 The OpenSSL Project. All rights reserved. 3 * Copyright (c) 1999-2006 The OpenSSL Project. All rights reserved.
4 * 4 *
5 * Redistribution and use in source and binary forms, with or without 5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions 6 * modification, are permitted provided that the following conditions
diff --git a/src/lib/libcrypto/ui/ui_lib.c b/src/lib/libcrypto/ui/ui_lib.c
index ac0100808f..a8abc27064 100644
--- a/src/lib/libcrypto/ui/ui_lib.c
+++ b/src/lib/libcrypto/ui/ui_lib.c
@@ -693,6 +693,17 @@ int UI_method_set_closer(UI_METHOD *method, int (*closer)(UI *ui))
693 return -1; 693 return -1;
694 } 694 }
695 695
696int UI_method_set_prompt_constructor(UI_METHOD *method, char *(*prompt_constructor)(UI* ui, const char* object_desc, const char* object_name))
697 {
698 if (method)
699 {
700 method->ui_construct_prompt = prompt_constructor;
701 return 0;
702 }
703 else
704 return -1;
705 }
706
696int (*UI_method_get_opener(UI_METHOD *method))(UI*) 707int (*UI_method_get_opener(UI_METHOD *method))(UI*)
697 { 708 {
698 if (method) 709 if (method)
@@ -733,6 +744,14 @@ int (*UI_method_get_closer(UI_METHOD *method))(UI*)
733 return NULL; 744 return NULL;
734 } 745 }
735 746
747char* (*UI_method_get_prompt_constructor(UI_METHOD *method))(UI*, const char*, const char*)
748 {
749 if (method)
750 return method->ui_construct_prompt;
751 else
752 return NULL;
753 }
754
736enum UI_string_types UI_get_string_type(UI_STRING *uis) 755enum UI_string_types UI_get_string_type(UI_STRING *uis)
737 { 756 {
738 if (!uis) 757 if (!uis)
diff --git a/src/lib/libcrypto/ui/ui_openssl.c b/src/lib/libcrypto/ui/ui_openssl.c
index ef930bf247..1bc25f48d5 100644
--- a/src/lib/libcrypto/ui/ui_openssl.c
+++ b/src/lib/libcrypto/ui/ui_openssl.c
@@ -122,7 +122,9 @@
122 * sigaction and fileno included. -pedantic would be more appropriate for 122 * sigaction and fileno included. -pedantic would be more appropriate for
123 * the intended purposes, but we can't prevent users from adding -ansi. 123 * the intended purposes, but we can't prevent users from adding -ansi.
124 */ 124 */
125#define _POSIX_C_SOURCE 1 125#ifndef _POSIX_C_SOURCE
126#define _POSIX_C_SOURCE 2
127#endif
126#include <signal.h> 128#include <signal.h>
127#include <stdio.h> 129#include <stdio.h>
128#include <string.h> 130#include <string.h>
@@ -297,7 +299,7 @@ static int is_a_tty;
297 299
298/* Declare static functions */ 300/* Declare static functions */
299#if !defined(OPENSSL_SYS_WIN16) && !defined(OPENSSL_SYS_WINCE) 301#if !defined(OPENSSL_SYS_WIN16) && !defined(OPENSSL_SYS_WINCE)
300static void read_till_nl(FILE *); 302static int read_till_nl(FILE *);
301static void recsig(int); 303static void recsig(int);
302static void pushsig(void); 304static void pushsig(void);
303static void popsig(void); 305static void popsig(void);
@@ -390,14 +392,16 @@ static int read_string(UI *ui, UI_STRING *uis)
390 392
391#if !defined(OPENSSL_SYS_WIN16) && !defined(OPENSSL_SYS_WINCE) 393#if !defined(OPENSSL_SYS_WIN16) && !defined(OPENSSL_SYS_WINCE)
392/* Internal functions to read a string without echoing */ 394/* Internal functions to read a string without echoing */
393static void read_till_nl(FILE *in) 395static int read_till_nl(FILE *in)
394 { 396 {
395#define SIZE 4 397#define SIZE 4
396 char buf[SIZE+1]; 398 char buf[SIZE+1];
397 399
398 do { 400 do {
399 fgets(buf,SIZE,in); 401 if (!fgets(buf,SIZE,in))
402 return 0;
400 } while (strchr(buf,'\n') == NULL); 403 } while (strchr(buf,'\n') == NULL);
404 return 1;
401 } 405 }
402 406
403static volatile sig_atomic_t intr_signal; 407static volatile sig_atomic_t intr_signal;
@@ -445,7 +449,8 @@ static int read_string_inner(UI *ui, UI_STRING *uis, int echo, int strip_nl)
445 *p='\0'; 449 *p='\0';
446 } 450 }
447 else 451 else
448 read_till_nl(tty_in); 452 if (!read_till_nl(tty_in))
453 goto error;
449 if (UI_set_result(ui, uis, result) >= 0) 454 if (UI_set_result(ui, uis, result) >= 0)
450 ok=1; 455 ok=1;
451 456
@@ -473,7 +478,7 @@ static int open_console(UI *ui)
473 CRYPTO_w_lock(CRYPTO_LOCK_UI); 478 CRYPTO_w_lock(CRYPTO_LOCK_UI);
474 is_a_tty = 1; 479 is_a_tty = 1;
475 480
476#if defined(OPENSSL_SYS_MACINTOSH_CLASSIC) || defined(OPENSSL_SYS_VXWORKS) || defined(OPENSSL_SYS_NETWARE) 481#if defined(OPENSSL_SYS_MACINTOSH_CLASSIC) || defined(OPENSSL_SYS_VXWORKS) || defined(OPENSSL_SYS_NETWARE) || defined(OPENSSL_SYS_BEOS)
477 tty_in=stdin; 482 tty_in=stdin;
478 tty_out=stderr; 483 tty_out=stderr;
479#else 484#else
diff --git a/src/lib/libcrypto/util/mkerr.pl b/src/lib/libcrypto/util/mkerr.pl
index 554bebb159..15b774f277 100644
--- a/src/lib/libcrypto/util/mkerr.pl
+++ b/src/lib/libcrypto/util/mkerr.pl
@@ -1,6 +1,7 @@
1#!/usr/local/bin/perl -w 1#!/usr/local/bin/perl -w
2 2
3my $config = "crypto/err/openssl.ec"; 3my $config = "crypto/err/openssl.ec";
4my $hprefix = "openssl/";
4my $debug = 0; 5my $debug = 0;
5my $rebuild = 0; 6my $rebuild = 0;
6my $static = 1; 7my $static = 1;
@@ -12,11 +13,16 @@ my $staticloader = "";
12my $pack_errcode; 13my $pack_errcode;
13my $load_errcode; 14my $load_errcode;
14 15
16my $errcount;
17
15while (@ARGV) { 18while (@ARGV) {
16 my $arg = $ARGV[0]; 19 my $arg = $ARGV[0];
17 if($arg eq "-conf") { 20 if($arg eq "-conf") {
18 shift @ARGV; 21 shift @ARGV;
19 $config = shift @ARGV; 22 $config = shift @ARGV;
23 } elsif($arg eq "-hprefix") {
24 shift @ARGV;
25 $hprefix = shift @ARGV;
20 } elsif($arg eq "-debug") { 26 } elsif($arg eq "-debug") {
21 $debug = 1; 27 $debug = 1;
22 shift @ARGV; 28 shift @ARGV;
@@ -38,14 +44,78 @@ while (@ARGV) {
38 } elsif($arg eq "-write") { 44 } elsif($arg eq "-write") {
39 $dowrite = 1; 45 $dowrite = 1;
40 shift @ARGV; 46 shift @ARGV;
47 } elsif($arg eq "-help" || $arg eq "-h" || $arg eq "-?" || $arg eq "--help") {
48 print STDERR <<"EOF";
49mkerr.pl [options] ...
50
51Options:
52
53 -conf F Use the config file F instead of the default one:
54 crypto/err/openssl.ec
55
56 -hprefix P Prepend the filenames in generated #include <header>
57 statements with prefix P. Default: 'openssl/' (without
58 the quotes, naturally)
59
60 -debug Turn on debugging verbose output on stderr.
61
62 -rebuild Rebuild all header and C source files, irrespective of the
63 fact if any error or function codes have been added/removed.
64 Default: only update files for libraries which saw change
65 (of course, this requires '-write' as well, or no
66 files will be touched!)
67
68 -recurse scan a preconfigured set of directories / files for error and
69 function codes:
70 (<crypto/*.c>, <crypto/*/*.c>, <ssl/*.c>, <apps/*.c>)
71 When this option is NOT specified, the filelist is taken from
72 the commandline instead. Here, wildcards may be embedded. (Be
73 sure to escape those to prevent the shell from expanding them
74 for you when you wish mkerr.pl to do so instead.)
75 Default: take file list to scan from the command line.
76
77 -reindex Discard the numeric values previously assigned to the error
78 and function codes as extracted from the scanned header files;
79 instead renumber all of them starting from 100. (Note that
80 the numbers assigned through 'R' records in the config file
81 remain intact.)
82 Default: keep previously assigned numbers. (You are warned
83 when collisions are detected.)
84
85 -nostatic Generates a different source code, where these additional
86 functions are generated for each library specified in the
87 config file:
88 void ERR_load_<LIB>_strings(void);
89 void ERR_unload_<LIB>_strings(void);
90 void ERR_<LIB>_error(int f, int r, char *fn, int ln);
91 #define <LIB>err(f,r) ERR_<LIB>_error(f,r,__FILE__,__LINE__)
92 while the code facilitates the use of these in an environment
93 where the error support routines are dynamically loaded at
94 runtime.
95 Default: 'static' code generation.
96
97 -staticloader Prefix generated functions with the 'static' scope modifier.
98 Default: don't write any scope modifier prefix.
99
100 -write Actually (over)write the generated code to the header and C
101 source files as assigned to each library through the config
102 file.
103 Default: don't write.
104
105 -help / -h / -? / --help Show this help text.
106
107 ... Additional arguments are added to the file list to scan,
108 assuming '-recurse' was NOT specified on the command line.
109
110EOF
111 exit 1;
41 } else { 112 } else {
42 last; 113 last;
43 } 114 }
44} 115}
45 116
46if($recurse) { 117if($recurse) {
47 @source = ( <crypto/*.c>, <crypto/*/*.c>, <ssl/*.c>, 118 @source = (<crypto/*.c>, <crypto/*/*.c>, <ssl/*.c>);
48 <fips/*.c>, <fips/*/*.c>);
49} else { 119} else {
50 @source = @ARGV; 120 @source = @ARGV;
51} 121}
@@ -64,8 +134,8 @@ while(<IN>)
64 $cskip{$3} = $1; 134 $cskip{$3} = $1;
65 if($3 ne "NONE") { 135 if($3 ne "NONE") {
66 $csrc{$1} = $3; 136 $csrc{$1} = $3;
67 $fmax{$1} = 99; 137 $fmax{$1} = 100;
68 $rmax{$1} = 99; 138 $rmax{$1} = 100;
69 $fassigned{$1} = ":"; 139 $fassigned{$1} = ":";
70 $rassigned{$1} = ":"; 140 $rassigned{$1} = ":";
71 $fnew{$1} = 0; 141 $fnew{$1} = 0;
@@ -191,7 +261,8 @@ while (($hdr, $lib) = each %libinc)
191 if($1 eq "R") { 261 if($1 eq "R") {
192 $rcodes{$name} = $code; 262 $rcodes{$name} = $code;
193 if ($rassigned{$lib} =~ /:$code:/) { 263 if ($rassigned{$lib} =~ /:$code:/) {
194 print STDERR "!! ERROR: $lib reason code $code assigned twice\n"; 264 print STDERR "!! ERROR: $lib reason code $code assigned twice (collision at $name)\n";
265 ++$errcount;
195 } 266 }
196 $rassigned{$lib} .= "$code:"; 267 $rassigned{$lib} .= "$code:";
197 if(!(exists $rextra{$name}) && 268 if(!(exists $rextra{$name}) &&
@@ -200,7 +271,8 @@ while (($hdr, $lib) = each %libinc)
200 } 271 }
201 } else { 272 } else {
202 if ($fassigned{$lib} =~ /:$code:/) { 273 if ($fassigned{$lib} =~ /:$code:/) {
203 print STDERR "!! ERROR: $lib function code $code assigned twice\n"; 274 print STDERR "!! ERROR: $lib function code $code assigned twice (collision at $name)\n";
275 ++$errcount;
204 } 276 }
205 $fassigned{$lib} .= "$code:"; 277 $fassigned{$lib} .= "$code:";
206 if($code > $fmax{$lib}) { 278 if($code > $fmax{$lib}) {
@@ -231,6 +303,7 @@ while (($hdr, $lib) = each %libinc)
231 if ($rmax{$lib} >= 1000) { 303 if ($rmax{$lib} >= 1000) {
232 print STDERR "!! ERROR: SSL error codes 1000+ are reserved for alerts.\n"; 304 print STDERR "!! ERROR: SSL error codes 1000+ are reserved for alerts.\n";
233 print STDERR "!! Any new alerts must be added to $config.\n"; 305 print STDERR "!! Any new alerts must be added to $config.\n";
306 ++$errcount;
234 print STDERR "\n"; 307 print STDERR "\n";
235 } 308 }
236 } 309 }
@@ -255,6 +328,9 @@ foreach $file (@source) {
255 print STDERR "File loaded: ".$file."\r" if $debug; 328 print STDERR "File loaded: ".$file."\r" if $debug;
256 open(IN, "<$file") || die "Can't open source file $file\n"; 329 open(IN, "<$file") || die "Can't open source file $file\n";
257 while(<IN>) { 330 while(<IN>) {
331 # skip obsoleted source files entirely!
332 last if(/^#error\s+obsolete/);
333
258 if(/(([A-Z0-9]+)_F_([A-Z0-9_]+))/) { 334 if(/(([A-Z0-9]+)_F_([A-Z0-9_]+))/) {
259 next unless exists $csrc{$2}; 335 next unless exists $csrc{$2};
260 next if($1 eq "BIO_F_BUFFER_CTX"); 336 next if($1 eq "BIO_F_BUFFER_CTX");
@@ -264,6 +340,7 @@ foreach $file (@source) {
264 $fnew{$2}++; 340 $fnew{$2}++;
265 } 341 }
266 $notrans{$1} = 1 unless exists $ftrans{$3}; 342 $notrans{$1} = 1 unless exists $ftrans{$3};
343 print STDERR "Function: $1\t= $fcodes{$1} (lib: $2, name: $3)\n" if $debug;
267 } 344 }
268 if(/(([A-Z0-9]+)_R_[A-Z0-9_]+)/) { 345 if(/(([A-Z0-9]+)_R_[A-Z0-9_]+)/) {
269 next unless exists $csrc{$2}; 346 next unless exists $csrc{$2};
@@ -272,6 +349,7 @@ foreach $file (@source) {
272 $rcodes{$1} = "X"; 349 $rcodes{$1} = "X";
273 $rnew{$2}++; 350 $rnew{$2}++;
274 } 351 }
352 print STDERR "Reason: $1\t= $rcodes{$1} (lib: $2)\n" if $debug;
275 } 353 }
276 } 354 }
277 close IN; 355 close IN;
@@ -313,7 +391,7 @@ foreach $lib (keys %csrc)
313 } else { 391 } else {
314 push @out, 392 push @out,
315"/* ====================================================================\n", 393"/* ====================================================================\n",
316" * Copyright (c) 2001-2008 The OpenSSL Project. All rights reserved.\n", 394" * Copyright (c) 2001-2010 The OpenSSL Project. All rights reserved.\n",
317" *\n", 395" *\n",
318" * Redistribution and use in source and binary forms, with or without\n", 396" * Redistribution and use in source and binary forms, with or without\n",
319" * modification, are permitted provided that the following conditions\n", 397" * modification, are permitted provided that the following conditions\n",
@@ -369,6 +447,10 @@ foreach $lib (keys %csrc)
369"#ifndef HEADER_${lib}_ERR_H\n", 447"#ifndef HEADER_${lib}_ERR_H\n",
370"#define HEADER_${lib}_ERR_H\n", 448"#define HEADER_${lib}_ERR_H\n",
371"\n", 449"\n",
450"#ifdef __cplusplus\n",
451"extern \"C\" {\n",
452"#endif\n",
453"\n",
372"/* BEGIN ERROR CODES */\n"; 454"/* BEGIN ERROR CODES */\n";
373 } 455 }
374 open (OUT, ">$hfile") || die "Can't Open File $hfile for writing\n"; 456 open (OUT, ">$hfile") || die "Can't Open File $hfile for writing\n";
@@ -455,14 +537,21 @@ EOF
455 if (/\b(${lib}_R_\w*)\b.*\"(.*)\"/) { 537 if (/\b(${lib}_R_\w*)\b.*\"(.*)\"/) {
456 $err_reason_strings{$1} = $2; 538 $err_reason_strings{$1} = $2;
457 } 539 }
540 if (/\b${lib}_F_(\w*)\b.*\"(.*)\"/) {
541 if (!exists $ftrans{$1} && ($1 ne $2)) {
542 print STDERR "WARNING: Mismatched function string $2\n";
543 $ftrans{$1} = $2;
544 }
545 }
458 } 546 }
459 close(IN); 547 close(IN);
460 } 548 }
461 549
550
462 my $hincf; 551 my $hincf;
463 if($static) { 552 if($static) {
464 $hfile =~ /([^\/]+)$/; 553 $hfile =~ /([^\/]+)$/;
465 $hincf = "<openssl/$1>"; 554 $hincf = "<${hprefix}$1>";
466 } else { 555 } else {
467 $hincf = "\"$hfile\""; 556 $hincf = "\"$hfile\"";
468 } 557 }
@@ -487,7 +576,7 @@ EOF
487 print OUT <<"EOF"; 576 print OUT <<"EOF";
488/* $cfile */ 577/* $cfile */
489/* ==================================================================== 578/* ====================================================================
490 * Copyright (c) 1999-2008 The OpenSSL Project. All rights reserved. 579 * Copyright (c) 1999-2010 The OpenSSL Project. All rights reserved.
491 * 580 *
492 * Redistribution and use in source and binary forms, with or without 581 * Redistribution and use in source and binary forms, with or without
493 * modification, are permitted provided that the following conditions 582 * modification, are permitted provided that the following conditions
@@ -713,3 +802,9 @@ if($debug && defined(@runref) ) {
713 print STDERR "$_\n"; 802 print STDERR "$_\n";
714 } 803 }
715} 804}
805
806if($errcount) {
807 print STDERR "There were errors, failing...\n\n";
808 exit $errcount;
809}
810
diff --git a/src/lib/libcrypto/util/mkstack.pl b/src/lib/libcrypto/util/mkstack.pl
index 2a968f395f..6a43757c95 100644
--- a/src/lib/libcrypto/util/mkstack.pl
+++ b/src/lib/libcrypto/util/mkstack.pl
@@ -21,7 +21,7 @@ while (@ARGV) {
21} 21}
22 22
23 23
24@source = (<crypto/*.[ch]>, <crypto/*/*.[ch]>, <ssl/*.[ch]>); 24@source = (<crypto/*.[ch]>, <crypto/*/*.[ch]>, <ssl/*.[ch]>, <apps/*.[ch]>);
25foreach $file (@source) { 25foreach $file (@source) {
26 next if -l $file; 26 next if -l $file;
27 27
@@ -31,11 +31,19 @@ foreach $file (@source) {
31 while(<IN>) { 31 while(<IN>) {
32 if (/^DECLARE_STACK_OF\(([^)]+)\)/) { 32 if (/^DECLARE_STACK_OF\(([^)]+)\)/) {
33 push @stacklst, $1; 33 push @stacklst, $1;
34 } if (/^DECLARE_ASN1_SET_OF\(([^)]+)\)/) { 34 }
35 if (/^DECLARE_SPECIAL_STACK_OF\(([^,\s]+)\s*,\s*([^>\s]+)\)/) {
36 push @sstacklst, [$1, $2];
37 }
38 if (/^DECLARE_ASN1_SET_OF\(([^)]+)\)/) {
35 push @asn1setlst, $1; 39 push @asn1setlst, $1;
36 } if (/^DECLARE_PKCS12_STACK_OF\(([^)]+)\)/) { 40 }
41 if (/^DECLARE_PKCS12_STACK_OF\(([^)]+)\)/) {
37 push @p12stklst, $1; 42 push @p12stklst, $1;
38 } 43 }
44 if (/^DECLARE_LHASH_OF\(([^)]+)\)/) {
45 push @lhashlst, $1;
46 }
39 } 47 }
40 close(IN); 48 close(IN);
41} 49}
@@ -65,7 +73,7 @@ while(<IN>) {
65 foreach $type_thing (sort @stacklst) { 73 foreach $type_thing (sort @stacklst) {
66 $new_stackfile .= <<EOF; 74 $new_stackfile .= <<EOF;
67 75
68#define sk_${type_thing}_new(st) SKM_sk_new($type_thing, (st)) 76#define sk_${type_thing}_new(cmp) SKM_sk_new($type_thing, (cmp))
69#define sk_${type_thing}_new_null() SKM_sk_new_null($type_thing) 77#define sk_${type_thing}_new_null() SKM_sk_new_null($type_thing)
70#define sk_${type_thing}_free(st) SKM_sk_free($type_thing, (st)) 78#define sk_${type_thing}_free(st) SKM_sk_free($type_thing, (st))
71#define sk_${type_thing}_num(st) SKM_sk_num($type_thing, (st)) 79#define sk_${type_thing}_num(st) SKM_sk_num($type_thing, (st))
@@ -88,6 +96,39 @@ while(<IN>) {
88#define sk_${type_thing}_is_sorted(st) SKM_sk_is_sorted($type_thing, (st)) 96#define sk_${type_thing}_is_sorted(st) SKM_sk_is_sorted($type_thing, (st))
89EOF 97EOF
90 } 98 }
99
100 foreach $type_thing (sort @sstacklst) {
101 my $t1 = $type_thing->[0];
102 my $t2 = $type_thing->[1];
103 $new_stackfile .= <<EOF;
104
105#define sk_${t1}_new(cmp) ((STACK_OF($t1) *)sk_new(CHECKED_SK_CMP_FUNC($t2, cmp)))
106#define sk_${t1}_new_null() ((STACK_OF($t1) *)sk_new_null())
107#define sk_${t1}_push(st, val) sk_push(CHECKED_PTR_OF(STACK_OF($t1), st), CHECKED_PTR_OF($t2, val))
108#define sk_${t1}_find(st, val) sk_find(CHECKED_PTR_OF(STACK_OF($t1), st), CHECKED_PTR_OF($t2, val))
109#define sk_${t1}_value(st, i) (($t1)sk_value(CHECKED_PTR_OF(STACK_OF($t1), st), i))
110#define sk_${t1}_num(st) SKM_sk_num($t1, st)
111#define sk_${t1}_pop_free(st, free_func) sk_pop_free(CHECKED_PTR_OF(STACK_OF($t1), st), CHECKED_SK_FREE_FUNC2($t1, free_func))
112#define sk_${t1}_insert(st, val, i) sk_insert(CHECKED_PTR_OF(STACK_OF($t1), st), CHECKED_PTR_OF($t2, val), i)
113#define sk_${t1}_free(st) SKM_sk_free(${t1}, st)
114#define sk_${t1}_set(st, i, val) sk_set((_STACK *)CHECKED_PTR_OF(STACK_OF($t1), st), i, CHECKED_PTR_OF($t2, val))
115#define sk_${t1}_zero(st) SKM_sk_zero($t1, (st))
116#define sk_${t1}_unshift(st, val) sk_unshift((_STACK *)CHECKED_PTR_OF(STACK_OF($t1), st), CHECKED_PTR_OF($t2, val))
117#define sk_${t1}_find_ex(st, val) sk_find_ex((_STACK *)CHECKED_CONST_PTR_OF(STACK_OF($t1), st), CHECKED_CONST_PTR_OF($t2, val))
118#define sk_${t1}_delete(st, i) SKM_sk_delete($t1, (st), (i))
119#define sk_${t1}_delete_ptr(st, ptr) ($t1 *)sk_delete_ptr((_STACK *)CHECKED_PTR_OF(STACK_OF($t1), st), CHECKED_PTR_OF($t2, ptr))
120#define sk_${t1}_set_cmp_func(st, cmp) \\
121 ((int (*)(const $t2 * const *,const $t2 * const *)) \\
122 sk_set_cmp_func((_STACK *)CHECKED_PTR_OF(STACK_OF($t1), st), CHECKED_SK_CMP_FUNC($t2, cmp)))
123#define sk_${t1}_dup(st) SKM_sk_dup($t1, st)
124#define sk_${t1}_shift(st) SKM_sk_shift($t1, (st))
125#define sk_${t1}_pop(st) ($t2 *)sk_pop((_STACK *)CHECKED_PTR_OF(STACK_OF($t1), st))
126#define sk_${t1}_sort(st) SKM_sk_sort($t1, (st))
127#define sk_${t1}_is_sorted(st) SKM_sk_is_sorted($t1, (st))
128
129EOF
130 }
131
91 foreach $type_thing (sort @asn1setlst) { 132 foreach $type_thing (sort @asn1setlst) {
92 $new_stackfile .= <<EOF; 133 $new_stackfile .= <<EOF;
93 134
@@ -108,6 +149,31 @@ EOF
108 SKM_PKCS12_decrypt_d2i($type_thing, (algor), (d2i_func), (free_func), (pass), (passlen), (oct), (seq)) 149 SKM_PKCS12_decrypt_d2i($type_thing, (algor), (d2i_func), (free_func), (pass), (passlen), (oct), (seq))
109EOF 150EOF
110 } 151 }
152
153 foreach $type_thing (sort @lhashlst) {
154 my $lc_tt = lc $type_thing;
155 $new_stackfile .= <<EOF;
156
157#define lh_${type_thing}_new() LHM_lh_new(${type_thing},${lc_tt})
158#define lh_${type_thing}_insert(lh,inst) LHM_lh_insert(${type_thing},lh,inst)
159#define lh_${type_thing}_retrieve(lh,inst) LHM_lh_retrieve(${type_thing},lh,inst)
160#define lh_${type_thing}_delete(lh,inst) LHM_lh_delete(${type_thing},lh,inst)
161#define lh_${type_thing}_doall(lh,fn) LHM_lh_doall(${type_thing},lh,fn)
162#define lh_${type_thing}_doall_arg(lh,fn,arg_type,arg) \\
163 LHM_lh_doall_arg(${type_thing},lh,fn,arg_type,arg)
164#define lh_${type_thing}_error(lh) LHM_lh_error(${type_thing},lh)
165#define lh_${type_thing}_num_items(lh) LHM_lh_num_items(${type_thing},lh)
166#define lh_${type_thing}_down_load(lh) LHM_lh_down_load(${type_thing},lh)
167#define lh_${type_thing}_node_stats_bio(lh,out) \\
168 LHM_lh_node_stats_bio(${type_thing},lh,out)
169#define lh_${type_thing}_node_usage_stats_bio(lh,out) \\
170 LHM_lh_node_usage_stats_bio(${type_thing},lh,out)
171#define lh_${type_thing}_stats_bio(lh,out) \\
172 LHM_lh_stats_bio(${type_thing},lh,out)
173#define lh_${type_thing}_free(lh) LHM_lh_free(${type_thing},lh)
174EOF
175 }
176
111 $new_stackfile .= "/* End of util/mkstack.pl block, you may now edit :-) */\n"; 177 $new_stackfile .= "/* End of util/mkstack.pl block, you may now edit :-) */\n";
112 $inside_block = 2; 178 $inside_block = 2;
113} 179}
diff --git a/src/lib/libcrypto/whrlpool/asm/wp-mmx.pl b/src/lib/libcrypto/whrlpool/asm/wp-mmx.pl
new file mode 100644
index 0000000000..32cf16380b
--- /dev/null
+++ b/src/lib/libcrypto/whrlpool/asm/wp-mmx.pl
@@ -0,0 +1,493 @@
1#!/usr/bin/env perl
2#
3# ====================================================================
4# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
5# project. Rights for redistribution and usage in source and binary
6# forms are granted according to the OpenSSL license.
7# ====================================================================
8#
9# whirlpool_block_mmx implementation.
10#
11*SCALE=\(2); # 2 or 8, that is the question:-) Value of 8 results
12# in 16KB large table, which is tough on L1 cache, but eliminates
13# unaligned references to it. Value of 2 results in 4KB table, but
14# 7/8 of references to it are unaligned. AMD cores seem to be
15# allergic to the latter, while Intel ones - to former [see the
16# table]. I stick to value of 2 for two reasons: 1. smaller table
17# minimizes cache trashing and thus mitigates the hazard of side-
18# channel leakage similar to AES cache-timing one; 2. performance
19# gap among different µ-archs is smaller.
20#
21# Performance table lists rounded amounts of CPU cycles spent by
22# whirlpool_block_mmx routine on single 64 byte input block, i.e.
23# smaller is better and asymptotic throughput can be estimated by
24# multiplying 64 by CPU clock frequency and dividing by relevant
25# value from the given table:
26#
27# $SCALE=2/8 icc8 gcc3
28# Intel P4 3200/4600 4600(*) 6400
29# Intel PIII 2900/3000 4900 5400
30# AMD K[78] 2500/1800 9900 8200(**)
31#
32# (*) I've sketched even non-MMX assembler, but for the record
33# I've failed to beat the Intel compiler on P4, without using
34# MMX that is...
35# (**) ... on AMD on the other hand non-MMX assembler was observed
36# to perform significantly better, but I figured this MMX
37# implementation is even faster anyway, so why bother? As for
38# pre-MMX AMD core[s], the improvement coefficient is more
39# than likely to vary anyway and I don't know how. But the
40# least I know is that gcc-generated code compiled with
41# -DL_ENDIAN and -DOPENSSL_SMALL_FOOTPRINT [see C module for
42# details] and optimized for Pentium was observed to perform
43# *better* on Pentium 100 than unrolled non-MMX assembler
44# loop... So we just say that I don't know if maintaining
45# non-MMX implementation would actually pay off, but till
46# opposite is proved "unlikely" is assumed.
47
48$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
49push(@INC,"${dir}","${dir}../../perlasm");
50require "x86asm.pl";
51
52&asm_init($ARGV[0],"wp-mmx.pl");
53
54sub L() { &data_byte(@_); }
55sub LL()
56{ if ($SCALE==2) { &data_byte(@_); &data_byte(@_); }
57 elsif ($SCALE==8) { for ($i=0;$i<8;$i++) {
58 &data_byte(@_);
59 unshift(@_,pop(@_));
60 }
61 }
62 else { die "unvalid SCALE value"; }
63}
64
65sub scale()
66{ if ($SCALE==2) { &lea(@_[0],&DWP(0,@_[1],@_[1])); }
67 elsif ($SCALE==8) { &lea(@_[0],&DWP(0,"",@_[1],8)); }
68 else { die "unvalid SCALE value"; }
69}
70
71sub row()
72{ if ($SCALE==2) { ((8-shift)&7); }
73 elsif ($SCALE==8) { (8*shift); }
74 else { die "unvalid SCALE value"; }
75}
76
77$tbl="ebp";
78@mm=("mm0","mm1","mm2","mm3","mm4","mm5","mm6","mm7");
79
80&function_begin_B("whirlpool_block_mmx");
81 &push ("ebp");
82 &push ("ebx");
83 &push ("esi");
84 &push ("edi");
85
86 &mov ("esi",&wparam(0)); # hash value
87 &mov ("edi",&wparam(1)); # input data stream
88 &mov ("ebp",&wparam(2)); # number of chunks in input
89
90 &mov ("eax","esp"); # copy stack pointer
91 &sub ("esp",128+20); # allocate frame
92 &and ("esp",-64); # align for cache-line
93
94 &lea ("ebx",&DWP(128,"esp"));
95 &mov (&DWP(0,"ebx"),"esi"); # save parameter block
96 &mov (&DWP(4,"ebx"),"edi");
97 &mov (&DWP(8,"ebx"),"ebp");
98 &mov (&DWP(16,"ebx"),"eax"); # saved stack pointer
99
100 &call (&label("pic_point"));
101&set_label("pic_point");
102 &blindpop($tbl);
103 &lea ($tbl,&DWP(&label("table")."-".&label("pic_point"),$tbl));
104
105 &xor ("ecx","ecx");
106 &xor ("edx","edx");
107
108 for($i=0;$i<8;$i++) { &movq(@mm[$i],&QWP($i*8,"esi")); } # L=H
109&set_label("outerloop");
110 for($i=0;$i<8;$i++) { &movq(&QWP($i*8,"esp"),@mm[$i]); } # K=L
111 for($i=0;$i<8;$i++) { &pxor(@mm[$i],&QWP($i*8,"edi")); } # L^=inp
112 for($i=0;$i<8;$i++) { &movq(&QWP(64+$i*8,"esp"),@mm[$i]); } # S=L
113
114 &xor ("esi","esi");
115 &mov (&DWP(12,"ebx"),"esi"); # zero round counter
116
117&set_label("round",16);
118 &movq (@mm[0],&QWP(2048*$SCALE,$tbl,"esi",8)); # rc[r]
119 &mov ("eax",&DWP(0,"esp"));
120 &mov ("ebx",&DWP(4,"esp"));
121for($i=0;$i<8;$i++) {
122 my $func = ($i==0)? movq : pxor;
123 &movb (&LB("ecx"),&LB("eax"));
124 &movb (&LB("edx"),&HB("eax"));
125 &scale ("esi","ecx");
126 &scale ("edi","edx");
127 &shr ("eax",16);
128 &pxor (@mm[0],&QWP(&row(0),$tbl,"esi",8));
129 &$func (@mm[1],&QWP(&row(1),$tbl,"edi",8));
130 &movb (&LB("ecx"),&LB("eax"));
131 &movb (&LB("edx"),&HB("eax"));
132 &mov ("eax",&DWP(($i+1)*8,"esp"));
133 &scale ("esi","ecx");
134 &scale ("edi","edx");
135 &$func (@mm[2],&QWP(&row(2),$tbl,"esi",8));
136 &$func (@mm[3],&QWP(&row(3),$tbl,"edi",8));
137 &movb (&LB("ecx"),&LB("ebx"));
138 &movb (&LB("edx"),&HB("ebx"));
139 &scale ("esi","ecx");
140 &scale ("edi","edx");
141 &shr ("ebx",16);
142 &$func (@mm[4],&QWP(&row(4),$tbl,"esi",8));
143 &$func (@mm[5],&QWP(&row(5),$tbl,"edi",8));
144 &movb (&LB("ecx"),&LB("ebx"));
145 &movb (&LB("edx"),&HB("ebx"));
146 &mov ("ebx",&DWP(($i+1)*8+4,"esp"));
147 &scale ("esi","ecx");
148 &scale ("edi","edx");
149 &$func (@mm[6],&QWP(&row(6),$tbl,"esi",8));
150 &$func (@mm[7],&QWP(&row(7),$tbl,"edi",8));
151 push(@mm,shift(@mm));
152}
153
154 for($i=0;$i<8;$i++) { &movq(&QWP($i*8,"esp"),@mm[$i]); } # K=L
155
156for($i=0;$i<8;$i++) {
157 &movb (&LB("ecx"),&LB("eax"));
158 &movb (&LB("edx"),&HB("eax"));
159 &scale ("esi","ecx");
160 &scale ("edi","edx");
161 &shr ("eax",16);
162 &pxor (@mm[0],&QWP(&row(0),$tbl,"esi",8));
163 &pxor (@mm[1],&QWP(&row(1),$tbl,"edi",8));
164 &movb (&LB("ecx"),&LB("eax"));
165 &movb (&LB("edx"),&HB("eax"));
166 &mov ("eax",&DWP(64+($i+1)*8,"esp")) if ($i<7);
167 &scale ("esi","ecx");
168 &scale ("edi","edx");
169 &pxor (@mm[2],&QWP(&row(2),$tbl,"esi",8));
170 &pxor (@mm[3],&QWP(&row(3),$tbl,"edi",8));
171 &movb (&LB("ecx"),&LB("ebx"));
172 &movb (&LB("edx"),&HB("ebx"));
173 &scale ("esi","ecx");
174 &scale ("edi","edx");
175 &shr ("ebx",16);
176 &pxor (@mm[4],&QWP(&row(4),$tbl,"esi",8));
177 &pxor (@mm[5],&QWP(&row(5),$tbl,"edi",8));
178 &movb (&LB("ecx"),&LB("ebx"));
179 &movb (&LB("edx"),&HB("ebx"));
180 &mov ("ebx",&DWP(64+($i+1)*8+4,"esp")) if ($i<7);
181 &scale ("esi","ecx");
182 &scale ("edi","edx");
183 &pxor (@mm[6],&QWP(&row(6),$tbl,"esi",8));
184 &pxor (@mm[7],&QWP(&row(7),$tbl,"edi",8));
185 push(@mm,shift(@mm));
186}
187 &lea ("ebx",&DWP(128,"esp"));
188 &mov ("esi",&DWP(12,"ebx")); # pull round counter
189 &add ("esi",1);
190 &cmp ("esi",10);
191 &je (&label("roundsdone"));
192
193 &mov (&DWP(12,"ebx"),"esi"); # update round counter
194 for($i=0;$i<8;$i++) { &movq(&QWP(64+$i*8,"esp"),@mm[$i]); } # S=L
195 &jmp (&label("round"));
196
197&set_label("roundsdone",16);
198 &mov ("esi",&DWP(0,"ebx")); # reload argument block
199 &mov ("edi",&DWP(4,"ebx"));
200 &mov ("eax",&DWP(8,"ebx"));
201
202 for($i=0;$i<8;$i++) { &pxor(@mm[$i],&QWP($i*8,"edi")); } # L^=inp
203 for($i=0;$i<8;$i++) { &pxor(@mm[$i],&QWP($i*8,"esi")); } # L^=H
204 for($i=0;$i<8;$i++) { &movq(&QWP($i*8,"esi"),@mm[$i]); } # H=L
205
206 &lea ("edi",&DWP(64,"edi")); # inp+=64
207 &sub ("eax",1); # num--
208 &jz (&label("alldone"));
209 &mov (&DWP(4,"ebx"),"edi"); # update argument block
210 &mov (&DWP(8,"ebx"),"eax");
211 &jmp (&label("outerloop"));
212
213&set_label("alldone");
214 &emms ();
215 &mov ("esp",&DWP(16,"ebx")); # restore saved stack pointer
216 &pop ("edi");
217 &pop ("esi");
218 &pop ("ebx");
219 &pop ("ebp");
220 &ret ();
221
222&align(64);
223&set_label("table");
224 &LL(0x18,0x18,0x60,0x18,0xc0,0x78,0x30,0xd8);
225 &LL(0x23,0x23,0x8c,0x23,0x05,0xaf,0x46,0x26);
226 &LL(0xc6,0xc6,0x3f,0xc6,0x7e,0xf9,0x91,0xb8);
227 &LL(0xe8,0xe8,0x87,0xe8,0x13,0x6f,0xcd,0xfb);
228 &LL(0x87,0x87,0x26,0x87,0x4c,0xa1,0x13,0xcb);
229 &LL(0xb8,0xb8,0xda,0xb8,0xa9,0x62,0x6d,0x11);
230 &LL(0x01,0x01,0x04,0x01,0x08,0x05,0x02,0x09);
231 &LL(0x4f,0x4f,0x21,0x4f,0x42,0x6e,0x9e,0x0d);
232 &LL(0x36,0x36,0xd8,0x36,0xad,0xee,0x6c,0x9b);
233 &LL(0xa6,0xa6,0xa2,0xa6,0x59,0x04,0x51,0xff);
234 &LL(0xd2,0xd2,0x6f,0xd2,0xde,0xbd,0xb9,0x0c);
235 &LL(0xf5,0xf5,0xf3,0xf5,0xfb,0x06,0xf7,0x0e);
236 &LL(0x79,0x79,0xf9,0x79,0xef,0x80,0xf2,0x96);
237 &LL(0x6f,0x6f,0xa1,0x6f,0x5f,0xce,0xde,0x30);
238 &LL(0x91,0x91,0x7e,0x91,0xfc,0xef,0x3f,0x6d);
239 &LL(0x52,0x52,0x55,0x52,0xaa,0x07,0xa4,0xf8);
240 &LL(0x60,0x60,0x9d,0x60,0x27,0xfd,0xc0,0x47);
241 &LL(0xbc,0xbc,0xca,0xbc,0x89,0x76,0x65,0x35);
242 &LL(0x9b,0x9b,0x56,0x9b,0xac,0xcd,0x2b,0x37);
243 &LL(0x8e,0x8e,0x02,0x8e,0x04,0x8c,0x01,0x8a);
244 &LL(0xa3,0xa3,0xb6,0xa3,0x71,0x15,0x5b,0xd2);
245 &LL(0x0c,0x0c,0x30,0x0c,0x60,0x3c,0x18,0x6c);
246 &LL(0x7b,0x7b,0xf1,0x7b,0xff,0x8a,0xf6,0x84);
247 &LL(0x35,0x35,0xd4,0x35,0xb5,0xe1,0x6a,0x80);
248 &LL(0x1d,0x1d,0x74,0x1d,0xe8,0x69,0x3a,0xf5);
249 &LL(0xe0,0xe0,0xa7,0xe0,0x53,0x47,0xdd,0xb3);
250 &LL(0xd7,0xd7,0x7b,0xd7,0xf6,0xac,0xb3,0x21);
251 &LL(0xc2,0xc2,0x2f,0xc2,0x5e,0xed,0x99,0x9c);
252 &LL(0x2e,0x2e,0xb8,0x2e,0x6d,0x96,0x5c,0x43);
253 &LL(0x4b,0x4b,0x31,0x4b,0x62,0x7a,0x96,0x29);
254 &LL(0xfe,0xfe,0xdf,0xfe,0xa3,0x21,0xe1,0x5d);
255 &LL(0x57,0x57,0x41,0x57,0x82,0x16,0xae,0xd5);
256 &LL(0x15,0x15,0x54,0x15,0xa8,0x41,0x2a,0xbd);
257 &LL(0x77,0x77,0xc1,0x77,0x9f,0xb6,0xee,0xe8);
258 &LL(0x37,0x37,0xdc,0x37,0xa5,0xeb,0x6e,0x92);
259 &LL(0xe5,0xe5,0xb3,0xe5,0x7b,0x56,0xd7,0x9e);
260 &LL(0x9f,0x9f,0x46,0x9f,0x8c,0xd9,0x23,0x13);
261 &LL(0xf0,0xf0,0xe7,0xf0,0xd3,0x17,0xfd,0x23);
262 &LL(0x4a,0x4a,0x35,0x4a,0x6a,0x7f,0x94,0x20);
263 &LL(0xda,0xda,0x4f,0xda,0x9e,0x95,0xa9,0x44);
264 &LL(0x58,0x58,0x7d,0x58,0xfa,0x25,0xb0,0xa2);
265 &LL(0xc9,0xc9,0x03,0xc9,0x06,0xca,0x8f,0xcf);
266 &LL(0x29,0x29,0xa4,0x29,0x55,0x8d,0x52,0x7c);
267 &LL(0x0a,0x0a,0x28,0x0a,0x50,0x22,0x14,0x5a);
268 &LL(0xb1,0xb1,0xfe,0xb1,0xe1,0x4f,0x7f,0x50);
269 &LL(0xa0,0xa0,0xba,0xa0,0x69,0x1a,0x5d,0xc9);
270 &LL(0x6b,0x6b,0xb1,0x6b,0x7f,0xda,0xd6,0x14);
271 &LL(0x85,0x85,0x2e,0x85,0x5c,0xab,0x17,0xd9);
272 &LL(0xbd,0xbd,0xce,0xbd,0x81,0x73,0x67,0x3c);
273 &LL(0x5d,0x5d,0x69,0x5d,0xd2,0x34,0xba,0x8f);
274 &LL(0x10,0x10,0x40,0x10,0x80,0x50,0x20,0x90);
275 &LL(0xf4,0xf4,0xf7,0xf4,0xf3,0x03,0xf5,0x07);
276 &LL(0xcb,0xcb,0x0b,0xcb,0x16,0xc0,0x8b,0xdd);
277 &LL(0x3e,0x3e,0xf8,0x3e,0xed,0xc6,0x7c,0xd3);
278 &LL(0x05,0x05,0x14,0x05,0x28,0x11,0x0a,0x2d);
279 &LL(0x67,0x67,0x81,0x67,0x1f,0xe6,0xce,0x78);
280 &LL(0xe4,0xe4,0xb7,0xe4,0x73,0x53,0xd5,0x97);
281 &LL(0x27,0x27,0x9c,0x27,0x25,0xbb,0x4e,0x02);
282 &LL(0x41,0x41,0x19,0x41,0x32,0x58,0x82,0x73);
283 &LL(0x8b,0x8b,0x16,0x8b,0x2c,0x9d,0x0b,0xa7);
284 &LL(0xa7,0xa7,0xa6,0xa7,0x51,0x01,0x53,0xf6);
285 &LL(0x7d,0x7d,0xe9,0x7d,0xcf,0x94,0xfa,0xb2);
286 &LL(0x95,0x95,0x6e,0x95,0xdc,0xfb,0x37,0x49);
287 &LL(0xd8,0xd8,0x47,0xd8,0x8e,0x9f,0xad,0x56);
288 &LL(0xfb,0xfb,0xcb,0xfb,0x8b,0x30,0xeb,0x70);
289 &LL(0xee,0xee,0x9f,0xee,0x23,0x71,0xc1,0xcd);
290 &LL(0x7c,0x7c,0xed,0x7c,0xc7,0x91,0xf8,0xbb);
291 &LL(0x66,0x66,0x85,0x66,0x17,0xe3,0xcc,0x71);
292 &LL(0xdd,0xdd,0x53,0xdd,0xa6,0x8e,0xa7,0x7b);
293 &LL(0x17,0x17,0x5c,0x17,0xb8,0x4b,0x2e,0xaf);
294 &LL(0x47,0x47,0x01,0x47,0x02,0x46,0x8e,0x45);
295 &LL(0x9e,0x9e,0x42,0x9e,0x84,0xdc,0x21,0x1a);
296 &LL(0xca,0xca,0x0f,0xca,0x1e,0xc5,0x89,0xd4);
297 &LL(0x2d,0x2d,0xb4,0x2d,0x75,0x99,0x5a,0x58);
298 &LL(0xbf,0xbf,0xc6,0xbf,0x91,0x79,0x63,0x2e);
299 &LL(0x07,0x07,0x1c,0x07,0x38,0x1b,0x0e,0x3f);
300 &LL(0xad,0xad,0x8e,0xad,0x01,0x23,0x47,0xac);
301 &LL(0x5a,0x5a,0x75,0x5a,0xea,0x2f,0xb4,0xb0);
302 &LL(0x83,0x83,0x36,0x83,0x6c,0xb5,0x1b,0xef);
303 &LL(0x33,0x33,0xcc,0x33,0x85,0xff,0x66,0xb6);
304 &LL(0x63,0x63,0x91,0x63,0x3f,0xf2,0xc6,0x5c);
305 &LL(0x02,0x02,0x08,0x02,0x10,0x0a,0x04,0x12);
306 &LL(0xaa,0xaa,0x92,0xaa,0x39,0x38,0x49,0x93);
307 &LL(0x71,0x71,0xd9,0x71,0xaf,0xa8,0xe2,0xde);
308 &LL(0xc8,0xc8,0x07,0xc8,0x0e,0xcf,0x8d,0xc6);
309 &LL(0x19,0x19,0x64,0x19,0xc8,0x7d,0x32,0xd1);
310 &LL(0x49,0x49,0x39,0x49,0x72,0x70,0x92,0x3b);
311 &LL(0xd9,0xd9,0x43,0xd9,0x86,0x9a,0xaf,0x5f);
312 &LL(0xf2,0xf2,0xef,0xf2,0xc3,0x1d,0xf9,0x31);
313 &LL(0xe3,0xe3,0xab,0xe3,0x4b,0x48,0xdb,0xa8);
314 &LL(0x5b,0x5b,0x71,0x5b,0xe2,0x2a,0xb6,0xb9);
315 &LL(0x88,0x88,0x1a,0x88,0x34,0x92,0x0d,0xbc);
316 &LL(0x9a,0x9a,0x52,0x9a,0xa4,0xc8,0x29,0x3e);
317 &LL(0x26,0x26,0x98,0x26,0x2d,0xbe,0x4c,0x0b);
318 &LL(0x32,0x32,0xc8,0x32,0x8d,0xfa,0x64,0xbf);
319 &LL(0xb0,0xb0,0xfa,0xb0,0xe9,0x4a,0x7d,0x59);
320 &LL(0xe9,0xe9,0x83,0xe9,0x1b,0x6a,0xcf,0xf2);
321 &LL(0x0f,0x0f,0x3c,0x0f,0x78,0x33,0x1e,0x77);
322 &LL(0xd5,0xd5,0x73,0xd5,0xe6,0xa6,0xb7,0x33);
323 &LL(0x80,0x80,0x3a,0x80,0x74,0xba,0x1d,0xf4);
324 &LL(0xbe,0xbe,0xc2,0xbe,0x99,0x7c,0x61,0x27);
325 &LL(0xcd,0xcd,0x13,0xcd,0x26,0xde,0x87,0xeb);
326 &LL(0x34,0x34,0xd0,0x34,0xbd,0xe4,0x68,0x89);
327 &LL(0x48,0x48,0x3d,0x48,0x7a,0x75,0x90,0x32);
328 &LL(0xff,0xff,0xdb,0xff,0xab,0x24,0xe3,0x54);
329 &LL(0x7a,0x7a,0xf5,0x7a,0xf7,0x8f,0xf4,0x8d);
330 &LL(0x90,0x90,0x7a,0x90,0xf4,0xea,0x3d,0x64);
331 &LL(0x5f,0x5f,0x61,0x5f,0xc2,0x3e,0xbe,0x9d);
332 &LL(0x20,0x20,0x80,0x20,0x1d,0xa0,0x40,0x3d);
333 &LL(0x68,0x68,0xbd,0x68,0x67,0xd5,0xd0,0x0f);
334 &LL(0x1a,0x1a,0x68,0x1a,0xd0,0x72,0x34,0xca);
335 &LL(0xae,0xae,0x82,0xae,0x19,0x2c,0x41,0xb7);
336 &LL(0xb4,0xb4,0xea,0xb4,0xc9,0x5e,0x75,0x7d);
337 &LL(0x54,0x54,0x4d,0x54,0x9a,0x19,0xa8,0xce);
338 &LL(0x93,0x93,0x76,0x93,0xec,0xe5,0x3b,0x7f);
339 &LL(0x22,0x22,0x88,0x22,0x0d,0xaa,0x44,0x2f);
340 &LL(0x64,0x64,0x8d,0x64,0x07,0xe9,0xc8,0x63);
341 &LL(0xf1,0xf1,0xe3,0xf1,0xdb,0x12,0xff,0x2a);
342 &LL(0x73,0x73,0xd1,0x73,0xbf,0xa2,0xe6,0xcc);
343 &LL(0x12,0x12,0x48,0x12,0x90,0x5a,0x24,0x82);
344 &LL(0x40,0x40,0x1d,0x40,0x3a,0x5d,0x80,0x7a);
345 &LL(0x08,0x08,0x20,0x08,0x40,0x28,0x10,0x48);
346 &LL(0xc3,0xc3,0x2b,0xc3,0x56,0xe8,0x9b,0x95);
347 &LL(0xec,0xec,0x97,0xec,0x33,0x7b,0xc5,0xdf);
348 &LL(0xdb,0xdb,0x4b,0xdb,0x96,0x90,0xab,0x4d);
349 &LL(0xa1,0xa1,0xbe,0xa1,0x61,0x1f,0x5f,0xc0);
350 &LL(0x8d,0x8d,0x0e,0x8d,0x1c,0x83,0x07,0x91);
351 &LL(0x3d,0x3d,0xf4,0x3d,0xf5,0xc9,0x7a,0xc8);
352 &LL(0x97,0x97,0x66,0x97,0xcc,0xf1,0x33,0x5b);
353 &LL(0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00);
354 &LL(0xcf,0xcf,0x1b,0xcf,0x36,0xd4,0x83,0xf9);
355 &LL(0x2b,0x2b,0xac,0x2b,0x45,0x87,0x56,0x6e);
356 &LL(0x76,0x76,0xc5,0x76,0x97,0xb3,0xec,0xe1);
357 &LL(0x82,0x82,0x32,0x82,0x64,0xb0,0x19,0xe6);
358 &LL(0xd6,0xd6,0x7f,0xd6,0xfe,0xa9,0xb1,0x28);
359 &LL(0x1b,0x1b,0x6c,0x1b,0xd8,0x77,0x36,0xc3);
360 &LL(0xb5,0xb5,0xee,0xb5,0xc1,0x5b,0x77,0x74);
361 &LL(0xaf,0xaf,0x86,0xaf,0x11,0x29,0x43,0xbe);
362 &LL(0x6a,0x6a,0xb5,0x6a,0x77,0xdf,0xd4,0x1d);
363 &LL(0x50,0x50,0x5d,0x50,0xba,0x0d,0xa0,0xea);
364 &LL(0x45,0x45,0x09,0x45,0x12,0x4c,0x8a,0x57);
365 &LL(0xf3,0xf3,0xeb,0xf3,0xcb,0x18,0xfb,0x38);
366 &LL(0x30,0x30,0xc0,0x30,0x9d,0xf0,0x60,0xad);
367 &LL(0xef,0xef,0x9b,0xef,0x2b,0x74,0xc3,0xc4);
368 &LL(0x3f,0x3f,0xfc,0x3f,0xe5,0xc3,0x7e,0xda);
369 &LL(0x55,0x55,0x49,0x55,0x92,0x1c,0xaa,0xc7);
370 &LL(0xa2,0xa2,0xb2,0xa2,0x79,0x10,0x59,0xdb);
371 &LL(0xea,0xea,0x8f,0xea,0x03,0x65,0xc9,0xe9);
372 &LL(0x65,0x65,0x89,0x65,0x0f,0xec,0xca,0x6a);
373 &LL(0xba,0xba,0xd2,0xba,0xb9,0x68,0x69,0x03);
374 &LL(0x2f,0x2f,0xbc,0x2f,0x65,0x93,0x5e,0x4a);
375 &LL(0xc0,0xc0,0x27,0xc0,0x4e,0xe7,0x9d,0x8e);
376 &LL(0xde,0xde,0x5f,0xde,0xbe,0x81,0xa1,0x60);
377 &LL(0x1c,0x1c,0x70,0x1c,0xe0,0x6c,0x38,0xfc);
378 &LL(0xfd,0xfd,0xd3,0xfd,0xbb,0x2e,0xe7,0x46);
379 &LL(0x4d,0x4d,0x29,0x4d,0x52,0x64,0x9a,0x1f);
380 &LL(0x92,0x92,0x72,0x92,0xe4,0xe0,0x39,0x76);
381 &LL(0x75,0x75,0xc9,0x75,0x8f,0xbc,0xea,0xfa);
382 &LL(0x06,0x06,0x18,0x06,0x30,0x1e,0x0c,0x36);
383 &LL(0x8a,0x8a,0x12,0x8a,0x24,0x98,0x09,0xae);
384 &LL(0xb2,0xb2,0xf2,0xb2,0xf9,0x40,0x79,0x4b);
385 &LL(0xe6,0xe6,0xbf,0xe6,0x63,0x59,0xd1,0x85);
386 &LL(0x0e,0x0e,0x38,0x0e,0x70,0x36,0x1c,0x7e);
387 &LL(0x1f,0x1f,0x7c,0x1f,0xf8,0x63,0x3e,0xe7);
388 &LL(0x62,0x62,0x95,0x62,0x37,0xf7,0xc4,0x55);
389 &LL(0xd4,0xd4,0x77,0xd4,0xee,0xa3,0xb5,0x3a);
390 &LL(0xa8,0xa8,0x9a,0xa8,0x29,0x32,0x4d,0x81);
391 &LL(0x96,0x96,0x62,0x96,0xc4,0xf4,0x31,0x52);
392 &LL(0xf9,0xf9,0xc3,0xf9,0x9b,0x3a,0xef,0x62);
393 &LL(0xc5,0xc5,0x33,0xc5,0x66,0xf6,0x97,0xa3);
394 &LL(0x25,0x25,0x94,0x25,0x35,0xb1,0x4a,0x10);
395 &LL(0x59,0x59,0x79,0x59,0xf2,0x20,0xb2,0xab);
396 &LL(0x84,0x84,0x2a,0x84,0x54,0xae,0x15,0xd0);
397 &LL(0x72,0x72,0xd5,0x72,0xb7,0xa7,0xe4,0xc5);
398 &LL(0x39,0x39,0xe4,0x39,0xd5,0xdd,0x72,0xec);
399 &LL(0x4c,0x4c,0x2d,0x4c,0x5a,0x61,0x98,0x16);
400 &LL(0x5e,0x5e,0x65,0x5e,0xca,0x3b,0xbc,0x94);
401 &LL(0x78,0x78,0xfd,0x78,0xe7,0x85,0xf0,0x9f);
402 &LL(0x38,0x38,0xe0,0x38,0xdd,0xd8,0x70,0xe5);
403 &LL(0x8c,0x8c,0x0a,0x8c,0x14,0x86,0x05,0x98);
404 &LL(0xd1,0xd1,0x63,0xd1,0xc6,0xb2,0xbf,0x17);
405 &LL(0xa5,0xa5,0xae,0xa5,0x41,0x0b,0x57,0xe4);
406 &LL(0xe2,0xe2,0xaf,0xe2,0x43,0x4d,0xd9,0xa1);
407 &LL(0x61,0x61,0x99,0x61,0x2f,0xf8,0xc2,0x4e);
408 &LL(0xb3,0xb3,0xf6,0xb3,0xf1,0x45,0x7b,0x42);
409 &LL(0x21,0x21,0x84,0x21,0x15,0xa5,0x42,0x34);
410 &LL(0x9c,0x9c,0x4a,0x9c,0x94,0xd6,0x25,0x08);
411 &LL(0x1e,0x1e,0x78,0x1e,0xf0,0x66,0x3c,0xee);
412 &LL(0x43,0x43,0x11,0x43,0x22,0x52,0x86,0x61);
413 &LL(0xc7,0xc7,0x3b,0xc7,0x76,0xfc,0x93,0xb1);
414 &LL(0xfc,0xfc,0xd7,0xfc,0xb3,0x2b,0xe5,0x4f);
415 &LL(0x04,0x04,0x10,0x04,0x20,0x14,0x08,0x24);
416 &LL(0x51,0x51,0x59,0x51,0xb2,0x08,0xa2,0xe3);
417 &LL(0x99,0x99,0x5e,0x99,0xbc,0xc7,0x2f,0x25);
418 &LL(0x6d,0x6d,0xa9,0x6d,0x4f,0xc4,0xda,0x22);
419 &LL(0x0d,0x0d,0x34,0x0d,0x68,0x39,0x1a,0x65);
420 &LL(0xfa,0xfa,0xcf,0xfa,0x83,0x35,0xe9,0x79);
421 &LL(0xdf,0xdf,0x5b,0xdf,0xb6,0x84,0xa3,0x69);
422 &LL(0x7e,0x7e,0xe5,0x7e,0xd7,0x9b,0xfc,0xa9);
423 &LL(0x24,0x24,0x90,0x24,0x3d,0xb4,0x48,0x19);
424 &LL(0x3b,0x3b,0xec,0x3b,0xc5,0xd7,0x76,0xfe);
425 &LL(0xab,0xab,0x96,0xab,0x31,0x3d,0x4b,0x9a);
426 &LL(0xce,0xce,0x1f,0xce,0x3e,0xd1,0x81,0xf0);
427 &LL(0x11,0x11,0x44,0x11,0x88,0x55,0x22,0x99);
428 &LL(0x8f,0x8f,0x06,0x8f,0x0c,0x89,0x03,0x83);
429 &LL(0x4e,0x4e,0x25,0x4e,0x4a,0x6b,0x9c,0x04);
430 &LL(0xb7,0xb7,0xe6,0xb7,0xd1,0x51,0x73,0x66);
431 &LL(0xeb,0xeb,0x8b,0xeb,0x0b,0x60,0xcb,0xe0);
432 &LL(0x3c,0x3c,0xf0,0x3c,0xfd,0xcc,0x78,0xc1);
433 &LL(0x81,0x81,0x3e,0x81,0x7c,0xbf,0x1f,0xfd);
434 &LL(0x94,0x94,0x6a,0x94,0xd4,0xfe,0x35,0x40);
435 &LL(0xf7,0xf7,0xfb,0xf7,0xeb,0x0c,0xf3,0x1c);
436 &LL(0xb9,0xb9,0xde,0xb9,0xa1,0x67,0x6f,0x18);
437 &LL(0x13,0x13,0x4c,0x13,0x98,0x5f,0x26,0x8b);
438 &LL(0x2c,0x2c,0xb0,0x2c,0x7d,0x9c,0x58,0x51);
439 &LL(0xd3,0xd3,0x6b,0xd3,0xd6,0xb8,0xbb,0x05);
440 &LL(0xe7,0xe7,0xbb,0xe7,0x6b,0x5c,0xd3,0x8c);
441 &LL(0x6e,0x6e,0xa5,0x6e,0x57,0xcb,0xdc,0x39);
442 &LL(0xc4,0xc4,0x37,0xc4,0x6e,0xf3,0x95,0xaa);
443 &LL(0x03,0x03,0x0c,0x03,0x18,0x0f,0x06,0x1b);
444 &LL(0x56,0x56,0x45,0x56,0x8a,0x13,0xac,0xdc);
445 &LL(0x44,0x44,0x0d,0x44,0x1a,0x49,0x88,0x5e);
446 &LL(0x7f,0x7f,0xe1,0x7f,0xdf,0x9e,0xfe,0xa0);
447 &LL(0xa9,0xa9,0x9e,0xa9,0x21,0x37,0x4f,0x88);
448 &LL(0x2a,0x2a,0xa8,0x2a,0x4d,0x82,0x54,0x67);
449 &LL(0xbb,0xbb,0xd6,0xbb,0xb1,0x6d,0x6b,0x0a);
450 &LL(0xc1,0xc1,0x23,0xc1,0x46,0xe2,0x9f,0x87);
451 &LL(0x53,0x53,0x51,0x53,0xa2,0x02,0xa6,0xf1);
452 &LL(0xdc,0xdc,0x57,0xdc,0xae,0x8b,0xa5,0x72);
453 &LL(0x0b,0x0b,0x2c,0x0b,0x58,0x27,0x16,0x53);
454 &LL(0x9d,0x9d,0x4e,0x9d,0x9c,0xd3,0x27,0x01);
455 &LL(0x6c,0x6c,0xad,0x6c,0x47,0xc1,0xd8,0x2b);
456 &LL(0x31,0x31,0xc4,0x31,0x95,0xf5,0x62,0xa4);
457 &LL(0x74,0x74,0xcd,0x74,0x87,0xb9,0xe8,0xf3);
458 &LL(0xf6,0xf6,0xff,0xf6,0xe3,0x09,0xf1,0x15);
459 &LL(0x46,0x46,0x05,0x46,0x0a,0x43,0x8c,0x4c);
460 &LL(0xac,0xac,0x8a,0xac,0x09,0x26,0x45,0xa5);
461 &LL(0x89,0x89,0x1e,0x89,0x3c,0x97,0x0f,0xb5);
462 &LL(0x14,0x14,0x50,0x14,0xa0,0x44,0x28,0xb4);
463 &LL(0xe1,0xe1,0xa3,0xe1,0x5b,0x42,0xdf,0xba);
464 &LL(0x16,0x16,0x58,0x16,0xb0,0x4e,0x2c,0xa6);
465 &LL(0x3a,0x3a,0xe8,0x3a,0xcd,0xd2,0x74,0xf7);
466 &LL(0x69,0x69,0xb9,0x69,0x6f,0xd0,0xd2,0x06);
467 &LL(0x09,0x09,0x24,0x09,0x48,0x2d,0x12,0x41);
468 &LL(0x70,0x70,0xdd,0x70,0xa7,0xad,0xe0,0xd7);
469 &LL(0xb6,0xb6,0xe2,0xb6,0xd9,0x54,0x71,0x6f);
470 &LL(0xd0,0xd0,0x67,0xd0,0xce,0xb7,0xbd,0x1e);
471 &LL(0xed,0xed,0x93,0xed,0x3b,0x7e,0xc7,0xd6);
472 &LL(0xcc,0xcc,0x17,0xcc,0x2e,0xdb,0x85,0xe2);
473 &LL(0x42,0x42,0x15,0x42,0x2a,0x57,0x84,0x68);
474 &LL(0x98,0x98,0x5a,0x98,0xb4,0xc2,0x2d,0x2c);
475 &LL(0xa4,0xa4,0xaa,0xa4,0x49,0x0e,0x55,0xed);
476 &LL(0x28,0x28,0xa0,0x28,0x5d,0x88,0x50,0x75);
477 &LL(0x5c,0x5c,0x6d,0x5c,0xda,0x31,0xb8,0x86);
478 &LL(0xf8,0xf8,0xc7,0xf8,0x93,0x3f,0xed,0x6b);
479 &LL(0x86,0x86,0x22,0x86,0x44,0xa4,0x11,0xc2);
480
481 &L(0x18,0x23,0xc6,0xe8,0x87,0xb8,0x01,0x4f); # rc[ROUNDS]
482 &L(0x36,0xa6,0xd2,0xf5,0x79,0x6f,0x91,0x52);
483 &L(0x60,0xbc,0x9b,0x8e,0xa3,0x0c,0x7b,0x35);
484 &L(0x1d,0xe0,0xd7,0xc2,0x2e,0x4b,0xfe,0x57);
485 &L(0x15,0x77,0x37,0xe5,0x9f,0xf0,0x4a,0xda);
486 &L(0x58,0xc9,0x29,0x0a,0xb1,0xa0,0x6b,0x85);
487 &L(0xbd,0x5d,0x10,0xf4,0xcb,0x3e,0x05,0x67);
488 &L(0xe4,0x27,0x41,0x8b,0xa7,0x7d,0x95,0xd8);
489 &L(0xfb,0xee,0x7c,0x66,0xdd,0x17,0x47,0x9e);
490 &L(0xca,0x2d,0xbf,0x07,0xad,0x5a,0x83,0x33);
491
492&function_end_B("whirlpool_block_mmx");
493&asm_finish();
diff --git a/src/lib/libcrypto/whrlpool/asm/wp-x86_64.pl b/src/lib/libcrypto/whrlpool/asm/wp-x86_64.pl
new file mode 100644
index 0000000000..87c0843dc1
--- /dev/null
+++ b/src/lib/libcrypto/whrlpool/asm/wp-x86_64.pl
@@ -0,0 +1,589 @@
1#!/usr/bin/env perl
2#
3# ====================================================================
4# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
5# project. Rights for redistribution and usage in source and binary
6# forms are granted according to the OpenSSL license.
7# ====================================================================
8#
9# whirlpool_block for x86_64.
10#
11# 2500 cycles per 64-byte input block on AMD64, which is *identical*
12# to 32-bit MMX version executed on same CPU. So why did I bother?
13# Well, it's faster than gcc 3.3.2 generated code by over 50%, and
14# over 80% faster than PathScale 1.4, an "ambitious" commercial
15# compiler. Furthermore it surpasses gcc 3.4.3 by 170% and Sun Studio
16# 10 - by 360%[!]... What is it with x86_64 compilers? It's not the
17# first example when they fail to generate more optimal code, when
18# I believe they had *all* chances to...
19#
20# Note that register and stack frame layout are virtually identical
21# to 32-bit MMX version, except that %r8-15 are used instead of
22# %mm0-8. You can even notice that K[i] and S[i] are loaded to
23# %eax:%ebx as pair of 32-bit values and not as single 64-bit one.
24# This is done in order to avoid 64-bit shift penalties on Intel
25# EM64T core. Speaking of which! I bet it's possible to improve
26# Opteron performance by compressing the table to 2KB and replacing
27# unaligned references with complementary rotations [which would
28# incidentally replace lea instructions], but it would definitely
29# just "kill" EM64T, because it has only 1 shifter/rotator [against
30# 3 on Opteron] and which is *unacceptably* slow with 64-bit
31# operand.
32
33$flavour = shift;
34$output = shift;
35if ($flavour =~ /\./) { $output = $flavour; undef $flavour; }
36
37$win64=0; $win64=1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/);
38
39$0 =~ m/(.*[\/\\])[^\/\\]+$/; my $dir=$1; my $xlate;
40( $xlate="${dir}x86_64-xlate.pl" and -f $xlate ) or
41( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or
42die "can't locate x86_64-xlate.pl";
43
44open STDOUT,"| $^X $xlate $flavour $output";
45
46sub L() { $code.=".byte ".join(',',@_)."\n"; }
47sub LL(){ $code.=".byte ".join(',',@_).",".join(',',@_)."\n"; }
48
49@mm=("%r8","%r9","%r10","%r11","%r12","%r13","%r14","%r15");
50
51$func="whirlpool_block";
52$table=".Ltable";
53
54$code=<<___;
55.text
56
57.globl $func
58.type $func,\@function,3
59.align 16
60$func:
61 push %rbx
62 push %rbp
63 push %r12
64 push %r13
65 push %r14
66 push %r15
67
68 mov %rsp,%r11
69 sub \$128+40,%rsp
70 and \$-64,%rsp
71
72 lea 128(%rsp),%r10
73 mov %rdi,0(%r10) # save parameter block
74 mov %rsi,8(%r10)
75 mov %rdx,16(%r10)
76 mov %r11,32(%r10) # saved stack pointer
77.Lprologue:
78
79 mov %r10,%rbx
80 lea $table(%rip),%rbp
81
82 xor %rcx,%rcx
83 xor %rdx,%rdx
84___
85for($i=0;$i<8;$i++) { $code.="mov $i*8(%rdi),@mm[$i]\n"; } # L=H
86$code.=".Louterloop:\n";
87for($i=0;$i<8;$i++) { $code.="mov @mm[$i],$i*8(%rsp)\n"; } # K=L
88for($i=0;$i<8;$i++) { $code.="xor $i*8(%rsi),@mm[$i]\n"; } # L^=inp
89for($i=0;$i<8;$i++) { $code.="mov @mm[$i],64+$i*8(%rsp)\n"; } # S=L
90$code.=<<___;
91 xor %rsi,%rsi
92 mov %rsi,24(%rbx) # zero round counter
93.align 16
94.Lround:
95 mov 4096(%rbp,%rsi,8),@mm[0] # rc[r]
96 mov 0(%rsp),%eax
97 mov 4(%rsp),%ebx
98___
99for($i=0;$i<8;$i++) {
100 my $func = ($i==0)? "mov" : "xor";
101 $code.=<<___;
102 mov %al,%cl
103 mov %ah,%dl
104 lea (%rcx,%rcx),%rsi
105 lea (%rdx,%rdx),%rdi
106 shr \$16,%eax
107 xor 0(%rbp,%rsi,8),@mm[0]
108 $func 7(%rbp,%rdi,8),@mm[1]
109 mov %al,%cl
110 mov %ah,%dl
111 mov $i*8+8(%rsp),%eax # ($i+1)*8
112 lea (%rcx,%rcx),%rsi
113 lea (%rdx,%rdx),%rdi
114 $func 6(%rbp,%rsi,8),@mm[2]
115 $func 5(%rbp,%rdi,8),@mm[3]
116 mov %bl,%cl
117 mov %bh,%dl
118 lea (%rcx,%rcx),%rsi
119 lea (%rdx,%rdx),%rdi
120 shr \$16,%ebx
121 $func 4(%rbp,%rsi,8),@mm[4]
122 $func 3(%rbp,%rdi,8),@mm[5]
123 mov %bl,%cl
124 mov %bh,%dl
125 mov $i*8+8+4(%rsp),%ebx # ($i+1)*8+4
126 lea (%rcx,%rcx),%rsi
127 lea (%rdx,%rdx),%rdi
128 $func 2(%rbp,%rsi,8),@mm[6]
129 $func 1(%rbp,%rdi,8),@mm[7]
130___
131 push(@mm,shift(@mm));
132}
133for($i=0;$i<8;$i++) { $code.="mov @mm[$i],$i*8(%rsp)\n"; } # K=L
134for($i=0;$i<8;$i++) {
135 $code.=<<___;
136 mov %al,%cl
137 mov %ah,%dl
138 lea (%rcx,%rcx),%rsi
139 lea (%rdx,%rdx),%rdi
140 shr \$16,%eax
141 xor 0(%rbp,%rsi,8),@mm[0]
142 xor 7(%rbp,%rdi,8),@mm[1]
143 mov %al,%cl
144 mov %ah,%dl
145 `"mov 64+$i*8+8(%rsp),%eax" if($i<7);` # 64+($i+1)*8
146 lea (%rcx,%rcx),%rsi
147 lea (%rdx,%rdx),%rdi
148 xor 6(%rbp,%rsi,8),@mm[2]
149 xor 5(%rbp,%rdi,8),@mm[3]
150 mov %bl,%cl
151 mov %bh,%dl
152 lea (%rcx,%rcx),%rsi
153 lea (%rdx,%rdx),%rdi
154 shr \$16,%ebx
155 xor 4(%rbp,%rsi,8),@mm[4]
156 xor 3(%rbp,%rdi,8),@mm[5]
157 mov %bl,%cl
158 mov %bh,%dl
159 `"mov 64+$i*8+8+4(%rsp),%ebx" if($i<7);` # 64+($i+1)*8+4
160 lea (%rcx,%rcx),%rsi
161 lea (%rdx,%rdx),%rdi
162 xor 2(%rbp,%rsi,8),@mm[6]
163 xor 1(%rbp,%rdi,8),@mm[7]
164___
165 push(@mm,shift(@mm));
166}
167$code.=<<___;
168 lea 128(%rsp),%rbx
169 mov 24(%rbx),%rsi # pull round counter
170 add \$1,%rsi
171 cmp \$10,%rsi
172 je .Lroundsdone
173
174 mov %rsi,24(%rbx) # update round counter
175___
176for($i=0;$i<8;$i++) { $code.="mov @mm[$i],64+$i*8(%rsp)\n"; } # S=L
177$code.=<<___;
178 jmp .Lround
179.align 16
180.Lroundsdone:
181 mov 0(%rbx),%rdi # reload argument block
182 mov 8(%rbx),%rsi
183 mov 16(%rbx),%rax
184___
185for($i=0;$i<8;$i++) { $code.="xor $i*8(%rsi),@mm[$i]\n"; } # L^=inp
186for($i=0;$i<8;$i++) { $code.="xor $i*8(%rdi),@mm[$i]\n"; } # L^=H
187for($i=0;$i<8;$i++) { $code.="mov @mm[$i],$i*8(%rdi)\n"; } # H=L
188$code.=<<___;
189 lea 64(%rsi),%rsi # inp+=64
190 sub \$1,%rax # num--
191 jz .Lalldone
192 mov %rsi,8(%rbx) # update parameter block
193 mov %rax,16(%rbx)
194 jmp .Louterloop
195.Lalldone:
196 mov 32(%rbx),%rsi # restore saved pointer
197 mov (%rsi),%r15
198 mov 8(%rsi),%r14
199 mov 16(%rsi),%r13
200 mov 24(%rsi),%r12
201 mov 32(%rsi),%rbp
202 mov 40(%rsi),%rbx
203 lea 48(%rsi),%rsp
204.Lepilogue:
205 ret
206.size $func,.-$func
207
208.align 64
209.type $table,\@object
210$table:
211___
212 &LL(0x18,0x18,0x60,0x18,0xc0,0x78,0x30,0xd8);
213 &LL(0x23,0x23,0x8c,0x23,0x05,0xaf,0x46,0x26);
214 &LL(0xc6,0xc6,0x3f,0xc6,0x7e,0xf9,0x91,0xb8);
215 &LL(0xe8,0xe8,0x87,0xe8,0x13,0x6f,0xcd,0xfb);
216 &LL(0x87,0x87,0x26,0x87,0x4c,0xa1,0x13,0xcb);
217 &LL(0xb8,0xb8,0xda,0xb8,0xa9,0x62,0x6d,0x11);
218 &LL(0x01,0x01,0x04,0x01,0x08,0x05,0x02,0x09);
219 &LL(0x4f,0x4f,0x21,0x4f,0x42,0x6e,0x9e,0x0d);
220 &LL(0x36,0x36,0xd8,0x36,0xad,0xee,0x6c,0x9b);
221 &LL(0xa6,0xa6,0xa2,0xa6,0x59,0x04,0x51,0xff);
222 &LL(0xd2,0xd2,0x6f,0xd2,0xde,0xbd,0xb9,0x0c);
223 &LL(0xf5,0xf5,0xf3,0xf5,0xfb,0x06,0xf7,0x0e);
224 &LL(0x79,0x79,0xf9,0x79,0xef,0x80,0xf2,0x96);
225 &LL(0x6f,0x6f,0xa1,0x6f,0x5f,0xce,0xde,0x30);
226 &LL(0x91,0x91,0x7e,0x91,0xfc,0xef,0x3f,0x6d);
227 &LL(0x52,0x52,0x55,0x52,0xaa,0x07,0xa4,0xf8);
228 &LL(0x60,0x60,0x9d,0x60,0x27,0xfd,0xc0,0x47);
229 &LL(0xbc,0xbc,0xca,0xbc,0x89,0x76,0x65,0x35);
230 &LL(0x9b,0x9b,0x56,0x9b,0xac,0xcd,0x2b,0x37);
231 &LL(0x8e,0x8e,0x02,0x8e,0x04,0x8c,0x01,0x8a);
232 &LL(0xa3,0xa3,0xb6,0xa3,0x71,0x15,0x5b,0xd2);
233 &LL(0x0c,0x0c,0x30,0x0c,0x60,0x3c,0x18,0x6c);
234 &LL(0x7b,0x7b,0xf1,0x7b,0xff,0x8a,0xf6,0x84);
235 &LL(0x35,0x35,0xd4,0x35,0xb5,0xe1,0x6a,0x80);
236 &LL(0x1d,0x1d,0x74,0x1d,0xe8,0x69,0x3a,0xf5);
237 &LL(0xe0,0xe0,0xa7,0xe0,0x53,0x47,0xdd,0xb3);
238 &LL(0xd7,0xd7,0x7b,0xd7,0xf6,0xac,0xb3,0x21);
239 &LL(0xc2,0xc2,0x2f,0xc2,0x5e,0xed,0x99,0x9c);
240 &LL(0x2e,0x2e,0xb8,0x2e,0x6d,0x96,0x5c,0x43);
241 &LL(0x4b,0x4b,0x31,0x4b,0x62,0x7a,0x96,0x29);
242 &LL(0xfe,0xfe,0xdf,0xfe,0xa3,0x21,0xe1,0x5d);
243 &LL(0x57,0x57,0x41,0x57,0x82,0x16,0xae,0xd5);
244 &LL(0x15,0x15,0x54,0x15,0xa8,0x41,0x2a,0xbd);
245 &LL(0x77,0x77,0xc1,0x77,0x9f,0xb6,0xee,0xe8);
246 &LL(0x37,0x37,0xdc,0x37,0xa5,0xeb,0x6e,0x92);
247 &LL(0xe5,0xe5,0xb3,0xe5,0x7b,0x56,0xd7,0x9e);
248 &LL(0x9f,0x9f,0x46,0x9f,0x8c,0xd9,0x23,0x13);
249 &LL(0xf0,0xf0,0xe7,0xf0,0xd3,0x17,0xfd,0x23);
250 &LL(0x4a,0x4a,0x35,0x4a,0x6a,0x7f,0x94,0x20);
251 &LL(0xda,0xda,0x4f,0xda,0x9e,0x95,0xa9,0x44);
252 &LL(0x58,0x58,0x7d,0x58,0xfa,0x25,0xb0,0xa2);
253 &LL(0xc9,0xc9,0x03,0xc9,0x06,0xca,0x8f,0xcf);
254 &LL(0x29,0x29,0xa4,0x29,0x55,0x8d,0x52,0x7c);
255 &LL(0x0a,0x0a,0x28,0x0a,0x50,0x22,0x14,0x5a);
256 &LL(0xb1,0xb1,0xfe,0xb1,0xe1,0x4f,0x7f,0x50);
257 &LL(0xa0,0xa0,0xba,0xa0,0x69,0x1a,0x5d,0xc9);
258 &LL(0x6b,0x6b,0xb1,0x6b,0x7f,0xda,0xd6,0x14);
259 &LL(0x85,0x85,0x2e,0x85,0x5c,0xab,0x17,0xd9);
260 &LL(0xbd,0xbd,0xce,0xbd,0x81,0x73,0x67,0x3c);
261 &LL(0x5d,0x5d,0x69,0x5d,0xd2,0x34,0xba,0x8f);
262 &LL(0x10,0x10,0x40,0x10,0x80,0x50,0x20,0x90);
263 &LL(0xf4,0xf4,0xf7,0xf4,0xf3,0x03,0xf5,0x07);
264 &LL(0xcb,0xcb,0x0b,0xcb,0x16,0xc0,0x8b,0xdd);
265 &LL(0x3e,0x3e,0xf8,0x3e,0xed,0xc6,0x7c,0xd3);
266 &LL(0x05,0x05,0x14,0x05,0x28,0x11,0x0a,0x2d);
267 &LL(0x67,0x67,0x81,0x67,0x1f,0xe6,0xce,0x78);
268 &LL(0xe4,0xe4,0xb7,0xe4,0x73,0x53,0xd5,0x97);
269 &LL(0x27,0x27,0x9c,0x27,0x25,0xbb,0x4e,0x02);
270 &LL(0x41,0x41,0x19,0x41,0x32,0x58,0x82,0x73);
271 &LL(0x8b,0x8b,0x16,0x8b,0x2c,0x9d,0x0b,0xa7);
272 &LL(0xa7,0xa7,0xa6,0xa7,0x51,0x01,0x53,0xf6);
273 &LL(0x7d,0x7d,0xe9,0x7d,0xcf,0x94,0xfa,0xb2);
274 &LL(0x95,0x95,0x6e,0x95,0xdc,0xfb,0x37,0x49);
275 &LL(0xd8,0xd8,0x47,0xd8,0x8e,0x9f,0xad,0x56);
276 &LL(0xfb,0xfb,0xcb,0xfb,0x8b,0x30,0xeb,0x70);
277 &LL(0xee,0xee,0x9f,0xee,0x23,0x71,0xc1,0xcd);
278 &LL(0x7c,0x7c,0xed,0x7c,0xc7,0x91,0xf8,0xbb);
279 &LL(0x66,0x66,0x85,0x66,0x17,0xe3,0xcc,0x71);
280 &LL(0xdd,0xdd,0x53,0xdd,0xa6,0x8e,0xa7,0x7b);
281 &LL(0x17,0x17,0x5c,0x17,0xb8,0x4b,0x2e,0xaf);
282 &LL(0x47,0x47,0x01,0x47,0x02,0x46,0x8e,0x45);
283 &LL(0x9e,0x9e,0x42,0x9e,0x84,0xdc,0x21,0x1a);
284 &LL(0xca,0xca,0x0f,0xca,0x1e,0xc5,0x89,0xd4);
285 &LL(0x2d,0x2d,0xb4,0x2d,0x75,0x99,0x5a,0x58);
286 &LL(0xbf,0xbf,0xc6,0xbf,0x91,0x79,0x63,0x2e);
287 &LL(0x07,0x07,0x1c,0x07,0x38,0x1b,0x0e,0x3f);
288 &LL(0xad,0xad,0x8e,0xad,0x01,0x23,0x47,0xac);
289 &LL(0x5a,0x5a,0x75,0x5a,0xea,0x2f,0xb4,0xb0);
290 &LL(0x83,0x83,0x36,0x83,0x6c,0xb5,0x1b,0xef);
291 &LL(0x33,0x33,0xcc,0x33,0x85,0xff,0x66,0xb6);
292 &LL(0x63,0x63,0x91,0x63,0x3f,0xf2,0xc6,0x5c);
293 &LL(0x02,0x02,0x08,0x02,0x10,0x0a,0x04,0x12);
294 &LL(0xaa,0xaa,0x92,0xaa,0x39,0x38,0x49,0x93);
295 &LL(0x71,0x71,0xd9,0x71,0xaf,0xa8,0xe2,0xde);
296 &LL(0xc8,0xc8,0x07,0xc8,0x0e,0xcf,0x8d,0xc6);
297 &LL(0x19,0x19,0x64,0x19,0xc8,0x7d,0x32,0xd1);
298 &LL(0x49,0x49,0x39,0x49,0x72,0x70,0x92,0x3b);
299 &LL(0xd9,0xd9,0x43,0xd9,0x86,0x9a,0xaf,0x5f);
300 &LL(0xf2,0xf2,0xef,0xf2,0xc3,0x1d,0xf9,0x31);
301 &LL(0xe3,0xe3,0xab,0xe3,0x4b,0x48,0xdb,0xa8);
302 &LL(0x5b,0x5b,0x71,0x5b,0xe2,0x2a,0xb6,0xb9);
303 &LL(0x88,0x88,0x1a,0x88,0x34,0x92,0x0d,0xbc);
304 &LL(0x9a,0x9a,0x52,0x9a,0xa4,0xc8,0x29,0x3e);
305 &LL(0x26,0x26,0x98,0x26,0x2d,0xbe,0x4c,0x0b);
306 &LL(0x32,0x32,0xc8,0x32,0x8d,0xfa,0x64,0xbf);
307 &LL(0xb0,0xb0,0xfa,0xb0,0xe9,0x4a,0x7d,0x59);
308 &LL(0xe9,0xe9,0x83,0xe9,0x1b,0x6a,0xcf,0xf2);
309 &LL(0x0f,0x0f,0x3c,0x0f,0x78,0x33,0x1e,0x77);
310 &LL(0xd5,0xd5,0x73,0xd5,0xe6,0xa6,0xb7,0x33);
311 &LL(0x80,0x80,0x3a,0x80,0x74,0xba,0x1d,0xf4);
312 &LL(0xbe,0xbe,0xc2,0xbe,0x99,0x7c,0x61,0x27);
313 &LL(0xcd,0xcd,0x13,0xcd,0x26,0xde,0x87,0xeb);
314 &LL(0x34,0x34,0xd0,0x34,0xbd,0xe4,0x68,0x89);
315 &LL(0x48,0x48,0x3d,0x48,0x7a,0x75,0x90,0x32);
316 &LL(0xff,0xff,0xdb,0xff,0xab,0x24,0xe3,0x54);
317 &LL(0x7a,0x7a,0xf5,0x7a,0xf7,0x8f,0xf4,0x8d);
318 &LL(0x90,0x90,0x7a,0x90,0xf4,0xea,0x3d,0x64);
319 &LL(0x5f,0x5f,0x61,0x5f,0xc2,0x3e,0xbe,0x9d);
320 &LL(0x20,0x20,0x80,0x20,0x1d,0xa0,0x40,0x3d);
321 &LL(0x68,0x68,0xbd,0x68,0x67,0xd5,0xd0,0x0f);
322 &LL(0x1a,0x1a,0x68,0x1a,0xd0,0x72,0x34,0xca);
323 &LL(0xae,0xae,0x82,0xae,0x19,0x2c,0x41,0xb7);
324 &LL(0xb4,0xb4,0xea,0xb4,0xc9,0x5e,0x75,0x7d);
325 &LL(0x54,0x54,0x4d,0x54,0x9a,0x19,0xa8,0xce);
326 &LL(0x93,0x93,0x76,0x93,0xec,0xe5,0x3b,0x7f);
327 &LL(0x22,0x22,0x88,0x22,0x0d,0xaa,0x44,0x2f);
328 &LL(0x64,0x64,0x8d,0x64,0x07,0xe9,0xc8,0x63);
329 &LL(0xf1,0xf1,0xe3,0xf1,0xdb,0x12,0xff,0x2a);
330 &LL(0x73,0x73,0xd1,0x73,0xbf,0xa2,0xe6,0xcc);
331 &LL(0x12,0x12,0x48,0x12,0x90,0x5a,0x24,0x82);
332 &LL(0x40,0x40,0x1d,0x40,0x3a,0x5d,0x80,0x7a);
333 &LL(0x08,0x08,0x20,0x08,0x40,0x28,0x10,0x48);
334 &LL(0xc3,0xc3,0x2b,0xc3,0x56,0xe8,0x9b,0x95);
335 &LL(0xec,0xec,0x97,0xec,0x33,0x7b,0xc5,0xdf);
336 &LL(0xdb,0xdb,0x4b,0xdb,0x96,0x90,0xab,0x4d);
337 &LL(0xa1,0xa1,0xbe,0xa1,0x61,0x1f,0x5f,0xc0);
338 &LL(0x8d,0x8d,0x0e,0x8d,0x1c,0x83,0x07,0x91);
339 &LL(0x3d,0x3d,0xf4,0x3d,0xf5,0xc9,0x7a,0xc8);
340 &LL(0x97,0x97,0x66,0x97,0xcc,0xf1,0x33,0x5b);
341 &LL(0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00);
342 &LL(0xcf,0xcf,0x1b,0xcf,0x36,0xd4,0x83,0xf9);
343 &LL(0x2b,0x2b,0xac,0x2b,0x45,0x87,0x56,0x6e);
344 &LL(0x76,0x76,0xc5,0x76,0x97,0xb3,0xec,0xe1);
345 &LL(0x82,0x82,0x32,0x82,0x64,0xb0,0x19,0xe6);
346 &LL(0xd6,0xd6,0x7f,0xd6,0xfe,0xa9,0xb1,0x28);
347 &LL(0x1b,0x1b,0x6c,0x1b,0xd8,0x77,0x36,0xc3);
348 &LL(0xb5,0xb5,0xee,0xb5,0xc1,0x5b,0x77,0x74);
349 &LL(0xaf,0xaf,0x86,0xaf,0x11,0x29,0x43,0xbe);
350 &LL(0x6a,0x6a,0xb5,0x6a,0x77,0xdf,0xd4,0x1d);
351 &LL(0x50,0x50,0x5d,0x50,0xba,0x0d,0xa0,0xea);
352 &LL(0x45,0x45,0x09,0x45,0x12,0x4c,0x8a,0x57);
353 &LL(0xf3,0xf3,0xeb,0xf3,0xcb,0x18,0xfb,0x38);
354 &LL(0x30,0x30,0xc0,0x30,0x9d,0xf0,0x60,0xad);
355 &LL(0xef,0xef,0x9b,0xef,0x2b,0x74,0xc3,0xc4);
356 &LL(0x3f,0x3f,0xfc,0x3f,0xe5,0xc3,0x7e,0xda);
357 &LL(0x55,0x55,0x49,0x55,0x92,0x1c,0xaa,0xc7);
358 &LL(0xa2,0xa2,0xb2,0xa2,0x79,0x10,0x59,0xdb);
359 &LL(0xea,0xea,0x8f,0xea,0x03,0x65,0xc9,0xe9);
360 &LL(0x65,0x65,0x89,0x65,0x0f,0xec,0xca,0x6a);
361 &LL(0xba,0xba,0xd2,0xba,0xb9,0x68,0x69,0x03);
362 &LL(0x2f,0x2f,0xbc,0x2f,0x65,0x93,0x5e,0x4a);
363 &LL(0xc0,0xc0,0x27,0xc0,0x4e,0xe7,0x9d,0x8e);
364 &LL(0xde,0xde,0x5f,0xde,0xbe,0x81,0xa1,0x60);
365 &LL(0x1c,0x1c,0x70,0x1c,0xe0,0x6c,0x38,0xfc);
366 &LL(0xfd,0xfd,0xd3,0xfd,0xbb,0x2e,0xe7,0x46);
367 &LL(0x4d,0x4d,0x29,0x4d,0x52,0x64,0x9a,0x1f);
368 &LL(0x92,0x92,0x72,0x92,0xe4,0xe0,0x39,0x76);
369 &LL(0x75,0x75,0xc9,0x75,0x8f,0xbc,0xea,0xfa);
370 &LL(0x06,0x06,0x18,0x06,0x30,0x1e,0x0c,0x36);
371 &LL(0x8a,0x8a,0x12,0x8a,0x24,0x98,0x09,0xae);
372 &LL(0xb2,0xb2,0xf2,0xb2,0xf9,0x40,0x79,0x4b);
373 &LL(0xe6,0xe6,0xbf,0xe6,0x63,0x59,0xd1,0x85);
374 &LL(0x0e,0x0e,0x38,0x0e,0x70,0x36,0x1c,0x7e);
375 &LL(0x1f,0x1f,0x7c,0x1f,0xf8,0x63,0x3e,0xe7);
376 &LL(0x62,0x62,0x95,0x62,0x37,0xf7,0xc4,0x55);
377 &LL(0xd4,0xd4,0x77,0xd4,0xee,0xa3,0xb5,0x3a);
378 &LL(0xa8,0xa8,0x9a,0xa8,0x29,0x32,0x4d,0x81);
379 &LL(0x96,0x96,0x62,0x96,0xc4,0xf4,0x31,0x52);
380 &LL(0xf9,0xf9,0xc3,0xf9,0x9b,0x3a,0xef,0x62);
381 &LL(0xc5,0xc5,0x33,0xc5,0x66,0xf6,0x97,0xa3);
382 &LL(0x25,0x25,0x94,0x25,0x35,0xb1,0x4a,0x10);
383 &LL(0x59,0x59,0x79,0x59,0xf2,0x20,0xb2,0xab);
384 &LL(0x84,0x84,0x2a,0x84,0x54,0xae,0x15,0xd0);
385 &LL(0x72,0x72,0xd5,0x72,0xb7,0xa7,0xe4,0xc5);
386 &LL(0x39,0x39,0xe4,0x39,0xd5,0xdd,0x72,0xec);
387 &LL(0x4c,0x4c,0x2d,0x4c,0x5a,0x61,0x98,0x16);
388 &LL(0x5e,0x5e,0x65,0x5e,0xca,0x3b,0xbc,0x94);
389 &LL(0x78,0x78,0xfd,0x78,0xe7,0x85,0xf0,0x9f);
390 &LL(0x38,0x38,0xe0,0x38,0xdd,0xd8,0x70,0xe5);
391 &LL(0x8c,0x8c,0x0a,0x8c,0x14,0x86,0x05,0x98);
392 &LL(0xd1,0xd1,0x63,0xd1,0xc6,0xb2,0xbf,0x17);
393 &LL(0xa5,0xa5,0xae,0xa5,0x41,0x0b,0x57,0xe4);
394 &LL(0xe2,0xe2,0xaf,0xe2,0x43,0x4d,0xd9,0xa1);
395 &LL(0x61,0x61,0x99,0x61,0x2f,0xf8,0xc2,0x4e);
396 &LL(0xb3,0xb3,0xf6,0xb3,0xf1,0x45,0x7b,0x42);
397 &LL(0x21,0x21,0x84,0x21,0x15,0xa5,0x42,0x34);
398 &LL(0x9c,0x9c,0x4a,0x9c,0x94,0xd6,0x25,0x08);
399 &LL(0x1e,0x1e,0x78,0x1e,0xf0,0x66,0x3c,0xee);
400 &LL(0x43,0x43,0x11,0x43,0x22,0x52,0x86,0x61);
401 &LL(0xc7,0xc7,0x3b,0xc7,0x76,0xfc,0x93,0xb1);
402 &LL(0xfc,0xfc,0xd7,0xfc,0xb3,0x2b,0xe5,0x4f);
403 &LL(0x04,0x04,0x10,0x04,0x20,0x14,0x08,0x24);
404 &LL(0x51,0x51,0x59,0x51,0xb2,0x08,0xa2,0xe3);
405 &LL(0x99,0x99,0x5e,0x99,0xbc,0xc7,0x2f,0x25);
406 &LL(0x6d,0x6d,0xa9,0x6d,0x4f,0xc4,0xda,0x22);
407 &LL(0x0d,0x0d,0x34,0x0d,0x68,0x39,0x1a,0x65);
408 &LL(0xfa,0xfa,0xcf,0xfa,0x83,0x35,0xe9,0x79);
409 &LL(0xdf,0xdf,0x5b,0xdf,0xb6,0x84,0xa3,0x69);
410 &LL(0x7e,0x7e,0xe5,0x7e,0xd7,0x9b,0xfc,0xa9);
411 &LL(0x24,0x24,0x90,0x24,0x3d,0xb4,0x48,0x19);
412 &LL(0x3b,0x3b,0xec,0x3b,0xc5,0xd7,0x76,0xfe);
413 &LL(0xab,0xab,0x96,0xab,0x31,0x3d,0x4b,0x9a);
414 &LL(0xce,0xce,0x1f,0xce,0x3e,0xd1,0x81,0xf0);
415 &LL(0x11,0x11,0x44,0x11,0x88,0x55,0x22,0x99);
416 &LL(0x8f,0x8f,0x06,0x8f,0x0c,0x89,0x03,0x83);
417 &LL(0x4e,0x4e,0x25,0x4e,0x4a,0x6b,0x9c,0x04);
418 &LL(0xb7,0xb7,0xe6,0xb7,0xd1,0x51,0x73,0x66);
419 &LL(0xeb,0xeb,0x8b,0xeb,0x0b,0x60,0xcb,0xe0);
420 &LL(0x3c,0x3c,0xf0,0x3c,0xfd,0xcc,0x78,0xc1);
421 &LL(0x81,0x81,0x3e,0x81,0x7c,0xbf,0x1f,0xfd);
422 &LL(0x94,0x94,0x6a,0x94,0xd4,0xfe,0x35,0x40);
423 &LL(0xf7,0xf7,0xfb,0xf7,0xeb,0x0c,0xf3,0x1c);
424 &LL(0xb9,0xb9,0xde,0xb9,0xa1,0x67,0x6f,0x18);
425 &LL(0x13,0x13,0x4c,0x13,0x98,0x5f,0x26,0x8b);
426 &LL(0x2c,0x2c,0xb0,0x2c,0x7d,0x9c,0x58,0x51);
427 &LL(0xd3,0xd3,0x6b,0xd3,0xd6,0xb8,0xbb,0x05);
428 &LL(0xe7,0xe7,0xbb,0xe7,0x6b,0x5c,0xd3,0x8c);
429 &LL(0x6e,0x6e,0xa5,0x6e,0x57,0xcb,0xdc,0x39);
430 &LL(0xc4,0xc4,0x37,0xc4,0x6e,0xf3,0x95,0xaa);
431 &LL(0x03,0x03,0x0c,0x03,0x18,0x0f,0x06,0x1b);
432 &LL(0x56,0x56,0x45,0x56,0x8a,0x13,0xac,0xdc);
433 &LL(0x44,0x44,0x0d,0x44,0x1a,0x49,0x88,0x5e);
434 &LL(0x7f,0x7f,0xe1,0x7f,0xdf,0x9e,0xfe,0xa0);
435 &LL(0xa9,0xa9,0x9e,0xa9,0x21,0x37,0x4f,0x88);
436 &LL(0x2a,0x2a,0xa8,0x2a,0x4d,0x82,0x54,0x67);
437 &LL(0xbb,0xbb,0xd6,0xbb,0xb1,0x6d,0x6b,0x0a);
438 &LL(0xc1,0xc1,0x23,0xc1,0x46,0xe2,0x9f,0x87);
439 &LL(0x53,0x53,0x51,0x53,0xa2,0x02,0xa6,0xf1);
440 &LL(0xdc,0xdc,0x57,0xdc,0xae,0x8b,0xa5,0x72);
441 &LL(0x0b,0x0b,0x2c,0x0b,0x58,0x27,0x16,0x53);
442 &LL(0x9d,0x9d,0x4e,0x9d,0x9c,0xd3,0x27,0x01);
443 &LL(0x6c,0x6c,0xad,0x6c,0x47,0xc1,0xd8,0x2b);
444 &LL(0x31,0x31,0xc4,0x31,0x95,0xf5,0x62,0xa4);
445 &LL(0x74,0x74,0xcd,0x74,0x87,0xb9,0xe8,0xf3);
446 &LL(0xf6,0xf6,0xff,0xf6,0xe3,0x09,0xf1,0x15);
447 &LL(0x46,0x46,0x05,0x46,0x0a,0x43,0x8c,0x4c);
448 &LL(0xac,0xac,0x8a,0xac,0x09,0x26,0x45,0xa5);
449 &LL(0x89,0x89,0x1e,0x89,0x3c,0x97,0x0f,0xb5);
450 &LL(0x14,0x14,0x50,0x14,0xa0,0x44,0x28,0xb4);
451 &LL(0xe1,0xe1,0xa3,0xe1,0x5b,0x42,0xdf,0xba);
452 &LL(0x16,0x16,0x58,0x16,0xb0,0x4e,0x2c,0xa6);
453 &LL(0x3a,0x3a,0xe8,0x3a,0xcd,0xd2,0x74,0xf7);
454 &LL(0x69,0x69,0xb9,0x69,0x6f,0xd0,0xd2,0x06);
455 &LL(0x09,0x09,0x24,0x09,0x48,0x2d,0x12,0x41);
456 &LL(0x70,0x70,0xdd,0x70,0xa7,0xad,0xe0,0xd7);
457 &LL(0xb6,0xb6,0xe2,0xb6,0xd9,0x54,0x71,0x6f);
458 &LL(0xd0,0xd0,0x67,0xd0,0xce,0xb7,0xbd,0x1e);
459 &LL(0xed,0xed,0x93,0xed,0x3b,0x7e,0xc7,0xd6);
460 &LL(0xcc,0xcc,0x17,0xcc,0x2e,0xdb,0x85,0xe2);
461 &LL(0x42,0x42,0x15,0x42,0x2a,0x57,0x84,0x68);
462 &LL(0x98,0x98,0x5a,0x98,0xb4,0xc2,0x2d,0x2c);
463 &LL(0xa4,0xa4,0xaa,0xa4,0x49,0x0e,0x55,0xed);
464 &LL(0x28,0x28,0xa0,0x28,0x5d,0x88,0x50,0x75);
465 &LL(0x5c,0x5c,0x6d,0x5c,0xda,0x31,0xb8,0x86);
466 &LL(0xf8,0xf8,0xc7,0xf8,0x93,0x3f,0xed,0x6b);
467 &LL(0x86,0x86,0x22,0x86,0x44,0xa4,0x11,0xc2);
468
469 &L(0x18,0x23,0xc6,0xe8,0x87,0xb8,0x01,0x4f); # rc[ROUNDS]
470 &L(0x36,0xa6,0xd2,0xf5,0x79,0x6f,0x91,0x52);
471 &L(0x60,0xbc,0x9b,0x8e,0xa3,0x0c,0x7b,0x35);
472 &L(0x1d,0xe0,0xd7,0xc2,0x2e,0x4b,0xfe,0x57);
473 &L(0x15,0x77,0x37,0xe5,0x9f,0xf0,0x4a,0xda);
474 &L(0x58,0xc9,0x29,0x0a,0xb1,0xa0,0x6b,0x85);
475 &L(0xbd,0x5d,0x10,0xf4,0xcb,0x3e,0x05,0x67);
476 &L(0xe4,0x27,0x41,0x8b,0xa7,0x7d,0x95,0xd8);
477 &L(0xfb,0xee,0x7c,0x66,0xdd,0x17,0x47,0x9e);
478 &L(0xca,0x2d,0xbf,0x07,0xad,0x5a,0x83,0x33);
479
480# EXCEPTION_DISPOSITION handler (EXCEPTION_RECORD *rec,ULONG64 frame,
481# CONTEXT *context,DISPATCHER_CONTEXT *disp)
482if ($win64) {
483$rec="%rcx";
484$frame="%rdx";
485$context="%r8";
486$disp="%r9";
487
488$code.=<<___;
489.extern __imp_RtlVirtualUnwind
490.type se_handler,\@abi-omnipotent
491.align 16
492se_handler:
493 push %rsi
494 push %rdi
495 push %rbx
496 push %rbp
497 push %r12
498 push %r13
499 push %r14
500 push %r15
501 pushfq
502 sub \$64,%rsp
503
504 mov 120($context),%rax # pull context->Rax
505 mov 248($context),%rbx # pull context->Rip
506
507 lea .Lprologue(%rip),%r10
508 cmp %r10,%rbx # context->Rip<.Lprologue
509 jb .Lin_prologue
510
511 mov 152($context),%rax # pull context->Rsp
512
513 lea .Lepilogue(%rip),%r10
514 cmp %r10,%rbx # context->Rip>=.Lepilogue
515 jae .Lin_prologue
516
517 mov 128+32(%rax),%rax # pull saved stack pointer
518 lea 48(%rax),%rax
519
520 mov -8(%rax),%rbx
521 mov -16(%rax),%rbp
522 mov -24(%rax),%r12
523 mov -32(%rax),%r13
524 mov -40(%rax),%r14
525 mov -48(%rax),%r15
526 mov %rbx,144($context) # restore context->Rbx
527 mov %rbp,160($context) # restore context->Rbp
528 mov %r12,216($context) # restore context->R12
529 mov %r13,224($context) # restore context->R13
530 mov %r14,232($context) # restore context->R14
531 mov %r15,240($context) # restore context->R15
532
533.Lin_prologue:
534 mov 8(%rax),%rdi
535 mov 16(%rax),%rsi
536 mov %rax,152($context) # restore context->Rsp
537 mov %rsi,168($context) # restore context->Rsi
538 mov %rdi,176($context) # restore context->Rdi
539
540 mov 40($disp),%rdi # disp->ContextRecord
541 mov $context,%rsi # context
542 mov \$154,%ecx # sizeof(CONTEXT)
543 .long 0xa548f3fc # cld; rep movsq
544
545 mov $disp,%rsi
546 xor %rcx,%rcx # arg1, UNW_FLAG_NHANDLER
547 mov 8(%rsi),%rdx # arg2, disp->ImageBase
548 mov 0(%rsi),%r8 # arg3, disp->ControlPc
549 mov 16(%rsi),%r9 # arg4, disp->FunctionEntry
550 mov 40(%rsi),%r10 # disp->ContextRecord
551 lea 56(%rsi),%r11 # &disp->HandlerData
552 lea 24(%rsi),%r12 # &disp->EstablisherFrame
553 mov %r10,32(%rsp) # arg5
554 mov %r11,40(%rsp) # arg6
555 mov %r12,48(%rsp) # arg7
556 mov %rcx,56(%rsp) # arg8, (NULL)
557 call *__imp_RtlVirtualUnwind(%rip)
558
559 mov \$1,%eax # ExceptionContinueSearch
560 add \$64,%rsp
561 popfq
562 pop %r15
563 pop %r14
564 pop %r13
565 pop %r12
566 pop %rbp
567 pop %rbx
568 pop %rdi
569 pop %rsi
570 ret
571.size se_handler,.-se_handler
572
573.section .pdata
574.align 4
575 .rva .LSEH_begin_$func
576 .rva .LSEH_end_$func
577 .rva .LSEH_info_$func
578
579.section .xdata
580.align 8
581.LSEH_info_$func:
582 .byte 9,0,0,0
583 .rva se_handler
584___
585}
586
587$code =~ s/\`([^\`]*)\`/eval $1/gem;
588print $code;
589close STDOUT;
diff --git a/src/lib/libcrypto/whrlpool/whrlpool.h b/src/lib/libcrypto/whrlpool/whrlpool.h
new file mode 100644
index 0000000000..03c91da115
--- /dev/null
+++ b/src/lib/libcrypto/whrlpool/whrlpool.h
@@ -0,0 +1,38 @@
1#ifndef HEADER_WHRLPOOL_H
2#define HEADER_WHRLPOOL_H
3
4#include <openssl/e_os2.h>
5#include <stddef.h>
6
7#ifdef __cplusplus
8extern "C" {
9#endif
10
11#define WHIRLPOOL_DIGEST_LENGTH (512/8)
12#define WHIRLPOOL_BBLOCK 512
13#define WHIRLPOOL_COUNTER (256/8)
14
15typedef struct {
16 union {
17 unsigned char c[WHIRLPOOL_DIGEST_LENGTH];
18 /* double q is here to ensure 64-bit alignment */
19 double q[WHIRLPOOL_DIGEST_LENGTH/sizeof(double)];
20 } H;
21 unsigned char data[WHIRLPOOL_BBLOCK/8];
22 unsigned int bitoff;
23 size_t bitlen[WHIRLPOOL_COUNTER/sizeof(size_t)];
24 } WHIRLPOOL_CTX;
25
26#ifndef OPENSSL_NO_WHIRLPOOL
27int WHIRLPOOL_Init (WHIRLPOOL_CTX *c);
28int WHIRLPOOL_Update (WHIRLPOOL_CTX *c,const void *inp,size_t bytes);
29void WHIRLPOOL_BitUpdate(WHIRLPOOL_CTX *c,const void *inp,size_t bits);
30int WHIRLPOOL_Final (unsigned char *md,WHIRLPOOL_CTX *c);
31unsigned char *WHIRLPOOL(const void *inp,size_t bytes,unsigned char *md);
32#endif
33
34#ifdef __cplusplus
35}
36#endif
37
38#endif
diff --git a/src/lib/libcrypto/whrlpool/wp_block.c b/src/lib/libcrypto/whrlpool/wp_block.c
new file mode 100644
index 0000000000..221f6cc59f
--- /dev/null
+++ b/src/lib/libcrypto/whrlpool/wp_block.c
@@ -0,0 +1,655 @@
1/**
2 * The Whirlpool hashing function.
3 *
4 * <P>
5 * <b>References</b>
6 *
7 * <P>
8 * The Whirlpool algorithm was developed by
9 * <a href="mailto:pbarreto@scopus.com.br">Paulo S. L. M. Barreto</a> and
10 * <a href="mailto:vincent.rijmen@cryptomathic.com">Vincent Rijmen</a>.
11 *
12 * See
13 * P.S.L.M. Barreto, V. Rijmen,
14 * ``The Whirlpool hashing function,''
15 * NESSIE submission, 2000 (tweaked version, 2001),
16 * <https://www.cosic.esat.kuleuven.ac.be/nessie/workshop/submissions/whirlpool.zip>
17 *
18 * Based on "@version 3.0 (2003.03.12)" by Paulo S.L.M. Barreto and
19 * Vincent Rijmen. Lookup "reference implementations" on
20 * <http://planeta.terra.com.br/informatica/paulobarreto/>
21 *
22 * =============================================================================
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''AS IS'' AND ANY EXPRESS
25 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
26 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE
28 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
29 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
30 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
31 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
32 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
33 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
34 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35 *
36 */
37
38#include "wp_locl.h"
39#include <string.h>
40
41typedef unsigned char u8;
42#if (defined(_WIN32) || defined(_WIN64)) && !defined(__MINGW32)
43typedef unsigned __int64 u64;
44#elif defined(__arch64__)
45typedef unsigned long u64;
46#else
47typedef unsigned long long u64;
48#endif
49
50#define ROUNDS 10
51
52#define STRICT_ALIGNMENT
53#if defined(__i386) || defined(__i386__) || \
54 defined(__x86_64) || defined(__x86_64__) || \
55 defined(_M_IX86) || defined(_M_AMD64) || defined(_M_X64)
56/* Well, formally there're couple of other architectures, which permit
57 * unaligned loads, specifically those not crossing cache lines, IA-64
58 * and PowerPC... */
59# undef STRICT_ALIGNMENT
60#endif
61
62#undef SMALL_REGISTER_BANK
63#if defined(__i386) || defined(__i386__) || defined(_M_IX86)
64# define SMALL_REGISTER_BANK
65# if defined(WHIRLPOOL_ASM)
66# ifndef OPENSSL_SMALL_FOOTPRINT
67# define OPENSSL_SMALL_FOOTPRINT /* it appears that for elder non-MMX
68 CPUs this is actually faster! */
69# endif
70# define GO_FOR_MMX(ctx,inp,num) do { \
71 extern unsigned long OPENSSL_ia32cap_P; \
72 void whirlpool_block_mmx(void *,const void *,size_t); \
73 if (!(OPENSSL_ia32cap_P & (1<<23))) break; \
74 whirlpool_block_mmx(ctx->H.c,inp,num); return; \
75 } while (0)
76# endif
77#endif
78
79#undef ROTATE
80#if defined(_MSC_VER)
81# if defined(_WIN64) /* applies to both IA-64 and AMD64 */
82# pragma intrinsic(_rotl64)
83# define ROTATE(a,n) _rotl64((a),n)
84# endif
85#elif defined(__GNUC__) && __GNUC__>=2
86# if defined(__x86_64) || defined(__x86_64__)
87# if defined(L_ENDIAN)
88# define ROTATE(a,n) ({ u64 ret; asm ("rolq %1,%0" \
89 : "=r"(ret) : "J"(n),"0"(a) : "cc"); ret; })
90# elif defined(B_ENDIAN)
91 /* Most will argue that x86_64 is always little-endian. Well,
92 * yes, but then we have stratus.com who has modified gcc to
93 * "emulate" big-endian on x86. Is there evidence that they
94 * [or somebody else] won't do same for x86_64? Naturally no.
95 * And this line is waiting ready for that brave soul:-) */
96# define ROTATE(a,n) ({ u64 ret; asm ("rorq %1,%0" \
97 : "=r"(ret) : "J"(n),"0"(a) : "cc"); ret; })
98# endif
99# elif defined(__ia64) || defined(__ia64__)
100# if defined(L_ENDIAN)
101# define ROTATE(a,n) ({ u64 ret; asm ("shrp %0=%1,%1,%2" \
102 : "=r"(ret) : "r"(a),"M"(64-(n))); ret; })
103# elif defined(B_ENDIAN)
104# define ROTATE(a,n) ({ u64 ret; asm ("shrp %0=%1,%1,%2" \
105 : "=r"(ret) : "r"(a),"M"(n)); ret; })
106# endif
107# endif
108#endif
109
110#if defined(OPENSSL_SMALL_FOOTPRINT)
111# if !defined(ROTATE)
112# if defined(L_ENDIAN) /* little-endians have to rotate left */
113# define ROTATE(i,n) ((i)<<(n) ^ (i)>>(64-n))
114# elif defined(B_ENDIAN) /* big-endians have to rotate right */
115# define ROTATE(i,n) ((i)>>(n) ^ (i)<<(64-n))
116# endif
117# endif
118# if defined(ROTATE) && !defined(STRICT_ALIGNMENT)
119# define STRICT_ALIGNMENT /* ensure smallest table size */
120# endif
121#endif
122
123/*
124 * Table size depends on STRICT_ALIGNMENT and whether or not endian-
125 * specific ROTATE macro is defined. If STRICT_ALIGNMENT is not
126 * defined, which is normally the case on x86[_64] CPUs, the table is
127 * 4KB large unconditionally. Otherwise if ROTATE is defined, the
128 * table is 2KB large, and otherwise - 16KB. 2KB table requires a
129 * whole bunch of additional rotations, but I'm willing to "trade,"
130 * because 16KB table certainly trashes L1 cache. I wish all CPUs
131 * could handle unaligned load as 4KB table doesn't trash the cache,
132 * nor does it require additional rotations.
133 */
134/*
135 * Note that every Cn macro expands as two loads: one byte load and
136 * one quadword load. One can argue that that many single-byte loads
137 * is too excessive, as one could load a quadword and "milk" it for
138 * eight 8-bit values instead. Well, yes, but in order to do so *and*
139 * avoid excessive loads you have to accomodate a handful of 64-bit
140 * values in the register bank and issue a bunch of shifts and mask.
141 * It's a tradeoff: loads vs. shift and mask in big register bank[!].
142 * On most CPUs eight single-byte loads are faster and I let other
143 * ones to depend on smart compiler to fold byte loads if beneficial.
144 * Hand-coded assembler would be another alternative:-)
145 */
146#ifdef STRICT_ALIGNMENT
147# if defined(ROTATE)
148# define N 1
149# define LL(c0,c1,c2,c3,c4,c5,c6,c7) c0,c1,c2,c3,c4,c5,c6,c7
150# define C0(K,i) (Cx.q[K.c[(i)*8+0]])
151# define C1(K,i) ROTATE(Cx.q[K.c[(i)*8+1]],8)
152# define C2(K,i) ROTATE(Cx.q[K.c[(i)*8+2]],16)
153# define C3(K,i) ROTATE(Cx.q[K.c[(i)*8+3]],24)
154# define C4(K,i) ROTATE(Cx.q[K.c[(i)*8+4]],32)
155# define C5(K,i) ROTATE(Cx.q[K.c[(i)*8+5]],40)
156# define C6(K,i) ROTATE(Cx.q[K.c[(i)*8+6]],48)
157# define C7(K,i) ROTATE(Cx.q[K.c[(i)*8+7]],56)
158# else
159# define N 8
160# define LL(c0,c1,c2,c3,c4,c5,c6,c7) c0,c1,c2,c3,c4,c5,c6,c7, \
161 c7,c0,c1,c2,c3,c4,c5,c6, \
162 c6,c7,c0,c1,c2,c3,c4,c5, \
163 c5,c6,c7,c0,c1,c2,c3,c4, \
164 c4,c5,c6,c7,c0,c1,c2,c3, \
165 c3,c4,c5,c6,c7,c0,c1,c2, \
166 c2,c3,c4,c5,c6,c7,c0,c1, \
167 c1,c2,c3,c4,c5,c6,c7,c0
168# define C0(K,i) (Cx.q[0+8*K.c[(i)*8+0]])
169# define C1(K,i) (Cx.q[1+8*K.c[(i)*8+1]])
170# define C2(K,i) (Cx.q[2+8*K.c[(i)*8+2]])
171# define C3(K,i) (Cx.q[3+8*K.c[(i)*8+3]])
172# define C4(K,i) (Cx.q[4+8*K.c[(i)*8+4]])
173# define C5(K,i) (Cx.q[5+8*K.c[(i)*8+5]])
174# define C6(K,i) (Cx.q[6+8*K.c[(i)*8+6]])
175# define C7(K,i) (Cx.q[7+8*K.c[(i)*8+7]])
176# endif
177#else
178# define N 2
179# define LL(c0,c1,c2,c3,c4,c5,c6,c7) c0,c1,c2,c3,c4,c5,c6,c7, \
180 c0,c1,c2,c3,c4,c5,c6,c7
181# define C0(K,i) (((u64*)(Cx.c+0))[2*K.c[(i)*8+0]])
182# define C1(K,i) (((u64*)(Cx.c+7))[2*K.c[(i)*8+1]])
183# define C2(K,i) (((u64*)(Cx.c+6))[2*K.c[(i)*8+2]])
184# define C3(K,i) (((u64*)(Cx.c+5))[2*K.c[(i)*8+3]])
185# define C4(K,i) (((u64*)(Cx.c+4))[2*K.c[(i)*8+4]])
186# define C5(K,i) (((u64*)(Cx.c+3))[2*K.c[(i)*8+5]])
187# define C6(K,i) (((u64*)(Cx.c+2))[2*K.c[(i)*8+6]])
188# define C7(K,i) (((u64*)(Cx.c+1))[2*K.c[(i)*8+7]])
189#endif
190
191static const
192union {
193 u8 c[(256*N+ROUNDS)*sizeof(u64)];
194 u64 q[(256*N+ROUNDS)];
195 } Cx = { {
196 /* Note endian-neutral representation:-) */
197 LL(0x18,0x18,0x60,0x18,0xc0,0x78,0x30,0xd8),
198 LL(0x23,0x23,0x8c,0x23,0x05,0xaf,0x46,0x26),
199 LL(0xc6,0xc6,0x3f,0xc6,0x7e,0xf9,0x91,0xb8),
200 LL(0xe8,0xe8,0x87,0xe8,0x13,0x6f,0xcd,0xfb),
201 LL(0x87,0x87,0x26,0x87,0x4c,0xa1,0x13,0xcb),
202 LL(0xb8,0xb8,0xda,0xb8,0xa9,0x62,0x6d,0x11),
203 LL(0x01,0x01,0x04,0x01,0x08,0x05,0x02,0x09),
204 LL(0x4f,0x4f,0x21,0x4f,0x42,0x6e,0x9e,0x0d),
205 LL(0x36,0x36,0xd8,0x36,0xad,0xee,0x6c,0x9b),
206 LL(0xa6,0xa6,0xa2,0xa6,0x59,0x04,0x51,0xff),
207 LL(0xd2,0xd2,0x6f,0xd2,0xde,0xbd,0xb9,0x0c),
208 LL(0xf5,0xf5,0xf3,0xf5,0xfb,0x06,0xf7,0x0e),
209 LL(0x79,0x79,0xf9,0x79,0xef,0x80,0xf2,0x96),
210 LL(0x6f,0x6f,0xa1,0x6f,0x5f,0xce,0xde,0x30),
211 LL(0x91,0x91,0x7e,0x91,0xfc,0xef,0x3f,0x6d),
212 LL(0x52,0x52,0x55,0x52,0xaa,0x07,0xa4,0xf8),
213 LL(0x60,0x60,0x9d,0x60,0x27,0xfd,0xc0,0x47),
214 LL(0xbc,0xbc,0xca,0xbc,0x89,0x76,0x65,0x35),
215 LL(0x9b,0x9b,0x56,0x9b,0xac,0xcd,0x2b,0x37),
216 LL(0x8e,0x8e,0x02,0x8e,0x04,0x8c,0x01,0x8a),
217 LL(0xa3,0xa3,0xb6,0xa3,0x71,0x15,0x5b,0xd2),
218 LL(0x0c,0x0c,0x30,0x0c,0x60,0x3c,0x18,0x6c),
219 LL(0x7b,0x7b,0xf1,0x7b,0xff,0x8a,0xf6,0x84),
220 LL(0x35,0x35,0xd4,0x35,0xb5,0xe1,0x6a,0x80),
221 LL(0x1d,0x1d,0x74,0x1d,0xe8,0x69,0x3a,0xf5),
222 LL(0xe0,0xe0,0xa7,0xe0,0x53,0x47,0xdd,0xb3),
223 LL(0xd7,0xd7,0x7b,0xd7,0xf6,0xac,0xb3,0x21),
224 LL(0xc2,0xc2,0x2f,0xc2,0x5e,0xed,0x99,0x9c),
225 LL(0x2e,0x2e,0xb8,0x2e,0x6d,0x96,0x5c,0x43),
226 LL(0x4b,0x4b,0x31,0x4b,0x62,0x7a,0x96,0x29),
227 LL(0xfe,0xfe,0xdf,0xfe,0xa3,0x21,0xe1,0x5d),
228 LL(0x57,0x57,0x41,0x57,0x82,0x16,0xae,0xd5),
229 LL(0x15,0x15,0x54,0x15,0xa8,0x41,0x2a,0xbd),
230 LL(0x77,0x77,0xc1,0x77,0x9f,0xb6,0xee,0xe8),
231 LL(0x37,0x37,0xdc,0x37,0xa5,0xeb,0x6e,0x92),
232 LL(0xe5,0xe5,0xb3,0xe5,0x7b,0x56,0xd7,0x9e),
233 LL(0x9f,0x9f,0x46,0x9f,0x8c,0xd9,0x23,0x13),
234 LL(0xf0,0xf0,0xe7,0xf0,0xd3,0x17,0xfd,0x23),
235 LL(0x4a,0x4a,0x35,0x4a,0x6a,0x7f,0x94,0x20),
236 LL(0xda,0xda,0x4f,0xda,0x9e,0x95,0xa9,0x44),
237 LL(0x58,0x58,0x7d,0x58,0xfa,0x25,0xb0,0xa2),
238 LL(0xc9,0xc9,0x03,0xc9,0x06,0xca,0x8f,0xcf),
239 LL(0x29,0x29,0xa4,0x29,0x55,0x8d,0x52,0x7c),
240 LL(0x0a,0x0a,0x28,0x0a,0x50,0x22,0x14,0x5a),
241 LL(0xb1,0xb1,0xfe,0xb1,0xe1,0x4f,0x7f,0x50),
242 LL(0xa0,0xa0,0xba,0xa0,0x69,0x1a,0x5d,0xc9),
243 LL(0x6b,0x6b,0xb1,0x6b,0x7f,0xda,0xd6,0x14),
244 LL(0x85,0x85,0x2e,0x85,0x5c,0xab,0x17,0xd9),
245 LL(0xbd,0xbd,0xce,0xbd,0x81,0x73,0x67,0x3c),
246 LL(0x5d,0x5d,0x69,0x5d,0xd2,0x34,0xba,0x8f),
247 LL(0x10,0x10,0x40,0x10,0x80,0x50,0x20,0x90),
248 LL(0xf4,0xf4,0xf7,0xf4,0xf3,0x03,0xf5,0x07),
249 LL(0xcb,0xcb,0x0b,0xcb,0x16,0xc0,0x8b,0xdd),
250 LL(0x3e,0x3e,0xf8,0x3e,0xed,0xc6,0x7c,0xd3),
251 LL(0x05,0x05,0x14,0x05,0x28,0x11,0x0a,0x2d),
252 LL(0x67,0x67,0x81,0x67,0x1f,0xe6,0xce,0x78),
253 LL(0xe4,0xe4,0xb7,0xe4,0x73,0x53,0xd5,0x97),
254 LL(0x27,0x27,0x9c,0x27,0x25,0xbb,0x4e,0x02),
255 LL(0x41,0x41,0x19,0x41,0x32,0x58,0x82,0x73),
256 LL(0x8b,0x8b,0x16,0x8b,0x2c,0x9d,0x0b,0xa7),
257 LL(0xa7,0xa7,0xa6,0xa7,0x51,0x01,0x53,0xf6),
258 LL(0x7d,0x7d,0xe9,0x7d,0xcf,0x94,0xfa,0xb2),
259 LL(0x95,0x95,0x6e,0x95,0xdc,0xfb,0x37,0x49),
260 LL(0xd8,0xd8,0x47,0xd8,0x8e,0x9f,0xad,0x56),
261 LL(0xfb,0xfb,0xcb,0xfb,0x8b,0x30,0xeb,0x70),
262 LL(0xee,0xee,0x9f,0xee,0x23,0x71,0xc1,0xcd),
263 LL(0x7c,0x7c,0xed,0x7c,0xc7,0x91,0xf8,0xbb),
264 LL(0x66,0x66,0x85,0x66,0x17,0xe3,0xcc,0x71),
265 LL(0xdd,0xdd,0x53,0xdd,0xa6,0x8e,0xa7,0x7b),
266 LL(0x17,0x17,0x5c,0x17,0xb8,0x4b,0x2e,0xaf),
267 LL(0x47,0x47,0x01,0x47,0x02,0x46,0x8e,0x45),
268 LL(0x9e,0x9e,0x42,0x9e,0x84,0xdc,0x21,0x1a),
269 LL(0xca,0xca,0x0f,0xca,0x1e,0xc5,0x89,0xd4),
270 LL(0x2d,0x2d,0xb4,0x2d,0x75,0x99,0x5a,0x58),
271 LL(0xbf,0xbf,0xc6,0xbf,0x91,0x79,0x63,0x2e),
272 LL(0x07,0x07,0x1c,0x07,0x38,0x1b,0x0e,0x3f),
273 LL(0xad,0xad,0x8e,0xad,0x01,0x23,0x47,0xac),
274 LL(0x5a,0x5a,0x75,0x5a,0xea,0x2f,0xb4,0xb0),
275 LL(0x83,0x83,0x36,0x83,0x6c,0xb5,0x1b,0xef),
276 LL(0x33,0x33,0xcc,0x33,0x85,0xff,0x66,0xb6),
277 LL(0x63,0x63,0x91,0x63,0x3f,0xf2,0xc6,0x5c),
278 LL(0x02,0x02,0x08,0x02,0x10,0x0a,0x04,0x12),
279 LL(0xaa,0xaa,0x92,0xaa,0x39,0x38,0x49,0x93),
280 LL(0x71,0x71,0xd9,0x71,0xaf,0xa8,0xe2,0xde),
281 LL(0xc8,0xc8,0x07,0xc8,0x0e,0xcf,0x8d,0xc6),
282 LL(0x19,0x19,0x64,0x19,0xc8,0x7d,0x32,0xd1),
283 LL(0x49,0x49,0x39,0x49,0x72,0x70,0x92,0x3b),
284 LL(0xd9,0xd9,0x43,0xd9,0x86,0x9a,0xaf,0x5f),
285 LL(0xf2,0xf2,0xef,0xf2,0xc3,0x1d,0xf9,0x31),
286 LL(0xe3,0xe3,0xab,0xe3,0x4b,0x48,0xdb,0xa8),
287 LL(0x5b,0x5b,0x71,0x5b,0xe2,0x2a,0xb6,0xb9),
288 LL(0x88,0x88,0x1a,0x88,0x34,0x92,0x0d,0xbc),
289 LL(0x9a,0x9a,0x52,0x9a,0xa4,0xc8,0x29,0x3e),
290 LL(0x26,0x26,0x98,0x26,0x2d,0xbe,0x4c,0x0b),
291 LL(0x32,0x32,0xc8,0x32,0x8d,0xfa,0x64,0xbf),
292 LL(0xb0,0xb0,0xfa,0xb0,0xe9,0x4a,0x7d,0x59),
293 LL(0xe9,0xe9,0x83,0xe9,0x1b,0x6a,0xcf,0xf2),
294 LL(0x0f,0x0f,0x3c,0x0f,0x78,0x33,0x1e,0x77),
295 LL(0xd5,0xd5,0x73,0xd5,0xe6,0xa6,0xb7,0x33),
296 LL(0x80,0x80,0x3a,0x80,0x74,0xba,0x1d,0xf4),
297 LL(0xbe,0xbe,0xc2,0xbe,0x99,0x7c,0x61,0x27),
298 LL(0xcd,0xcd,0x13,0xcd,0x26,0xde,0x87,0xeb),
299 LL(0x34,0x34,0xd0,0x34,0xbd,0xe4,0x68,0x89),
300 LL(0x48,0x48,0x3d,0x48,0x7a,0x75,0x90,0x32),
301 LL(0xff,0xff,0xdb,0xff,0xab,0x24,0xe3,0x54),
302 LL(0x7a,0x7a,0xf5,0x7a,0xf7,0x8f,0xf4,0x8d),
303 LL(0x90,0x90,0x7a,0x90,0xf4,0xea,0x3d,0x64),
304 LL(0x5f,0x5f,0x61,0x5f,0xc2,0x3e,0xbe,0x9d),
305 LL(0x20,0x20,0x80,0x20,0x1d,0xa0,0x40,0x3d),
306 LL(0x68,0x68,0xbd,0x68,0x67,0xd5,0xd0,0x0f),
307 LL(0x1a,0x1a,0x68,0x1a,0xd0,0x72,0x34,0xca),
308 LL(0xae,0xae,0x82,0xae,0x19,0x2c,0x41,0xb7),
309 LL(0xb4,0xb4,0xea,0xb4,0xc9,0x5e,0x75,0x7d),
310 LL(0x54,0x54,0x4d,0x54,0x9a,0x19,0xa8,0xce),
311 LL(0x93,0x93,0x76,0x93,0xec,0xe5,0x3b,0x7f),
312 LL(0x22,0x22,0x88,0x22,0x0d,0xaa,0x44,0x2f),
313 LL(0x64,0x64,0x8d,0x64,0x07,0xe9,0xc8,0x63),
314 LL(0xf1,0xf1,0xe3,0xf1,0xdb,0x12,0xff,0x2a),
315 LL(0x73,0x73,0xd1,0x73,0xbf,0xa2,0xe6,0xcc),
316 LL(0x12,0x12,0x48,0x12,0x90,0x5a,0x24,0x82),
317 LL(0x40,0x40,0x1d,0x40,0x3a,0x5d,0x80,0x7a),
318 LL(0x08,0x08,0x20,0x08,0x40,0x28,0x10,0x48),
319 LL(0xc3,0xc3,0x2b,0xc3,0x56,0xe8,0x9b,0x95),
320 LL(0xec,0xec,0x97,0xec,0x33,0x7b,0xc5,0xdf),
321 LL(0xdb,0xdb,0x4b,0xdb,0x96,0x90,0xab,0x4d),
322 LL(0xa1,0xa1,0xbe,0xa1,0x61,0x1f,0x5f,0xc0),
323 LL(0x8d,0x8d,0x0e,0x8d,0x1c,0x83,0x07,0x91),
324 LL(0x3d,0x3d,0xf4,0x3d,0xf5,0xc9,0x7a,0xc8),
325 LL(0x97,0x97,0x66,0x97,0xcc,0xf1,0x33,0x5b),
326 LL(0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00),
327 LL(0xcf,0xcf,0x1b,0xcf,0x36,0xd4,0x83,0xf9),
328 LL(0x2b,0x2b,0xac,0x2b,0x45,0x87,0x56,0x6e),
329 LL(0x76,0x76,0xc5,0x76,0x97,0xb3,0xec,0xe1),
330 LL(0x82,0x82,0x32,0x82,0x64,0xb0,0x19,0xe6),
331 LL(0xd6,0xd6,0x7f,0xd6,0xfe,0xa9,0xb1,0x28),
332 LL(0x1b,0x1b,0x6c,0x1b,0xd8,0x77,0x36,0xc3),
333 LL(0xb5,0xb5,0xee,0xb5,0xc1,0x5b,0x77,0x74),
334 LL(0xaf,0xaf,0x86,0xaf,0x11,0x29,0x43,0xbe),
335 LL(0x6a,0x6a,0xb5,0x6a,0x77,0xdf,0xd4,0x1d),
336 LL(0x50,0x50,0x5d,0x50,0xba,0x0d,0xa0,0xea),
337 LL(0x45,0x45,0x09,0x45,0x12,0x4c,0x8a,0x57),
338 LL(0xf3,0xf3,0xeb,0xf3,0xcb,0x18,0xfb,0x38),
339 LL(0x30,0x30,0xc0,0x30,0x9d,0xf0,0x60,0xad),
340 LL(0xef,0xef,0x9b,0xef,0x2b,0x74,0xc3,0xc4),
341 LL(0x3f,0x3f,0xfc,0x3f,0xe5,0xc3,0x7e,0xda),
342 LL(0x55,0x55,0x49,0x55,0x92,0x1c,0xaa,0xc7),
343 LL(0xa2,0xa2,0xb2,0xa2,0x79,0x10,0x59,0xdb),
344 LL(0xea,0xea,0x8f,0xea,0x03,0x65,0xc9,0xe9),
345 LL(0x65,0x65,0x89,0x65,0x0f,0xec,0xca,0x6a),
346 LL(0xba,0xba,0xd2,0xba,0xb9,0x68,0x69,0x03),
347 LL(0x2f,0x2f,0xbc,0x2f,0x65,0x93,0x5e,0x4a),
348 LL(0xc0,0xc0,0x27,0xc0,0x4e,0xe7,0x9d,0x8e),
349 LL(0xde,0xde,0x5f,0xde,0xbe,0x81,0xa1,0x60),
350 LL(0x1c,0x1c,0x70,0x1c,0xe0,0x6c,0x38,0xfc),
351 LL(0xfd,0xfd,0xd3,0xfd,0xbb,0x2e,0xe7,0x46),
352 LL(0x4d,0x4d,0x29,0x4d,0x52,0x64,0x9a,0x1f),
353 LL(0x92,0x92,0x72,0x92,0xe4,0xe0,0x39,0x76),
354 LL(0x75,0x75,0xc9,0x75,0x8f,0xbc,0xea,0xfa),
355 LL(0x06,0x06,0x18,0x06,0x30,0x1e,0x0c,0x36),
356 LL(0x8a,0x8a,0x12,0x8a,0x24,0x98,0x09,0xae),
357 LL(0xb2,0xb2,0xf2,0xb2,0xf9,0x40,0x79,0x4b),
358 LL(0xe6,0xe6,0xbf,0xe6,0x63,0x59,0xd1,0x85),
359 LL(0x0e,0x0e,0x38,0x0e,0x70,0x36,0x1c,0x7e),
360 LL(0x1f,0x1f,0x7c,0x1f,0xf8,0x63,0x3e,0xe7),
361 LL(0x62,0x62,0x95,0x62,0x37,0xf7,0xc4,0x55),
362 LL(0xd4,0xd4,0x77,0xd4,0xee,0xa3,0xb5,0x3a),
363 LL(0xa8,0xa8,0x9a,0xa8,0x29,0x32,0x4d,0x81),
364 LL(0x96,0x96,0x62,0x96,0xc4,0xf4,0x31,0x52),
365 LL(0xf9,0xf9,0xc3,0xf9,0x9b,0x3a,0xef,0x62),
366 LL(0xc5,0xc5,0x33,0xc5,0x66,0xf6,0x97,0xa3),
367 LL(0x25,0x25,0x94,0x25,0x35,0xb1,0x4a,0x10),
368 LL(0x59,0x59,0x79,0x59,0xf2,0x20,0xb2,0xab),
369 LL(0x84,0x84,0x2a,0x84,0x54,0xae,0x15,0xd0),
370 LL(0x72,0x72,0xd5,0x72,0xb7,0xa7,0xe4,0xc5),
371 LL(0x39,0x39,0xe4,0x39,0xd5,0xdd,0x72,0xec),
372 LL(0x4c,0x4c,0x2d,0x4c,0x5a,0x61,0x98,0x16),
373 LL(0x5e,0x5e,0x65,0x5e,0xca,0x3b,0xbc,0x94),
374 LL(0x78,0x78,0xfd,0x78,0xe7,0x85,0xf0,0x9f),
375 LL(0x38,0x38,0xe0,0x38,0xdd,0xd8,0x70,0xe5),
376 LL(0x8c,0x8c,0x0a,0x8c,0x14,0x86,0x05,0x98),
377 LL(0xd1,0xd1,0x63,0xd1,0xc6,0xb2,0xbf,0x17),
378 LL(0xa5,0xa5,0xae,0xa5,0x41,0x0b,0x57,0xe4),
379 LL(0xe2,0xe2,0xaf,0xe2,0x43,0x4d,0xd9,0xa1),
380 LL(0x61,0x61,0x99,0x61,0x2f,0xf8,0xc2,0x4e),
381 LL(0xb3,0xb3,0xf6,0xb3,0xf1,0x45,0x7b,0x42),
382 LL(0x21,0x21,0x84,0x21,0x15,0xa5,0x42,0x34),
383 LL(0x9c,0x9c,0x4a,0x9c,0x94,0xd6,0x25,0x08),
384 LL(0x1e,0x1e,0x78,0x1e,0xf0,0x66,0x3c,0xee),
385 LL(0x43,0x43,0x11,0x43,0x22,0x52,0x86,0x61),
386 LL(0xc7,0xc7,0x3b,0xc7,0x76,0xfc,0x93,0xb1),
387 LL(0xfc,0xfc,0xd7,0xfc,0xb3,0x2b,0xe5,0x4f),
388 LL(0x04,0x04,0x10,0x04,0x20,0x14,0x08,0x24),
389 LL(0x51,0x51,0x59,0x51,0xb2,0x08,0xa2,0xe3),
390 LL(0x99,0x99,0x5e,0x99,0xbc,0xc7,0x2f,0x25),
391 LL(0x6d,0x6d,0xa9,0x6d,0x4f,0xc4,0xda,0x22),
392 LL(0x0d,0x0d,0x34,0x0d,0x68,0x39,0x1a,0x65),
393 LL(0xfa,0xfa,0xcf,0xfa,0x83,0x35,0xe9,0x79),
394 LL(0xdf,0xdf,0x5b,0xdf,0xb6,0x84,0xa3,0x69),
395 LL(0x7e,0x7e,0xe5,0x7e,0xd7,0x9b,0xfc,0xa9),
396 LL(0x24,0x24,0x90,0x24,0x3d,0xb4,0x48,0x19),
397 LL(0x3b,0x3b,0xec,0x3b,0xc5,0xd7,0x76,0xfe),
398 LL(0xab,0xab,0x96,0xab,0x31,0x3d,0x4b,0x9a),
399 LL(0xce,0xce,0x1f,0xce,0x3e,0xd1,0x81,0xf0),
400 LL(0x11,0x11,0x44,0x11,0x88,0x55,0x22,0x99),
401 LL(0x8f,0x8f,0x06,0x8f,0x0c,0x89,0x03,0x83),
402 LL(0x4e,0x4e,0x25,0x4e,0x4a,0x6b,0x9c,0x04),
403 LL(0xb7,0xb7,0xe6,0xb7,0xd1,0x51,0x73,0x66),
404 LL(0xeb,0xeb,0x8b,0xeb,0x0b,0x60,0xcb,0xe0),
405 LL(0x3c,0x3c,0xf0,0x3c,0xfd,0xcc,0x78,0xc1),
406 LL(0x81,0x81,0x3e,0x81,0x7c,0xbf,0x1f,0xfd),
407 LL(0x94,0x94,0x6a,0x94,0xd4,0xfe,0x35,0x40),
408 LL(0xf7,0xf7,0xfb,0xf7,0xeb,0x0c,0xf3,0x1c),
409 LL(0xb9,0xb9,0xde,0xb9,0xa1,0x67,0x6f,0x18),
410 LL(0x13,0x13,0x4c,0x13,0x98,0x5f,0x26,0x8b),
411 LL(0x2c,0x2c,0xb0,0x2c,0x7d,0x9c,0x58,0x51),
412 LL(0xd3,0xd3,0x6b,0xd3,0xd6,0xb8,0xbb,0x05),
413 LL(0xe7,0xe7,0xbb,0xe7,0x6b,0x5c,0xd3,0x8c),
414 LL(0x6e,0x6e,0xa5,0x6e,0x57,0xcb,0xdc,0x39),
415 LL(0xc4,0xc4,0x37,0xc4,0x6e,0xf3,0x95,0xaa),
416 LL(0x03,0x03,0x0c,0x03,0x18,0x0f,0x06,0x1b),
417 LL(0x56,0x56,0x45,0x56,0x8a,0x13,0xac,0xdc),
418 LL(0x44,0x44,0x0d,0x44,0x1a,0x49,0x88,0x5e),
419 LL(0x7f,0x7f,0xe1,0x7f,0xdf,0x9e,0xfe,0xa0),
420 LL(0xa9,0xa9,0x9e,0xa9,0x21,0x37,0x4f,0x88),
421 LL(0x2a,0x2a,0xa8,0x2a,0x4d,0x82,0x54,0x67),
422 LL(0xbb,0xbb,0xd6,0xbb,0xb1,0x6d,0x6b,0x0a),
423 LL(0xc1,0xc1,0x23,0xc1,0x46,0xe2,0x9f,0x87),
424 LL(0x53,0x53,0x51,0x53,0xa2,0x02,0xa6,0xf1),
425 LL(0xdc,0xdc,0x57,0xdc,0xae,0x8b,0xa5,0x72),
426 LL(0x0b,0x0b,0x2c,0x0b,0x58,0x27,0x16,0x53),
427 LL(0x9d,0x9d,0x4e,0x9d,0x9c,0xd3,0x27,0x01),
428 LL(0x6c,0x6c,0xad,0x6c,0x47,0xc1,0xd8,0x2b),
429 LL(0x31,0x31,0xc4,0x31,0x95,0xf5,0x62,0xa4),
430 LL(0x74,0x74,0xcd,0x74,0x87,0xb9,0xe8,0xf3),
431 LL(0xf6,0xf6,0xff,0xf6,0xe3,0x09,0xf1,0x15),
432 LL(0x46,0x46,0x05,0x46,0x0a,0x43,0x8c,0x4c),
433 LL(0xac,0xac,0x8a,0xac,0x09,0x26,0x45,0xa5),
434 LL(0x89,0x89,0x1e,0x89,0x3c,0x97,0x0f,0xb5),
435 LL(0x14,0x14,0x50,0x14,0xa0,0x44,0x28,0xb4),
436 LL(0xe1,0xe1,0xa3,0xe1,0x5b,0x42,0xdf,0xba),
437 LL(0x16,0x16,0x58,0x16,0xb0,0x4e,0x2c,0xa6),
438 LL(0x3a,0x3a,0xe8,0x3a,0xcd,0xd2,0x74,0xf7),
439 LL(0x69,0x69,0xb9,0x69,0x6f,0xd0,0xd2,0x06),
440 LL(0x09,0x09,0x24,0x09,0x48,0x2d,0x12,0x41),
441 LL(0x70,0x70,0xdd,0x70,0xa7,0xad,0xe0,0xd7),
442 LL(0xb6,0xb6,0xe2,0xb6,0xd9,0x54,0x71,0x6f),
443 LL(0xd0,0xd0,0x67,0xd0,0xce,0xb7,0xbd,0x1e),
444 LL(0xed,0xed,0x93,0xed,0x3b,0x7e,0xc7,0xd6),
445 LL(0xcc,0xcc,0x17,0xcc,0x2e,0xdb,0x85,0xe2),
446 LL(0x42,0x42,0x15,0x42,0x2a,0x57,0x84,0x68),
447 LL(0x98,0x98,0x5a,0x98,0xb4,0xc2,0x2d,0x2c),
448 LL(0xa4,0xa4,0xaa,0xa4,0x49,0x0e,0x55,0xed),
449 LL(0x28,0x28,0xa0,0x28,0x5d,0x88,0x50,0x75),
450 LL(0x5c,0x5c,0x6d,0x5c,0xda,0x31,0xb8,0x86),
451 LL(0xf8,0xf8,0xc7,0xf8,0x93,0x3f,0xed,0x6b),
452 LL(0x86,0x86,0x22,0x86,0x44,0xa4,0x11,0xc2),
453#define RC (&(Cx.q[256*N]))
454 0x18,0x23,0xc6,0xe8,0x87,0xb8,0x01,0x4f, /* rc[ROUNDS] */
455 0x36,0xa6,0xd2,0xf5,0x79,0x6f,0x91,0x52,
456 0x60,0xbc,0x9b,0x8e,0xa3,0x0c,0x7b,0x35,
457 0x1d,0xe0,0xd7,0xc2,0x2e,0x4b,0xfe,0x57,
458 0x15,0x77,0x37,0xe5,0x9f,0xf0,0x4a,0xda,
459 0x58,0xc9,0x29,0x0a,0xb1,0xa0,0x6b,0x85,
460 0xbd,0x5d,0x10,0xf4,0xcb,0x3e,0x05,0x67,
461 0xe4,0x27,0x41,0x8b,0xa7,0x7d,0x95,0xd8,
462 0xfb,0xee,0x7c,0x66,0xdd,0x17,0x47,0x9e,
463 0xca,0x2d,0xbf,0x07,0xad,0x5a,0x83,0x33
464 }
465};
466
467void whirlpool_block(WHIRLPOOL_CTX *ctx,const void *inp,size_t n)
468 {
469 int r;
470 const u8 *p=inp;
471 union { u64 q[8]; u8 c[64]; } S,K,*H=(void *)ctx->H.q;
472
473#ifdef GO_FOR_MMX
474 GO_FOR_MMX(ctx,inp,n);
475#endif
476 do {
477#ifdef OPENSSL_SMALL_FOOTPRINT
478 u64 L[8];
479 int i;
480
481 for (i=0;i<64;i++) S.c[i] = (K.c[i] = H->c[i]) ^ p[i];
482 for (r=0;r<ROUNDS;r++)
483 {
484 for (i=0;i<8;i++)
485 {
486 L[i] = i ? 0 : RC[r];
487 L[i] ^= C0(K,i) ^ C1(K,(i-1)&7) ^
488 C2(K,(i-2)&7) ^ C3(K,(i-3)&7) ^
489 C4(K,(i-4)&7) ^ C5(K,(i-5)&7) ^
490 C6(K,(i-6)&7) ^ C7(K,(i-7)&7);
491 }
492 memcpy (K.q,L,64);
493 for (i=0;i<8;i++)
494 {
495 L[i] ^= C0(S,i) ^ C1(S,(i-1)&7) ^
496 C2(S,(i-2)&7) ^ C3(S,(i-3)&7) ^
497 C4(S,(i-4)&7) ^ C5(S,(i-5)&7) ^
498 C6(S,(i-6)&7) ^ C7(S,(i-7)&7);
499 }
500 memcpy (S.q,L,64);
501 }
502 for (i=0;i<64;i++) H->c[i] ^= S.c[i] ^ p[i];
503#else
504 u64 L0,L1,L2,L3,L4,L5,L6,L7;
505
506#ifdef STRICT_ALIGNMENT
507 if ((size_t)p & 7)
508 {
509 memcpy (S.c,p,64);
510 S.q[0] ^= (K.q[0] = H->q[0]);
511 S.q[1] ^= (K.q[1] = H->q[1]);
512 S.q[2] ^= (K.q[2] = H->q[2]);
513 S.q[3] ^= (K.q[3] = H->q[3]);
514 S.q[4] ^= (K.q[4] = H->q[4]);
515 S.q[5] ^= (K.q[5] = H->q[5]);
516 S.q[6] ^= (K.q[6] = H->q[6]);
517 S.q[7] ^= (K.q[7] = H->q[7]);
518 }
519 else
520#endif
521 {
522 const u64 *pa = (const u64*)p;
523 S.q[0] = (K.q[0] = H->q[0]) ^ pa[0];
524 S.q[1] = (K.q[1] = H->q[1]) ^ pa[1];
525 S.q[2] = (K.q[2] = H->q[2]) ^ pa[2];
526 S.q[3] = (K.q[3] = H->q[3]) ^ pa[3];
527 S.q[4] = (K.q[4] = H->q[4]) ^ pa[4];
528 S.q[5] = (K.q[5] = H->q[5]) ^ pa[5];
529 S.q[6] = (K.q[6] = H->q[6]) ^ pa[6];
530 S.q[7] = (K.q[7] = H->q[7]) ^ pa[7];
531 }
532
533 for(r=0;r<ROUNDS;r++)
534 {
535#ifdef SMALL_REGISTER_BANK
536 L0 = C0(K,0) ^ C1(K,7) ^ C2(K,6) ^ C3(K,5) ^
537 C4(K,4) ^ C5(K,3) ^ C6(K,2) ^ C7(K,1) ^ RC[r];
538 L1 = C0(K,1) ^ C1(K,0) ^ C2(K,7) ^ C3(K,6) ^
539 C4(K,5) ^ C5(K,4) ^ C6(K,3) ^ C7(K,2);
540 L2 = C0(K,2) ^ C1(K,1) ^ C2(K,0) ^ C3(K,7) ^
541 C4(K,6) ^ C5(K,5) ^ C6(K,4) ^ C7(K,3);
542 L3 = C0(K,3) ^ C1(K,2) ^ C2(K,1) ^ C3(K,0) ^
543 C4(K,7) ^ C5(K,6) ^ C6(K,5) ^ C7(K,4);
544 L4 = C0(K,4) ^ C1(K,3) ^ C2(K,2) ^ C3(K,1) ^
545 C4(K,0) ^ C5(K,7) ^ C6(K,6) ^ C7(K,5);
546 L5 = C0(K,5) ^ C1(K,4) ^ C2(K,3) ^ C3(K,2) ^
547 C4(K,1) ^ C5(K,0) ^ C6(K,7) ^ C7(K,6);
548 L6 = C0(K,6) ^ C1(K,5) ^ C2(K,4) ^ C3(K,3) ^
549 C4(K,2) ^ C5(K,1) ^ C6(K,0) ^ C7(K,7);
550 L7 = C0(K,7) ^ C1(K,6) ^ C2(K,5) ^ C3(K,4) ^
551 C4(K,3) ^ C5(K,2) ^ C6(K,1) ^ C7(K,0);
552
553 K.q[0] = L0; K.q[1] = L1; K.q[2] = L2; K.q[3] = L3;
554 K.q[4] = L4; K.q[5] = L5; K.q[6] = L6; K.q[7] = L7;
555
556 L0 ^= C0(S,0) ^ C1(S,7) ^ C2(S,6) ^ C3(S,5) ^
557 C4(S,4) ^ C5(S,3) ^ C6(S,2) ^ C7(S,1);
558 L1 ^= C0(S,1) ^ C1(S,0) ^ C2(S,7) ^ C3(S,6) ^
559 C4(S,5) ^ C5(S,4) ^ C6(S,3) ^ C7(S,2);
560 L2 ^= C0(S,2) ^ C1(S,1) ^ C2(S,0) ^ C3(S,7) ^
561 C4(S,6) ^ C5(S,5) ^ C6(S,4) ^ C7(S,3);
562 L3 ^= C0(S,3) ^ C1(S,2) ^ C2(S,1) ^ C3(S,0) ^
563 C4(S,7) ^ C5(S,6) ^ C6(S,5) ^ C7(S,4);
564 L4 ^= C0(S,4) ^ C1(S,3) ^ C2(S,2) ^ C3(S,1) ^
565 C4(S,0) ^ C5(S,7) ^ C6(S,6) ^ C7(S,5);
566 L5 ^= C0(S,5) ^ C1(S,4) ^ C2(S,3) ^ C3(S,2) ^
567 C4(S,1) ^ C5(S,0) ^ C6(S,7) ^ C7(S,6);
568 L6 ^= C0(S,6) ^ C1(S,5) ^ C2(S,4) ^ C3(S,3) ^
569 C4(S,2) ^ C5(S,1) ^ C6(S,0) ^ C7(S,7);
570 L7 ^= C0(S,7) ^ C1(S,6) ^ C2(S,5) ^ C3(S,4) ^
571 C4(S,3) ^ C5(S,2) ^ C6(S,1) ^ C7(S,0);
572
573 S.q[0] = L0; S.q[1] = L1; S.q[2] = L2; S.q[3] = L3;
574 S.q[4] = L4; S.q[5] = L5; S.q[6] = L6; S.q[7] = L7;
575#else
576 L0 = C0(K,0); L1 = C1(K,0); L2 = C2(K,0); L3 = C3(K,0);
577 L4 = C4(K,0); L5 = C5(K,0); L6 = C6(K,0); L7 = C7(K,0);
578 L0 ^= RC[r];
579
580 L1 ^= C0(K,1); L2 ^= C1(K,1); L3 ^= C2(K,1); L4 ^= C3(K,1);
581 L5 ^= C4(K,1); L6 ^= C5(K,1); L7 ^= C6(K,1); L0 ^= C7(K,1);
582
583 L2 ^= C0(K,2); L3 ^= C1(K,2); L4 ^= C2(K,2); L5 ^= C3(K,2);
584 L6 ^= C4(K,2); L7 ^= C5(K,2); L0 ^= C6(K,2); L1 ^= C7(K,2);
585
586 L3 ^= C0(K,3); L4 ^= C1(K,3); L5 ^= C2(K,3); L6 ^= C3(K,3);
587 L7 ^= C4(K,3); L0 ^= C5(K,3); L1 ^= C6(K,3); L2 ^= C7(K,3);
588
589 L4 ^= C0(K,4); L5 ^= C1(K,4); L6 ^= C2(K,4); L7 ^= C3(K,4);
590 L0 ^= C4(K,4); L1 ^= C5(K,4); L2 ^= C6(K,4); L3 ^= C7(K,4);
591
592 L5 ^= C0(K,5); L6 ^= C1(K,5); L7 ^= C2(K,5); L0 ^= C3(K,5);
593 L1 ^= C4(K,5); L2 ^= C5(K,5); L3 ^= C6(K,5); L4 ^= C7(K,5);
594
595 L6 ^= C0(K,6); L7 ^= C1(K,6); L0 ^= C2(K,6); L1 ^= C3(K,6);
596 L2 ^= C4(K,6); L3 ^= C5(K,6); L4 ^= C6(K,6); L5 ^= C7(K,6);
597
598 L7 ^= C0(K,7); L0 ^= C1(K,7); L1 ^= C2(K,7); L2 ^= C3(K,7);
599 L3 ^= C4(K,7); L4 ^= C5(K,7); L5 ^= C6(K,7); L6 ^= C7(K,7);
600
601 K.q[0] = L0; K.q[1] = L1; K.q[2] = L2; K.q[3] = L3;
602 K.q[4] = L4; K.q[5] = L5; K.q[6] = L6; K.q[7] = L7;
603
604 L0 ^= C0(S,0); L1 ^= C1(S,0); L2 ^= C2(S,0); L3 ^= C3(S,0);
605 L4 ^= C4(S,0); L5 ^= C5(S,0); L6 ^= C6(S,0); L7 ^= C7(S,0);
606
607 L1 ^= C0(S,1); L2 ^= C1(S,1); L3 ^= C2(S,1); L4 ^= C3(S,1);
608 L5 ^= C4(S,1); L6 ^= C5(S,1); L7 ^= C6(S,1); L0 ^= C7(S,1);
609
610 L2 ^= C0(S,2); L3 ^= C1(S,2); L4 ^= C2(S,2); L5 ^= C3(S,2);
611 L6 ^= C4(S,2); L7 ^= C5(S,2); L0 ^= C6(S,2); L1 ^= C7(S,2);
612
613 L3 ^= C0(S,3); L4 ^= C1(S,3); L5 ^= C2(S,3); L6 ^= C3(S,3);
614 L7 ^= C4(S,3); L0 ^= C5(S,3); L1 ^= C6(S,3); L2 ^= C7(S,3);
615
616 L4 ^= C0(S,4); L5 ^= C1(S,4); L6 ^= C2(S,4); L7 ^= C3(S,4);
617 L0 ^= C4(S,4); L1 ^= C5(S,4); L2 ^= C6(S,4); L3 ^= C7(S,4);
618
619 L5 ^= C0(S,5); L6 ^= C1(S,5); L7 ^= C2(S,5); L0 ^= C3(S,5);
620 L1 ^= C4(S,5); L2 ^= C5(S,5); L3 ^= C6(S,5); L4 ^= C7(S,5);
621
622 L6 ^= C0(S,6); L7 ^= C1(S,6); L0 ^= C2(S,6); L1 ^= C3(S,6);
623 L2 ^= C4(S,6); L3 ^= C5(S,6); L4 ^= C6(S,6); L5 ^= C7(S,6);
624
625 L7 ^= C0(S,7); L0 ^= C1(S,7); L1 ^= C2(S,7); L2 ^= C3(S,7);
626 L3 ^= C4(S,7); L4 ^= C5(S,7); L5 ^= C6(S,7); L6 ^= C7(S,7);
627
628 S.q[0] = L0; S.q[1] = L1; S.q[2] = L2; S.q[3] = L3;
629 S.q[4] = L4; S.q[5] = L5; S.q[6] = L6; S.q[7] = L7;
630#endif
631 }
632
633#ifdef STRICT_ALIGNMENT
634 if ((size_t)p & 7)
635 {
636 int i;
637 for(i=0;i<64;i++) H->c[i] ^= S.c[i] ^ p[i];
638 }
639 else
640#endif
641 {
642 const u64 *pa=(const u64 *)p;
643 H->q[0] ^= S.q[0] ^ pa[0];
644 H->q[1] ^= S.q[1] ^ pa[1];
645 H->q[2] ^= S.q[2] ^ pa[2];
646 H->q[3] ^= S.q[3] ^ pa[3];
647 H->q[4] ^= S.q[4] ^ pa[4];
648 H->q[5] ^= S.q[5] ^ pa[5];
649 H->q[6] ^= S.q[6] ^ pa[6];
650 H->q[7] ^= S.q[7] ^ pa[7];
651 }
652#endif
653 p += 64;
654 } while(--n);
655 }
diff --git a/src/lib/libcrypto/whrlpool/wp_dgst.c b/src/lib/libcrypto/whrlpool/wp_dgst.c
new file mode 100644
index 0000000000..ee5c5c1bf3
--- /dev/null
+++ b/src/lib/libcrypto/whrlpool/wp_dgst.c
@@ -0,0 +1,264 @@
1/**
2 * The Whirlpool hashing function.
3 *
4 * <P>
5 * <b>References</b>
6 *
7 * <P>
8 * The Whirlpool algorithm was developed by
9 * <a href="mailto:pbarreto@scopus.com.br">Paulo S. L. M. Barreto</a> and
10 * <a href="mailto:vincent.rijmen@cryptomathic.com">Vincent Rijmen</a>.
11 *
12 * See
13 * P.S.L.M. Barreto, V. Rijmen,
14 * ``The Whirlpool hashing function,''
15 * NESSIE submission, 2000 (tweaked version, 2001),
16 * <https://www.cosic.esat.kuleuven.ac.be/nessie/workshop/submissions/whirlpool.zip>
17 *
18 * Based on "@version 3.0 (2003.03.12)" by Paulo S.L.M. Barreto and
19 * Vincent Rijmen. Lookup "reference implementations" on
20 * <http://planeta.terra.com.br/informatica/paulobarreto/>
21 *
22 * =============================================================================
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''AS IS'' AND ANY EXPRESS
25 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
26 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE
28 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
29 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
30 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
31 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
32 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
33 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
34 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35 *
36 */
37
38/*
39 * OpenSSL-specific implementation notes.
40 *
41 * WHIRLPOOL_Update as well as one-stroke WHIRLPOOL both expect
42 * number of *bytes* as input length argument. Bit-oriented routine
43 * as specified by authors is called WHIRLPOOL_BitUpdate[!] and
44 * does not have one-stroke counterpart.
45 *
46 * WHIRLPOOL_BitUpdate implements byte-oriented loop, essentially
47 * to serve WHIRLPOOL_Update. This is done for performance.
48 *
49 * Unlike authors' reference implementation, block processing
50 * routine whirlpool_block is designed to operate on multi-block
51 * input. This is done for perfomance.
52 */
53
54#include "wp_locl.h"
55#include <string.h>
56
57int WHIRLPOOL_Init (WHIRLPOOL_CTX *c)
58 {
59 memset (c,0,sizeof(*c));
60 return(1);
61 }
62
63int WHIRLPOOL_Update (WHIRLPOOL_CTX *c,const void *_inp,size_t bytes)
64 {
65 /* Well, largest suitable chunk size actually is
66 * (1<<(sizeof(size_t)*8-3))-64, but below number
67 * is large enough for not to care about excessive
68 * calls to WHIRLPOOL_BitUpdate... */
69 size_t chunk = ((size_t)1)<<(sizeof(size_t)*8-4);
70 const unsigned char *inp = _inp;
71
72 while (bytes>=chunk)
73 {
74 WHIRLPOOL_BitUpdate(c,inp,chunk*8);
75 bytes -= chunk;
76 inp += chunk;
77 }
78 if (bytes)
79 WHIRLPOOL_BitUpdate(c,inp,bytes*8);
80
81 return(1);
82 }
83
84void WHIRLPOOL_BitUpdate(WHIRLPOOL_CTX *c,const void *_inp,size_t bits)
85 {
86 size_t n;
87 unsigned int bitoff = c->bitoff,
88 bitrem = bitoff%8,
89 inpgap = (8-(unsigned int)bits%8)&7;
90 const unsigned char *inp=_inp;
91
92 /* This 256-bit increment procedure relies on the size_t
93 * being natural size of CPU register, so that we don't
94 * have to mask the value in order to detect overflows. */
95 c->bitlen[0] += bits;
96 if (c->bitlen[0] < bits) /* overflow */
97 {
98 n = 1;
99 do { c->bitlen[n]++;
100 } while(c->bitlen[n]==0
101 && ++n<(WHIRLPOOL_COUNTER/sizeof(size_t)));
102 }
103
104#ifndef OPENSSL_SMALL_FOOTPRINT
105 reconsider:
106 if (inpgap==0 && bitrem==0) /* byte-oriented loop */
107 {
108 while (bits)
109 {
110 if (bitoff==0 && (n=bits/WHIRLPOOL_BBLOCK))
111 {
112 whirlpool_block(c,inp,n);
113 inp += n*WHIRLPOOL_BBLOCK/8;
114 bits %= WHIRLPOOL_BBLOCK;
115 }
116 else
117 {
118 unsigned int byteoff = bitoff/8;
119
120 bitrem = WHIRLPOOL_BBLOCK - bitoff;/* re-use bitrem */
121 if (bits >= bitrem)
122 {
123 bits -= bitrem;
124 bitrem /= 8;
125 memcpy(c->data+byteoff,inp,bitrem);
126 inp += bitrem;
127 whirlpool_block(c,c->data,1);
128 bitoff = 0;
129 }
130 else
131 {
132 memcpy(c->data+byteoff,inp,bits/8);
133 bitoff += (unsigned int)bits;
134 bits = 0;
135 }
136 c->bitoff = bitoff;
137 }
138 }
139 }
140 else /* bit-oriented loop */
141#endif
142 {
143 /*
144 inp
145 |
146 +-------+-------+-------
147 |||||||||||||||||||||
148 +-------+-------+-------
149 +-------+-------+-------+-------+-------
150 |||||||||||||| c->data
151 +-------+-------+-------+-------+-------
152 |
153 c->bitoff/8
154 */
155 while (bits)
156 {
157 unsigned int byteoff = bitoff/8;
158 unsigned char b;
159
160#ifndef OPENSSL_SMALL_FOOTPRINT
161 if (bitrem==inpgap)
162 {
163 c->data[byteoff++] |= inp[0] & (0xff>>inpgap);
164 inpgap = 8-inpgap;
165 bitoff += inpgap; bitrem = 0; /* bitoff%8 */
166 bits -= inpgap; inpgap = 0; /* bits%8 */
167 inp++;
168 if (bitoff==WHIRLPOOL_BBLOCK)
169 {
170 whirlpool_block(c,c->data,1);
171 bitoff = 0;
172 }
173 c->bitoff = bitoff;
174 goto reconsider;
175 }
176 else
177#endif
178 if (bits>=8)
179 {
180 b = ((inp[0]<<inpgap) | (inp[1]>>(8-inpgap)));
181 b &= 0xff;
182 if (bitrem) c->data[byteoff++] |= b>>bitrem;
183 else c->data[byteoff++] = b;
184 bitoff += 8;
185 bits -= 8;
186 inp++;
187 if (bitoff>=WHIRLPOOL_BBLOCK)
188 {
189 whirlpool_block(c,c->data,1);
190 byteoff = 0;
191 bitoff %= WHIRLPOOL_BBLOCK;
192 }
193 if (bitrem) c->data[byteoff] = b<<(8-bitrem);
194 }
195 else /* remaining less than 8 bits */
196 {
197 b = (inp[0]<<inpgap)&0xff;
198 if (bitrem) c->data[byteoff++] |= b>>bitrem;
199 else c->data[byteoff++] = b;
200 bitoff += (unsigned int)bits;
201 if (bitoff==WHIRLPOOL_BBLOCK)
202 {
203 whirlpool_block(c,c->data,1);
204 byteoff = 0;
205 bitoff %= WHIRLPOOL_BBLOCK;
206 }
207 if (bitrem) c->data[byteoff] = b<<(8-bitrem);
208 bits = 0;
209 }
210 c->bitoff = bitoff;
211 }
212 }
213 }
214
215int WHIRLPOOL_Final (unsigned char *md,WHIRLPOOL_CTX *c)
216 {
217 unsigned int bitoff = c->bitoff,
218 byteoff = bitoff/8;
219 size_t i,j,v;
220 unsigned char *p;
221
222 bitoff %= 8;
223 if (bitoff) c->data[byteoff] |= 0x80>>bitoff;
224 else c->data[byteoff] = 0x80;
225 byteoff++;
226
227 /* pad with zeros */
228 if (byteoff > (WHIRLPOOL_BBLOCK/8-WHIRLPOOL_COUNTER))
229 {
230 if (byteoff<WHIRLPOOL_BBLOCK/8)
231 memset(&c->data[byteoff],0,WHIRLPOOL_BBLOCK/8-byteoff);
232 whirlpool_block(c,c->data,1);
233 byteoff = 0;
234 }
235 if (byteoff < (WHIRLPOOL_BBLOCK/8-WHIRLPOOL_COUNTER))
236 memset(&c->data[byteoff],0,
237 (WHIRLPOOL_BBLOCK/8-WHIRLPOOL_COUNTER)-byteoff);
238 /* smash 256-bit c->bitlen in big-endian order */
239 p = &c->data[WHIRLPOOL_BBLOCK/8-1]; /* last byte in c->data */
240 for(i=0;i<WHIRLPOOL_COUNTER/sizeof(size_t);i++)
241 for(v=c->bitlen[i],j=0;j<sizeof(size_t);j++,v>>=8)
242 *p-- = (unsigned char)(v&0xff);
243
244 whirlpool_block(c,c->data,1);
245
246 if (md) {
247 memcpy(md,c->H.c,WHIRLPOOL_DIGEST_LENGTH);
248 memset(c,0,sizeof(*c));
249 return(1);
250 }
251 return(0);
252 }
253
254unsigned char *WHIRLPOOL(const void *inp, size_t bytes,unsigned char *md)
255 {
256 WHIRLPOOL_CTX ctx;
257 static unsigned char m[WHIRLPOOL_DIGEST_LENGTH];
258
259 if (md == NULL) md=m;
260 WHIRLPOOL_Init(&ctx);
261 WHIRLPOOL_Update(&ctx,inp,bytes);
262 WHIRLPOOL_Final(md,&ctx);
263 return(md);
264 }
diff --git a/src/lib/libcrypto/whrlpool/wp_locl.h b/src/lib/libcrypto/whrlpool/wp_locl.h
new file mode 100644
index 0000000000..94e56a39f1
--- /dev/null
+++ b/src/lib/libcrypto/whrlpool/wp_locl.h
@@ -0,0 +1,3 @@
1#include <openssl/whrlpool.h>
2
3void whirlpool_block(WHIRLPOOL_CTX *,const void *,size_t);
diff --git a/src/lib/libcrypto/x509/by_dir.c b/src/lib/libcrypto/x509/by_dir.c
index 341e0ba6a4..27ca5150c1 100644
--- a/src/lib/libcrypto/x509/by_dir.c
+++ b/src/lib/libcrypto/x509/by_dir.c
@@ -65,28 +65,36 @@
65#ifndef NO_SYS_TYPES_H 65#ifndef NO_SYS_TYPES_H
66# include <sys/types.h> 66# include <sys/types.h>
67#endif 67#endif
68#ifdef MAC_OS_pre_X 68#ifndef OPENSSL_NO_POSIX_IO
69# include <stat.h>
70#else
71# include <sys/stat.h> 69# include <sys/stat.h>
72#endif 70#endif
73 71
74#include <openssl/lhash.h> 72#include <openssl/lhash.h>
75#include <openssl/x509.h> 73#include <openssl/x509.h>
76 74
77#ifdef _WIN32 75
78#define stat _stat 76typedef struct lookup_dir_hashes_st
79#endif 77 {
78 unsigned long hash;
79 int suffix;
80 } BY_DIR_HASH;
81
82typedef struct lookup_dir_entry_st
83 {
84 char *dir;
85 int dir_type;
86 STACK_OF(BY_DIR_HASH) *hashes;
87 } BY_DIR_ENTRY;
80 88
81typedef struct lookup_dir_st 89typedef struct lookup_dir_st
82 { 90 {
83 BUF_MEM *buffer; 91 BUF_MEM *buffer;
84 int num_dirs; 92 STACK_OF(BY_DIR_ENTRY) *dirs;
85 char **dirs;
86 int *dirs_type;
87 int num_dirs_alloced;
88 } BY_DIR; 93 } BY_DIR;
89 94
95DECLARE_STACK_OF(BY_DIR_HASH)
96DECLARE_STACK_OF(BY_DIR_ENTRY)
97
90static int dir_ctrl(X509_LOOKUP *ctx, int cmd, const char *argp, long argl, 98static int dir_ctrl(X509_LOOKUP *ctx, int cmd, const char *argp, long argl,
91 char **ret); 99 char **ret);
92static int new_dir(X509_LOOKUP *lu); 100static int new_dir(X509_LOOKUP *lu);
@@ -127,7 +135,7 @@ static int dir_ctrl(X509_LOOKUP *ctx, int cmd, const char *argp, long argl,
127 case X509_L_ADD_DIR: 135 case X509_L_ADD_DIR:
128 if (argl == X509_FILETYPE_DEFAULT) 136 if (argl == X509_FILETYPE_DEFAULT)
129 { 137 {
130 dir=(char *)Getenv(X509_get_default_cert_dir_env()); 138 dir=(char *)getenv(X509_get_default_cert_dir_env());
131 if (dir) 139 if (dir)
132 ret=add_cert_dir(ld,dir,X509_FILETYPE_PEM); 140 ret=add_cert_dir(ld,dir,X509_FILETYPE_PEM);
133 else 141 else
@@ -156,34 +164,51 @@ static int new_dir(X509_LOOKUP *lu)
156 OPENSSL_free(a); 164 OPENSSL_free(a);
157 return(0); 165 return(0);
158 } 166 }
159 a->num_dirs=0;
160 a->dirs=NULL; 167 a->dirs=NULL;
161 a->dirs_type=NULL;
162 a->num_dirs_alloced=0;
163 lu->method_data=(char *)a; 168 lu->method_data=(char *)a;
164 return(1); 169 return(1);
165 } 170 }
166 171
172static void by_dir_hash_free(BY_DIR_HASH *hash)
173 {
174 OPENSSL_free(hash);
175 }
176
177static int by_dir_hash_cmp(const BY_DIR_HASH * const *a,
178 const BY_DIR_HASH * const *b)
179 {
180 if ((*a)->hash > (*b)->hash)
181 return 1;
182 if ((*a)->hash < (*b)->hash)
183 return -1;
184 return 0;
185 }
186
187static void by_dir_entry_free(BY_DIR_ENTRY *ent)
188 {
189 if (ent->dir)
190 OPENSSL_free(ent->dir);
191 if (ent->hashes)
192 sk_BY_DIR_HASH_pop_free(ent->hashes, by_dir_hash_free);
193 OPENSSL_free(ent);
194 }
195
167static void free_dir(X509_LOOKUP *lu) 196static void free_dir(X509_LOOKUP *lu)
168 { 197 {
169 BY_DIR *a; 198 BY_DIR *a;
170 int i;
171 199
172 a=(BY_DIR *)lu->method_data; 200 a=(BY_DIR *)lu->method_data;
173 for (i=0; i<a->num_dirs; i++) 201 if (a->dirs != NULL)
174 if (a->dirs[i] != NULL) OPENSSL_free(a->dirs[i]); 202 sk_BY_DIR_ENTRY_pop_free(a->dirs, by_dir_entry_free);
175 if (a->dirs != NULL) OPENSSL_free(a->dirs); 203 if (a->buffer != NULL)
176 if (a->dirs_type != NULL) OPENSSL_free(a->dirs_type); 204 BUF_MEM_free(a->buffer);
177 if (a->buffer != NULL) BUF_MEM_free(a->buffer);
178 OPENSSL_free(a); 205 OPENSSL_free(a);
179 } 206 }
180 207
181static int add_cert_dir(BY_DIR *ctx, const char *dir, int type) 208static int add_cert_dir(BY_DIR *ctx, const char *dir, int type)
182 { 209 {
183 int j,len; 210 int j,len;
184 int *ip;
185 const char *s,*ss,*p; 211 const char *s,*ss,*p;
186 char **pp;
187 212
188 if (dir == NULL || !*dir) 213 if (dir == NULL || !*dir)
189 { 214 {
@@ -197,49 +222,52 @@ static int add_cert_dir(BY_DIR *ctx, const char *dir, int type)
197 { 222 {
198 if ((*p == LIST_SEPARATOR_CHAR) || (*p == '\0')) 223 if ((*p == LIST_SEPARATOR_CHAR) || (*p == '\0'))
199 { 224 {
225 BY_DIR_ENTRY *ent;
200 ss=s; 226 ss=s;
201 s=p+1; 227 s=p+1;
202 len=(int)(p-ss); 228 len=(int)(p-ss);
203 if (len == 0) continue; 229 if (len == 0) continue;
204 for (j=0; j<ctx->num_dirs; j++) 230 for (j=0; j < sk_BY_DIR_ENTRY_num(ctx->dirs); j++)
205 if (strlen(ctx->dirs[j]) == (size_t)len && 231 {
206 strncmp(ctx->dirs[j],ss,(unsigned int)len) == 0) 232 ent = sk_BY_DIR_ENTRY_value(ctx->dirs, j);
233 if (strlen(ent->dir) == (size_t)len &&
234 strncmp(ent->dir,ss,(unsigned int)len) == 0)
207 break; 235 break;
208 if (j<ctx->num_dirs) 236 }
237 if (j < sk_BY_DIR_ENTRY_num(ctx->dirs))
209 continue; 238 continue;
210 if (ctx->num_dirs_alloced < (ctx->num_dirs+1)) 239 if (ctx->dirs == NULL)
211 { 240 {
212 ctx->num_dirs_alloced+=10; 241 ctx->dirs = sk_BY_DIR_ENTRY_new_null();
213 pp=(char **)OPENSSL_malloc(ctx->num_dirs_alloced* 242 if (!ctx->dirs)
214 sizeof(char *));
215 ip=(int *)OPENSSL_malloc(ctx->num_dirs_alloced*
216 sizeof(int));
217 if ((pp == NULL) || (ip == NULL))
218 { 243 {
219 X509err(X509_F_ADD_CERT_DIR,ERR_R_MALLOC_FAILURE); 244 X509err(X509_F_ADD_CERT_DIR,ERR_R_MALLOC_FAILURE);
220 return(0); 245 return 0;
221 } 246 }
222 memcpy(pp,ctx->dirs,(ctx->num_dirs_alloced-10)*
223 sizeof(char *));
224 memcpy(ip,ctx->dirs_type,(ctx->num_dirs_alloced-10)*
225 sizeof(int));
226 if (ctx->dirs != NULL)
227 OPENSSL_free(ctx->dirs);
228 if (ctx->dirs_type != NULL)
229 OPENSSL_free(ctx->dirs_type);
230 ctx->dirs=pp;
231 ctx->dirs_type=ip;
232 } 247 }
233 ctx->dirs_type[ctx->num_dirs]=type; 248 ent = OPENSSL_malloc(sizeof(BY_DIR_ENTRY));
234 ctx->dirs[ctx->num_dirs]=(char *)OPENSSL_malloc((unsigned int)len+1); 249 if (!ent)
235 if (ctx->dirs[ctx->num_dirs] == NULL) return(0); 250 return 0;
236 strncpy(ctx->dirs[ctx->num_dirs],ss,(unsigned int)len); 251 ent->dir_type = type;
237 ctx->dirs[ctx->num_dirs][len]='\0'; 252 ent->hashes = sk_BY_DIR_HASH_new(by_dir_hash_cmp);
238 ctx->num_dirs++; 253 ent->dir = OPENSSL_malloc((unsigned int)len+1);
254 if (!ent->dir || !ent->hashes)
255 {
256 by_dir_entry_free(ent);
257 return 0;
258 }
259 strncpy(ent->dir,ss,(unsigned int)len);
260 ent->dir[len] = '\0';
261 if (!sk_BY_DIR_ENTRY_push(ctx->dirs, ent))
262 {
263 by_dir_entry_free(ent);
264 return 0;
265 }
239 } 266 }
240 if (*p == '\0') break; 267 if (*p == '\0')
268 break;
241 } 269 }
242 return(1); 270 return 1;
243 } 271 }
244 272
245static int get_cert_by_subject(X509_LOOKUP *xl, int type, X509_NAME *name, 273static int get_cert_by_subject(X509_LOOKUP *xl, int type, X509_NAME *name,
@@ -260,7 +288,6 @@ static int get_cert_by_subject(X509_LOOKUP *xl, int type, X509_NAME *name,
260 int i,j,k; 288 int i,j,k;
261 unsigned long h; 289 unsigned long h;
262 BUF_MEM *b=NULL; 290 BUF_MEM *b=NULL;
263 struct stat st;
264 X509_OBJECT stmp,*tmp; 291 X509_OBJECT stmp,*tmp;
265 const char *postfix=""; 292 const char *postfix="";
266 293
@@ -296,20 +323,45 @@ static int get_cert_by_subject(X509_LOOKUP *xl, int type, X509_NAME *name,
296 ctx=(BY_DIR *)xl->method_data; 323 ctx=(BY_DIR *)xl->method_data;
297 324
298 h=X509_NAME_hash(name); 325 h=X509_NAME_hash(name);
299 for (i=0; i<ctx->num_dirs; i++) 326 for (i=0; i < sk_BY_DIR_ENTRY_num(ctx->dirs); i++)
300 { 327 {
301 j=strlen(ctx->dirs[i])+1+8+6+1+1; 328 BY_DIR_ENTRY *ent;
329 int idx;
330 BY_DIR_HASH htmp, *hent;
331 ent = sk_BY_DIR_ENTRY_value(ctx->dirs, i);
332 j=strlen(ent->dir)+1+8+6+1+1;
302 if (!BUF_MEM_grow(b,j)) 333 if (!BUF_MEM_grow(b,j))
303 { 334 {
304 X509err(X509_F_GET_CERT_BY_SUBJECT,ERR_R_MALLOC_FAILURE); 335 X509err(X509_F_GET_CERT_BY_SUBJECT,ERR_R_MALLOC_FAILURE);
305 goto finish; 336 goto finish;
306 } 337 }
307 k=0; 338 if (type == X509_LU_CRL && ent->hashes)
339 {
340 htmp.hash = h;
341 CRYPTO_r_lock(CRYPTO_LOCK_X509_STORE);
342 idx = sk_BY_DIR_HASH_find(ent->hashes, &htmp);
343 if (idx >= 0)
344 {
345 hent = sk_BY_DIR_HASH_value(ent->hashes, idx);
346 k = hent->suffix;
347 }
348 else
349 {
350 hent = NULL;
351 k=0;
352 }
353 CRYPTO_r_unlock(CRYPTO_LOCK_X509_STORE);
354 }
355 else
356 {
357 k = 0;
358 hent = NULL;
359 }
308 for (;;) 360 for (;;)
309 { 361 {
310 char c = '/'; 362 char c = '/';
311#ifdef OPENSSL_SYS_VMS 363#ifdef OPENSSL_SYS_VMS
312 c = ctx->dirs[i][strlen(ctx->dirs[i])-1]; 364 c = ent->dir[strlen(ent->dir)-1];
313 if (c != ':' && c != '>' && c != ']') 365 if (c != ':' && c != '>' && c != ']')
314 { 366 {
315 /* If no separator is present, we assume the 367 /* If no separator is present, we assume the
@@ -330,41 +382,86 @@ static int get_cert_by_subject(X509_LOOKUP *xl, int type, X509_NAME *name,
330 /* This is special. When c == '\0', no 382 /* This is special. When c == '\0', no
331 directory separator should be added. */ 383 directory separator should be added. */
332 BIO_snprintf(b->data,b->max, 384 BIO_snprintf(b->data,b->max,
333 "%s%08lx.%s%d",ctx->dirs[i],h, 385 "%s%08lx.%s%d",ent->dir,h,
334 postfix,k); 386 postfix,k);
335 } 387 }
336 else 388 else
337 { 389 {
338 BIO_snprintf(b->data,b->max, 390 BIO_snprintf(b->data,b->max,
339 "%s%c%08lx.%s%d",ctx->dirs[i],c,h, 391 "%s%c%08lx.%s%d",ent->dir,c,h,
340 postfix,k); 392 postfix,k);
341 } 393 }
342 k++; 394#ifndef OPENSSL_NO_POSIX_IO
395#ifdef _WIN32
396#define stat _stat
397#endif
398 {
399 struct stat st;
343 if (stat(b->data,&st) < 0) 400 if (stat(b->data,&st) < 0)
344 break; 401 break;
402 }
403#endif
345 /* found one. */ 404 /* found one. */
346 if (type == X509_LU_X509) 405 if (type == X509_LU_X509)
347 { 406 {
348 if ((X509_load_cert_file(xl,b->data, 407 if ((X509_load_cert_file(xl,b->data,
349 ctx->dirs_type[i])) == 0) 408 ent->dir_type)) == 0)
350 break; 409 break;
351 } 410 }
352 else if (type == X509_LU_CRL) 411 else if (type == X509_LU_CRL)
353 { 412 {
354 if ((X509_load_crl_file(xl,b->data, 413 if ((X509_load_crl_file(xl,b->data,
355 ctx->dirs_type[i])) == 0) 414 ent->dir_type)) == 0)
356 break; 415 break;
357 } 416 }
358 /* else case will caught higher up */ 417 /* else case will caught higher up */
418 k++;
359 } 419 }
360 420
361 /* we have added it to the cache so now pull 421 /* we have added it to the cache so now pull
362 * it out again */ 422 * it out again */
363 CRYPTO_r_lock(CRYPTO_LOCK_X509_STORE); 423 CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE);
364 j = sk_X509_OBJECT_find(xl->store_ctx->objs,&stmp); 424 j = sk_X509_OBJECT_find(xl->store_ctx->objs,&stmp);
365 if(j != -1) tmp=sk_X509_OBJECT_value(xl->store_ctx->objs,j); 425 if(j != -1) tmp=sk_X509_OBJECT_value(xl->store_ctx->objs,j);
366 else tmp = NULL; 426 else tmp = NULL;
367 CRYPTO_r_unlock(CRYPTO_LOCK_X509_STORE); 427 CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
428
429
430 /* If a CRL, update the last file suffix added for this */
431
432 if (type == X509_LU_CRL)
433 {
434 CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE);
435 /* Look for entry again in case another thread added
436 * an entry first.
437 */
438 if (!hent)
439 {
440 htmp.hash = h;
441 idx = sk_BY_DIR_HASH_find(ent->hashes, &htmp);
442 if (idx >= 0)
443 hent =
444 sk_BY_DIR_HASH_value(ent->hashes, idx);
445 }
446 if (!hent)
447 {
448 hent = OPENSSL_malloc(sizeof(BY_DIR_HASH));
449 hent->hash = h;
450 hent->suffix = k;
451 if (!sk_BY_DIR_HASH_push(ent->hashes, hent))
452 {
453 CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
454 OPENSSL_free(hent);
455 ok = 0;
456 goto finish;
457 }
458 }
459 else if (hent->suffix < k)
460 hent->suffix = k;
461
462 CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
463
464 }
368 465
369 if (tmp != NULL) 466 if (tmp != NULL)
370 { 467 {
@@ -383,4 +480,3 @@ finish:
383 if (b != NULL) BUF_MEM_free(b); 480 if (b != NULL) BUF_MEM_free(b);
384 return(ok); 481 return(ok);
385 } 482 }
386
diff --git a/src/lib/libcrypto/x509/by_file.c b/src/lib/libcrypto/x509/by_file.c
index a5e0d4aefa..57b08ee094 100644
--- a/src/lib/libcrypto/x509/by_file.c
+++ b/src/lib/libcrypto/x509/by_file.c
@@ -100,7 +100,7 @@ static int by_file_ctrl(X509_LOOKUP *ctx, int cmd, const char *argp, long argl,
100 case X509_L_FILE_LOAD: 100 case X509_L_FILE_LOAD:
101 if (argl == X509_FILETYPE_DEFAULT) 101 if (argl == X509_FILETYPE_DEFAULT)
102 { 102 {
103 file = (char *)Getenv(X509_get_default_cert_file_env()); 103 file = (char *)getenv(X509_get_default_cert_file_env());
104 if (file) 104 if (file)
105 ok = (X509_load_cert_crl_file(ctx,file, 105 ok = (X509_load_cert_crl_file(ctx,file,
106 X509_FILETYPE_PEM) != 0); 106 X509_FILETYPE_PEM) != 0);
diff --git a/src/lib/libcrypto/x509/x509.h b/src/lib/libcrypto/x509/x509.h
index e71b5257e5..604f4fb27f 100644
--- a/src/lib/libcrypto/x509/x509.h
+++ b/src/lib/libcrypto/x509/x509.h
@@ -116,6 +116,7 @@ extern "C" {
116/* Under Win32 these are defined in wincrypt.h */ 116/* Under Win32 these are defined in wincrypt.h */
117#undef X509_NAME 117#undef X509_NAME
118#undef X509_CERT_PAIR 118#undef X509_CERT_PAIR
119#undef X509_EXTENSIONS
119#endif 120#endif
120 121
121#define X509_FILETYPE_PEM 1 122#define X509_FILETYPE_PEM 1
@@ -156,12 +157,12 @@ typedef struct X509_val_st
156 ASN1_TIME *notAfter; 157 ASN1_TIME *notAfter;
157 } X509_VAL; 158 } X509_VAL;
158 159
159typedef struct X509_pubkey_st 160struct X509_pubkey_st
160 { 161 {
161 X509_ALGOR *algor; 162 X509_ALGOR *algor;
162 ASN1_BIT_STRING *public_key; 163 ASN1_BIT_STRING *public_key;
163 EVP_PKEY *pkey; 164 EVP_PKEY *pkey;
164 } X509_PUBKEY; 165 };
165 166
166typedef struct X509_sig_st 167typedef struct X509_sig_st
167 { 168 {
@@ -190,7 +191,9 @@ struct X509_name_st
190#else 191#else
191 char *bytes; 192 char *bytes;
192#endif 193#endif
193 unsigned long hash; /* Keep the hash around for lookups */ 194/* unsigned long hash; Keep the hash around for lookups */
195 unsigned char *canon_enc;
196 int canon_enclen;
194 } /* X509_NAME */; 197 } /* X509_NAME */;
195 198
196DECLARE_STACK_OF(X509_NAME) 199DECLARE_STACK_OF(X509_NAME)
@@ -289,8 +292,11 @@ struct x509_st
289 unsigned long ex_xkusage; 292 unsigned long ex_xkusage;
290 unsigned long ex_nscert; 293 unsigned long ex_nscert;
291 ASN1_OCTET_STRING *skid; 294 ASN1_OCTET_STRING *skid;
292 struct AUTHORITY_KEYID_st *akid; 295 AUTHORITY_KEYID *akid;
293 X509_POLICY_CACHE *policy_cache; 296 X509_POLICY_CACHE *policy_cache;
297 STACK_OF(DIST_POINT) *crldp;
298 STACK_OF(GENERAL_NAME) *altname;
299 NAME_CONSTRAINTS *nc;
294#ifndef OPENSSL_NO_RFC3779 300#ifndef OPENSSL_NO_RFC3779
295 STACK_OF(IPAddressFamily) *rfc3779_addr; 301 STACK_OF(IPAddressFamily) *rfc3779_addr;
296 struct ASIdentifiers_st *rfc3779_asid; 302 struct ASIdentifiers_st *rfc3779_asid;
@@ -333,10 +339,11 @@ typedef struct x509_cert_pair_st {
333#define X509_TRUST_OBJECT_SIGN 5 339#define X509_TRUST_OBJECT_SIGN 5
334#define X509_TRUST_OCSP_SIGN 6 340#define X509_TRUST_OCSP_SIGN 6
335#define X509_TRUST_OCSP_REQUEST 7 341#define X509_TRUST_OCSP_REQUEST 7
342#define X509_TRUST_TSA 8
336 343
337/* Keep these up to date! */ 344/* Keep these up to date! */
338#define X509_TRUST_MIN 1 345#define X509_TRUST_MIN 1
339#define X509_TRUST_MAX 7 346#define X509_TRUST_MAX 8
340 347
341 348
342/* trust_flags values */ 349/* trust_flags values */
@@ -423,13 +430,17 @@ typedef struct x509_cert_pair_st {
423 XN_FLAG_FN_LN | \ 430 XN_FLAG_FN_LN | \
424 XN_FLAG_FN_ALIGN) 431 XN_FLAG_FN_ALIGN)
425 432
426typedef struct X509_revoked_st 433struct x509_revoked_st
427 { 434 {
428 ASN1_INTEGER *serialNumber; 435 ASN1_INTEGER *serialNumber;
429 ASN1_TIME *revocationDate; 436 ASN1_TIME *revocationDate;
430 STACK_OF(X509_EXTENSION) /* optional */ *extensions; 437 STACK_OF(X509_EXTENSION) /* optional */ *extensions;
438 /* Set up if indirect CRL */
439 STACK_OF(GENERAL_NAME) *issuer;
440 /* Revocation reason */
441 int reason;
431 int sequence; /* load sequence */ 442 int sequence; /* load sequence */
432 } X509_REVOKED; 443 };
433 444
434DECLARE_STACK_OF(X509_REVOKED) 445DECLARE_STACK_OF(X509_REVOKED)
435DECLARE_ASN1_SET_OF(X509_REVOKED) 446DECLARE_ASN1_SET_OF(X509_REVOKED)
@@ -453,6 +464,22 @@ struct X509_crl_st
453 X509_ALGOR *sig_alg; 464 X509_ALGOR *sig_alg;
454 ASN1_BIT_STRING *signature; 465 ASN1_BIT_STRING *signature;
455 int references; 466 int references;
467 int flags;
468 /* Copies of various extensions */
469 AUTHORITY_KEYID *akid;
470 ISSUING_DIST_POINT *idp;
471 /* Convenient breakdown of IDP */
472 int idp_flags;
473 int idp_reasons;
474 /* CRL and base CRL numbers for delta processing */
475 ASN1_INTEGER *crl_number;
476 ASN1_INTEGER *base_crl_number;
477#ifndef OPENSSL_NO_SHA
478 unsigned char sha1_hash[SHA_DIGEST_LENGTH];
479#endif
480 STACK_OF(GENERAL_NAMES) *issuers;
481 const X509_CRL_METHOD *meth;
482 void *meth_data;
456 } /* X509_CRL */; 483 } /* X509_CRL */;
457 484
458DECLARE_STACK_OF(X509_CRL) 485DECLARE_STACK_OF(X509_CRL)
@@ -551,18 +578,19 @@ X509_ALGOR *prf;
551 578
552/* PKCS#8 private key info structure */ 579/* PKCS#8 private key info structure */
553 580
554typedef struct pkcs8_priv_key_info_st 581struct pkcs8_priv_key_info_st
555 { 582 {
556 int broken; /* Flag for various broken formats */ 583 int broken; /* Flag for various broken formats */
557#define PKCS8_OK 0 584#define PKCS8_OK 0
558#define PKCS8_NO_OCTET 1 585#define PKCS8_NO_OCTET 1
559#define PKCS8_EMBEDDED_PARAM 2 586#define PKCS8_EMBEDDED_PARAM 2
560#define PKCS8_NS_DB 3 587#define PKCS8_NS_DB 3
588#define PKCS8_NEG_PRIVKEY 4
561 ASN1_INTEGER *version; 589 ASN1_INTEGER *version;
562 X509_ALGOR *pkeyalg; 590 X509_ALGOR *pkeyalg;
563 ASN1_TYPE *pkey; /* Should be OCTET STRING but some are broken */ 591 ASN1_TYPE *pkey; /* Should be OCTET STRING but some are broken */
564 STACK_OF(X509_ATTRIBUTE) *attributes; 592 STACK_OF(X509_ATTRIBUTE) *attributes;
565 } PKCS8_PRIV_KEY_INFO; 593 };
566 594
567#ifdef __cplusplus 595#ifdef __cplusplus
568} 596}
@@ -575,151 +603,6 @@ typedef struct pkcs8_priv_key_info_st
575extern "C" { 603extern "C" {
576#endif 604#endif
577 605
578#ifdef SSLEAY_MACROS
579#define X509_verify(a,r) ASN1_verify((int (*)())i2d_X509_CINF,a->sig_alg,\
580 a->signature,(char *)a->cert_info,r)
581#define X509_REQ_verify(a,r) ASN1_verify((int (*)())i2d_X509_REQ_INFO, \
582 a->sig_alg,a->signature,(char *)a->req_info,r)
583#define X509_CRL_verify(a,r) ASN1_verify((int (*)())i2d_X509_CRL_INFO, \
584 a->sig_alg, a->signature,(char *)a->crl,r)
585
586#define X509_sign(x,pkey,md) \
587 ASN1_sign((int (*)())i2d_X509_CINF, x->cert_info->signature, \
588 x->sig_alg, x->signature, (char *)x->cert_info,pkey,md)
589#define X509_REQ_sign(x,pkey,md) \
590 ASN1_sign((int (*)())i2d_X509_REQ_INFO,x->sig_alg, NULL, \
591 x->signature, (char *)x->req_info,pkey,md)
592#define X509_CRL_sign(x,pkey,md) \
593 ASN1_sign((int (*)())i2d_X509_CRL_INFO,x->crl->sig_alg,x->sig_alg, \
594 x->signature, (char *)x->crl,pkey,md)
595#define NETSCAPE_SPKI_sign(x,pkey,md) \
596 ASN1_sign((int (*)())i2d_NETSCAPE_SPKAC, x->sig_algor,NULL, \
597 x->signature, (char *)x->spkac,pkey,md)
598
599#define X509_dup(x509) (X509 *)ASN1_dup((int (*)())i2d_X509, \
600 (char *(*)())d2i_X509,(char *)x509)
601#define X509_ATTRIBUTE_dup(xa) (X509_ATTRIBUTE *)ASN1_dup(\
602 (int (*)())i2d_X509_ATTRIBUTE, \
603 (char *(*)())d2i_X509_ATTRIBUTE,(char *)xa)
604#define X509_EXTENSION_dup(ex) (X509_EXTENSION *)ASN1_dup( \
605 (int (*)())i2d_X509_EXTENSION, \
606 (char *(*)())d2i_X509_EXTENSION,(char *)ex)
607#define d2i_X509_fp(fp,x509) (X509 *)ASN1_d2i_fp((char *(*)())X509_new, \
608 (char *(*)())d2i_X509, (fp),(unsigned char **)(x509))
609#define i2d_X509_fp(fp,x509) ASN1_i2d_fp(i2d_X509,fp,(unsigned char *)x509)
610#define d2i_X509_bio(bp,x509) (X509 *)ASN1_d2i_bio((char *(*)())X509_new, \
611 (char *(*)())d2i_X509, (bp),(unsigned char **)(x509))
612#define i2d_X509_bio(bp,x509) ASN1_i2d_bio(i2d_X509,bp,(unsigned char *)x509)
613
614#define X509_CRL_dup(crl) (X509_CRL *)ASN1_dup((int (*)())i2d_X509_CRL, \
615 (char *(*)())d2i_X509_CRL,(char *)crl)
616#define d2i_X509_CRL_fp(fp,crl) (X509_CRL *)ASN1_d2i_fp((char *(*)()) \
617 X509_CRL_new,(char *(*)())d2i_X509_CRL, (fp),\
618 (unsigned char **)(crl))
619#define i2d_X509_CRL_fp(fp,crl) ASN1_i2d_fp(i2d_X509_CRL,fp,\
620 (unsigned char *)crl)
621#define d2i_X509_CRL_bio(bp,crl) (X509_CRL *)ASN1_d2i_bio((char *(*)()) \
622 X509_CRL_new,(char *(*)())d2i_X509_CRL, (bp),\
623 (unsigned char **)(crl))
624#define i2d_X509_CRL_bio(bp,crl) ASN1_i2d_bio(i2d_X509_CRL,bp,\
625 (unsigned char *)crl)
626
627#define PKCS7_dup(p7) (PKCS7 *)ASN1_dup((int (*)())i2d_PKCS7, \
628 (char *(*)())d2i_PKCS7,(char *)p7)
629#define d2i_PKCS7_fp(fp,p7) (PKCS7 *)ASN1_d2i_fp((char *(*)()) \
630 PKCS7_new,(char *(*)())d2i_PKCS7, (fp),\
631 (unsigned char **)(p7))
632#define i2d_PKCS7_fp(fp,p7) ASN1_i2d_fp(i2d_PKCS7,fp,\
633 (unsigned char *)p7)
634#define d2i_PKCS7_bio(bp,p7) (PKCS7 *)ASN1_d2i_bio((char *(*)()) \
635 PKCS7_new,(char *(*)())d2i_PKCS7, (bp),\
636 (unsigned char **)(p7))
637#define i2d_PKCS7_bio(bp,p7) ASN1_i2d_bio(i2d_PKCS7,bp,\
638 (unsigned char *)p7)
639
640#define X509_REQ_dup(req) (X509_REQ *)ASN1_dup((int (*)())i2d_X509_REQ, \
641 (char *(*)())d2i_X509_REQ,(char *)req)
642#define d2i_X509_REQ_fp(fp,req) (X509_REQ *)ASN1_d2i_fp((char *(*)())\
643 X509_REQ_new, (char *(*)())d2i_X509_REQ, (fp),\
644 (unsigned char **)(req))
645#define i2d_X509_REQ_fp(fp,req) ASN1_i2d_fp(i2d_X509_REQ,fp,\
646 (unsigned char *)req)
647#define d2i_X509_REQ_bio(bp,req) (X509_REQ *)ASN1_d2i_bio((char *(*)())\
648 X509_REQ_new, (char *(*)())d2i_X509_REQ, (bp),\
649 (unsigned char **)(req))
650#define i2d_X509_REQ_bio(bp,req) ASN1_i2d_bio(i2d_X509_REQ,bp,\
651 (unsigned char *)req)
652
653#define RSAPublicKey_dup(rsa) (RSA *)ASN1_dup((int (*)())i2d_RSAPublicKey, \
654 (char *(*)())d2i_RSAPublicKey,(char *)rsa)
655#define RSAPrivateKey_dup(rsa) (RSA *)ASN1_dup((int (*)())i2d_RSAPrivateKey, \
656 (char *(*)())d2i_RSAPrivateKey,(char *)rsa)
657
658#define d2i_RSAPrivateKey_fp(fp,rsa) (RSA *)ASN1_d2i_fp((char *(*)())\
659 RSA_new,(char *(*)())d2i_RSAPrivateKey, (fp), \
660 (unsigned char **)(rsa))
661#define i2d_RSAPrivateKey_fp(fp,rsa) ASN1_i2d_fp(i2d_RSAPrivateKey,fp, \
662 (unsigned char *)rsa)
663#define d2i_RSAPrivateKey_bio(bp,rsa) (RSA *)ASN1_d2i_bio((char *(*)())\
664 RSA_new,(char *(*)())d2i_RSAPrivateKey, (bp), \
665 (unsigned char **)(rsa))
666#define i2d_RSAPrivateKey_bio(bp,rsa) ASN1_i2d_bio(i2d_RSAPrivateKey,bp, \
667 (unsigned char *)rsa)
668
669#define d2i_RSAPublicKey_fp(fp,rsa) (RSA *)ASN1_d2i_fp((char *(*)())\
670 RSA_new,(char *(*)())d2i_RSAPublicKey, (fp), \
671 (unsigned char **)(rsa))
672#define i2d_RSAPublicKey_fp(fp,rsa) ASN1_i2d_fp(i2d_RSAPublicKey,fp, \
673 (unsigned char *)rsa)
674#define d2i_RSAPublicKey_bio(bp,rsa) (RSA *)ASN1_d2i_bio((char *(*)())\
675 RSA_new,(char *(*)())d2i_RSAPublicKey, (bp), \
676 (unsigned char **)(rsa))
677#define i2d_RSAPublicKey_bio(bp,rsa) ASN1_i2d_bio(i2d_RSAPublicKey,bp, \
678 (unsigned char *)rsa)
679
680#define d2i_DSAPrivateKey_fp(fp,dsa) (DSA *)ASN1_d2i_fp((char *(*)())\
681 DSA_new,(char *(*)())d2i_DSAPrivateKey, (fp), \
682 (unsigned char **)(dsa))
683#define i2d_DSAPrivateKey_fp(fp,dsa) ASN1_i2d_fp(i2d_DSAPrivateKey,fp, \
684 (unsigned char *)dsa)
685#define d2i_DSAPrivateKey_bio(bp,dsa) (DSA *)ASN1_d2i_bio((char *(*)())\
686 DSA_new,(char *(*)())d2i_DSAPrivateKey, (bp), \
687 (unsigned char **)(dsa))
688#define i2d_DSAPrivateKey_bio(bp,dsa) ASN1_i2d_bio(i2d_DSAPrivateKey,bp, \
689 (unsigned char *)dsa)
690
691#define d2i_ECPrivateKey_fp(fp,ecdsa) (EC_KEY *)ASN1_d2i_fp((char *(*)())\
692 EC_KEY_new,(char *(*)())d2i_ECPrivateKey, (fp), \
693 (unsigned char **)(ecdsa))
694#define i2d_ECPrivateKey_fp(fp,ecdsa) ASN1_i2d_fp(i2d_ECPrivateKey,fp, \
695 (unsigned char *)ecdsa)
696#define d2i_ECPrivateKey_bio(bp,ecdsa) (EC_KEY *)ASN1_d2i_bio((char *(*)())\
697 EC_KEY_new,(char *(*)())d2i_ECPrivateKey, (bp), \
698 (unsigned char **)(ecdsa))
699#define i2d_ECPrivateKey_bio(bp,ecdsa) ASN1_i2d_bio(i2d_ECPrivateKey,bp, \
700 (unsigned char *)ecdsa)
701
702#define X509_ALGOR_dup(xn) (X509_ALGOR *)ASN1_dup((int (*)())i2d_X509_ALGOR,\
703 (char *(*)())d2i_X509_ALGOR,(char *)xn)
704
705#define X509_NAME_dup(xn) (X509_NAME *)ASN1_dup((int (*)())i2d_X509_NAME, \
706 (char *(*)())d2i_X509_NAME,(char *)xn)
707#define X509_NAME_ENTRY_dup(ne) (X509_NAME_ENTRY *)ASN1_dup( \
708 (int (*)())i2d_X509_NAME_ENTRY, \
709 (char *(*)())d2i_X509_NAME_ENTRY,\
710 (char *)ne)
711
712#define X509_digest(data,type,md,len) \
713 ASN1_digest((int (*)())i2d_X509,type,(char *)data,md,len)
714#define X509_NAME_digest(data,type,md,len) \
715 ASN1_digest((int (*)())i2d_X509_NAME,type,(char *)data,md,len)
716#ifndef PKCS7_ISSUER_AND_SERIAL_digest
717#define PKCS7_ISSUER_AND_SERIAL_digest(data,type,md,len) \
718 ASN1_digest((int (*)())i2d_PKCS7_ISSUER_AND_SERIAL,type,\
719 (char *)data,md,len)
720#endif
721#endif
722
723#define X509_EXT_PACK_UNKNOWN 1 606#define X509_EXT_PACK_UNKNOWN 1
724#define X509_EXT_PACK_STRING 2 607#define X509_EXT_PACK_STRING 2
725 608
@@ -740,6 +623,18 @@ extern "C" {
740#define X509_CRL_get_issuer(x) ((x)->crl->issuer) 623#define X509_CRL_get_issuer(x) ((x)->crl->issuer)
741#define X509_CRL_get_REVOKED(x) ((x)->crl->revoked) 624#define X509_CRL_get_REVOKED(x) ((x)->crl->revoked)
742 625
626void X509_CRL_set_default_method(const X509_CRL_METHOD *meth);
627X509_CRL_METHOD *X509_CRL_METHOD_new(
628 int (*crl_init)(X509_CRL *crl),
629 int (*crl_free)(X509_CRL *crl),
630 int (*crl_lookup)(X509_CRL *crl, X509_REVOKED **ret,
631 ASN1_INTEGER *ser, X509_NAME *issuer),
632 int (*crl_verify)(X509_CRL *crl, EVP_PKEY *pk));
633void X509_CRL_METHOD_free(X509_CRL_METHOD *m);
634
635void X509_CRL_set_meth_data(X509_CRL *crl, void *dat);
636void *X509_CRL_get_meth_data(X509_CRL *crl);
637
743/* This one is only used so that a binary form can output, as in 638/* This one is only used so that a binary form can output, as in
744 * i2d_X509_NAME(X509_get_X509_PUBKEY(x),&buf) */ 639 * i2d_X509_NAME(X509_get_X509_PUBKEY(x),&buf) */
745#define X509_get_X509_PUBKEY(x) ((x)->cert_info->key) 640#define X509_get_X509_PUBKEY(x) ((x)->cert_info->key)
@@ -747,7 +642,6 @@ extern "C" {
747 642
748const char *X509_verify_cert_error_string(long n); 643const char *X509_verify_cert_error_string(long n);
749 644
750#ifndef SSLEAY_MACROS
751#ifndef OPENSSL_NO_EVP 645#ifndef OPENSSL_NO_EVP
752int X509_verify(X509 *a, EVP_PKEY *r); 646int X509_verify(X509 *a, EVP_PKEY *r);
753 647
@@ -872,11 +766,11 @@ void X509_ALGOR_get0(ASN1_OBJECT **paobj, int *pptype, void **ppval,
872X509_NAME *X509_NAME_dup(X509_NAME *xn); 766X509_NAME *X509_NAME_dup(X509_NAME *xn);
873X509_NAME_ENTRY *X509_NAME_ENTRY_dup(X509_NAME_ENTRY *ne); 767X509_NAME_ENTRY *X509_NAME_ENTRY_dup(X509_NAME_ENTRY *ne);
874 768
875#endif /* !SSLEAY_MACROS */ 769int X509_cmp_time(const ASN1_TIME *s, time_t *t);
876 770int X509_cmp_current_time(const ASN1_TIME *s);
877int X509_cmp_time(ASN1_TIME *s, time_t *t);
878int X509_cmp_current_time(ASN1_TIME *s);
879ASN1_TIME * X509_time_adj(ASN1_TIME *s, long adj, time_t *t); 771ASN1_TIME * X509_time_adj(ASN1_TIME *s, long adj, time_t *t);
772ASN1_TIME * X509_time_adj_ex(ASN1_TIME *s,
773 int offset_day, long offset_sec, time_t *t);
880ASN1_TIME * X509_gmtime_adj(ASN1_TIME *s, long adj); 774ASN1_TIME * X509_gmtime_adj(ASN1_TIME *s, long adj);
881 775
882const char * X509_get_default_cert_area(void ); 776const char * X509_get_default_cert_area(void );
@@ -964,6 +858,9 @@ DECLARE_ASN1_FUNCTIONS(X509_CRL_INFO)
964DECLARE_ASN1_FUNCTIONS(X509_CRL) 858DECLARE_ASN1_FUNCTIONS(X509_CRL)
965 859
966int X509_CRL_add0_revoked(X509_CRL *crl, X509_REVOKED *rev); 860int X509_CRL_add0_revoked(X509_CRL *crl, X509_REVOKED *rev);
861int X509_CRL_get0_by_serial(X509_CRL *crl,
862 X509_REVOKED **ret, ASN1_INTEGER *serial);
863int X509_CRL_get0_by_cert(X509_CRL *crl, X509_REVOKED **ret, X509 *x);
967 864
968X509_PKEY * X509_PKEY_new(void ); 865X509_PKEY * X509_PKEY_new(void );
969void X509_PKEY_free(X509_PKEY *a); 866void X509_PKEY_free(X509_PKEY *a);
@@ -1007,8 +904,8 @@ int X509_set_issuer_name(X509 *x, X509_NAME *name);
1007X509_NAME * X509_get_issuer_name(X509 *a); 904X509_NAME * X509_get_issuer_name(X509 *a);
1008int X509_set_subject_name(X509 *x, X509_NAME *name); 905int X509_set_subject_name(X509 *x, X509_NAME *name);
1009X509_NAME * X509_get_subject_name(X509 *a); 906X509_NAME * X509_get_subject_name(X509 *a);
1010int X509_set_notBefore(X509 *x, ASN1_TIME *tm); 907int X509_set_notBefore(X509 *x, const ASN1_TIME *tm);
1011int X509_set_notAfter(X509 *x, ASN1_TIME *tm); 908int X509_set_notAfter(X509 *x, const ASN1_TIME *tm);
1012int X509_set_pubkey(X509 *x, EVP_PKEY *pkey); 909int X509_set_pubkey(X509 *x, EVP_PKEY *pkey);
1013EVP_PKEY * X509_get_pubkey(X509 *x); 910EVP_PKEY * X509_get_pubkey(X509 *x);
1014ASN1_BIT_STRING * X509_get0_pubkey_bitstr(const X509 *x); 911ASN1_BIT_STRING * X509_get0_pubkey_bitstr(const X509 *x);
@@ -1045,8 +942,8 @@ int X509_REQ_add1_attr_by_txt(X509_REQ *req,
1045 942
1046int X509_CRL_set_version(X509_CRL *x, long version); 943int X509_CRL_set_version(X509_CRL *x, long version);
1047int X509_CRL_set_issuer_name(X509_CRL *x, X509_NAME *name); 944int X509_CRL_set_issuer_name(X509_CRL *x, X509_NAME *name);
1048int X509_CRL_set_lastUpdate(X509_CRL *x, ASN1_TIME *tm); 945int X509_CRL_set_lastUpdate(X509_CRL *x, const ASN1_TIME *tm);
1049int X509_CRL_set_nextUpdate(X509_CRL *x, ASN1_TIME *tm); 946int X509_CRL_set_nextUpdate(X509_CRL *x, const ASN1_TIME *tm);
1050int X509_CRL_sort(X509_CRL *crl); 947int X509_CRL_sort(X509_CRL *crl);
1051 948
1052int X509_REVOKED_set_serialNumber(X509_REVOKED *x, ASN1_INTEGER *serial); 949int X509_REVOKED_set_serialNumber(X509_REVOKED *x, ASN1_INTEGER *serial);
@@ -1065,11 +962,18 @@ unsigned long X509_issuer_name_hash(X509 *a);
1065int X509_subject_name_cmp(const X509 *a, const X509 *b); 962int X509_subject_name_cmp(const X509 *a, const X509 *b);
1066unsigned long X509_subject_name_hash(X509 *x); 963unsigned long X509_subject_name_hash(X509 *x);
1067 964
965#ifndef OPENSSL_NO_MD5
966unsigned long X509_issuer_name_hash_old(X509 *a);
967unsigned long X509_subject_name_hash_old(X509 *x);
968#endif
969
1068int X509_cmp(const X509 *a, const X509 *b); 970int X509_cmp(const X509 *a, const X509 *b);
1069int X509_NAME_cmp(const X509_NAME *a, const X509_NAME *b); 971int X509_NAME_cmp(const X509_NAME *a, const X509_NAME *b);
1070unsigned long X509_NAME_hash(X509_NAME *x); 972unsigned long X509_NAME_hash(X509_NAME *x);
973unsigned long X509_NAME_hash_old(X509_NAME *x);
1071 974
1072int X509_CRL_cmp(const X509_CRL *a, const X509_CRL *b); 975int X509_CRL_cmp(const X509_CRL *a, const X509_CRL *b);
976int X509_CRL_match(const X509_CRL *a, const X509_CRL *b);
1073#ifndef OPENSSL_NO_FP_API 977#ifndef OPENSSL_NO_FP_API
1074int X509_print_ex_fp(FILE *bp,X509 *x, unsigned long nmflag, unsigned long cflag); 978int X509_print_ex_fp(FILE *bp,X509 *x, unsigned long nmflag, unsigned long cflag);
1075int X509_print_fp(FILE *bp,X509 *x); 979int X509_print_fp(FILE *bp,X509 *x);
@@ -1245,9 +1149,16 @@ DECLARE_ASN1_FUNCTIONS(PBEPARAM)
1245DECLARE_ASN1_FUNCTIONS(PBE2PARAM) 1149DECLARE_ASN1_FUNCTIONS(PBE2PARAM)
1246DECLARE_ASN1_FUNCTIONS(PBKDF2PARAM) 1150DECLARE_ASN1_FUNCTIONS(PBKDF2PARAM)
1247 1151
1248X509_ALGOR *PKCS5_pbe_set(int alg, int iter, unsigned char *salt, int saltlen); 1152int PKCS5_pbe_set0_algor(X509_ALGOR *algor, int alg, int iter,
1153 const unsigned char *salt, int saltlen);
1154
1155X509_ALGOR *PKCS5_pbe_set(int alg, int iter,
1156 const unsigned char *salt, int saltlen);
1249X509_ALGOR *PKCS5_pbe2_set(const EVP_CIPHER *cipher, int iter, 1157X509_ALGOR *PKCS5_pbe2_set(const EVP_CIPHER *cipher, int iter,
1250 unsigned char *salt, int saltlen); 1158 unsigned char *salt, int saltlen);
1159X509_ALGOR *PKCS5_pbe2_set_iv(const EVP_CIPHER *cipher, int iter,
1160 unsigned char *salt, int saltlen,
1161 unsigned char *aiv, int prf_nid);
1251 1162
1252/* PKCS#8 utilities */ 1163/* PKCS#8 utilities */
1253 1164
@@ -1258,6 +1169,22 @@ PKCS8_PRIV_KEY_INFO *EVP_PKEY2PKCS8(EVP_PKEY *pkey);
1258PKCS8_PRIV_KEY_INFO *EVP_PKEY2PKCS8_broken(EVP_PKEY *pkey, int broken); 1169PKCS8_PRIV_KEY_INFO *EVP_PKEY2PKCS8_broken(EVP_PKEY *pkey, int broken);
1259PKCS8_PRIV_KEY_INFO *PKCS8_set_broken(PKCS8_PRIV_KEY_INFO *p8, int broken); 1170PKCS8_PRIV_KEY_INFO *PKCS8_set_broken(PKCS8_PRIV_KEY_INFO *p8, int broken);
1260 1171
1172int PKCS8_pkey_set0(PKCS8_PRIV_KEY_INFO *priv, ASN1_OBJECT *aobj,
1173 int version, int ptype, void *pval,
1174 unsigned char *penc, int penclen);
1175int PKCS8_pkey_get0(ASN1_OBJECT **ppkalg,
1176 const unsigned char **pk, int *ppklen,
1177 X509_ALGOR **pa,
1178 PKCS8_PRIV_KEY_INFO *p8);
1179
1180int X509_PUBKEY_set0_param(X509_PUBKEY *pub, ASN1_OBJECT *aobj,
1181 int ptype, void *pval,
1182 unsigned char *penc, int penclen);
1183int X509_PUBKEY_get0_param(ASN1_OBJECT **ppkalg,
1184 const unsigned char **pk, int *ppklen,
1185 X509_ALGOR **pa,
1186 X509_PUBKEY *pub);
1187
1261int X509_check_trust(X509 *x, int id, int flags); 1188int X509_check_trust(X509 *x, int id, int flags);
1262int X509_TRUST_get_count(void); 1189int X509_TRUST_get_count(void);
1263X509_TRUST * X509_TRUST_get0(int idx); 1190X509_TRUST * X509_TRUST_get0(int idx);
@@ -1337,7 +1264,10 @@ void ERR_load_X509_strings(void);
1337#define X509_R_KEY_VALUES_MISMATCH 116 1264#define X509_R_KEY_VALUES_MISMATCH 116
1338#define X509_R_LOADING_CERT_DIR 103 1265#define X509_R_LOADING_CERT_DIR 103
1339#define X509_R_LOADING_DEFAULTS 104 1266#define X509_R_LOADING_DEFAULTS 104
1267#define X509_R_METHOD_NOT_SUPPORTED 124
1340#define X509_R_NO_CERT_SET_FOR_US_TO_VERIFY 105 1268#define X509_R_NO_CERT_SET_FOR_US_TO_VERIFY 105
1269#define X509_R_PUBLIC_KEY_DECODE_ERROR 125
1270#define X509_R_PUBLIC_KEY_ENCODE_ERROR 126
1341#define X509_R_SHOULD_RETRY 106 1271#define X509_R_SHOULD_RETRY 106
1342#define X509_R_UNABLE_TO_FIND_PARAMETERS_IN_CHAIN 107 1272#define X509_R_UNABLE_TO_FIND_PARAMETERS_IN_CHAIN 107
1343#define X509_R_UNABLE_TO_GET_CERTS_PUBLIC_KEY 108 1273#define X509_R_UNABLE_TO_GET_CERTS_PUBLIC_KEY 108
diff --git a/src/lib/libcrypto/x509/x509_cmp.c b/src/lib/libcrypto/x509/x509_cmp.c
index 2faf92514a..4bc9da07e0 100644
--- a/src/lib/libcrypto/x509/x509_cmp.c
+++ b/src/lib/libcrypto/x509/x509_cmp.c
@@ -116,6 +116,13 @@ int X509_CRL_cmp(const X509_CRL *a, const X509_CRL *b)
116 return(X509_NAME_cmp(a->crl->issuer,b->crl->issuer)); 116 return(X509_NAME_cmp(a->crl->issuer,b->crl->issuer));
117 } 117 }
118 118
119#ifndef OPENSSL_NO_SHA
120int X509_CRL_match(const X509_CRL *a, const X509_CRL *b)
121 {
122 return memcmp(a->sha1_hash, b->sha1_hash, 20);
123 }
124#endif
125
119X509_NAME *X509_get_issuer_name(X509 *a) 126X509_NAME *X509_get_issuer_name(X509 *a)
120 { 127 {
121 return(a->cert_info->issuer); 128 return(a->cert_info->issuer);
@@ -126,6 +133,13 @@ unsigned long X509_issuer_name_hash(X509 *x)
126 return(X509_NAME_hash(x->cert_info->issuer)); 133 return(X509_NAME_hash(x->cert_info->issuer));
127 } 134 }
128 135
136#ifndef OPENSSL_NO_MD5
137unsigned long X509_issuer_name_hash_old(X509 *x)
138 {
139 return(X509_NAME_hash_old(x->cert_info->issuer));
140 }
141#endif
142
129X509_NAME *X509_get_subject_name(X509 *a) 143X509_NAME *X509_get_subject_name(X509 *a)
130 { 144 {
131 return(a->cert_info->subject); 145 return(a->cert_info->subject);
@@ -141,6 +155,13 @@ unsigned long X509_subject_name_hash(X509 *x)
141 return(X509_NAME_hash(x->cert_info->subject)); 155 return(X509_NAME_hash(x->cert_info->subject));
142 } 156 }
143 157
158#ifndef OPENSSL_NO_MD5
159unsigned long X509_subject_name_hash_old(X509 *x)
160 {
161 return(X509_NAME_hash_old(x->cert_info->subject));
162 }
163#endif
164
144#ifndef OPENSSL_NO_SHA 165#ifndef OPENSSL_NO_SHA
145/* Compare two certificates: they must be identical for 166/* Compare two certificates: they must be identical for
146 * this to work. NB: Although "cmp" operations are generally 167 * this to work. NB: Although "cmp" operations are generally
@@ -162,177 +183,63 @@ int X509_cmp(const X509 *a, const X509 *b)
162#endif 183#endif
163 184
164 185
165/* Case insensitive string comparision */ 186int X509_NAME_cmp(const X509_NAME *a, const X509_NAME *b)
166static int nocase_cmp(const ASN1_STRING *a, const ASN1_STRING *b)
167{
168 int i;
169
170 if (a->length != b->length)
171 return (a->length - b->length);
172
173 for (i=0; i<a->length; i++)
174 {
175 int ca, cb;
176
177 ca = tolower(a->data[i]);
178 cb = tolower(b->data[i]);
179
180 if (ca != cb)
181 return(ca-cb);
182 }
183 return 0;
184}
185
186/* Case insensitive string comparision with space normalization
187 * Space normalization - ignore leading, trailing spaces,
188 * multiple spaces between characters are replaced by single space
189 */
190static int nocase_spacenorm_cmp(const ASN1_STRING *a, const ASN1_STRING *b)
191{
192 unsigned char *pa = NULL, *pb = NULL;
193 int la, lb;
194
195 la = a->length;
196 lb = b->length;
197 pa = a->data;
198 pb = b->data;
199
200 /* skip leading spaces */
201 while (la > 0 && isspace(*pa))
202 {
203 la--;
204 pa++;
205 }
206 while (lb > 0 && isspace(*pb))
207 {
208 lb--;
209 pb++;
210 }
211
212 /* skip trailing spaces */
213 while (la > 0 && isspace(pa[la-1]))
214 la--;
215 while (lb > 0 && isspace(pb[lb-1]))
216 lb--;
217
218 /* compare strings with space normalization */
219 while (la > 0 && lb > 0)
220 { 187 {
221 int ca, cb; 188 int ret;
222
223 /* compare character */
224 ca = tolower(*pa);
225 cb = tolower(*pb);
226 if (ca != cb)
227 return (ca - cb);
228 189
229 pa++; pb++; 190 /* Ensure canonical encoding is present and up to date */
230 la--; lb--;
231 191
232 if (la <= 0 || lb <= 0) 192 if (!a->canon_enc || a->modified)
233 break; 193 {
194 ret = i2d_X509_NAME((X509_NAME *)a, NULL);
195 if (ret < 0)
196 return -2;
197 }
234 198
235 /* is white space next character ? */ 199 if (!b->canon_enc || b->modified)
236 if (isspace(*pa) && isspace(*pb))
237 { 200 {
238 /* skip remaining white spaces */ 201 ret = i2d_X509_NAME((X509_NAME *)b, NULL);
239 while (la > 0 && isspace(*pa)) 202 if (ret < 0)
240 { 203 return -2;
241 la--;
242 pa++;
243 }
244 while (lb > 0 && isspace(*pb))
245 {
246 lb--;
247 pb++;
248 }
249 } 204 }
250 }
251 if (la > 0 || lb > 0)
252 return la - lb;
253 205
254 return 0; 206 ret = a->canon_enclen - b->canon_enclen;
255}
256 207
257static int asn1_string_memcmp(ASN1_STRING *a, ASN1_STRING *b) 208 if (ret)
258 { 209 return ret;
259 int j;
260 j = a->length - b->length;
261 if (j)
262 return j;
263 return memcmp(a->data, b->data, a->length);
264 }
265 210
266#define STR_TYPE_CMP (B_ASN1_PRINTABLESTRING|B_ASN1_T61STRING|B_ASN1_UTF8STRING) 211 return memcmp(a->canon_enc, b->canon_enc, a->canon_enclen);
267 212
268int X509_NAME_cmp(const X509_NAME *a, const X509_NAME *b) 213 }
269 {
270 int i,j;
271 X509_NAME_ENTRY *na,*nb;
272 214
273 unsigned long nabit, nbbit; 215unsigned long X509_NAME_hash(X509_NAME *x)
216 {
217 unsigned long ret=0;
218 unsigned char md[SHA_DIGEST_LENGTH];
274 219
275 j = sk_X509_NAME_ENTRY_num(a->entries) 220 /* Make sure X509_NAME structure contains valid cached encoding */
276 - sk_X509_NAME_ENTRY_num(b->entries); 221 i2d_X509_NAME(x,NULL);
277 if (j) 222 EVP_Digest(x->canon_enc, x->canon_enclen, md, NULL, EVP_sha1(), NULL);
278 return j;
279 for (i=sk_X509_NAME_ENTRY_num(a->entries)-1; i>=0; i--)
280 {
281 na=sk_X509_NAME_ENTRY_value(a->entries,i);
282 nb=sk_X509_NAME_ENTRY_value(b->entries,i);
283 j=na->value->type-nb->value->type;
284 if (j)
285 {
286 nabit = ASN1_tag2bit(na->value->type);
287 nbbit = ASN1_tag2bit(nb->value->type);
288 if (!(nabit & STR_TYPE_CMP) ||
289 !(nbbit & STR_TYPE_CMP))
290 return j;
291 if (!asn1_string_memcmp(na->value, nb->value))
292 j = 0;
293 }
294 else if (na->value->type == V_ASN1_PRINTABLESTRING)
295 j=nocase_spacenorm_cmp(na->value, nb->value);
296 else if (na->value->type == V_ASN1_IA5STRING
297 && OBJ_obj2nid(na->object) == NID_pkcs9_emailAddress)
298 j=nocase_cmp(na->value, nb->value);
299 else
300 j = asn1_string_memcmp(na->value, nb->value);
301 if (j) return(j);
302 j=na->set-nb->set;
303 if (j) return(j);
304 }
305 223
306 /* We will check the object types after checking the values 224 ret=( ((unsigned long)md[0] )|((unsigned long)md[1]<<8L)|
307 * since the values will more often be different than the object 225 ((unsigned long)md[2]<<16L)|((unsigned long)md[3]<<24L)
308 * types. */ 226 )&0xffffffffL;
309 for (i=sk_X509_NAME_ENTRY_num(a->entries)-1; i>=0; i--) 227 return(ret);
310 {
311 na=sk_X509_NAME_ENTRY_value(a->entries,i);
312 nb=sk_X509_NAME_ENTRY_value(b->entries,i);
313 j=OBJ_cmp(na->object,nb->object);
314 if (j) return(j);
315 }
316 return(0);
317 } 228 }
318 229
230
319#ifndef OPENSSL_NO_MD5 231#ifndef OPENSSL_NO_MD5
320/* I now DER encode the name and hash it. Since I cache the DER encoding, 232/* I now DER encode the name and hash it. Since I cache the DER encoding,
321 * this is reasonably efficient. */ 233 * this is reasonably efficient. */
322unsigned long X509_NAME_hash(X509_NAME *x) 234
235unsigned long X509_NAME_hash_old(X509_NAME *x)
323 { 236 {
324 unsigned long ret=0; 237 unsigned long ret=0;
325 unsigned char md[16]; 238 unsigned char md[16];
326 EVP_MD_CTX md_ctx;
327 239
328 /* Make sure X509_NAME structure contains valid cached encoding */ 240 /* Make sure X509_NAME structure contains valid cached encoding */
329 i2d_X509_NAME(x,NULL); 241 i2d_X509_NAME(x,NULL);
330 EVP_MD_CTX_init(&md_ctx); 242 EVP_Digest(x->bytes->data, x->bytes->length, md, NULL, EVP_md5(), NULL);
331 EVP_MD_CTX_set_flags(&md_ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
332 EVP_DigestInit_ex(&md_ctx, EVP_md5(), NULL);
333 EVP_DigestUpdate(&md_ctx, x->bytes->data, x->bytes->length);
334 EVP_DigestFinal_ex(&md_ctx,md,NULL);
335 EVP_MD_CTX_cleanup(&md_ctx);
336 243
337 ret=( ((unsigned long)md[0] )|((unsigned long)md[1]<<8L)| 244 ret=( ((unsigned long)md[0] )|((unsigned long)md[1]<<8L)|
338 ((unsigned long)md[2]<<16L)|((unsigned long)md[3]<<24L) 245 ((unsigned long)md[2]<<16L)|((unsigned long)md[3]<<24L)
@@ -393,14 +300,19 @@ ASN1_BIT_STRING *X509_get0_pubkey_bitstr(const X509 *x)
393 300
394int X509_check_private_key(X509 *x, EVP_PKEY *k) 301int X509_check_private_key(X509 *x, EVP_PKEY *k)
395 { 302 {
396 EVP_PKEY *xk=NULL; 303 EVP_PKEY *xk;
397 int ok=0; 304 int ret;
398 305
399 xk=X509_get_pubkey(x); 306 xk=X509_get_pubkey(x);
400 switch (EVP_PKEY_cmp(xk, k)) 307
308 if (xk)
309 ret = EVP_PKEY_cmp(xk, k);
310 else
311 ret = -2;
312
313 switch (ret)
401 { 314 {
402 case 1: 315 case 1:
403 ok=1;
404 break; 316 break;
405 case 0: 317 case 0:
406 X509err(X509_F_X509_CHECK_PRIVATE_KEY,X509_R_KEY_VALUES_MISMATCH); 318 X509err(X509_F_X509_CHECK_PRIVATE_KEY,X509_R_KEY_VALUES_MISMATCH);
@@ -409,24 +321,11 @@ int X509_check_private_key(X509 *x, EVP_PKEY *k)
409 X509err(X509_F_X509_CHECK_PRIVATE_KEY,X509_R_KEY_TYPE_MISMATCH); 321 X509err(X509_F_X509_CHECK_PRIVATE_KEY,X509_R_KEY_TYPE_MISMATCH);
410 break; 322 break;
411 case -2: 323 case -2:
412#ifndef OPENSSL_NO_EC
413 if (k->type == EVP_PKEY_EC)
414 {
415 X509err(X509_F_X509_CHECK_PRIVATE_KEY, ERR_R_EC_LIB);
416 break;
417 }
418#endif
419#ifndef OPENSSL_NO_DH
420 if (k->type == EVP_PKEY_DH)
421 {
422 /* No idea */
423 X509err(X509_F_X509_CHECK_PRIVATE_KEY,X509_R_CANT_CHECK_DH_KEY);
424 break;
425 }
426#endif
427 X509err(X509_F_X509_CHECK_PRIVATE_KEY,X509_R_UNKNOWN_KEY_TYPE); 324 X509err(X509_F_X509_CHECK_PRIVATE_KEY,X509_R_UNKNOWN_KEY_TYPE);
428 } 325 }
429 326 if (xk)
430 EVP_PKEY_free(xk); 327 EVP_PKEY_free(xk);
431 return(ok); 328 if (ret > 0)
329 return 1;
330 return 0;
432 } 331 }
diff --git a/src/lib/libcrypto/x509/x509_err.c b/src/lib/libcrypto/x509/x509_err.c
index fb377292da..a01402f416 100644
--- a/src/lib/libcrypto/x509/x509_err.c
+++ b/src/lib/libcrypto/x509/x509_err.c
@@ -1,6 +1,6 @@
1/* crypto/x509/x509_err.c */ 1/* crypto/x509/x509_err.c */
2/* ==================================================================== 2/* ====================================================================
3 * Copyright (c) 1999-2005 The OpenSSL Project. All rights reserved. 3 * Copyright (c) 1999-2006 The OpenSSL Project. All rights reserved.
4 * 4 *
5 * Redistribution and use in source and binary forms, with or without 5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions 6 * modification, are permitted provided that the following conditions
@@ -132,7 +132,10 @@ static ERR_STRING_DATA X509_str_reasons[]=
132{ERR_REASON(X509_R_KEY_VALUES_MISMATCH) ,"key values mismatch"}, 132{ERR_REASON(X509_R_KEY_VALUES_MISMATCH) ,"key values mismatch"},
133{ERR_REASON(X509_R_LOADING_CERT_DIR) ,"loading cert dir"}, 133{ERR_REASON(X509_R_LOADING_CERT_DIR) ,"loading cert dir"},
134{ERR_REASON(X509_R_LOADING_DEFAULTS) ,"loading defaults"}, 134{ERR_REASON(X509_R_LOADING_DEFAULTS) ,"loading defaults"},
135{ERR_REASON(X509_R_METHOD_NOT_SUPPORTED) ,"method not supported"},
135{ERR_REASON(X509_R_NO_CERT_SET_FOR_US_TO_VERIFY),"no cert set for us to verify"}, 136{ERR_REASON(X509_R_NO_CERT_SET_FOR_US_TO_VERIFY),"no cert set for us to verify"},
137{ERR_REASON(X509_R_PUBLIC_KEY_DECODE_ERROR),"public key decode error"},
138{ERR_REASON(X509_R_PUBLIC_KEY_ENCODE_ERROR),"public key encode error"},
136{ERR_REASON(X509_R_SHOULD_RETRY) ,"should retry"}, 139{ERR_REASON(X509_R_SHOULD_RETRY) ,"should retry"},
137{ERR_REASON(X509_R_UNABLE_TO_FIND_PARAMETERS_IN_CHAIN),"unable to find parameters in chain"}, 140{ERR_REASON(X509_R_UNABLE_TO_FIND_PARAMETERS_IN_CHAIN),"unable to find parameters in chain"},
138{ERR_REASON(X509_R_UNABLE_TO_GET_CERTS_PUBLIC_KEY),"unable to get certs public key"}, 141{ERR_REASON(X509_R_UNABLE_TO_GET_CERTS_PUBLIC_KEY),"unable to get certs public key"},
diff --git a/src/lib/libcrypto/x509/x509_lu.c b/src/lib/libcrypto/x509/x509_lu.c
index cd2cfb6d85..3a6e04a1de 100644
--- a/src/lib/libcrypto/x509/x509_lu.c
+++ b/src/lib/libcrypto/x509/x509_lu.c
@@ -196,9 +196,17 @@ X509_STORE *X509_STORE_new(void)
196 ret->get_crl = 0; 196 ret->get_crl = 0;
197 ret->check_crl = 0; 197 ret->check_crl = 0;
198 ret->cert_crl = 0; 198 ret->cert_crl = 0;
199 ret->lookup_certs = 0;
200 ret->lookup_crls = 0;
199 ret->cleanup = 0; 201 ret->cleanup = 0;
200 202
201 CRYPTO_new_ex_data(CRYPTO_EX_INDEX_X509_STORE, ret, &ret->ex_data); 203 if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_X509_STORE, ret, &ret->ex_data))
204 {
205 sk_X509_OBJECT_free(ret->objs);
206 OPENSSL_free(ret);
207 return NULL;
208 }
209
202 ret->references=1; 210 ret->references=1;
203 return ret; 211 return ret;
204 } 212 }
@@ -286,9 +294,11 @@ int X509_STORE_get_by_subject(X509_STORE_CTX *vs, int type, X509_NAME *name,
286 X509_OBJECT stmp,*tmp; 294 X509_OBJECT stmp,*tmp;
287 int i,j; 295 int i,j;
288 296
297 CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE);
289 tmp=X509_OBJECT_retrieve_by_subject(ctx->objs,type,name); 298 tmp=X509_OBJECT_retrieve_by_subject(ctx->objs,type,name);
299 CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
290 300
291 if (tmp == NULL) 301 if (tmp == NULL || type == X509_LU_CRL)
292 { 302 {
293 for (i=vs->current_method; i<sk_X509_LOOKUP_num(ctx->get_cert_methods); i++) 303 for (i=vs->current_method; i<sk_X509_LOOKUP_num(ctx->get_cert_methods); i++)
294 { 304 {
@@ -340,7 +350,6 @@ int X509_STORE_add_cert(X509_STORE *ctx, X509 *x)
340 350
341 X509_OBJECT_up_ref_count(obj); 351 X509_OBJECT_up_ref_count(obj);
342 352
343
344 if (X509_OBJECT_retrieve_match(ctx->objs, obj)) 353 if (X509_OBJECT_retrieve_match(ctx->objs, obj))
345 { 354 {
346 X509_OBJECT_free_contents(obj); 355 X509_OBJECT_free_contents(obj);
@@ -414,14 +423,15 @@ void X509_OBJECT_free_contents(X509_OBJECT *a)
414 } 423 }
415 } 424 }
416 425
417int X509_OBJECT_idx_by_subject(STACK_OF(X509_OBJECT) *h, int type, 426static int x509_object_idx_cnt(STACK_OF(X509_OBJECT) *h, int type,
418 X509_NAME *name) 427 X509_NAME *name, int *pnmatch)
419 { 428 {
420 X509_OBJECT stmp; 429 X509_OBJECT stmp;
421 X509 x509_s; 430 X509 x509_s;
422 X509_CINF cinf_s; 431 X509_CINF cinf_s;
423 X509_CRL crl_s; 432 X509_CRL crl_s;
424 X509_CRL_INFO crl_info_s; 433 X509_CRL_INFO crl_info_s;
434 int idx;
425 435
426 stmp.type=type; 436 stmp.type=type;
427 switch (type) 437 switch (type)
@@ -441,41 +451,169 @@ int X509_OBJECT_idx_by_subject(STACK_OF(X509_OBJECT) *h, int type,
441 return -1; 451 return -1;
442 } 452 }
443 453
444 return sk_X509_OBJECT_find(h,&stmp); 454 idx = sk_X509_OBJECT_find(h,&stmp);
455 if (idx >= 0 && pnmatch)
456 {
457 int tidx;
458 const X509_OBJECT *tobj, *pstmp;
459 *pnmatch = 1;
460 pstmp = &stmp;
461 for (tidx = idx + 1; tidx < sk_X509_OBJECT_num(h); tidx++)
462 {
463 tobj = sk_X509_OBJECT_value(h, tidx);
464 if (x509_object_cmp(&tobj, &pstmp))
465 break;
466 (*pnmatch)++;
467 }
468 }
469 return idx;
470 }
471
472
473int X509_OBJECT_idx_by_subject(STACK_OF(X509_OBJECT) *h, int type,
474 X509_NAME *name)
475 {
476 return x509_object_idx_cnt(h, type, name, NULL);
445 } 477 }
446 478
447X509_OBJECT *X509_OBJECT_retrieve_by_subject(STACK_OF(X509_OBJECT) *h, int type, 479X509_OBJECT *X509_OBJECT_retrieve_by_subject(STACK_OF(X509_OBJECT) *h, int type,
448 X509_NAME *name) 480 X509_NAME *name)
449{ 481 {
450 int idx; 482 int idx;
451 idx = X509_OBJECT_idx_by_subject(h, type, name); 483 idx = X509_OBJECT_idx_by_subject(h, type, name);
452 if (idx==-1) return NULL; 484 if (idx==-1) return NULL;
453 return sk_X509_OBJECT_value(h, idx); 485 return sk_X509_OBJECT_value(h, idx);
454} 486 }
487
488STACK_OF(X509)* X509_STORE_get1_certs(X509_STORE_CTX *ctx, X509_NAME *nm)
489 {
490 int i, idx, cnt;
491 STACK_OF(X509) *sk;
492 X509 *x;
493 X509_OBJECT *obj;
494 sk = sk_X509_new_null();
495 CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE);
496 idx = x509_object_idx_cnt(ctx->ctx->objs, X509_LU_X509, nm, &cnt);
497 if (idx < 0)
498 {
499 /* Nothing found in cache: do lookup to possibly add new
500 * objects to cache
501 */
502 X509_OBJECT xobj;
503 CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
504 if (!X509_STORE_get_by_subject(ctx, X509_LU_X509, nm, &xobj))
505 {
506 sk_X509_free(sk);
507 return NULL;
508 }
509 X509_OBJECT_free_contents(&xobj);
510 CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE);
511 idx = x509_object_idx_cnt(ctx->ctx->objs,X509_LU_X509,nm, &cnt);
512 if (idx < 0)
513 {
514 CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
515 sk_X509_free(sk);
516 return NULL;
517 }
518 }
519 for (i = 0; i < cnt; i++, idx++)
520 {
521 obj = sk_X509_OBJECT_value(ctx->ctx->objs, idx);
522 x = obj->data.x509;
523 CRYPTO_add(&x->references, 1, CRYPTO_LOCK_X509);
524 if (!sk_X509_push(sk, x))
525 {
526 CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
527 X509_free(x);
528 sk_X509_pop_free(sk, X509_free);
529 return NULL;
530 }
531 }
532 CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
533 return sk;
534
535 }
536
537STACK_OF(X509_CRL)* X509_STORE_get1_crls(X509_STORE_CTX *ctx, X509_NAME *nm)
538 {
539 int i, idx, cnt;
540 STACK_OF(X509_CRL) *sk;
541 X509_CRL *x;
542 X509_OBJECT *obj, xobj;
543 sk = sk_X509_CRL_new_null();
544 CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE);
545 /* Check cache first */
546 idx = x509_object_idx_cnt(ctx->ctx->objs, X509_LU_CRL, nm, &cnt);
547
548 /* Always do lookup to possibly add new CRLs to cache
549 */
550 CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
551 if (!X509_STORE_get_by_subject(ctx, X509_LU_CRL, nm, &xobj))
552 {
553 sk_X509_CRL_free(sk);
554 return NULL;
555 }
556 X509_OBJECT_free_contents(&xobj);
557 CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE);
558 idx = x509_object_idx_cnt(ctx->ctx->objs,X509_LU_CRL, nm, &cnt);
559 if (idx < 0)
560 {
561 CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
562 sk_X509_CRL_free(sk);
563 return NULL;
564 }
565
566 for (i = 0; i < cnt; i++, idx++)
567 {
568 obj = sk_X509_OBJECT_value(ctx->ctx->objs, idx);
569 x = obj->data.crl;
570 CRYPTO_add(&x->references, 1, CRYPTO_LOCK_X509_CRL);
571 if (!sk_X509_CRL_push(sk, x))
572 {
573 CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
574 X509_CRL_free(x);
575 sk_X509_CRL_pop_free(sk, X509_CRL_free);
576 return NULL;
577 }
578 }
579 CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
580 return sk;
581 }
455 582
456X509_OBJECT *X509_OBJECT_retrieve_match(STACK_OF(X509_OBJECT) *h, X509_OBJECT *x) 583X509_OBJECT *X509_OBJECT_retrieve_match(STACK_OF(X509_OBJECT) *h, X509_OBJECT *x)
457{ 584 {
458 int idx, i; 585 int idx, i;
459 X509_OBJECT *obj; 586 X509_OBJECT *obj;
460 idx = sk_X509_OBJECT_find(h, x); 587 idx = sk_X509_OBJECT_find(h, x);
461 if (idx == -1) return NULL; 588 if (idx == -1) return NULL;
462 if (x->type != X509_LU_X509) return sk_X509_OBJECT_value(h, idx); 589 if ((x->type != X509_LU_X509) && (x->type != X509_LU_CRL))
590 return sk_X509_OBJECT_value(h, idx);
463 for (i = idx; i < sk_X509_OBJECT_num(h); i++) 591 for (i = idx; i < sk_X509_OBJECT_num(h); i++)
464 { 592 {
465 obj = sk_X509_OBJECT_value(h, i); 593 obj = sk_X509_OBJECT_value(h, i);
466 if (x509_object_cmp((const X509_OBJECT **)&obj, (const X509_OBJECT **)&x)) 594 if (x509_object_cmp((const X509_OBJECT **)&obj, (const X509_OBJECT **)&x))
467 return NULL; 595 return NULL;
468 if ((x->type != X509_LU_X509) || !X509_cmp(obj->data.x509, x->data.x509)) 596 if (x->type == X509_LU_X509)
597 {
598 if (!X509_cmp(obj->data.x509, x->data.x509))
599 return obj;
600 }
601 else if (x->type == X509_LU_CRL)
602 {
603 if (!X509_CRL_match(obj->data.crl, x->data.crl))
604 return obj;
605 }
606 else
469 return obj; 607 return obj;
470 } 608 }
471 return NULL; 609 return NULL;
472} 610 }
473 611
474 612
475/* Try to get issuer certificate from store. Due to limitations 613/* Try to get issuer certificate from store. Due to limitations
476 * of the API this can only retrieve a single certificate matching 614 * of the API this can only retrieve a single certificate matching
477 * a given subject name. However it will fill the cache with all 615 * a given subject name. However it will fill the cache with all
478 * matching certificates, so we can examine the cache for all 616 * matching certificates, so we can examine the cache for all
479 * matches. 617 * matches.
480 * 618 *
481 * Return values are: 619 * Return values are:
@@ -483,13 +621,11 @@ X509_OBJECT *X509_OBJECT_retrieve_match(STACK_OF(X509_OBJECT) *h, X509_OBJECT *x
483 * 0 certificate not found. 621 * 0 certificate not found.
484 * -1 some other error. 622 * -1 some other error.
485 */ 623 */
486
487
488int X509_STORE_CTX_get1_issuer(X509 **issuer, X509_STORE_CTX *ctx, X509 *x) 624int X509_STORE_CTX_get1_issuer(X509 **issuer, X509_STORE_CTX *ctx, X509 *x)
489{ 625 {
490 X509_NAME *xn; 626 X509_NAME *xn;
491 X509_OBJECT obj, *pobj; 627 X509_OBJECT obj, *pobj;
492 int i, ok, idx; 628 int i, ok, idx, ret;
493 xn=X509_get_issuer_name(x); 629 xn=X509_get_issuer_name(x);
494 ok=X509_STORE_get_by_subject(ctx,X509_LU_X509,xn,&obj); 630 ok=X509_STORE_get_by_subject(ctx,X509_LU_X509,xn,&obj);
495 if (ok != X509_LU_X509) 631 if (ok != X509_LU_X509)
@@ -515,27 +651,34 @@ int X509_STORE_CTX_get1_issuer(X509 **issuer, X509_STORE_CTX *ctx, X509 *x)
515 return 1; 651 return 1;
516 } 652 }
517 X509_OBJECT_free_contents(&obj); 653 X509_OBJECT_free_contents(&obj);
518 /* Else find index of first matching cert */
519 idx = X509_OBJECT_idx_by_subject(ctx->ctx->objs, X509_LU_X509, xn);
520 /* This shouldn't normally happen since we already have one match */
521 if (idx == -1) return 0;
522 654
523 /* Look through all matching certificates for a suitable issuer */ 655 /* Else find index of first cert accepted by 'check_issued' */
524 for (i = idx; i < sk_X509_OBJECT_num(ctx->ctx->objs); i++) 656 ret = 0;
657 CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE);
658 idx = X509_OBJECT_idx_by_subject(ctx->ctx->objs, X509_LU_X509, xn);
659 if (idx != -1) /* should be true as we've had at least one match */
525 { 660 {
526 pobj = sk_X509_OBJECT_value(ctx->ctx->objs, i); 661 /* Look through all matching certs for suitable issuer */
527 /* See if we've ran out of matches */ 662 for (i = idx; i < sk_X509_OBJECT_num(ctx->ctx->objs); i++)
528 if (pobj->type != X509_LU_X509) return 0;
529 if (X509_NAME_cmp(xn, X509_get_subject_name(pobj->data.x509))) return 0;
530 if (ctx->check_issued(ctx, x, pobj->data.x509))
531 { 663 {
532 *issuer = pobj->data.x509; 664 pobj = sk_X509_OBJECT_value(ctx->ctx->objs, i);
533 X509_OBJECT_up_ref_count(pobj); 665 /* See if we've run past the matches */
534 return 1; 666 if (pobj->type != X509_LU_X509)
667 break;
668 if (X509_NAME_cmp(xn, X509_get_subject_name(pobj->data.x509)))
669 break;
670 if (ctx->check_issued(ctx, x, pobj->data.x509))
671 {
672 *issuer = pobj->data.x509;
673 X509_OBJECT_up_ref_count(pobj);
674 ret = 1;
675 break;
676 }
535 } 677 }
536 } 678 }
537 return 0; 679 CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
538} 680 return ret;
681 }
539 682
540int X509_STORE_set_flags(X509_STORE *ctx, unsigned long flags) 683int X509_STORE_set_flags(X509_STORE *ctx, unsigned long flags)
541 { 684 {
@@ -563,5 +706,11 @@ int X509_STORE_set1_param(X509_STORE *ctx, X509_VERIFY_PARAM *param)
563 return X509_VERIFY_PARAM_set1(ctx->param, param); 706 return X509_VERIFY_PARAM_set1(ctx->param, param);
564 } 707 }
565 708
709void X509_STORE_set_verify_cb(X509_STORE *ctx,
710 int (*verify_cb)(int, X509_STORE_CTX *))
711 {
712 ctx->verify_cb = verify_cb;
713 }
714
566IMPLEMENT_STACK_OF(X509_LOOKUP) 715IMPLEMENT_STACK_OF(X509_LOOKUP)
567IMPLEMENT_STACK_OF(X509_OBJECT) 716IMPLEMENT_STACK_OF(X509_OBJECT)
diff --git a/src/lib/libcrypto/x509/x509_obj.c b/src/lib/libcrypto/x509/x509_obj.c
index 1e718f76eb..21fed9f838 100644
--- a/src/lib/libcrypto/x509/x509_obj.c
+++ b/src/lib/libcrypto/x509/x509_obj.c
@@ -72,7 +72,7 @@ int i;
72 char *p; 72 char *p;
73 unsigned char *q; 73 unsigned char *q;
74 BUF_MEM *b=NULL; 74 BUF_MEM *b=NULL;
75 static char hex[17]="0123456789ABCDEF"; 75 static const char hex[17]="0123456789ABCDEF";
76 int gs_doit[4]; 76 int gs_doit[4];
77 char tmp_buf[80]; 77 char tmp_buf[80];
78#ifdef CHARSET_EBCDIC 78#ifdef CHARSET_EBCDIC
diff --git a/src/lib/libcrypto/x509/x509_req.c b/src/lib/libcrypto/x509/x509_req.c
index 3872e1fb64..48183dc00c 100644
--- a/src/lib/libcrypto/x509/x509_req.c
+++ b/src/lib/libcrypto/x509/x509_req.c
@@ -61,6 +61,7 @@
61#include <openssl/bn.h> 61#include <openssl/bn.h>
62#include <openssl/evp.h> 62#include <openssl/evp.h>
63#include <openssl/asn1.h> 63#include <openssl/asn1.h>
64#include <openssl/asn1t.h>
64#include <openssl/x509.h> 65#include <openssl/x509.h>
65#include <openssl/objects.h> 66#include <openssl/objects.h>
66#include <openssl/buffer.h> 67#include <openssl/buffer.h>
@@ -205,10 +206,9 @@ STACK_OF(X509_EXTENSION) *X509_REQ_get_extensions(X509_REQ *req)
205 if(!ext || (ext->type != V_ASN1_SEQUENCE)) 206 if(!ext || (ext->type != V_ASN1_SEQUENCE))
206 return NULL; 207 return NULL;
207 p = ext->value.sequence->data; 208 p = ext->value.sequence->data;
208 return d2i_ASN1_SET_OF_X509_EXTENSION(NULL, &p, 209 return (STACK_OF(X509_EXTENSION) *)
209 ext->value.sequence->length, 210 ASN1_item_d2i(NULL, &p, ext->value.sequence->length,
210 d2i_X509_EXTENSION, X509_EXTENSION_free, 211 ASN1_ITEM_rptr(X509_EXTENSIONS));
211 V_ASN1_SEQUENCE, V_ASN1_UNIVERSAL);
212} 212}
213 213
214/* Add a STACK_OF extensions to a certificate request: allow alternative OIDs 214/* Add a STACK_OF extensions to a certificate request: allow alternative OIDs
@@ -218,8 +218,6 @@ STACK_OF(X509_EXTENSION) *X509_REQ_get_extensions(X509_REQ *req)
218int X509_REQ_add_extensions_nid(X509_REQ *req, STACK_OF(X509_EXTENSION) *exts, 218int X509_REQ_add_extensions_nid(X509_REQ *req, STACK_OF(X509_EXTENSION) *exts,
219 int nid) 219 int nid)
220{ 220{
221 unsigned char *p = NULL, *q;
222 long len;
223 ASN1_TYPE *at = NULL; 221 ASN1_TYPE *at = NULL;
224 X509_ATTRIBUTE *attr = NULL; 222 X509_ATTRIBUTE *attr = NULL;
225 if(!(at = ASN1_TYPE_new()) || 223 if(!(at = ASN1_TYPE_new()) ||
@@ -227,15 +225,10 @@ int X509_REQ_add_extensions_nid(X509_REQ *req, STACK_OF(X509_EXTENSION) *exts,
227 225
228 at->type = V_ASN1_SEQUENCE; 226 at->type = V_ASN1_SEQUENCE;
229 /* Generate encoding of extensions */ 227 /* Generate encoding of extensions */
230 len = i2d_ASN1_SET_OF_X509_EXTENSION(exts, NULL, i2d_X509_EXTENSION, 228 at->value.sequence->length =
231 V_ASN1_SEQUENCE, V_ASN1_UNIVERSAL, IS_SEQUENCE); 229 ASN1_item_i2d((ASN1_VALUE *)exts,
232 if(!(p = OPENSSL_malloc(len))) goto err; 230 &at->value.sequence->data,
233 q = p; 231 ASN1_ITEM_rptr(X509_EXTENSIONS));
234 i2d_ASN1_SET_OF_X509_EXTENSION(exts, &q, i2d_X509_EXTENSION,
235 V_ASN1_SEQUENCE, V_ASN1_UNIVERSAL, IS_SEQUENCE);
236 at->value.sequence->data = p;
237 p = NULL;
238 at->value.sequence->length = len;
239 if(!(attr = X509_ATTRIBUTE_new())) goto err; 232 if(!(attr = X509_ATTRIBUTE_new())) goto err;
240 if(!(attr->value.set = sk_ASN1_TYPE_new_null())) goto err; 233 if(!(attr->value.set = sk_ASN1_TYPE_new_null())) goto err;
241 if(!sk_ASN1_TYPE_push(attr->value.set, at)) goto err; 234 if(!sk_ASN1_TYPE_push(attr->value.set, at)) goto err;
@@ -250,7 +243,6 @@ int X509_REQ_add_extensions_nid(X509_REQ *req, STACK_OF(X509_EXTENSION) *exts,
250 if(!sk_X509_ATTRIBUTE_push(req->req_info->attributes, attr)) goto err; 243 if(!sk_X509_ATTRIBUTE_push(req->req_info->attributes, attr)) goto err;
251 return 1; 244 return 1;
252 err: 245 err:
253 if(p) OPENSSL_free(p);
254 X509_ATTRIBUTE_free(attr); 246 X509_ATTRIBUTE_free(attr);
255 ASN1_TYPE_free(at); 247 ASN1_TYPE_free(at);
256 return 0; 248 return 0;
diff --git a/src/lib/libcrypto/x509/x509_set.c b/src/lib/libcrypto/x509/x509_set.c
index aaf61ca062..4b94fc5847 100644
--- a/src/lib/libcrypto/x509/x509_set.c
+++ b/src/lib/libcrypto/x509/x509_set.c
@@ -104,7 +104,7 @@ int X509_set_subject_name(X509 *x, X509_NAME *name)
104 return(X509_NAME_set(&x->cert_info->subject,name)); 104 return(X509_NAME_set(&x->cert_info->subject,name));
105 } 105 }
106 106
107int X509_set_notBefore(X509 *x, ASN1_TIME *tm) 107int X509_set_notBefore(X509 *x, const ASN1_TIME *tm)
108 { 108 {
109 ASN1_TIME *in; 109 ASN1_TIME *in;
110 110
@@ -122,7 +122,7 @@ int X509_set_notBefore(X509 *x, ASN1_TIME *tm)
122 return(in != NULL); 122 return(in != NULL);
123 } 123 }
124 124
125int X509_set_notAfter(X509 *x, ASN1_TIME *tm) 125int X509_set_notAfter(X509 *x, const ASN1_TIME *tm)
126 { 126 {
127 ASN1_TIME *in; 127 ASN1_TIME *in;
128 128
diff --git a/src/lib/libcrypto/x509/x509_trs.c b/src/lib/libcrypto/x509/x509_trs.c
index ed18700585..a6cb9c8b1b 100644
--- a/src/lib/libcrypto/x509/x509_trs.c
+++ b/src/lib/libcrypto/x509/x509_trs.c
@@ -84,7 +84,8 @@ static X509_TRUST trstandard[] = {
84{X509_TRUST_EMAIL, 0, trust_1oidany, "S/MIME email", NID_email_protect, NULL}, 84{X509_TRUST_EMAIL, 0, trust_1oidany, "S/MIME email", NID_email_protect, NULL},
85{X509_TRUST_OBJECT_SIGN, 0, trust_1oidany, "Object Signer", NID_code_sign, NULL}, 85{X509_TRUST_OBJECT_SIGN, 0, trust_1oidany, "Object Signer", NID_code_sign, NULL},
86{X509_TRUST_OCSP_SIGN, 0, trust_1oid, "OCSP responder", NID_OCSP_sign, NULL}, 86{X509_TRUST_OCSP_SIGN, 0, trust_1oid, "OCSP responder", NID_OCSP_sign, NULL},
87{X509_TRUST_OCSP_REQUEST, 0, trust_1oid, "OCSP request", NID_ad_OCSP, NULL} 87{X509_TRUST_OCSP_REQUEST, 0, trust_1oid, "OCSP request", NID_ad_OCSP, NULL},
88{X509_TRUST_TSA, 0, trust_1oidany, "TSA server", NID_time_stamp, NULL}
88}; 89};
89 90
90#define X509_TRUST_COUNT (sizeof(trstandard)/sizeof(X509_TRUST)) 91#define X509_TRUST_COUNT (sizeof(trstandard)/sizeof(X509_TRUST))
diff --git a/src/lib/libcrypto/x509/x509_txt.c b/src/lib/libcrypto/x509/x509_txt.c
index 73a8ec726f..c44f753c46 100644
--- a/src/lib/libcrypto/x509/x509_txt.c
+++ b/src/lib/libcrypto/x509/x509_txt.c
@@ -162,8 +162,28 @@ const char *X509_verify_cert_error_string(long n)
162 return("invalid or inconsistent certificate policy extension"); 162 return("invalid or inconsistent certificate policy extension");
163 case X509_V_ERR_NO_EXPLICIT_POLICY: 163 case X509_V_ERR_NO_EXPLICIT_POLICY:
164 return("no explicit policy"); 164 return("no explicit policy");
165 case X509_V_ERR_UNNESTED_RESOURCE: 165 case X509_V_ERR_DIFFERENT_CRL_SCOPE:
166 return("RFC 3779 resource not subset of parent's resources"); 166 return("Different CRL scope");
167 case X509_V_ERR_UNSUPPORTED_EXTENSION_FEATURE:
168 return("Unsupported extension feature");
169 case X509_V_ERR_UNNESTED_RESOURCE:
170 return("RFC 3779 resource not subset of parent's resources");
171
172 case X509_V_ERR_PERMITTED_VIOLATION:
173 return("permitted subtree violation");
174 case X509_V_ERR_EXCLUDED_VIOLATION:
175 return("excluded subtree violation");
176 case X509_V_ERR_SUBTREE_MINMAX:
177 return("name constraints minimum and maximum not supported");
178 case X509_V_ERR_UNSUPPORTED_CONSTRAINT_TYPE:
179 return("unsupported name constraint type");
180 case X509_V_ERR_UNSUPPORTED_CONSTRAINT_SYNTAX:
181 return("unsupported or invalid name constraint syntax");
182 case X509_V_ERR_UNSUPPORTED_NAME_SYNTAX:
183 return("unsupported or invalid name syntax");
184 case X509_V_ERR_CRL_PATH_VALIDATION_ERROR:
185 return("CRL path validation error");
186
167 default: 187 default:
168 BIO_snprintf(buf,sizeof buf,"error number %ld",n); 188 BIO_snprintf(buf,sizeof buf,"error number %ld",n);
169 return(buf); 189 return(buf);
diff --git a/src/lib/libcrypto/x509/x509_vfy.c b/src/lib/libcrypto/x509/x509_vfy.c
index 336c40ddd7..87ebf62525 100644
--- a/src/lib/libcrypto/x509/x509_vfy.c
+++ b/src/lib/libcrypto/x509/x509_vfy.c
@@ -70,14 +70,70 @@
70#include <openssl/x509v3.h> 70#include <openssl/x509v3.h>
71#include <openssl/objects.h> 71#include <openssl/objects.h>
72 72
73/* CRL score values */
74
75/* No unhandled critical extensions */
76
77#define CRL_SCORE_NOCRITICAL 0x100
78
79/* certificate is within CRL scope */
80
81#define CRL_SCORE_SCOPE 0x080
82
83/* CRL times valid */
84
85#define CRL_SCORE_TIME 0x040
86
87/* Issuer name matches certificate */
88
89#define CRL_SCORE_ISSUER_NAME 0x020
90
91/* If this score or above CRL is probably valid */
92
93#define CRL_SCORE_VALID (CRL_SCORE_NOCRITICAL|CRL_SCORE_TIME|CRL_SCORE_SCOPE)
94
95/* CRL issuer is certificate issuer */
96
97#define CRL_SCORE_ISSUER_CERT 0x018
98
99/* CRL issuer is on certificate path */
100
101#define CRL_SCORE_SAME_PATH 0x008
102
103/* CRL issuer matches CRL AKID */
104
105#define CRL_SCORE_AKID 0x004
106
107/* Have a delta CRL with valid times */
108
109#define CRL_SCORE_TIME_DELTA 0x002
110
73static int null_callback(int ok,X509_STORE_CTX *e); 111static int null_callback(int ok,X509_STORE_CTX *e);
74static int check_issued(X509_STORE_CTX *ctx, X509 *x, X509 *issuer); 112static int check_issued(X509_STORE_CTX *ctx, X509 *x, X509 *issuer);
75static X509 *find_issuer(X509_STORE_CTX *ctx, STACK_OF(X509) *sk, X509 *x); 113static X509 *find_issuer(X509_STORE_CTX *ctx, STACK_OF(X509) *sk, X509 *x);
76static int check_chain_extensions(X509_STORE_CTX *ctx); 114static int check_chain_extensions(X509_STORE_CTX *ctx);
115static int check_name_constraints(X509_STORE_CTX *ctx);
77static int check_trust(X509_STORE_CTX *ctx); 116static int check_trust(X509_STORE_CTX *ctx);
78static int check_revocation(X509_STORE_CTX *ctx); 117static int check_revocation(X509_STORE_CTX *ctx);
79static int check_cert(X509_STORE_CTX *ctx); 118static int check_cert(X509_STORE_CTX *ctx);
80static int check_policy(X509_STORE_CTX *ctx); 119static int check_policy(X509_STORE_CTX *ctx);
120
121static int get_crl_score(X509_STORE_CTX *ctx, X509 **pissuer,
122 unsigned int *preasons,
123 X509_CRL *crl, X509 *x);
124static int get_crl_delta(X509_STORE_CTX *ctx,
125 X509_CRL **pcrl, X509_CRL **pdcrl, X509 *x);
126static void get_delta_sk(X509_STORE_CTX *ctx, X509_CRL **dcrl, int *pcrl_score,
127 X509_CRL *base, STACK_OF(X509_CRL) *crls);
128static void crl_akid_check(X509_STORE_CTX *ctx, X509_CRL *crl,
129 X509 **pissuer, int *pcrl_score);
130static int crl_crldp_check(X509 *x, X509_CRL *crl, int crl_score,
131 unsigned int *preasons);
132static int check_crl_path(X509_STORE_CTX *ctx, X509 *x);
133static int check_crl_chain(X509_STORE_CTX *ctx,
134 STACK_OF(X509) *cert_path,
135 STACK_OF(X509) *crl_path);
136
81static int internal_verify(X509_STORE_CTX *ctx); 137static int internal_verify(X509_STORE_CTX *ctx);
82const char X509_version[]="X.509" OPENSSL_VERSION_PTEXT; 138const char X509_version[]="X.509" OPENSSL_VERSION_PTEXT;
83 139
@@ -289,6 +345,12 @@ int X509_verify_cert(X509_STORE_CTX *ctx)
289 345
290 if (!ok) goto end; 346 if (!ok) goto end;
291 347
348 /* Check name constraints */
349
350 ok = check_name_constraints(ctx);
351
352 if (!ok) goto end;
353
292 /* The chain extensions are OK: check trust */ 354 /* The chain extensions are OK: check trust */
293 355
294 if (param->trust > 0) ok = check_trust(ctx); 356 if (param->trust > 0) ok = check_trust(ctx);
@@ -398,8 +460,8 @@ static int check_chain_extensions(X509_STORE_CTX *ctx)
398 X509 *x; 460 X509 *x;
399 int (*cb)(int xok,X509_STORE_CTX *xctx); 461 int (*cb)(int xok,X509_STORE_CTX *xctx);
400 int proxy_path_length = 0; 462 int proxy_path_length = 0;
401 int allow_proxy_certs = 463 int purpose;
402 !!(ctx->param->flags & X509_V_FLAG_ALLOW_PROXY_CERTS); 464 int allow_proxy_certs;
403 cb=ctx->verify_cb; 465 cb=ctx->verify_cb;
404 466
405 /* must_be_ca can have 1 of 3 values: 467 /* must_be_ca can have 1 of 3 values:
@@ -412,10 +474,22 @@ static int check_chain_extensions(X509_STORE_CTX *ctx)
412 */ 474 */
413 must_be_ca = -1; 475 must_be_ca = -1;
414 476
415 /* A hack to keep people who don't want to modify their software 477 /* CRL path validation */
416 happy */ 478 if (ctx->parent)
417 if (getenv("OPENSSL_ALLOW_PROXY_CERTS")) 479 {
418 allow_proxy_certs = 1; 480 allow_proxy_certs = 0;
481 purpose = X509_PURPOSE_CRL_SIGN;
482 }
483 else
484 {
485 allow_proxy_certs =
486 !!(ctx->param->flags & X509_V_FLAG_ALLOW_PROXY_CERTS);
487 /* A hack to keep people who don't want to modify their
488 software happy */
489 if (getenv("OPENSSL_ALLOW_PROXY_CERTS"))
490 allow_proxy_certs = 1;
491 purpose = ctx->param->purpose;
492 }
419 493
420 /* Check all untrusted certificates */ 494 /* Check all untrusted certificates */
421 for (i = 0; i < ctx->last_untrusted; i++) 495 for (i = 0; i < ctx->last_untrusted; i++)
@@ -482,8 +556,7 @@ static int check_chain_extensions(X509_STORE_CTX *ctx)
482 } 556 }
483 if (ctx->param->purpose > 0) 557 if (ctx->param->purpose > 0)
484 { 558 {
485 ret = X509_check_purpose(x, ctx->param->purpose, 559 ret = X509_check_purpose(x, purpose, must_be_ca > 0);
486 must_be_ca > 0);
487 if ((ret == 0) 560 if ((ret == 0)
488 || ((ctx->param->flags & X509_V_FLAG_X509_STRICT) 561 || ((ctx->param->flags & X509_V_FLAG_X509_STRICT)
489 && (ret != 1))) 562 && (ret != 1)))
@@ -536,6 +609,42 @@ static int check_chain_extensions(X509_STORE_CTX *ctx)
536#endif 609#endif
537} 610}
538 611
612static int check_name_constraints(X509_STORE_CTX *ctx)
613 {
614 X509 *x;
615 int i, j, rv;
616 /* Check name constraints for all certificates */
617 for (i = sk_X509_num(ctx->chain) - 1; i >= 0; i--)
618 {
619 x = sk_X509_value(ctx->chain, i);
620 /* Ignore self issued certs unless last in chain */
621 if (i && (x->ex_flags & EXFLAG_SI))
622 continue;
623 /* Check against constraints for all certificates higher in
624 * chain including trust anchor. Trust anchor not strictly
625 * speaking needed but if it includes constraints it is to be
626 * assumed it expects them to be obeyed.
627 */
628 for (j = sk_X509_num(ctx->chain) - 1; j > i; j--)
629 {
630 NAME_CONSTRAINTS *nc = sk_X509_value(ctx->chain, j)->nc;
631 if (nc)
632 {
633 rv = NAME_CONSTRAINTS_check(x, nc);
634 if (rv != X509_V_OK)
635 {
636 ctx->error = rv;
637 ctx->error_depth = i;
638 ctx->current_cert = x;
639 if (!ctx->verify_cb(0,ctx))
640 return 0;
641 }
642 }
643 }
644 }
645 return 1;
646 }
647
539static int check_trust(X509_STORE_CTX *ctx) 648static int check_trust(X509_STORE_CTX *ctx)
540{ 649{
541#ifdef OPENSSL_NO_CHAIN_VERIFY 650#ifdef OPENSSL_NO_CHAIN_VERIFY
@@ -570,7 +679,12 @@ static int check_revocation(X509_STORE_CTX *ctx)
570 if (ctx->param->flags & X509_V_FLAG_CRL_CHECK_ALL) 679 if (ctx->param->flags & X509_V_FLAG_CRL_CHECK_ALL)
571 last = sk_X509_num(ctx->chain) - 1; 680 last = sk_X509_num(ctx->chain) - 1;
572 else 681 else
682 {
683 /* If checking CRL paths this isn't the EE certificate */
684 if (ctx->parent)
685 return 1;
573 last = 0; 686 last = 0;
687 }
574 for(i = 0; i <= last; i++) 688 for(i = 0; i <= last; i++)
575 { 689 {
576 ctx->error_depth = i; 690 ctx->error_depth = i;
@@ -582,30 +696,65 @@ static int check_revocation(X509_STORE_CTX *ctx)
582 696
583static int check_cert(X509_STORE_CTX *ctx) 697static int check_cert(X509_STORE_CTX *ctx)
584 { 698 {
585 X509_CRL *crl = NULL; 699 X509_CRL *crl = NULL, *dcrl = NULL;
586 X509 *x; 700 X509 *x;
587 int ok, cnum; 701 int ok, cnum;
588 cnum = ctx->error_depth; 702 cnum = ctx->error_depth;
589 x = sk_X509_value(ctx->chain, cnum); 703 x = sk_X509_value(ctx->chain, cnum);
590 ctx->current_cert = x; 704 ctx->current_cert = x;
591 /* Try to retrieve relevant CRL */ 705 ctx->current_issuer = NULL;
592 ok = ctx->get_crl(ctx, &crl, x); 706 ctx->current_reasons = 0;
593 /* If error looking up CRL, nothing we can do except 707 while (ctx->current_reasons != CRLDP_ALL_REASONS)
594 * notify callback
595 */
596 if(!ok)
597 { 708 {
598 ctx->error = X509_V_ERR_UNABLE_TO_GET_CRL; 709 /* Try to retrieve relevant CRL */
599 ok = ctx->verify_cb(0, ctx); 710 if (ctx->get_crl)
600 goto err; 711 ok = ctx->get_crl(ctx, &crl, x);
712 else
713 ok = get_crl_delta(ctx, &crl, &dcrl, x);
714 /* If error looking up CRL, nothing we can do except
715 * notify callback
716 */
717 if(!ok)
718 {
719 ctx->error = X509_V_ERR_UNABLE_TO_GET_CRL;
720 ok = ctx->verify_cb(0, ctx);
721 goto err;
722 }
723 ctx->current_crl = crl;
724 ok = ctx->check_crl(ctx, crl);
725 if (!ok)
726 goto err;
727
728 if (dcrl)
729 {
730 ok = ctx->check_crl(ctx, dcrl);
731 if (!ok)
732 goto err;
733 ok = ctx->cert_crl(ctx, dcrl, x);
734 if (!ok)
735 goto err;
736 }
737 else
738 ok = 1;
739
740 /* Don't look in full CRL if delta reason is removefromCRL */
741 if (ok != 2)
742 {
743 ok = ctx->cert_crl(ctx, crl, x);
744 if (!ok)
745 goto err;
746 }
747
748 X509_CRL_free(crl);
749 X509_CRL_free(dcrl);
750 crl = NULL;
751 dcrl = NULL;
601 } 752 }
602 ctx->current_crl = crl;
603 ok = ctx->check_crl(ctx, crl);
604 if (!ok) goto err;
605 ok = ctx->cert_crl(ctx, crl, x);
606 err: 753 err:
607 ctx->current_crl = NULL;
608 X509_CRL_free(crl); 754 X509_CRL_free(crl);
755 X509_CRL_free(dcrl);
756
757 ctx->current_crl = NULL;
609 return ok; 758 return ok;
610 759
611 } 760 }
@@ -616,7 +765,8 @@ static int check_crl_time(X509_STORE_CTX *ctx, X509_CRL *crl, int notify)
616 { 765 {
617 time_t *ptime; 766 time_t *ptime;
618 int i; 767 int i;
619 ctx->current_crl = crl; 768 if (notify)
769 ctx->current_crl = crl;
620 if (ctx->param->flags & X509_V_FLAG_USE_CHECK_TIME) 770 if (ctx->param->flags & X509_V_FLAG_USE_CHECK_TIME)
621 ptime = &ctx->param->check_time; 771 ptime = &ctx->param->check_time;
622 else 772 else
@@ -625,15 +775,19 @@ static int check_crl_time(X509_STORE_CTX *ctx, X509_CRL *crl, int notify)
625 i=X509_cmp_time(X509_CRL_get_lastUpdate(crl), ptime); 775 i=X509_cmp_time(X509_CRL_get_lastUpdate(crl), ptime);
626 if (i == 0) 776 if (i == 0)
627 { 777 {
778 if (!notify)
779 return 0;
628 ctx->error=X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD; 780 ctx->error=X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD;
629 if (!notify || !ctx->verify_cb(0, ctx)) 781 if (!ctx->verify_cb(0, ctx))
630 return 0; 782 return 0;
631 } 783 }
632 784
633 if (i > 0) 785 if (i > 0)
634 { 786 {
787 if (!notify)
788 return 0;
635 ctx->error=X509_V_ERR_CRL_NOT_YET_VALID; 789 ctx->error=X509_V_ERR_CRL_NOT_YET_VALID;
636 if (!notify || !ctx->verify_cb(0, ctx)) 790 if (!ctx->verify_cb(0, ctx))
637 return 0; 791 return 0;
638 } 792 }
639 793
@@ -643,92 +797,545 @@ static int check_crl_time(X509_STORE_CTX *ctx, X509_CRL *crl, int notify)
643 797
644 if (i == 0) 798 if (i == 0)
645 { 799 {
800 if (!notify)
801 return 0;
646 ctx->error=X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD; 802 ctx->error=X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD;
647 if (!notify || !ctx->verify_cb(0, ctx)) 803 if (!ctx->verify_cb(0, ctx))
648 return 0; 804 return 0;
649 } 805 }
650 806 /* Ignore expiry of base CRL is delta is valid */
651 if (i < 0) 807 if ((i < 0) && !(ctx->current_crl_score & CRL_SCORE_TIME_DELTA))
652 { 808 {
809 if (!notify)
810 return 0;
653 ctx->error=X509_V_ERR_CRL_HAS_EXPIRED; 811 ctx->error=X509_V_ERR_CRL_HAS_EXPIRED;
654 if (!notify || !ctx->verify_cb(0, ctx)) 812 if (!ctx->verify_cb(0, ctx))
655 return 0; 813 return 0;
656 } 814 }
657 } 815 }
658 816
659 ctx->current_crl = NULL; 817 if (notify)
818 ctx->current_crl = NULL;
660 819
661 return 1; 820 return 1;
662 } 821 }
663 822
664/* Lookup CRLs from the supplied list. Look for matching isser name 823static int get_crl_sk(X509_STORE_CTX *ctx, X509_CRL **pcrl, X509_CRL **pdcrl,
665 * and validity. If we can't find a valid CRL return the last one 824 X509 **pissuer, int *pscore, unsigned int *preasons,
666 * with matching name. This gives more meaningful error codes. Otherwise 825 STACK_OF(X509_CRL) *crls)
667 * we'd get a CRL not found error if a CRL existed with matching name but
668 * was invalid.
669 */
670
671static int get_crl_sk(X509_STORE_CTX *ctx, X509_CRL **pcrl,
672 X509_NAME *nm, STACK_OF(X509_CRL) *crls)
673 { 826 {
674 int i; 827 int i, crl_score, best_score = *pscore;
828 unsigned int reasons, best_reasons = 0;
829 X509 *x = ctx->current_cert;
675 X509_CRL *crl, *best_crl = NULL; 830 X509_CRL *crl, *best_crl = NULL;
831 X509 *crl_issuer = NULL, *best_crl_issuer = NULL;
832
676 for (i = 0; i < sk_X509_CRL_num(crls); i++) 833 for (i = 0; i < sk_X509_CRL_num(crls); i++)
677 { 834 {
678 crl = sk_X509_CRL_value(crls, i); 835 crl = sk_X509_CRL_value(crls, i);
679 if (X509_NAME_cmp(nm, X509_CRL_get_issuer(crl))) 836 reasons = *preasons;
680 continue; 837 crl_score = get_crl_score(ctx, &crl_issuer, &reasons, crl, x);
681 if (check_crl_time(ctx, crl, 0)) 838
839 if (crl_score > best_score)
682 { 840 {
683 *pcrl = crl; 841 best_crl = crl;
684 CRYPTO_add(&crl->references, 1, CRYPTO_LOCK_X509); 842 best_crl_issuer = crl_issuer;
685 return 1; 843 best_score = crl_score;
844 best_reasons = reasons;
686 } 845 }
687 best_crl = crl;
688 } 846 }
847
689 if (best_crl) 848 if (best_crl)
690 { 849 {
850 if (*pcrl)
851 X509_CRL_free(*pcrl);
691 *pcrl = best_crl; 852 *pcrl = best_crl;
692 CRYPTO_add(&best_crl->references, 1, CRYPTO_LOCK_X509); 853 *pissuer = best_crl_issuer;
854 *pscore = best_score;
855 *preasons = best_reasons;
856 CRYPTO_add(&best_crl->references, 1, CRYPTO_LOCK_X509_CRL);
857 if (*pdcrl)
858 {
859 X509_CRL_free(*pdcrl);
860 *pdcrl = NULL;
861 }
862 get_delta_sk(ctx, pdcrl, pscore, best_crl, crls);
693 } 863 }
694 864
865 if (best_score >= CRL_SCORE_VALID)
866 return 1;
867
695 return 0; 868 return 0;
696 } 869 }
697 870
698/* Retrieve CRL corresponding to certificate: currently just a 871/* Compare two CRL extensions for delta checking purposes. They should be
699 * subject lookup: maybe use AKID later... 872 * both present or both absent. If both present all fields must be identical.
700 */ 873 */
701static int get_crl(X509_STORE_CTX *ctx, X509_CRL **pcrl, X509 *x) 874
875static int crl_extension_match(X509_CRL *a, X509_CRL *b, int nid)
702 { 876 {
703 int ok; 877 ASN1_OCTET_STRING *exta, *extb;
704 X509_CRL *crl = NULL; 878 int i;
705 X509_OBJECT xobj; 879 i = X509_CRL_get_ext_by_NID(a, nid, 0);
706 X509_NAME *nm; 880 if (i >= 0)
707 nm = X509_get_issuer_name(x);
708 ok = get_crl_sk(ctx, &crl, nm, ctx->crls);
709 if (ok)
710 { 881 {
711 *pcrl = crl; 882 /* Can't have multiple occurrences */
883 if (X509_CRL_get_ext_by_NID(a, nid, i) != -1)
884 return 0;
885 exta = X509_EXTENSION_get_data(X509_CRL_get_ext(a, i));
886 }
887 else
888 exta = NULL;
889
890 i = X509_CRL_get_ext_by_NID(b, nid, 0);
891
892 if (i >= 0)
893 {
894
895 if (X509_CRL_get_ext_by_NID(b, nid, i) != -1)
896 return 0;
897 extb = X509_EXTENSION_get_data(X509_CRL_get_ext(b, i));
898 }
899 else
900 extb = NULL;
901
902 if (!exta && !extb)
712 return 1; 903 return 1;
904
905 if (!exta || !extb)
906 return 0;
907
908
909 if (ASN1_OCTET_STRING_cmp(exta, extb))
910 return 0;
911
912 return 1;
913 }
914
915/* See if a base and delta are compatible */
916
917static int check_delta_base(X509_CRL *delta, X509_CRL *base)
918 {
919 /* Delta CRL must be a delta */
920 if (!delta->base_crl_number)
921 return 0;
922 /* Base must have a CRL number */
923 if (!base->crl_number)
924 return 0;
925 /* Issuer names must match */
926 if (X509_NAME_cmp(X509_CRL_get_issuer(base),
927 X509_CRL_get_issuer(delta)))
928 return 0;
929 /* AKID and IDP must match */
930 if (!crl_extension_match(delta, base, NID_authority_key_identifier))
931 return 0;
932 if (!crl_extension_match(delta, base, NID_issuing_distribution_point))
933 return 0;
934 /* Delta CRL base number must not exceed Full CRL number. */
935 if (ASN1_INTEGER_cmp(delta->base_crl_number, base->crl_number) > 0)
936 return 0;
937 /* Delta CRL number must exceed full CRL number */
938 if (ASN1_INTEGER_cmp(delta->crl_number, base->crl_number) > 0)
939 return 1;
940 return 0;
941 }
942
943/* For a given base CRL find a delta... maybe extend to delta scoring
944 * or retrieve a chain of deltas...
945 */
946
947static void get_delta_sk(X509_STORE_CTX *ctx, X509_CRL **dcrl, int *pscore,
948 X509_CRL *base, STACK_OF(X509_CRL) *crls)
949 {
950 X509_CRL *delta;
951 int i;
952 if (!(ctx->param->flags & X509_V_FLAG_USE_DELTAS))
953 return;
954 if (!((ctx->current_cert->ex_flags | base->flags) & EXFLAG_FRESHEST))
955 return;
956 for (i = 0; i < sk_X509_CRL_num(crls); i++)
957 {
958 delta = sk_X509_CRL_value(crls, i);
959 if (check_delta_base(delta, base))
960 {
961 if (check_crl_time(ctx, delta, 0))
962 *pscore |= CRL_SCORE_TIME_DELTA;
963 CRYPTO_add(&delta->references, 1, CRYPTO_LOCK_X509_CRL);
964 *dcrl = delta;
965 return;
966 }
967 }
968 *dcrl = NULL;
969 }
970
971/* For a given CRL return how suitable it is for the supplied certificate 'x'.
972 * The return value is a mask of several criteria.
973 * If the issuer is not the certificate issuer this is returned in *pissuer.
974 * The reasons mask is also used to determine if the CRL is suitable: if
975 * no new reasons the CRL is rejected, otherwise reasons is updated.
976 */
977
978static int get_crl_score(X509_STORE_CTX *ctx, X509 **pissuer,
979 unsigned int *preasons,
980 X509_CRL *crl, X509 *x)
981 {
982
983 int crl_score = 0;
984 unsigned int tmp_reasons = *preasons, crl_reasons;
985
986 /* First see if we can reject CRL straight away */
987
988 /* Invalid IDP cannot be processed */
989 if (crl->idp_flags & IDP_INVALID)
990 return 0;
991 /* Reason codes or indirect CRLs need extended CRL support */
992 if (!(ctx->param->flags & X509_V_FLAG_EXTENDED_CRL_SUPPORT))
993 {
994 if (crl->idp_flags & (IDP_INDIRECT | IDP_REASONS))
995 return 0;
996 }
997 else if (crl->idp_flags & IDP_REASONS)
998 {
999 /* If no new reasons reject */
1000 if (!(crl->idp_reasons & ~tmp_reasons))
1001 return 0;
1002 }
1003 /* Don't process deltas at this stage */
1004 else if (crl->base_crl_number)
1005 return 0;
1006 /* If issuer name doesn't match certificate need indirect CRL */
1007 if (X509_NAME_cmp(X509_get_issuer_name(x), X509_CRL_get_issuer(crl)))
1008 {
1009 if (!(crl->idp_flags & IDP_INDIRECT))
1010 return 0;
1011 }
1012 else
1013 crl_score |= CRL_SCORE_ISSUER_NAME;
1014
1015 if (!(crl->flags & EXFLAG_CRITICAL))
1016 crl_score |= CRL_SCORE_NOCRITICAL;
1017
1018 /* Check expiry */
1019 if (check_crl_time(ctx, crl, 0))
1020 crl_score |= CRL_SCORE_TIME;
1021
1022 /* Check authority key ID and locate certificate issuer */
1023 crl_akid_check(ctx, crl, pissuer, &crl_score);
1024
1025 /* If we can't locate certificate issuer at this point forget it */
1026
1027 if (!(crl_score & CRL_SCORE_AKID))
1028 return 0;
1029
1030 /* Check cert for matching CRL distribution points */
1031
1032 if (crl_crldp_check(x, crl, crl_score, &crl_reasons))
1033 {
1034 /* If no new reasons reject */
1035 if (!(crl_reasons & ~tmp_reasons))
1036 return 0;
1037 tmp_reasons |= crl_reasons;
1038 crl_score |= CRL_SCORE_SCOPE;
713 } 1039 }
714 1040
715 ok = X509_STORE_get_by_subject(ctx, X509_LU_CRL, nm, &xobj); 1041 *preasons = tmp_reasons;
1042
1043 return crl_score;
1044
1045 }
1046
1047static void crl_akid_check(X509_STORE_CTX *ctx, X509_CRL *crl,
1048 X509 **pissuer, int *pcrl_score)
1049 {
1050 X509 *crl_issuer = NULL;
1051 X509_NAME *cnm = X509_CRL_get_issuer(crl);
1052 int cidx = ctx->error_depth;
1053 int i;
716 1054
717 if (!ok) 1055 if (cidx != sk_X509_num(ctx->chain) - 1)
1056 cidx++;
1057
1058 crl_issuer = sk_X509_value(ctx->chain, cidx);
1059
1060 if (X509_check_akid(crl_issuer, crl->akid) == X509_V_OK)
718 { 1061 {
719 /* If we got a near match from get_crl_sk use that */ 1062 if (*pcrl_score & CRL_SCORE_ISSUER_NAME)
720 if (crl)
721 { 1063 {
722 *pcrl = crl; 1064 *pcrl_score |= CRL_SCORE_AKID|CRL_SCORE_ISSUER_CERT;
723 return 1; 1065 *pissuer = crl_issuer;
1066 return;
1067 }
1068 }
1069
1070 for (cidx++; cidx < sk_X509_num(ctx->chain); cidx++)
1071 {
1072 crl_issuer = sk_X509_value(ctx->chain, cidx);
1073 if (X509_NAME_cmp(X509_get_subject_name(crl_issuer), cnm))
1074 continue;
1075 if (X509_check_akid(crl_issuer, crl->akid) == X509_V_OK)
1076 {
1077 *pcrl_score |= CRL_SCORE_AKID|CRL_SCORE_SAME_PATH;
1078 *pissuer = crl_issuer;
1079 return;
1080 }
1081 }
1082
1083 /* Anything else needs extended CRL support */
1084
1085 if (!(ctx->param->flags & X509_V_FLAG_EXTENDED_CRL_SUPPORT))
1086 return;
1087
1088 /* Otherwise the CRL issuer is not on the path. Look for it in the
1089 * set of untrusted certificates.
1090 */
1091 for (i = 0; i < sk_X509_num(ctx->untrusted); i++)
1092 {
1093 crl_issuer = sk_X509_value(ctx->untrusted, i);
1094 if (X509_NAME_cmp(X509_get_subject_name(crl_issuer), cnm))
1095 continue;
1096 if (X509_check_akid(crl_issuer, crl->akid) == X509_V_OK)
1097 {
1098 *pissuer = crl_issuer;
1099 *pcrl_score |= CRL_SCORE_AKID;
1100 return;
724 } 1101 }
1102 }
1103 }
1104
1105/* Check the path of a CRL issuer certificate. This creates a new
1106 * X509_STORE_CTX and populates it with most of the parameters from the
1107 * parent. This could be optimised somewhat since a lot of path checking
1108 * will be duplicated by the parent, but this will rarely be used in
1109 * practice.
1110 */
1111
1112static int check_crl_path(X509_STORE_CTX *ctx, X509 *x)
1113 {
1114 X509_STORE_CTX crl_ctx;
1115 int ret;
1116 /* Don't allow recursive CRL path validation */
1117 if (ctx->parent)
725 return 0; 1118 return 0;
1119 if (!X509_STORE_CTX_init(&crl_ctx, ctx->ctx, x, ctx->untrusted))
1120 return -1;
1121
1122 crl_ctx.crls = ctx->crls;
1123 /* Copy verify params across */
1124 X509_STORE_CTX_set0_param(&crl_ctx, ctx->param);
1125
1126 crl_ctx.parent = ctx;
1127 crl_ctx.verify_cb = ctx->verify_cb;
1128
1129 /* Verify CRL issuer */
1130 ret = X509_verify_cert(&crl_ctx);
1131
1132 if (ret <= 0)
1133 goto err;
1134
1135 /* Check chain is acceptable */
1136
1137 ret = check_crl_chain(ctx, ctx->chain, crl_ctx.chain);
1138 err:
1139 X509_STORE_CTX_cleanup(&crl_ctx);
1140 return ret;
1141 }
1142
1143/* RFC3280 says nothing about the relationship between CRL path
1144 * and certificate path, which could lead to situations where a
1145 * certificate could be revoked or validated by a CA not authorised
1146 * to do so. RFC5280 is more strict and states that the two paths must
1147 * end in the same trust anchor, though some discussions remain...
1148 * until this is resolved we use the RFC5280 version
1149 */
1150
1151static int check_crl_chain(X509_STORE_CTX *ctx,
1152 STACK_OF(X509) *cert_path,
1153 STACK_OF(X509) *crl_path)
1154 {
1155 X509 *cert_ta, *crl_ta;
1156 cert_ta = sk_X509_value(cert_path, sk_X509_num(cert_path) - 1);
1157 crl_ta = sk_X509_value(crl_path, sk_X509_num(crl_path) - 1);
1158 if (!X509_cmp(cert_ta, crl_ta))
1159 return 1;
1160 return 0;
1161 }
1162
1163/* Check for match between two dist point names: three separate cases.
1164 * 1. Both are relative names and compare X509_NAME types.
1165 * 2. One full, one relative. Compare X509_NAME to GENERAL_NAMES.
1166 * 3. Both are full names and compare two GENERAL_NAMES.
1167 * 4. One is NULL: automatic match.
1168 */
1169
1170
1171static int idp_check_dp(DIST_POINT_NAME *a, DIST_POINT_NAME *b)
1172 {
1173 X509_NAME *nm = NULL;
1174 GENERAL_NAMES *gens = NULL;
1175 GENERAL_NAME *gena, *genb;
1176 int i, j;
1177 if (!a || !b)
1178 return 1;
1179 if (a->type == 1)
1180 {
1181 if (!a->dpname)
1182 return 0;
1183 /* Case 1: two X509_NAME */
1184 if (b->type == 1)
1185 {
1186 if (!b->dpname)
1187 return 0;
1188 if (!X509_NAME_cmp(a->dpname, b->dpname))
1189 return 1;
1190 else
1191 return 0;
1192 }
1193 /* Case 2: set name and GENERAL_NAMES appropriately */
1194 nm = a->dpname;
1195 gens = b->name.fullname;
1196 }
1197 else if (b->type == 1)
1198 {
1199 if (!b->dpname)
1200 return 0;
1201 /* Case 2: set name and GENERAL_NAMES appropriately */
1202 gens = a->name.fullname;
1203 nm = b->dpname;
726 } 1204 }
727 1205
728 *pcrl = xobj.data.crl; 1206 /* Handle case 2 with one GENERAL_NAMES and one X509_NAME */
1207 if (nm)
1208 {
1209 for (i = 0; i < sk_GENERAL_NAME_num(gens); i++)
1210 {
1211 gena = sk_GENERAL_NAME_value(gens, i);
1212 if (gena->type != GEN_DIRNAME)
1213 continue;
1214 if (!X509_NAME_cmp(nm, gena->d.directoryName))
1215 return 1;
1216 }
1217 return 0;
1218 }
1219
1220 /* Else case 3: two GENERAL_NAMES */
1221
1222 for (i = 0; i < sk_GENERAL_NAME_num(a->name.fullname); i++)
1223 {
1224 gena = sk_GENERAL_NAME_value(a->name.fullname, i);
1225 for (j = 0; j < sk_GENERAL_NAME_num(b->name.fullname); j++)
1226 {
1227 genb = sk_GENERAL_NAME_value(b->name.fullname, j);
1228 if (!GENERAL_NAME_cmp(gena, genb))
1229 return 1;
1230 }
1231 }
1232
1233 return 0;
1234
1235 }
1236
1237static int crldp_check_crlissuer(DIST_POINT *dp, X509_CRL *crl, int crl_score)
1238 {
1239 int i;
1240 X509_NAME *nm = X509_CRL_get_issuer(crl);
1241 /* If no CRLissuer return is successful iff don't need a match */
1242 if (!dp->CRLissuer)
1243 return !!(crl_score & CRL_SCORE_ISSUER_NAME);
1244 for (i = 0; i < sk_GENERAL_NAME_num(dp->CRLissuer); i++)
1245 {
1246 GENERAL_NAME *gen = sk_GENERAL_NAME_value(dp->CRLissuer, i);
1247 if (gen->type != GEN_DIRNAME)
1248 continue;
1249 if (!X509_NAME_cmp(gen->d.directoryName, nm))
1250 return 1;
1251 }
1252 return 0;
1253 }
1254
1255/* Check CRLDP and IDP */
1256
1257static int crl_crldp_check(X509 *x, X509_CRL *crl, int crl_score,
1258 unsigned int *preasons)
1259 {
1260 int i;
1261 if (crl->idp_flags & IDP_ONLYATTR)
1262 return 0;
1263 if (x->ex_flags & EXFLAG_CA)
1264 {
1265 if (crl->idp_flags & IDP_ONLYUSER)
1266 return 0;
1267 }
1268 else
1269 {
1270 if (crl->idp_flags & IDP_ONLYCA)
1271 return 0;
1272 }
1273 *preasons = crl->idp_reasons;
1274 for (i = 0; i < sk_DIST_POINT_num(x->crldp); i++)
1275 {
1276 DIST_POINT *dp = sk_DIST_POINT_value(x->crldp, i);
1277 if (crldp_check_crlissuer(dp, crl, crl_score))
1278 {
1279 if (!crl->idp ||
1280 idp_check_dp(dp->distpoint, crl->idp->distpoint))
1281 {
1282 *preasons &= dp->dp_reasons;
1283 return 1;
1284 }
1285 }
1286 }
1287 if ((!crl->idp || !crl->idp->distpoint) && (crl_score & CRL_SCORE_ISSUER_NAME))
1288 return 1;
1289 return 0;
1290 }
1291
1292/* Retrieve CRL corresponding to current certificate.
1293 * If deltas enabled try to find a delta CRL too
1294 */
1295
1296static int get_crl_delta(X509_STORE_CTX *ctx,
1297 X509_CRL **pcrl, X509_CRL **pdcrl, X509 *x)
1298 {
1299 int ok;
1300 X509 *issuer = NULL;
1301 int crl_score = 0;
1302 unsigned int reasons;
1303 X509_CRL *crl = NULL, *dcrl = NULL;
1304 STACK_OF(X509_CRL) *skcrl;
1305 X509_NAME *nm = X509_get_issuer_name(x);
1306 reasons = ctx->current_reasons;
1307 ok = get_crl_sk(ctx, &crl, &dcrl,
1308 &issuer, &crl_score, &reasons, ctx->crls);
1309
1310 if (ok)
1311 goto done;
1312
1313 /* Lookup CRLs from store */
1314
1315 skcrl = ctx->lookup_crls(ctx, nm);
1316
1317 /* If no CRLs found and a near match from get_crl_sk use that */
1318 if (!skcrl && crl)
1319 goto done;
1320
1321 get_crl_sk(ctx, &crl, &dcrl, &issuer, &crl_score, &reasons, skcrl);
1322
1323 sk_X509_CRL_pop_free(skcrl, X509_CRL_free);
1324
1325 done:
1326
1327 /* If we got any kind of CRL use it and return success */
729 if (crl) 1328 if (crl)
730 X509_CRL_free(crl); 1329 {
731 return 1; 1330 ctx->current_issuer = issuer;
1331 ctx->current_crl_score = crl_score;
1332 ctx->current_reasons = reasons;
1333 *pcrl = crl;
1334 *pdcrl = dcrl;
1335 return 1;
1336 }
1337
1338 return 0;
732 } 1339 }
733 1340
734/* Check CRL validity */ 1341/* Check CRL validity */
@@ -739,10 +1346,14 @@ static int check_crl(X509_STORE_CTX *ctx, X509_CRL *crl)
739 int ok = 0, chnum, cnum; 1346 int ok = 0, chnum, cnum;
740 cnum = ctx->error_depth; 1347 cnum = ctx->error_depth;
741 chnum = sk_X509_num(ctx->chain) - 1; 1348 chnum = sk_X509_num(ctx->chain) - 1;
742 /* Find CRL issuer: if not last certificate then issuer 1349 /* if we have an alternative CRL issuer cert use that */
1350 if (ctx->current_issuer)
1351 issuer = ctx->current_issuer;
1352
1353 /* Else find CRL issuer: if not last certificate then issuer
743 * is next certificate in chain. 1354 * is next certificate in chain.
744 */ 1355 */
745 if(cnum < chnum) 1356 else if (cnum < chnum)
746 issuer = sk_X509_value(ctx->chain, cnum + 1); 1357 issuer = sk_X509_value(ctx->chain, cnum + 1);
747 else 1358 else
748 { 1359 {
@@ -758,13 +1369,52 @@ static int check_crl(X509_STORE_CTX *ctx, X509_CRL *crl)
758 1369
759 if(issuer) 1370 if(issuer)
760 { 1371 {
761 /* Check for cRLSign bit if keyUsage present */ 1372 /* Skip most tests for deltas because they have already
762 if ((issuer->ex_flags & EXFLAG_KUSAGE) && 1373 * been done
763 !(issuer->ex_kusage & KU_CRL_SIGN)) 1374 */
1375 if (!crl->base_crl_number)
764 { 1376 {
765 ctx->error = X509_V_ERR_KEYUSAGE_NO_CRL_SIGN; 1377 /* Check for cRLSign bit if keyUsage present */
766 ok = ctx->verify_cb(0, ctx); 1378 if ((issuer->ex_flags & EXFLAG_KUSAGE) &&
767 if(!ok) goto err; 1379 !(issuer->ex_kusage & KU_CRL_SIGN))
1380 {
1381 ctx->error = X509_V_ERR_KEYUSAGE_NO_CRL_SIGN;
1382 ok = ctx->verify_cb(0, ctx);
1383 if(!ok) goto err;
1384 }
1385
1386 if (!(ctx->current_crl_score & CRL_SCORE_SCOPE))
1387 {
1388 ctx->error = X509_V_ERR_DIFFERENT_CRL_SCOPE;
1389 ok = ctx->verify_cb(0, ctx);
1390 if(!ok) goto err;
1391 }
1392
1393 if (!(ctx->current_crl_score & CRL_SCORE_SAME_PATH))
1394 {
1395 if (check_crl_path(ctx, ctx->current_issuer) <= 0)
1396 {
1397 ctx->error = X509_V_ERR_CRL_PATH_VALIDATION_ERROR;
1398 ok = ctx->verify_cb(0, ctx);
1399 if(!ok) goto err;
1400 }
1401 }
1402
1403 if (crl->idp_flags & IDP_INVALID)
1404 {
1405 ctx->error = X509_V_ERR_INVALID_EXTENSION;
1406 ok = ctx->verify_cb(0, ctx);
1407 if(!ok) goto err;
1408 }
1409
1410
1411 }
1412
1413 if (!(ctx->current_crl_score & CRL_SCORE_TIME))
1414 {
1415 ok = check_crl_time(ctx, crl, 1);
1416 if (!ok)
1417 goto err;
768 } 1418 }
769 1419
770 /* Attempt to get issuer certificate public key */ 1420 /* Attempt to get issuer certificate public key */
@@ -788,10 +1438,6 @@ static int check_crl(X509_STORE_CTX *ctx, X509_CRL *crl)
788 } 1438 }
789 } 1439 }
790 1440
791 ok = check_crl_time(ctx, crl, 1);
792 if (!ok)
793 goto err;
794
795 ok = 1; 1441 ok = 1;
796 1442
797 err: 1443 err:
@@ -802,62 +1448,43 @@ static int check_crl(X509_STORE_CTX *ctx, X509_CRL *crl)
802/* Check certificate against CRL */ 1448/* Check certificate against CRL */
803static int cert_crl(X509_STORE_CTX *ctx, X509_CRL *crl, X509 *x) 1449static int cert_crl(X509_STORE_CTX *ctx, X509_CRL *crl, X509 *x)
804 { 1450 {
805 int idx, ok; 1451 int ok;
806 X509_REVOKED rtmp; 1452 X509_REVOKED *rev;
807 STACK_OF(X509_EXTENSION) *exts; 1453 /* The rules changed for this... previously if a CRL contained
808 X509_EXTENSION *ext; 1454 * unhandled critical extensions it could still be used to indicate
809 /* Look for serial number of certificate in CRL */ 1455 * a certificate was revoked. This has since been changed since
810 rtmp.serialNumber = X509_get_serialNumber(x); 1456 * critical extension can change the meaning of CRL entries.
811 /* Sort revoked into serial number order if not already sorted. 1457 */
812 * Do this under a lock to avoid race condition. 1458 if (crl->flags & EXFLAG_CRITICAL)
813 */
814 if (!sk_X509_REVOKED_is_sorted(crl->crl->revoked))
815 { 1459 {
816 CRYPTO_w_lock(CRYPTO_LOCK_X509_CRL); 1460 if (ctx->param->flags & X509_V_FLAG_IGNORE_CRITICAL)
817 sk_X509_REVOKED_sort(crl->crl->revoked); 1461 return 1;
818 CRYPTO_w_unlock(CRYPTO_LOCK_X509_CRL); 1462 ctx->error = X509_V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION;
1463 ok = ctx->verify_cb(0, ctx);
1464 if(!ok)
1465 return 0;
819 } 1466 }
820 idx = sk_X509_REVOKED_find(crl->crl->revoked, &rtmp); 1467 /* Look for serial number of certificate in CRL
821 /* If found assume revoked: want something cleverer than 1468 * If found make sure reason is not removeFromCRL.
822 * this to handle entry extensions in V2 CRLs.
823 */ 1469 */
824 if(idx >= 0) 1470 if (X509_CRL_get0_by_cert(crl, &rev, x))
825 { 1471 {
1472 if (rev->reason == CRL_REASON_REMOVE_FROM_CRL)
1473 return 2;
826 ctx->error = X509_V_ERR_CERT_REVOKED; 1474 ctx->error = X509_V_ERR_CERT_REVOKED;
827 ok = ctx->verify_cb(0, ctx); 1475 ok = ctx->verify_cb(0, ctx);
828 if (!ok) return 0; 1476 if (!ok)
1477 return 0;
829 } 1478 }
830 1479
831 if (ctx->param->flags & X509_V_FLAG_IGNORE_CRITICAL)
832 return 1;
833
834 /* See if we have any critical CRL extensions: since we
835 * currently don't handle any CRL extensions the CRL must be
836 * rejected.
837 * This code accesses the X509_CRL structure directly: applications
838 * shouldn't do this.
839 */
840
841 exts = crl->crl->extensions;
842
843 for (idx = 0; idx < sk_X509_EXTENSION_num(exts); idx++)
844 {
845 ext = sk_X509_EXTENSION_value(exts, idx);
846 if (ext->critical > 0)
847 {
848 ctx->error =
849 X509_V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION;
850 ok = ctx->verify_cb(0, ctx);
851 if(!ok) return 0;
852 break;
853 }
854 }
855 return 1; 1480 return 1;
856 } 1481 }
857 1482
858static int check_policy(X509_STORE_CTX *ctx) 1483static int check_policy(X509_STORE_CTX *ctx)
859 { 1484 {
860 int ret; 1485 int ret;
1486 if (ctx->parent)
1487 return 1;
861 ret = X509_policy_check(&ctx->tree, &ctx->explicit_policy, ctx->chain, 1488 ret = X509_policy_check(&ctx->tree, &ctx->explicit_policy, ctx->chain,
862 ctx->param->policies, ctx->param->flags); 1489 ctx->param->policies, ctx->param->flags);
863 if (ret == 0) 1490 if (ret == 0)
@@ -880,7 +1507,8 @@ static int check_policy(X509_STORE_CTX *ctx)
880 continue; 1507 continue;
881 ctx->current_cert = x; 1508 ctx->current_cert = x;
882 ctx->error = X509_V_ERR_INVALID_POLICY_EXTENSION; 1509 ctx->error = X509_V_ERR_INVALID_POLICY_EXTENSION;
883 ret = ctx->verify_cb(0, ctx); 1510 if(!ctx->verify_cb(0, ctx))
1511 return 0;
884 } 1512 }
885 return 1; 1513 return 1;
886 } 1514 }
@@ -986,7 +1614,12 @@ static int internal_verify(X509_STORE_CTX *ctx)
986 while (n >= 0) 1614 while (n >= 0)
987 { 1615 {
988 ctx->error_depth=n; 1616 ctx->error_depth=n;
989 if (!xs->valid) 1617
1618 /* Skip signature check for self signed certificates unless
1619 * explicitly asked for. It doesn't add any security and
1620 * just wastes time.
1621 */
1622 if (!xs->valid && (xs != xi || (ctx->param->flags & X509_V_FLAG_CHECK_SS_SIGNATURE)))
990 { 1623 {
991 if ((pkey=X509_get_pubkey(xi)) == NULL) 1624 if ((pkey=X509_get_pubkey(xi)) == NULL)
992 { 1625 {
@@ -996,13 +1629,6 @@ static int internal_verify(X509_STORE_CTX *ctx)
996 if (!ok) goto end; 1629 if (!ok) goto end;
997 } 1630 }
998 else if (X509_verify(xs,pkey) <= 0) 1631 else if (X509_verify(xs,pkey) <= 0)
999 /* XXX For the final trusted self-signed cert,
1000 * this is a waste of time. That check should
1001 * optional so that e.g. 'openssl x509' can be
1002 * used to detect invalid self-signatures, but
1003 * we don't verify again and again in SSL
1004 * handshakes and the like once the cert has
1005 * been declared trusted. */
1006 { 1632 {
1007 ctx->error=X509_V_ERR_CERT_SIGNATURE_FAILURE; 1633 ctx->error=X509_V_ERR_CERT_SIGNATURE_FAILURE;
1008 ctx->current_cert=xs; 1634 ctx->current_cert=xs;
@@ -1041,12 +1667,12 @@ end:
1041 return ok; 1667 return ok;
1042 } 1668 }
1043 1669
1044int X509_cmp_current_time(ASN1_TIME *ctm) 1670int X509_cmp_current_time(const ASN1_TIME *ctm)
1045{ 1671{
1046 return X509_cmp_time(ctm, NULL); 1672 return X509_cmp_time(ctm, NULL);
1047} 1673}
1048 1674
1049int X509_cmp_time(ASN1_TIME *ctm, time_t *cmp_time) 1675int X509_cmp_time(const ASN1_TIME *ctm, time_t *cmp_time)
1050 { 1676 {
1051 char *str; 1677 char *str;
1052 ASN1_TIME atm; 1678 ASN1_TIME atm;
@@ -1101,6 +1727,7 @@ int X509_cmp_time(ASN1_TIME *ctm, time_t *cmp_time)
1101 offset= -offset; 1727 offset= -offset;
1102 } 1728 }
1103 atm.type=ctm->type; 1729 atm.type=ctm->type;
1730 atm.flags = 0;
1104 atm.length=sizeof(buff2); 1731 atm.length=sizeof(buff2);
1105 atm.data=(unsigned char *)buff2; 1732 atm.data=(unsigned char *)buff2;
1106 1733
@@ -1129,19 +1756,28 @@ ASN1_TIME *X509_gmtime_adj(ASN1_TIME *s, long adj)
1129 return X509_time_adj(s, adj, NULL); 1756 return X509_time_adj(s, adj, NULL);
1130} 1757}
1131 1758
1132ASN1_TIME *X509_time_adj(ASN1_TIME *s, long adj, time_t *in_tm) 1759ASN1_TIME *X509_time_adj(ASN1_TIME *s, long offset_sec, time_t *in_tm)
1760 {
1761 return X509_time_adj_ex(s, 0, offset_sec, in_tm);
1762 }
1763
1764ASN1_TIME *X509_time_adj_ex(ASN1_TIME *s,
1765 int offset_day, long offset_sec, time_t *in_tm)
1133 { 1766 {
1134 time_t t; 1767 time_t t;
1135 int type = -1;
1136 1768
1137 if (in_tm) t = *in_tm; 1769 if (in_tm) t = *in_tm;
1138 else time(&t); 1770 else time(&t);
1139 1771
1140 t+=adj; 1772 if (s && !(s->flags & ASN1_STRING_FLAG_MSTRING))
1141 if (s) type = s->type; 1773 {
1142 if (type == V_ASN1_UTCTIME) return ASN1_UTCTIME_set(s,t); 1774 if (s->type == V_ASN1_UTCTIME)
1143 if (type == V_ASN1_GENERALIZEDTIME) return ASN1_GENERALIZEDTIME_set(s, t); 1775 return ASN1_UTCTIME_adj(s,t, offset_day, offset_sec);
1144 return ASN1_TIME_set(s, t); 1776 if (s->type == V_ASN1_GENERALIZEDTIME)
1777 return ASN1_GENERALIZEDTIME_adj(s, t, offset_day,
1778 offset_sec);
1779 }
1780 return ASN1_TIME_adj(s, t, offset_day, offset_sec);
1145 } 1781 }
1146 1782
1147int X509_get_pubkey_parameters(EVP_PKEY *pkey, STACK_OF(X509) *chain) 1783int X509_get_pubkey_parameters(EVP_PKEY *pkey, STACK_OF(X509) *chain)
@@ -1244,6 +1880,21 @@ STACK_OF(X509) *X509_STORE_CTX_get1_chain(X509_STORE_CTX *ctx)
1244 return chain; 1880 return chain;
1245 } 1881 }
1246 1882
1883X509 *X509_STORE_CTX_get0_current_issuer(X509_STORE_CTX *ctx)
1884 {
1885 return ctx->current_issuer;
1886 }
1887
1888X509_CRL *X509_STORE_CTX_get0_current_crl(X509_STORE_CTX *ctx)
1889 {
1890 return ctx->current_crl;
1891 }
1892
1893X509_STORE_CTX *X509_STORE_CTX_get0_parent_ctx(X509_STORE_CTX *ctx)
1894 {
1895 return ctx->parent;
1896 }
1897
1247void X509_STORE_CTX_set_cert(X509_STORE_CTX *ctx, X509 *x) 1898void X509_STORE_CTX_set_cert(X509_STORE_CTX *ctx, X509 *x)
1248 { 1899 {
1249 ctx->cert=x; 1900 ctx->cert=x;
@@ -1365,6 +2016,7 @@ int X509_STORE_CTX_init(X509_STORE_CTX *ctx, X509_STORE *store, X509 *x509,
1365 ctx->current_cert=NULL; 2016 ctx->current_cert=NULL;
1366 ctx->current_issuer=NULL; 2017 ctx->current_issuer=NULL;
1367 ctx->tree = NULL; 2018 ctx->tree = NULL;
2019 ctx->parent = NULL;
1368 2020
1369 ctx->param = X509_VERIFY_PARAM_new(); 2021 ctx->param = X509_VERIFY_PARAM_new();
1370 2022
@@ -1430,7 +2082,7 @@ int X509_STORE_CTX_init(X509_STORE_CTX *ctx, X509_STORE *store, X509 *x509,
1430 if (store && store->get_crl) 2082 if (store && store->get_crl)
1431 ctx->get_crl = store->get_crl; 2083 ctx->get_crl = store->get_crl;
1432 else 2084 else
1433 ctx->get_crl = get_crl; 2085 ctx->get_crl = NULL;
1434 2086
1435 if (store && store->check_crl) 2087 if (store && store->check_crl)
1436 ctx->check_crl = store->check_crl; 2088 ctx->check_crl = store->check_crl;
@@ -1442,6 +2094,16 @@ int X509_STORE_CTX_init(X509_STORE_CTX *ctx, X509_STORE *store, X509 *x509,
1442 else 2094 else
1443 ctx->cert_crl = cert_crl; 2095 ctx->cert_crl = cert_crl;
1444 2096
2097 if (store && store->lookup_certs)
2098 ctx->lookup_certs = store->lookup_certs;
2099 else
2100 ctx->lookup_certs = X509_STORE_get1_certs;
2101
2102 if (store && store->lookup_crls)
2103 ctx->lookup_crls = store->lookup_crls;
2104 else
2105 ctx->lookup_crls = X509_STORE_get1_crls;
2106
1445 ctx->check_policy = check_policy; 2107 ctx->check_policy = check_policy;
1446 2108
1447 2109
@@ -1474,7 +2136,8 @@ void X509_STORE_CTX_cleanup(X509_STORE_CTX *ctx)
1474 if (ctx->cleanup) ctx->cleanup(ctx); 2136 if (ctx->cleanup) ctx->cleanup(ctx);
1475 if (ctx->param != NULL) 2137 if (ctx->param != NULL)
1476 { 2138 {
1477 X509_VERIFY_PARAM_free(ctx->param); 2139 if (ctx->parent == NULL)
2140 X509_VERIFY_PARAM_free(ctx->param);
1478 ctx->param=NULL; 2141 ctx->param=NULL;
1479 } 2142 }
1480 if (ctx->tree != NULL) 2143 if (ctx->tree != NULL)
diff --git a/src/lib/libcrypto/x509/x509_vfy.h b/src/lib/libcrypto/x509/x509_vfy.h
index 76c76e1719..fe09b30aaa 100644
--- a/src/lib/libcrypto/x509/x509_vfy.h
+++ b/src/lib/libcrypto/x509/x509_vfy.h
@@ -77,6 +77,7 @@
77extern "C" { 77extern "C" {
78#endif 78#endif
79 79
80#if 0
80/* Outer object */ 81/* Outer object */
81typedef struct x509_hash_dir_st 82typedef struct x509_hash_dir_st
82 { 83 {
@@ -85,6 +86,7 @@ typedef struct x509_hash_dir_st
85 int *dirs_type; 86 int *dirs_type;
86 int num_dirs_alloced; 87 int num_dirs_alloced;
87 } X509_HASH_DIR_CTX; 88 } X509_HASH_DIR_CTX;
89#endif
88 90
89typedef struct x509_file_st 91typedef struct x509_file_st
90 { 92 {
@@ -198,6 +200,8 @@ struct x509_store_st
198 int (*get_crl)(X509_STORE_CTX *ctx, X509_CRL **crl, X509 *x); /* retrieve CRL */ 200 int (*get_crl)(X509_STORE_CTX *ctx, X509_CRL **crl, X509 *x); /* retrieve CRL */
199 int (*check_crl)(X509_STORE_CTX *ctx, X509_CRL *crl); /* Check CRL validity */ 201 int (*check_crl)(X509_STORE_CTX *ctx, X509_CRL *crl); /* Check CRL validity */
200 int (*cert_crl)(X509_STORE_CTX *ctx, X509_CRL *crl, X509 *x); /* Check certificate against CRL */ 202 int (*cert_crl)(X509_STORE_CTX *ctx, X509_CRL *crl, X509 *x); /* Check certificate against CRL */
203 STACK_OF(X509) * (*lookup_certs)(X509_STORE_CTX *ctx, X509_NAME *nm);
204 STACK_OF(X509_CRL) * (*lookup_crls)(X509_STORE_CTX *ctx, X509_NAME *nm);
201 int (*cleanup)(X509_STORE_CTX *ctx); 205 int (*cleanup)(X509_STORE_CTX *ctx);
202 206
203 CRYPTO_EX_DATA ex_data; 207 CRYPTO_EX_DATA ex_data;
@@ -246,6 +250,8 @@ struct x509_store_ctx_st /* X509_STORE_CTX */
246 int (*check_crl)(X509_STORE_CTX *ctx, X509_CRL *crl); /* Check CRL validity */ 250 int (*check_crl)(X509_STORE_CTX *ctx, X509_CRL *crl); /* Check CRL validity */
247 int (*cert_crl)(X509_STORE_CTX *ctx, X509_CRL *crl, X509 *x); /* Check certificate against CRL */ 251 int (*cert_crl)(X509_STORE_CTX *ctx, X509_CRL *crl, X509 *x); /* Check certificate against CRL */
248 int (*check_policy)(X509_STORE_CTX *ctx); 252 int (*check_policy)(X509_STORE_CTX *ctx);
253 STACK_OF(X509) * (*lookup_certs)(X509_STORE_CTX *ctx, X509_NAME *nm);
254 STACK_OF(X509_CRL) * (*lookup_crls)(X509_STORE_CTX *ctx, X509_NAME *nm);
249 int (*cleanup)(X509_STORE_CTX *ctx); 255 int (*cleanup)(X509_STORE_CTX *ctx);
250 256
251 /* The following is built up */ 257 /* The following is built up */
@@ -263,6 +269,11 @@ struct x509_store_ctx_st /* X509_STORE_CTX */
263 X509 *current_issuer; /* cert currently being tested as valid issuer */ 269 X509 *current_issuer; /* cert currently being tested as valid issuer */
264 X509_CRL *current_crl; /* current CRL */ 270 X509_CRL *current_crl; /* current CRL */
265 271
272 int current_crl_score; /* score of current CRL */
273 unsigned int current_reasons; /* Reason mask */
274
275 X509_STORE_CTX *parent; /* For CRL path validation: parent context */
276
266 CRYPTO_EX_DATA ex_data; 277 CRYPTO_EX_DATA ex_data;
267 } /* X509_STORE_CTX */; 278 } /* X509_STORE_CTX */;
268 279
@@ -330,8 +341,18 @@ void X509_STORE_CTX_set_depth(X509_STORE_CTX *ctx, int depth);
330#define X509_V_ERR_INVALID_EXTENSION 41 341#define X509_V_ERR_INVALID_EXTENSION 41
331#define X509_V_ERR_INVALID_POLICY_EXTENSION 42 342#define X509_V_ERR_INVALID_POLICY_EXTENSION 42
332#define X509_V_ERR_NO_EXPLICIT_POLICY 43 343#define X509_V_ERR_NO_EXPLICIT_POLICY 43
344#define X509_V_ERR_DIFFERENT_CRL_SCOPE 44
345#define X509_V_ERR_UNSUPPORTED_EXTENSION_FEATURE 45
346
347#define X509_V_ERR_UNNESTED_RESOURCE 46
333 348
334#define X509_V_ERR_UNNESTED_RESOURCE 44 349#define X509_V_ERR_PERMITTED_VIOLATION 47
350#define X509_V_ERR_EXCLUDED_VIOLATION 48
351#define X509_V_ERR_SUBTREE_MINMAX 49
352#define X509_V_ERR_UNSUPPORTED_CONSTRAINT_TYPE 51
353#define X509_V_ERR_UNSUPPORTED_CONSTRAINT_SYNTAX 52
354#define X509_V_ERR_UNSUPPORTED_NAME_SYNTAX 53
355#define X509_V_ERR_CRL_PATH_VALIDATION_ERROR 54
335 356
336/* The application is not happy */ 357/* The application is not happy */
337#define X509_V_ERR_APPLICATION_VERIFICATION 50 358#define X509_V_ERR_APPLICATION_VERIFICATION 50
@@ -362,6 +383,13 @@ void X509_STORE_CTX_set_depth(X509_STORE_CTX *ctx, int depth);
362#define X509_V_FLAG_INHIBIT_MAP 0x400 383#define X509_V_FLAG_INHIBIT_MAP 0x400
363/* Notify callback that policy is OK */ 384/* Notify callback that policy is OK */
364#define X509_V_FLAG_NOTIFY_POLICY 0x800 385#define X509_V_FLAG_NOTIFY_POLICY 0x800
386/* Extended CRL features such as indirect CRLs, alternate CRL signing keys */
387#define X509_V_FLAG_EXTENDED_CRL_SUPPORT 0x1000
388/* Delta CRL support */
389#define X509_V_FLAG_USE_DELTAS 0x2000
390/* Check selfsigned CA signature */
391#define X509_V_FLAG_CHECK_SS_SIGNATURE 0x4000
392
365 393
366#define X509_VP_FLAG_DEFAULT 0x1 394#define X509_VP_FLAG_DEFAULT 0x1
367#define X509_VP_FLAG_OVERWRITE 0x2 395#define X509_VP_FLAG_OVERWRITE 0x2
@@ -384,11 +412,16 @@ void X509_OBJECT_free_contents(X509_OBJECT *a);
384X509_STORE *X509_STORE_new(void ); 412X509_STORE *X509_STORE_new(void );
385void X509_STORE_free(X509_STORE *v); 413void X509_STORE_free(X509_STORE *v);
386 414
415STACK_OF(X509)* X509_STORE_get1_certs(X509_STORE_CTX *st, X509_NAME *nm);
416STACK_OF(X509_CRL)* X509_STORE_get1_crls(X509_STORE_CTX *st, X509_NAME *nm);
387int X509_STORE_set_flags(X509_STORE *ctx, unsigned long flags); 417int X509_STORE_set_flags(X509_STORE *ctx, unsigned long flags);
388int X509_STORE_set_purpose(X509_STORE *ctx, int purpose); 418int X509_STORE_set_purpose(X509_STORE *ctx, int purpose);
389int X509_STORE_set_trust(X509_STORE *ctx, int trust); 419int X509_STORE_set_trust(X509_STORE *ctx, int trust);
390int X509_STORE_set1_param(X509_STORE *ctx, X509_VERIFY_PARAM *pm); 420int X509_STORE_set1_param(X509_STORE *ctx, X509_VERIFY_PARAM *pm);
391 421
422void X509_STORE_set_verify_cb(X509_STORE *ctx,
423 int (*verify_cb)(int, X509_STORE_CTX *));
424
392X509_STORE_CTX *X509_STORE_CTX_new(void); 425X509_STORE_CTX *X509_STORE_CTX_new(void);
393 426
394int X509_STORE_CTX_get1_issuer(X509 **issuer, X509_STORE_CTX *ctx, X509 *x); 427int X509_STORE_CTX_get1_issuer(X509 **issuer, X509_STORE_CTX *ctx, X509 *x);
@@ -447,6 +480,9 @@ int X509_STORE_CTX_get_error(X509_STORE_CTX *ctx);
447void X509_STORE_CTX_set_error(X509_STORE_CTX *ctx,int s); 480void X509_STORE_CTX_set_error(X509_STORE_CTX *ctx,int s);
448int X509_STORE_CTX_get_error_depth(X509_STORE_CTX *ctx); 481int X509_STORE_CTX_get_error_depth(X509_STORE_CTX *ctx);
449X509 * X509_STORE_CTX_get_current_cert(X509_STORE_CTX *ctx); 482X509 * X509_STORE_CTX_get_current_cert(X509_STORE_CTX *ctx);
483X509 *X509_STORE_CTX_get0_current_issuer(X509_STORE_CTX *ctx);
484X509_CRL *X509_STORE_CTX_get0_current_crl(X509_STORE_CTX *ctx);
485X509_STORE_CTX *X509_STORE_CTX_get0_parent_ctx(X509_STORE_CTX *ctx);
450STACK_OF(X509) *X509_STORE_CTX_get_chain(X509_STORE_CTX *ctx); 486STACK_OF(X509) *X509_STORE_CTX_get_chain(X509_STORE_CTX *ctx);
451STACK_OF(X509) *X509_STORE_CTX_get1_chain(X509_STORE_CTX *ctx); 487STACK_OF(X509) *X509_STORE_CTX_get1_chain(X509_STORE_CTX *ctx);
452void X509_STORE_CTX_set_cert(X509_STORE_CTX *c,X509 *x); 488void X509_STORE_CTX_set_cert(X509_STORE_CTX *c,X509 *x);
diff --git a/src/lib/libcrypto/x509/x509_vpm.c b/src/lib/libcrypto/x509/x509_vpm.c
index 2b06718aec..dfd89d89fa 100644
--- a/src/lib/libcrypto/x509/x509_vpm.c
+++ b/src/lib/libcrypto/x509/x509_vpm.c
@@ -74,6 +74,7 @@ static void x509_verify_param_zero(X509_VERIFY_PARAM *param)
74 param->name = NULL; 74 param->name = NULL;
75 param->purpose = 0; 75 param->purpose = 0;
76 param->trust = 0; 76 param->trust = 0;
77 /*param->inh_flags = X509_VP_FLAG_DEFAULT;*/
77 param->inh_flags = 0; 78 param->inh_flags = 0;
78 param->flags = 0; 79 param->flags = 0;
79 param->depth = -1; 80 param->depth = -1;
@@ -198,8 +199,12 @@ int X509_VERIFY_PARAM_inherit(X509_VERIFY_PARAM *dest,
198int X509_VERIFY_PARAM_set1(X509_VERIFY_PARAM *to, 199int X509_VERIFY_PARAM_set1(X509_VERIFY_PARAM *to,
199 const X509_VERIFY_PARAM *from) 200 const X509_VERIFY_PARAM *from)
200 { 201 {
202 unsigned long save_flags = to->inh_flags;
203 int ret;
201 to->inh_flags |= X509_VP_FLAG_DEFAULT; 204 to->inh_flags |= X509_VP_FLAG_DEFAULT;
202 return X509_VERIFY_PARAM_inherit(to, from); 205 ret = X509_VERIFY_PARAM_inherit(to, from);
206 to->inh_flags = save_flags;
207 return ret;
203 } 208 }
204 209
205int X509_VERIFY_PARAM_set1_name(X509_VERIFY_PARAM *param, const char *name) 210int X509_VERIFY_PARAM_set1_name(X509_VERIFY_PARAM *param, const char *name)
@@ -324,7 +329,7 @@ static const X509_VERIFY_PARAM default_table[] = {
324 NULL /* policies */ 329 NULL /* policies */
325 }, 330 },
326 { 331 {
327 "pkcs7", /* S/MIME signing parameters */ 332 "pkcs7", /* S/MIME sign parameters */
328 0, /* Check time */ 333 0, /* Check time */
329 0, /* internal flags */ 334 0, /* internal flags */
330 0, /* flags */ 335 0, /* flags */
@@ -334,7 +339,7 @@ static const X509_VERIFY_PARAM default_table[] = {
334 NULL /* policies */ 339 NULL /* policies */
335 }, 340 },
336 { 341 {
337 "smime_sign", /* S/MIME signing parameters */ 342 "smime_sign", /* S/MIME sign parameters */
338 0, /* Check time */ 343 0, /* Check time */
339 0, /* internal flags */ 344 0, /* internal flags */
340 0, /* flags */ 345 0, /* flags */
@@ -366,12 +371,17 @@ static const X509_VERIFY_PARAM default_table[] = {
366 371
367static STACK_OF(X509_VERIFY_PARAM) *param_table = NULL; 372static STACK_OF(X509_VERIFY_PARAM) *param_table = NULL;
368 373
369static int table_cmp(const void *pa, const void *pb) 374static int table_cmp(const X509_VERIFY_PARAM *a, const X509_VERIFY_PARAM *b)
375
370 { 376 {
371 const X509_VERIFY_PARAM *a = pa, *b = pb;
372 return strcmp(a->name, b->name); 377 return strcmp(a->name, b->name);
373 } 378 }
374 379
380DECLARE_OBJ_BSEARCH_CMP_FN(X509_VERIFY_PARAM, X509_VERIFY_PARAM,
381 table);
382IMPLEMENT_OBJ_BSEARCH_CMP_FN(X509_VERIFY_PARAM, X509_VERIFY_PARAM,
383 table);
384
375static int param_cmp(const X509_VERIFY_PARAM * const *a, 385static int param_cmp(const X509_VERIFY_PARAM * const *a,
376 const X509_VERIFY_PARAM * const *b) 386 const X509_VERIFY_PARAM * const *b)
377 { 387 {
@@ -407,6 +417,7 @@ const X509_VERIFY_PARAM *X509_VERIFY_PARAM_lookup(const char *name)
407 { 417 {
408 int idx; 418 int idx;
409 X509_VERIFY_PARAM pm; 419 X509_VERIFY_PARAM pm;
420
410 pm.name = (char *)name; 421 pm.name = (char *)name;
411 if (param_table) 422 if (param_table)
412 { 423 {
@@ -414,11 +425,8 @@ const X509_VERIFY_PARAM *X509_VERIFY_PARAM_lookup(const char *name)
414 if (idx != -1) 425 if (idx != -1)
415 return sk_X509_VERIFY_PARAM_value(param_table, idx); 426 return sk_X509_VERIFY_PARAM_value(param_table, idx);
416 } 427 }
417 return (const X509_VERIFY_PARAM *) OBJ_bsearch((char *)&pm, 428 return OBJ_bsearch_table(&pm, default_table,
418 (char *)&default_table, 429 sizeof(default_table)/sizeof(X509_VERIFY_PARAM));
419 sizeof(default_table)/sizeof(X509_VERIFY_PARAM),
420 sizeof(X509_VERIFY_PARAM),
421 table_cmp);
422 } 430 }
423 431
424void X509_VERIFY_PARAM_table_cleanup(void) 432void X509_VERIFY_PARAM_table_cleanup(void)
diff --git a/src/lib/libcrypto/x509/x509cset.c b/src/lib/libcrypto/x509/x509cset.c
index 7f4004b291..3109defb0b 100644
--- a/src/lib/libcrypto/x509/x509cset.c
+++ b/src/lib/libcrypto/x509/x509cset.c
@@ -81,7 +81,7 @@ int X509_CRL_set_issuer_name(X509_CRL *x, X509_NAME *name)
81 } 81 }
82 82
83 83
84int X509_CRL_set_lastUpdate(X509_CRL *x, ASN1_TIME *tm) 84int X509_CRL_set_lastUpdate(X509_CRL *x, const ASN1_TIME *tm)
85 { 85 {
86 ASN1_TIME *in; 86 ASN1_TIME *in;
87 87
@@ -99,7 +99,7 @@ int X509_CRL_set_lastUpdate(X509_CRL *x, ASN1_TIME *tm)
99 return(in != NULL); 99 return(in != NULL);
100 } 100 }
101 101
102int X509_CRL_set_nextUpdate(X509_CRL *x, ASN1_TIME *tm) 102int X509_CRL_set_nextUpdate(X509_CRL *x, const ASN1_TIME *tm)
103 { 103 {
104 ASN1_TIME *in; 104 ASN1_TIME *in;
105 105
diff --git a/src/lib/libcrypto/x509/x509name.c b/src/lib/libcrypto/x509/x509name.c
index 068abfe5f0..27bc4dc9a3 100644
--- a/src/lib/libcrypto/x509/x509name.c
+++ b/src/lib/libcrypto/x509/x509name.c
@@ -356,7 +356,7 @@ int X509_NAME_ENTRY_set_data(X509_NAME_ENTRY *ne, int type,
356 return ASN1_STRING_set_by_NID(&ne->value, bytes, 356 return ASN1_STRING_set_by_NID(&ne->value, bytes,
357 len, type, 357 len, type,
358 OBJ_obj2nid(ne->object)) ? 1 : 0; 358 OBJ_obj2nid(ne->object)) ? 1 : 0;
359 if (len < 0) len=strlen((char *)bytes); 359 if (len < 0) len=strlen((const char *)bytes);
360 i=ASN1_STRING_set(ne->value,bytes,len); 360 i=ASN1_STRING_set(ne->value,bytes,len);
361 if (!i) return(0); 361 if (!i) return(0);
362 if (type != V_ASN1_UNDEF) 362 if (type != V_ASN1_UNDEF)
diff --git a/src/lib/libcrypto/x509/x509type.c b/src/lib/libcrypto/x509/x509type.c
index 2cd994c5b0..3385ad3f67 100644
--- a/src/lib/libcrypto/x509/x509type.c
+++ b/src/lib/libcrypto/x509/x509type.c
@@ -91,6 +91,10 @@ int X509_certificate_type(X509 *x, EVP_PKEY *pkey)
91 break; 91 break;
92 case EVP_PKEY_DH: 92 case EVP_PKEY_DH:
93 ret=EVP_PK_DH|EVP_PKT_EXCH; 93 ret=EVP_PK_DH|EVP_PKT_EXCH;
94 break;
95 case NID_id_GostR3410_94:
96 case NID_id_GostR3410_2001:
97 ret=EVP_PKT_EXCH|EVP_PKT_SIGN;
94 break; 98 break;
95 default: 99 default:
96 break; 100 break;
diff --git a/src/lib/libcrypto/x509/x_all.c b/src/lib/libcrypto/x509/x_all.c
index 9039caad60..ebae30b701 100644
--- a/src/lib/libcrypto/x509/x_all.c
+++ b/src/lib/libcrypto/x509/x_all.c
@@ -57,7 +57,6 @@
57 */ 57 */
58 58
59#include <stdio.h> 59#include <stdio.h>
60#undef SSLEAY_MACROS
61#include <openssl/stack.h> 60#include <openssl/stack.h>
62#include "cryptlib.h" 61#include "cryptlib.h"
63#include <openssl/buffer.h> 62#include <openssl/buffer.h>
@@ -83,12 +82,6 @@ int X509_REQ_verify(X509_REQ *a, EVP_PKEY *r)
83 a->sig_alg,a->signature,a->req_info,r)); 82 a->sig_alg,a->signature,a->req_info,r));
84 } 83 }
85 84
86int X509_CRL_verify(X509_CRL *a, EVP_PKEY *r)
87 {
88 return(ASN1_item_verify(ASN1_ITEM_rptr(X509_CRL_INFO),
89 a->sig_alg, a->signature,a->crl,r));
90 }
91
92int NETSCAPE_SPKI_verify(NETSCAPE_SPKI *a, EVP_PKEY *r) 85int NETSCAPE_SPKI_verify(NETSCAPE_SPKI *a, EVP_PKEY *r)
93 { 86 {
94 return(ASN1_item_verify(ASN1_ITEM_rptr(NETSCAPE_SPKAC), 87 return(ASN1_item_verify(ASN1_ITEM_rptr(NETSCAPE_SPKAC),
diff --git a/src/lib/libcrypto/x509v3/ext_dat.h b/src/lib/libcrypto/x509v3/ext_dat.h
index 3eaec46f8a..76daee6fcd 100644
--- a/src/lib/libcrypto/x509v3/ext_dat.h
+++ b/src/lib/libcrypto/x509v3/ext_dat.h
@@ -61,21 +61,19 @@ extern X509V3_EXT_METHOD v3_bcons, v3_nscert, v3_key_usage, v3_ext_ku;
61extern X509V3_EXT_METHOD v3_pkey_usage_period, v3_sxnet, v3_info, v3_sinfo; 61extern X509V3_EXT_METHOD v3_pkey_usage_period, v3_sxnet, v3_info, v3_sinfo;
62extern X509V3_EXT_METHOD v3_ns_ia5_list[], v3_alt[], v3_skey_id, v3_akey_id; 62extern X509V3_EXT_METHOD v3_ns_ia5_list[], v3_alt[], v3_skey_id, v3_akey_id;
63extern X509V3_EXT_METHOD v3_crl_num, v3_crl_reason, v3_crl_invdate; 63extern X509V3_EXT_METHOD v3_crl_num, v3_crl_reason, v3_crl_invdate;
64extern X509V3_EXT_METHOD v3_delta_crl, v3_cpols, v3_crld; 64extern X509V3_EXT_METHOD v3_delta_crl, v3_cpols, v3_crld, v3_freshest_crl;
65extern X509V3_EXT_METHOD v3_ocsp_nonce, v3_ocsp_accresp, v3_ocsp_acutoff; 65extern X509V3_EXT_METHOD v3_ocsp_nonce, v3_ocsp_accresp, v3_ocsp_acutoff;
66extern X509V3_EXT_METHOD v3_ocsp_crlid, v3_ocsp_nocheck, v3_ocsp_serviceloc; 66extern X509V3_EXT_METHOD v3_ocsp_crlid, v3_ocsp_nocheck, v3_ocsp_serviceloc;
67extern X509V3_EXT_METHOD v3_crl_hold, v3_pci; 67extern X509V3_EXT_METHOD v3_crl_hold, v3_pci;
68extern X509V3_EXT_METHOD v3_policy_mappings, v3_policy_constraints; 68extern X509V3_EXT_METHOD v3_policy_mappings, v3_policy_constraints;
69extern X509V3_EXT_METHOD v3_name_constraints, v3_inhibit_anyp; 69extern X509V3_EXT_METHOD v3_name_constraints, v3_inhibit_anyp, v3_idp;
70#ifndef OPENSSL_NO_RFC3779
71extern X509V3_EXT_METHOD v3_addr, v3_asid; 70extern X509V3_EXT_METHOD v3_addr, v3_asid;
72#endif
73 71
74/* This table will be searched using OBJ_bsearch so it *must* kept in 72/* This table will be searched using OBJ_bsearch so it *must* kept in
75 * order of the ext_nid values. 73 * order of the ext_nid values.
76 */ 74 */
77 75
78static X509V3_EXT_METHOD *standard_exts[] = { 76static const X509V3_EXT_METHOD *standard_exts[] = {
79&v3_nscert, 77&v3_nscert,
80&v3_ns_ia5_list[0], 78&v3_ns_ia5_list[0],
81&v3_ns_ia5_list[1], 79&v3_ns_ia5_list[1],
@@ -122,7 +120,10 @@ static X509V3_EXT_METHOD *standard_exts[] = {
122&v3_pci, 120&v3_pci,
123&v3_name_constraints, 121&v3_name_constraints,
124&v3_policy_mappings, 122&v3_policy_mappings,
125&v3_inhibit_anyp 123&v3_inhibit_anyp,
124&v3_idp,
125&v3_alt[2],
126&v3_freshest_crl,
126}; 127};
127 128
128/* Number of standard extensions */ 129/* Number of standard extensions */
diff --git a/src/lib/libcrypto/x509v3/pcy_cache.c b/src/lib/libcrypto/x509v3/pcy_cache.c
index 1030931b71..172b7e7ee4 100644
--- a/src/lib/libcrypto/x509v3/pcy_cache.c
+++ b/src/lib/libcrypto/x509v3/pcy_cache.c
@@ -139,7 +139,6 @@ static int policy_cache_new(X509 *x)
139 return 0; 139 return 0;
140 cache->anyPolicy = NULL; 140 cache->anyPolicy = NULL;
141 cache->data = NULL; 141 cache->data = NULL;
142 cache->maps = NULL;
143 cache->any_skip = -1; 142 cache->any_skip = -1;
144 cache->explicit_skip = -1; 143 cache->explicit_skip = -1;
145 cache->map_skip = -1; 144 cache->map_skip = -1;
diff --git a/src/lib/libcrypto/x509v3/pcy_data.c b/src/lib/libcrypto/x509v3/pcy_data.c
index fb392b901f..3444b03195 100644
--- a/src/lib/libcrypto/x509v3/pcy_data.c
+++ b/src/lib/libcrypto/x509v3/pcy_data.c
@@ -82,17 +82,21 @@ void policy_data_free(X509_POLICY_DATA *data)
82 * another source. 82 * another source.
83 */ 83 */
84 84
85X509_POLICY_DATA *policy_data_new(POLICYINFO *policy, ASN1_OBJECT *id, int crit) 85X509_POLICY_DATA *policy_data_new(POLICYINFO *policy,
86 const ASN1_OBJECT *cid, int crit)
86 { 87 {
87 X509_POLICY_DATA *ret; 88 X509_POLICY_DATA *ret;
88 if (!policy && !id) 89 ASN1_OBJECT *id;
90 if (!policy && !cid)
89 return NULL; 91 return NULL;
90 if (id) 92 if (cid)
91 { 93 {
92 id = OBJ_dup(id); 94 id = OBJ_dup(cid);
93 if (!id) 95 if (!id)
94 return NULL; 96 return NULL;
95 } 97 }
98 else
99 id = NULL;
96 ret = OPENSSL_malloc(sizeof(X509_POLICY_DATA)); 100 ret = OPENSSL_malloc(sizeof(X509_POLICY_DATA));
97 if (!ret) 101 if (!ret)
98 return NULL; 102 return NULL;
diff --git a/src/lib/libcrypto/x509v3/pcy_int.h b/src/lib/libcrypto/x509v3/pcy_int.h
index 3780de4fcd..ccff92846e 100644
--- a/src/lib/libcrypto/x509v3/pcy_int.h
+++ b/src/lib/libcrypto/x509v3/pcy_int.h
@@ -56,12 +56,10 @@
56 * 56 *
57 */ 57 */
58 58
59DECLARE_STACK_OF(X509_POLICY_DATA)
60DECLARE_STACK_OF(X509_POLICY_REF)
61DECLARE_STACK_OF(X509_POLICY_NODE)
62 59
63typedef struct X509_POLICY_DATA_st X509_POLICY_DATA; 60typedef struct X509_POLICY_DATA_st X509_POLICY_DATA;
64typedef struct X509_POLICY_REF_st X509_POLICY_REF; 61
62DECLARE_STACK_OF(X509_POLICY_DATA)
65 63
66/* Internal structures */ 64/* Internal structures */
67 65
@@ -110,16 +108,6 @@ struct X509_POLICY_DATA_st
110 108
111#define POLICY_DATA_FLAG_CRITICAL 0x10 109#define POLICY_DATA_FLAG_CRITICAL 0x10
112 110
113/* This structure is an entry from a table of mapped policies which
114 * cross reference the policy it refers to.
115 */
116
117struct X509_POLICY_REF_st
118 {
119 ASN1_OBJECT *subjectDomainPolicy;
120 const X509_POLICY_DATA *data;
121 };
122
123/* This structure is cached with a certificate */ 111/* This structure is cached with a certificate */
124 112
125struct X509_POLICY_CACHE_st { 113struct X509_POLICY_CACHE_st {
@@ -127,8 +115,6 @@ struct X509_POLICY_CACHE_st {
127 X509_POLICY_DATA *anyPolicy; 115 X509_POLICY_DATA *anyPolicy;
128 /* other policy data */ 116 /* other policy data */
129 STACK_OF(X509_POLICY_DATA) *data; 117 STACK_OF(X509_POLICY_DATA) *data;
130 /* If policyMappings extension present a table of mapped policies */
131 STACK_OF(X509_POLICY_REF) *maps;
132 /* If InhibitAnyPolicy present this is its value or -1 if absent. */ 118 /* If InhibitAnyPolicy present this is its value or -1 if absent. */
133 long any_skip; 119 long any_skip;
134 /* If policyConstraints and requireExplicitPolicy present this is its 120 /* If policyConstraints and requireExplicitPolicy present this is its
@@ -193,7 +179,7 @@ struct X509_POLICY_TREE_st
193 179
194/* Internal functions */ 180/* Internal functions */
195 181
196X509_POLICY_DATA *policy_data_new(POLICYINFO *policy, ASN1_OBJECT *id, 182X509_POLICY_DATA *policy_data_new(POLICYINFO *policy, const ASN1_OBJECT *id,
197 int crit); 183 int crit);
198void policy_data_free(X509_POLICY_DATA *data); 184void policy_data_free(X509_POLICY_DATA *data);
199 185
@@ -209,15 +195,18 @@ void policy_cache_init(void);
209void policy_cache_free(X509_POLICY_CACHE *cache); 195void policy_cache_free(X509_POLICY_CACHE *cache);
210 196
211X509_POLICY_NODE *level_find_node(const X509_POLICY_LEVEL *level, 197X509_POLICY_NODE *level_find_node(const X509_POLICY_LEVEL *level,
198 const X509_POLICY_NODE *parent,
212 const ASN1_OBJECT *id); 199 const ASN1_OBJECT *id);
213 200
214X509_POLICY_NODE *tree_find_sk(STACK_OF(X509_POLICY_NODE) *sk, 201X509_POLICY_NODE *tree_find_sk(STACK_OF(X509_POLICY_NODE) *sk,
215 const ASN1_OBJECT *id); 202 const ASN1_OBJECT *id);
216 203
217X509_POLICY_NODE *level_add_node(X509_POLICY_LEVEL *level, 204X509_POLICY_NODE *level_add_node(X509_POLICY_LEVEL *level,
218 X509_POLICY_DATA *data, 205 const X509_POLICY_DATA *data,
219 X509_POLICY_NODE *parent, 206 X509_POLICY_NODE *parent,
220 X509_POLICY_TREE *tree); 207 X509_POLICY_TREE *tree);
221void policy_node_free(X509_POLICY_NODE *node); 208void policy_node_free(X509_POLICY_NODE *node);
209int policy_node_match(const X509_POLICY_LEVEL *lvl,
210 const X509_POLICY_NODE *node, const ASN1_OBJECT *oid);
222 211
223const X509_POLICY_CACHE *policy_cache_set(X509 *x); 212const X509_POLICY_CACHE *policy_cache_set(X509 *x);
diff --git a/src/lib/libcrypto/x509v3/pcy_map.c b/src/lib/libcrypto/x509v3/pcy_map.c
index f28796e6d4..21163b529d 100644
--- a/src/lib/libcrypto/x509v3/pcy_map.c
+++ b/src/lib/libcrypto/x509v3/pcy_map.c
@@ -62,31 +62,6 @@
62 62
63#include "pcy_int.h" 63#include "pcy_int.h"
64 64
65static int ref_cmp(const X509_POLICY_REF * const *a,
66 const X509_POLICY_REF * const *b)
67 {
68 return OBJ_cmp((*a)->subjectDomainPolicy, (*b)->subjectDomainPolicy);
69 }
70
71static void policy_map_free(X509_POLICY_REF *map)
72 {
73 if (map->subjectDomainPolicy)
74 ASN1_OBJECT_free(map->subjectDomainPolicy);
75 OPENSSL_free(map);
76 }
77
78static X509_POLICY_REF *policy_map_find(X509_POLICY_CACHE *cache, ASN1_OBJECT *id)
79 {
80 X509_POLICY_REF tmp;
81 int idx;
82 tmp.subjectDomainPolicy = id;
83
84 idx = sk_X509_POLICY_REF_find(cache->maps, &tmp);
85 if (idx == -1)
86 return NULL;
87 return sk_X509_POLICY_REF_value(cache->maps, idx);
88 }
89
90/* Set policy mapping entries in cache. 65/* Set policy mapping entries in cache.
91 * Note: this modifies the passed POLICY_MAPPINGS structure 66 * Note: this modifies the passed POLICY_MAPPINGS structure
92 */ 67 */
@@ -94,7 +69,6 @@ static X509_POLICY_REF *policy_map_find(X509_POLICY_CACHE *cache, ASN1_OBJECT *i
94int policy_cache_set_mapping(X509 *x, POLICY_MAPPINGS *maps) 69int policy_cache_set_mapping(X509 *x, POLICY_MAPPINGS *maps)
95 { 70 {
96 POLICY_MAPPING *map; 71 POLICY_MAPPING *map;
97 X509_POLICY_REF *ref = NULL;
98 X509_POLICY_DATA *data; 72 X509_POLICY_DATA *data;
99 X509_POLICY_CACHE *cache = x->policy_cache; 73 X509_POLICY_CACHE *cache = x->policy_cache;
100 int i; 74 int i;
@@ -104,7 +78,6 @@ int policy_cache_set_mapping(X509 *x, POLICY_MAPPINGS *maps)
104 ret = -1; 78 ret = -1;
105 goto bad_mapping; 79 goto bad_mapping;
106 } 80 }
107 cache->maps = sk_X509_POLICY_REF_new(ref_cmp);
108 for (i = 0; i < sk_POLICY_MAPPING_num(maps); i++) 81 for (i = 0; i < sk_POLICY_MAPPING_num(maps); i++)
109 { 82 {
110 map = sk_POLICY_MAPPING_value(maps, i); 83 map = sk_POLICY_MAPPING_value(maps, i);
@@ -116,13 +89,6 @@ int policy_cache_set_mapping(X509 *x, POLICY_MAPPINGS *maps)
116 goto bad_mapping; 89 goto bad_mapping;
117 } 90 }
118 91
119 /* If we've already mapped from this OID bad mapping */
120 if (policy_map_find(cache, map->subjectDomainPolicy) != NULL)
121 {
122 ret = -1;
123 goto bad_mapping;
124 }
125
126 /* Attempt to find matching policy data */ 92 /* Attempt to find matching policy data */
127 data = policy_cache_find_data(cache, map->issuerDomainPolicy); 93 data = policy_cache_find_data(cache, map->issuerDomainPolicy);
128 /* If we don't have anyPolicy can't map */ 94 /* If we don't have anyPolicy can't map */
@@ -138,7 +104,7 @@ int policy_cache_set_mapping(X509 *x, POLICY_MAPPINGS *maps)
138 if (!data) 104 if (!data)
139 goto bad_mapping; 105 goto bad_mapping;
140 data->qualifier_set = cache->anyPolicy->qualifier_set; 106 data->qualifier_set = cache->anyPolicy->qualifier_set;
141 map->issuerDomainPolicy = NULL; 107 /*map->issuerDomainPolicy = NULL;*/
142 data->flags |= POLICY_DATA_FLAG_MAPPED_ANY; 108 data->flags |= POLICY_DATA_FLAG_MAPPED_ANY;
143 data->flags |= POLICY_DATA_FLAG_SHARED_QUALIFIERS; 109 data->flags |= POLICY_DATA_FLAG_SHARED_QUALIFIERS;
144 if (!sk_X509_POLICY_DATA_push(cache->data, data)) 110 if (!sk_X509_POLICY_DATA_push(cache->data, data))
@@ -149,23 +115,10 @@ int policy_cache_set_mapping(X509 *x, POLICY_MAPPINGS *maps)
149 } 115 }
150 else 116 else
151 data->flags |= POLICY_DATA_FLAG_MAPPED; 117 data->flags |= POLICY_DATA_FLAG_MAPPED;
152
153 if (!sk_ASN1_OBJECT_push(data->expected_policy_set, 118 if (!sk_ASN1_OBJECT_push(data->expected_policy_set,
154 map->subjectDomainPolicy)) 119 map->subjectDomainPolicy))
155 goto bad_mapping; 120 goto bad_mapping;
156
157 ref = OPENSSL_malloc(sizeof(X509_POLICY_REF));
158 if (!ref)
159 goto bad_mapping;
160
161 ref->subjectDomainPolicy = map->subjectDomainPolicy;
162 map->subjectDomainPolicy = NULL; 121 map->subjectDomainPolicy = NULL;
163 ref->data = data;
164
165 if (!sk_X509_POLICY_REF_push(cache->maps, ref))
166 goto bad_mapping;
167
168 ref = NULL;
169 122
170 } 123 }
171 124
@@ -173,13 +126,6 @@ int policy_cache_set_mapping(X509 *x, POLICY_MAPPINGS *maps)
173 bad_mapping: 126 bad_mapping:
174 if (ret == -1) 127 if (ret == -1)
175 x->ex_flags |= EXFLAG_INVALID_POLICY; 128 x->ex_flags |= EXFLAG_INVALID_POLICY;
176 if (ref)
177 policy_map_free(ref);
178 if (ret <= 0)
179 {
180 sk_X509_POLICY_REF_pop_free(cache->maps, policy_map_free);
181 cache->maps = NULL;
182 }
183 sk_POLICY_MAPPING_pop_free(maps, POLICY_MAPPING_free); 129 sk_POLICY_MAPPING_pop_free(maps, POLICY_MAPPING_free);
184 return ret; 130 return ret;
185 131
diff --git a/src/lib/libcrypto/x509v3/pcy_node.c b/src/lib/libcrypto/x509v3/pcy_node.c
index 6587cb05ab..bd1e7f1ae8 100644
--- a/src/lib/libcrypto/x509v3/pcy_node.c
+++ b/src/lib/libcrypto/x509v3/pcy_node.c
@@ -92,13 +92,25 @@ X509_POLICY_NODE *tree_find_sk(STACK_OF(X509_POLICY_NODE) *nodes,
92 } 92 }
93 93
94X509_POLICY_NODE *level_find_node(const X509_POLICY_LEVEL *level, 94X509_POLICY_NODE *level_find_node(const X509_POLICY_LEVEL *level,
95 const X509_POLICY_NODE *parent,
95 const ASN1_OBJECT *id) 96 const ASN1_OBJECT *id)
96 { 97 {
97 return tree_find_sk(level->nodes, id); 98 X509_POLICY_NODE *node;
99 int i;
100 for (i = 0; i < sk_X509_POLICY_NODE_num(level->nodes); i++)
101 {
102 node = sk_X509_POLICY_NODE_value(level->nodes, i);
103 if (node->parent == parent)
104 {
105 if (!OBJ_cmp(node->data->valid_policy, id))
106 return node;
107 }
108 }
109 return NULL;
98 } 110 }
99 111
100X509_POLICY_NODE *level_add_node(X509_POLICY_LEVEL *level, 112X509_POLICY_NODE *level_add_node(X509_POLICY_LEVEL *level,
101 X509_POLICY_DATA *data, 113 const X509_POLICY_DATA *data,
102 X509_POLICY_NODE *parent, 114 X509_POLICY_NODE *parent,
103 X509_POLICY_TREE *tree) 115 X509_POLICY_TREE *tree)
104 { 116 {
@@ -155,4 +167,31 @@ void policy_node_free(X509_POLICY_NODE *node)
155 OPENSSL_free(node); 167 OPENSSL_free(node);
156 } 168 }
157 169
170/* See if a policy node matches a policy OID. If mapping enabled look through
171 * expected policy set otherwise just valid policy.
172 */
173
174int policy_node_match(const X509_POLICY_LEVEL *lvl,
175 const X509_POLICY_NODE *node, const ASN1_OBJECT *oid)
176 {
177 int i;
178 ASN1_OBJECT *policy_oid;
179 const X509_POLICY_DATA *x = node->data;
180
181 if ( (lvl->flags & X509_V_FLAG_INHIBIT_MAP)
182 || !(x->flags & POLICY_DATA_FLAG_MAP_MASK))
183 {
184 if (!OBJ_cmp(x->valid_policy, oid))
185 return 1;
186 return 0;
187 }
188
189 for (i = 0; i < sk_ASN1_OBJECT_num(x->expected_policy_set); i++)
190 {
191 policy_oid = sk_ASN1_OBJECT_value(x->expected_policy_set, i);
192 if (!OBJ_cmp(policy_oid, oid))
193 return 1;
194 }
195 return 0;
158 196
197 }
diff --git a/src/lib/libcrypto/x509v3/pcy_tree.c b/src/lib/libcrypto/x509v3/pcy_tree.c
index 6c87a7f506..92f6b24556 100644
--- a/src/lib/libcrypto/x509v3/pcy_tree.c
+++ b/src/lib/libcrypto/x509v3/pcy_tree.c
@@ -62,6 +62,75 @@
62 62
63#include "pcy_int.h" 63#include "pcy_int.h"
64 64
65/* Enable this to print out the complete policy tree at various point during
66 * evaluation.
67 */
68
69/*#define OPENSSL_POLICY_DEBUG*/
70
71#ifdef OPENSSL_POLICY_DEBUG
72
73static void expected_print(BIO *err, X509_POLICY_LEVEL *lev,
74 X509_POLICY_NODE *node, int indent)
75 {
76 if ( (lev->flags & X509_V_FLAG_INHIBIT_MAP)
77 || !(node->data->flags & POLICY_DATA_FLAG_MAP_MASK))
78 BIO_puts(err, " Not Mapped\n");
79 else
80 {
81 int i;
82 STACK_OF(ASN1_OBJECT) *pset = node->data->expected_policy_set;
83 ASN1_OBJECT *oid;
84 BIO_puts(err, " Expected: ");
85 for (i = 0; i < sk_ASN1_OBJECT_num(pset); i++)
86 {
87 oid = sk_ASN1_OBJECT_value(pset, i);
88 if (i)
89 BIO_puts(err, ", ");
90 i2a_ASN1_OBJECT(err, oid);
91 }
92 BIO_puts(err, "\n");
93 }
94 }
95
96static void tree_print(char *str, X509_POLICY_TREE *tree,
97 X509_POLICY_LEVEL *curr)
98 {
99 X509_POLICY_LEVEL *plev;
100 X509_POLICY_NODE *node;
101 int i;
102 BIO *err;
103 err = BIO_new_fp(stderr, BIO_NOCLOSE);
104 if (!curr)
105 curr = tree->levels + tree->nlevel;
106 else
107 curr++;
108 BIO_printf(err, "Level print after %s\n", str);
109 BIO_printf(err, "Printing Up to Level %ld\n", curr - tree->levels);
110 for (plev = tree->levels; plev != curr; plev++)
111 {
112 BIO_printf(err, "Level %ld, flags = %x\n",
113 plev - tree->levels, plev->flags);
114 for (i = 0; i < sk_X509_POLICY_NODE_num(plev->nodes); i++)
115 {
116 node = sk_X509_POLICY_NODE_value(plev->nodes, i);
117 X509_POLICY_NODE_print(err, node, 2);
118 expected_print(err, plev, node, 2);
119 BIO_printf(err, " Flags: %x\n", node->data->flags);
120 }
121 if (plev->anyPolicy)
122 X509_POLICY_NODE_print(err, plev->anyPolicy, 2);
123 }
124
125 BIO_free(err);
126
127 }
128#else
129
130#define tree_print(a,b,c) /* */
131
132#endif
133
65/* Initialize policy tree. Return values: 134/* Initialize policy tree. Return values:
66 * 0 Some internal error occured. 135 * 0 Some internal error occured.
67 * -1 Inconsistent or invalid extensions in certificates. 136 * -1 Inconsistent or invalid extensions in certificates.
@@ -87,8 +156,10 @@ static int tree_init(X509_POLICY_TREE **ptree, STACK_OF(X509) *certs,
87 *ptree = NULL; 156 *ptree = NULL;
88 n = sk_X509_num(certs); 157 n = sk_X509_num(certs);
89 158
159#if 0
90 /* Disable policy mapping for now... */ 160 /* Disable policy mapping for now... */
91 flags |= X509_V_FLAG_INHIBIT_MAP; 161 flags |= X509_V_FLAG_INHIBIT_MAP;
162#endif
92 163
93 if (flags & X509_V_FLAG_EXPLICIT_POLICY) 164 if (flags & X509_V_FLAG_EXPLICIT_POLICY)
94 explicit_policy = 0; 165 explicit_policy = 0;
@@ -160,7 +231,7 @@ static int tree_init(X509_POLICY_TREE **ptree, STACK_OF(X509) *certs,
160 tree->auth_policies = NULL; 231 tree->auth_policies = NULL;
161 tree->user_policies = NULL; 232 tree->user_policies = NULL;
162 233
163 if (!tree) 234 if (!tree->levels)
164 { 235 {
165 OPENSSL_free(tree); 236 OPENSSL_free(tree);
166 return 0; 237 return 0;
@@ -184,7 +255,6 @@ static int tree_init(X509_POLICY_TREE **ptree, STACK_OF(X509) *certs,
184 level++; 255 level++;
185 x = sk_X509_value(certs, i); 256 x = sk_X509_value(certs, i);
186 cache = policy_cache_set(x); 257 cache = policy_cache_set(x);
187
188 CRYPTO_add(&x->references, 1, CRYPTO_LOCK_X509); 258 CRYPTO_add(&x->references, 1, CRYPTO_LOCK_X509);
189 level->cert = x; 259 level->cert = x;
190 260
@@ -213,13 +283,13 @@ static int tree_init(X509_POLICY_TREE **ptree, STACK_OF(X509) *certs,
213 level->flags |= X509_V_FLAG_INHIBIT_MAP; 283 level->flags |= X509_V_FLAG_INHIBIT_MAP;
214 else 284 else
215 { 285 {
216 map_skip--; 286 if (!(x->ex_flags & EXFLAG_SI))
287 map_skip--;
217 if ((cache->map_skip >= 0) 288 if ((cache->map_skip >= 0)
218 && (cache->map_skip < map_skip)) 289 && (cache->map_skip < map_skip))
219 map_skip = cache->map_skip; 290 map_skip = cache->map_skip;
220 } 291 }
221 292
222
223 } 293 }
224 294
225 *ptree = tree; 295 *ptree = tree;
@@ -237,7 +307,32 @@ static int tree_init(X509_POLICY_TREE **ptree, STACK_OF(X509) *certs,
237 307
238 } 308 }
239 309
240/* This corresponds to RFC3280 XXXX XXXXX: 310static int tree_link_matching_nodes(X509_POLICY_LEVEL *curr,
311 const X509_POLICY_DATA *data)
312 {
313 X509_POLICY_LEVEL *last = curr - 1;
314 X509_POLICY_NODE *node;
315 int i, matched = 0;
316 /* Iterate through all in nodes linking matches */
317 for (i = 0; i < sk_X509_POLICY_NODE_num(last->nodes); i++)
318 {
319 node = sk_X509_POLICY_NODE_value(last->nodes, i);
320 if (policy_node_match(last, node, data->valid_policy))
321 {
322 if (!level_add_node(curr, data, node, NULL))
323 return 0;
324 matched = 1;
325 }
326 }
327 if (!matched && last->anyPolicy)
328 {
329 if (!level_add_node(curr, data, last->anyPolicy, NULL))
330 return 0;
331 }
332 return 1;
333 }
334
335/* This corresponds to RFC3280 6.1.3(d)(1):
241 * link any data from CertificatePolicies onto matching parent 336 * link any data from CertificatePolicies onto matching parent
242 * or anyPolicy if no match. 337 * or anyPolicy if no match.
243 */ 338 */
@@ -248,7 +343,6 @@ static int tree_link_nodes(X509_POLICY_LEVEL *curr,
248 int i; 343 int i;
249 X509_POLICY_LEVEL *last; 344 X509_POLICY_LEVEL *last;
250 X509_POLICY_DATA *data; 345 X509_POLICY_DATA *data;
251 X509_POLICY_NODE *parent;
252 last = curr - 1; 346 last = curr - 1;
253 for (i = 0; i < sk_X509_POLICY_DATA_num(cache->data); i++) 347 for (i = 0; i < sk_X509_POLICY_DATA_num(cache->data); i++)
254 { 348 {
@@ -261,40 +355,109 @@ static int tree_link_nodes(X509_POLICY_LEVEL *curr,
261 * link because then it will have the mapping flags 355 * link because then it will have the mapping flags
262 * right and we can prune it later. 356 * right and we can prune it later.
263 */ 357 */
358#if 0
264 if ((data->flags & POLICY_DATA_FLAG_MAPPED_ANY) 359 if ((data->flags & POLICY_DATA_FLAG_MAPPED_ANY)
265 && !(curr->flags & X509_V_FLAG_INHIBIT_ANY)) 360 && !(curr->flags & X509_V_FLAG_INHIBIT_ANY))
266 continue; 361 continue;
267 /* Look for matching node in parent */ 362#endif
268 parent = level_find_node(last, data->valid_policy); 363 /* Look for matching nodes in previous level */
269 /* If no match link to anyPolicy */ 364 if (!tree_link_matching_nodes(curr, data))
270 if (!parent)
271 parent = last->anyPolicy;
272 if (parent && !level_add_node(curr, data, parent, NULL))
273 return 0; 365 return 0;
274 } 366 }
275 return 1; 367 return 1;
276 } 368 }
277 369
278/* This corresponds to RFC3280 XXXX XXXXX: 370/* This corresponds to RFC3280 6.1.3(d)(2):
279 * Create new data for any unmatched policies in the parent and link 371 * Create new data for any unmatched policies in the parent and link
280 * to anyPolicy. 372 * to anyPolicy.
281 */ 373 */
282 374
375static int tree_add_unmatched(X509_POLICY_LEVEL *curr,
376 const X509_POLICY_CACHE *cache,
377 const ASN1_OBJECT *id,
378 X509_POLICY_NODE *node,
379 X509_POLICY_TREE *tree)
380 {
381 X509_POLICY_DATA *data;
382 if (id == NULL)
383 id = node->data->valid_policy;
384 /* Create a new node with qualifiers from anyPolicy and
385 * id from unmatched node.
386 */
387 data = policy_data_new(NULL, id, node_critical(node));
388
389 if (data == NULL)
390 return 0;
391 /* Curr may not have anyPolicy */
392 data->qualifier_set = cache->anyPolicy->qualifier_set;
393 data->flags |= POLICY_DATA_FLAG_SHARED_QUALIFIERS;
394 if (!level_add_node(curr, data, node, tree))
395 {
396 policy_data_free(data);
397 return 0;
398 }
399
400 return 1;
401 }
402
403static int tree_link_unmatched(X509_POLICY_LEVEL *curr,
404 const X509_POLICY_CACHE *cache,
405 X509_POLICY_NODE *node,
406 X509_POLICY_TREE *tree)
407 {
408 const X509_POLICY_LEVEL *last = curr - 1;
409 int i;
410
411 if ( (last->flags & X509_V_FLAG_INHIBIT_MAP)
412 || !(node->data->flags & POLICY_DATA_FLAG_MAPPED))
413 {
414 /* If no policy mapping: matched if one child present */
415 if (node->nchild)
416 return 1;
417 if (!tree_add_unmatched(curr, cache, NULL, node, tree))
418 return 0;
419 /* Add it */
420 }
421 else
422 {
423 /* If mapping: matched if one child per expected policy set */
424 STACK_OF(ASN1_OBJECT) *expset = node->data->expected_policy_set;
425 if (node->nchild == sk_ASN1_OBJECT_num(expset))
426 return 1;
427 /* Locate unmatched nodes */
428 for (i = 0; i < sk_ASN1_OBJECT_num(expset); i++)
429 {
430 ASN1_OBJECT *oid = sk_ASN1_OBJECT_value(expset, i);
431 if (level_find_node(curr, node, oid))
432 continue;
433 if (!tree_add_unmatched(curr, cache, oid, node, tree))
434 return 0;
435 }
436
437 }
438
439 return 1;
440
441 }
442
283static int tree_link_any(X509_POLICY_LEVEL *curr, 443static int tree_link_any(X509_POLICY_LEVEL *curr,
284 const X509_POLICY_CACHE *cache, 444 const X509_POLICY_CACHE *cache,
285 X509_POLICY_TREE *tree) 445 X509_POLICY_TREE *tree)
286 { 446 {
287 int i; 447 int i;
288 X509_POLICY_DATA *data; 448 /*X509_POLICY_DATA *data;*/
289 X509_POLICY_NODE *node; 449 X509_POLICY_NODE *node;
290 X509_POLICY_LEVEL *last; 450 X509_POLICY_LEVEL *last = curr - 1;
291
292 last = curr - 1;
293 451
294 for (i = 0; i < sk_X509_POLICY_NODE_num(last->nodes); i++) 452 for (i = 0; i < sk_X509_POLICY_NODE_num(last->nodes); i++)
295 { 453 {
296 node = sk_X509_POLICY_NODE_value(last->nodes, i); 454 node = sk_X509_POLICY_NODE_value(last->nodes, i);
297 455
456 if (!tree_link_unmatched(curr, cache, node, tree))
457 return 0;
458
459#if 0
460
298 /* Skip any node with any children: we only want unmathced 461 /* Skip any node with any children: we only want unmathced
299 * nodes. 462 * nodes.
300 * 463 *
@@ -303,6 +466,7 @@ static int tree_link_any(X509_POLICY_LEVEL *curr,
303 */ 466 */
304 if (node->nchild) 467 if (node->nchild)
305 continue; 468 continue;
469
306 /* Create a new node with qualifiers from anyPolicy and 470 /* Create a new node with qualifiers from anyPolicy and
307 * id from unmatched node. 471 * id from unmatched node.
308 */ 472 */
@@ -319,6 +483,9 @@ static int tree_link_any(X509_POLICY_LEVEL *curr,
319 policy_data_free(data); 483 policy_data_free(data);
320 return 0; 484 return 0;
321 } 485 }
486
487#endif
488
322 } 489 }
323 /* Finally add link to anyPolicy */ 490 /* Finally add link to anyPolicy */
324 if (last->anyPolicy) 491 if (last->anyPolicy)
@@ -337,30 +504,36 @@ static int tree_link_any(X509_POLICY_LEVEL *curr,
337 504
338static int tree_prune(X509_POLICY_TREE *tree, X509_POLICY_LEVEL *curr) 505static int tree_prune(X509_POLICY_TREE *tree, X509_POLICY_LEVEL *curr)
339 { 506 {
507 STACK_OF(X509_POLICY_NODE) *nodes;
340 X509_POLICY_NODE *node; 508 X509_POLICY_NODE *node;
341 int i; 509 int i;
342 for (i = sk_X509_POLICY_NODE_num(curr->nodes) - 1; i >= 0; i--) 510 nodes = curr->nodes;
511 if (curr->flags & X509_V_FLAG_INHIBIT_MAP)
343 { 512 {
344 node = sk_X509_POLICY_NODE_value(curr->nodes, i); 513 for (i = sk_X509_POLICY_NODE_num(nodes) - 1; i >= 0; i--)
345 /* Delete any mapped data: see RFC3280 XXXX */
346 if (node->data->flags & POLICY_DATA_FLAG_MAP_MASK)
347 { 514 {
348 node->parent->nchild--; 515 node = sk_X509_POLICY_NODE_value(nodes, i);
349 OPENSSL_free(node); 516 /* Delete any mapped data: see RFC3280 XXXX */
350 (void)sk_X509_POLICY_NODE_delete(curr->nodes, i); 517 if (node->data->flags & POLICY_DATA_FLAG_MAP_MASK)
518 {
519 node->parent->nchild--;
520 OPENSSL_free(node);
521 (void)sk_X509_POLICY_NODE_delete(nodes,i);
522 }
351 } 523 }
352 } 524 }
353 525
354 for(;;) { 526 for(;;) {
355 --curr; 527 --curr;
356 for (i = sk_X509_POLICY_NODE_num(curr->nodes) - 1; i >= 0; i--) 528 nodes = curr->nodes;
529 for (i = sk_X509_POLICY_NODE_num(nodes) - 1; i >= 0; i--)
357 { 530 {
358 node = sk_X509_POLICY_NODE_value(curr->nodes, i); 531 node = sk_X509_POLICY_NODE_value(nodes, i);
359 if (node->nchild == 0) 532 if (node->nchild == 0)
360 { 533 {
361 node->parent->nchild--; 534 node->parent->nchild--;
362 OPENSSL_free(node); 535 OPENSSL_free(node);
363 (void)sk_X509_POLICY_NODE_delete(curr->nodes, i); 536 (void)sk_X509_POLICY_NODE_delete(nodes, i);
364 } 537 }
365 } 538 }
366 if (curr->anyPolicy && !curr->anyPolicy->nchild) 539 if (curr->anyPolicy && !curr->anyPolicy->nchild)
@@ -536,6 +709,7 @@ static int tree_evaluate(X509_POLICY_TREE *tree)
536 if (!(curr->flags & X509_V_FLAG_INHIBIT_ANY) 709 if (!(curr->flags & X509_V_FLAG_INHIBIT_ANY)
537 && !tree_link_any(curr, cache, tree)) 710 && !tree_link_any(curr, cache, tree))
538 return 0; 711 return 0;
712 tree_print("before tree_prune()", tree, curr);
539 ret = tree_prune(tree, curr); 713 ret = tree_prune(tree, curr);
540 if (ret != 1) 714 if (ret != 1)
541 return ret; 715 return ret;
@@ -604,7 +778,6 @@ int X509_policy_check(X509_POLICY_TREE **ptree, int *pexplicit_policy,
604 *pexplicit_policy = 0; 778 *pexplicit_policy = 0;
605 ret = tree_init(&tree, certs, flags); 779 ret = tree_init(&tree, certs, flags);
606 780
607
608 switch (ret) 781 switch (ret)
609 { 782 {
610 783
@@ -613,6 +786,10 @@ int X509_policy_check(X509_POLICY_TREE **ptree, int *pexplicit_policy,
613 return 1; 786 return 1;
614 787
615 /* Some internal error */ 788 /* Some internal error */
789 case -1:
790 return -1;
791
792 /* Some internal error */
616 case 0: 793 case 0:
617 return 0; 794 return 0;
618 795
@@ -646,6 +823,8 @@ int X509_policy_check(X509_POLICY_TREE **ptree, int *pexplicit_policy,
646 if (!tree) goto error; 823 if (!tree) goto error;
647 ret = tree_evaluate(tree); 824 ret = tree_evaluate(tree);
648 825
826 tree_print("tree_evaluate()", tree, NULL);
827
649 if (ret <= 0) 828 if (ret <= 0)
650 goto error; 829 goto error;
651 830
diff --git a/src/lib/libcrypto/x509v3/v3_alt.c b/src/lib/libcrypto/x509v3/v3_alt.c
index 58b2952478..d29d94338e 100644
--- a/src/lib/libcrypto/x509v3/v3_alt.c
+++ b/src/lib/libcrypto/x509v3/v3_alt.c
@@ -82,6 +82,12 @@ NULL, NULL, NULL},
82(X509V3_EXT_I2V)i2v_GENERAL_NAMES, 82(X509V3_EXT_I2V)i2v_GENERAL_NAMES,
83(X509V3_EXT_V2I)v2i_issuer_alt, 83(X509V3_EXT_V2I)v2i_issuer_alt,
84NULL, NULL, NULL}, 84NULL, NULL, NULL},
85
86{ NID_certificate_issuer, 0, ASN1_ITEM_ref(GENERAL_NAMES),
870,0,0,0,
880,0,
89(X509V3_EXT_I2V)i2v_GENERAL_NAMES,
90NULL, NULL, NULL, NULL},
85}; 91};
86 92
87STACK_OF(CONF_VALUE) *i2v_GENERAL_NAMES(X509V3_EXT_METHOD *method, 93STACK_OF(CONF_VALUE) *i2v_GENERAL_NAMES(X509V3_EXT_METHOD *method,
@@ -360,6 +366,7 @@ static int copy_email(X509V3_CTX *ctx, GENERAL_NAMES *gens, int move_p)
360 if (move_p) 366 if (move_p)
361 { 367 {
362 X509_NAME_delete_entry(nm, i); 368 X509_NAME_delete_entry(nm, i);
369 X509_NAME_ENTRY_free(ne);
363 i--; 370 i--;
364 } 371 }
365 if(!email || !(gen = GENERAL_NAME_new())) { 372 if(!email || !(gen = GENERAL_NAME_new())) {
@@ -386,8 +393,8 @@ static int copy_email(X509V3_CTX *ctx, GENERAL_NAMES *gens, int move_p)
386 393
387} 394}
388 395
389GENERAL_NAMES *v2i_GENERAL_NAMES(X509V3_EXT_METHOD *method, 396GENERAL_NAMES *v2i_GENERAL_NAMES(const X509V3_EXT_METHOD *method,
390 X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval) 397 X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval)
391{ 398{
392 GENERAL_NAME *gen; 399 GENERAL_NAME *gen;
393 GENERAL_NAMES *gens = NULL; 400 GENERAL_NAMES *gens = NULL;
@@ -408,28 +415,22 @@ GENERAL_NAMES *v2i_GENERAL_NAMES(X509V3_EXT_METHOD *method,
408 return NULL; 415 return NULL;
409} 416}
410 417
411GENERAL_NAME *v2i_GENERAL_NAME(X509V3_EXT_METHOD *method, X509V3_CTX *ctx, 418GENERAL_NAME *v2i_GENERAL_NAME(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx,
412 CONF_VALUE *cnf) 419 CONF_VALUE *cnf)
413 { 420 {
414 return v2i_GENERAL_NAME_ex(NULL, method, ctx, cnf, 0); 421 return v2i_GENERAL_NAME_ex(NULL, method, ctx, cnf, 0);
415 } 422 }
416 423
417GENERAL_NAME *v2i_GENERAL_NAME_ex(GENERAL_NAME *out, 424GENERAL_NAME *a2i_GENERAL_NAME(GENERAL_NAME *out,
418 X509V3_EXT_METHOD *method, X509V3_CTX *ctx, 425 const X509V3_EXT_METHOD *method, X509V3_CTX *ctx,
419 CONF_VALUE *cnf, int is_nc) 426 int gen_type, char *value, int is_nc)
420 { 427 {
421 char is_string = 0; 428 char is_string = 0;
422 int type;
423 GENERAL_NAME *gen = NULL; 429 GENERAL_NAME *gen = NULL;
424 430
425 char *name, *value;
426
427 name = cnf->name;
428 value = cnf->value;
429
430 if(!value) 431 if(!value)
431 { 432 {
432 X509V3err(X509V3_F_V2I_GENERAL_NAME_EX,X509V3_R_MISSING_VALUE); 433 X509V3err(X509V3_F_A2I_GENERAL_NAME,X509V3_R_MISSING_VALUE);
433 return NULL; 434 return NULL;
434 } 435 }
435 436
@@ -440,74 +441,62 @@ GENERAL_NAME *v2i_GENERAL_NAME_ex(GENERAL_NAME *out,
440 gen = GENERAL_NAME_new(); 441 gen = GENERAL_NAME_new();
441 if(gen == NULL) 442 if(gen == NULL)
442 { 443 {
443 X509V3err(X509V3_F_V2I_GENERAL_NAME_EX,ERR_R_MALLOC_FAILURE); 444 X509V3err(X509V3_F_A2I_GENERAL_NAME,ERR_R_MALLOC_FAILURE);
444 return NULL; 445 return NULL;
445 } 446 }
446 } 447 }
447 448
448 if(!name_cmp(name, "email")) 449 switch (gen_type)
449 {
450 is_string = 1;
451 type = GEN_EMAIL;
452 }
453 else if(!name_cmp(name, "URI"))
454 {
455 is_string = 1;
456 type = GEN_URI;
457 }
458 else if(!name_cmp(name, "DNS"))
459 { 450 {
451 case GEN_URI:
452 case GEN_EMAIL:
453 case GEN_DNS:
460 is_string = 1; 454 is_string = 1;
461 type = GEN_DNS; 455 break;
462 } 456
463 else if(!name_cmp(name, "RID")) 457 case GEN_RID:
464 { 458 {
465 ASN1_OBJECT *obj; 459 ASN1_OBJECT *obj;
466 if(!(obj = OBJ_txt2obj(value,0))) 460 if(!(obj = OBJ_txt2obj(value,0)))
467 { 461 {
468 X509V3err(X509V3_F_V2I_GENERAL_NAME_EX,X509V3_R_BAD_OBJECT); 462 X509V3err(X509V3_F_A2I_GENERAL_NAME,X509V3_R_BAD_OBJECT);
469 ERR_add_error_data(2, "value=", value); 463 ERR_add_error_data(2, "value=", value);
470 goto err; 464 goto err;
471 } 465 }
472 gen->d.rid = obj; 466 gen->d.rid = obj;
473 type = GEN_RID;
474 } 467 }
475 else if(!name_cmp(name, "IP")) 468 break;
476 { 469
470 case GEN_IPADD:
477 if (is_nc) 471 if (is_nc)
478 gen->d.ip = a2i_IPADDRESS_NC(value); 472 gen->d.ip = a2i_IPADDRESS_NC(value);
479 else 473 else
480 gen->d.ip = a2i_IPADDRESS(value); 474 gen->d.ip = a2i_IPADDRESS(value);
481 if(gen->d.ip == NULL) 475 if(gen->d.ip == NULL)
482 { 476 {
483 X509V3err(X509V3_F_V2I_GENERAL_NAME_EX,X509V3_R_BAD_IP_ADDRESS); 477 X509V3err(X509V3_F_A2I_GENERAL_NAME,X509V3_R_BAD_IP_ADDRESS);
484 ERR_add_error_data(2, "value=", value); 478 ERR_add_error_data(2, "value=", value);
485 goto err; 479 goto err;
486 } 480 }
487 type = GEN_IPADD; 481 break;
488 } 482
489 else if(!name_cmp(name, "dirName")) 483 case GEN_DIRNAME:
490 {
491 type = GEN_DIRNAME;
492 if (!do_dirname(gen, value, ctx)) 484 if (!do_dirname(gen, value, ctx))
493 { 485 {
494 X509V3err(X509V3_F_V2I_GENERAL_NAME_EX,X509V3_R_DIRNAME_ERROR); 486 X509V3err(X509V3_F_A2I_GENERAL_NAME,X509V3_R_DIRNAME_ERROR);
495 goto err; 487 goto err;
496 } 488 }
497 } 489 break;
498 else if(!name_cmp(name, "otherName")) 490
499 { 491 case GEN_OTHERNAME:
500 if (!do_othername(gen, value, ctx)) 492 if (!do_othername(gen, value, ctx))
501 { 493 {
502 X509V3err(X509V3_F_V2I_GENERAL_NAME_EX,X509V3_R_OTHERNAME_ERROR); 494 X509V3err(X509V3_F_A2I_GENERAL_NAME,X509V3_R_OTHERNAME_ERROR);
503 goto err; 495 goto err;
504 } 496 }
505 type = GEN_OTHERNAME; 497 break;
506 } 498 default:
507 else 499 X509V3err(X509V3_F_A2I_GENERAL_NAME,X509V3_R_UNSUPPORTED_TYPE);
508 {
509 X509V3err(X509V3_F_V2I_GENERAL_NAME_EX,X509V3_R_UNSUPPORTED_OPTION);
510 ERR_add_error_data(2, "name=", name);
511 goto err; 500 goto err;
512 } 501 }
513 502
@@ -517,12 +506,12 @@ GENERAL_NAME *v2i_GENERAL_NAME_ex(GENERAL_NAME *out,
517 !ASN1_STRING_set(gen->d.ia5, (unsigned char*)value, 506 !ASN1_STRING_set(gen->d.ia5, (unsigned char*)value,
518 strlen(value))) 507 strlen(value)))
519 { 508 {
520 X509V3err(X509V3_F_V2I_GENERAL_NAME_EX,ERR_R_MALLOC_FAILURE); 509 X509V3err(X509V3_F_A2I_GENERAL_NAME,ERR_R_MALLOC_FAILURE);
521 goto err; 510 goto err;
522 } 511 }
523 } 512 }
524 513
525 gen->type = type; 514 gen->type = gen_type;
526 515
527 return gen; 516 return gen;
528 517
@@ -532,6 +521,48 @@ GENERAL_NAME *v2i_GENERAL_NAME_ex(GENERAL_NAME *out,
532 return NULL; 521 return NULL;
533 } 522 }
534 523
524GENERAL_NAME *v2i_GENERAL_NAME_ex(GENERAL_NAME *out,
525 const X509V3_EXT_METHOD *method,
526 X509V3_CTX *ctx, CONF_VALUE *cnf, int is_nc)
527 {
528 int type;
529
530 char *name, *value;
531
532 name = cnf->name;
533 value = cnf->value;
534
535 if(!value)
536 {
537 X509V3err(X509V3_F_V2I_GENERAL_NAME_EX,X509V3_R_MISSING_VALUE);
538 return NULL;
539 }
540
541 if(!name_cmp(name, "email"))
542 type = GEN_EMAIL;
543 else if(!name_cmp(name, "URI"))
544 type = GEN_URI;
545 else if(!name_cmp(name, "DNS"))
546 type = GEN_DNS;
547 else if(!name_cmp(name, "RID"))
548 type = GEN_RID;
549 else if(!name_cmp(name, "IP"))
550 type = GEN_IPADD;
551 else if(!name_cmp(name, "dirName"))
552 type = GEN_DIRNAME;
553 else if(!name_cmp(name, "otherName"))
554 type = GEN_OTHERNAME;
555 else
556 {
557 X509V3err(X509V3_F_V2I_GENERAL_NAME_EX,X509V3_R_UNSUPPORTED_OPTION);
558 ERR_add_error_data(2, "name=", name);
559 return NULL;
560 }
561
562 return a2i_GENERAL_NAME(out, method, ctx, type, value, is_nc);
563
564 }
565
535static int do_othername(GENERAL_NAME *gen, char *value, X509V3_CTX *ctx) 566static int do_othername(GENERAL_NAME *gen, char *value, X509V3_CTX *ctx)
536 { 567 {
537 char *objtmp = NULL, *p; 568 char *objtmp = NULL, *p;
@@ -577,6 +608,7 @@ static int do_dirname(GENERAL_NAME *gen, char *value, X509V3_CTX *ctx)
577 if (!ret) 608 if (!ret)
578 X509_NAME_free(nm); 609 X509_NAME_free(nm);
579 gen->d.dirn = nm; 610 gen->d.dirn = nm;
611 X509V3_section_free(ctx, sk);
580 612
581 return ret; 613 return ret;
582 } 614 }
diff --git a/src/lib/libcrypto/x509v3/v3_conf.c b/src/lib/libcrypto/x509v3/v3_conf.c
index 11eb6b7fd5..6730f9a6ee 100644
--- a/src/lib/libcrypto/x509v3/v3_conf.c
+++ b/src/lib/libcrypto/x509v3/v3_conf.c
@@ -72,14 +72,14 @@ static X509_EXTENSION *do_ext_nconf(CONF *conf, X509V3_CTX *ctx, int ext_nid, in
72static X509_EXTENSION *v3_generic_extension(const char *ext, char *value, int crit, int type, X509V3_CTX *ctx); 72static X509_EXTENSION *v3_generic_extension(const char *ext, char *value, int crit, int type, X509V3_CTX *ctx);
73static char *conf_lhash_get_string(void *db, char *section, char *value); 73static char *conf_lhash_get_string(void *db, char *section, char *value);
74static STACK_OF(CONF_VALUE) *conf_lhash_get_section(void *db, char *section); 74static STACK_OF(CONF_VALUE) *conf_lhash_get_section(void *db, char *section);
75static X509_EXTENSION *do_ext_i2d(X509V3_EXT_METHOD *method, int ext_nid, 75static X509_EXTENSION *do_ext_i2d(const X509V3_EXT_METHOD *method, int ext_nid,
76 int crit, void *ext_struc); 76 int crit, void *ext_struc);
77static unsigned char *generic_asn1(char *value, X509V3_CTX *ctx, long *ext_len); 77static unsigned char *generic_asn1(char *value, X509V3_CTX *ctx, long *ext_len);
78/* CONF *conf: Config file */ 78/* CONF *conf: Config file */
79/* char *name: Name */ 79/* char *name: Name */
80/* char *value: Value */ 80/* char *value: Value */
81X509_EXTENSION *X509V3_EXT_nconf(CONF *conf, X509V3_CTX *ctx, char *name, 81X509_EXTENSION *X509V3_EXT_nconf(CONF *conf, X509V3_CTX *ctx, char *name,
82 char *value) 82 char *value)
83 { 83 {
84 int crit; 84 int crit;
85 int ext_type; 85 int ext_type;
@@ -99,7 +99,7 @@ X509_EXTENSION *X509V3_EXT_nconf(CONF *conf, X509V3_CTX *ctx, char *name,
99/* CONF *conf: Config file */ 99/* CONF *conf: Config file */
100/* char *value: Value */ 100/* char *value: Value */
101X509_EXTENSION *X509V3_EXT_nconf_nid(CONF *conf, X509V3_CTX *ctx, int ext_nid, 101X509_EXTENSION *X509V3_EXT_nconf_nid(CONF *conf, X509V3_CTX *ctx, int ext_nid,
102 char *value) 102 char *value)
103 { 103 {
104 int crit; 104 int crit;
105 int ext_type; 105 int ext_type;
@@ -113,9 +113,9 @@ X509_EXTENSION *X509V3_EXT_nconf_nid(CONF *conf, X509V3_CTX *ctx, int ext_nid,
113/* CONF *conf: Config file */ 113/* CONF *conf: Config file */
114/* char *value: Value */ 114/* char *value: Value */
115static X509_EXTENSION *do_ext_nconf(CONF *conf, X509V3_CTX *ctx, int ext_nid, 115static X509_EXTENSION *do_ext_nconf(CONF *conf, X509V3_CTX *ctx, int ext_nid,
116 int crit, char *value) 116 int crit, char *value)
117 { 117 {
118 X509V3_EXT_METHOD *method; 118 const X509V3_EXT_METHOD *method;
119 X509_EXTENSION *ext; 119 X509_EXTENSION *ext;
120 STACK_OF(CONF_VALUE) *nval; 120 STACK_OF(CONF_VALUE) *nval;
121 void *ext_struc; 121 void *ext_struc;
@@ -172,8 +172,8 @@ static X509_EXTENSION *do_ext_nconf(CONF *conf, X509V3_CTX *ctx, int ext_nid,
172 172
173 } 173 }
174 174
175static X509_EXTENSION *do_ext_i2d(X509V3_EXT_METHOD *method, int ext_nid, 175static X509_EXTENSION *do_ext_i2d(const X509V3_EXT_METHOD *method, int ext_nid,
176 int crit, void *ext_struc) 176 int crit, void *ext_struc)
177 { 177 {
178 unsigned char *ext_der; 178 unsigned char *ext_der;
179 int ext_len; 179 int ext_len;
@@ -214,7 +214,7 @@ static X509_EXTENSION *do_ext_i2d(X509V3_EXT_METHOD *method, int ext_nid,
214 214
215X509_EXTENSION *X509V3_EXT_i2d(int ext_nid, int crit, void *ext_struc) 215X509_EXTENSION *X509V3_EXT_i2d(int ext_nid, int crit, void *ext_struc)
216 { 216 {
217 X509V3_EXT_METHOD *method; 217 const X509V3_EXT_METHOD *method;
218 if (!(method = X509V3_EXT_get_nid(ext_nid))) { 218 if (!(method = X509V3_EXT_get_nid(ext_nid))) {
219 X509V3err(X509V3_F_X509V3_EXT_I2D,X509V3_R_UNKNOWN_EXTENSION); 219 X509V3err(X509V3_F_X509V3_EXT_I2D,X509V3_R_UNKNOWN_EXTENSION);
220 return NULL; 220 return NULL;
@@ -258,7 +258,8 @@ static int v3_check_generic(char **value)
258 258
259/* Create a generic extension: for now just handle DER type */ 259/* Create a generic extension: for now just handle DER type */
260static X509_EXTENSION *v3_generic_extension(const char *ext, char *value, 260static X509_EXTENSION *v3_generic_extension(const char *ext, char *value,
261 int crit, int gen_type, X509V3_CTX *ctx) 261 int crit, int gen_type,
262 X509V3_CTX *ctx)
262 { 263 {
263 unsigned char *ext_der=NULL; 264 unsigned char *ext_der=NULL;
264 long ext_len; 265 long ext_len;
@@ -322,7 +323,7 @@ static unsigned char *generic_asn1(char *value, X509V3_CTX *ctx, long *ext_len)
322 323
323 324
324int X509V3_EXT_add_nconf_sk(CONF *conf, X509V3_CTX *ctx, char *section, 325int X509V3_EXT_add_nconf_sk(CONF *conf, X509V3_CTX *ctx, char *section,
325 STACK_OF(X509_EXTENSION) **sk) 326 STACK_OF(X509_EXTENSION) **sk)
326 { 327 {
327 X509_EXTENSION *ext; 328 X509_EXTENSION *ext;
328 STACK_OF(CONF_VALUE) *nval; 329 STACK_OF(CONF_VALUE) *nval;
@@ -343,7 +344,7 @@ int X509V3_EXT_add_nconf_sk(CONF *conf, X509V3_CTX *ctx, char *section,
343/* Convenience functions to add extensions to a certificate, CRL and request */ 344/* Convenience functions to add extensions to a certificate, CRL and request */
344 345
345int X509V3_EXT_add_nconf(CONF *conf, X509V3_CTX *ctx, char *section, 346int X509V3_EXT_add_nconf(CONF *conf, X509V3_CTX *ctx, char *section,
346 X509 *cert) 347 X509 *cert)
347 { 348 {
348 STACK_OF(X509_EXTENSION) **sk = NULL; 349 STACK_OF(X509_EXTENSION) **sk = NULL;
349 if (cert) 350 if (cert)
@@ -354,7 +355,7 @@ int X509V3_EXT_add_nconf(CONF *conf, X509V3_CTX *ctx, char *section,
354/* Same as above but for a CRL */ 355/* Same as above but for a CRL */
355 356
356int X509V3_EXT_CRL_add_nconf(CONF *conf, X509V3_CTX *ctx, char *section, 357int X509V3_EXT_CRL_add_nconf(CONF *conf, X509V3_CTX *ctx, char *section,
357 X509_CRL *crl) 358 X509_CRL *crl)
358 { 359 {
359 STACK_OF(X509_EXTENSION) **sk = NULL; 360 STACK_OF(X509_EXTENSION) **sk = NULL;
360 if (crl) 361 if (crl)
@@ -443,7 +444,7 @@ void X509V3_set_nconf(X509V3_CTX *ctx, CONF *conf)
443 } 444 }
444 445
445void X509V3_set_ctx(X509V3_CTX *ctx, X509 *issuer, X509 *subj, X509_REQ *req, 446void X509V3_set_ctx(X509V3_CTX *ctx, X509 *issuer, X509 *subj, X509_REQ *req,
446 X509_CRL *crl, int flags) 447 X509_CRL *crl, int flags)
447 { 448 {
448 ctx->issuer_cert = issuer; 449 ctx->issuer_cert = issuer;
449 ctx->subject_cert = subj; 450 ctx->subject_cert = subj;
@@ -454,8 +455,8 @@ void X509V3_set_ctx(X509V3_CTX *ctx, X509 *issuer, X509 *subj, X509_REQ *req,
454 455
455/* Old conf compatibility functions */ 456/* Old conf compatibility functions */
456 457
457X509_EXTENSION *X509V3_EXT_conf(LHASH *conf, X509V3_CTX *ctx, char *name, 458X509_EXTENSION *X509V3_EXT_conf(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx,
458 char *value) 459 char *name, char *value)
459 { 460 {
460 CONF ctmp; 461 CONF ctmp;
461 CONF_set_nconf(&ctmp, conf); 462 CONF_set_nconf(&ctmp, conf);
@@ -464,8 +465,8 @@ X509_EXTENSION *X509V3_EXT_conf(LHASH *conf, X509V3_CTX *ctx, char *name,
464 465
465/* LHASH *conf: Config file */ 466/* LHASH *conf: Config file */
466/* char *value: Value */ 467/* char *value: Value */
467X509_EXTENSION *X509V3_EXT_conf_nid(LHASH *conf, X509V3_CTX *ctx, int ext_nid, 468X509_EXTENSION *X509V3_EXT_conf_nid(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx,
468 char *value) 469 int ext_nid, char *value)
469 { 470 {
470 CONF ctmp; 471 CONF ctmp;
471 CONF_set_nconf(&ctmp, conf); 472 CONF_set_nconf(&ctmp, conf);
@@ -489,14 +490,14 @@ NULL,
489NULL 490NULL
490}; 491};
491 492
492void X509V3_set_conf_lhash(X509V3_CTX *ctx, LHASH *lhash) 493void X509V3_set_conf_lhash(X509V3_CTX *ctx, LHASH_OF(CONF_VALUE) *lhash)
493 { 494 {
494 ctx->db_meth = &conf_lhash_method; 495 ctx->db_meth = &conf_lhash_method;
495 ctx->db = lhash; 496 ctx->db = lhash;
496 } 497 }
497 498
498int X509V3_EXT_add_conf(LHASH *conf, X509V3_CTX *ctx, char *section, 499int X509V3_EXT_add_conf(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx,
499 X509 *cert) 500 char *section, X509 *cert)
500 { 501 {
501 CONF ctmp; 502 CONF ctmp;
502 CONF_set_nconf(&ctmp, conf); 503 CONF_set_nconf(&ctmp, conf);
@@ -505,8 +506,8 @@ int X509V3_EXT_add_conf(LHASH *conf, X509V3_CTX *ctx, char *section,
505 506
506/* Same as above but for a CRL */ 507/* Same as above but for a CRL */
507 508
508int X509V3_EXT_CRL_add_conf(LHASH *conf, X509V3_CTX *ctx, char *section, 509int X509V3_EXT_CRL_add_conf(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx,
509 X509_CRL *crl) 510 char *section, X509_CRL *crl)
510 { 511 {
511 CONF ctmp; 512 CONF ctmp;
512 CONF_set_nconf(&ctmp, conf); 513 CONF_set_nconf(&ctmp, conf);
@@ -515,8 +516,8 @@ int X509V3_EXT_CRL_add_conf(LHASH *conf, X509V3_CTX *ctx, char *section,
515 516
516/* Add extensions to certificate request */ 517/* Add extensions to certificate request */
517 518
518int X509V3_EXT_REQ_add_conf(LHASH *conf, X509V3_CTX *ctx, char *section, 519int X509V3_EXT_REQ_add_conf(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx,
519 X509_REQ *req) 520 char *section, X509_REQ *req)
520 { 521 {
521 CONF ctmp; 522 CONF ctmp;
522 CONF_set_nconf(&ctmp, conf); 523 CONF_set_nconf(&ctmp, conf);
diff --git a/src/lib/libcrypto/x509v3/v3_cpols.c b/src/lib/libcrypto/x509v3/v3_cpols.c
index ad0506d75c..1f0798b946 100644
--- a/src/lib/libcrypto/x509v3/v3_cpols.c
+++ b/src/lib/libcrypto/x509v3/v3_cpols.c
@@ -450,5 +450,8 @@ void X509_POLICY_NODE_print(BIO *out, X509_POLICY_NODE *node, int indent)
450 else 450 else
451 BIO_printf(out, "%*sNo Qualifiers\n", indent + 2, ""); 451 BIO_printf(out, "%*sNo Qualifiers\n", indent + 2, "");
452 } 452 }
453 453
454
454IMPLEMENT_STACK_OF(X509_POLICY_NODE) 455IMPLEMENT_STACK_OF(X509_POLICY_NODE)
456IMPLEMENT_STACK_OF(X509_POLICY_DATA)
457
diff --git a/src/lib/libcrypto/x509v3/v3_crld.c b/src/lib/libcrypto/x509v3/v3_crld.c
index 181a8977b1..790a6dd032 100644
--- a/src/lib/libcrypto/x509v3/v3_crld.c
+++ b/src/lib/libcrypto/x509v3/v3_crld.c
@@ -3,7 +3,7 @@
3 * project 1999. 3 * project 1999.
4 */ 4 */
5/* ==================================================================== 5/* ====================================================================
6 * Copyright (c) 1999 The OpenSSL Project. All rights reserved. 6 * Copyright (c) 1999-2008 The OpenSSL Project. All rights reserved.
7 * 7 *
8 * Redistribution and use in source and binary forms, with or without 8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions 9 * modification, are permitted provided that the following conditions
@@ -63,45 +63,254 @@
63#include <openssl/asn1t.h> 63#include <openssl/asn1t.h>
64#include <openssl/x509v3.h> 64#include <openssl/x509v3.h>
65 65
66static STACK_OF(CONF_VALUE) *i2v_crld(X509V3_EXT_METHOD *method, 66static void *v2i_crld(const X509V3_EXT_METHOD *method,
67 STACK_OF(DIST_POINT) *crld, STACK_OF(CONF_VALUE) *extlist); 67 X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval);
68static STACK_OF(DIST_POINT) *v2i_crld(X509V3_EXT_METHOD *method, 68static int i2r_crldp(const X509V3_EXT_METHOD *method, void *pcrldp, BIO *out,
69 X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval); 69 int indent);
70 70
71const X509V3_EXT_METHOD v3_crld = { 71const X509V3_EXT_METHOD v3_crld =
72NID_crl_distribution_points, X509V3_EXT_MULTILINE, ASN1_ITEM_ref(CRL_DIST_POINTS), 72 {
730,0,0,0, 73 NID_crl_distribution_points, 0, ASN1_ITEM_ref(CRL_DIST_POINTS),
740,0, 74 0,0,0,0,
75(X509V3_EXT_I2V)i2v_crld, 75 0,0,
76(X509V3_EXT_V2I)v2i_crld, 76 0,
770,0, 77 v2i_crld,
78NULL 78 i2r_crldp,0,
79 NULL
80 };
81
82const X509V3_EXT_METHOD v3_freshest_crl =
83 {
84 NID_freshest_crl, 0, ASN1_ITEM_ref(CRL_DIST_POINTS),
85 0,0,0,0,
86 0,0,
87 0,
88 v2i_crld,
89 i2r_crldp,0,
90 NULL
91 };
92
93static STACK_OF(GENERAL_NAME) *gnames_from_sectname(X509V3_CTX *ctx, char *sect)
94 {
95 STACK_OF(CONF_VALUE) *gnsect;
96 STACK_OF(GENERAL_NAME) *gens;
97 if (*sect == '@')
98 gnsect = X509V3_get_section(ctx, sect + 1);
99 else
100 gnsect = X509V3_parse_list(sect);
101 if (!gnsect)
102 {
103 X509V3err(X509V3_F_GNAMES_FROM_SECTNAME,
104 X509V3_R_SECTION_NOT_FOUND);
105 return NULL;
106 }
107 gens = v2i_GENERAL_NAMES(NULL, ctx, gnsect);
108 if (*sect == '@')
109 X509V3_section_free(ctx, gnsect);
110 else
111 sk_CONF_VALUE_pop_free(gnsect, X509V3_conf_free);
112 return gens;
113 }
114
115static int set_dist_point_name(DIST_POINT_NAME **pdp, X509V3_CTX *ctx,
116 CONF_VALUE *cnf)
117 {
118 STACK_OF(GENERAL_NAME) *fnm = NULL;
119 STACK_OF(X509_NAME_ENTRY) *rnm = NULL;
120 if (!strncmp(cnf->name, "fullname", 9))
121 {
122 fnm = gnames_from_sectname(ctx, cnf->value);
123 if (!fnm)
124 goto err;
125 }
126 else if (!strcmp(cnf->name, "relativename"))
127 {
128 int ret;
129 STACK_OF(CONF_VALUE) *dnsect;
130 X509_NAME *nm;
131 nm = X509_NAME_new();
132 if (!nm)
133 return -1;
134 dnsect = X509V3_get_section(ctx, cnf->value);
135 if (!dnsect)
136 {
137 X509V3err(X509V3_F_SET_DIST_POINT_NAME,
138 X509V3_R_SECTION_NOT_FOUND);
139 return -1;
140 }
141 ret = X509V3_NAME_from_section(nm, dnsect, MBSTRING_ASC);
142 X509V3_section_free(ctx, dnsect);
143 rnm = nm->entries;
144 nm->entries = NULL;
145 X509_NAME_free(nm);
146 if (!ret || sk_X509_NAME_ENTRY_num(rnm) <= 0)
147 goto err;
148 /* Since its a name fragment can't have more than one
149 * RDNSequence
150 */
151 if (sk_X509_NAME_ENTRY_value(rnm,
152 sk_X509_NAME_ENTRY_num(rnm) - 1)->set)
153 {
154 X509V3err(X509V3_F_SET_DIST_POINT_NAME,
155 X509V3_R_INVALID_MULTIPLE_RDNS);
156 goto err;
157 }
158 }
159 else
160 return 0;
161
162 if (*pdp)
163 {
164 X509V3err(X509V3_F_SET_DIST_POINT_NAME,
165 X509V3_R_DISTPOINT_ALREADY_SET);
166 goto err;
167 }
168
169 *pdp = DIST_POINT_NAME_new();
170 if (!*pdp)
171 goto err;
172 if (fnm)
173 {
174 (*pdp)->type = 0;
175 (*pdp)->name.fullname = fnm;
176 }
177 else
178 {
179 (*pdp)->type = 1;
180 (*pdp)->name.relativename = rnm;
181 }
182
183 return 1;
184
185 err:
186 if (fnm)
187 sk_GENERAL_NAME_pop_free(fnm, GENERAL_NAME_free);
188 if (rnm)
189 sk_X509_NAME_ENTRY_pop_free(rnm, X509_NAME_ENTRY_free);
190 return -1;
191 }
192
193static const BIT_STRING_BITNAME reason_flags[] = {
194{0, "Unused", "unused"},
195{1, "Key Compromise", "keyCompromise"},
196{2, "CA Compromise", "CACompromise"},
197{3, "Affiliation Changed", "affiliationChanged"},
198{4, "Superseded", "superseded"},
199{5, "Cessation Of Operation", "cessationOfOperation"},
200{6, "Certificate Hold", "certificateHold"},
201{7, "Privilege Withdrawn", "privilegeWithdrawn"},
202{8, "AA Compromise", "AACompromise"},
203{-1, NULL, NULL}
79}; 204};
80 205
81static STACK_OF(CONF_VALUE) *i2v_crld(X509V3_EXT_METHOD *method, 206static int set_reasons(ASN1_BIT_STRING **preas, char *value)
82 STACK_OF(DIST_POINT) *crld, STACK_OF(CONF_VALUE) *exts) 207 {
83{ 208 STACK_OF(CONF_VALUE) *rsk = NULL;
84 DIST_POINT *point; 209 const BIT_STRING_BITNAME *pbn;
210 const char *bnam;
211 int i, ret = 0;
212 rsk = X509V3_parse_list(value);
213 if (!rsk)
214 return 0;
215 if (*preas)
216 return 0;
217 for (i = 0; i < sk_CONF_VALUE_num(rsk); i++)
218 {
219 bnam = sk_CONF_VALUE_value(rsk, i)->name;
220 if (!*preas)
221 {
222 *preas = ASN1_BIT_STRING_new();
223 if (!*preas)
224 goto err;
225 }
226 for (pbn = reason_flags; pbn->lname; pbn++)
227 {
228 if (!strcmp(pbn->sname, bnam))
229 {
230 if (!ASN1_BIT_STRING_set_bit(*preas,
231 pbn->bitnum, 1))
232 goto err;
233 break;
234 }
235 }
236 if (!pbn->lname)
237 goto err;
238 }
239 ret = 1;
240
241 err:
242 sk_CONF_VALUE_pop_free(rsk, X509V3_conf_free);
243 return ret;
244 }
245
246static int print_reasons(BIO *out, const char *rname,
247 ASN1_BIT_STRING *rflags, int indent)
248 {
249 int first = 1;
250 const BIT_STRING_BITNAME *pbn;
251 BIO_printf(out, "%*s%s:\n%*s", indent, "", rname, indent + 2, "");
252 for (pbn = reason_flags; pbn->lname; pbn++)
253 {
254 if (ASN1_BIT_STRING_get_bit(rflags, pbn->bitnum))
255 {
256 if (first)
257 first = 0;
258 else
259 BIO_puts(out, ", ");
260 BIO_puts(out, pbn->lname);
261 }
262 }
263 if (first)
264 BIO_puts(out, "<EMPTY>\n");
265 else
266 BIO_puts(out, "\n");
267 return 1;
268 }
269
270static DIST_POINT *crldp_from_section(X509V3_CTX *ctx,
271 STACK_OF(CONF_VALUE) *nval)
272 {
85 int i; 273 int i;
86 for(i = 0; i < sk_DIST_POINT_num(crld); i++) { 274 CONF_VALUE *cnf;
87 point = sk_DIST_POINT_value(crld, i); 275 DIST_POINT *point = NULL;
88 if(point->distpoint) { 276 point = DIST_POINT_new();
89 if(point->distpoint->type == 0) 277 if (!point)
90 exts = i2v_GENERAL_NAMES(NULL, 278 goto err;
91 point->distpoint->name.fullname, exts); 279 for(i = 0; i < sk_CONF_VALUE_num(nval); i++)
92 else X509V3_add_value("RelativeName","<UNSUPPORTED>", &exts); 280 {
281 int ret;
282 cnf = sk_CONF_VALUE_value(nval, i);
283 ret = set_dist_point_name(&point->distpoint, ctx, cnf);
284 if (ret > 0)
285 continue;
286 if (ret < 0)
287 goto err;
288 if (!strcmp(cnf->name, "reasons"))
289 {
290 if (!set_reasons(&point->reasons, cnf->value))
291 goto err;
292 }
293 else if (!strcmp(cnf->name, "CRLissuer"))
294 {
295 point->CRLissuer =
296 gnames_from_sectname(ctx, cnf->value);
297 if (!point->CRLissuer)
298 goto err;
299 }
93 } 300 }
94 if(point->reasons) 301
95 X509V3_add_value("reasons","<UNSUPPORTED>", &exts); 302 return point;
96 if(point->CRLissuer) 303
97 X509V3_add_value("CRLissuer","<UNSUPPORTED>", &exts); 304
305 err:
306 if (point)
307 DIST_POINT_free(point);
308 return NULL;
98 } 309 }
99 return exts;
100}
101 310
102static STACK_OF(DIST_POINT) *v2i_crld(X509V3_EXT_METHOD *method, 311static void *v2i_crld(const X509V3_EXT_METHOD *method,
103 X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval) 312 X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval)
104{ 313 {
105 STACK_OF(DIST_POINT) *crld = NULL; 314 STACK_OF(DIST_POINT) *crld = NULL;
106 GENERAL_NAMES *gens = NULL; 315 GENERAL_NAMES *gens = NULL;
107 GENERAL_NAME *gen = NULL; 316 GENERAL_NAME *gen = NULL;
@@ -111,19 +320,44 @@ static STACK_OF(DIST_POINT) *v2i_crld(X509V3_EXT_METHOD *method,
111 for(i = 0; i < sk_CONF_VALUE_num(nval); i++) { 320 for(i = 0; i < sk_CONF_VALUE_num(nval); i++) {
112 DIST_POINT *point; 321 DIST_POINT *point;
113 cnf = sk_CONF_VALUE_value(nval, i); 322 cnf = sk_CONF_VALUE_value(nval, i);
114 if(!(gen = v2i_GENERAL_NAME(method, ctx, cnf))) goto err; 323 if (!cnf->value)
115 if(!(gens = GENERAL_NAMES_new())) goto merr; 324 {
116 if(!sk_GENERAL_NAME_push(gens, gen)) goto merr; 325 STACK_OF(CONF_VALUE) *dpsect;
117 gen = NULL; 326 dpsect = X509V3_get_section(ctx, cnf->name);
118 if(!(point = DIST_POINT_new())) goto merr; 327 if (!dpsect)
119 if(!sk_DIST_POINT_push(crld, point)) { 328 goto err;
120 DIST_POINT_free(point); 329 point = crldp_from_section(ctx, dpsect);
121 goto merr; 330 X509V3_section_free(ctx, dpsect);
122 } 331 if (!point)
123 if(!(point->distpoint = DIST_POINT_NAME_new())) goto merr; 332 goto err;
124 point->distpoint->name.fullname = gens; 333 if(!sk_DIST_POINT_push(crld, point))
125 point->distpoint->type = 0; 334 {
126 gens = NULL; 335 DIST_POINT_free(point);
336 goto merr;
337 }
338 }
339 else
340 {
341 if(!(gen = v2i_GENERAL_NAME(method, ctx, cnf)))
342 goto err;
343 if(!(gens = GENERAL_NAMES_new()))
344 goto merr;
345 if(!sk_GENERAL_NAME_push(gens, gen))
346 goto merr;
347 gen = NULL;
348 if(!(point = DIST_POINT_new()))
349 goto merr;
350 if(!sk_DIST_POINT_push(crld, point))
351 {
352 DIST_POINT_free(point);
353 goto merr;
354 }
355 if(!(point->distpoint = DIST_POINT_NAME_new()))
356 goto merr;
357 point->distpoint->name.fullname = gens;
358 point->distpoint->type = 0;
359 gens = NULL;
360 }
127 } 361 }
128 return crld; 362 return crld;
129 363
@@ -139,11 +373,31 @@ static STACK_OF(DIST_POINT) *v2i_crld(X509V3_EXT_METHOD *method,
139IMPLEMENT_STACK_OF(DIST_POINT) 373IMPLEMENT_STACK_OF(DIST_POINT)
140IMPLEMENT_ASN1_SET_OF(DIST_POINT) 374IMPLEMENT_ASN1_SET_OF(DIST_POINT)
141 375
376static int dpn_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
377 void *exarg)
378 {
379 DIST_POINT_NAME *dpn = (DIST_POINT_NAME *)*pval;
380
381 switch(operation)
382 {
383 case ASN1_OP_NEW_POST:
384 dpn->dpname = NULL;
385 break;
386
387 case ASN1_OP_FREE_POST:
388 if (dpn->dpname)
389 X509_NAME_free(dpn->dpname);
390 break;
391 }
392 return 1;
393 }
394
142 395
143ASN1_CHOICE(DIST_POINT_NAME) = { 396ASN1_CHOICE_cb(DIST_POINT_NAME, dpn_cb) = {
144 ASN1_IMP_SEQUENCE_OF(DIST_POINT_NAME, name.fullname, GENERAL_NAME, 0), 397 ASN1_IMP_SEQUENCE_OF(DIST_POINT_NAME, name.fullname, GENERAL_NAME, 0),
145 ASN1_IMP_SET_OF(DIST_POINT_NAME, name.relativename, X509_NAME_ENTRY, 1) 398 ASN1_IMP_SET_OF(DIST_POINT_NAME, name.relativename, X509_NAME_ENTRY, 1)
146} ASN1_CHOICE_END(DIST_POINT_NAME) 399} ASN1_CHOICE_END_cb(DIST_POINT_NAME, DIST_POINT_NAME, type)
400
147 401
148IMPLEMENT_ASN1_FUNCTIONS(DIST_POINT_NAME) 402IMPLEMENT_ASN1_FUNCTIONS(DIST_POINT_NAME)
149 403
@@ -160,3 +414,203 @@ ASN1_ITEM_TEMPLATE(CRL_DIST_POINTS) =
160ASN1_ITEM_TEMPLATE_END(CRL_DIST_POINTS) 414ASN1_ITEM_TEMPLATE_END(CRL_DIST_POINTS)
161 415
162IMPLEMENT_ASN1_FUNCTIONS(CRL_DIST_POINTS) 416IMPLEMENT_ASN1_FUNCTIONS(CRL_DIST_POINTS)
417
418ASN1_SEQUENCE(ISSUING_DIST_POINT) = {
419 ASN1_EXP_OPT(ISSUING_DIST_POINT, distpoint, DIST_POINT_NAME, 0),
420 ASN1_IMP_OPT(ISSUING_DIST_POINT, onlyuser, ASN1_FBOOLEAN, 1),
421 ASN1_IMP_OPT(ISSUING_DIST_POINT, onlyCA, ASN1_FBOOLEAN, 2),
422 ASN1_IMP_OPT(ISSUING_DIST_POINT, onlysomereasons, ASN1_BIT_STRING, 3),
423 ASN1_IMP_OPT(ISSUING_DIST_POINT, indirectCRL, ASN1_FBOOLEAN, 4),
424 ASN1_IMP_OPT(ISSUING_DIST_POINT, onlyattr, ASN1_FBOOLEAN, 5)
425} ASN1_SEQUENCE_END(ISSUING_DIST_POINT)
426
427IMPLEMENT_ASN1_FUNCTIONS(ISSUING_DIST_POINT)
428
429static int i2r_idp(const X509V3_EXT_METHOD *method, void *pidp, BIO *out,
430 int indent);
431static void *v2i_idp(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx,
432 STACK_OF(CONF_VALUE) *nval);
433
434const X509V3_EXT_METHOD v3_idp =
435 {
436 NID_issuing_distribution_point, X509V3_EXT_MULTILINE,
437 ASN1_ITEM_ref(ISSUING_DIST_POINT),
438 0,0,0,0,
439 0,0,
440 0,
441 v2i_idp,
442 i2r_idp,0,
443 NULL
444 };
445
446static void *v2i_idp(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx,
447 STACK_OF(CONF_VALUE) *nval)
448 {
449 ISSUING_DIST_POINT *idp = NULL;
450 CONF_VALUE *cnf;
451 char *name, *val;
452 int i, ret;
453 idp = ISSUING_DIST_POINT_new();
454 if (!idp)
455 goto merr;
456 for(i = 0; i < sk_CONF_VALUE_num(nval); i++)
457 {
458 cnf = sk_CONF_VALUE_value(nval, i);
459 name = cnf->name;
460 val = cnf->value;
461 ret = set_dist_point_name(&idp->distpoint, ctx, cnf);
462 if (ret > 0)
463 continue;
464 if (ret < 0)
465 goto err;
466 if (!strcmp(name, "onlyuser"))
467 {
468 if (!X509V3_get_value_bool(cnf, &idp->onlyuser))
469 goto err;
470 }
471 else if (!strcmp(name, "onlyCA"))
472 {
473 if (!X509V3_get_value_bool(cnf, &idp->onlyCA))
474 goto err;
475 }
476 else if (!strcmp(name, "onlyAA"))
477 {
478 if (!X509V3_get_value_bool(cnf, &idp->onlyattr))
479 goto err;
480 }
481 else if (!strcmp(name, "indirectCRL"))
482 {
483 if (!X509V3_get_value_bool(cnf, &idp->indirectCRL))
484 goto err;
485 }
486 else if (!strcmp(name, "onlysomereasons"))
487 {
488 if (!set_reasons(&idp->onlysomereasons, val))
489 goto err;
490 }
491 else
492 {
493 X509V3err(X509V3_F_V2I_IDP, X509V3_R_INVALID_NAME);
494 X509V3_conf_err(cnf);
495 goto err;
496 }
497 }
498 return idp;
499
500 merr:
501 X509V3err(X509V3_F_V2I_IDP,ERR_R_MALLOC_FAILURE);
502 err:
503 ISSUING_DIST_POINT_free(idp);
504 return NULL;
505 }
506
507static int print_gens(BIO *out, STACK_OF(GENERAL_NAME) *gens, int indent)
508 {
509 int i;
510 for (i = 0; i < sk_GENERAL_NAME_num(gens); i++)
511 {
512 BIO_printf(out, "%*s", indent + 2, "");
513 GENERAL_NAME_print(out, sk_GENERAL_NAME_value(gens, i));
514 BIO_puts(out, "\n");
515 }
516 return 1;
517 }
518
519static int print_distpoint(BIO *out, DIST_POINT_NAME *dpn, int indent)
520 {
521 if (dpn->type == 0)
522 {
523 BIO_printf(out, "%*sFull Name:\n", indent, "");
524 print_gens(out, dpn->name.fullname, indent);
525 }
526 else
527 {
528 X509_NAME ntmp;
529 ntmp.entries = dpn->name.relativename;
530 BIO_printf(out, "%*sRelative Name:\n%*s",
531 indent, "", indent + 2, "");
532 X509_NAME_print_ex(out, &ntmp, 0, XN_FLAG_ONELINE);
533 BIO_puts(out, "\n");
534 }
535 return 1;
536 }
537
538static int i2r_idp(const X509V3_EXT_METHOD *method, void *pidp, BIO *out,
539 int indent)
540 {
541 ISSUING_DIST_POINT *idp = pidp;
542 if (idp->distpoint)
543 print_distpoint(out, idp->distpoint, indent);
544 if (idp->onlyuser > 0)
545 BIO_printf(out, "%*sOnly User Certificates\n", indent, "");
546 if (idp->onlyCA > 0)
547 BIO_printf(out, "%*sOnly CA Certificates\n", indent, "");
548 if (idp->indirectCRL > 0)
549 BIO_printf(out, "%*sIndirect CRL\n", indent, "");
550 if (idp->onlysomereasons)
551 print_reasons(out, "Only Some Reasons",
552 idp->onlysomereasons, indent);
553 if (idp->onlyattr > 0)
554 BIO_printf(out, "%*sOnly Attribute Certificates\n", indent, "");
555 if (!idp->distpoint && (idp->onlyuser <= 0) && (idp->onlyCA <= 0)
556 && (idp->indirectCRL <= 0) && !idp->onlysomereasons
557 && (idp->onlyattr <= 0))
558 BIO_printf(out, "%*s<EMPTY>\n", indent, "");
559
560 return 1;
561 }
562
563static int i2r_crldp(const X509V3_EXT_METHOD *method, void *pcrldp, BIO *out,
564 int indent)
565 {
566 STACK_OF(DIST_POINT) *crld = pcrldp;
567 DIST_POINT *point;
568 int i;
569 for(i = 0; i < sk_DIST_POINT_num(crld); i++)
570 {
571 BIO_puts(out, "\n");
572 point = sk_DIST_POINT_value(crld, i);
573 if(point->distpoint)
574 print_distpoint(out, point->distpoint, indent);
575 if(point->reasons)
576 print_reasons(out, "Reasons", point->reasons,
577 indent);
578 if(point->CRLissuer)
579 {
580 BIO_printf(out, "%*sCRL Issuer:\n", indent, "");
581 print_gens(out, point->CRLissuer, indent);
582 }
583 }
584 return 1;
585 }
586
587int DIST_POINT_set_dpname(DIST_POINT_NAME *dpn, X509_NAME *iname)
588 {
589 int i;
590 STACK_OF(X509_NAME_ENTRY) *frag;
591 X509_NAME_ENTRY *ne;
592 if (!dpn || (dpn->type != 1))
593 return 1;
594 frag = dpn->name.relativename;
595 dpn->dpname = X509_NAME_dup(iname);
596 if (!dpn->dpname)
597 return 0;
598 for (i = 0; i < sk_X509_NAME_ENTRY_num(frag); i++)
599 {
600 ne = sk_X509_NAME_ENTRY_value(frag, i);
601 if (!X509_NAME_add_entry(dpn->dpname, ne, -1, i ? 0 : 1))
602 {
603 X509_NAME_free(dpn->dpname);
604 dpn->dpname = NULL;
605 return 0;
606 }
607 }
608 /* generate cached encoding of name */
609 if (i2d_X509_NAME(dpn->dpname, NULL) < 0)
610 {
611 X509_NAME_free(dpn->dpname);
612 dpn->dpname = NULL;
613 return 0;
614 }
615 return 1;
616 }
diff --git a/src/lib/libcrypto/x509v3/v3_enum.c b/src/lib/libcrypto/x509v3/v3_enum.c
index 36576eaa4d..c0575e368d 100644
--- a/src/lib/libcrypto/x509v3/v3_enum.c
+++ b/src/lib/libcrypto/x509v3/v3_enum.c
@@ -61,14 +61,17 @@
61#include <openssl/x509v3.h> 61#include <openssl/x509v3.h>
62 62
63static ENUMERATED_NAMES crl_reasons[] = { 63static ENUMERATED_NAMES crl_reasons[] = {
64{0, "Unspecified", "unspecified"}, 64{CRL_REASON_UNSPECIFIED, "Unspecified", "unspecified"},
65{1, "Key Compromise", "keyCompromise"}, 65{CRL_REASON_KEY_COMPROMISE, "Key Compromise", "keyCompromise"},
66{2, "CA Compromise", "CACompromise"}, 66{CRL_REASON_CA_COMPROMISE, "CA Compromise", "CACompromise"},
67{3, "Affiliation Changed", "affiliationChanged"}, 67{CRL_REASON_AFFILIATION_CHANGED, "Affiliation Changed", "affiliationChanged"},
68{4, "Superseded", "superseded"}, 68{CRL_REASON_SUPERSEDED, "Superseded", "superseded"},
69{5, "Cessation Of Operation", "cessationOfOperation"}, 69{CRL_REASON_CESSATION_OF_OPERATION,
70{6, "Certificate Hold", "certificateHold"}, 70 "Cessation Of Operation", "cessationOfOperation"},
71{8, "Remove From CRL", "removeFromCRL"}, 71{CRL_REASON_CERTIFICATE_HOLD, "Certificate Hold", "certificateHold"},
72{CRL_REASON_REMOVE_FROM_CRL, "Remove From CRL", "removeFromCRL"},
73{CRL_REASON_PRIVILEGE_WITHDRAWN, "Privilege Withdrawn", "privilegeWithdrawn"},
74{CRL_REASON_AA_COMPROMISE, "AA Compromise", "AACompromise"},
72{-1, NULL, NULL} 75{-1, NULL, NULL}
73}; 76};
74 77
diff --git a/src/lib/libcrypto/x509v3/v3_extku.c b/src/lib/libcrypto/x509v3/v3_extku.c
index c0d14500ed..1c66532757 100644
--- a/src/lib/libcrypto/x509v3/v3_extku.c
+++ b/src/lib/libcrypto/x509v3/v3_extku.c
@@ -63,9 +63,10 @@
63#include <openssl/conf.h> 63#include <openssl/conf.h>
64#include <openssl/x509v3.h> 64#include <openssl/x509v3.h>
65 65
66static void *v2i_EXTENDED_KEY_USAGE(X509V3_EXT_METHOD *method, 66static void *v2i_EXTENDED_KEY_USAGE(const X509V3_EXT_METHOD *method,
67 X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval); 67 X509V3_CTX *ctx,
68static STACK_OF(CONF_VALUE) *i2v_EXTENDED_KEY_USAGE(X509V3_EXT_METHOD *method, 68 STACK_OF(CONF_VALUE) *nval);
69static STACK_OF(CONF_VALUE) *i2v_EXTENDED_KEY_USAGE(const X509V3_EXT_METHOD *method,
69 void *eku, STACK_OF(CONF_VALUE) *extlist); 70 void *eku, STACK_OF(CONF_VALUE) *extlist);
70 71
71const X509V3_EXT_METHOD v3_ext_ku = { 72const X509V3_EXT_METHOD v3_ext_ku = {
@@ -97,8 +98,9 @@ ASN1_ITEM_TEMPLATE_END(EXTENDED_KEY_USAGE)
97 98
98IMPLEMENT_ASN1_FUNCTIONS(EXTENDED_KEY_USAGE) 99IMPLEMENT_ASN1_FUNCTIONS(EXTENDED_KEY_USAGE)
99 100
100static STACK_OF(CONF_VALUE) *i2v_EXTENDED_KEY_USAGE(X509V3_EXT_METHOD *method, 101static STACK_OF(CONF_VALUE) *
101 void *a, STACK_OF(CONF_VALUE) *ext_list) 102 i2v_EXTENDED_KEY_USAGE(const X509V3_EXT_METHOD *method, void *a,
103 STACK_OF(CONF_VALUE) *ext_list)
102{ 104{
103 EXTENDED_KEY_USAGE *eku = a; 105 EXTENDED_KEY_USAGE *eku = a;
104 int i; 106 int i;
@@ -112,8 +114,8 @@ static STACK_OF(CONF_VALUE) *i2v_EXTENDED_KEY_USAGE(X509V3_EXT_METHOD *method,
112 return ext_list; 114 return ext_list;
113} 115}
114 116
115static void *v2i_EXTENDED_KEY_USAGE(X509V3_EXT_METHOD *method, 117static void *v2i_EXTENDED_KEY_USAGE(const X509V3_EXT_METHOD *method,
116 X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval) 118 X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval)
117{ 119{
118 EXTENDED_KEY_USAGE *extku; 120 EXTENDED_KEY_USAGE *extku;
119 char *extval; 121 char *extval;
diff --git a/src/lib/libcrypto/x509v3/v3_genn.c b/src/lib/libcrypto/x509v3/v3_genn.c
index 84b4b1c881..b628357301 100644
--- a/src/lib/libcrypto/x509v3/v3_genn.c
+++ b/src/lib/libcrypto/x509v3/v3_genn.c
@@ -3,7 +3,7 @@
3 * project 1999. 3 * project 1999.
4 */ 4 */
5/* ==================================================================== 5/* ====================================================================
6 * Copyright (c) 1999 The OpenSSL Project. All rights reserved. 6 * Copyright (c) 1999-2008 The OpenSSL Project. All rights reserved.
7 * 7 *
8 * Redistribution and use in source and binary forms, with or without 8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions 9 * modification, are permitted provided that the following conditions
@@ -99,3 +99,154 @@ ASN1_ITEM_TEMPLATE(GENERAL_NAMES) =
99ASN1_ITEM_TEMPLATE_END(GENERAL_NAMES) 99ASN1_ITEM_TEMPLATE_END(GENERAL_NAMES)
100 100
101IMPLEMENT_ASN1_FUNCTIONS(GENERAL_NAMES) 101IMPLEMENT_ASN1_FUNCTIONS(GENERAL_NAMES)
102
103GENERAL_NAME *GENERAL_NAME_dup(GENERAL_NAME *a)
104 {
105 return (GENERAL_NAME *) ASN1_dup((i2d_of_void *) i2d_GENERAL_NAME,
106 (d2i_of_void *) d2i_GENERAL_NAME,
107 (char *) a);
108 }
109
110/* Returns 0 if they are equal, != 0 otherwise. */
111int GENERAL_NAME_cmp(GENERAL_NAME *a, GENERAL_NAME *b)
112 {
113 int result = -1;
114
115 if (!a || !b || a->type != b->type) return -1;
116 switch(a->type)
117 {
118 case GEN_X400:
119 case GEN_EDIPARTY:
120 result = ASN1_TYPE_cmp(a->d.other, b->d.other);
121 break;
122
123 case GEN_OTHERNAME:
124 result = OTHERNAME_cmp(a->d.otherName, b->d.otherName);
125 break;
126
127 case GEN_EMAIL:
128 case GEN_DNS:
129 case GEN_URI:
130 result = ASN1_STRING_cmp(a->d.ia5, b->d.ia5);
131 break;
132
133 case GEN_DIRNAME:
134 result = X509_NAME_cmp(a->d.dirn, b->d.dirn);
135 break;
136
137 case GEN_IPADD:
138 result = ASN1_OCTET_STRING_cmp(a->d.ip, b->d.ip);
139 break;
140
141 case GEN_RID:
142 result = OBJ_cmp(a->d.rid, b->d.rid);
143 break;
144 }
145 return result;
146 }
147
148/* Returns 0 if they are equal, != 0 otherwise. */
149int OTHERNAME_cmp(OTHERNAME *a, OTHERNAME *b)
150 {
151 int result = -1;
152
153 if (!a || !b) return -1;
154 /* Check their type first. */
155 if ((result = OBJ_cmp(a->type_id, b->type_id)) != 0)
156 return result;
157 /* Check the value. */
158 result = ASN1_TYPE_cmp(a->value, b->value);
159 return result;
160 }
161
162void GENERAL_NAME_set0_value(GENERAL_NAME *a, int type, void *value)
163 {
164 switch(type)
165 {
166 case GEN_X400:
167 case GEN_EDIPARTY:
168 a->d.other = value;
169 break;
170
171 case GEN_OTHERNAME:
172 a->d.otherName = value;
173 break;
174
175 case GEN_EMAIL:
176 case GEN_DNS:
177 case GEN_URI:
178 a->d.ia5 = value;
179 break;
180
181 case GEN_DIRNAME:
182 a->d.dirn = value;
183 break;
184
185 case GEN_IPADD:
186 a->d.ip = value;
187 break;
188
189 case GEN_RID:
190 a->d.rid = value;
191 break;
192 }
193 a->type = type;
194 }
195
196void *GENERAL_NAME_get0_value(GENERAL_NAME *a, int *ptype)
197 {
198 if (ptype)
199 *ptype = a->type;
200 switch(a->type)
201 {
202 case GEN_X400:
203 case GEN_EDIPARTY:
204 return a->d.other;
205
206 case GEN_OTHERNAME:
207 return a->d.otherName;
208
209 case GEN_EMAIL:
210 case GEN_DNS:
211 case GEN_URI:
212 return a->d.ia5;
213
214 case GEN_DIRNAME:
215 return a->d.dirn;
216
217 case GEN_IPADD:
218 return a->d.ip;
219
220 case GEN_RID:
221 return a->d.rid;
222
223 default:
224 return NULL;
225 }
226 }
227
228int GENERAL_NAME_set0_othername(GENERAL_NAME *gen,
229 ASN1_OBJECT *oid, ASN1_TYPE *value)
230 {
231 OTHERNAME *oth;
232 oth = OTHERNAME_new();
233 if (!oth)
234 return 0;
235 oth->type_id = oid;
236 oth->value = value;
237 GENERAL_NAME_set0_value(gen, GEN_OTHERNAME, oth);
238 return 1;
239 }
240
241int GENERAL_NAME_get0_otherName(GENERAL_NAME *gen,
242 ASN1_OBJECT **poid, ASN1_TYPE **pvalue)
243 {
244 if (gen->type != GEN_OTHERNAME)
245 return 0;
246 if (poid)
247 *poid = gen->d.otherName->type_id;
248 if (pvalue)
249 *pvalue = gen->d.otherName->value;
250 return 1;
251 }
252
diff --git a/src/lib/libcrypto/x509v3/v3_lib.c b/src/lib/libcrypto/x509v3/v3_lib.c
index df3a48f43e..0f1e1d4422 100644
--- a/src/lib/libcrypto/x509v3/v3_lib.c
+++ b/src/lib/libcrypto/x509v3/v3_lib.c
@@ -84,20 +84,24 @@ int X509V3_EXT_add(X509V3_EXT_METHOD *ext)
84} 84}
85 85
86static int ext_cmp(const X509V3_EXT_METHOD * const *a, 86static int ext_cmp(const X509V3_EXT_METHOD * const *a,
87 const X509V3_EXT_METHOD * const *b) 87 const X509V3_EXT_METHOD * const *b)
88{ 88{
89 return ((*a)->ext_nid - (*b)->ext_nid); 89 return ((*a)->ext_nid - (*b)->ext_nid);
90} 90}
91 91
92X509V3_EXT_METHOD *X509V3_EXT_get_nid(int nid) 92DECLARE_OBJ_BSEARCH_CMP_FN(const X509V3_EXT_METHOD *, const X509V3_EXT_METHOD *,
93 ext);
94IMPLEMENT_OBJ_BSEARCH_CMP_FN(const X509V3_EXT_METHOD *,
95 const X509V3_EXT_METHOD *, ext);
96
97const X509V3_EXT_METHOD *X509V3_EXT_get_nid(int nid)
93{ 98{
94 X509V3_EXT_METHOD tmp, *t = &tmp, **ret; 99 X509V3_EXT_METHOD tmp;
100 const X509V3_EXT_METHOD *t = &tmp, * const *ret;
95 int idx; 101 int idx;
96 if(nid < 0) return NULL; 102 if(nid < 0) return NULL;
97 tmp.ext_nid = nid; 103 tmp.ext_nid = nid;
98 ret = (X509V3_EXT_METHOD **) OBJ_bsearch((char *)&t, 104 ret = OBJ_bsearch_ext(&t, standard_exts, STANDARD_EXTENSION_COUNT);
99 (char *)standard_exts, STANDARD_EXTENSION_COUNT,
100 sizeof(X509V3_EXT_METHOD *), (int (*)(const void *, const void *))ext_cmp);
101 if(ret) return *ret; 105 if(ret) return *ret;
102 if(!ext_list) return NULL; 106 if(!ext_list) return NULL;
103 idx = sk_X509V3_EXT_METHOD_find(ext_list, &tmp); 107 idx = sk_X509V3_EXT_METHOD_find(ext_list, &tmp);
@@ -105,7 +109,7 @@ X509V3_EXT_METHOD *X509V3_EXT_get_nid(int nid)
105 return sk_X509V3_EXT_METHOD_value(ext_list, idx); 109 return sk_X509V3_EXT_METHOD_value(ext_list, idx);
106} 110}
107 111
108X509V3_EXT_METHOD *X509V3_EXT_get(X509_EXTENSION *ext) 112const X509V3_EXT_METHOD *X509V3_EXT_get(X509_EXTENSION *ext)
109{ 113{
110 int nid; 114 int nid;
111 if((nid = OBJ_obj2nid(ext->object)) == NID_undef) return NULL; 115 if((nid = OBJ_obj2nid(ext->object)) == NID_undef) return NULL;
@@ -122,7 +126,9 @@ int X509V3_EXT_add_list(X509V3_EXT_METHOD *extlist)
122 126
123int X509V3_EXT_add_alias(int nid_to, int nid_from) 127int X509V3_EXT_add_alias(int nid_to, int nid_from)
124{ 128{
125 X509V3_EXT_METHOD *ext, *tmpext; 129 const X509V3_EXT_METHOD *ext;
130 X509V3_EXT_METHOD *tmpext;
131
126 if(!(ext = X509V3_EXT_get_nid(nid_from))) { 132 if(!(ext = X509V3_EXT_get_nid(nid_from))) {
127 X509V3err(X509V3_F_X509V3_EXT_ADD_ALIAS,X509V3_R_EXTENSION_NOT_FOUND); 133 X509V3err(X509V3_F_X509V3_EXT_ADD_ALIAS,X509V3_R_EXTENSION_NOT_FOUND);
128 return 0; 134 return 0;
@@ -161,7 +167,7 @@ int X509V3_add_standard_extensions(void)
161 167
162void *X509V3_EXT_d2i(X509_EXTENSION *ext) 168void *X509V3_EXT_d2i(X509_EXTENSION *ext)
163{ 169{
164 X509V3_EXT_METHOD *method; 170 const X509V3_EXT_METHOD *method;
165 const unsigned char *p; 171 const unsigned char *p;
166 172
167 if(!(method = X509V3_EXT_get(ext))) return NULL; 173 if(!(method = X509V3_EXT_get(ext))) return NULL;
diff --git a/src/lib/libcrypto/x509v3/v3_ncons.c b/src/lib/libcrypto/x509v3/v3_ncons.c
index 4e706be3e1..689df46acd 100644
--- a/src/lib/libcrypto/x509v3/v3_ncons.c
+++ b/src/lib/libcrypto/x509v3/v3_ncons.c
@@ -63,15 +63,22 @@
63#include <openssl/conf.h> 63#include <openssl/conf.h>
64#include <openssl/x509v3.h> 64#include <openssl/x509v3.h>
65 65
66static void *v2i_NAME_CONSTRAINTS(X509V3_EXT_METHOD *method, 66static void *v2i_NAME_CONSTRAINTS(const X509V3_EXT_METHOD *method,
67 X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval); 67 X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval);
68static int i2r_NAME_CONSTRAINTS(X509V3_EXT_METHOD *method, 68static int i2r_NAME_CONSTRAINTS(const X509V3_EXT_METHOD *method,
69 void *a, BIO *bp, int ind); 69 void *a, BIO *bp, int ind);
70static int do_i2r_name_constraints(X509V3_EXT_METHOD *method, 70static int do_i2r_name_constraints(const X509V3_EXT_METHOD *method,
71 STACK_OF(GENERAL_SUBTREE) *trees, 71 STACK_OF(GENERAL_SUBTREE) *trees,
72 BIO *bp, int ind, char *name); 72 BIO *bp, int ind, char *name);
73static int print_nc_ipadd(BIO *bp, ASN1_OCTET_STRING *ip); 73static int print_nc_ipadd(BIO *bp, ASN1_OCTET_STRING *ip);
74 74
75static int nc_match(GENERAL_NAME *gen, NAME_CONSTRAINTS *nc);
76static int nc_match_single(GENERAL_NAME *sub, GENERAL_NAME *gen);
77static int nc_dn(X509_NAME *sub, X509_NAME *nm);
78static int nc_dns(ASN1_IA5STRING *sub, ASN1_IA5STRING *dns);
79static int nc_email(ASN1_IA5STRING *sub, ASN1_IA5STRING *eml);
80static int nc_uri(ASN1_IA5STRING *uri, ASN1_IA5STRING *base);
81
75const X509V3_EXT_METHOD v3_name_constraints = { 82const X509V3_EXT_METHOD v3_name_constraints = {
76 NID_name_constraints, 0, 83 NID_name_constraints, 0,
77 ASN1_ITEM_ref(NAME_CONSTRAINTS), 84 ASN1_ITEM_ref(NAME_CONSTRAINTS),
@@ -99,8 +106,8 @@ ASN1_SEQUENCE(NAME_CONSTRAINTS) = {
99IMPLEMENT_ASN1_ALLOC_FUNCTIONS(GENERAL_SUBTREE) 106IMPLEMENT_ASN1_ALLOC_FUNCTIONS(GENERAL_SUBTREE)
100IMPLEMENT_ASN1_ALLOC_FUNCTIONS(NAME_CONSTRAINTS) 107IMPLEMENT_ASN1_ALLOC_FUNCTIONS(NAME_CONSTRAINTS)
101 108
102static void *v2i_NAME_CONSTRAINTS(X509V3_EXT_METHOD *method, 109static void *v2i_NAME_CONSTRAINTS(const X509V3_EXT_METHOD *method,
103 X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval) 110 X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval)
104 { 111 {
105 int i; 112 int i;
106 CONF_VALUE tval, *val; 113 CONF_VALUE tval, *val;
@@ -155,8 +162,8 @@ static void *v2i_NAME_CONSTRAINTS(X509V3_EXT_METHOD *method,
155 162
156 163
157 164
158static int i2r_NAME_CONSTRAINTS(X509V3_EXT_METHOD *method, 165static int i2r_NAME_CONSTRAINTS(const X509V3_EXT_METHOD *method, void *a,
159 void *a, BIO *bp, int ind) 166 BIO *bp, int ind)
160 { 167 {
161 NAME_CONSTRAINTS *ncons = a; 168 NAME_CONSTRAINTS *ncons = a;
162 do_i2r_name_constraints(method, ncons->permittedSubtrees, 169 do_i2r_name_constraints(method, ncons->permittedSubtrees,
@@ -166,9 +173,9 @@ static int i2r_NAME_CONSTRAINTS(X509V3_EXT_METHOD *method,
166 return 1; 173 return 1;
167 } 174 }
168 175
169static int do_i2r_name_constraints(X509V3_EXT_METHOD *method, 176static int do_i2r_name_constraints(const X509V3_EXT_METHOD *method,
170 STACK_OF(GENERAL_SUBTREE) *trees, 177 STACK_OF(GENERAL_SUBTREE) *trees,
171 BIO *bp, int ind, char *name) 178 BIO *bp, int ind, char *name)
172 { 179 {
173 GENERAL_SUBTREE *tree; 180 GENERAL_SUBTREE *tree;
174 int i; 181 int i;
@@ -218,3 +225,282 @@ static int print_nc_ipadd(BIO *bp, ASN1_OCTET_STRING *ip)
218 return 1; 225 return 1;
219 } 226 }
220 227
228/* Check a certificate conforms to a specified set of constraints.
229 * Return values:
230 * X509_V_OK: All constraints obeyed.
231 * X509_V_ERR_PERMITTED_VIOLATION: Permitted subtree violation.
232 * X509_V_ERR_EXCLUDED_VIOLATION: Excluded subtree violation.
233 * X509_V_ERR_SUBTREE_MINMAX: Min or max values present and matching type.
234 * X509_V_ERR_UNSUPPORTED_CONSTRAINT_TYPE: Unsupported constraint type.
235 * X509_V_ERR_UNSUPPORTED_CONSTRAINT_SYNTAX: bad unsupported constraint syntax.
236 * X509_V_ERR_UNSUPPORTED_NAME_SYNTAX: bad or unsupported syntax of name
237
238 */
239
240int NAME_CONSTRAINTS_check(X509 *x, NAME_CONSTRAINTS *nc)
241 {
242 int r, i;
243 X509_NAME *nm;
244
245 nm = X509_get_subject_name(x);
246
247 if (X509_NAME_entry_count(nm) > 0)
248 {
249 GENERAL_NAME gntmp;
250 gntmp.type = GEN_DIRNAME;
251 gntmp.d.directoryName = nm;
252
253 r = nc_match(&gntmp, nc);
254
255 if (r != X509_V_OK)
256 return r;
257
258 gntmp.type = GEN_EMAIL;
259
260
261 /* Process any email address attributes in subject name */
262
263 for (i = -1;;)
264 {
265 X509_NAME_ENTRY *ne;
266 i = X509_NAME_get_index_by_NID(nm,
267 NID_pkcs9_emailAddress,
268 i);
269 if (i == -1)
270 break;
271 ne = X509_NAME_get_entry(nm, i);
272 gntmp.d.rfc822Name = X509_NAME_ENTRY_get_data(ne);
273 if (gntmp.d.rfc822Name->type != V_ASN1_IA5STRING)
274 return X509_V_ERR_UNSUPPORTED_NAME_SYNTAX;
275
276 r = nc_match(&gntmp, nc);
277
278 if (r != X509_V_OK)
279 return r;
280 }
281
282 }
283
284 for (i = 0; i < sk_GENERAL_NAME_num(x->altname); i++)
285 {
286 GENERAL_NAME *gen = sk_GENERAL_NAME_value(x->altname, i);
287 r = nc_match(gen, nc);
288 if (r != X509_V_OK)
289 return r;
290 }
291
292 return X509_V_OK;
293
294 }
295
296static int nc_match(GENERAL_NAME *gen, NAME_CONSTRAINTS *nc)
297 {
298 GENERAL_SUBTREE *sub;
299 int i, r, match = 0;
300
301 /* Permitted subtrees: if any subtrees exist of matching the type
302 * at least one subtree must match.
303 */
304
305 for (i = 0; i < sk_GENERAL_SUBTREE_num(nc->permittedSubtrees); i++)
306 {
307 sub = sk_GENERAL_SUBTREE_value(nc->permittedSubtrees, i);
308 if (gen->type != sub->base->type)
309 continue;
310 if (sub->minimum || sub->maximum)
311 return X509_V_ERR_SUBTREE_MINMAX;
312 /* If we already have a match don't bother trying any more */
313 if (match == 2)
314 continue;
315 if (match == 0)
316 match = 1;
317 r = nc_match_single(gen, sub->base);
318 if (r == X509_V_OK)
319 match = 2;
320 else if (r != X509_V_ERR_PERMITTED_VIOLATION)
321 return r;
322 }
323
324 if (match == 1)
325 return X509_V_ERR_PERMITTED_VIOLATION;
326
327 /* Excluded subtrees: must not match any of these */
328
329 for (i = 0; i < sk_GENERAL_SUBTREE_num(nc->excludedSubtrees); i++)
330 {
331 sub = sk_GENERAL_SUBTREE_value(nc->excludedSubtrees, i);
332 if (gen->type != sub->base->type)
333 continue;
334 if (sub->minimum || sub->maximum)
335 return X509_V_ERR_SUBTREE_MINMAX;
336
337 r = nc_match_single(gen, sub->base);
338 if (r == X509_V_OK)
339 return X509_V_ERR_EXCLUDED_VIOLATION;
340 else if (r != X509_V_ERR_PERMITTED_VIOLATION)
341 return r;
342
343 }
344
345 return X509_V_OK;
346
347 }
348
349static int nc_match_single(GENERAL_NAME *gen, GENERAL_NAME *base)
350 {
351 switch(base->type)
352 {
353 case GEN_DIRNAME:
354 return nc_dn(gen->d.directoryName, base->d.directoryName);
355
356 case GEN_DNS:
357 return nc_dns(gen->d.dNSName, base->d.dNSName);
358
359 case GEN_EMAIL:
360 return nc_email(gen->d.rfc822Name, base->d.rfc822Name);
361
362 case GEN_URI:
363 return nc_uri(gen->d.uniformResourceIdentifier,
364 base->d.uniformResourceIdentifier);
365
366 default:
367 return X509_V_ERR_UNSUPPORTED_CONSTRAINT_TYPE;
368 }
369
370 }
371
372/* directoryName name constraint matching.
373 * The canonical encoding of X509_NAME makes this comparison easy. It is
374 * matched if the subtree is a subset of the name.
375 */
376
377static int nc_dn(X509_NAME *nm, X509_NAME *base)
378 {
379 /* Ensure canonical encodings are up to date. */
380 if (nm->modified && i2d_X509_NAME(nm, NULL) < 0)
381 return X509_V_ERR_OUT_OF_MEM;
382 if (base->modified && i2d_X509_NAME(base, NULL) < 0)
383 return X509_V_ERR_OUT_OF_MEM;
384 if (base->canon_enclen > nm->canon_enclen)
385 return X509_V_ERR_PERMITTED_VIOLATION;
386 if (memcmp(base->canon_enc, nm->canon_enc, base->canon_enclen))
387 return X509_V_ERR_PERMITTED_VIOLATION;
388 return X509_V_OK;
389 }
390
391static int nc_dns(ASN1_IA5STRING *dns, ASN1_IA5STRING *base)
392 {
393 char *baseptr = (char *)base->data;
394 char *dnsptr = (char *)dns->data;
395 /* Empty matches everything */
396 if (!*baseptr)
397 return X509_V_OK;
398 /* Otherwise can add zero or more components on the left so
399 * compare RHS and if dns is longer and expect '.' as preceding
400 * character.
401 */
402 if (dns->length > base->length)
403 {
404 dnsptr += dns->length - base->length;
405 if (dnsptr[-1] != '.')
406 return X509_V_ERR_PERMITTED_VIOLATION;
407 }
408
409 if (strcasecmp(baseptr, dnsptr))
410 return X509_V_ERR_PERMITTED_VIOLATION;
411
412 return X509_V_OK;
413
414 }
415
416static int nc_email(ASN1_IA5STRING *eml, ASN1_IA5STRING *base)
417 {
418 const char *baseptr = (char *)base->data;
419 const char *emlptr = (char *)eml->data;
420
421 const char *baseat = strchr(baseptr, '@');
422 const char *emlat = strchr(emlptr, '@');
423 if (!emlat)
424 return X509_V_ERR_UNSUPPORTED_NAME_SYNTAX;
425 /* Special case: inital '.' is RHS match */
426 if (!baseat && (*baseptr == '.'))
427 {
428 if (eml->length > base->length)
429 {
430 emlptr += eml->length - base->length;
431 if (!strcasecmp(baseptr, emlptr))
432 return X509_V_OK;
433 }
434 return X509_V_ERR_PERMITTED_VIOLATION;
435 }
436
437 /* If we have anything before '@' match local part */
438
439 if (baseat)
440 {
441 if (baseat != baseptr)
442 {
443 if ((baseat - baseptr) != (emlat - emlptr))
444 return X509_V_ERR_PERMITTED_VIOLATION;
445 /* Case sensitive match of local part */
446 if (strncmp(baseptr, emlptr, emlat - emlptr))
447 return X509_V_ERR_PERMITTED_VIOLATION;
448 }
449 /* Position base after '@' */
450 baseptr = baseat + 1;
451 }
452 emlptr = emlat + 1;
453 /* Just have hostname left to match: case insensitive */
454 if (strcasecmp(baseptr, emlptr))
455 return X509_V_ERR_PERMITTED_VIOLATION;
456
457 return X509_V_OK;
458
459 }
460
461static int nc_uri(ASN1_IA5STRING *uri, ASN1_IA5STRING *base)
462 {
463 const char *baseptr = (char *)base->data;
464 const char *hostptr = (char *)uri->data;
465 const char *p = strchr(hostptr, ':');
466 int hostlen;
467 /* Check for foo:// and skip past it */
468 if (!p || (p[1] != '/') || (p[2] != '/'))
469 return X509_V_ERR_UNSUPPORTED_NAME_SYNTAX;
470 hostptr = p + 3;
471
472 /* Determine length of hostname part of URI */
473
474 /* Look for a port indicator as end of hostname first */
475
476 p = strchr(hostptr, ':');
477 /* Otherwise look for trailing slash */
478 if (!p)
479 p = strchr(hostptr, '/');
480
481 if (!p)
482 hostlen = strlen(hostptr);
483 else
484 hostlen = p - hostptr;
485
486 if (hostlen == 0)
487 return X509_V_ERR_UNSUPPORTED_NAME_SYNTAX;
488
489 /* Special case: inital '.' is RHS match */
490 if (*baseptr == '.')
491 {
492 if (hostlen > base->length)
493 {
494 p = hostptr + hostlen - base->length;
495 if (!strncasecmp(p, baseptr, base->length))
496 return X509_V_OK;
497 }
498 return X509_V_ERR_PERMITTED_VIOLATION;
499 }
500
501 if ((base->length != (int)hostlen) || strncasecmp(hostptr, baseptr, hostlen))
502 return X509_V_ERR_PERMITTED_VIOLATION;
503
504 return X509_V_OK;
505
506 }
diff --git a/src/lib/libcrypto/x509v3/v3_ocsp.c b/src/lib/libcrypto/x509v3/v3_ocsp.c
index e426ea930c..0c165af314 100644
--- a/src/lib/libcrypto/x509v3/v3_ocsp.c
+++ b/src/lib/libcrypto/x509v3/v3_ocsp.c
@@ -68,19 +68,26 @@
68/* OCSP extensions and a couple of CRL entry extensions 68/* OCSP extensions and a couple of CRL entry extensions
69 */ 69 */
70 70
71static int i2r_ocsp_crlid(X509V3_EXT_METHOD *method, void *nonce, BIO *out, int indent); 71static int i2r_ocsp_crlid(const X509V3_EXT_METHOD *method, void *nonce,
72static int i2r_ocsp_acutoff(X509V3_EXT_METHOD *method, void *nonce, BIO *out, int indent); 72 BIO *out, int indent);
73static int i2r_object(X509V3_EXT_METHOD *method, void *obj, BIO *out, int indent); 73static int i2r_ocsp_acutoff(const X509V3_EXT_METHOD *method, void *nonce,
74 BIO *out, int indent);
75static int i2r_object(const X509V3_EXT_METHOD *method, void *obj, BIO *out,
76 int indent);
74 77
75static void *ocsp_nonce_new(void); 78static void *ocsp_nonce_new(void);
76static int i2d_ocsp_nonce(void *a, unsigned char **pp); 79static int i2d_ocsp_nonce(void *a, unsigned char **pp);
77static void *d2i_ocsp_nonce(void *a, const unsigned char **pp, long length); 80static void *d2i_ocsp_nonce(void *a, const unsigned char **pp, long length);
78static void ocsp_nonce_free(void *a); 81static void ocsp_nonce_free(void *a);
79static int i2r_ocsp_nonce(X509V3_EXT_METHOD *method, void *nonce, BIO *out, int indent); 82static int i2r_ocsp_nonce(const X509V3_EXT_METHOD *method, void *nonce,
83 BIO *out, int indent);
80 84
81static int i2r_ocsp_nocheck(X509V3_EXT_METHOD *method, void *nocheck, BIO *out, int indent); 85static int i2r_ocsp_nocheck(const X509V3_EXT_METHOD *method,
82static void *s2i_ocsp_nocheck(X509V3_EXT_METHOD *method, X509V3_CTX *ctx, const char *str); 86 void *nocheck, BIO *out, int indent);
83static int i2r_ocsp_serviceloc(X509V3_EXT_METHOD *method, void *in, BIO *bp, int ind); 87static void *s2i_ocsp_nocheck(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx,
88 const char *str);
89static int i2r_ocsp_serviceloc(const X509V3_EXT_METHOD *method, void *in,
90 BIO *bp, int ind);
84 91
85const X509V3_EXT_METHOD v3_ocsp_crlid = { 92const X509V3_EXT_METHOD v3_ocsp_crlid = {
86 NID_id_pkix_OCSP_CrlID, 0, ASN1_ITEM_ref(OCSP_CRLID), 93 NID_id_pkix_OCSP_CrlID, 0, ASN1_ITEM_ref(OCSP_CRLID),
@@ -148,44 +155,47 @@ const X509V3_EXT_METHOD v3_ocsp_serviceloc = {
148 NULL 155 NULL
149}; 156};
150 157
151static int i2r_ocsp_crlid(X509V3_EXT_METHOD *method, void *in, BIO *bp, int ind) 158static int i2r_ocsp_crlid(const X509V3_EXT_METHOD *method, void *in, BIO *bp,
159 int ind)
152{ 160{
153 OCSP_CRLID *a = in; 161 OCSP_CRLID *a = in;
154 if (a->crlUrl) 162 if (a->crlUrl)
155 { 163 {
156 if (!BIO_printf(bp, "%*scrlUrl: ", ind, "")) goto err; 164 if (BIO_printf(bp, "%*scrlUrl: ", ind, "") <= 0) goto err;
157 if (!ASN1_STRING_print(bp, (ASN1_STRING*)a->crlUrl)) goto err; 165 if (!ASN1_STRING_print(bp, (ASN1_STRING*)a->crlUrl)) goto err;
158 if (!BIO_write(bp, "\n", 1)) goto err; 166 if (BIO_write(bp, "\n", 1) <= 0) goto err;
159 } 167 }
160 if (a->crlNum) 168 if (a->crlNum)
161 { 169 {
162 if (!BIO_printf(bp, "%*scrlNum: ", ind, "")) goto err; 170 if (BIO_printf(bp, "%*scrlNum: ", ind, "") <= 0) goto err;
163 if (!i2a_ASN1_INTEGER(bp, a->crlNum)) goto err; 171 if (i2a_ASN1_INTEGER(bp, a->crlNum) <= 0) goto err;
164 if (!BIO_write(bp, "\n", 1)) goto err; 172 if (BIO_write(bp, "\n", 1) <= 0) goto err;
165 } 173 }
166 if (a->crlTime) 174 if (a->crlTime)
167 { 175 {
168 if (!BIO_printf(bp, "%*scrlTime: ", ind, "")) goto err; 176 if (BIO_printf(bp, "%*scrlTime: ", ind, "") <= 0) goto err;
169 if (!ASN1_GENERALIZEDTIME_print(bp, a->crlTime)) goto err; 177 if (!ASN1_GENERALIZEDTIME_print(bp, a->crlTime)) goto err;
170 if (!BIO_write(bp, "\n", 1)) goto err; 178 if (BIO_write(bp, "\n", 1) <= 0) goto err;
171 } 179 }
172 return 1; 180 return 1;
173 err: 181 err:
174 return 0; 182 return 0;
175} 183}
176 184
177static int i2r_ocsp_acutoff(X509V3_EXT_METHOD *method, void *cutoff, BIO *bp, int ind) 185static int i2r_ocsp_acutoff(const X509V3_EXT_METHOD *method, void *cutoff,
186 BIO *bp, int ind)
178{ 187{
179 if (!BIO_printf(bp, "%*s", ind, "")) return 0; 188 if (BIO_printf(bp, "%*s", ind, "") <= 0) return 0;
180 if(!ASN1_GENERALIZEDTIME_print(bp, cutoff)) return 0; 189 if(!ASN1_GENERALIZEDTIME_print(bp, cutoff)) return 0;
181 return 1; 190 return 1;
182} 191}
183 192
184 193
185static int i2r_object(X509V3_EXT_METHOD *method, void *oid, BIO *bp, int ind) 194static int i2r_object(const X509V3_EXT_METHOD *method, void *oid, BIO *bp,
195 int ind)
186{ 196{
187 if (!BIO_printf(bp, "%*s", ind, "")) return 0; 197 if (BIO_printf(bp, "%*s", ind, "") <= 0) return 0;
188 if(!i2a_ASN1_OBJECT(bp, oid)) return 0; 198 if(i2a_ASN1_OBJECT(bp, oid) <= 0) return 0;
189 return 1; 199 return 1;
190} 200}
191 201
@@ -232,7 +242,8 @@ static void ocsp_nonce_free(void *a)
232 M_ASN1_OCTET_STRING_free(a); 242 M_ASN1_OCTET_STRING_free(a);
233} 243}
234 244
235static int i2r_ocsp_nonce(X509V3_EXT_METHOD *method, void *nonce, BIO *out, int indent) 245static int i2r_ocsp_nonce(const X509V3_EXT_METHOD *method, void *nonce,
246 BIO *out, int indent)
236{ 247{
237 if(BIO_printf(out, "%*s", indent, "") <= 0) return 0; 248 if(BIO_printf(out, "%*s", indent, "") <= 0) return 0;
238 if(i2a_ASN1_STRING(out, nonce, V_ASN1_OCTET_STRING) <= 0) return 0; 249 if(i2a_ASN1_STRING(out, nonce, V_ASN1_OCTET_STRING) <= 0) return 0;
@@ -241,17 +252,20 @@ static int i2r_ocsp_nonce(X509V3_EXT_METHOD *method, void *nonce, BIO *out, int
241 252
242/* Nocheck is just a single NULL. Don't print anything and always set it */ 253/* Nocheck is just a single NULL. Don't print anything and always set it */
243 254
244static int i2r_ocsp_nocheck(X509V3_EXT_METHOD *method, void *nocheck, BIO *out, int indent) 255static int i2r_ocsp_nocheck(const X509V3_EXT_METHOD *method, void *nocheck,
256 BIO *out, int indent)
245{ 257{
246 return 1; 258 return 1;
247} 259}
248 260
249static void *s2i_ocsp_nocheck(X509V3_EXT_METHOD *method, X509V3_CTX *ctx, const char *str) 261static void *s2i_ocsp_nocheck(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx,
262 const char *str)
250{ 263{
251 return ASN1_NULL_new(); 264 return ASN1_NULL_new();
252} 265}
253 266
254static int i2r_ocsp_serviceloc(X509V3_EXT_METHOD *method, void *in, BIO *bp, int ind) 267static int i2r_ocsp_serviceloc(const X509V3_EXT_METHOD *method, void *in,
268 BIO *bp, int ind)
255 { 269 {
256 int i; 270 int i;
257 OCSP_SERVICELOC *a = in; 271 OCSP_SERVICELOC *a = in;
diff --git a/src/lib/libcrypto/x509v3/v3_pci.c b/src/lib/libcrypto/x509v3/v3_pci.c
index 601211f416..0dcfa004fe 100644
--- a/src/lib/libcrypto/x509v3/v3_pci.c
+++ b/src/lib/libcrypto/x509v3/v3_pci.c
@@ -82,7 +82,7 @@ static int process_pci_value(CONF_VALUE *val,
82 { 82 {
83 if (*language) 83 if (*language)
84 { 84 {
85 X509V3err(X509V3_F_PROCESS_PCI_VALUE,X509V3_R_POLICY_LANGUAGE_ALREADTY_DEFINED); 85 X509V3err(X509V3_F_PROCESS_PCI_VALUE,X509V3_R_POLICY_LANGUAGE_ALREADY_DEFINED);
86 X509V3_conf_err(val); 86 X509V3_conf_err(val);
87 return 0; 87 return 0;
88 } 88 }
@@ -97,7 +97,7 @@ static int process_pci_value(CONF_VALUE *val,
97 { 97 {
98 if (*pathlen) 98 if (*pathlen)
99 { 99 {
100 X509V3err(X509V3_F_PROCESS_PCI_VALUE,X509V3_R_POLICY_PATH_LENGTH_ALREADTY_DEFINED); 100 X509V3err(X509V3_F_PROCESS_PCI_VALUE,X509V3_R_POLICY_PATH_LENGTH_ALREADY_DEFINED);
101 X509V3_conf_err(val); 101 X509V3_conf_err(val);
102 return 0; 102 return 0;
103 } 103 }
@@ -128,7 +128,12 @@ static int process_pci_value(CONF_VALUE *val,
128 unsigned char *tmp_data2 = 128 unsigned char *tmp_data2 =
129 string_to_hex(val->value + 4, &val_len); 129 string_to_hex(val->value + 4, &val_len);
130 130
131 if (!tmp_data2) goto err; 131 if (!tmp_data2)
132 {
133 X509V3err(X509V3_F_PROCESS_PCI_VALUE,X509V3_R_ILLEGAL_HEX_DIGIT);
134 X509V3_conf_err(val);
135 goto err;
136 }
132 137
133 tmp_data = OPENSSL_realloc((*policy)->data, 138 tmp_data = OPENSSL_realloc((*policy)->data,
134 (*policy)->length + val_len + 1); 139 (*policy)->length + val_len + 1);
@@ -140,6 +145,17 @@ static int process_pci_value(CONF_VALUE *val,
140 (*policy)->length += val_len; 145 (*policy)->length += val_len;
141 (*policy)->data[(*policy)->length] = '\0'; 146 (*policy)->data[(*policy)->length] = '\0';
142 } 147 }
148 else
149 {
150 OPENSSL_free(tmp_data2);
151 /* realloc failure implies the original data space is b0rked too! */
152 (*policy)->data = NULL;
153 (*policy)->length = 0;
154 X509V3err(X509V3_F_PROCESS_PCI_VALUE,ERR_R_MALLOC_FAILURE);
155 X509V3_conf_err(val);
156 goto err;
157 }
158 OPENSSL_free(tmp_data2);
143 } 159 }
144 else if (strncmp(val->value, "file:", 5) == 0) 160 else if (strncmp(val->value, "file:", 5) == 0)
145 { 161 {
@@ -169,6 +185,7 @@ static int process_pci_value(CONF_VALUE *val,
169 (*policy)->length += n; 185 (*policy)->length += n;
170 (*policy)->data[(*policy)->length] = '\0'; 186 (*policy)->data[(*policy)->length] = '\0';
171 } 187 }
188 BIO_free_all(b);
172 189
173 if (n < 0) 190 if (n < 0)
174 { 191 {
@@ -190,6 +207,15 @@ static int process_pci_value(CONF_VALUE *val,
190 (*policy)->length += val_len; 207 (*policy)->length += val_len;
191 (*policy)->data[(*policy)->length] = '\0'; 208 (*policy)->data[(*policy)->length] = '\0';
192 } 209 }
210 else
211 {
212 /* realloc failure implies the original data space is b0rked too! */
213 (*policy)->data = NULL;
214 (*policy)->length = 0;
215 X509V3err(X509V3_F_PROCESS_PCI_VALUE,ERR_R_MALLOC_FAILURE);
216 X509V3_conf_err(val);
217 goto err;
218 }
193 } 219 }
194 else 220 else
195 { 221 {
diff --git a/src/lib/libcrypto/x509v3/v3_pcons.c b/src/lib/libcrypto/x509v3/v3_pcons.c
index 86c0ff70e6..30ca652351 100644
--- a/src/lib/libcrypto/x509v3/v3_pcons.c
+++ b/src/lib/libcrypto/x509v3/v3_pcons.c
@@ -64,10 +64,12 @@
64#include <openssl/conf.h> 64#include <openssl/conf.h>
65#include <openssl/x509v3.h> 65#include <openssl/x509v3.h>
66 66
67static STACK_OF(CONF_VALUE) *i2v_POLICY_CONSTRAINTS(X509V3_EXT_METHOD *method, 67static STACK_OF(CONF_VALUE) *
68 void *bcons, STACK_OF(CONF_VALUE) *extlist); 68i2v_POLICY_CONSTRAINTS(const X509V3_EXT_METHOD *method, void *bcons,
69static void *v2i_POLICY_CONSTRAINTS(X509V3_EXT_METHOD *method, 69 STACK_OF(CONF_VALUE) *extlist);
70 X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *values); 70static void *v2i_POLICY_CONSTRAINTS(const X509V3_EXT_METHOD *method,
71 X509V3_CTX *ctx,
72 STACK_OF(CONF_VALUE) *values);
71 73
72const X509V3_EXT_METHOD v3_policy_constraints = { 74const X509V3_EXT_METHOD v3_policy_constraints = {
73NID_policy_constraints, 0, 75NID_policy_constraints, 0,
@@ -88,8 +90,9 @@ ASN1_SEQUENCE(POLICY_CONSTRAINTS) = {
88IMPLEMENT_ASN1_ALLOC_FUNCTIONS(POLICY_CONSTRAINTS) 90IMPLEMENT_ASN1_ALLOC_FUNCTIONS(POLICY_CONSTRAINTS)
89 91
90 92
91static STACK_OF(CONF_VALUE) *i2v_POLICY_CONSTRAINTS(X509V3_EXT_METHOD *method, 93static STACK_OF(CONF_VALUE) *
92 void *a, STACK_OF(CONF_VALUE) *extlist) 94i2v_POLICY_CONSTRAINTS(const X509V3_EXT_METHOD *method, void *a,
95 STACK_OF(CONF_VALUE) *extlist)
93{ 96{
94 POLICY_CONSTRAINTS *pcons = a; 97 POLICY_CONSTRAINTS *pcons = a;
95 X509V3_add_value_int("Require Explicit Policy", 98 X509V3_add_value_int("Require Explicit Policy",
@@ -99,8 +102,9 @@ static STACK_OF(CONF_VALUE) *i2v_POLICY_CONSTRAINTS(X509V3_EXT_METHOD *method,
99 return extlist; 102 return extlist;
100} 103}
101 104
102static void *v2i_POLICY_CONSTRAINTS(X509V3_EXT_METHOD *method, 105static void *v2i_POLICY_CONSTRAINTS(const X509V3_EXT_METHOD *method,
103 X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *values) 106 X509V3_CTX *ctx,
107 STACK_OF(CONF_VALUE) *values)
104{ 108{
105 POLICY_CONSTRAINTS *pcons=NULL; 109 POLICY_CONSTRAINTS *pcons=NULL;
106 CONF_VALUE *val; 110 CONF_VALUE *val;
diff --git a/src/lib/libcrypto/x509v3/v3_pmaps.c b/src/lib/libcrypto/x509v3/v3_pmaps.c
index da03bbc35d..865bcd3980 100644
--- a/src/lib/libcrypto/x509v3/v3_pmaps.c
+++ b/src/lib/libcrypto/x509v3/v3_pmaps.c
@@ -63,10 +63,11 @@
63#include <openssl/conf.h> 63#include <openssl/conf.h>
64#include <openssl/x509v3.h> 64#include <openssl/x509v3.h>
65 65
66static void *v2i_POLICY_MAPPINGS(X509V3_EXT_METHOD *method, 66static void *v2i_POLICY_MAPPINGS(const X509V3_EXT_METHOD *method,
67 X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval); 67 X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval);
68static STACK_OF(CONF_VALUE) *i2v_POLICY_MAPPINGS(X509V3_EXT_METHOD *method, 68static STACK_OF(CONF_VALUE) *
69 void *pmps, STACK_OF(CONF_VALUE) *extlist); 69i2v_POLICY_MAPPINGS(const X509V3_EXT_METHOD *method, void *pmps,
70 STACK_OF(CONF_VALUE) *extlist);
70 71
71const X509V3_EXT_METHOD v3_policy_mappings = { 72const X509V3_EXT_METHOD v3_policy_mappings = {
72 NID_policy_mappings, 0, 73 NID_policy_mappings, 0,
@@ -92,8 +93,9 @@ ASN1_ITEM_TEMPLATE_END(POLICY_MAPPINGS)
92IMPLEMENT_ASN1_ALLOC_FUNCTIONS(POLICY_MAPPING) 93IMPLEMENT_ASN1_ALLOC_FUNCTIONS(POLICY_MAPPING)
93 94
94 95
95static STACK_OF(CONF_VALUE) *i2v_POLICY_MAPPINGS(X509V3_EXT_METHOD *method, 96static STACK_OF(CONF_VALUE) *
96 void *a, STACK_OF(CONF_VALUE) *ext_list) 97i2v_POLICY_MAPPINGS(const X509V3_EXT_METHOD *method, void *a,
98 STACK_OF(CONF_VALUE) *ext_list)
97{ 99{
98 POLICY_MAPPINGS *pmaps = a; 100 POLICY_MAPPINGS *pmaps = a;
99 POLICY_MAPPING *pmap; 101 POLICY_MAPPING *pmap;
@@ -109,8 +111,8 @@ static STACK_OF(CONF_VALUE) *i2v_POLICY_MAPPINGS(X509V3_EXT_METHOD *method,
109 return ext_list; 111 return ext_list;
110} 112}
111 113
112static void *v2i_POLICY_MAPPINGS(X509V3_EXT_METHOD *method, 114static void *v2i_POLICY_MAPPINGS(const X509V3_EXT_METHOD *method,
113 X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval) 115 X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval)
114{ 116{
115 POLICY_MAPPINGS *pmaps; 117 POLICY_MAPPINGS *pmaps;
116 POLICY_MAPPING *pmap; 118 POLICY_MAPPING *pmap;
diff --git a/src/lib/libcrypto/x509v3/v3_prn.c b/src/lib/libcrypto/x509v3/v3_prn.c
index c1bb17f105..3146218708 100644
--- a/src/lib/libcrypto/x509v3/v3_prn.c
+++ b/src/lib/libcrypto/x509v3/v3_prn.c
@@ -110,7 +110,7 @@ int X509V3_EXT_print(BIO *out, X509_EXTENSION *ext, unsigned long flag, int inde
110 void *ext_str = NULL; 110 void *ext_str = NULL;
111 char *value = NULL; 111 char *value = NULL;
112 const unsigned char *p; 112 const unsigned char *p;
113 X509V3_EXT_METHOD *method; 113 const X509V3_EXT_METHOD *method;
114 STACK_OF(CONF_VALUE) *nval = NULL; 114 STACK_OF(CONF_VALUE) *nval = NULL;
115 int ok = 1; 115 int ok = 1;
116 116
diff --git a/src/lib/libcrypto/x509v3/v3_purp.c b/src/lib/libcrypto/x509v3/v3_purp.c
index e18751e01c..181bd34979 100644
--- a/src/lib/libcrypto/x509v3/v3_purp.c
+++ b/src/lib/libcrypto/x509v3/v3_purp.c
@@ -71,6 +71,7 @@ static int purpose_smime(const X509 *x, int ca);
71static int check_purpose_smime_sign(const X509_PURPOSE *xp, const X509 *x, int ca); 71static int check_purpose_smime_sign(const X509_PURPOSE *xp, const X509 *x, int ca);
72static int check_purpose_smime_encrypt(const X509_PURPOSE *xp, const X509 *x, int ca); 72static int check_purpose_smime_encrypt(const X509_PURPOSE *xp, const X509 *x, int ca);
73static int check_purpose_crl_sign(const X509_PURPOSE *xp, const X509 *x, int ca); 73static int check_purpose_crl_sign(const X509_PURPOSE *xp, const X509 *x, int ca);
74static int check_purpose_timestamp_sign(const X509_PURPOSE *xp, const X509 *x, int ca);
74static int no_check(const X509_PURPOSE *xp, const X509 *x, int ca); 75static int no_check(const X509_PURPOSE *xp, const X509 *x, int ca);
75static int ocsp_helper(const X509_PURPOSE *xp, const X509 *x, int ca); 76static int ocsp_helper(const X509_PURPOSE *xp, const X509 *x, int ca);
76 77
@@ -87,6 +88,7 @@ static X509_PURPOSE xstandard[] = {
87 {X509_PURPOSE_CRL_SIGN, X509_TRUST_COMPAT, 0, check_purpose_crl_sign, "CRL signing", "crlsign", NULL}, 88 {X509_PURPOSE_CRL_SIGN, X509_TRUST_COMPAT, 0, check_purpose_crl_sign, "CRL signing", "crlsign", NULL},
88 {X509_PURPOSE_ANY, X509_TRUST_DEFAULT, 0, no_check, "Any Purpose", "any", NULL}, 89 {X509_PURPOSE_ANY, X509_TRUST_DEFAULT, 0, no_check, "Any Purpose", "any", NULL},
89 {X509_PURPOSE_OCSP_HELPER, X509_TRUST_COMPAT, 0, ocsp_helper, "OCSP helper", "ocsphelper", NULL}, 90 {X509_PURPOSE_OCSP_HELPER, X509_TRUST_COMPAT, 0, ocsp_helper, "OCSP helper", "ocsphelper", NULL},
91 {X509_PURPOSE_TIMESTAMP_SIGN, X509_TRUST_TSA, 0, check_purpose_timestamp_sign, "Time Stamp signing", "timestampsign", NULL},
90}; 92};
91 93
92#define X509_PURPOSE_COUNT (sizeof(xstandard)/sizeof(X509_PURPOSE)) 94#define X509_PURPOSE_COUNT (sizeof(xstandard)/sizeof(X509_PURPOSE))
@@ -265,11 +267,14 @@ int X509_PURPOSE_get_trust(X509_PURPOSE *xp)
265 return xp->trust; 267 return xp->trust;
266} 268}
267 269
268static int nid_cmp(int *a, int *b) 270static int nid_cmp(const int *a, const int *b)
269 { 271 {
270 return *a - *b; 272 return *a - *b;
271 } 273 }
272 274
275DECLARE_OBJ_BSEARCH_CMP_FN(int, int, nid);
276IMPLEMENT_OBJ_BSEARCH_CMP_FN(int, int, nid);
277
273int X509_supported_extension(X509_EXTENSION *ex) 278int X509_supported_extension(X509_EXTENSION *ex)
274 { 279 {
275 /* This table is a list of the NIDs of supported extensions: 280 /* This table is a list of the NIDs of supported extensions:
@@ -280,7 +285,7 @@ int X509_supported_extension(X509_EXTENSION *ex)
280 * searched using bsearch. 285 * searched using bsearch.
281 */ 286 */
282 287
283 static int supported_nids[] = { 288 static const int supported_nids[] = {
284 NID_netscape_cert_type, /* 71 */ 289 NID_netscape_cert_type, /* 71 */
285 NID_key_usage, /* 83 */ 290 NID_key_usage, /* 83 */
286 NID_subject_alt_name, /* 85 */ 291 NID_subject_alt_name, /* 85 */
@@ -292,24 +297,62 @@ int X509_supported_extension(X509_EXTENSION *ex)
292 NID_sbgp_autonomousSysNum, /* 291 */ 297 NID_sbgp_autonomousSysNum, /* 291 */
293#endif 298#endif
294 NID_policy_constraints, /* 401 */ 299 NID_policy_constraints, /* 401 */
295 NID_proxyCertInfo, /* 661 */ 300 NID_proxyCertInfo, /* 663 */
301 NID_name_constraints, /* 666 */
302 NID_policy_mappings, /* 747 */
296 NID_inhibit_any_policy /* 748 */ 303 NID_inhibit_any_policy /* 748 */
297 }; 304 };
298 305
299 int ex_nid; 306 int ex_nid = OBJ_obj2nid(X509_EXTENSION_get_object(ex));
300
301 ex_nid = OBJ_obj2nid(X509_EXTENSION_get_object(ex));
302 307
303 if (ex_nid == NID_undef) 308 if (ex_nid == NID_undef)
304 return 0; 309 return 0;
305 310
306 if (OBJ_bsearch((char *)&ex_nid, (char *)supported_nids, 311 if (OBJ_bsearch_nid(&ex_nid, supported_nids,
307 sizeof(supported_nids)/sizeof(int), sizeof(int), 312 sizeof(supported_nids)/sizeof(int)))
308 (int (*)(const void *, const void *))nid_cmp))
309 return 1; 313 return 1;
310 return 0; 314 return 0;
311 } 315 }
312 316
317static void setup_dp(X509 *x, DIST_POINT *dp)
318 {
319 X509_NAME *iname = NULL;
320 int i;
321 if (dp->reasons)
322 {
323 if (dp->reasons->length > 0)
324 dp->dp_reasons = dp->reasons->data[0];
325 if (dp->reasons->length > 1)
326 dp->dp_reasons |= (dp->reasons->data[1] << 8);
327 dp->dp_reasons &= CRLDP_ALL_REASONS;
328 }
329 else
330 dp->dp_reasons = CRLDP_ALL_REASONS;
331 if (!dp->distpoint || (dp->distpoint->type != 1))
332 return;
333 for (i = 0; i < sk_GENERAL_NAME_num(dp->CRLissuer); i++)
334 {
335 GENERAL_NAME *gen = sk_GENERAL_NAME_value(dp->CRLissuer, i);
336 if (gen->type == GEN_DIRNAME)
337 {
338 iname = gen->d.directoryName;
339 break;
340 }
341 }
342 if (!iname)
343 iname = X509_get_issuer_name(x);
344
345 DIST_POINT_set_dpname(dp->distpoint, iname);
346
347 }
348
349static void setup_crldp(X509 *x)
350 {
351 int i;
352 x->crldp = X509_get_ext_d2i(x, NID_crl_distribution_points, NULL, NULL);
353 for (i = 0; i < sk_DIST_POINT_num(x->crldp); i++)
354 setup_dp(x, sk_DIST_POINT_value(x->crldp, i));
355 }
313 356
314static void x509v3_cache_extensions(X509 *x) 357static void x509v3_cache_extensions(X509 *x)
315{ 358{
@@ -417,16 +460,25 @@ static void x509v3_cache_extensions(X509 *x)
417 } 460 }
418 x->skid =X509_get_ext_d2i(x, NID_subject_key_identifier, NULL, NULL); 461 x->skid =X509_get_ext_d2i(x, NID_subject_key_identifier, NULL, NULL);
419 x->akid =X509_get_ext_d2i(x, NID_authority_key_identifier, NULL, NULL); 462 x->akid =X509_get_ext_d2i(x, NID_authority_key_identifier, NULL, NULL);
463 x->altname = X509_get_ext_d2i(x, NID_subject_alt_name, NULL, NULL);
464 x->nc = X509_get_ext_d2i(x, NID_name_constraints, &i, NULL);
465 if (!x->nc && (i != -1))
466 x->ex_flags |= EXFLAG_INVALID;
467 setup_crldp(x);
468
420#ifndef OPENSSL_NO_RFC3779 469#ifndef OPENSSL_NO_RFC3779
421 x->rfc3779_addr =X509_get_ext_d2i(x, NID_sbgp_ipAddrBlock, NULL, NULL); 470 x->rfc3779_addr =X509_get_ext_d2i(x, NID_sbgp_ipAddrBlock, NULL, NULL);
422 x->rfc3779_asid =X509_get_ext_d2i(x, NID_sbgp_autonomousSysNum, 471 x->rfc3779_asid =X509_get_ext_d2i(x, NID_sbgp_autonomousSysNum,
423 NULL, NULL); 472 NULL, NULL);
424#endif 473#endif
425 for (i = 0; i < X509_get_ext_count(x); i++) 474 for (i = 0; i < X509_get_ext_count(x); i++)
426 { 475 {
427 ex = X509_get_ext(x, i); 476 ex = X509_get_ext(x, i);
428 if (!X509_EXTENSION_get_critical(ex)) 477 if (!X509_EXTENSION_get_critical(ex))
429 continue; 478 continue;
479 if (OBJ_obj2nid(X509_EXTENSION_get_object(ex))
480 == NID_freshest_crl)
481 x->ex_flags |= EXFLAG_FRESHEST;
430 if (!X509_supported_extension(ex)) 482 if (!X509_supported_extension(ex))
431 { 483 {
432 x->ex_flags |= EXFLAG_CRITICAL; 484 x->ex_flags |= EXFLAG_CRITICAL;
@@ -594,6 +646,41 @@ static int ocsp_helper(const X509_PURPOSE *xp, const X509 *x, int ca)
594 return 1; 646 return 1;
595} 647}
596 648
649static int check_purpose_timestamp_sign(const X509_PURPOSE *xp, const X509 *x,
650 int ca)
651{
652 int i_ext;
653
654 /* If ca is true we must return if this is a valid CA certificate. */
655 if (ca) return check_ca(x);
656
657 /*
658 * Check the optional key usage field:
659 * if Key Usage is present, it must be one of digitalSignature
660 * and/or nonRepudiation (other values are not consistent and shall
661 * be rejected).
662 */
663 if ((x->ex_flags & EXFLAG_KUSAGE)
664 && ((x->ex_kusage & ~(KU_NON_REPUDIATION | KU_DIGITAL_SIGNATURE)) ||
665 !(x->ex_kusage & (KU_NON_REPUDIATION | KU_DIGITAL_SIGNATURE))))
666 return 0;
667
668 /* Only time stamp key usage is permitted and it's required. */
669 if (!(x->ex_flags & EXFLAG_XKUSAGE) || x->ex_xkusage != XKU_TIMESTAMP)
670 return 0;
671
672 /* Extended Key Usage MUST be critical */
673 i_ext = X509_get_ext_by_NID((X509 *) x, NID_ext_key_usage, 0);
674 if (i_ext >= 0)
675 {
676 X509_EXTENSION *ext = X509_get_ext((X509 *) x, i_ext);
677 if (!X509_EXTENSION_get_critical(ext))
678 return 0;
679 }
680
681 return 1;
682}
683
597static int no_check(const X509_PURPOSE *xp, const X509 *x, int ca) 684static int no_check(const X509_PURPOSE *xp, const X509 *x, int ca)
598{ 685{
599 return 1; 686 return 1;
@@ -618,39 +705,14 @@ int X509_check_issued(X509 *issuer, X509 *subject)
618 return X509_V_ERR_SUBJECT_ISSUER_MISMATCH; 705 return X509_V_ERR_SUBJECT_ISSUER_MISMATCH;
619 x509v3_cache_extensions(issuer); 706 x509v3_cache_extensions(issuer);
620 x509v3_cache_extensions(subject); 707 x509v3_cache_extensions(subject);
621 if(subject->akid) { 708
622 /* Check key ids (if present) */ 709 if(subject->akid)
623 if(subject->akid->keyid && issuer->skid && 710 {
624 ASN1_OCTET_STRING_cmp(subject->akid->keyid, issuer->skid) ) 711 int ret = X509_check_akid(issuer, subject->akid);
625 return X509_V_ERR_AKID_SKID_MISMATCH; 712 if (ret != X509_V_OK)
626 /* Check serial number */ 713 return ret;
627 if(subject->akid->serial &&
628 ASN1_INTEGER_cmp(X509_get_serialNumber(issuer),
629 subject->akid->serial))
630 return X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH;
631 /* Check issuer name */
632 if(subject->akid->issuer) {
633 /* Ugh, for some peculiar reason AKID includes
634 * SEQUENCE OF GeneralName. So look for a DirName.
635 * There may be more than one but we only take any
636 * notice of the first.
637 */
638 GENERAL_NAMES *gens;
639 GENERAL_NAME *gen;
640 X509_NAME *nm = NULL;
641 int i;
642 gens = subject->akid->issuer;
643 for(i = 0; i < sk_GENERAL_NAME_num(gens); i++) {
644 gen = sk_GENERAL_NAME_value(gens, i);
645 if(gen->type == GEN_DIRNAME) {
646 nm = gen->d.dirn;
647 break;
648 }
649 }
650 if(nm && X509_NAME_cmp(nm, X509_get_issuer_name(issuer)))
651 return X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH;
652 } 714 }
653 } 715
654 if(subject->ex_flags & EXFLAG_PROXY) 716 if(subject->ex_flags & EXFLAG_PROXY)
655 { 717 {
656 if(ku_reject(issuer, KU_DIGITAL_SIGNATURE)) 718 if(ku_reject(issuer, KU_DIGITAL_SIGNATURE))
@@ -661,3 +723,45 @@ int X509_check_issued(X509 *issuer, X509 *subject)
661 return X509_V_OK; 723 return X509_V_OK;
662} 724}
663 725
726int X509_check_akid(X509 *issuer, AUTHORITY_KEYID *akid)
727 {
728
729 if(!akid)
730 return X509_V_OK;
731
732 /* Check key ids (if present) */
733 if(akid->keyid && issuer->skid &&
734 ASN1_OCTET_STRING_cmp(akid->keyid, issuer->skid) )
735 return X509_V_ERR_AKID_SKID_MISMATCH;
736 /* Check serial number */
737 if(akid->serial &&
738 ASN1_INTEGER_cmp(X509_get_serialNumber(issuer), akid->serial))
739 return X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH;
740 /* Check issuer name */
741 if(akid->issuer)
742 {
743 /* Ugh, for some peculiar reason AKID includes
744 * SEQUENCE OF GeneralName. So look for a DirName.
745 * There may be more than one but we only take any
746 * notice of the first.
747 */
748 GENERAL_NAMES *gens;
749 GENERAL_NAME *gen;
750 X509_NAME *nm = NULL;
751 int i;
752 gens = akid->issuer;
753 for(i = 0; i < sk_GENERAL_NAME_num(gens); i++)
754 {
755 gen = sk_GENERAL_NAME_value(gens, i);
756 if(gen->type == GEN_DIRNAME)
757 {
758 nm = gen->d.dirn;
759 break;
760 }
761 }
762 if(nm && X509_NAME_cmp(nm, X509_get_issuer_name(issuer)))
763 return X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH;
764 }
765 return X509_V_OK;
766 }
767
diff --git a/src/lib/libcrypto/x509v3/v3_utl.c b/src/lib/libcrypto/x509v3/v3_utl.c
index 7a45216c00..e030234540 100644
--- a/src/lib/libcrypto/x509v3/v3_utl.c
+++ b/src/lib/libcrypto/x509v3/v3_utl.c
@@ -67,9 +67,9 @@
67 67
68static char *strip_spaces(char *name); 68static char *strip_spaces(char *name);
69static int sk_strcmp(const char * const *a, const char * const *b); 69static int sk_strcmp(const char * const *a, const char * const *b);
70static STACK *get_email(X509_NAME *name, GENERAL_NAMES *gens); 70static STACK_OF(OPENSSL_STRING) *get_email(X509_NAME *name, GENERAL_NAMES *gens);
71static void str_free(void *str); 71static void str_free(OPENSSL_STRING str);
72static int append_ia5(STACK **sk, ASN1_IA5STRING *email); 72static int append_ia5(STACK_OF(OPENSSL_STRING) **sk, ASN1_IA5STRING *email);
73 73
74static int ipv4_from_asc(unsigned char *v4, const char *in); 74static int ipv4_from_asc(unsigned char *v4, const char *in);
75static int ipv6_from_asc(unsigned char *v6, const char *in); 75static int ipv6_from_asc(unsigned char *v6, const char *in);
@@ -360,10 +360,10 @@ static char *strip_spaces(char *name)
360 * @@@ (Contents of buffer are always kept in ASCII, also on EBCDIC machines) 360 * @@@ (Contents of buffer are always kept in ASCII, also on EBCDIC machines)
361 */ 361 */
362 362
363char *hex_to_string(unsigned char *buffer, long len) 363char *hex_to_string(const unsigned char *buffer, long len)
364{ 364{
365 char *tmp, *q; 365 char *tmp, *q;
366 unsigned char *p; 366 const unsigned char *p;
367 int i; 367 int i;
368 const static char hexdig[] = "0123456789ABCDEF"; 368 const static char hexdig[] = "0123456789ABCDEF";
369 if(!buffer || !len) return NULL; 369 if(!buffer || !len) return NULL;
@@ -389,7 +389,7 @@ char *hex_to_string(unsigned char *buffer, long len)
389 * a buffer 389 * a buffer
390 */ 390 */
391 391
392unsigned char *string_to_hex(char *str, long *len) 392unsigned char *string_to_hex(const char *str, long *len)
393{ 393{
394 unsigned char *hexbuf, *q; 394 unsigned char *hexbuf, *q;
395 unsigned char ch, cl, *p; 395 unsigned char ch, cl, *p;
@@ -463,21 +463,23 @@ static int sk_strcmp(const char * const *a, const char * const *b)
463 return strcmp(*a, *b); 463 return strcmp(*a, *b);
464} 464}
465 465
466STACK *X509_get1_email(X509 *x) 466STACK_OF(OPENSSL_STRING) *X509_get1_email(X509 *x)
467{ 467{
468 GENERAL_NAMES *gens; 468 GENERAL_NAMES *gens;
469 STACK *ret; 469 STACK_OF(OPENSSL_STRING) *ret;
470
470 gens = X509_get_ext_d2i(x, NID_subject_alt_name, NULL, NULL); 471 gens = X509_get_ext_d2i(x, NID_subject_alt_name, NULL, NULL);
471 ret = get_email(X509_get_subject_name(x), gens); 472 ret = get_email(X509_get_subject_name(x), gens);
472 sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free); 473 sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free);
473 return ret; 474 return ret;
474} 475}
475 476
476STACK *X509_get1_ocsp(X509 *x) 477STACK_OF(OPENSSL_STRING) *X509_get1_ocsp(X509 *x)
477{ 478{
478 AUTHORITY_INFO_ACCESS *info; 479 AUTHORITY_INFO_ACCESS *info;
479 STACK *ret = NULL; 480 STACK_OF(OPENSSL_STRING) *ret = NULL;
480 int i; 481 int i;
482
481 info = X509_get_ext_d2i(x, NID_info_access, NULL, NULL); 483 info = X509_get_ext_d2i(x, NID_info_access, NULL, NULL);
482 if (!info) 484 if (!info)
483 return NULL; 485 return NULL;
@@ -497,11 +499,12 @@ STACK *X509_get1_ocsp(X509 *x)
497 return ret; 499 return ret;
498} 500}
499 501
500STACK *X509_REQ_get1_email(X509_REQ *x) 502STACK_OF(OPENSSL_STRING) *X509_REQ_get1_email(X509_REQ *x)
501{ 503{
502 GENERAL_NAMES *gens; 504 GENERAL_NAMES *gens;
503 STACK_OF(X509_EXTENSION) *exts; 505 STACK_OF(X509_EXTENSION) *exts;
504 STACK *ret; 506 STACK_OF(OPENSSL_STRING) *ret;
507
505 exts = X509_REQ_get_extensions(x); 508 exts = X509_REQ_get_extensions(x);
506 gens = X509V3_get_d2i(exts, NID_subject_alt_name, NULL, NULL); 509 gens = X509V3_get_d2i(exts, NID_subject_alt_name, NULL, NULL);
507 ret = get_email(X509_REQ_get_subject_name(x), gens); 510 ret = get_email(X509_REQ_get_subject_name(x), gens);
@@ -511,9 +514,9 @@ STACK *X509_REQ_get1_email(X509_REQ *x)
511} 514}
512 515
513 516
514static STACK *get_email(X509_NAME *name, GENERAL_NAMES *gens) 517static STACK_OF(OPENSSL_STRING) *get_email(X509_NAME *name, GENERAL_NAMES *gens)
515{ 518{
516 STACK *ret = NULL; 519 STACK_OF(OPENSSL_STRING) *ret = NULL;
517 X509_NAME_ENTRY *ne; 520 X509_NAME_ENTRY *ne;
518 ASN1_IA5STRING *email; 521 ASN1_IA5STRING *email;
519 GENERAL_NAME *gen; 522 GENERAL_NAME *gen;
@@ -536,23 +539,23 @@ static STACK *get_email(X509_NAME *name, GENERAL_NAMES *gens)
536 return ret; 539 return ret;
537} 540}
538 541
539static void str_free(void *str) 542static void str_free(OPENSSL_STRING str)
540{ 543{
541 OPENSSL_free(str); 544 OPENSSL_free(str);
542} 545}
543 546
544static int append_ia5(STACK **sk, ASN1_IA5STRING *email) 547static int append_ia5(STACK_OF(OPENSSL_STRING) **sk, ASN1_IA5STRING *email)
545{ 548{
546 char *emtmp; 549 char *emtmp;
547 /* First some sanity checks */ 550 /* First some sanity checks */
548 if(email->type != V_ASN1_IA5STRING) return 1; 551 if(email->type != V_ASN1_IA5STRING) return 1;
549 if(!email->data || !email->length) return 1; 552 if(!email->data || !email->length) return 1;
550 if(!*sk) *sk = sk_new(sk_strcmp); 553 if(!*sk) *sk = sk_OPENSSL_STRING_new(sk_strcmp);
551 if(!*sk) return 0; 554 if(!*sk) return 0;
552 /* Don't add duplicates */ 555 /* Don't add duplicates */
553 if(sk_find(*sk, (char *)email->data) != -1) return 1; 556 if(sk_OPENSSL_STRING_find(*sk, (char *)email->data) != -1) return 1;
554 emtmp = BUF_strdup((char *)email->data); 557 emtmp = BUF_strdup((char *)email->data);
555 if(!emtmp || !sk_push(*sk, emtmp)) { 558 if(!emtmp || !sk_OPENSSL_STRING_push(*sk, emtmp)) {
556 X509_email_free(*sk); 559 X509_email_free(*sk);
557 *sk = NULL; 560 *sk = NULL;
558 return 0; 561 return 0;
@@ -560,9 +563,9 @@ static int append_ia5(STACK **sk, ASN1_IA5STRING *email)
560 return 1; 563 return 1;
561} 564}
562 565
563void X509_email_free(STACK *sk) 566void X509_email_free(STACK_OF(OPENSSL_STRING) *sk)
564{ 567{
565 sk_pop_free(sk, str_free); 568 sk_OPENSSL_STRING_pop_free(sk, str_free);
566} 569}
567 570
568/* Convert IP addresses both IPv4 and IPv6 into an 571/* Convert IP addresses both IPv4 and IPv6 into an
diff --git a/src/lib/libcrypto/x509v3/v3err.c b/src/lib/libcrypto/x509v3/v3err.c
index d538ad8b80..f9f6f1f91f 100644
--- a/src/lib/libcrypto/x509v3/v3err.c
+++ b/src/lib/libcrypto/x509v3/v3err.c
@@ -1,6 +1,6 @@
1/* crypto/x509v3/v3err.c */ 1/* crypto/x509v3/v3err.c */
2/* ==================================================================== 2/* ====================================================================
3 * Copyright (c) 1999-2005 The OpenSSL Project. All rights reserved. 3 * Copyright (c) 1999-2007 The OpenSSL Project. All rights reserved.
4 * 4 *
5 * Redistribution and use in source and binary forms, with or without 5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions 6 * modification, are permitted provided that the following conditions
@@ -70,6 +70,7 @@
70 70
71static ERR_STRING_DATA X509V3_str_functs[]= 71static ERR_STRING_DATA X509V3_str_functs[]=
72 { 72 {
73{ERR_FUNC(X509V3_F_A2I_GENERAL_NAME), "A2I_GENERAL_NAME"},
73{ERR_FUNC(X509V3_F_ASIDENTIFIERCHOICE_CANONIZE), "ASIDENTIFIERCHOICE_CANONIZE"}, 74{ERR_FUNC(X509V3_F_ASIDENTIFIERCHOICE_CANONIZE), "ASIDENTIFIERCHOICE_CANONIZE"},
74{ERR_FUNC(X509V3_F_ASIDENTIFIERCHOICE_IS_CANONICAL), "ASIDENTIFIERCHOICE_IS_CANONICAL"}, 75{ERR_FUNC(X509V3_F_ASIDENTIFIERCHOICE_IS_CANONICAL), "ASIDENTIFIERCHOICE_IS_CANONICAL"},
75{ERR_FUNC(X509V3_F_COPY_EMAIL), "COPY_EMAIL"}, 76{ERR_FUNC(X509V3_F_COPY_EMAIL), "COPY_EMAIL"},
@@ -79,6 +80,7 @@ static ERR_STRING_DATA X509V3_str_functs[]=
79{ERR_FUNC(X509V3_F_DO_EXT_I2D), "DO_EXT_I2D"}, 80{ERR_FUNC(X509V3_F_DO_EXT_I2D), "DO_EXT_I2D"},
80{ERR_FUNC(X509V3_F_DO_EXT_NCONF), "DO_EXT_NCONF"}, 81{ERR_FUNC(X509V3_F_DO_EXT_NCONF), "DO_EXT_NCONF"},
81{ERR_FUNC(X509V3_F_DO_I2V_NAME_CONSTRAINTS), "DO_I2V_NAME_CONSTRAINTS"}, 82{ERR_FUNC(X509V3_F_DO_I2V_NAME_CONSTRAINTS), "DO_I2V_NAME_CONSTRAINTS"},
83{ERR_FUNC(X509V3_F_GNAMES_FROM_SECTNAME), "GNAMES_FROM_SECTNAME"},
82{ERR_FUNC(X509V3_F_HEX_TO_STRING), "hex_to_string"}, 84{ERR_FUNC(X509V3_F_HEX_TO_STRING), "hex_to_string"},
83{ERR_FUNC(X509V3_F_I2S_ASN1_ENUMERATED), "i2s_ASN1_ENUMERATED"}, 85{ERR_FUNC(X509V3_F_I2S_ASN1_ENUMERATED), "i2s_ASN1_ENUMERATED"},
84{ERR_FUNC(X509V3_F_I2S_ASN1_IA5STRING), "I2S_ASN1_IA5STRING"}, 86{ERR_FUNC(X509V3_F_I2S_ASN1_IA5STRING), "I2S_ASN1_IA5STRING"},
@@ -95,6 +97,7 @@ static ERR_STRING_DATA X509V3_str_functs[]=
95{ERR_FUNC(X509V3_F_S2I_ASN1_OCTET_STRING), "s2i_ASN1_OCTET_STRING"}, 97{ERR_FUNC(X509V3_F_S2I_ASN1_OCTET_STRING), "s2i_ASN1_OCTET_STRING"},
96{ERR_FUNC(X509V3_F_S2I_ASN1_SKEY_ID), "S2I_ASN1_SKEY_ID"}, 98{ERR_FUNC(X509V3_F_S2I_ASN1_SKEY_ID), "S2I_ASN1_SKEY_ID"},
97{ERR_FUNC(X509V3_F_S2I_SKEY_ID), "S2I_SKEY_ID"}, 99{ERR_FUNC(X509V3_F_S2I_SKEY_ID), "S2I_SKEY_ID"},
100{ERR_FUNC(X509V3_F_SET_DIST_POINT_NAME), "SET_DIST_POINT_NAME"},
98{ERR_FUNC(X509V3_F_STRING_TO_HEX), "string_to_hex"}, 101{ERR_FUNC(X509V3_F_STRING_TO_HEX), "string_to_hex"},
99{ERR_FUNC(X509V3_F_SXNET_ADD_ID_ASC), "SXNET_add_id_asc"}, 102{ERR_FUNC(X509V3_F_SXNET_ADD_ID_ASC), "SXNET_add_id_asc"},
100{ERR_FUNC(X509V3_F_SXNET_ADD_ID_INTEGER), "SXNET_add_id_INTEGER"}, 103{ERR_FUNC(X509V3_F_SXNET_ADD_ID_INTEGER), "SXNET_add_id_INTEGER"},
@@ -110,6 +113,7 @@ static ERR_STRING_DATA X509V3_str_functs[]=
110{ERR_FUNC(X509V3_F_V2I_EXTENDED_KEY_USAGE), "V2I_EXTENDED_KEY_USAGE"}, 113{ERR_FUNC(X509V3_F_V2I_EXTENDED_KEY_USAGE), "V2I_EXTENDED_KEY_USAGE"},
111{ERR_FUNC(X509V3_F_V2I_GENERAL_NAMES), "v2i_GENERAL_NAMES"}, 114{ERR_FUNC(X509V3_F_V2I_GENERAL_NAMES), "v2i_GENERAL_NAMES"},
112{ERR_FUNC(X509V3_F_V2I_GENERAL_NAME_EX), "v2i_GENERAL_NAME_ex"}, 115{ERR_FUNC(X509V3_F_V2I_GENERAL_NAME_EX), "v2i_GENERAL_NAME_ex"},
116{ERR_FUNC(X509V3_F_V2I_IDP), "V2I_IDP"},
113{ERR_FUNC(X509V3_F_V2I_IPADDRBLOCKS), "V2I_IPADDRBLOCKS"}, 117{ERR_FUNC(X509V3_F_V2I_IPADDRBLOCKS), "V2I_IPADDRBLOCKS"},
114{ERR_FUNC(X509V3_F_V2I_ISSUER_ALT), "V2I_ISSUER_ALT"}, 118{ERR_FUNC(X509V3_F_V2I_ISSUER_ALT), "V2I_ISSUER_ALT"},
115{ERR_FUNC(X509V3_F_V2I_NAME_CONSTRAINTS), "V2I_NAME_CONSTRAINTS"}, 119{ERR_FUNC(X509V3_F_V2I_NAME_CONSTRAINTS), "V2I_NAME_CONSTRAINTS"},
@@ -141,6 +145,7 @@ static ERR_STRING_DATA X509V3_str_reasons[]=
141{ERR_REASON(X509V3_R_BN_DEC2BN_ERROR) ,"bn dec2bn error"}, 145{ERR_REASON(X509V3_R_BN_DEC2BN_ERROR) ,"bn dec2bn error"},
142{ERR_REASON(X509V3_R_BN_TO_ASN1_INTEGER_ERROR),"bn to asn1 integer error"}, 146{ERR_REASON(X509V3_R_BN_TO_ASN1_INTEGER_ERROR),"bn to asn1 integer error"},
143{ERR_REASON(X509V3_R_DIRNAME_ERROR) ,"dirname error"}, 147{ERR_REASON(X509V3_R_DIRNAME_ERROR) ,"dirname error"},
148{ERR_REASON(X509V3_R_DISTPOINT_ALREADY_SET),"distpoint already set"},
144{ERR_REASON(X509V3_R_DUPLICATE_ZONE_ID) ,"duplicate zone id"}, 149{ERR_REASON(X509V3_R_DUPLICATE_ZONE_ID) ,"duplicate zone id"},
145{ERR_REASON(X509V3_R_ERROR_CONVERTING_ZONE),"error converting zone"}, 150{ERR_REASON(X509V3_R_ERROR_CONVERTING_ZONE),"error converting zone"},
146{ERR_REASON(X509V3_R_ERROR_CREATING_EXTENSION),"error creating extension"}, 151{ERR_REASON(X509V3_R_ERROR_CREATING_EXTENSION),"error creating extension"},
@@ -154,6 +159,7 @@ static ERR_STRING_DATA X509V3_str_reasons[]=
154{ERR_REASON(X509V3_R_ILLEGAL_EMPTY_EXTENSION),"illegal empty extension"}, 159{ERR_REASON(X509V3_R_ILLEGAL_EMPTY_EXTENSION),"illegal empty extension"},
155{ERR_REASON(X509V3_R_ILLEGAL_HEX_DIGIT) ,"illegal hex digit"}, 160{ERR_REASON(X509V3_R_ILLEGAL_HEX_DIGIT) ,"illegal hex digit"},
156{ERR_REASON(X509V3_R_INCORRECT_POLICY_SYNTAX_TAG),"incorrect policy syntax tag"}, 161{ERR_REASON(X509V3_R_INCORRECT_POLICY_SYNTAX_TAG),"incorrect policy syntax tag"},
162{ERR_REASON(X509V3_R_INVALID_MULTIPLE_RDNS),"invalid multiple rdns"},
157{ERR_REASON(X509V3_R_INVALID_ASNUMBER) ,"invalid asnumber"}, 163{ERR_REASON(X509V3_R_INVALID_ASNUMBER) ,"invalid asnumber"},
158{ERR_REASON(X509V3_R_INVALID_ASRANGE) ,"invalid asrange"}, 164{ERR_REASON(X509V3_R_INVALID_ASRANGE) ,"invalid asrange"},
159{ERR_REASON(X509V3_R_INVALID_BOOLEAN_STRING),"invalid boolean string"}, 165{ERR_REASON(X509V3_R_INVALID_BOOLEAN_STRING),"invalid boolean string"},
@@ -187,9 +193,9 @@ static ERR_STRING_DATA X509V3_str_reasons[]=
187{ERR_REASON(X509V3_R_ODD_NUMBER_OF_DIGITS),"odd number of digits"}, 193{ERR_REASON(X509V3_R_ODD_NUMBER_OF_DIGITS),"odd number of digits"},
188{ERR_REASON(X509V3_R_OPERATION_NOT_DEFINED),"operation not defined"}, 194{ERR_REASON(X509V3_R_OPERATION_NOT_DEFINED),"operation not defined"},
189{ERR_REASON(X509V3_R_OTHERNAME_ERROR) ,"othername error"}, 195{ERR_REASON(X509V3_R_OTHERNAME_ERROR) ,"othername error"},
190{ERR_REASON(X509V3_R_POLICY_LANGUAGE_ALREADTY_DEFINED),"policy language alreadty defined"}, 196{ERR_REASON(X509V3_R_POLICY_LANGUAGE_ALREADY_DEFINED),"policy language already defined"},
191{ERR_REASON(X509V3_R_POLICY_PATH_LENGTH) ,"policy path length"}, 197{ERR_REASON(X509V3_R_POLICY_PATH_LENGTH) ,"policy path length"},
192{ERR_REASON(X509V3_R_POLICY_PATH_LENGTH_ALREADTY_DEFINED),"policy path length alreadty defined"}, 198{ERR_REASON(X509V3_R_POLICY_PATH_LENGTH_ALREADY_DEFINED),"policy path length already defined"},
193{ERR_REASON(X509V3_R_POLICY_SYNTAX_NOT_CURRENTLY_SUPPORTED),"policy syntax not currently supported"}, 199{ERR_REASON(X509V3_R_POLICY_SYNTAX_NOT_CURRENTLY_SUPPORTED),"policy syntax not currently supported"},
194{ERR_REASON(X509V3_R_POLICY_WHEN_PROXY_LANGUAGE_REQUIRES_NO_POLICY),"policy when proxy language requires no policy"}, 200{ERR_REASON(X509V3_R_POLICY_WHEN_PROXY_LANGUAGE_REQUIRES_NO_POLICY),"policy when proxy language requires no policy"},
195{ERR_REASON(X509V3_R_SECTION_NOT_FOUND) ,"section not found"}, 201{ERR_REASON(X509V3_R_SECTION_NOT_FOUND) ,"section not found"},
@@ -200,6 +206,7 @@ static ERR_STRING_DATA X509V3_str_reasons[]=
200{ERR_REASON(X509V3_R_UNKNOWN_EXTENSION_NAME),"unknown extension name"}, 206{ERR_REASON(X509V3_R_UNKNOWN_EXTENSION_NAME),"unknown extension name"},
201{ERR_REASON(X509V3_R_UNKNOWN_OPTION) ,"unknown option"}, 207{ERR_REASON(X509V3_R_UNKNOWN_OPTION) ,"unknown option"},
202{ERR_REASON(X509V3_R_UNSUPPORTED_OPTION) ,"unsupported option"}, 208{ERR_REASON(X509V3_R_UNSUPPORTED_OPTION) ,"unsupported option"},
209{ERR_REASON(X509V3_R_UNSUPPORTED_TYPE) ,"unsupported type"},
203{ERR_REASON(X509V3_R_USER_TOO_LONG) ,"user too long"}, 210{ERR_REASON(X509V3_R_USER_TOO_LONG) ,"user too long"},
204{0,NULL} 211{0,NULL}
205 }; 212 };
diff --git a/src/lib/libcrypto/x509v3/x509v3.h b/src/lib/libcrypto/x509v3/x509v3.h
index 9ef83da755..b308abe7cd 100644
--- a/src/lib/libcrypto/x509v3/x509v3.h
+++ b/src/lib/libcrypto/x509v3/x509v3.h
@@ -76,12 +76,19 @@ typedef void * (*X509V3_EXT_NEW)(void);
76typedef void (*X509V3_EXT_FREE)(void *); 76typedef void (*X509V3_EXT_FREE)(void *);
77typedef void * (*X509V3_EXT_D2I)(void *, const unsigned char ** , long); 77typedef void * (*X509V3_EXT_D2I)(void *, const unsigned char ** , long);
78typedef int (*X509V3_EXT_I2D)(void *, unsigned char **); 78typedef int (*X509V3_EXT_I2D)(void *, unsigned char **);
79typedef STACK_OF(CONF_VALUE) * (*X509V3_EXT_I2V)(struct v3_ext_method *method, void *ext, STACK_OF(CONF_VALUE) *extlist); 79typedef STACK_OF(CONF_VALUE) *
80typedef void * (*X509V3_EXT_V2I)(struct v3_ext_method *method, struct v3_ext_ctx *ctx, STACK_OF(CONF_VALUE) *values); 80 (*X509V3_EXT_I2V)(const struct v3_ext_method *method, void *ext,
81typedef char * (*X509V3_EXT_I2S)(struct v3_ext_method *method, void *ext); 81 STACK_OF(CONF_VALUE) *extlist);
82typedef void * (*X509V3_EXT_S2I)(struct v3_ext_method *method, struct v3_ext_ctx *ctx, const char *str); 82typedef void * (*X509V3_EXT_V2I)(const struct v3_ext_method *method,
83typedef int (*X509V3_EXT_I2R)(struct v3_ext_method *method, void *ext, BIO *out, int indent); 83 struct v3_ext_ctx *ctx,
84typedef void * (*X509V3_EXT_R2I)(struct v3_ext_method *method, struct v3_ext_ctx *ctx, const char *str); 84 STACK_OF(CONF_VALUE) *values);
85typedef char * (*X509V3_EXT_I2S)(const struct v3_ext_method *method, void *ext);
86typedef void * (*X509V3_EXT_S2I)(const struct v3_ext_method *method,
87 struct v3_ext_ctx *ctx, const char *str);
88typedef int (*X509V3_EXT_I2R)(const struct v3_ext_method *method, void *ext,
89 BIO *out, int indent);
90typedef void * (*X509V3_EXT_R2I)(const struct v3_ext_method *method,
91 struct v3_ext_ctx *ctx, const char *str);
85 92
86/* V3 extension structure */ 93/* V3 extension structure */
87 94
@@ -220,24 +227,41 @@ union {
220 GENERAL_NAMES *fullname; 227 GENERAL_NAMES *fullname;
221 STACK_OF(X509_NAME_ENTRY) *relativename; 228 STACK_OF(X509_NAME_ENTRY) *relativename;
222} name; 229} name;
230/* If relativename then this contains the full distribution point name */
231X509_NAME *dpname;
223} DIST_POINT_NAME; 232} DIST_POINT_NAME;
224 233/* All existing reasons */
225typedef struct DIST_POINT_st { 234#define CRLDP_ALL_REASONS 0x807f
235
236#define CRL_REASON_NONE -1
237#define CRL_REASON_UNSPECIFIED 0
238#define CRL_REASON_KEY_COMPROMISE 1
239#define CRL_REASON_CA_COMPROMISE 2
240#define CRL_REASON_AFFILIATION_CHANGED 3
241#define CRL_REASON_SUPERSEDED 4
242#define CRL_REASON_CESSATION_OF_OPERATION 5
243#define CRL_REASON_CERTIFICATE_HOLD 6
244#define CRL_REASON_REMOVE_FROM_CRL 8
245#define CRL_REASON_PRIVILEGE_WITHDRAWN 9
246#define CRL_REASON_AA_COMPROMISE 10
247
248struct DIST_POINT_st {
226DIST_POINT_NAME *distpoint; 249DIST_POINT_NAME *distpoint;
227ASN1_BIT_STRING *reasons; 250ASN1_BIT_STRING *reasons;
228GENERAL_NAMES *CRLissuer; 251GENERAL_NAMES *CRLissuer;
229} DIST_POINT; 252int dp_reasons;
253};
230 254
231typedef STACK_OF(DIST_POINT) CRL_DIST_POINTS; 255typedef STACK_OF(DIST_POINT) CRL_DIST_POINTS;
232 256
233DECLARE_STACK_OF(DIST_POINT) 257DECLARE_STACK_OF(DIST_POINT)
234DECLARE_ASN1_SET_OF(DIST_POINT) 258DECLARE_ASN1_SET_OF(DIST_POINT)
235 259
236typedef struct AUTHORITY_KEYID_st { 260struct AUTHORITY_KEYID_st {
237ASN1_OCTET_STRING *keyid; 261ASN1_OCTET_STRING *keyid;
238GENERAL_NAMES *issuer; 262GENERAL_NAMES *issuer;
239ASN1_INTEGER *serial; 263ASN1_INTEGER *serial;
240} AUTHORITY_KEYID; 264};
241 265
242/* Strong extranet structures */ 266/* Strong extranet structures */
243 267
@@ -303,10 +327,10 @@ typedef struct GENERAL_SUBTREE_st {
303 327
304DECLARE_STACK_OF(GENERAL_SUBTREE) 328DECLARE_STACK_OF(GENERAL_SUBTREE)
305 329
306typedef struct NAME_CONSTRAINTS_st { 330struct NAME_CONSTRAINTS_st {
307 STACK_OF(GENERAL_SUBTREE) *permittedSubtrees; 331 STACK_OF(GENERAL_SUBTREE) *permittedSubtrees;
308 STACK_OF(GENERAL_SUBTREE) *excludedSubtrees; 332 STACK_OF(GENERAL_SUBTREE) *excludedSubtrees;
309} NAME_CONSTRAINTS; 333};
310 334
311typedef struct POLICY_CONSTRAINTS_st { 335typedef struct POLICY_CONSTRAINTS_st {
312 ASN1_INTEGER *requireExplicitPolicy; 336 ASN1_INTEGER *requireExplicitPolicy;
@@ -329,6 +353,31 @@ typedef struct PROXY_CERT_INFO_EXTENSION_st
329DECLARE_ASN1_FUNCTIONS(PROXY_POLICY) 353DECLARE_ASN1_FUNCTIONS(PROXY_POLICY)
330DECLARE_ASN1_FUNCTIONS(PROXY_CERT_INFO_EXTENSION) 354DECLARE_ASN1_FUNCTIONS(PROXY_CERT_INFO_EXTENSION)
331 355
356struct ISSUING_DIST_POINT_st
357 {
358 DIST_POINT_NAME *distpoint;
359 int onlyuser;
360 int onlyCA;
361 ASN1_BIT_STRING *onlysomereasons;
362 int indirectCRL;
363 int onlyattr;
364 };
365
366/* Values in idp_flags field */
367/* IDP present */
368#define IDP_PRESENT 0x1
369/* IDP values inconsistent */
370#define IDP_INVALID 0x2
371/* onlyuser true */
372#define IDP_ONLYUSER 0x4
373/* onlyCA true */
374#define IDP_ONLYCA 0x8
375/* onlyattr true */
376#define IDP_ONLYATTR 0x10
377/* indirectCRL true */
378#define IDP_INDIRECT 0x20
379/* onlysomereasons present */
380#define IDP_REASONS 0x40
332 381
333#define X509V3_conf_err(val) ERR_add_error_data(6, "section:", val->section, \ 382#define X509V3_conf_err(val) ERR_add_error_data(6, "section:", val->section, \
334",name:", val->name, ",value:", val->value); 383",name:", val->name, ",value:", val->value);
@@ -373,6 +422,7 @@ DECLARE_ASN1_FUNCTIONS(PROXY_CERT_INFO_EXTENSION)
373#define EXFLAG_PROXY 0x400 422#define EXFLAG_PROXY 0x400
374 423
375#define EXFLAG_INVALID_POLICY 0x800 424#define EXFLAG_INVALID_POLICY 0x800
425#define EXFLAG_FRESHEST 0x1000
376 426
377#define KU_DIGITAL_SIGNATURE 0x0080 427#define KU_DIGITAL_SIGNATURE 0x0080
378#define KU_NON_REPUDIATION 0x0040 428#define KU_NON_REPUDIATION 0x0040
@@ -424,9 +474,10 @@ typedef struct x509_purpose_st {
424#define X509_PURPOSE_CRL_SIGN 6 474#define X509_PURPOSE_CRL_SIGN 6
425#define X509_PURPOSE_ANY 7 475#define X509_PURPOSE_ANY 7
426#define X509_PURPOSE_OCSP_HELPER 8 476#define X509_PURPOSE_OCSP_HELPER 8
477#define X509_PURPOSE_TIMESTAMP_SIGN 9
427 478
428#define X509_PURPOSE_MIN 1 479#define X509_PURPOSE_MIN 1
429#define X509_PURPOSE_MAX 8 480#define X509_PURPOSE_MAX 9
430 481
431/* Flags for X509V3_EXT_print() */ 482/* Flags for X509V3_EXT_print() */
432 483
@@ -471,6 +522,9 @@ DECLARE_ASN1_FUNCTIONS(AUTHORITY_KEYID)
471DECLARE_ASN1_FUNCTIONS(PKEY_USAGE_PERIOD) 522DECLARE_ASN1_FUNCTIONS(PKEY_USAGE_PERIOD)
472 523
473DECLARE_ASN1_FUNCTIONS(GENERAL_NAME) 524DECLARE_ASN1_FUNCTIONS(GENERAL_NAME)
525GENERAL_NAME *GENERAL_NAME_dup(GENERAL_NAME *a);
526int GENERAL_NAME_cmp(GENERAL_NAME *a, GENERAL_NAME *b);
527
474 528
475 529
476ASN1_BIT_STRING *v2i_ASN1_BIT_STRING(X509V3_EXT_METHOD *method, 530ASN1_BIT_STRING *v2i_ASN1_BIT_STRING(X509V3_EXT_METHOD *method,
@@ -486,11 +540,18 @@ DECLARE_ASN1_FUNCTIONS(GENERAL_NAMES)
486 540
487STACK_OF(CONF_VALUE) *i2v_GENERAL_NAMES(X509V3_EXT_METHOD *method, 541STACK_OF(CONF_VALUE) *i2v_GENERAL_NAMES(X509V3_EXT_METHOD *method,
488 GENERAL_NAMES *gen, STACK_OF(CONF_VALUE) *extlist); 542 GENERAL_NAMES *gen, STACK_OF(CONF_VALUE) *extlist);
489GENERAL_NAMES *v2i_GENERAL_NAMES(X509V3_EXT_METHOD *method, 543GENERAL_NAMES *v2i_GENERAL_NAMES(const X509V3_EXT_METHOD *method,
490 X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval); 544 X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval);
491 545
492DECLARE_ASN1_FUNCTIONS(OTHERNAME) 546DECLARE_ASN1_FUNCTIONS(OTHERNAME)
493DECLARE_ASN1_FUNCTIONS(EDIPARTYNAME) 547DECLARE_ASN1_FUNCTIONS(EDIPARTYNAME)
548int OTHERNAME_cmp(OTHERNAME *a, OTHERNAME *b);
549void GENERAL_NAME_set0_value(GENERAL_NAME *a, int type, void *value);
550void *GENERAL_NAME_get0_value(GENERAL_NAME *a, int *ptype);
551int GENERAL_NAME_set0_othername(GENERAL_NAME *gen,
552 ASN1_OBJECT *oid, ASN1_TYPE *value);
553int GENERAL_NAME_get0_otherName(GENERAL_NAME *gen,
554 ASN1_OBJECT **poid, ASN1_TYPE **pvalue);
494 555
495char *i2s_ASN1_OCTET_STRING(X509V3_EXT_METHOD *method, ASN1_OCTET_STRING *ia5); 556char *i2s_ASN1_OCTET_STRING(X509V3_EXT_METHOD *method, ASN1_OCTET_STRING *ia5);
496ASN1_OCTET_STRING *s2i_ASN1_OCTET_STRING(X509V3_EXT_METHOD *method, X509V3_CTX *ctx, char *str); 557ASN1_OCTET_STRING *s2i_ASN1_OCTET_STRING(X509V3_EXT_METHOD *method, X509V3_CTX *ctx, char *str);
@@ -507,6 +568,11 @@ DECLARE_ASN1_FUNCTIONS(NOTICEREF)
507DECLARE_ASN1_FUNCTIONS(CRL_DIST_POINTS) 568DECLARE_ASN1_FUNCTIONS(CRL_DIST_POINTS)
508DECLARE_ASN1_FUNCTIONS(DIST_POINT) 569DECLARE_ASN1_FUNCTIONS(DIST_POINT)
509DECLARE_ASN1_FUNCTIONS(DIST_POINT_NAME) 570DECLARE_ASN1_FUNCTIONS(DIST_POINT_NAME)
571DECLARE_ASN1_FUNCTIONS(ISSUING_DIST_POINT)
572
573int DIST_POINT_set_dpname(DIST_POINT_NAME *dpn, X509_NAME *iname);
574
575int NAME_CONSTRAINTS_check(X509 *x, NAME_CONSTRAINTS *nc);
510 576
511DECLARE_ASN1_FUNCTIONS(ACCESS_DESCRIPTION) 577DECLARE_ASN1_FUNCTIONS(ACCESS_DESCRIPTION)
512DECLARE_ASN1_FUNCTIONS(AUTHORITY_INFO_ACCESS) 578DECLARE_ASN1_FUNCTIONS(AUTHORITY_INFO_ACCESS)
@@ -524,11 +590,16 @@ DECLARE_ASN1_ALLOC_FUNCTIONS(NAME_CONSTRAINTS)
524DECLARE_ASN1_ALLOC_FUNCTIONS(POLICY_CONSTRAINTS) 590DECLARE_ASN1_ALLOC_FUNCTIONS(POLICY_CONSTRAINTS)
525DECLARE_ASN1_ITEM(POLICY_CONSTRAINTS) 591DECLARE_ASN1_ITEM(POLICY_CONSTRAINTS)
526 592
593GENERAL_NAME *a2i_GENERAL_NAME(GENERAL_NAME *out,
594 const X509V3_EXT_METHOD *method, X509V3_CTX *ctx,
595 int gen_type, char *value, int is_nc);
596
527#ifdef HEADER_CONF_H 597#ifdef HEADER_CONF_H
528GENERAL_NAME *v2i_GENERAL_NAME(X509V3_EXT_METHOD *method, X509V3_CTX *ctx, 598GENERAL_NAME *v2i_GENERAL_NAME(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx,
529 CONF_VALUE *cnf); 599 CONF_VALUE *cnf);
530GENERAL_NAME *v2i_GENERAL_NAME_ex(GENERAL_NAME *out, X509V3_EXT_METHOD *method, 600GENERAL_NAME *v2i_GENERAL_NAME_ex(GENERAL_NAME *out,
531 X509V3_CTX *ctx, CONF_VALUE *cnf, int is_nc); 601 const X509V3_EXT_METHOD *method,
602 X509V3_CTX *ctx, CONF_VALUE *cnf, int is_nc);
532void X509V3_conf_free(CONF_VALUE *val); 603void X509V3_conf_free(CONF_VALUE *val);
533 604
534X509_EXTENSION *X509V3_EXT_nconf_nid(CONF *conf, X509V3_CTX *ctx, int ext_nid, char *value); 605X509_EXTENSION *X509V3_EXT_nconf_nid(CONF *conf, X509V3_CTX *ctx, int ext_nid, char *value);
@@ -538,18 +609,23 @@ int X509V3_EXT_add_nconf(CONF *conf, X509V3_CTX *ctx, char *section, X509 *cert)
538int X509V3_EXT_REQ_add_nconf(CONF *conf, X509V3_CTX *ctx, char *section, X509_REQ *req); 609int X509V3_EXT_REQ_add_nconf(CONF *conf, X509V3_CTX *ctx, char *section, X509_REQ *req);
539int X509V3_EXT_CRL_add_nconf(CONF *conf, X509V3_CTX *ctx, char *section, X509_CRL *crl); 610int X509V3_EXT_CRL_add_nconf(CONF *conf, X509V3_CTX *ctx, char *section, X509_CRL *crl);
540 611
541X509_EXTENSION *X509V3_EXT_conf_nid(LHASH *conf, X509V3_CTX *ctx, int ext_nid, char *value); 612X509_EXTENSION *X509V3_EXT_conf_nid(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx,
542X509_EXTENSION *X509V3_EXT_conf(LHASH *conf, X509V3_CTX *ctx, char *name, char *value); 613 int ext_nid, char *value);
543int X509V3_EXT_add_conf(LHASH *conf, X509V3_CTX *ctx, char *section, X509 *cert); 614X509_EXTENSION *X509V3_EXT_conf(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx,
544int X509V3_EXT_REQ_add_conf(LHASH *conf, X509V3_CTX *ctx, char *section, X509_REQ *req); 615 char *name, char *value);
545int X509V3_EXT_CRL_add_conf(LHASH *conf, X509V3_CTX *ctx, char *section, X509_CRL *crl); 616int X509V3_EXT_add_conf(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx,
617 char *section, X509 *cert);
618int X509V3_EXT_REQ_add_conf(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx,
619 char *section, X509_REQ *req);
620int X509V3_EXT_CRL_add_conf(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx,
621 char *section, X509_CRL *crl);
546 622
547int X509V3_add_value_bool_nf(char *name, int asn1_bool, 623int X509V3_add_value_bool_nf(char *name, int asn1_bool,
548 STACK_OF(CONF_VALUE) **extlist); 624 STACK_OF(CONF_VALUE) **extlist);
549int X509V3_get_value_bool(CONF_VALUE *value, int *asn1_bool); 625int X509V3_get_value_bool(CONF_VALUE *value, int *asn1_bool);
550int X509V3_get_value_int(CONF_VALUE *value, ASN1_INTEGER **aint); 626int X509V3_get_value_int(CONF_VALUE *value, ASN1_INTEGER **aint);
551void X509V3_set_nconf(X509V3_CTX *ctx, CONF *conf); 627void X509V3_set_nconf(X509V3_CTX *ctx, CONF *conf);
552void X509V3_set_conf_lhash(X509V3_CTX *ctx, LHASH *lhash); 628void X509V3_set_conf_lhash(X509V3_CTX *ctx, LHASH_OF(CONF_VALUE) *lhash);
553#endif 629#endif
554 630
555char * X509V3_get_string(X509V3_CTX *ctx, char *name, char *section); 631char * X509V3_get_string(X509V3_CTX *ctx, char *name, char *section);
@@ -576,8 +652,8 @@ int X509V3_EXT_add_list(X509V3_EXT_METHOD *extlist);
576int X509V3_EXT_add_alias(int nid_to, int nid_from); 652int X509V3_EXT_add_alias(int nid_to, int nid_from);
577void X509V3_EXT_cleanup(void); 653void X509V3_EXT_cleanup(void);
578 654
579X509V3_EXT_METHOD *X509V3_EXT_get(X509_EXTENSION *ext); 655const X509V3_EXT_METHOD *X509V3_EXT_get(X509_EXTENSION *ext);
580X509V3_EXT_METHOD *X509V3_EXT_get_nid(int nid); 656const X509V3_EXT_METHOD *X509V3_EXT_get_nid(int nid);
581int X509V3_add_standard_extensions(void); 657int X509V3_add_standard_extensions(void);
582STACK_OF(CONF_VALUE) *X509V3_parse_list(const char *line); 658STACK_OF(CONF_VALUE) *X509V3_parse_list(const char *line);
583void *X509V3_EXT_d2i(X509_EXTENSION *ext); 659void *X509V3_EXT_d2i(X509_EXTENSION *ext);
@@ -587,8 +663,8 @@ void *X509V3_get_d2i(STACK_OF(X509_EXTENSION) *x, int nid, int *crit, int *idx);
587X509_EXTENSION *X509V3_EXT_i2d(int ext_nid, int crit, void *ext_struc); 663X509_EXTENSION *X509V3_EXT_i2d(int ext_nid, int crit, void *ext_struc);
588int X509V3_add1_i2d(STACK_OF(X509_EXTENSION) **x, int nid, void *value, int crit, unsigned long flags); 664int X509V3_add1_i2d(STACK_OF(X509_EXTENSION) **x, int nid, void *value, int crit, unsigned long flags);
589 665
590char *hex_to_string(unsigned char *buffer, long len); 666char *hex_to_string(const unsigned char *buffer, long len);
591unsigned char *string_to_hex(char *str, long *len); 667unsigned char *string_to_hex(const char *str, long *len);
592int name_cmp(const char *name, const char *cmp); 668int name_cmp(const char *name, const char *cmp);
593 669
594void X509V3_EXT_val_prn(BIO *out, STACK_OF(CONF_VALUE) *val, int indent, 670void X509V3_EXT_val_prn(BIO *out, STACK_OF(CONF_VALUE) *val, int indent,
@@ -603,6 +679,7 @@ int X509_check_purpose(X509 *x, int id, int ca);
603int X509_supported_extension(X509_EXTENSION *ex); 679int X509_supported_extension(X509_EXTENSION *ex);
604int X509_PURPOSE_set(int *p, int purpose); 680int X509_PURPOSE_set(int *p, int purpose);
605int X509_check_issued(X509 *issuer, X509 *subject); 681int X509_check_issued(X509 *issuer, X509 *subject);
682int X509_check_akid(X509 *issuer, AUTHORITY_KEYID *akid);
606int X509_PURPOSE_get_count(void); 683int X509_PURPOSE_get_count(void);
607X509_PURPOSE * X509_PURPOSE_get0(int idx); 684X509_PURPOSE * X509_PURPOSE_get0(int idx);
608int X509_PURPOSE_get_by_sname(char *sname); 685int X509_PURPOSE_get_by_sname(char *sname);
@@ -616,10 +693,10 @@ int X509_PURPOSE_get_trust(X509_PURPOSE *xp);
616void X509_PURPOSE_cleanup(void); 693void X509_PURPOSE_cleanup(void);
617int X509_PURPOSE_get_id(X509_PURPOSE *); 694int X509_PURPOSE_get_id(X509_PURPOSE *);
618 695
619STACK *X509_get1_email(X509 *x); 696STACK_OF(OPENSSL_STRING) *X509_get1_email(X509 *x);
620STACK *X509_REQ_get1_email(X509_REQ *x); 697STACK_OF(OPENSSL_STRING) *X509_REQ_get1_email(X509_REQ *x);
621void X509_email_free(STACK *sk); 698void X509_email_free(STACK_OF(OPENSSL_STRING) *sk);
622STACK *X509_get1_ocsp(X509 *x); 699STACK_OF(OPENSSL_STRING) *X509_get1_ocsp(X509 *x);
623 700
624ASN1_OCTET_STRING *a2i_IPADDRESS(const char *ipasc); 701ASN1_OCTET_STRING *a2i_IPADDRESS(const char *ipasc);
625ASN1_OCTET_STRING *a2i_IPADDRESS_NC(const char *ipasc); 702ASN1_OCTET_STRING *a2i_IPADDRESS_NC(const char *ipasc);
@@ -628,6 +705,7 @@ int X509V3_NAME_from_section(X509_NAME *nm, STACK_OF(CONF_VALUE)*dn_sk,
628 unsigned long chtype); 705 unsigned long chtype);
629 706
630void X509_POLICY_NODE_print(BIO *out, X509_POLICY_NODE *node, int indent); 707void X509_POLICY_NODE_print(BIO *out, X509_POLICY_NODE *node, int indent);
708DECLARE_STACK_OF(X509_POLICY_NODE)
631 709
632#ifndef OPENSSL_NO_RFC3779 710#ifndef OPENSSL_NO_RFC3779
633 711
@@ -787,8 +865,9 @@ void ERR_load_X509V3_strings(void);
787/* Error codes for the X509V3 functions. */ 865/* Error codes for the X509V3 functions. */
788 866
789/* Function codes. */ 867/* Function codes. */
790#define X509V3_F_ASIDENTIFIERCHOICE_CANONIZE 156 868#define X509V3_F_A2I_GENERAL_NAME 164
791#define X509V3_F_ASIDENTIFIERCHOICE_IS_CANONICAL 157 869#define X509V3_F_ASIDENTIFIERCHOICE_CANONIZE 161
870#define X509V3_F_ASIDENTIFIERCHOICE_IS_CANONICAL 162
792#define X509V3_F_COPY_EMAIL 122 871#define X509V3_F_COPY_EMAIL 122
793#define X509V3_F_COPY_ISSUER 123 872#define X509V3_F_COPY_ISSUER 123
794#define X509V3_F_DO_DIRNAME 144 873#define X509V3_F_DO_DIRNAME 144
@@ -796,6 +875,7 @@ void ERR_load_X509V3_strings(void);
796#define X509V3_F_DO_EXT_I2D 135 875#define X509V3_F_DO_EXT_I2D 135
797#define X509V3_F_DO_EXT_NCONF 151 876#define X509V3_F_DO_EXT_NCONF 151
798#define X509V3_F_DO_I2V_NAME_CONSTRAINTS 148 877#define X509V3_F_DO_I2V_NAME_CONSTRAINTS 148
878#define X509V3_F_GNAMES_FROM_SECTNAME 156
799#define X509V3_F_HEX_TO_STRING 111 879#define X509V3_F_HEX_TO_STRING 111
800#define X509V3_F_I2S_ASN1_ENUMERATED 121 880#define X509V3_F_I2S_ASN1_ENUMERATED 121
801#define X509V3_F_I2S_ASN1_IA5STRING 149 881#define X509V3_F_I2S_ASN1_IA5STRING 149
@@ -812,13 +892,14 @@ void ERR_load_X509V3_strings(void);
812#define X509V3_F_S2I_ASN1_OCTET_STRING 112 892#define X509V3_F_S2I_ASN1_OCTET_STRING 112
813#define X509V3_F_S2I_ASN1_SKEY_ID 114 893#define X509V3_F_S2I_ASN1_SKEY_ID 114
814#define X509V3_F_S2I_SKEY_ID 115 894#define X509V3_F_S2I_SKEY_ID 115
895#define X509V3_F_SET_DIST_POINT_NAME 158
815#define X509V3_F_STRING_TO_HEX 113 896#define X509V3_F_STRING_TO_HEX 113
816#define X509V3_F_SXNET_ADD_ID_ASC 125 897#define X509V3_F_SXNET_ADD_ID_ASC 125
817#define X509V3_F_SXNET_ADD_ID_INTEGER 126 898#define X509V3_F_SXNET_ADD_ID_INTEGER 126
818#define X509V3_F_SXNET_ADD_ID_ULONG 127 899#define X509V3_F_SXNET_ADD_ID_ULONG 127
819#define X509V3_F_SXNET_GET_ID_ASC 128 900#define X509V3_F_SXNET_GET_ID_ASC 128
820#define X509V3_F_SXNET_GET_ID_ULONG 129 901#define X509V3_F_SXNET_GET_ID_ULONG 129
821#define X509V3_F_V2I_ASIDENTIFIERS 158 902#define X509V3_F_V2I_ASIDENTIFIERS 163
822#define X509V3_F_V2I_ASN1_BIT_STRING 101 903#define X509V3_F_V2I_ASN1_BIT_STRING 101
823#define X509V3_F_V2I_AUTHORITY_INFO_ACCESS 139 904#define X509V3_F_V2I_AUTHORITY_INFO_ACCESS 139
824#define X509V3_F_V2I_AUTHORITY_KEYID 119 905#define X509V3_F_V2I_AUTHORITY_KEYID 119
@@ -827,6 +908,7 @@ void ERR_load_X509V3_strings(void);
827#define X509V3_F_V2I_EXTENDED_KEY_USAGE 103 908#define X509V3_F_V2I_EXTENDED_KEY_USAGE 103
828#define X509V3_F_V2I_GENERAL_NAMES 118 909#define X509V3_F_V2I_GENERAL_NAMES 118
829#define X509V3_F_V2I_GENERAL_NAME_EX 117 910#define X509V3_F_V2I_GENERAL_NAME_EX 117
911#define X509V3_F_V2I_IDP 157
830#define X509V3_F_V2I_IPADDRBLOCKS 159 912#define X509V3_F_V2I_IPADDRBLOCKS 159
831#define X509V3_F_V2I_ISSUER_ALT 153 913#define X509V3_F_V2I_ISSUER_ALT 153
832#define X509V3_F_V2I_NAME_CONSTRAINTS 147 914#define X509V3_F_V2I_NAME_CONSTRAINTS 147
@@ -855,6 +937,7 @@ void ERR_load_X509V3_strings(void);
855#define X509V3_R_BN_DEC2BN_ERROR 100 937#define X509V3_R_BN_DEC2BN_ERROR 100
856#define X509V3_R_BN_TO_ASN1_INTEGER_ERROR 101 938#define X509V3_R_BN_TO_ASN1_INTEGER_ERROR 101
857#define X509V3_R_DIRNAME_ERROR 149 939#define X509V3_R_DIRNAME_ERROR 149
940#define X509V3_R_DISTPOINT_ALREADY_SET 160
858#define X509V3_R_DUPLICATE_ZONE_ID 133 941#define X509V3_R_DUPLICATE_ZONE_ID 133
859#define X509V3_R_ERROR_CONVERTING_ZONE 131 942#define X509V3_R_ERROR_CONVERTING_ZONE 131
860#define X509V3_R_ERROR_CREATING_EXTENSION 144 943#define X509V3_R_ERROR_CREATING_EXTENSION 144
@@ -868,12 +951,13 @@ void ERR_load_X509V3_strings(void);
868#define X509V3_R_ILLEGAL_EMPTY_EXTENSION 151 951#define X509V3_R_ILLEGAL_EMPTY_EXTENSION 151
869#define X509V3_R_ILLEGAL_HEX_DIGIT 113 952#define X509V3_R_ILLEGAL_HEX_DIGIT 113
870#define X509V3_R_INCORRECT_POLICY_SYNTAX_TAG 152 953#define X509V3_R_INCORRECT_POLICY_SYNTAX_TAG 152
871#define X509V3_R_INVALID_ASNUMBER 160 954#define X509V3_R_INVALID_MULTIPLE_RDNS 161
872#define X509V3_R_INVALID_ASRANGE 161 955#define X509V3_R_INVALID_ASNUMBER 162
956#define X509V3_R_INVALID_ASRANGE 163
873#define X509V3_R_INVALID_BOOLEAN_STRING 104 957#define X509V3_R_INVALID_BOOLEAN_STRING 104
874#define X509V3_R_INVALID_EXTENSION_STRING 105 958#define X509V3_R_INVALID_EXTENSION_STRING 105
875#define X509V3_R_INVALID_INHERITANCE 162 959#define X509V3_R_INVALID_INHERITANCE 165
876#define X509V3_R_INVALID_IPADDRESS 163 960#define X509V3_R_INVALID_IPADDRESS 166
877#define X509V3_R_INVALID_NAME 106 961#define X509V3_R_INVALID_NAME 106
878#define X509V3_R_INVALID_NULL_ARGUMENT 107 962#define X509V3_R_INVALID_NULL_ARGUMENT 107
879#define X509V3_R_INVALID_NULL_NAME 108 963#define X509V3_R_INVALID_NULL_NAME 108
@@ -901,9 +985,9 @@ void ERR_load_X509V3_strings(void);
901#define X509V3_R_ODD_NUMBER_OF_DIGITS 112 985#define X509V3_R_ODD_NUMBER_OF_DIGITS 112
902#define X509V3_R_OPERATION_NOT_DEFINED 148 986#define X509V3_R_OPERATION_NOT_DEFINED 148
903#define X509V3_R_OTHERNAME_ERROR 147 987#define X509V3_R_OTHERNAME_ERROR 147
904#define X509V3_R_POLICY_LANGUAGE_ALREADTY_DEFINED 155 988#define X509V3_R_POLICY_LANGUAGE_ALREADY_DEFINED 155
905#define X509V3_R_POLICY_PATH_LENGTH 156 989#define X509V3_R_POLICY_PATH_LENGTH 156
906#define X509V3_R_POLICY_PATH_LENGTH_ALREADTY_DEFINED 157 990#define X509V3_R_POLICY_PATH_LENGTH_ALREADY_DEFINED 157
907#define X509V3_R_POLICY_SYNTAX_NOT_CURRENTLY_SUPPORTED 158 991#define X509V3_R_POLICY_SYNTAX_NOT_CURRENTLY_SUPPORTED 158
908#define X509V3_R_POLICY_WHEN_PROXY_LANGUAGE_REQUIRES_NO_POLICY 159 992#define X509V3_R_POLICY_WHEN_PROXY_LANGUAGE_REQUIRES_NO_POLICY 159
909#define X509V3_R_SECTION_NOT_FOUND 150 993#define X509V3_R_SECTION_NOT_FOUND 150
@@ -914,6 +998,7 @@ void ERR_load_X509V3_strings(void);
914#define X509V3_R_UNKNOWN_EXTENSION_NAME 130 998#define X509V3_R_UNKNOWN_EXTENSION_NAME 130
915#define X509V3_R_UNKNOWN_OPTION 120 999#define X509V3_R_UNKNOWN_OPTION 120
916#define X509V3_R_UNSUPPORTED_OPTION 117 1000#define X509V3_R_UNSUPPORTED_OPTION 117
1001#define X509V3_R_UNSUPPORTED_TYPE 167
917#define X509V3_R_USER_TOO_LONG 132 1002#define X509V3_R_USER_TOO_LONG 132
918 1003
919#ifdef __cplusplus 1004#ifdef __cplusplus
diff --git a/src/lib/libcrypto/x86_64cpuid.pl b/src/lib/libcrypto/x86_64cpuid.pl
index 2616a03da6..c96821a3c8 100644
--- a/src/lib/libcrypto/x86_64cpuid.pl
+++ b/src/lib/libcrypto/x86_64cpuid.pl
@@ -1,108 +1,37 @@
1#!/usr/bin/env perl 1#!/usr/bin/env perl
2 2
3$output=shift; 3$flavour = shift;
4$masm=1 if ($output =~ /\.asm/); 4$output = shift;
5open STDOUT,">$output" || die "can't open $output: $!"; 5if ($flavour =~ /\./) { $output = $flavour; undef $flavour; }
6
7print<<___ if(defined($masm));
8_TEXT SEGMENT
9PUBLIC OPENSSL_rdtsc
10
11PUBLIC OPENSSL_atomic_add
12ALIGN 16
13OPENSSL_atomic_add PROC
14 mov eax,DWORD PTR[rcx]
15\$Lspin: lea r8,DWORD PTR[rdx+rax]
16lock cmpxchg DWORD PTR[rcx],r8d
17 jne \$Lspin
18 mov eax,r8d
19 cdqe
20 ret
21OPENSSL_atomic_add ENDP
22
23PUBLIC OPENSSL_wipe_cpu
24ALIGN 16
25OPENSSL_wipe_cpu PROC
26 pxor xmm0,xmm0
27 pxor xmm1,xmm1
28 pxor xmm2,xmm2
29 pxor xmm3,xmm3
30 pxor xmm4,xmm4
31 pxor xmm5,xmm5
32 xor rcx,rcx
33 xor rdx,rdx
34 xor r8,r8
35 xor r9,r9
36 xor r10,r10
37 xor r11,r11
38 lea rax,QWORD PTR[rsp+8]
39 ret
40OPENSSL_wipe_cpu ENDP
41_TEXT ENDS
42 6
43CRT\$XIU SEGMENT 7$win64=0; $win64=1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/);
44EXTRN OPENSSL_cpuid_setup:PROC 8
45DQ OPENSSL_cpuid_setup 9$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
46CRT\$XIU ENDS 10open STDOUT,"| $^X ${dir}perlasm/x86_64-xlate.pl $flavour $output";
11
12if ($win64) { $arg1="%rcx"; $arg2="%rdx"; }
13else { $arg1="%rdi"; $arg2="%rsi"; }
14print<<___;
15.extern OPENSSL_cpuid_setup
16.section .init
17 call OPENSSL_cpuid_setup
47 18
48___
49print<<___ if(!defined($masm));
50.text 19.text
51 20
52.globl OPENSSL_atomic_add 21.globl OPENSSL_atomic_add
53.type OPENSSL_atomic_add,\@function 22.type OPENSSL_atomic_add,\@abi-omnipotent
54.align 16 23.align 16
55OPENSSL_atomic_add: 24OPENSSL_atomic_add:
56 movl (%rdi),%eax 25 movl ($arg1),%eax
57.Lspin: leaq (%rsi,%rax),%r8 26.Lspin: leaq ($arg2,%rax),%r8
58lock; cmpxchgl %r8d,(%rdi) 27 .byte 0xf0 # lock
28 cmpxchgl %r8d,($arg1)
59 jne .Lspin 29 jne .Lspin
60 movl %r8d,%eax 30 movl %r8d,%eax
61 .byte 0x48,0x98 31 .byte 0x48,0x98 # cltq/cdqe
62 ret 32 ret
63.size OPENSSL_atomic_add,.-OPENSSL_atomic_add 33.size OPENSSL_atomic_add,.-OPENSSL_atomic_add
64 34
65.globl OPENSSL_wipe_cpu
66.type OPENSSL_wipe_cpu,\@function
67.align 16
68OPENSSL_wipe_cpu:
69 pxor %xmm0,%xmm0
70 pxor %xmm1,%xmm1
71 pxor %xmm2,%xmm2
72 pxor %xmm3,%xmm3
73 pxor %xmm4,%xmm4
74 pxor %xmm5,%xmm5
75 pxor %xmm6,%xmm6
76 pxor %xmm7,%xmm7
77 pxor %xmm8,%xmm8
78 pxor %xmm9,%xmm9
79 pxor %xmm10,%xmm10
80 pxor %xmm11,%xmm11
81 pxor %xmm12,%xmm12
82 pxor %xmm13,%xmm13
83 pxor %xmm14,%xmm14
84 pxor %xmm15,%xmm15
85 xorq %rcx,%rcx
86 xorq %rdx,%rdx
87 xorq %rsi,%rsi
88 xorq %rdi,%rdi
89 xorq %r8,%r8
90 xorq %r9,%r9
91 xorq %r10,%r10
92 xorq %r11,%r11
93 leaq 8(%rsp),%rax
94 ret
95.size OPENSSL_wipe_cpu,.-OPENSSL_wipe_cpu
96
97.section .init
98 call OPENSSL_cpuid_setup
99
100___
101
102open STDOUT,"| $^X perlasm/x86_64-xlate.pl $output";
103print<<___;
104.text
105
106.globl OPENSSL_rdtsc 35.globl OPENSSL_rdtsc
107.type OPENSSL_rdtsc,\@abi-omnipotent 36.type OPENSSL_rdtsc,\@abi-omnipotent
108.align 16 37.align 16
@@ -121,6 +50,8 @@ OPENSSL_ia32_cpuid:
121 50
122 xor %eax,%eax 51 xor %eax,%eax
123 cpuid 52 cpuid
53 mov %eax,%r11d # max value for standard query level
54
124 xor %eax,%eax 55 xor %eax,%eax
125 cmp \$0x756e6547,%ebx # "Genu" 56 cmp \$0x756e6547,%ebx # "Genu"
126 setne %al 57 setne %al
@@ -130,10 +61,56 @@ OPENSSL_ia32_cpuid:
130 or %eax,%r9d 61 or %eax,%r9d
131 cmp \$0x6c65746e,%ecx # "ntel" 62 cmp \$0x6c65746e,%ecx # "ntel"
132 setne %al 63 setne %al
133 or %eax,%r9d 64 or %eax,%r9d # 0 indicates Intel CPU
65 jz .Lintel
66
67 cmp \$0x68747541,%ebx # "Auth"
68 setne %al
69 mov %eax,%r10d
70 cmp \$0x69746E65,%edx # "enti"
71 setne %al
72 or %eax,%r10d
73 cmp \$0x444D4163,%ecx # "cAMD"
74 setne %al
75 or %eax,%r10d # 0 indicates AMD CPU
76 jnz .Lintel
77
78 # AMD specific
79 mov \$0x80000000,%eax
80 cpuid
81 cmp \$0x80000008,%eax
82 jb .Lintel
83
84 mov \$0x80000008,%eax
85 cpuid
86 movzb %cl,%r10 # number of cores - 1
87 inc %r10 # number of cores
134 88
135 mov \$1,%eax 89 mov \$1,%eax
136 cpuid 90 cpuid
91 bt \$28,%edx # test hyper-threading bit
92 jnc .Ldone
93 shr \$16,%ebx # number of logical processors
94 cmp %r10b,%bl
95 ja .Ldone
96 and \$0xefffffff,%edx # ~(1<<28)
97 jmp .Ldone
98
99.Lintel:
100 cmp \$4,%r11d
101 mov \$-1,%r10d
102 jb .Lnocacheinfo
103
104 mov \$4,%eax
105 mov \$0,%ecx # query L1D
106 cpuid
107 mov %eax,%r10d
108 shr \$14,%r10d
109 and \$0xfff,%r10d # number of cores -1 per L1D
110
111.Lnocacheinfo:
112 mov \$1,%eax
113 cpuid
137 cmp \$0,%r9d 114 cmp \$0,%r9d
138 jne .Lnotintel 115 jne .Lnotintel
139 or \$0x00100000,%edx # use reserved 20th bit to engage RC4_CHAR 116 or \$0x00100000,%edx # use reserved 20th bit to engage RC4_CHAR
@@ -144,6 +121,11 @@ OPENSSL_ia32_cpuid:
144.Lnotintel: 121.Lnotintel:
145 bt \$28,%edx # test hyper-threading bit 122 bt \$28,%edx # test hyper-threading bit
146 jnc .Ldone 123 jnc .Ldone
124 and \$0xefffffff,%edx # ~(1<<28)
125 cmp \$0,%r10d
126 je .Ldone
127
128 or \$0x10000000,%edx # 1<<28
147 shr \$16,%ebx 129 shr \$16,%ebx
148 cmp \$1,%bl # see if cache is shared 130 cmp \$1,%bl # see if cache is shared
149 ja .Ldone 131 ja .Ldone
@@ -155,5 +137,96 @@ OPENSSL_ia32_cpuid:
155 or %rcx,%rax 137 or %rcx,%rax
156 ret 138 ret
157.size OPENSSL_ia32_cpuid,.-OPENSSL_ia32_cpuid 139.size OPENSSL_ia32_cpuid,.-OPENSSL_ia32_cpuid
140
141.globl OPENSSL_cleanse
142.type OPENSSL_cleanse,\@abi-omnipotent
143.align 16
144OPENSSL_cleanse:
145 xor %rax,%rax
146 cmp \$15,$arg2
147 jae .Lot
148 cmp \$0,$arg2
149 je .Lret
150.Little:
151 mov %al,($arg1)
152 sub \$1,$arg2
153 lea 1($arg1),$arg1
154 jnz .Little
155.Lret:
156 ret
157.align 16
158.Lot:
159 test \$7,$arg1
160 jz .Laligned
161 mov %al,($arg1)
162 lea -1($arg2),$arg2
163 lea 1($arg1),$arg1
164 jmp .Lot
165.Laligned:
166 mov %rax,($arg1)
167 lea -8($arg2),$arg2
168 test \$-8,$arg2
169 lea 8($arg1),$arg1
170 jnz .Laligned
171 cmp \$0,$arg2
172 jne .Little
173 ret
174.size OPENSSL_cleanse,.-OPENSSL_cleanse
175___
176
177print<<___ if (!$win64);
178.globl OPENSSL_wipe_cpu
179.type OPENSSL_wipe_cpu,\@abi-omnipotent
180.align 16
181OPENSSL_wipe_cpu:
182 pxor %xmm0,%xmm0
183 pxor %xmm1,%xmm1
184 pxor %xmm2,%xmm2
185 pxor %xmm3,%xmm3
186 pxor %xmm4,%xmm4
187 pxor %xmm5,%xmm5
188 pxor %xmm6,%xmm6
189 pxor %xmm7,%xmm7
190 pxor %xmm8,%xmm8
191 pxor %xmm9,%xmm9
192 pxor %xmm10,%xmm10
193 pxor %xmm11,%xmm11
194 pxor %xmm12,%xmm12
195 pxor %xmm13,%xmm13
196 pxor %xmm14,%xmm14
197 pxor %xmm15,%xmm15
198 xorq %rcx,%rcx
199 xorq %rdx,%rdx
200 xorq %rsi,%rsi
201 xorq %rdi,%rdi
202 xorq %r8,%r8
203 xorq %r9,%r9
204 xorq %r10,%r10
205 xorq %r11,%r11
206 leaq 8(%rsp),%rax
207 ret
208.size OPENSSL_wipe_cpu,.-OPENSSL_wipe_cpu
158___ 209___
210print<<___ if ($win64);
211.globl OPENSSL_wipe_cpu
212.type OPENSSL_wipe_cpu,\@abi-omnipotent
213.align 16
214OPENSSL_wipe_cpu:
215 pxor %xmm0,%xmm0
216 pxor %xmm1,%xmm1
217 pxor %xmm2,%xmm2
218 pxor %xmm3,%xmm3
219 pxor %xmm4,%xmm4
220 pxor %xmm5,%xmm5
221 xorq %rcx,%rcx
222 xorq %rdx,%rdx
223 xorq %r8,%r8
224 xorq %r9,%r9
225 xorq %r10,%r10
226 xorq %r11,%r11
227 leaq 8(%rsp),%rax
228 ret
229.size OPENSSL_wipe_cpu,.-OPENSSL_wipe_cpu
230___
231
159close STDOUT; # flush 232close STDOUT; # flush
diff --git a/src/lib/libcrypto/x86cpuid.pl b/src/lib/libcrypto/x86cpuid.pl
index 4408ef2936..a7464af19b 100644
--- a/src/lib/libcrypto/x86cpuid.pl
+++ b/src/lib/libcrypto/x86cpuid.pl
@@ -1,6 +1,7 @@
1#!/usr/bin/env perl 1#!/usr/bin/env perl
2 2
3push(@INC,"perlasm"); 3$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
4push(@INC, "${dir}perlasm", "perlasm");
4require "x86asm.pl"; 5require "x86asm.pl";
5 6
6&asm_init($ARGV[0],"x86cpuid"); 7&asm_init($ARGV[0],"x86cpuid");
@@ -22,38 +23,90 @@ for (@ARGV) { $sse2=1 if (/-DOPENSSL_IA32_SSE2/); }
22 &jnc (&label("done")); 23 &jnc (&label("done"));
23 &xor ("eax","eax"); 24 &xor ("eax","eax");
24 &cpuid (); 25 &cpuid ();
26 &mov ("edi","eax"); # max value for standard query level
27
25 &xor ("eax","eax"); 28 &xor ("eax","eax");
26 &cmp ("ebx",0x756e6547); # "Genu" 29 &cmp ("ebx",0x756e6547); # "Genu"
27 &data_byte(0x0f,0x95,0xc0); #&setne (&LB("eax")); 30 &setne (&LB("eax"));
28 &mov ("ebp","eax"); 31 &mov ("ebp","eax");
29 &cmp ("edx",0x49656e69); # "ineI" 32 &cmp ("edx",0x49656e69); # "ineI"
30 &data_byte(0x0f,0x95,0xc0); #&setne (&LB("eax")); 33 &setne (&LB("eax"));
31 &or ("ebp","eax"); 34 &or ("ebp","eax");
32 &cmp ("ecx",0x6c65746e); # "ntel" 35 &cmp ("ecx",0x6c65746e); # "ntel"
33 &data_byte(0x0f,0x95,0xc0); #&setne (&LB("eax")); 36 &setne (&LB("eax"));
34 &or ("ebp","eax"); 37 &or ("ebp","eax"); # 0 indicates Intel CPU
38 &jz (&label("intel"));
39
40 &cmp ("ebx",0x68747541); # "Auth"
41 &setne (&LB("eax"));
42 &mov ("esi","eax");
43 &cmp ("edx",0x69746E65); # "enti"
44 &setne (&LB("eax"));
45 &or ("esi","eax");
46 &cmp ("ecx",0x444D4163); # "cAMD"
47 &setne (&LB("eax"));
48 &or ("esi","eax"); # 0 indicates AMD CPU
49 &jnz (&label("intel"));
50
51 # AMD specific
52 &mov ("eax",0x80000000);
53 &cpuid ();
54 &cmp ("eax",0x80000008);
55 &jb (&label("intel"));
56
57 &mov ("eax",0x80000008);
58 &cpuid ();
59 &movz ("esi",&LB("ecx")); # number of cores - 1
60 &inc ("esi"); # number of cores
61
62 &mov ("eax",1);
63 &cpuid ();
64 &bt ("edx",28);
65 &jnc (&label("done"));
66 &shr ("ebx",16);
67 &and ("ebx",0xff);
68 &cmp ("ebx","esi");
69 &ja (&label("done"));
70 &and ("edx",0xefffffff); # clear hyper-threading bit
71 &jmp (&label("done"));
72
73&set_label("intel");
74 &cmp ("edi",4);
75 &mov ("edi",-1);
76 &jb (&label("nocacheinfo"));
77
78 &mov ("eax",4);
79 &mov ("ecx",0); # query L1D
80 &cpuid ();
81 &mov ("edi","eax");
82 &shr ("edi",14);
83 &and ("edi",0xfff); # number of cores -1 per L1D
84
85&set_label("nocacheinfo");
35 &mov ("eax",1); 86 &mov ("eax",1);
36 &cpuid (); 87 &cpuid ();
37 &cmp ("ebp",0); 88 &cmp ("ebp",0);
38 &jne (&label("notP4")); 89 &jne (&label("notP4"));
39 &and ("eax",15<<8); # familiy ID 90 &and (&HB("eax"),15); # familiy ID
40 &cmp ("eax",15<<8); # P4? 91 &cmp (&HB("eax"),15); # P4?
41 &jne (&label("notP4")); 92 &jne (&label("notP4"));
42 &or ("edx",1<<20); # use reserved bit to engage RC4_CHAR 93 &or ("edx",1<<20); # use reserved bit to engage RC4_CHAR
43&set_label("notP4"); 94&set_label("notP4");
44 &bt ("edx",28); # test hyper-threading bit 95 &bt ("edx",28); # test hyper-threading bit
45 &jnc (&label("done")); 96 &jnc (&label("done"));
97 &and ("edx",0xefffffff);
98 &cmp ("edi",0);
99 &je (&label("done"));
100
101 &or ("edx",0x10000000);
46 &shr ("ebx",16); 102 &shr ("ebx",16);
47 &and ("ebx",0xff); 103 &cmp (&LB("ebx"),1);
48 &cmp ("ebx",1); # see if cache is shared(*)
49 &ja (&label("done")); 104 &ja (&label("done"));
50 &and ("edx",0xefffffff); # clear hyper-threading bit if not 105 &and ("edx",0xefffffff); # clear hyper-threading bit if not
51&set_label("done"); 106&set_label("done");
52 &mov ("eax","edx"); 107 &mov ("eax","edx");
53 &mov ("edx","ecx"); 108 &mov ("edx","ecx");
54&function_end("OPENSSL_ia32_cpuid"); 109&function_end("OPENSSL_ia32_cpuid");
55# (*) on Core2 this value is set to 2 denoting the fact that L2
56# cache is shared between cores.
57 110
58&external_label("OPENSSL_ia32cap_P"); 111&external_label("OPENSSL_ia32cap_P");
59 112
@@ -220,6 +273,40 @@ for (@ARGV) { $sse2=1 if (/-DOPENSSL_IA32_SSE2/); }
220 } 273 }
221&function_end_B("OPENSSL_indirect_call"); 274&function_end_B("OPENSSL_indirect_call");
222 275
276&function_begin_B("OPENSSL_cleanse");
277 &mov ("edx",&wparam(0));
278 &mov ("ecx",&wparam(1));
279 &xor ("eax","eax");
280 &cmp ("ecx",7);
281 &jae (&label("lot"));
282 &cmp ("ecx",0);
283 &je (&label("ret"));
284&set_label("little");
285 &mov (&BP(0,"edx"),"al");
286 &sub ("ecx",1);
287 &lea ("edx",&DWP(1,"edx"));
288 &jnz (&label("little"));
289&set_label("ret");
290 &ret ();
291
292&set_label("lot",16);
293 &test ("edx",3);
294 &jz (&label("aligned"));
295 &mov (&BP(0,"edx"),"al");
296 &lea ("ecx",&DWP(-1,"ecx"));
297 &lea ("edx",&DWP(1,"edx"));
298 &jmp (&label("lot"));
299&set_label("aligned");
300 &mov (&DWP(0,"edx"),"eax");
301 &lea ("ecx",&DWP(-4,"ecx"));
302 &test ("ecx",-4);
303 &lea ("edx",&DWP(4,"edx"));
304 &jnz (&label("aligned"));
305 &cmp ("ecx",0);
306 &jne (&label("little"));
307 &ret ();
308&function_end_B("OPENSSL_cleanse");
309
223&initseg("OPENSSL_cpuid_setup"); 310&initseg("OPENSSL_cpuid_setup");
224 311
225&asm_finish(); 312&asm_finish();