summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordjm <>2010-10-01 22:54:21 +0000
committerdjm <>2010-10-01 22:54:21 +0000
commit2ea67f4aa254b09ded62e6e14fc893bbe6381579 (patch)
treebb3923b81f2ce34b1ad62684afdf1a94d904c185
parent6ddfb710ab14b10183ff3a6a32f643554c80065e (diff)
parent829fd51d4f8dde4a7f3bf54754f3c1d1a502f5e2 (diff)
downloadopenbsd-2ea67f4aa254b09ded62e6e14fc893bbe6381579.tar.gz
openbsd-2ea67f4aa254b09ded62e6e14fc893bbe6381579.tar.bz2
openbsd-2ea67f4aa254b09ded62e6e14fc893bbe6381579.zip
This commit was generated by cvs2git to track changes on a CVS vendor
branch.
-rw-r--r--src/lib/libcrypto/aes/aes_ige.c12
-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/ameth_lib.c4
-rw-r--r--src/lib/libcrypto/asn1/asn1_gen.c42
-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/ppc.pl233
-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/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/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/des/asm/des_enc.m46
-rw-r--r--src/lib/libcrypto/dh/dh_ameth.c500
-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/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/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_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/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_ameth.c657
-rw-r--r--src/lib/libcrypto/dsa/dsa_locl.h59
-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/ec/ec2_mult.c33
-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_pmeth.c340
-rw-r--r--src/lib/libcrypto/ec/eck_prn.c391
-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/tb_asnmth.c246
-rw-r--r--src/lib/libcrypto/engine/tb_pkmeth.c167
-rw-r--r--src/lib/libcrypto/evp/e_camellia.c2
-rw-r--r--src/lib/libcrypto/evp/m_ecdsa.c2
-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/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/hmac/hm_ameth.c167
-rw-r--r--src/lib/libcrypto/hmac/hm_pmeth.c265
-rw-r--r--src/lib/libcrypto/ia64cpuid.S46
-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/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/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/objxref.pl107
-rw-r--r--src/lib/libcrypto/pem/pvkfmt.c942
-rwxr-xr-xsrc/lib/libcrypto/perlasm/ppc-xlate.pl152
-rw-r--r--src/lib/libcrypto/perlasm/x86gas.pl247
-rw-r--r--src/lib/libcrypto/pkcs7/bio_pk7.c69
-rwxr-xr-xsrc/lib/libcrypto/ppccpuid.pl2
-rw-r--r--src/lib/libcrypto/rc4/asm/rc4-ia64.pl755
-rw-r--r--src/lib/libcrypto/rc4/asm/rc4-s390x.pl205
-rw-r--r--src/lib/libcrypto/rsa/rsa_ameth.c349
-rw-r--r--src/lib/libcrypto/rsa/rsa_locl.h4
-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/s390xcap.c37
-rw-r--r--src/lib/libcrypto/s390xcpuid.S16
-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/sha256.c32
-rw-r--r--src/lib/libcrypto/sha/sha512.c184
-rw-r--r--src/lib/libcrypto/sparccpuid.S119
-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/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/x509_vpm.c28
-rw-r--r--src/lib/libcrypto/x509v3/pcy_cache.c1
-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/v3_ncons.c312
-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/x86cpuid.pl109
-rw-r--r--src/lib/libssl/d1_both.c627
-rw-r--r--src/lib/libssl/d1_enc.c31
-rw-r--r--src/lib/libssl/d1_lib.c235
-rw-r--r--src/lib/libssl/d1_meth.c4
-rw-r--r--src/lib/libssl/t1_reneg.c292
-rw-r--r--src/lib/libssl/test/CAss.cnf2
-rw-r--r--src/lib/libssl/test/CAtsa.cnf163
-rw-r--r--src/lib/libssl/test/Uss.cnf2
-rwxr-xr-xsrc/lib/libssl/test/asn1test.c22
-rw-r--r--src/lib/libssl/test/cms-test.pl18
-rw-r--r--src/lib/libssl/test/pkits-test.pl940
-rwxr-xr-xsrc/lib/libssl/test/test_padlock64
-rw-r--r--src/lib/libssl/test/testtsa238
189 files changed, 34138 insertions, 4739 deletions
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/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/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_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/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/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/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/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/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/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/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_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/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/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_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/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_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_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_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/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/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_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/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/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/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/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_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/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/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/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/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/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/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/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/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/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/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/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/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/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_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_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/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-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/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/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/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/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/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/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_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/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_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/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();
diff --git a/src/lib/libssl/d1_both.c b/src/lib/libssl/d1_both.c
index 15a201a25c..4ce4064cc9 100644
--- a/src/lib/libssl/d1_both.c
+++ b/src/lib/libssl/d1_both.c
@@ -123,6 +123,37 @@
123#include <openssl/evp.h> 123#include <openssl/evp.h>
124#include <openssl/x509.h> 124#include <openssl/x509.h>
125 125
126#define RSMBLY_BITMASK_SIZE(msg_len) (((msg_len) + 7) / 8)
127
128#define RSMBLY_BITMASK_MARK(bitmask, start, end) { \
129 if ((end) - (start) <= 8) { \
130 long ii; \
131 for (ii = (start); ii < (end); ii++) bitmask[((ii) >> 3)] |= (1 << ((ii) & 7)); \
132 } else { \
133 long ii; \
134 bitmask[((start) >> 3)] |= bitmask_start_values[((start) & 7)]; \
135 for (ii = (((start) >> 3) + 1); ii < ((((end) - 1)) >> 3); ii++) bitmask[ii] = 0xff; \
136 bitmask[(((end) - 1) >> 3)] |= bitmask_end_values[((end) & 7)]; \
137 } }
138
139#define RSMBLY_BITMASK_IS_COMPLETE(bitmask, msg_len, is_complete) { \
140 long ii; \
141 OPENSSL_assert((msg_len) > 0); \
142 is_complete = 1; \
143 if (bitmask[(((msg_len) - 1) >> 3)] != bitmask_end_values[((msg_len) & 7)]) is_complete = 0; \
144 if (is_complete) for (ii = (((msg_len) - 1) >> 3) - 1; ii >= 0 ; ii--) \
145 if (bitmask[ii] != 0xff) { is_complete = 0; break; } }
146
147#if 0
148#define RSMBLY_BITMASK_PRINT(bitmask, msg_len) { \
149 long ii; \
150 printf("bitmask: "); for (ii = 0; ii < (msg_len); ii++) \
151 printf("%d ", (bitmask[ii >> 3] & (1 << (ii & 7))) >> (ii & 7)); \
152 printf("\n"); }
153#endif
154
155static unsigned char bitmask_start_values[] = {0xff, 0xfe, 0xfc, 0xf8, 0xf0, 0xe0, 0xc0, 0x80};
156static unsigned char bitmask_end_values[] = {0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f};
126 157
127/* XDTLS: figure out the right values */ 158/* XDTLS: figure out the right values */
128static unsigned int g_probable_mtu[] = {1500 - 28, 512 - 28, 256 - 28}; 159static unsigned int g_probable_mtu[] = {1500 - 28, 512 - 28, 256 - 28};
@@ -136,15 +167,15 @@ static unsigned char *dtls1_write_message_header(SSL *s,
136static void dtls1_set_message_header_int(SSL *s, unsigned char mt, 167static void dtls1_set_message_header_int(SSL *s, unsigned char mt,
137 unsigned long len, unsigned short seq_num, unsigned long frag_off, 168 unsigned long len, unsigned short seq_num, unsigned long frag_off,
138 unsigned long frag_len); 169 unsigned long frag_len);
139static int dtls1_retransmit_buffered_messages(SSL *s);
140static long dtls1_get_message_fragment(SSL *s, int st1, int stn, 170static long dtls1_get_message_fragment(SSL *s, int st1, int stn,
141 long max, int *ok); 171 long max, int *ok);
142 172
143static hm_fragment * 173static hm_fragment *
144dtls1_hm_fragment_new(unsigned long frag_len) 174dtls1_hm_fragment_new(unsigned long frag_len, int reassembly)
145 { 175 {
146 hm_fragment *frag = NULL; 176 hm_fragment *frag = NULL;
147 unsigned char *buf = NULL; 177 unsigned char *buf = NULL;
178 unsigned char *bitmask = NULL;
148 179
149 frag = (hm_fragment *)OPENSSL_malloc(sizeof(hm_fragment)); 180 frag = (hm_fragment *)OPENSSL_malloc(sizeof(hm_fragment));
150 if ( frag == NULL) 181 if ( frag == NULL)
@@ -163,6 +194,21 @@ dtls1_hm_fragment_new(unsigned long frag_len)
163 /* zero length fragment gets zero frag->fragment */ 194 /* zero length fragment gets zero frag->fragment */
164 frag->fragment = buf; 195 frag->fragment = buf;
165 196
197 /* Initialize reassembly bitmask if necessary */
198 if (reassembly)
199 {
200 bitmask = (unsigned char *)OPENSSL_malloc(RSMBLY_BITMASK_SIZE(frag_len));
201 if (bitmask == NULL)
202 {
203 if (buf != NULL) OPENSSL_free(buf);
204 OPENSSL_free(frag);
205 return NULL;
206 }
207 memset(bitmask, 0, RSMBLY_BITMASK_SIZE(frag_len));
208 }
209
210 frag->reassembly = bitmask;
211
166 return frag; 212 return frag;
167 } 213 }
168 214
@@ -170,6 +216,7 @@ static void
170dtls1_hm_fragment_free(hm_fragment *frag) 216dtls1_hm_fragment_free(hm_fragment *frag)
171 { 217 {
172 if (frag->fragment) OPENSSL_free(frag->fragment); 218 if (frag->fragment) OPENSSL_free(frag->fragment);
219 if (frag->reassembly) OPENSSL_free(frag->reassembly);
173 OPENSSL_free(frag); 220 OPENSSL_free(frag);
174 } 221 }
175 222
@@ -178,7 +225,7 @@ int dtls1_do_write(SSL *s, int type)
178 { 225 {
179 int ret; 226 int ret;
180 int curr_mtu; 227 int curr_mtu;
181 unsigned int len, frag_off; 228 unsigned int len, frag_off, mac_size, blocksize;
182 229
183 /* AHA! Figure out the MTU, and stick to the right size */ 230 /* AHA! Figure out the MTU, and stick to the right size */
184 if ( ! (SSL_get_options(s) & SSL_OP_NO_QUERY_MTU)) 231 if ( ! (SSL_get_options(s) & SSL_OP_NO_QUERY_MTU))
@@ -226,11 +273,22 @@ int dtls1_do_write(SSL *s, int type)
226 OPENSSL_assert(s->init_num == 273 OPENSSL_assert(s->init_num ==
227 (int)s->d1->w_msg_hdr.msg_len + DTLS1_HM_HEADER_LENGTH); 274 (int)s->d1->w_msg_hdr.msg_len + DTLS1_HM_HEADER_LENGTH);
228 275
276 if (s->write_hash)
277 mac_size = EVP_MD_CTX_size(s->write_hash);
278 else
279 mac_size = 0;
280
281 if (s->enc_write_ctx &&
282 (EVP_CIPHER_mode( s->enc_write_ctx->cipher) & EVP_CIPH_CBC_MODE))
283 blocksize = 2 * EVP_CIPHER_block_size(s->enc_write_ctx->cipher);
284 else
285 blocksize = 0;
286
229 frag_off = 0; 287 frag_off = 0;
230 while( s->init_num) 288 while( s->init_num)
231 { 289 {
232 curr_mtu = s->d1->mtu - BIO_wpending(SSL_get_wbio(s)) - 290 curr_mtu = s->d1->mtu - BIO_wpending(SSL_get_wbio(s)) -
233 DTLS1_RT_HEADER_LENGTH; 291 DTLS1_RT_HEADER_LENGTH - mac_size - blocksize;
234 292
235 if ( curr_mtu <= DTLS1_HM_HEADER_LENGTH) 293 if ( curr_mtu <= DTLS1_HM_HEADER_LENGTH)
236 { 294 {
@@ -238,7 +296,8 @@ int dtls1_do_write(SSL *s, int type)
238 ret = BIO_flush(SSL_get_wbio(s)); 296 ret = BIO_flush(SSL_get_wbio(s));
239 if ( ret <= 0) 297 if ( ret <= 0)
240 return ret; 298 return ret;
241 curr_mtu = s->d1->mtu - DTLS1_RT_HEADER_LENGTH; 299 curr_mtu = s->d1->mtu - DTLS1_RT_HEADER_LENGTH -
300 mac_size - blocksize;
242 } 301 }
243 302
244 if ( s->init_num > curr_mtu) 303 if ( s->init_num > curr_mtu)
@@ -280,7 +339,7 @@ int dtls1_do_write(SSL *s, int type)
280 * retransmit 339 * retransmit
281 */ 340 */
282 if ( BIO_ctrl(SSL_get_wbio(s), 341 if ( BIO_ctrl(SSL_get_wbio(s),
283 BIO_CTRL_DGRAM_MTU_EXCEEDED, 0, NULL)) 342 BIO_CTRL_DGRAM_MTU_EXCEEDED, 0, NULL) > 0 )
284 s->d1->mtu = BIO_ctrl(SSL_get_wbio(s), 343 s->d1->mtu = BIO_ctrl(SSL_get_wbio(s),
285 BIO_CTRL_DGRAM_QUERY_MTU, 0, NULL); 344 BIO_CTRL_DGRAM_QUERY_MTU, 0, NULL);
286 else 345 else
@@ -301,7 +360,7 @@ int dtls1_do_write(SSL *s, int type)
301 const struct hm_header_st *msg_hdr = &s->d1->w_msg_hdr; 360 const struct hm_header_st *msg_hdr = &s->d1->w_msg_hdr;
302 int xlen; 361 int xlen;
303 362
304 if (frag_off == 0 && s->client_version != DTLS1_BAD_VER) 363 if (frag_off == 0 && s->version != DTLS1_BAD_VER)
305 { 364 {
306 /* reconstruct message header is if it 365 /* reconstruct message header is if it
307 * is being sent in single fragment */ 366 * is being sent in single fragment */
@@ -352,6 +411,8 @@ long dtls1_get_message(SSL *s, int st1, int stn, int mt, long max, int *ok)
352 { 411 {
353 int i, al; 412 int i, al;
354 struct hm_header_st *msg_hdr; 413 struct hm_header_st *msg_hdr;
414 unsigned char *p;
415 unsigned long msg_len;
355 416
356 /* s3->tmp is used to store messages that are unexpected, caused 417 /* s3->tmp is used to store messages that are unexpected, caused
357 * by the absence of an optional handshake message */ 418 * by the absence of an optional handshake message */
@@ -371,76 +432,55 @@ long dtls1_get_message(SSL *s, int st1, int stn, int mt, long max, int *ok)
371 } 432 }
372 433
373 msg_hdr = &s->d1->r_msg_hdr; 434 msg_hdr = &s->d1->r_msg_hdr;
374 do 435 memset(msg_hdr, 0x00, sizeof(struct hm_header_st));
375 {
376 if ( msg_hdr->frag_off == 0)
377 {
378 /* s->d1->r_message_header.msg_len = 0; */
379 memset(msg_hdr, 0x00, sizeof(struct hm_header_st));
380 }
381 436
382 i = dtls1_get_message_fragment(s, st1, stn, max, ok); 437again:
383 if ( i == DTLS1_HM_BAD_FRAGMENT || 438 i = dtls1_get_message_fragment(s, st1, stn, max, ok);
384 i == DTLS1_HM_FRAGMENT_RETRY) /* bad fragment received */ 439 if ( i == DTLS1_HM_BAD_FRAGMENT ||
385 continue; 440 i == DTLS1_HM_FRAGMENT_RETRY) /* bad fragment received */
386 else if ( i <= 0 && !*ok) 441 goto again;
387 return i; 442 else if ( i <= 0 && !*ok)
443 return i;
388 444
389 /* Note that s->init_sum is used as a counter summing 445 p = (unsigned char *)s->init_buf->data;
390 * up fragments' lengths: as soon as they sum up to 446 msg_len = msg_hdr->msg_len;
391 * handshake packet length, we assume we have got all 447
392 * the fragments. Overlapping fragments would cause 448 /* reconstruct message header */
393 * premature termination, so we don't expect overlaps. 449 *(p++) = msg_hdr->type;
394 * Well, handling overlaps would require something more 450 l2n3(msg_len,p);
395 * drastic. Indeed, as it is now there is no way to 451 s2n (msg_hdr->seq,p);
396 * tell if out-of-order fragment from the middle was 452 l2n3(0,p);
397 * the last. '>=' is the best/least we can do to control 453 l2n3(msg_len,p);
398 * the potential damage caused by malformed overlaps. */ 454 if (s->version != DTLS1_BAD_VER) {
399 if ((unsigned int)s->init_num >= msg_hdr->msg_len) 455 p -= DTLS1_HM_HEADER_LENGTH;
400 { 456 msg_len += DTLS1_HM_HEADER_LENGTH;
401 unsigned char *p = (unsigned char *)s->init_buf->data; 457 }
402 unsigned long msg_len = msg_hdr->msg_len; 458
403 459 ssl3_finish_mac(s, p, msg_len);
404 /* reconstruct message header as if it was 460 if (s->msg_callback)
405 * sent in single fragment */ 461 s->msg_callback(0, s->version, SSL3_RT_HANDSHAKE,
406 *(p++) = msg_hdr->type; 462 p, msg_len,
407 l2n3(msg_len,p); 463 s, s->msg_callback_arg);
408 s2n (msg_hdr->seq,p); 464
409 l2n3(0,p); 465 memset(msg_hdr, 0x00, sizeof(struct hm_header_st));
410 l2n3(msg_len,p); 466
411 if (s->client_version != DTLS1_BAD_VER) 467 s->d1->handshake_read_seq++;
412 p -= DTLS1_HM_HEADER_LENGTH, 468 /* we just read a handshake message from the other side:
413 msg_len += DTLS1_HM_HEADER_LENGTH; 469 * this means that we don't need to retransmit of the
414 470 * buffered messages.
415 ssl3_finish_mac(s, p, msg_len); 471 * XDTLS: may be able clear out this
416 if (s->msg_callback) 472 * buffer a little sooner (i.e if an out-of-order
417 s->msg_callback(0, s->version, SSL3_RT_HANDSHAKE, 473 * handshake message/record is received at the record
418 p, msg_len, 474 * layer.
419 s, s->msg_callback_arg); 475 * XDTLS: exception is that the server needs to
420 476 * know that change cipher spec and finished messages
421 memset(msg_hdr, 0x00, sizeof(struct hm_header_st)); 477 * have been received by the client before clearing this
422 478 * buffer. this can simply be done by waiting for the
423 s->d1->handshake_read_seq++; 479 * first data segment, but is there a better way? */
424 /* we just read a handshake message from the other side: 480 dtls1_clear_record_buffer(s);
425 * this means that we don't need to retransmit of the 481
426 * buffered messages. 482 s->init_msg = s->init_buf->data + DTLS1_HM_HEADER_LENGTH;
427 * XDTLS: may be able clear out this 483 return s->init_num;
428 * buffer a little sooner (i.e if an out-of-order
429 * handshake message/record is received at the record
430 * layer.
431 * XDTLS: exception is that the server needs to
432 * know that change cipher spec and finished messages
433 * have been received by the client before clearing this
434 * buffer. this can simply be done by waiting for the
435 * first data segment, but is there a better way? */
436 dtls1_clear_record_buffer(s);
437
438 s->init_msg = s->init_buf->data + DTLS1_HM_HEADER_LENGTH;
439 return s->init_num;
440 }
441 else
442 msg_hdr->frag_off = i;
443 } while(1) ;
444 484
445f_err: 485f_err:
446 ssl3_send_alert(s,SSL3_AL_FATAL,al); 486 ssl3_send_alert(s,SSL3_AL_FATAL,al);
@@ -474,7 +514,7 @@ static int dtls1_preprocess_fragment(SSL *s,struct hm_header_st *msg_hdr,int max
474 { 514 {
475 /* msg_len is limited to 2^24, but is effectively checked 515 /* msg_len is limited to 2^24, but is effectively checked
476 * against max above */ 516 * against max above */
477 if (!BUF_MEM_grow_clean(s->init_buf,(int)msg_len+DTLS1_HM_HEADER_LENGTH)) 517 if (!BUF_MEM_grow_clean(s->init_buf,msg_len+DTLS1_HM_HEADER_LENGTH))
478 { 518 {
479 SSLerr(SSL_F_DTLS1_PREPROCESS_FRAGMENT,ERR_R_BUF_LIB); 519 SSLerr(SSL_F_DTLS1_PREPROCESS_FRAGMENT,ERR_R_BUF_LIB);
480 return SSL_AD_INTERNAL_ERROR; 520 return SSL_AD_INTERNAL_ERROR;
@@ -516,9 +556,14 @@ dtls1_retrieve_buffered_fragment(SSL *s, long max, int *ok)
516 return 0; 556 return 0;
517 557
518 frag = (hm_fragment *)item->data; 558 frag = (hm_fragment *)item->data;
559
560 /* Don't return if reassembly still in progress */
561 if (frag->reassembly != NULL)
562 return 0;
519 563
520 if ( s->d1->handshake_read_seq == frag->msg_header.seq) 564 if ( s->d1->handshake_read_seq == frag->msg_header.seq)
521 { 565 {
566 unsigned long frag_len = frag->msg_header.frag_len;
522 pqueue_pop(s->d1->buffered_messages); 567 pqueue_pop(s->d1->buffered_messages);
523 568
524 al=dtls1_preprocess_fragment(s,&frag->msg_header,max); 569 al=dtls1_preprocess_fragment(s,&frag->msg_header,max);
@@ -536,7 +581,7 @@ dtls1_retrieve_buffered_fragment(SSL *s, long max, int *ok)
536 if (al==0) 581 if (al==0)
537 { 582 {
538 *ok = 1; 583 *ok = 1;
539 return frag->msg_header.frag_len; 584 return frag_len;
540 } 585 }
541 586
542 ssl3_send_alert(s,SSL3_AL_FATAL,al); 587 ssl3_send_alert(s,SSL3_AL_FATAL,al);
@@ -550,18 +595,50 @@ dtls1_retrieve_buffered_fragment(SSL *s, long max, int *ok)
550 595
551 596
552static int 597static int
553dtls1_process_out_of_seq_message(SSL *s, struct hm_header_st* msg_hdr, int *ok) 598dtls1_reassemble_fragment(SSL *s, struct hm_header_st* msg_hdr, int *ok)
554{ 599 {
555 int i=-1;
556 hm_fragment *frag = NULL; 600 hm_fragment *frag = NULL;
557 pitem *item = NULL; 601 pitem *item = NULL;
558 PQ_64BIT seq64; 602 int i = -1, is_complete;
559 unsigned long frag_len = msg_hdr->frag_len; 603 unsigned char seq64be[8];
604 unsigned long frag_len = msg_hdr->frag_len, max_len;
560 605
561 if ((msg_hdr->frag_off+frag_len) > msg_hdr->msg_len) 606 if ((msg_hdr->frag_off+frag_len) > msg_hdr->msg_len)
562 goto err; 607 goto err;
563 608
564 if (msg_hdr->seq <= s->d1->handshake_read_seq) 609 /* Determine maximum allowed message size. Depends on (user set)
610 * maximum certificate length, but 16k is minimum.
611 */
612 if (DTLS1_HM_HEADER_LENGTH + SSL3_RT_MAX_ENCRYPTED_LENGTH < s->max_cert_list)
613 max_len = s->max_cert_list;
614 else
615 max_len = DTLS1_HM_HEADER_LENGTH + SSL3_RT_MAX_ENCRYPTED_LENGTH;
616
617 if ((msg_hdr->frag_off+frag_len) > max_len)
618 goto err;
619
620 /* Try to find item in queue */
621 memset(seq64be,0,sizeof(seq64be));
622 seq64be[6] = (unsigned char) (msg_hdr->seq>>8);
623 seq64be[7] = (unsigned char) msg_hdr->seq;
624 item = pqueue_find(s->d1->buffered_messages, seq64be);
625
626 if (item == NULL)
627 {
628 frag = dtls1_hm_fragment_new(msg_hdr->msg_len, 1);
629 if ( frag == NULL)
630 goto err;
631 memcpy(&(frag->msg_header), msg_hdr, sizeof(*msg_hdr));
632 frag->msg_header.frag_len = frag->msg_header.msg_len;
633 frag->msg_header.frag_off = 0;
634 }
635 else
636 frag = (hm_fragment*) item->data;
637
638 /* If message is already reassembled, this must be a
639 * retransmit and can be dropped.
640 */
641 if (frag->reassembly == NULL)
565 { 642 {
566 unsigned char devnull [256]; 643 unsigned char devnull [256];
567 644
@@ -573,32 +650,128 @@ dtls1_process_out_of_seq_message(SSL *s, struct hm_header_st* msg_hdr, int *ok)
573 if (i<=0) goto err; 650 if (i<=0) goto err;
574 frag_len -= i; 651 frag_len -= i;
575 } 652 }
653 return DTLS1_HM_FRAGMENT_RETRY;
576 } 654 }
577 655
578 frag = dtls1_hm_fragment_new(frag_len); 656 /* read the body of the fragment (header has already been read */
579 if ( frag == NULL) 657 i = s->method->ssl_read_bytes(s,SSL3_RT_HANDSHAKE,
658 frag->fragment + msg_hdr->frag_off,frag_len,0);
659 if (i<=0 || (unsigned long)i!=frag_len)
580 goto err; 660 goto err;
581 661
582 memcpy(&(frag->msg_header), msg_hdr, sizeof(*msg_hdr)); 662 RSMBLY_BITMASK_MARK(frag->reassembly, (long)msg_hdr->frag_off,
663 (long)(msg_hdr->frag_off + frag_len));
583 664
584 if (frag_len) 665 RSMBLY_BITMASK_IS_COMPLETE(frag->reassembly, (long)msg_hdr->msg_len,
666 is_complete);
667
668 if (is_complete)
669 {
670 OPENSSL_free(frag->reassembly);
671 frag->reassembly = NULL;
672 }
673
674 if (item == NULL)
585 { 675 {
586 /* read the body of the fragment (header has already been read */ 676 memset(seq64be,0,sizeof(seq64be));
587 i = s->method->ssl_read_bytes(s,SSL3_RT_HANDSHAKE, 677 seq64be[6] = (unsigned char)(msg_hdr->seq>>8);
588 frag->fragment,frag_len,0); 678 seq64be[7] = (unsigned char)(msg_hdr->seq);
589 if (i<=0 || (unsigned long)i!=frag_len) 679
680 item = pitem_new(seq64be, frag);
681 if (item == NULL)
682 {
590 goto err; 683 goto err;
684 i = -1;
685 }
686
687 pqueue_insert(s->d1->buffered_messages, item);
591 } 688 }
592 689
593 pq_64bit_init(&seq64); 690 return DTLS1_HM_FRAGMENT_RETRY;
594 pq_64bit_assign_word(&seq64, msg_hdr->seq); 691
692err:
693 if (frag != NULL) dtls1_hm_fragment_free(frag);
694 if (item != NULL) OPENSSL_free(item);
695 *ok = 0;
696 return i;
697 }
698
595 699
596 item = pitem_new(seq64, frag); 700static int
597 pq_64bit_free(&seq64); 701dtls1_process_out_of_seq_message(SSL *s, struct hm_header_st* msg_hdr, int *ok)
598 if ( item == NULL) 702{
703 int i=-1;
704 hm_fragment *frag = NULL;
705 pitem *item = NULL;
706 unsigned char seq64be[8];
707 unsigned long frag_len = msg_hdr->frag_len;
708
709 if ((msg_hdr->frag_off+frag_len) > msg_hdr->msg_len)
599 goto err; 710 goto err;
600 711
601 pqueue_insert(s->d1->buffered_messages, item); 712 /* Try to find item in queue, to prevent duplicate entries */
713 memset(seq64be,0,sizeof(seq64be));
714 seq64be[6] = (unsigned char) (msg_hdr->seq>>8);
715 seq64be[7] = (unsigned char) msg_hdr->seq;
716 item = pqueue_find(s->d1->buffered_messages, seq64be);
717
718 /* If we already have an entry and this one is a fragment,
719 * don't discard it and rather try to reassemble it.
720 */
721 if (item != NULL && frag_len < msg_hdr->msg_len)
722 item = NULL;
723
724 /* Discard the message if sequence number was already there, is
725 * too far in the future, already in the queue or if we received
726 * a FINISHED before the SERVER_HELLO, which then must be a stale
727 * retransmit.
728 */
729 if (msg_hdr->seq <= s->d1->handshake_read_seq ||
730 msg_hdr->seq > s->d1->handshake_read_seq + 10 || item != NULL ||
731 (s->d1->handshake_read_seq == 0 && msg_hdr->type == SSL3_MT_FINISHED))
732 {
733 unsigned char devnull [256];
734
735 while (frag_len)
736 {
737 i = s->method->ssl_read_bytes(s,SSL3_RT_HANDSHAKE,
738 devnull,
739 frag_len>sizeof(devnull)?sizeof(devnull):frag_len,0);
740 if (i<=0) goto err;
741 frag_len -= i;
742 }
743 }
744 else
745 {
746 if (frag_len && frag_len < msg_hdr->msg_len)
747 return dtls1_reassemble_fragment(s, msg_hdr, ok);
748
749 frag = dtls1_hm_fragment_new(frag_len, 0);
750 if ( frag == NULL)
751 goto err;
752
753 memcpy(&(frag->msg_header), msg_hdr, sizeof(*msg_hdr));
754
755 if (frag_len)
756 {
757 /* read the body of the fragment (header has already been read */
758 i = s->method->ssl_read_bytes(s,SSL3_RT_HANDSHAKE,
759 frag->fragment,frag_len,0);
760 if (i<=0 || (unsigned long)i!=frag_len)
761 goto err;
762 }
763
764 memset(seq64be,0,sizeof(seq64be));
765 seq64be[6] = (unsigned char)(msg_hdr->seq>>8);
766 seq64be[7] = (unsigned char)(msg_hdr->seq);
767
768 item = pitem_new(seq64be, frag);
769 if ( item == NULL)
770 goto err;
771
772 pqueue_insert(s->d1->buffered_messages, item);
773 }
774
602 return DTLS1_HM_FRAGMENT_RETRY; 775 return DTLS1_HM_FRAGMENT_RETRY;
603 776
604err: 777err:
@@ -613,14 +786,14 @@ static long
613dtls1_get_message_fragment(SSL *s, int st1, int stn, long max, int *ok) 786dtls1_get_message_fragment(SSL *s, int st1, int stn, long max, int *ok)
614 { 787 {
615 unsigned char wire[DTLS1_HM_HEADER_LENGTH]; 788 unsigned char wire[DTLS1_HM_HEADER_LENGTH];
616 unsigned long l, frag_off, frag_len; 789 unsigned long len, frag_off, frag_len;
617 int i,al; 790 int i,al;
618 struct hm_header_st msg_hdr; 791 struct hm_header_st msg_hdr;
619 792
620 /* see if we have the required fragment already */ 793 /* see if we have the required fragment already */
621 if ((frag_len = dtls1_retrieve_buffered_fragment(s,max,ok)) || *ok) 794 if ((frag_len = dtls1_retrieve_buffered_fragment(s,max,ok)) || *ok)
622 { 795 {
623 if (*ok) s->init_num += frag_len; 796 if (*ok) s->init_num = frag_len;
624 return frag_len; 797 return frag_len;
625 } 798 }
626 799
@@ -645,10 +818,13 @@ dtls1_get_message_fragment(SSL *s, int st1, int stn, long max, int *ok)
645 if ( msg_hdr.seq != s->d1->handshake_read_seq) 818 if ( msg_hdr.seq != s->d1->handshake_read_seq)
646 return dtls1_process_out_of_seq_message(s, &msg_hdr, ok); 819 return dtls1_process_out_of_seq_message(s, &msg_hdr, ok);
647 820
648 l = msg_hdr.msg_len; 821 len = msg_hdr.msg_len;
649 frag_off = msg_hdr.frag_off; 822 frag_off = msg_hdr.frag_off;
650 frag_len = msg_hdr.frag_len; 823 frag_len = msg_hdr.frag_len;
651 824
825 if (frag_len && frag_len < len)
826 return dtls1_reassemble_fragment(s, &msg_hdr, ok);
827
652 if (!s->server && s->d1->r_msg_hdr.frag_off == 0 && 828 if (!s->server && s->d1->r_msg_hdr.frag_off == 0 &&
653 wire[0] == SSL3_MT_HELLO_REQUEST) 829 wire[0] == SSL3_MT_HELLO_REQUEST)
654 { 830 {
@@ -708,7 +884,7 @@ dtls1_get_message_fragment(SSL *s, int st1, int stn, long max, int *ok)
708 * s->init_buf->data, but as a counter summing up fragments' 884 * s->init_buf->data, but as a counter summing up fragments'
709 * lengths: as soon as they sum up to handshake packet 885 * lengths: as soon as they sum up to handshake packet
710 * length, we assume we have got all the fragments. */ 886 * length, we assume we have got all the fragments. */
711 s->init_num += frag_len; 887 s->init_num = frag_len;
712 return frag_len; 888 return frag_len;
713 889
714f_err: 890f_err:
@@ -731,14 +907,30 @@ int dtls1_send_finished(SSL *s, int a, int b, const char *sender, int slen)
731 p= &(d[DTLS1_HM_HEADER_LENGTH]); 907 p= &(d[DTLS1_HM_HEADER_LENGTH]);
732 908
733 i=s->method->ssl3_enc->final_finish_mac(s, 909 i=s->method->ssl3_enc->final_finish_mac(s,
734 &(s->s3->finish_dgst1),
735 &(s->s3->finish_dgst2),
736 sender,slen,s->s3->tmp.finish_md); 910 sender,slen,s->s3->tmp.finish_md);
737 s->s3->tmp.finish_md_len = i; 911 s->s3->tmp.finish_md_len = i;
738 memcpy(p, s->s3->tmp.finish_md, i); 912 memcpy(p, s->s3->tmp.finish_md, i);
739 p+=i; 913 p+=i;
740 l=i; 914 l=i;
741 915
916 /* Copy the finished so we can use it for
917 * renegotiation checks
918 */
919 if(s->type == SSL_ST_CONNECT)
920 {
921 OPENSSL_assert(i <= EVP_MAX_MD_SIZE);
922 memcpy(s->s3->previous_client_finished,
923 s->s3->tmp.finish_md, i);
924 s->s3->previous_client_finished_len=i;
925 }
926 else
927 {
928 OPENSSL_assert(i <= EVP_MAX_MD_SIZE);
929 memcpy(s->s3->previous_server_finished,
930 s->s3->tmp.finish_md, i);
931 s->s3->previous_server_finished_len=i;
932 }
933
742#ifdef OPENSSL_SYS_WIN16 934#ifdef OPENSSL_SYS_WIN16
743 /* MSVC 1.5 does not clear the top bytes of the word unless 935 /* MSVC 1.5 does not clear the top bytes of the word unless
744 * I do this. 936 * I do this.
@@ -779,12 +971,11 @@ int dtls1_send_change_cipher_spec(SSL *s, int a, int b)
779 s->d1->handshake_write_seq = s->d1->next_handshake_write_seq; 971 s->d1->handshake_write_seq = s->d1->next_handshake_write_seq;
780 s->init_num=DTLS1_CCS_HEADER_LENGTH; 972 s->init_num=DTLS1_CCS_HEADER_LENGTH;
781 973
782 if (s->client_version == DTLS1_BAD_VER) 974 if (s->version == DTLS1_BAD_VER) {
783 {
784 s->d1->next_handshake_write_seq++; 975 s->d1->next_handshake_write_seq++;
785 s2n(s->d1->handshake_write_seq,p); 976 s2n(s->d1->handshake_write_seq,p);
786 s->init_num+=2; 977 s->init_num+=2;
787 } 978 }
788 979
789 s->init_off=0; 980 s->init_off=0;
790 981
@@ -801,14 +992,30 @@ int dtls1_send_change_cipher_spec(SSL *s, int a, int b)
801 return(dtls1_do_write(s,SSL3_RT_CHANGE_CIPHER_SPEC)); 992 return(dtls1_do_write(s,SSL3_RT_CHANGE_CIPHER_SPEC));
802 } 993 }
803 994
995static int dtls1_add_cert_to_buf(BUF_MEM *buf, unsigned long *l, X509 *x)
996 {
997 int n;
998 unsigned char *p;
999
1000 n=i2d_X509(x,NULL);
1001 if (!BUF_MEM_grow_clean(buf,(int)(n+(*l)+3)))
1002 {
1003 SSLerr(SSL_F_DTLS1_ADD_CERT_TO_BUF,ERR_R_BUF_LIB);
1004 return 0;
1005 }
1006 p=(unsigned char *)&(buf->data[*l]);
1007 l2n3(n,p);
1008 i2d_X509(x,&p);
1009 *l+=n+3;
1010
1011 return 1;
1012 }
804unsigned long dtls1_output_cert_chain(SSL *s, X509 *x) 1013unsigned long dtls1_output_cert_chain(SSL *s, X509 *x)
805 { 1014 {
806 unsigned char *p; 1015 unsigned char *p;
807 int n,i; 1016 int i;
808 unsigned long l= 3 + DTLS1_HM_HEADER_LENGTH; 1017 unsigned long l= 3 + DTLS1_HM_HEADER_LENGTH;
809 BUF_MEM *buf; 1018 BUF_MEM *buf;
810 X509_STORE_CTX xs_ctx;
811 X509_OBJECT obj;
812 1019
813 /* TLSv1 sends a chain with nothing in it, instead of an alert */ 1020 /* TLSv1 sends a chain with nothing in it, instead of an alert */
814 buf=s->init_buf; 1021 buf=s->init_buf;
@@ -819,54 +1026,35 @@ unsigned long dtls1_output_cert_chain(SSL *s, X509 *x)
819 } 1026 }
820 if (x != NULL) 1027 if (x != NULL)
821 { 1028 {
822 if(!X509_STORE_CTX_init(&xs_ctx,s->ctx->cert_store,NULL,NULL)) 1029 X509_STORE_CTX xs_ctx;
823 { 1030
824 SSLerr(SSL_F_DTLS1_OUTPUT_CERT_CHAIN,ERR_R_X509_LIB); 1031 if (!X509_STORE_CTX_init(&xs_ctx,s->ctx->cert_store,x,NULL))
825 return(0); 1032 {
826 } 1033 SSLerr(SSL_F_DTLS1_OUTPUT_CERT_CHAIN,ERR_R_X509_LIB);
827 1034 return(0);
828 for (;;) 1035 }
829 { 1036
830 n=i2d_X509(x,NULL); 1037 X509_verify_cert(&xs_ctx);
831 if (!BUF_MEM_grow_clean(buf,(int)(n+l+3))) 1038 /* Don't leave errors in the queue */
832 { 1039 ERR_clear_error();
833 SSLerr(SSL_F_DTLS1_OUTPUT_CERT_CHAIN,ERR_R_BUF_LIB); 1040 for (i=0; i < sk_X509_num(xs_ctx.chain); i++)
834 return(0); 1041 {
835 } 1042 x = sk_X509_value(xs_ctx.chain, i);
836 p=(unsigned char *)&(buf->data[l]); 1043
837 l2n3(n,p); 1044 if (!dtls1_add_cert_to_buf(buf, &l, x))
838 i2d_X509(x,&p); 1045 {
839 l+=n+3; 1046 X509_STORE_CTX_cleanup(&xs_ctx);
840 if (X509_NAME_cmp(X509_get_subject_name(x), 1047 return 0;
841 X509_get_issuer_name(x)) == 0) break; 1048 }
842 1049 }
843 i=X509_STORE_get_by_subject(&xs_ctx,X509_LU_X509, 1050 X509_STORE_CTX_cleanup(&xs_ctx);
844 X509_get_issuer_name(x),&obj); 1051 }
845 if (i <= 0) break; 1052 /* Thawte special :-) */
846 x=obj.data.x509;
847 /* Count is one too high since the X509_STORE_get uped the
848 * ref count */
849 X509_free(x);
850 }
851
852 X509_STORE_CTX_cleanup(&xs_ctx);
853 }
854
855 /* Thawte special :-) */
856 if (s->ctx->extra_certs != NULL)
857 for (i=0; i<sk_X509_num(s->ctx->extra_certs); i++) 1053 for (i=0; i<sk_X509_num(s->ctx->extra_certs); i++)
858 { 1054 {
859 x=sk_X509_value(s->ctx->extra_certs,i); 1055 x=sk_X509_value(s->ctx->extra_certs,i);
860 n=i2d_X509(x,NULL); 1056 if (!dtls1_add_cert_to_buf(buf, &l, x))
861 if (!BUF_MEM_grow_clean(buf,(int)(n+l+3))) 1057 return 0;
862 {
863 SSLerr(SSL_F_DTLS1_OUTPUT_CERT_CHAIN,ERR_R_BUF_LIB);
864 return(0);
865 }
866 p=(unsigned char *)&(buf->data[l]);
867 l2n3(n,p);
868 i2d_X509(x,&p);
869 l+=n+3;
870 } 1058 }
871 1059
872 l-= (3 + DTLS1_HM_HEADER_LENGTH); 1060 l-= (3 + DTLS1_HM_HEADER_LENGTH);
@@ -883,18 +1071,13 @@ unsigned long dtls1_output_cert_chain(SSL *s, X509 *x)
883 1071
884int dtls1_read_failed(SSL *s, int code) 1072int dtls1_read_failed(SSL *s, int code)
885 { 1073 {
886 DTLS1_STATE *state;
887 BIO *bio;
888 int send_alert = 0;
889
890 if ( code > 0) 1074 if ( code > 0)
891 { 1075 {
892 fprintf( stderr, "invalid state reached %s:%d", __FILE__, __LINE__); 1076 fprintf( stderr, "invalid state reached %s:%d", __FILE__, __LINE__);
893 return 1; 1077 return 1;
894 } 1078 }
895 1079
896 bio = SSL_get_rbio(s); 1080 if (!dtls1_is_timer_expired(s))
897 if ( ! BIO_dgram_recv_timedout(bio))
898 { 1081 {
899 /* not a timeout, none of our business, 1082 /* not a timeout, none of our business,
900 let higher layers handle this. in fact it's probably an error */ 1083 let higher layers handle this. in fact it's probably an error */
@@ -907,23 +1090,6 @@ int dtls1_read_failed(SSL *s, int code)
907 return code; 1090 return code;
908 } 1091 }
909 1092
910 state = s->d1;
911 state->timeout.num_alerts++;
912 if ( state->timeout.num_alerts > DTLS1_TMO_ALERT_COUNT)
913 {
914 /* fail the connection, enough alerts have been sent */
915 SSLerr(SSL_F_DTLS1_READ_FAILED,SSL_R_READ_TIMEOUT_EXPIRED);
916 return 0;
917 }
918
919 state->timeout.read_timeouts++;
920 if ( state->timeout.read_timeouts > DTLS1_TMO_READ_COUNT)
921 {
922 send_alert = 1;
923 state->timeout.read_timeouts = 1;
924 }
925
926
927#if 0 /* for now, each alert contains only one record number */ 1093#if 0 /* for now, each alert contains only one record number */
928 item = pqueue_peek(state->rcvd_records); 1094 item = pqueue_peek(state->rcvd_records);
929 if ( item ) 1095 if ( item )
@@ -934,16 +1100,29 @@ int dtls1_read_failed(SSL *s, int code)
934#endif 1100#endif
935 1101
936#if 0 /* no more alert sending, just retransmit the last set of messages */ 1102#if 0 /* no more alert sending, just retransmit the last set of messages */
937 if ( send_alert) 1103 if ( state->timeout.read_timeouts >= DTLS1_TMO_READ_COUNT)
938 ssl3_send_alert(s,SSL3_AL_WARNING, 1104 ssl3_send_alert(s,SSL3_AL_WARNING,
939 DTLS1_AD_MISSING_HANDSHAKE_MESSAGE); 1105 DTLS1_AD_MISSING_HANDSHAKE_MESSAGE);
940#endif 1106#endif
941 1107
942 return dtls1_retransmit_buffered_messages(s) ; 1108 return dtls1_handle_timeout(s);
943 } 1109 }
944 1110
1111int
1112dtls1_get_queue_priority(unsigned short seq, int is_ccs)
1113 {
1114 /* The index of the retransmission queue actually is the message sequence number,
1115 * since the queue only contains messages of a single handshake. However, the
1116 * ChangeCipherSpec has no message sequence number and so using only the sequence
1117 * will result in the CCS and Finished having the same index. To prevent this,
1118 * the sequence number is multiplied by 2. In case of a CCS 1 is subtracted.
1119 * This does not only differ CSS and Finished, it also maintains the order of the
1120 * index (important for priority queues) and fits in the unsigned short variable.
1121 */
1122 return seq * 2 - is_ccs;
1123 }
945 1124
946static int 1125int
947dtls1_retransmit_buffered_messages(SSL *s) 1126dtls1_retransmit_buffered_messages(SSL *s)
948 { 1127 {
949 pqueue sent = s->d1->sent_messages; 1128 pqueue sent = s->d1->sent_messages;
@@ -957,8 +1136,9 @@ dtls1_retransmit_buffered_messages(SSL *s)
957 for ( item = pqueue_next(&iter); item != NULL; item = pqueue_next(&iter)) 1136 for ( item = pqueue_next(&iter); item != NULL; item = pqueue_next(&iter))
958 { 1137 {
959 frag = (hm_fragment *)item->data; 1138 frag = (hm_fragment *)item->data;
960 if ( dtls1_retransmit_message(s, frag->msg_header.seq, 0, &found) <= 0 && 1139 if ( dtls1_retransmit_message(s,
961 found) 1140 (unsigned short)dtls1_get_queue_priority(frag->msg_header.seq, frag->msg_header.is_ccs),
1141 0, &found) <= 0 && found)
962 { 1142 {
963 fprintf(stderr, "dtls1_retransmit_message() failed\n"); 1143 fprintf(stderr, "dtls1_retransmit_message() failed\n");
964 return -1; 1144 return -1;
@@ -973,22 +1153,20 @@ dtls1_buffer_message(SSL *s, int is_ccs)
973 { 1153 {
974 pitem *item; 1154 pitem *item;
975 hm_fragment *frag; 1155 hm_fragment *frag;
976 PQ_64BIT seq64; 1156 unsigned char seq64be[8];
977 unsigned int epoch = s->d1->w_epoch;
978 1157
979 /* this function is called immediately after a message has 1158 /* this function is called immediately after a message has
980 * been serialized */ 1159 * been serialized */
981 OPENSSL_assert(s->init_off == 0); 1160 OPENSSL_assert(s->init_off == 0);
982 1161
983 frag = dtls1_hm_fragment_new(s->init_num); 1162 frag = dtls1_hm_fragment_new(s->init_num, 0);
984 1163
985 memcpy(frag->fragment, s->init_buf->data, s->init_num); 1164 memcpy(frag->fragment, s->init_buf->data, s->init_num);
986 1165
987 if ( is_ccs) 1166 if ( is_ccs)
988 { 1167 {
989 OPENSSL_assert(s->d1->w_msg_hdr.msg_len + 1168 OPENSSL_assert(s->d1->w_msg_hdr.msg_len +
990 DTLS1_CCS_HEADER_LENGTH <= (unsigned int)s->init_num); 1169 ((s->version==DTLS1_VERSION)?DTLS1_CCS_HEADER_LENGTH:3) == (unsigned int)s->init_num);
991 epoch++;
992 } 1170 }
993 else 1171 else
994 { 1172 {
@@ -1003,11 +1181,20 @@ dtls1_buffer_message(SSL *s, int is_ccs)
1003 frag->msg_header.frag_len = s->d1->w_msg_hdr.msg_len; 1181 frag->msg_header.frag_len = s->d1->w_msg_hdr.msg_len;
1004 frag->msg_header.is_ccs = is_ccs; 1182 frag->msg_header.is_ccs = is_ccs;
1005 1183
1006 pq_64bit_init(&seq64); 1184 /* save current state*/
1007 pq_64bit_assign_word(&seq64, epoch<<16 | frag->msg_header.seq); 1185 frag->msg_header.saved_retransmit_state.enc_write_ctx = s->enc_write_ctx;
1008 1186 frag->msg_header.saved_retransmit_state.write_hash = s->write_hash;
1009 item = pitem_new(seq64, frag); 1187 frag->msg_header.saved_retransmit_state.compress = s->compress;
1010 pq_64bit_free(&seq64); 1188 frag->msg_header.saved_retransmit_state.session = s->session;
1189 frag->msg_header.saved_retransmit_state.epoch = s->d1->w_epoch;
1190
1191 memset(seq64be,0,sizeof(seq64be));
1192 seq64be[6] = (unsigned char)(dtls1_get_queue_priority(frag->msg_header.seq,
1193 frag->msg_header.is_ccs)>>8);
1194 seq64be[7] = (unsigned char)(dtls1_get_queue_priority(frag->msg_header.seq,
1195 frag->msg_header.is_ccs));
1196
1197 item = pitem_new(seq64be, frag);
1011 if ( item == NULL) 1198 if ( item == NULL)
1012 { 1199 {
1013 dtls1_hm_fragment_free(frag); 1200 dtls1_hm_fragment_free(frag);
@@ -1033,7 +1220,9 @@ dtls1_retransmit_message(SSL *s, unsigned short seq, unsigned long frag_off,
1033 pitem *item; 1220 pitem *item;
1034 hm_fragment *frag ; 1221 hm_fragment *frag ;
1035 unsigned long header_length; 1222 unsigned long header_length;
1036 PQ_64BIT seq64; 1223 unsigned char seq64be[8];
1224 struct dtls1_retransmit_state saved_state;
1225 unsigned char save_write_sequence[8];
1037 1226
1038 /* 1227 /*
1039 OPENSSL_assert(s->init_num == 0); 1228 OPENSSL_assert(s->init_num == 0);
@@ -1041,11 +1230,11 @@ dtls1_retransmit_message(SSL *s, unsigned short seq, unsigned long frag_off,
1041 */ 1230 */
1042 1231
1043 /* XDTLS: the requested message ought to be found, otherwise error */ 1232 /* XDTLS: the requested message ought to be found, otherwise error */
1044 pq_64bit_init(&seq64); 1233 memset(seq64be,0,sizeof(seq64be));
1045 pq_64bit_assign_word(&seq64, seq); 1234 seq64be[6] = (unsigned char)(seq>>8);
1235 seq64be[7] = (unsigned char)seq;
1046 1236
1047 item = pqueue_find(s->d1->sent_messages, seq64); 1237 item = pqueue_find(s->d1->sent_messages, seq64be);
1048 pq_64bit_free(&seq64);
1049 if ( item == NULL) 1238 if ( item == NULL)
1050 { 1239 {
1051 fprintf(stderr, "retransmit: message %d non-existant\n", seq); 1240 fprintf(stderr, "retransmit: message %d non-existant\n", seq);
@@ -1069,9 +1258,45 @@ dtls1_retransmit_message(SSL *s, unsigned short seq, unsigned long frag_off,
1069 frag->msg_header.msg_len, frag->msg_header.seq, 0, 1258 frag->msg_header.msg_len, frag->msg_header.seq, 0,
1070 frag->msg_header.frag_len); 1259 frag->msg_header.frag_len);
1071 1260
1261 /* save current state */
1262 saved_state.enc_write_ctx = s->enc_write_ctx;
1263 saved_state.write_hash = s->write_hash;
1264 saved_state.compress = s->compress;
1265 saved_state.session = s->session;
1266 saved_state.epoch = s->d1->w_epoch;
1267 saved_state.epoch = s->d1->w_epoch;
1268
1072 s->d1->retransmitting = 1; 1269 s->d1->retransmitting = 1;
1270
1271 /* restore state in which the message was originally sent */
1272 s->enc_write_ctx = frag->msg_header.saved_retransmit_state.enc_write_ctx;
1273 s->write_hash = frag->msg_header.saved_retransmit_state.write_hash;
1274 s->compress = frag->msg_header.saved_retransmit_state.compress;
1275 s->session = frag->msg_header.saved_retransmit_state.session;
1276 s->d1->w_epoch = frag->msg_header.saved_retransmit_state.epoch;
1277
1278 if (frag->msg_header.saved_retransmit_state.epoch == saved_state.epoch - 1)
1279 {
1280 memcpy(save_write_sequence, s->s3->write_sequence, sizeof(s->s3->write_sequence));
1281 memcpy(s->s3->write_sequence, s->d1->last_write_sequence, sizeof(s->s3->write_sequence));
1282 }
1283
1073 ret = dtls1_do_write(s, frag->msg_header.is_ccs ? 1284 ret = dtls1_do_write(s, frag->msg_header.is_ccs ?
1074 SSL3_RT_CHANGE_CIPHER_SPEC : SSL3_RT_HANDSHAKE); 1285 SSL3_RT_CHANGE_CIPHER_SPEC : SSL3_RT_HANDSHAKE);
1286
1287 /* restore current state */
1288 s->enc_write_ctx = saved_state.enc_write_ctx;
1289 s->write_hash = saved_state.write_hash;
1290 s->compress = saved_state.compress;
1291 s->session = saved_state.session;
1292 s->d1->w_epoch = saved_state.epoch;
1293
1294 if (frag->msg_header.saved_retransmit_state.epoch == saved_state.epoch - 1)
1295 {
1296 memcpy(s->d1->last_write_sequence, s->s3->write_sequence, sizeof(s->s3->write_sequence));
1297 memcpy(s->s3->write_sequence, save_write_sequence, sizeof(s->s3->write_sequence));
1298 }
1299
1075 s->d1->retransmitting = 0; 1300 s->d1->retransmitting = 0;
1076 1301
1077 (void)BIO_flush(SSL_get_wbio(s)); 1302 (void)BIO_flush(SSL_get_wbio(s));
@@ -1160,7 +1385,7 @@ dtls1_min_mtu(void)
1160static unsigned int 1385static unsigned int
1161dtls1_guess_mtu(unsigned int curr_mtu) 1386dtls1_guess_mtu(unsigned int curr_mtu)
1162 { 1387 {
1163 size_t i; 1388 unsigned int i;
1164 1389
1165 if ( curr_mtu == 0 ) 1390 if ( curr_mtu == 0 )
1166 return g_probable_mtu[0] ; 1391 return g_probable_mtu[0] ;
diff --git a/src/lib/libssl/d1_enc.c b/src/lib/libssl/d1_enc.c
index cf3332e4e4..8fa57347a9 100644
--- a/src/lib/libssl/d1_enc.c
+++ b/src/lib/libssl/d1_enc.c
@@ -136,8 +136,12 @@ int dtls1_enc(SSL *s, int send)
136 136
137 if (send) 137 if (send)
138 { 138 {
139 if (s->write_hash != NULL) 139 if (EVP_MD_CTX_md(s->write_hash))
140 n=EVP_MD_size(s->write_hash); 140 {
141 n=EVP_MD_CTX_size(s->write_hash);
142 if (n < 0)
143 return -1;
144 }
141 ds=s->enc_write_ctx; 145 ds=s->enc_write_ctx;
142 rec= &(s->s3->wrec); 146 rec= &(s->s3->wrec);
143 if (s->enc_write_ctx == NULL) 147 if (s->enc_write_ctx == NULL)
@@ -151,15 +155,19 @@ int dtls1_enc(SSL *s, int send)
151 __FILE__, __LINE__); 155 __FILE__, __LINE__);
152 else if ( EVP_CIPHER_block_size(ds->cipher) > 1) 156 else if ( EVP_CIPHER_block_size(ds->cipher) > 1)
153 { 157 {
154 if (!RAND_bytes(rec->input, EVP_CIPHER_block_size(ds->cipher))) 158 if (RAND_bytes(rec->input, EVP_CIPHER_block_size(ds->cipher)) <= 0)
155 return -1; 159 return -1;
156 } 160 }
157 } 161 }
158 } 162 }
159 else 163 else
160 { 164 {
161 if (s->read_hash != NULL) 165 if (EVP_MD_CTX_md(s->read_hash))
162 n=EVP_MD_size(s->read_hash); 166 {
167 n=EVP_MD_CTX_size(s->read_hash);
168 if (n < 0)
169 return -1;
170 }
163 ds=s->enc_read_ctx; 171 ds=s->enc_read_ctx;
164 rec= &(s->s3->rrec); 172 rec= &(s->s3->rrec);
165 if (s->enc_read_ctx == NULL) 173 if (s->enc_read_ctx == NULL)
@@ -206,11 +214,10 @@ int dtls1_enc(SSL *s, int send)
206 { 214 {
207 unsigned long ui; 215 unsigned long ui;
208 printf("EVP_Cipher(ds=%p,rec->data=%p,rec->input=%p,l=%ld) ==>\n", 216 printf("EVP_Cipher(ds=%p,rec->data=%p,rec->input=%p,l=%ld) ==>\n",
209 (void *)ds,rec->data,rec->input,l); 217 ds,rec->data,rec->input,l);
210 printf("\tEVP_CIPHER_CTX: %d buf_len, %d key_len [%ld %ld], %d iv_len\n", 218 printf("\tEVP_CIPHER_CTX: %d buf_len, %d key_len [%d %d], %d iv_len\n",
211 ds->buf_len, ds->cipher->key_len, 219 ds->buf_len, ds->cipher->key_len,
212 (unsigned long)DES_KEY_SZ, 220 DES_KEY_SZ, DES_SCHEDULE_SZ,
213 (unsigned long)DES_SCHEDULE_SZ,
214 ds->cipher->iv_len); 221 ds->cipher->iv_len);
215 printf("\t\tIV: "); 222 printf("\t\tIV: ");
216 for (i=0; i<ds->cipher->iv_len; i++) printf("%02X", ds->iv[i]); 223 for (i=0; i<ds->cipher->iv_len; i++) printf("%02X", ds->iv[i]);
@@ -235,10 +242,10 @@ int dtls1_enc(SSL *s, int send)
235 242
236#ifdef KSSL_DEBUG 243#ifdef KSSL_DEBUG
237 { 244 {
238 unsigned long ki; 245 unsigned long i;
239 printf("\trec->data="); 246 printf("\trec->data=");
240 for (ki=0; ki<l; ki++) 247 for (i=0; i<l; i++)
241 printf(" %02x", rec->data[ki]); printf("\n"); 248 printf(" %02x", rec->data[i]); printf("\n");
242 } 249 }
243#endif /* KSSL_DEBUG */ 250#endif /* KSSL_DEBUG */
244 251
diff --git a/src/lib/libssl/d1_lib.c b/src/lib/libssl/d1_lib.c
index 3568e97a87..96b220e87c 100644
--- a/src/lib/libssl/d1_lib.c
+++ b/src/lib/libssl/d1_lib.c
@@ -58,10 +58,17 @@
58 */ 58 */
59 59
60#include <stdio.h> 60#include <stdio.h>
61#define USE_SOCKETS
61#include <openssl/objects.h> 62#include <openssl/objects.h>
62#include "ssl_locl.h" 63#include "ssl_locl.h"
63 64
65#if defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_VMS)
66#include <sys/timeb.h>
67#endif
68
69static void get_current_time(struct timeval *t);
64const char dtls1_version_str[]="DTLSv1" OPENSSL_VERSION_PTEXT; 70const char dtls1_version_str[]="DTLSv1" OPENSSL_VERSION_PTEXT;
71int dtls1_listen(SSL *s, struct sockaddr *client);
65 72
66SSL3_ENC_METHOD DTLSv1_enc_data={ 73SSL3_ENC_METHOD DTLSv1_enc_data={
67 dtls1_enc, 74 dtls1_enc,
@@ -84,11 +91,6 @@ long dtls1_default_timeout(void)
84 return(60*60*2); 91 return(60*60*2);
85 } 92 }
86 93
87IMPLEMENT_dtls1_meth_func(dtlsv1_base_method,
88 ssl_undefined_function,
89 ssl_undefined_function,
90 ssl_bad_method)
91
92int dtls1_new(SSL *s) 94int dtls1_new(SSL *s)
93 { 95 {
94 DTLS1_STATE *d1; 96 DTLS1_STATE *d1;
@@ -98,22 +100,12 @@ int dtls1_new(SSL *s)
98 memset(d1,0, sizeof *d1); 100 memset(d1,0, sizeof *d1);
99 101
100 /* d1->handshake_epoch=0; */ 102 /* d1->handshake_epoch=0; */
101#if defined(OPENSSL_SYS_VMS) || defined(VMS_TEST)
102 d1->bitmap.length=64;
103#else
104 d1->bitmap.length=sizeof(d1->bitmap.map) * 8;
105#endif
106 pq_64bit_init(&(d1->bitmap.map));
107 pq_64bit_init(&(d1->bitmap.max_seq_num));
108
109 d1->next_bitmap.length = d1->bitmap.length;
110 pq_64bit_init(&(d1->next_bitmap.map));
111 pq_64bit_init(&(d1->next_bitmap.max_seq_num));
112 103
113 d1->unprocessed_rcds.q=pqueue_new(); 104 d1->unprocessed_rcds.q=pqueue_new();
114 d1->processed_rcds.q=pqueue_new(); 105 d1->processed_rcds.q=pqueue_new();
115 d1->buffered_messages = pqueue_new(); 106 d1->buffered_messages = pqueue_new();
116 d1->sent_messages=pqueue_new(); 107 d1->sent_messages=pqueue_new();
108 d1->buffered_app_data.q=pqueue_new();
117 109
118 if ( s->server) 110 if ( s->server)
119 { 111 {
@@ -121,12 +113,13 @@ int dtls1_new(SSL *s)
121 } 113 }
122 114
123 if( ! d1->unprocessed_rcds.q || ! d1->processed_rcds.q 115 if( ! d1->unprocessed_rcds.q || ! d1->processed_rcds.q
124 || ! d1->buffered_messages || ! d1->sent_messages) 116 || ! d1->buffered_messages || ! d1->sent_messages || ! d1->buffered_app_data.q)
125 { 117 {
126 if ( d1->unprocessed_rcds.q) pqueue_free(d1->unprocessed_rcds.q); 118 if ( d1->unprocessed_rcds.q) pqueue_free(d1->unprocessed_rcds.q);
127 if ( d1->processed_rcds.q) pqueue_free(d1->processed_rcds.q); 119 if ( d1->processed_rcds.q) pqueue_free(d1->processed_rcds.q);
128 if ( d1->buffered_messages) pqueue_free(d1->buffered_messages); 120 if ( d1->buffered_messages) pqueue_free(d1->buffered_messages);
129 if ( d1->sent_messages) pqueue_free(d1->sent_messages); 121 if ( d1->sent_messages) pqueue_free(d1->sent_messages);
122 if ( d1->buffered_app_data.q) pqueue_free(d1->buffered_app_data.q);
130 OPENSSL_free(d1); 123 OPENSSL_free(d1);
131 return (0); 124 return (0);
132 } 125 }
@@ -175,11 +168,14 @@ void dtls1_free(SSL *s)
175 } 168 }
176 pqueue_free(s->d1->sent_messages); 169 pqueue_free(s->d1->sent_messages);
177 170
178 pq_64bit_free(&(s->d1->bitmap.map)); 171 while ( (item = pqueue_pop(s->d1->buffered_app_data.q)) != NULL)
179 pq_64bit_free(&(s->d1->bitmap.max_seq_num)); 172 {
180 173 frag = (hm_fragment *)item->data;
181 pq_64bit_free(&(s->d1->next_bitmap.map)); 174 OPENSSL_free(frag->fragment);
182 pq_64bit_free(&(s->d1->next_bitmap.max_seq_num)); 175 OPENSSL_free(frag);
176 pitem_free(item);
177 }
178 pqueue_free(s->d1->buffered_app_data.q);
183 179
184 OPENSSL_free(s->d1); 180 OPENSSL_free(s->d1);
185 } 181 }
@@ -187,7 +183,36 @@ void dtls1_free(SSL *s)
187void dtls1_clear(SSL *s) 183void dtls1_clear(SSL *s)
188 { 184 {
189 ssl3_clear(s); 185 ssl3_clear(s);
190 s->version=DTLS1_VERSION; 186 if (s->options & SSL_OP_CISCO_ANYCONNECT)
187 s->version=DTLS1_BAD_VER;
188 else
189 s->version=DTLS1_VERSION;
190 }
191
192long dtls1_ctrl(SSL *s, int cmd, long larg, void *parg)
193 {
194 int ret=0;
195
196 switch (cmd)
197 {
198 case DTLS_CTRL_GET_TIMEOUT:
199 if (dtls1_get_timeout(s, (struct timeval*) parg) != NULL)
200 {
201 ret = 1;
202 }
203 break;
204 case DTLS_CTRL_HANDLE_TIMEOUT:
205 ret = dtls1_handle_timeout(s);
206 break;
207 case DTLS_CTRL_LISTEN:
208 ret = dtls1_listen(s, parg);
209 break;
210
211 default:
212 ret = ssl3_ctrl(s, cmd, larg, parg);
213 break;
214 }
215 return(ret);
191 } 216 }
192 217
193/* 218/*
@@ -197,15 +222,173 @@ void dtls1_clear(SSL *s)
197 * to explicitly list their SSL_* codes. Currently RC4 is the only one 222 * to explicitly list their SSL_* codes. Currently RC4 is the only one
198 * available, but if new ones emerge, they will have to be added... 223 * available, but if new ones emerge, they will have to be added...
199 */ 224 */
200SSL_CIPHER *dtls1_get_cipher(unsigned int u) 225const SSL_CIPHER *dtls1_get_cipher(unsigned int u)
201 { 226 {
202 SSL_CIPHER *ciph = ssl3_get_cipher(u); 227 const SSL_CIPHER *ciph = ssl3_get_cipher(u);
203 228
204 if (ciph != NULL) 229 if (ciph != NULL)
205 { 230 {
206 if ((ciph->algorithms&SSL_ENC_MASK) == SSL_RC4) 231 if (ciph->algorithm_enc == SSL_RC4)
207 return NULL; 232 return NULL;
208 } 233 }
209 234
210 return ciph; 235 return ciph;
211 } 236 }
237
238void dtls1_start_timer(SSL *s)
239 {
240 /* If timer is not set, initialize duration with 1 second */
241 if (s->d1->next_timeout.tv_sec == 0 && s->d1->next_timeout.tv_usec == 0)
242 {
243 s->d1->timeout_duration = 1;
244 }
245
246 /* Set timeout to current time */
247 get_current_time(&(s->d1->next_timeout));
248
249 /* Add duration to current time */
250 s->d1->next_timeout.tv_sec += s->d1->timeout_duration;
251 BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT, 0, &(s->d1->next_timeout));
252 }
253
254struct timeval* dtls1_get_timeout(SSL *s, struct timeval* timeleft)
255 {
256 struct timeval timenow;
257
258 /* If no timeout is set, just return NULL */
259 if (s->d1->next_timeout.tv_sec == 0 && s->d1->next_timeout.tv_usec == 0)
260 {
261 return NULL;
262 }
263
264 /* Get current time */
265 get_current_time(&timenow);
266
267 /* If timer already expired, set remaining time to 0 */
268 if (s->d1->next_timeout.tv_sec < timenow.tv_sec ||
269 (s->d1->next_timeout.tv_sec == timenow.tv_sec &&
270 s->d1->next_timeout.tv_usec <= timenow.tv_usec))
271 {
272 memset(timeleft, 0, sizeof(struct timeval));
273 return timeleft;
274 }
275
276 /* Calculate time left until timer expires */
277 memcpy(timeleft, &(s->d1->next_timeout), sizeof(struct timeval));
278 timeleft->tv_sec -= timenow.tv_sec;
279 timeleft->tv_usec -= timenow.tv_usec;
280 if (timeleft->tv_usec < 0)
281 {
282 timeleft->tv_sec--;
283 timeleft->tv_usec += 1000000;
284 }
285
286 /* If remaining time is less than 15 ms, set it to 0
287 * to prevent issues because of small devergences with
288 * socket timeouts.
289 */
290 if (timeleft->tv_sec == 0 && timeleft->tv_usec < 15000)
291 {
292 memset(timeleft, 0, sizeof(struct timeval));
293 }
294
295
296 return timeleft;
297 }
298
299int dtls1_is_timer_expired(SSL *s)
300 {
301 struct timeval timeleft;
302
303 /* Get time left until timeout, return false if no timer running */
304 if (dtls1_get_timeout(s, &timeleft) == NULL)
305 {
306 return 0;
307 }
308
309 /* Return false if timer is not expired yet */
310 if (timeleft.tv_sec > 0 || timeleft.tv_usec > 0)
311 {
312 return 0;
313 }
314
315 /* Timer expired, so return true */
316 return 1;
317 }
318
319void dtls1_double_timeout(SSL *s)
320 {
321 s->d1->timeout_duration *= 2;
322 if (s->d1->timeout_duration > 60)
323 s->d1->timeout_duration = 60;
324 dtls1_start_timer(s);
325 }
326
327void dtls1_stop_timer(SSL *s)
328 {
329 /* Reset everything */
330 memset(&(s->d1->next_timeout), 0, sizeof(struct timeval));
331 s->d1->timeout_duration = 1;
332 BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT, 0, &(s->d1->next_timeout));
333 }
334
335int dtls1_handle_timeout(SSL *s)
336 {
337 DTLS1_STATE *state;
338
339 /* if no timer is expired, don't do anything */
340 if (!dtls1_is_timer_expired(s))
341 {
342 return 0;
343 }
344
345 dtls1_double_timeout(s);
346 state = s->d1;
347 state->timeout.num_alerts++;
348 if ( state->timeout.num_alerts > DTLS1_TMO_ALERT_COUNT)
349 {
350 /* fail the connection, enough alerts have been sent */
351 SSLerr(SSL_F_DTLS1_HANDLE_TIMEOUT,SSL_R_READ_TIMEOUT_EXPIRED);
352 return 0;
353 }
354
355 state->timeout.read_timeouts++;
356 if ( state->timeout.read_timeouts > DTLS1_TMO_READ_COUNT)
357 {
358 state->timeout.read_timeouts = 1;
359 }
360
361 dtls1_start_timer(s);
362 return dtls1_retransmit_buffered_messages(s);
363 }
364
365static void get_current_time(struct timeval *t)
366{
367#ifdef OPENSSL_SYS_WIN32
368 struct _timeb tb;
369 _ftime(&tb);
370 t->tv_sec = (long)tb.time;
371 t->tv_usec = (long)tb.millitm * 1000;
372#elif defined(OPENSSL_SYS_VMS)
373 struct timeb tb;
374 ftime(&tb);
375 t->tv_sec = (long)tb.time;
376 t->tv_usec = (long)tb.millitm * 1000;
377#else
378 gettimeofday(t, NULL);
379#endif
380}
381
382int dtls1_listen(SSL *s, struct sockaddr *client)
383 {
384 int ret;
385
386 SSL_set_options(s, SSL_OP_COOKIE_EXCHANGE);
387 s->d1->listen = 1;
388
389 ret = SSL_accept(s);
390 if (ret <= 0) return ret;
391
392 (void) BIO_dgram_get_peer(SSL_get_rbio(s), client);
393 return 1;
394 }
diff --git a/src/lib/libssl/d1_meth.c b/src/lib/libssl/d1_meth.c
index 8a6cf31947..5c4004bfe3 100644
--- a/src/lib/libssl/d1_meth.c
+++ b/src/lib/libssl/d1_meth.c
@@ -61,8 +61,8 @@
61#include <openssl/objects.h> 61#include <openssl/objects.h>
62#include "ssl_locl.h" 62#include "ssl_locl.h"
63 63
64static SSL_METHOD *dtls1_get_method(int ver); 64static const SSL_METHOD *dtls1_get_method(int ver);
65static SSL_METHOD *dtls1_get_method(int ver) 65static const SSL_METHOD *dtls1_get_method(int ver)
66 { 66 {
67 if (ver == DTLS1_VERSION) 67 if (ver == DTLS1_VERSION)
68 return(DTLSv1_method()); 68 return(DTLSv1_method());
diff --git a/src/lib/libssl/t1_reneg.c b/src/lib/libssl/t1_reneg.c
new file mode 100644
index 0000000000..9c2cc3c712
--- /dev/null
+++ b/src/lib/libssl/t1_reneg.c
@@ -0,0 +1,292 @@
1/* ssl/t1_reneg.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 * Copyright (c) 1998-2009 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#include <stdio.h>
112#include <openssl/objects.h>
113#include "ssl_locl.h"
114
115/* Add the client's renegotiation binding */
116int ssl_add_clienthello_renegotiate_ext(SSL *s, unsigned char *p, int *len,
117 int maxlen)
118 {
119 if(p)
120 {
121 if((s->s3->previous_client_finished_len+1) > maxlen)
122 {
123 SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_RENEGOTIATE_EXT,SSL_R_RENEGOTIATE_EXT_TOO_LONG);
124 return 0;
125 }
126
127 /* Length byte */
128 *p = s->s3->previous_client_finished_len;
129 p++;
130
131 memcpy(p, s->s3->previous_client_finished,
132 s->s3->previous_client_finished_len);
133#ifdef OPENSSL_RI_DEBUG
134 fprintf(stderr, "%s RI extension sent by client\n",
135 s->s3->previous_client_finished_len ? "Non-empty" : "Empty");
136#endif
137 }
138
139 *len=s->s3->previous_client_finished_len + 1;
140
141
142 return 1;
143 }
144
145/* Parse the client's renegotiation binding and abort if it's not
146 right */
147int ssl_parse_clienthello_renegotiate_ext(SSL *s, unsigned char *d, int len,
148 int *al)
149 {
150 int ilen;
151
152 /* Parse the length byte */
153 if(len < 1)
154 {
155 SSLerr(SSL_F_SSL_PARSE_CLIENTHELLO_RENEGOTIATE_EXT,SSL_R_RENEGOTIATION_ENCODING_ERR);
156 *al=SSL_AD_ILLEGAL_PARAMETER;
157 return 0;
158 }
159 ilen = *d;
160 d++;
161
162 /* Consistency check */
163 if((ilen+1) != len)
164 {
165 SSLerr(SSL_F_SSL_PARSE_CLIENTHELLO_RENEGOTIATE_EXT,SSL_R_RENEGOTIATION_ENCODING_ERR);
166 *al=SSL_AD_ILLEGAL_PARAMETER;
167 return 0;
168 }
169
170 /* Check that the extension matches */
171 if(ilen != s->s3->previous_client_finished_len)
172 {
173 SSLerr(SSL_F_SSL_PARSE_CLIENTHELLO_RENEGOTIATE_EXT,SSL_R_RENEGOTIATION_MISMATCH);
174 *al=SSL_AD_HANDSHAKE_FAILURE;
175 return 0;
176 }
177
178 if(memcmp(d, s->s3->previous_client_finished,
179 s->s3->previous_client_finished_len))
180 {
181 SSLerr(SSL_F_SSL_PARSE_CLIENTHELLO_RENEGOTIATE_EXT,SSL_R_RENEGOTIATION_MISMATCH);
182 *al=SSL_AD_HANDSHAKE_FAILURE;
183 return 0;
184 }
185#ifdef OPENSSL_RI_DEBUG
186 fprintf(stderr, "%s RI extension received by server\n",
187 ilen ? "Non-empty" : "Empty");
188#endif
189
190 s->s3->send_connection_binding=1;
191
192 return 1;
193 }
194
195/* Add the server's renegotiation binding */
196int ssl_add_serverhello_renegotiate_ext(SSL *s, unsigned char *p, int *len,
197 int maxlen)
198 {
199 if(p)
200 {
201 if((s->s3->previous_client_finished_len +
202 s->s3->previous_server_finished_len + 1) > maxlen)
203 {
204 SSLerr(SSL_F_SSL_ADD_SERVERHELLO_RENEGOTIATE_EXT,SSL_R_RENEGOTIATE_EXT_TOO_LONG);
205 return 0;
206 }
207
208 /* Length byte */
209 *p = s->s3->previous_client_finished_len + s->s3->previous_server_finished_len;
210 p++;
211
212 memcpy(p, s->s3->previous_client_finished,
213 s->s3->previous_client_finished_len);
214 p += s->s3->previous_client_finished_len;
215
216 memcpy(p, s->s3->previous_server_finished,
217 s->s3->previous_server_finished_len);
218#ifdef OPENSSL_RI_DEBUG
219 fprintf(stderr, "%s RI extension sent by server\n",
220 s->s3->previous_client_finished_len ? "Non-empty" : "Empty");
221#endif
222 }
223
224 *len=s->s3->previous_client_finished_len
225 + s->s3->previous_server_finished_len + 1;
226
227 return 1;
228 }
229
230/* Parse the server's renegotiation binding and abort if it's not
231 right */
232int ssl_parse_serverhello_renegotiate_ext(SSL *s, unsigned char *d, int len,
233 int *al)
234 {
235 int expected_len=s->s3->previous_client_finished_len
236 + s->s3->previous_server_finished_len;
237 int ilen;
238
239 /* Check for logic errors */
240 OPENSSL_assert(!expected_len || s->s3->previous_client_finished_len);
241 OPENSSL_assert(!expected_len || s->s3->previous_server_finished_len);
242
243 /* Parse the length byte */
244 if(len < 1)
245 {
246 SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_RENEGOTIATE_EXT,SSL_R_RENEGOTIATION_ENCODING_ERR);
247 *al=SSL_AD_ILLEGAL_PARAMETER;
248 return 0;
249 }
250 ilen = *d;
251 d++;
252
253 /* Consistency check */
254 if(ilen+1 != len)
255 {
256 SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_RENEGOTIATE_EXT,SSL_R_RENEGOTIATION_ENCODING_ERR);
257 *al=SSL_AD_ILLEGAL_PARAMETER;
258 return 0;
259 }
260
261 /* Check that the extension matches */
262 if(ilen != expected_len)
263 {
264 SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_RENEGOTIATE_EXT,SSL_R_RENEGOTIATION_MISMATCH);
265 *al=SSL_AD_HANDSHAKE_FAILURE;
266 return 0;
267 }
268
269 if(memcmp(d, s->s3->previous_client_finished,
270 s->s3->previous_client_finished_len))
271 {
272 SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_RENEGOTIATE_EXT,SSL_R_RENEGOTIATION_MISMATCH);
273 *al=SSL_AD_HANDSHAKE_FAILURE;
274 return 0;
275 }
276 d += s->s3->previous_client_finished_len;
277
278 if(memcmp(d, s->s3->previous_server_finished,
279 s->s3->previous_server_finished_len))
280 {
281 SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_RENEGOTIATE_EXT,SSL_R_RENEGOTIATION_MISMATCH);
282 *al=SSL_AD_ILLEGAL_PARAMETER;
283 return 0;
284 }
285#ifdef OPENSSL_RI_DEBUG
286 fprintf(stderr, "%s RI extension received by client\n",
287 ilen ? "Non-empty" : "Empty");
288#endif
289 s->s3->send_connection_binding=1;
290
291 return 1;
292 }
diff --git a/src/lib/libssl/test/CAss.cnf b/src/lib/libssl/test/CAss.cnf
index 546e660626..20f8f05e3d 100644
--- a/src/lib/libssl/test/CAss.cnf
+++ b/src/lib/libssl/test/CAss.cnf
@@ -7,7 +7,7 @@ RANDFILE = ./.rnd
7 7
8#################################################################### 8####################################################################
9[ req ] 9[ req ]
10default_bits = 1024 10default_bits = 512
11default_keyfile = keySS.pem 11default_keyfile = keySS.pem
12distinguished_name = req_distinguished_name 12distinguished_name = req_distinguished_name
13encrypt_rsa_key = no 13encrypt_rsa_key = no
diff --git a/src/lib/libssl/test/CAtsa.cnf b/src/lib/libssl/test/CAtsa.cnf
new file mode 100644
index 0000000000..f5a275bfc2
--- /dev/null
+++ b/src/lib/libssl/test/CAtsa.cnf
@@ -0,0 +1,163 @@
1
2#
3# This config is used by the Time Stamp Authority tests.
4#
5
6RANDFILE = ./.rnd
7
8# Extra OBJECT IDENTIFIER info:
9oid_section = new_oids
10
11TSDNSECT = ts_cert_dn
12INDEX = 1
13
14[ new_oids ]
15
16# Policies used by the TSA tests.
17tsa_policy1 = 1.2.3.4.1
18tsa_policy2 = 1.2.3.4.5.6
19tsa_policy3 = 1.2.3.4.5.7
20
21#----------------------------------------------------------------------
22[ ca ]
23default_ca = CA_default # The default ca section
24
25[ CA_default ]
26
27dir = ./demoCA
28certs = $dir/certs # Where the issued certs are kept
29database = $dir/index.txt # database index file.
30new_certs_dir = $dir/newcerts # default place for new certs.
31
32certificate = $dir/cacert.pem # The CA certificate
33serial = $dir/serial # The current serial number
34private_key = $dir/private/cakey.pem# The private key
35RANDFILE = $dir/private/.rand # private random number file
36
37default_days = 365 # how long to certify for
38default_md = sha1 # which md to use.
39preserve = no # keep passed DN ordering
40
41policy = policy_match
42
43# For the CA policy
44[ policy_match ]
45countryName = supplied
46stateOrProvinceName = supplied
47organizationName = supplied
48organizationalUnitName = optional
49commonName = supplied
50emailAddress = optional
51
52#----------------------------------------------------------------------
53[ req ]
54default_bits = 1024
55default_md = sha1
56distinguished_name = $ENV::TSDNSECT
57encrypt_rsa_key = no
58prompt = no
59# attributes = req_attributes
60x509_extensions = v3_ca # The extentions to add to the self signed cert
61
62string_mask = nombstr
63
64[ ts_ca_dn ]
65countryName = HU
66stateOrProvinceName = Budapest
67localityName = Budapest
68organizationName = Gov-CA Ltd.
69commonName = ca1
70
71[ ts_cert_dn ]
72countryName = HU
73stateOrProvinceName = Budapest
74localityName = Buda
75organizationName = Hun-TSA Ltd.
76commonName = tsa$ENV::INDEX
77
78[ tsa_cert ]
79
80# TSA server cert is not a CA cert.
81basicConstraints=CA:FALSE
82
83# The following key usage flags are needed for TSA server certificates.
84keyUsage = nonRepudiation, digitalSignature
85extendedKeyUsage = critical,timeStamping
86
87# PKIX recommendations harmless if included in all certificates.
88subjectKeyIdentifier=hash
89authorityKeyIdentifier=keyid,issuer:always
90
91[ non_tsa_cert ]
92
93# This is not a CA cert and not a TSA cert, either (timeStamping usage missing)
94basicConstraints=CA:FALSE
95
96# The following key usage flags are needed for TSA server certificates.
97keyUsage = nonRepudiation, digitalSignature
98# timeStamping is not supported by this certificate
99# extendedKeyUsage = critical,timeStamping
100
101# PKIX recommendations harmless if included in all certificates.
102subjectKeyIdentifier=hash
103authorityKeyIdentifier=keyid,issuer:always
104
105[ v3_req ]
106
107# Extensions to add to a certificate request
108basicConstraints = CA:FALSE
109keyUsage = nonRepudiation, digitalSignature
110
111[ v3_ca ]
112
113# Extensions for a typical CA
114
115subjectKeyIdentifier=hash
116authorityKeyIdentifier=keyid:always,issuer:always
117basicConstraints = critical,CA:true
118keyUsage = cRLSign, keyCertSign
119
120#----------------------------------------------------------------------
121[ tsa ]
122
123default_tsa = tsa_config1 # the default TSA section
124
125[ tsa_config1 ]
126
127# These are used by the TSA reply generation only.
128dir = . # TSA root directory
129serial = $dir/tsa_serial # The current serial number (mandatory)
130signer_cert = $dir/tsa_cert1.pem # The TSA signing certificate
131 # (optional)
132certs = $dir/tsaca.pem # Certificate chain to include in reply
133 # (optional)
134signer_key = $dir/tsa_key1.pem # The TSA private key (optional)
135
136default_policy = tsa_policy1 # Policy if request did not specify it
137 # (optional)
138other_policies = tsa_policy2, tsa_policy3 # acceptable policies (optional)
139digests = md5, sha1 # Acceptable message digests (mandatory)
140accuracy = secs:1, millisecs:500, microsecs:100 # (optional)
141ordering = yes # Is ordering defined for timestamps?
142 # (optional, default: no)
143tsa_name = yes # Must the TSA name be included in the reply?
144 # (optional, default: no)
145ess_cert_id_chain = yes # Must the ESS cert id chain be included?
146 # (optional, default: no)
147
148[ tsa_config2 ]
149
150# This configuration uses a certificate which doesn't have timeStamping usage.
151# These are used by the TSA reply generation only.
152dir = . # TSA root directory
153serial = $dir/tsa_serial # The current serial number (mandatory)
154signer_cert = $dir/tsa_cert2.pem # The TSA signing certificate
155 # (optional)
156certs = $dir/demoCA/cacert.pem# Certificate chain to include in reply
157 # (optional)
158signer_key = $dir/tsa_key2.pem # The TSA private key (optional)
159
160default_policy = tsa_policy1 # Policy if request did not specify it
161 # (optional)
162other_policies = tsa_policy2, tsa_policy3 # acceptable policies (optional)
163digests = md5, sha1 # Acceptable message digests (mandatory)
diff --git a/src/lib/libssl/test/Uss.cnf b/src/lib/libssl/test/Uss.cnf
index 98b2e054b7..0c0ebb5f67 100644
--- a/src/lib/libssl/test/Uss.cnf
+++ b/src/lib/libssl/test/Uss.cnf
@@ -7,7 +7,7 @@ RANDFILE = ./.rnd
7 7
8#################################################################### 8####################################################################
9[ req ] 9[ req ]
10default_bits = 1024 10default_bits = 512
11default_keyfile = keySS.pem 11default_keyfile = keySS.pem
12distinguished_name = req_distinguished_name 12distinguished_name = req_distinguished_name
13encrypt_rsa_key = no 13encrypt_rsa_key = no
diff --git a/src/lib/libssl/test/asn1test.c b/src/lib/libssl/test/asn1test.c
new file mode 100755
index 0000000000..9f53d80344
--- /dev/null
+++ b/src/lib/libssl/test/asn1test.c
@@ -0,0 +1,22 @@
1#include <openssl/x509.h>
2#include <openssl/asn1_mac.h>
3
4typedef struct X
5 {
6 STACK_OF(X509_EXTENSION) *ext;
7 } X;
8
9/* This isn't meant to run particularly, it's just to test type checking */
10int main(int argc, char **argv)
11 {
12 X *x = NULL;
13 unsigned char **pp = NULL;
14
15 M_ASN1_I2D_vars(x);
16 M_ASN1_I2D_len_SEQUENCE_opt_type(X509_EXTENSION, x->ext,
17 i2d_X509_EXTENSION);
18 M_ASN1_I2D_seq_total();
19 M_ASN1_I2D_put_SEQUENCE_opt_type(X509_EXTENSION, x->ext,
20 i2d_X509_EXTENSION);
21 M_ASN1_I2D_finish();
22 }
diff --git a/src/lib/libssl/test/cms-test.pl b/src/lib/libssl/test/cms-test.pl
index a84e089ddc..9c50dff3e9 100644
--- a/src/lib/libssl/test/cms-test.pl
+++ b/src/lib/libssl/test/cms-test.pl
@@ -54,8 +54,12 @@
54# OpenSSL PKCS#7 and CMS implementations. 54# OpenSSL PKCS#7 and CMS implementations.
55 55
56my $ossl_path; 56my $ossl_path;
57 57my $redir = " 2>cms.err 1>cms.out";
58if ( -f "../apps/openssl" ) { 58# Make MSYS work
59if ( $^O eq "MSWin32" && -f "../apps/openssl.exe" ) {
60 $ossl_path = "cmd /c ..\\apps\\openssl";
61}
62elsif ( -f "../apps/openssl$ENV{EXE_EXT}" ) {
59 $ossl_path = "../util/shlib_wrap.sh ../apps/openssl"; 63 $ossl_path = "../util/shlib_wrap.sh ../apps/openssl";
60} 64}
61elsif ( -f "..\\out32dll\\openssl.exe" ) { 65elsif ( -f "..\\out32dll\\openssl.exe" ) {
@@ -232,7 +236,7 @@ my @smime_cms_tests = (
232 [ 236 [
233 "signed content MIME format, RSA key, signed receipt request", 237 "signed content MIME format, RSA key, signed receipt request",
234 "-sign -in smcont.txt -signer $smdir/smrsa1.pem -nodetach" 238 "-sign -in smcont.txt -signer $smdir/smrsa1.pem -nodetach"
235 . " -receipt_request_to test@openssl.org -receipt_request_all" 239 . " -receipt_request_to test\@openssl.org -receipt_request_all"
236 . " -out test.cms", 240 . " -out test.cms",
237 "-verify -in test.cms " 241 "-verify -in test.cms "
238 . " -CAfile $smdir/smroot.pem -out smtst.txt" 242 . " -CAfile $smdir/smroot.pem -out smtst.txt"
@@ -333,10 +337,6 @@ my @smime_cms_comp_tests = (
333 337
334); 338);
335 339
336print "PKCS#7 <=> PKCS#7 consistency tests\n";
337
338run_smime_tests( \$badcmd, \@smime_pkcs7_tests, $pk7cmd, $pk7cmd );
339
340print "CMS => PKCS#7 compatibility tests\n"; 340print "CMS => PKCS#7 compatibility tests\n";
341 341
342run_smime_tests( \$badcmd, \@smime_pkcs7_tests, $cmscmd, $pk7cmd ); 342run_smime_tests( \$badcmd, \@smime_pkcs7_tests, $cmscmd, $pk7cmd );
@@ -386,14 +386,14 @@ sub run_smime_tests {
386 $rscmd =~ s/-stream//; 386 $rscmd =~ s/-stream//;
387 $rvcmd =~ s/-stream//; 387 $rvcmd =~ s/-stream//;
388 } 388 }
389 system("$scmd$rscmd 2>cms.err 1>cms.out"); 389 system("$scmd$rscmd$redir");
390 if ($?) { 390 if ($?) {
391 print "$tnam: generation error\n"; 391 print "$tnam: generation error\n";
392 $$rv++; 392 $$rv++;
393 exit 1 if $halt_err; 393 exit 1 if $halt_err;
394 next; 394 next;
395 } 395 }
396 system("$vcmd$rvcmd 2>cms.err 1>cms.out"); 396 system("$vcmd$rvcmd$redir");
397 if ($?) { 397 if ($?) {
398 print "$tnam: verify error\n"; 398 print "$tnam: verify error\n";
399 $$rv++; 399 $$rv++;
diff --git a/src/lib/libssl/test/pkits-test.pl b/src/lib/libssl/test/pkits-test.pl
new file mode 100644
index 0000000000..69dffa16f9
--- /dev/null
+++ b/src/lib/libssl/test/pkits-test.pl
@@ -0,0 +1,940 @@
1# test/pkits-test.pl
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# Perl utility to run PKITS tests for RFC3280 compliance.
54
55my $ossl_path;
56
57if ( -f "../apps/openssl" ) {
58 $ossl_path = "../util/shlib_wrap.sh ../apps/openssl";
59}
60elsif ( -f "..\\out32dll\\openssl.exe" ) {
61 $ossl_path = "..\\out32dll\\openssl.exe";
62}
63elsif ( -f "..\\out32\\openssl.exe" ) {
64 $ossl_path = "..\\out32\\openssl.exe";
65}
66else {
67 die "Can't find OpenSSL executable";
68}
69
70my $pkitsdir = "pkits/smime";
71my $pkitsta = "pkits/certs/TrustAnchorRootCertificate.crt";
72
73die "Can't find PKITS test data" if !-d $pkitsdir;
74
75my $nist1 = "2.16.840.1.101.3.2.1.48.1";
76my $nist2 = "2.16.840.1.101.3.2.1.48.2";
77my $nist3 = "2.16.840.1.101.3.2.1.48.3";
78my $nist4 = "2.16.840.1.101.3.2.1.48.4";
79my $nist5 = "2.16.840.1.101.3.2.1.48.5";
80my $nist6 = "2.16.840.1.101.3.2.1.48.6";
81
82my $apolicy = "X509v3 Any Policy";
83
84# This table contains the chapter headings of the accompanying PKITS
85# document. They provide useful informational output and their names
86# can be converted into the filename to test.
87
88my @testlists = (
89 [ "4.1", "Signature Verification" ],
90 [ "4.1.1", "Valid Signatures Test1", 0 ],
91 [ "4.1.2", "Invalid CA Signature Test2", 7 ],
92 [ "4.1.3", "Invalid EE Signature Test3", 7 ],
93 [ "4.1.4", "Valid DSA Signatures Test4", 0 ],
94 [ "4.1.5", "Valid DSA Parameter Inheritance Test5", 0 ],
95 [ "4.1.6", "Invalid DSA Signature Test6", 7 ],
96 [ "4.2", "Validity Periods" ],
97 [ "4.2.1", "Invalid CA notBefore Date Test1", 9 ],
98 [ "4.2.2", "Invalid EE notBefore Date Test2", 9 ],
99 [ "4.2.3", "Valid pre2000 UTC notBefore Date Test3", 0 ],
100 [ "4.2.4", "Valid GeneralizedTime notBefore Date Test4", 0 ],
101 [ "4.2.5", "Invalid CA notAfter Date Test5", 10 ],
102 [ "4.2.6", "Invalid EE notAfter Date Test6", 10 ],
103 [ "4.2.7", "Invalid pre2000 UTC EE notAfter Date Test7", 10 ],
104 [ "4.2.8", "Valid GeneralizedTime notAfter Date Test8", 0 ],
105 [ "4.3", "Verifying Name Chaining" ],
106 [ "4.3.1", "Invalid Name Chaining EE Test1", 20 ],
107 [ "4.3.2", "Invalid Name Chaining Order Test2", 20 ],
108 [ "4.3.3", "Valid Name Chaining Whitespace Test3", 0 ],
109 [ "4.3.4", "Valid Name Chaining Whitespace Test4", 0 ],
110 [ "4.3.5", "Valid Name Chaining Capitalization Test5", 0 ],
111 [ "4.3.6", "Valid Name Chaining UIDs Test6", 0 ],
112 [ "4.3.7", "Valid RFC3280 Mandatory Attribute Types Test7", 0 ],
113 [ "4.3.8", "Valid RFC3280 Optional Attribute Types Test8", 0 ],
114 [ "4.3.9", "Valid UTF8String Encoded Names Test9", 0 ],
115 [ "4.3.10", "Valid Rollover from PrintableString to UTF8String Test10", 0 ],
116 [ "4.3.11", "Valid UTF8String Case Insensitive Match Test11", 0 ],
117 [ "4.4", "Basic Certificate Revocation Tests" ],
118 [ "4.4.1", "Missing CRL Test1", 3 ],
119 [ "4.4.2", "Invalid Revoked CA Test2", 23 ],
120 [ "4.4.3", "Invalid Revoked EE Test3", 23 ],
121 [ "4.4.4", "Invalid Bad CRL Signature Test4", 8 ],
122 [ "4.4.5", "Invalid Bad CRL Issuer Name Test5", 3 ],
123 [ "4.4.6", "Invalid Wrong CRL Test6", 3 ],
124 [ "4.4.7", "Valid Two CRLs Test7", 0 ],
125
126 # The test document suggests these should return certificate revoked...
127 # Subsquent discussion has concluded they should not due to unhandle
128 # critical CRL extensions.
129 [ "4.4.8", "Invalid Unknown CRL Entry Extension Test8", 36 ],
130 [ "4.4.9", "Invalid Unknown CRL Extension Test9", 36 ],
131
132 [ "4.4.10", "Invalid Unknown CRL Extension Test10", 36 ],
133 [ "4.4.11", "Invalid Old CRL nextUpdate Test11", 12 ],
134 [ "4.4.12", "Invalid pre2000 CRL nextUpdate Test12", 12 ],
135 [ "4.4.13", "Valid GeneralizedTime CRL nextUpdate Test13", 0 ],
136 [ "4.4.14", "Valid Negative Serial Number Test14", 0 ],
137 [ "4.4.15", "Invalid Negative Serial Number Test15", 23 ],
138 [ "4.4.16", "Valid Long Serial Number Test16", 0 ],
139 [ "4.4.17", "Valid Long Serial Number Test17", 0 ],
140 [ "4.4.18", "Invalid Long Serial Number Test18", 23 ],
141 [ "4.4.19", "Valid Separate Certificate and CRL Keys Test19", 0 ],
142 [ "4.4.20", "Invalid Separate Certificate and CRL Keys Test20", 23 ],
143
144 # CRL path is revoked so get a CRL path validation error
145 [ "4.4.21", "Invalid Separate Certificate and CRL Keys Test21", 54 ],
146 [ "4.5", "Verifying Paths with Self-Issued Certificates" ],
147 [ "4.5.1", "Valid Basic Self-Issued Old With New Test1", 0 ],
148 [ "4.5.2", "Invalid Basic Self-Issued Old With New Test2", 23 ],
149 [ "4.5.3", "Valid Basic Self-Issued New With Old Test3", 0 ],
150 [ "4.5.4", "Valid Basic Self-Issued New With Old Test4", 0 ],
151 [ "4.5.5", "Invalid Basic Self-Issued New With Old Test5", 23 ],
152 [ "4.5.6", "Valid Basic Self-Issued CRL Signing Key Test6", 0 ],
153 [ "4.5.7", "Invalid Basic Self-Issued CRL Signing Key Test7", 23 ],
154 [ "4.5.8", "Invalid Basic Self-Issued CRL Signing Key Test8", 20 ],
155 [ "4.6", "Verifying Basic Constraints" ],
156 [ "4.6.1", "Invalid Missing basicConstraints Test1", 24 ],
157 [ "4.6.2", "Invalid cA False Test2", 24 ],
158 [ "4.6.3", "Invalid cA False Test3", 24 ],
159 [ "4.6.4", "Valid basicConstraints Not Critical Test4", 0 ],
160 [ "4.6.5", "Invalid pathLenConstraint Test5", 25 ],
161 [ "4.6.6", "Invalid pathLenConstraint Test6", 25 ],
162 [ "4.6.7", "Valid pathLenConstraint Test7", 0 ],
163 [ "4.6.8", "Valid pathLenConstraint Test8", 0 ],
164 [ "4.6.9", "Invalid pathLenConstraint Test9", 25 ],
165 [ "4.6.10", "Invalid pathLenConstraint Test10", 25 ],
166 [ "4.6.11", "Invalid pathLenConstraint Test11", 25 ],
167 [ "4.6.12", "Invalid pathLenConstraint Test12", 25 ],
168 [ "4.6.13", "Valid pathLenConstraint Test13", 0 ],
169 [ "4.6.14", "Valid pathLenConstraint Test14", 0 ],
170 [ "4.6.15", "Valid Self-Issued pathLenConstraint Test15", 0 ],
171 [ "4.6.16", "Invalid Self-Issued pathLenConstraint Test16", 25 ],
172 [ "4.6.17", "Valid Self-Issued pathLenConstraint Test17", 0 ],
173 [ "4.7", "Key Usage" ],
174 [ "4.7.1", "Invalid keyUsage Critical keyCertSign False Test1", 20 ],
175 [ "4.7.2", "Invalid keyUsage Not Critical keyCertSign False Test2", 20 ],
176 [ "4.7.3", "Valid keyUsage Not Critical Test3", 0 ],
177 [ "4.7.4", "Invalid keyUsage Critical cRLSign False Test4", 35 ],
178 [ "4.7.5", "Invalid keyUsage Not Critical cRLSign False Test5", 35 ],
179
180 # Certificate policy tests need special handling. They can have several
181 # sub tests and we need to check the outputs are correct.
182
183 [ "4.8", "Certificate Policies" ],
184 [
185 "4.8.1.1",
186 "All Certificates Same Policy Test1",
187 "-policy anyPolicy -explicit_policy",
188 "True", $nist1, $nist1, 0
189 ],
190 [
191 "4.8.1.2",
192 "All Certificates Same Policy Test1",
193 "-policy $nist1 -explicit_policy",
194 "True", $nist1, $nist1, 0
195 ],
196 [
197 "4.8.1.3",
198 "All Certificates Same Policy Test1",
199 "-policy $nist2 -explicit_policy",
200 "True", $nist1, "<empty>", 43
201 ],
202 [
203 "4.8.1.4",
204 "All Certificates Same Policy Test1",
205 "-policy $nist1 -policy $nist2 -explicit_policy",
206 "True", $nist1, $nist1, 0
207 ],
208 [
209 "4.8.2.1",
210 "All Certificates No Policies Test2",
211 "-policy anyPolicy",
212 "False", "<empty>", "<empty>", 0
213 ],
214 [
215 "4.8.2.2",
216 "All Certificates No Policies Test2",
217 "-policy anyPolicy -explicit_policy",
218 "True", "<empty>", "<empty>", 43
219 ],
220 [
221 "4.8.3.1",
222 "Different Policies Test3",
223 "-policy anyPolicy",
224 "False", "<empty>", "<empty>", 0
225 ],
226 [
227 "4.8.3.2",
228 "Different Policies Test3",
229 "-policy anyPolicy -explicit_policy",
230 "True", "<empty>", "<empty>", 43
231 ],
232 [
233 "4.8.3.3",
234 "Different Policies Test3",
235 "-policy $nist1 -policy $nist2 -explicit_policy",
236 "True", "<empty>", "<empty>", 43
237 ],
238
239 [
240 "4.8.4",
241 "Different Policies Test4",
242 "-policy anyPolicy",
243 "True", "<empty>", "<empty>", 43
244 ],
245 [
246 "4.8.5",
247 "Different Policies Test5",
248 "-policy anyPolicy",
249 "True", "<empty>", "<empty>", 43
250 ],
251 [
252 "4.8.6.1",
253 "Overlapping Policies Test6",
254 "-policy anyPolicy",
255 "True", $nist1, $nist1, 0
256 ],
257 [
258 "4.8.6.2",
259 "Overlapping Policies Test6",
260 "-policy $nist1",
261 "True", $nist1, $nist1, 0
262 ],
263 [
264 "4.8.6.3",
265 "Overlapping Policies Test6",
266 "-policy $nist2",
267 "True", $nist1, "<empty>", 43
268 ],
269 [
270 "4.8.7",
271 "Different Policies Test7",
272 "-policy anyPolicy",
273 "True", "<empty>", "<empty>", 43
274 ],
275 [
276 "4.8.8",
277 "Different Policies Test8",
278 "-policy anyPolicy",
279 "True", "<empty>", "<empty>", 43
280 ],
281 [
282 "4.8.9",
283 "Different Policies Test9",
284 "-policy anyPolicy",
285 "True", "<empty>", "<empty>", 43
286 ],
287 [
288 "4.8.10.1",
289 "All Certificates Same Policies Test10",
290 "-policy $nist1",
291 "True", "$nist1:$nist2", "$nist1", 0
292 ],
293 [
294 "4.8.10.2",
295 "All Certificates Same Policies Test10",
296 "-policy $nist2",
297 "True", "$nist1:$nist2", "$nist2", 0
298 ],
299 [
300 "4.8.10.3",
301 "All Certificates Same Policies Test10",
302 "-policy anyPolicy",
303 "True", "$nist1:$nist2", "$nist1:$nist2", 0
304 ],
305 [
306 "4.8.11.1",
307 "All Certificates AnyPolicy Test11",
308 "-policy anyPolicy",
309 "True", "$apolicy", "$apolicy", 0
310 ],
311 [
312 "4.8.11.2",
313 "All Certificates AnyPolicy Test11",
314 "-policy $nist1",
315 "True", "$apolicy", "$nist1", 0
316 ],
317 [
318 "4.8.12",
319 "Different Policies Test12",
320 "-policy anyPolicy",
321 "True", "<empty>", "<empty>", 43
322 ],
323 [
324 "4.8.13.1",
325 "All Certificates Same Policies Test13",
326 "-policy $nist1",
327 "True", "$nist1:$nist2:$nist3", "$nist1", 0
328 ],
329 [
330 "4.8.13.2",
331 "All Certificates Same Policies Test13",
332 "-policy $nist2",
333 "True", "$nist1:$nist2:$nist3", "$nist2", 0
334 ],
335 [
336 "4.8.13.3",
337 "All Certificates Same Policies Test13",
338 "-policy $nist3",
339 "True", "$nist1:$nist2:$nist3", "$nist3", 0
340 ],
341 [
342 "4.8.14.1", "AnyPolicy Test14",
343 "-policy $nist1", "True",
344 "$nist1", "$nist1",
345 0
346 ],
347 [
348 "4.8.14.2", "AnyPolicy Test14",
349 "-policy $nist2", "True",
350 "$nist1", "<empty>",
351 43
352 ],
353 [
354 "4.8.15",
355 "User Notice Qualifier Test15",
356 "-policy anyPolicy",
357 "False", "$nist1", "$nist1", 0
358 ],
359 [
360 "4.8.16",
361 "User Notice Qualifier Test16",
362 "-policy anyPolicy",
363 "False", "$nist1", "$nist1", 0
364 ],
365 [
366 "4.8.17",
367 "User Notice Qualifier Test17",
368 "-policy anyPolicy",
369 "False", "$nist1", "$nist1", 0
370 ],
371 [
372 "4.8.18.1",
373 "User Notice Qualifier Test18",
374 "-policy $nist1",
375 "True", "$nist1:$nist2", "$nist1", 0
376 ],
377 [
378 "4.8.18.2",
379 "User Notice Qualifier Test18",
380 "-policy $nist2",
381 "True", "$nist1:$nist2", "$nist2", 0
382 ],
383 [
384 "4.8.19",
385 "User Notice Qualifier Test19",
386 "-policy anyPolicy",
387 "False", "$nist1", "$nist1", 0
388 ],
389 [
390 "4.8.20",
391 "CPS Pointer Qualifier Test20",
392 "-policy anyPolicy -explicit_policy",
393 "True", "$nist1", "$nist1", 0
394 ],
395 [ "4.9", "Require Explicit Policy" ],
396 [
397 "4.9.1",
398 "Valid RequireExplicitPolicy Test1",
399 "-policy anyPolicy",
400 "False", "<empty>", "<empty>", 0
401 ],
402 [
403 "4.9.2",
404 "Valid RequireExplicitPolicy Test2",
405 "-policy anyPolicy",
406 "False", "<empty>", "<empty>", 0
407 ],
408 [
409 "4.9.3",
410 "Invalid RequireExplicitPolicy Test3",
411 "-policy anyPolicy",
412 "True", "<empty>", "<empty>", 43
413 ],
414 [
415 "4.9.4",
416 "Valid RequireExplicitPolicy Test4",
417 "-policy anyPolicy",
418 "True", "$nist1", "$nist1", 0
419 ],
420 [
421 "4.9.5",
422 "Invalid RequireExplicitPolicy Test5",
423 "-policy anyPolicy",
424 "True", "<empty>", "<empty>", 43
425 ],
426 [
427 "4.9.6",
428 "Valid Self-Issued requireExplicitPolicy Test6",
429 "-policy anyPolicy",
430 "False", "<empty>", "<empty>", 0
431 ],
432 [
433 "4.9.7",
434 "Invalid Self-Issued requireExplicitPolicy Test7",
435 "-policy anyPolicy",
436 "True", "<empty>", "<empty>", 43
437 ],
438 [
439 "4.9.8",
440 "Invalid Self-Issued requireExplicitPolicy Test8",
441 "-policy anyPolicy",
442 "True", "<empty>", "<empty>", 43
443 ],
444 [ "4.10", "Policy Mappings" ],
445 [
446 "4.10.1.1",
447 "Valid Policy Mapping Test1",
448 "-policy $nist1",
449 "True", "$nist1", "$nist1", 0
450 ],
451 [
452 "4.10.1.2",
453 "Valid Policy Mapping Test1",
454 "-policy $nist2",
455 "True", "$nist1", "<empty>", 43
456 ],
457 [
458 "4.10.1.3",
459 "Valid Policy Mapping Test1",
460 "-policy anyPolicy -inhibit_map",
461 "True", "<empty>", "<empty>", 43
462 ],
463 [
464 "4.10.2.1",
465 "Invalid Policy Mapping Test2",
466 "-policy anyPolicy",
467 "True", "<empty>", "<empty>", 43
468 ],
469 [
470 "4.10.2.2",
471 "Invalid Policy Mapping Test2",
472 "-policy anyPolicy -inhibit_map",
473 "True", "<empty>", "<empty>", 43
474 ],
475 [
476 "4.10.3.1",
477 "Valid Policy Mapping Test3",
478 "-policy $nist1",
479 "True", "$nist2", "<empty>", 43
480 ],
481 [
482 "4.10.3.2",
483 "Valid Policy Mapping Test3",
484 "-policy $nist2",
485 "True", "$nist2", "$nist2", 0
486 ],
487 [
488 "4.10.4",
489 "Invalid Policy Mapping Test4",
490 "-policy anyPolicy",
491 "True", "<empty>", "<empty>", 43
492 ],
493 [
494 "4.10.5.1",
495 "Valid Policy Mapping Test5",
496 "-policy $nist1",
497 "True", "$nist1", "$nist1", 0
498 ],
499 [
500 "4.10.5.2",
501 "Valid Policy Mapping Test5",
502 "-policy $nist6",
503 "True", "$nist1", "<empty>", 43
504 ],
505 [
506 "4.10.6.1",
507 "Valid Policy Mapping Test6",
508 "-policy $nist1",
509 "True", "$nist1", "$nist1", 0
510 ],
511 [
512 "4.10.6.2",
513 "Valid Policy Mapping Test6",
514 "-policy $nist6",
515 "True", "$nist1", "<empty>", 43
516 ],
517 [ "4.10.7", "Invalid Mapping From anyPolicy Test7", 42 ],
518 [ "4.10.8", "Invalid Mapping To anyPolicy Test8", 42 ],
519 [
520 "4.10.9",
521 "Valid Policy Mapping Test9",
522 "-policy anyPolicy",
523 "True", "$nist1", "$nist1", 0
524 ],
525 [
526 "4.10.10",
527 "Invalid Policy Mapping Test10",
528 "-policy anyPolicy",
529 "True", "<empty>", "<empty>", 43
530 ],
531 [
532 "4.10.11",
533 "Valid Policy Mapping Test11",
534 "-policy anyPolicy",
535 "True", "$nist1", "$nist1", 0
536 ],
537
538 # TODO: check notice display
539 [
540 "4.10.12.1",
541 "Valid Policy Mapping Test12",
542 "-policy $nist1",
543 "True", "$nist1:$nist2", "$nist1", 0
544 ],
545
546 # TODO: check notice display
547 [
548 "4.10.12.2",
549 "Valid Policy Mapping Test12",
550 "-policy $nist2",
551 "True", "$nist1:$nist2", "$nist2", 0
552 ],
553 [
554 "4.10.13",
555 "Valid Policy Mapping Test13",
556 "-policy anyPolicy",
557 "True", "$nist1", "$nist1", 0
558 ],
559
560 # TODO: check notice display
561 [
562 "4.10.14",
563 "Valid Policy Mapping Test14",
564 "-policy anyPolicy",
565 "True", "$nist1", "$nist1", 0
566 ],
567 [ "4.11", "Inhibit Policy Mapping" ],
568 [
569 "4.11.1",
570 "Invalid inhibitPolicyMapping Test1",
571 "-policy anyPolicy",
572 "True", "<empty>", "<empty>", 43
573 ],
574 [
575 "4.11.2",
576 "Valid inhibitPolicyMapping Test2",
577 "-policy anyPolicy",
578 "True", "$nist1", "$nist1", 0
579 ],
580 [
581 "4.11.3",
582 "Invalid inhibitPolicyMapping Test3",
583 "-policy anyPolicy",
584 "True", "<empty>", "<empty>", 43
585 ],
586 [
587 "4.11.4",
588 "Valid inhibitPolicyMapping Test4",
589 "-policy anyPolicy",
590 "True", "$nist2", "$nist2", 0
591 ],
592 [
593 "4.11.5",
594 "Invalid inhibitPolicyMapping Test5",
595 "-policy anyPolicy",
596 "True", "<empty>", "<empty>", 43
597 ],
598 [
599 "4.11.6",
600 "Invalid inhibitPolicyMapping Test6",
601 "-policy anyPolicy",
602 "True", "<empty>", "<empty>", 43
603 ],
604 [
605 "4.11.7",
606 "Valid Self-Issued inhibitPolicyMapping Test7",
607 "-policy anyPolicy",
608 "True", "$nist1", "$nist1", 0
609 ],
610 [
611 "4.11.8",
612 "Invalid Self-Issued inhibitPolicyMapping Test8",
613 "-policy anyPolicy",
614 "True", "<empty>", "<empty>", 43
615 ],
616 [
617 "4.11.9",
618 "Invalid Self-Issued inhibitPolicyMapping Test9",
619 "-policy anyPolicy",
620 "True", "<empty>", "<empty>", 43
621 ],
622 [
623 "4.11.10",
624 "Invalid Self-Issued inhibitPolicyMapping Test10",
625 "-policy anyPolicy",
626 "True", "<empty>", "<empty>", 43
627 ],
628 [
629 "4.11.11",
630 "Invalid Self-Issued inhibitPolicyMapping Test11",
631 "-policy anyPolicy",
632 "True", "<empty>", "<empty>", 43
633 ],
634 [ "4.12", "Inhibit Any Policy" ],
635 [
636 "4.12.1",
637 "Invalid inhibitAnyPolicy Test1",
638 "-policy anyPolicy",
639 "True", "<empty>", "<empty>", 43
640 ],
641 [
642 "4.12.2",
643 "Valid inhibitAnyPolicy Test2",
644 "-policy anyPolicy",
645 "True", "$nist1", "$nist1", 0
646 ],
647 [
648 "4.12.3.1",
649 "inhibitAnyPolicy Test3",
650 "-policy anyPolicy",
651 "True", "$nist1", "$nist1", 0
652 ],
653 [
654 "4.12.3.2",
655 "inhibitAnyPolicy Test3",
656 "-policy anyPolicy -inhibit_any",
657 "True", "<empty>", "<empty>", 43
658 ],
659 [
660 "4.12.4",
661 "Invalid inhibitAnyPolicy Test4",
662 "-policy anyPolicy",
663 "True", "<empty>", "<empty>", 43
664 ],
665 [
666 "4.12.5",
667 "Invalid inhibitAnyPolicy Test5",
668 "-policy anyPolicy",
669 "True", "<empty>", "<empty>", 43
670 ],
671 [
672 "4.12.6",
673 "Invalid inhibitAnyPolicy Test6",
674 "-policy anyPolicy",
675 "True", "<empty>", "<empty>", 43
676 ],
677 [ "4.12.7", "Valid Self-Issued inhibitAnyPolicy Test7", 0 ],
678 [ "4.12.8", "Invalid Self-Issued inhibitAnyPolicy Test8", 43 ],
679 [ "4.12.9", "Valid Self-Issued inhibitAnyPolicy Test9", 0 ],
680 [ "4.12.10", "Invalid Self-Issued inhibitAnyPolicy Test10", 43 ],
681 [ "4.13", "Name Constraints" ],
682 [ "4.13.1", "Valid DN nameConstraints Test1", 0 ],
683 [ "4.13.2", "Invalid DN nameConstraints Test2", 47 ],
684 [ "4.13.3", "Invalid DN nameConstraints Test3", 47 ],
685 [ "4.13.4", "Valid DN nameConstraints Test4", 0 ],
686 [ "4.13.5", "Valid DN nameConstraints Test5", 0 ],
687 [ "4.13.6", "Valid DN nameConstraints Test6", 0 ],
688 [ "4.13.7", "Invalid DN nameConstraints Test7", 48 ],
689 [ "4.13.8", "Invalid DN nameConstraints Test8", 48 ],
690 [ "4.13.9", "Invalid DN nameConstraints Test9", 48 ],
691 [ "4.13.10", "Invalid DN nameConstraints Test10", 48 ],
692 [ "4.13.11", "Valid DN nameConstraints Test11", 0 ],
693 [ "4.13.12", "Invalid DN nameConstraints Test12", 47 ],
694 [ "4.13.13", "Invalid DN nameConstraints Test13", 47 ],
695 [ "4.13.14", "Valid DN nameConstraints Test14", 0 ],
696 [ "4.13.15", "Invalid DN nameConstraints Test15", 48 ],
697 [ "4.13.16", "Invalid DN nameConstraints Test16", 48 ],
698 [ "4.13.17", "Invalid DN nameConstraints Test17", 48 ],
699 [ "4.13.18", "Valid DN nameConstraints Test18", 0 ],
700 [ "4.13.19", "Valid Self-Issued DN nameConstraints Test19", 0 ],
701 [ "4.13.20", "Invalid Self-Issued DN nameConstraints Test20", 47 ],
702 [ "4.13.21", "Valid RFC822 nameConstraints Test21", 0 ],
703 [ "4.13.22", "Invalid RFC822 nameConstraints Test22", 47 ],
704 [ "4.13.23", "Valid RFC822 nameConstraints Test23", 0 ],
705 [ "4.13.24", "Invalid RFC822 nameConstraints Test24", 47 ],
706 [ "4.13.25", "Valid RFC822 nameConstraints Test25", 0 ],
707 [ "4.13.26", "Invalid RFC822 nameConstraints Test26", 48 ],
708 [ "4.13.27", "Valid DN and RFC822 nameConstraints Test27", 0 ],
709 [ "4.13.28", "Invalid DN and RFC822 nameConstraints Test28", 47 ],
710 [ "4.13.29", "Invalid DN and RFC822 nameConstraints Test29", 47 ],
711 [ "4.13.30", "Valid DNS nameConstraints Test30", 0 ],
712 [ "4.13.31", "Invalid DNS nameConstraints Test31", 47 ],
713 [ "4.13.32", "Valid DNS nameConstraints Test32", 0 ],
714 [ "4.13.33", "Invalid DNS nameConstraints Test33", 48 ],
715 [ "4.13.34", "Valid URI nameConstraints Test34", 0 ],
716 [ "4.13.35", "Invalid URI nameConstraints Test35", 47 ],
717 [ "4.13.36", "Valid URI nameConstraints Test36", 0 ],
718 [ "4.13.37", "Invalid URI nameConstraints Test37", 48 ],
719 [ "4.13.38", "Invalid DNS nameConstraints Test38", 47 ],
720 [ "4.14", "Distribution Points" ],
721 [ "4.14.1", "Valid distributionPoint Test1", 0 ],
722 [ "4.14.2", "Invalid distributionPoint Test2", 23 ],
723 [ "4.14.3", "Invalid distributionPoint Test3", 44 ],
724 [ "4.14.4", "Valid distributionPoint Test4", 0 ],
725 [ "4.14.5", "Valid distributionPoint Test5", 0 ],
726 [ "4.14.6", "Invalid distributionPoint Test6", 23 ],
727 [ "4.14.7", "Valid distributionPoint Test7", 0 ],
728 [ "4.14.8", "Invalid distributionPoint Test8", 44 ],
729 [ "4.14.9", "Invalid distributionPoint Test9", 44 ],
730 [ "4.14.10", "Valid No issuingDistributionPoint Test10", 0 ],
731 [ "4.14.11", "Invalid onlyContainsUserCerts CRL Test11", 44 ],
732 [ "4.14.12", "Invalid onlyContainsCACerts CRL Test12", 44 ],
733 [ "4.14.13", "Valid onlyContainsCACerts CRL Test13", 0 ],
734 [ "4.14.14", "Invalid onlyContainsAttributeCerts Test14", 44 ],
735 [ "4.14.15", "Invalid onlySomeReasons Test15", 23 ],
736 [ "4.14.16", "Invalid onlySomeReasons Test16", 23 ],
737 [ "4.14.17", "Invalid onlySomeReasons Test17", 3 ],
738 [ "4.14.18", "Valid onlySomeReasons Test18", 0 ],
739 [ "4.14.19", "Valid onlySomeReasons Test19", 0 ],
740 [ "4.14.20", "Invalid onlySomeReasons Test20", 23 ],
741 [ "4.14.21", "Invalid onlySomeReasons Test21", 23 ],
742 [ "4.14.22", "Valid IDP with indirectCRL Test22", 0 ],
743 [ "4.14.23", "Invalid IDP with indirectCRL Test23", 23 ],
744 [ "4.14.24", "Valid IDP with indirectCRL Test24", 0 ],
745 [ "4.14.25", "Valid IDP with indirectCRL Test25", 0 ],
746 [ "4.14.26", "Invalid IDP with indirectCRL Test26", 44 ],
747 [ "4.14.27", "Invalid cRLIssuer Test27", 3 ],
748 [ "4.14.28", "Valid cRLIssuer Test28", 0 ],
749 [ "4.14.29", "Valid cRLIssuer Test29", 0 ],
750
751 # Although this test is valid it has a circular dependency. As a result
752 # an attempt is made to reursively checks a CRL path and rejected due to
753 # a CRL path validation error. PKITS notes suggest this test does not
754 # need to be run due to this issue.
755 [ "4.14.30", "Valid cRLIssuer Test30", 54 ],
756 [ "4.14.31", "Invalid cRLIssuer Test31", 23 ],
757 [ "4.14.32", "Invalid cRLIssuer Test32", 23 ],
758 [ "4.14.33", "Valid cRLIssuer Test33", 0 ],
759 [ "4.14.34", "Invalid cRLIssuer Test34", 23 ],
760 [ "4.14.35", "Invalid cRLIssuer Test35", 44 ],
761 [ "4.15", "Delta-CRLs" ],
762 [ "4.15.1", "Invalid deltaCRLIndicator No Base Test1", 3 ],
763 [ "4.15.2", "Valid delta-CRL Test2", 0 ],
764 [ "4.15.3", "Invalid delta-CRL Test3", 23 ],
765 [ "4.15.4", "Invalid delta-CRL Test4", 23 ],
766 [ "4.15.5", "Valid delta-CRL Test5", 0 ],
767 [ "4.15.6", "Invalid delta-CRL Test6", 23 ],
768 [ "4.15.7", "Valid delta-CRL Test7", 0 ],
769 [ "4.15.8", "Valid delta-CRL Test8", 0 ],
770 [ "4.15.9", "Invalid delta-CRL Test9", 23 ],
771 [ "4.15.10", "Invalid delta-CRL Test10", 12 ],
772 [ "4.16", "Private Certificate Extensions" ],
773 [ "4.16.1", "Valid Unknown Not Critical Certificate Extension Test1", 0 ],
774 [ "4.16.2", "Invalid Unknown Critical Certificate Extension Test2", 34 ],
775);
776
777
778my $verbose = 1;
779
780my $numtest = 0;
781my $numfail = 0;
782
783my $ossl = "ossl/apps/openssl";
784
785my $ossl_cmd = "$ossl_path cms -verify -verify_retcode ";
786$ossl_cmd .= "-CAfile pkitsta.pem -crl_check_all -x509_strict ";
787$ossl_cmd .= "-policy_check -extended_crl -use_deltas -out /dev/null 2>&1 ";
788
789system "$ossl_path x509 -inform DER -in $pkitsta -out pkitsta.pem";
790
791die "Can't create trust anchor file" if $?;
792
793print "Running PKITS tests:\n" if $verbose;
794
795foreach (@testlists) {
796 my $argnum = @$_;
797 if ( $argnum == 2 ) {
798 my ( $tnum, $title ) = @$_;
799 print "$tnum $title\n" if $verbose;
800 }
801 elsif ( $argnum == 3 ) {
802 my ( $tnum, $title, $exp_ret ) = @$_;
803 my $filename = $title;
804 $exp_ret += 32 if $exp_ret;
805 $filename =~ tr/ -//d;
806 $filename = "Signed${filename}.eml";
807 if ( !-f "$pkitsdir/$filename" ) {
808 print "\"$filename\" not found\n";
809 }
810 else {
811 my $ret;
812 my $test_fail = 0;
813 my $errmsg = "";
814 my $cmd = $ossl_cmd;
815 $cmd .= "-in $pkitsdir/$filename -policy anyPolicy";
816 my $cmdout = `$cmd`;
817 $ret = $? >> 8;
818 if ( $? & 0xff ) {
819 $errmsg .= "Abnormal OpenSSL termination\n";
820 $test_fail = 1;
821 }
822 if ( $exp_ret != $ret ) {
823 $errmsg .= "Return code:$ret, ";
824 $errmsg .= "expected $exp_ret\n";
825 $test_fail = 1;
826 }
827 if ($test_fail) {
828 print "$tnum $title : Failed!\n";
829 print "Filename: $pkitsdir/$filename\n";
830 print $errmsg;
831 print "Command output:\n$cmdout\n";
832 $numfail++;
833 }
834 $numtest++;
835 }
836 }
837 elsif ( $argnum == 7 ) {
838 my ( $tnum, $title, $exargs, $exp_epol, $exp_aset, $exp_uset, $exp_ret )
839 = @$_;
840 my $filename = $title;
841 $exp_ret += 32 if $exp_ret;
842 $filename =~ tr/ -//d;
843 $filename = "Signed${filename}.eml";
844 if ( !-f "$pkitsdir/$filename" ) {
845 print "\"$filename\" not found\n";
846 }
847 else {
848 my $ret;
849 my $cmdout = "";
850 my $errmsg = "";
851 my $epol = "";
852 my $aset = "";
853 my $uset = "";
854 my $pol = -1;
855 my $test_fail = 0;
856 my $cmd = $ossl_cmd;
857 $cmd .= "-in $pkitsdir/$filename $exargs -policy_print";
858 @oparr = `$cmd`;
859 $ret = $? >> 8;
860
861 if ( $? & 0xff ) {
862 $errmsg .= "Abnormal OpenSSL termination\n";
863 $test_fail = 1;
864 }
865 foreach (@oparr) {
866 my $test_failed = 0;
867 $cmdout .= $_;
868 if (/^Require explicit Policy: (.*)$/) {
869 $epol = $1;
870 }
871 if (/^Authority Policies/) {
872 if (/empty/) {
873 $aset = "<empty>";
874 }
875 else {
876 $pol = 1;
877 }
878 }
879 $test_fail = 1 if (/leak/i);
880 if (/^User Policies/) {
881 if (/empty/) {
882 $uset = "<empty>";
883 }
884 else {
885 $pol = 2;
886 }
887 }
888 if (/\s+Policy: (.*)$/) {
889 if ( $pol == 1 ) {
890 $aset .= ":" if $aset ne "";
891 $aset .= $1;
892 }
893 elsif ( $pol == 2 ) {
894 $uset .= ":" if $uset ne "";
895 $uset .= $1;
896 }
897 }
898 }
899
900 if ( $epol ne $exp_epol ) {
901 $errmsg .= "Explicit policy:$epol, ";
902 $errmsg .= "expected $exp_epol\n";
903 $test_fail = 1;
904 }
905 if ( $aset ne $exp_aset ) {
906 $errmsg .= "Authority policy set :$aset, ";
907 $errmsg .= "expected $exp_aset\n";
908 $test_fail = 1;
909 }
910 if ( $uset ne $exp_uset ) {
911 $errmsg .= "User policy set :$uset, ";
912 $errmsg .= "expected $exp_uset\n";
913 $test_fail = 1;
914 }
915
916 if ( $exp_ret != $ret ) {
917 print "Return code:$ret, expected $exp_ret\n";
918 $test_fail = 1;
919 }
920
921 if ($test_fail) {
922 print "$tnum $title : Failed!\n";
923 print "Filename: $pkitsdir/$filename\n";
924 print "Command output:\n$cmdout\n";
925 $numfail++;
926 }
927 $numtest++;
928 }
929 }
930}
931
932if ($numfail) {
933 print "$numfail tests failed out of $numtest\n";
934}
935else {
936 print "All Tests Successful.\n";
937}
938
939unlink "pkitsta.pem";
940
diff --git a/src/lib/libssl/test/test_padlock b/src/lib/libssl/test/test_padlock
new file mode 100755
index 0000000000..5c0f21043c
--- /dev/null
+++ b/src/lib/libssl/test/test_padlock
@@ -0,0 +1,64 @@
1#!/bin/sh
2
3PROG=$1
4
5if [ -x $PROG ]; then
6 if expr "x`$PROG version`" : "xOpenSSL" > /dev/null; then
7 :
8 else
9 echo "$PROG is not OpenSSL executable"
10 exit 1
11 fi
12else
13 echo "$PROG is not executable"
14 exit 1;
15fi
16
17if $PROG engine padlock | grep -v no-ACE; then
18
19 HASH=`cat $PROG | $PROG dgst -hex`
20
21 ACE_ALGS=" aes-128-ecb aes-192-ecb aes-256-ecb \
22 aes-128-cbc aes-192-cbc aes-256-cbc \
23 aes-128-cfb aes-192-cfb aes-256-cfb \
24 aes-128-ofb aes-192-ofb aes-256-ofb"
25
26 nerr=0
27
28 for alg in $ACE_ALGS; do
29 echo $alg
30 TEST=`( cat $PROG | \
31 $PROG enc -e -k "$HASH" -$alg -bufsize 999 -engine padlock | \
32 $PROG enc -d -k "$HASH" -$alg | \
33 $PROG dgst -hex ) 2>/dev/null`
34 if [ "$TEST" != "$HASH" ]; then
35 echo "-$alg encrypt test failed"
36 nerr=`expr $nerr + 1`
37 fi
38 TEST=`( cat $PROG | \
39 $PROG enc -e -k "$HASH" -$alg | \
40 $PROG enc -d -k "$HASH" -$alg -bufsize 999 -engine padlock | \
41 $PROG dgst -hex ) 2>/dev/null`
42 if [ "$TEST" != "$HASH" ]; then
43 echo "-$alg decrypt test failed"
44 nerr=`expr $nerr + 1`
45 fi
46 TEST=`( cat $PROG | \
47 $PROG enc -e -k "$HASH" -$alg -engine padlock | \
48 $PROG enc -d -k "$HASH" -$alg -engine padlock | \
49 $PROG dgst -hex ) 2>/dev/null`
50 if [ "$TEST" != "$HASH" ]; then
51 echo "-$alg en/decrypt test failed"
52 nerr=`expr $nerr + 1`
53 fi
54 done
55
56 if [ $nerr -gt 0 ]; then
57 echo "PadLock ACE test failed."
58 exit 1;
59 fi
60else
61 echo "PadLock ACE is not available"
62fi
63
64exit 0
diff --git a/src/lib/libssl/test/testtsa b/src/lib/libssl/test/testtsa
new file mode 100644
index 0000000000..bb653b5f73
--- /dev/null
+++ b/src/lib/libssl/test/testtsa
@@ -0,0 +1,238 @@
1#!/bin/sh
2
3#
4# A few very basic tests for the 'ts' time stamping authority command.
5#
6
7SH="/bin/sh"
8if test "$OSTYPE" = msdosdjgpp; then
9 PATH="../apps\;$PATH"
10else
11 PATH="../apps:$PATH"
12fi
13export SH PATH
14
15OPENSSL_CONF="../CAtsa.cnf"
16export OPENSSL_CONF
17# Because that's what ../apps/CA.sh really looks at
18SSLEAY_CONFIG="-config $OPENSSL_CONF"
19export SSLEAY_CONFIG
20
21OPENSSL="`pwd`/../util/opensslwrap.sh"
22export OPENSSL
23
24error () {
25
26 echo "TSA test failed!" >&2
27 exit 1
28}
29
30setup_dir () {
31
32 rm -rf tsa 2>/dev/null
33 mkdir tsa
34 cd ./tsa
35}
36
37clean_up_dir () {
38
39 cd ..
40 rm -rf tsa
41}
42
43create_ca () {
44
45 echo "Creating a new CA for the TSA tests..."
46 TSDNSECT=ts_ca_dn
47 export TSDNSECT
48 ../../util/shlib_wrap.sh ../../apps/openssl req -new -x509 -nodes \
49 -out tsaca.pem -keyout tsacakey.pem
50 test $? != 0 && error
51}
52
53create_tsa_cert () {
54
55 INDEX=$1
56 export INDEX
57 EXT=$2
58 TSDNSECT=ts_cert_dn
59 export TSDNSECT
60
61 ../../util/shlib_wrap.sh ../../apps/openssl req -new \
62 -out tsa_req${INDEX}.pem -keyout tsa_key${INDEX}.pem
63 test $? != 0 && error
64echo Using extension $EXT
65 ../../util/shlib_wrap.sh ../../apps/openssl x509 -req \
66 -in tsa_req${INDEX}.pem -out tsa_cert${INDEX}.pem \
67 -CA tsaca.pem -CAkey tsacakey.pem -CAcreateserial \
68 -extfile $OPENSSL_CONF -extensions $EXT
69 test $? != 0 && error
70}
71
72print_request () {
73
74 ../../util/shlib_wrap.sh ../../apps/openssl ts -query -in $1 -text
75}
76
77create_time_stamp_request1 () {
78
79 ../../util/shlib_wrap.sh ../../apps/openssl ts -query -data ../testtsa -policy tsa_policy1 -cert -out req1.tsq
80 test $? != 0 && error
81}
82
83create_time_stamp_request2 () {
84
85 ../../util/shlib_wrap.sh ../../apps/openssl ts -query -data ../testtsa -policy tsa_policy2 -no_nonce \
86 -out req2.tsq
87 test $? != 0 && error
88}
89
90create_time_stamp_request3 () {
91
92 ../../util/shlib_wrap.sh ../../apps/openssl ts -query -data ../CAtsa.cnf -no_nonce -out req3.tsq
93 test $? != 0 && error
94}
95
96print_response () {
97
98 ../../util/shlib_wrap.sh ../../apps/openssl ts -reply -in $1 -text
99 test $? != 0 && error
100}
101
102create_time_stamp_response () {
103
104 ../../util/shlib_wrap.sh ../../apps/openssl ts -reply -section $3 -queryfile $1 -out $2
105 test $? != 0 && error
106}
107
108time_stamp_response_token_test () {
109
110 RESPONSE2=$2.copy.tsr
111 TOKEN_DER=$2.token.der
112 ../../util/shlib_wrap.sh ../../apps/openssl ts -reply -in $2 -out $TOKEN_DER -token_out
113 test $? != 0 && error
114 ../../util/shlib_wrap.sh ../../apps/openssl ts -reply -in $TOKEN_DER -token_in -out $RESPONSE2
115 test $? != 0 && error
116 cmp $RESPONSE2 $2
117 test $? != 0 && error
118 ../../util/shlib_wrap.sh ../../apps/openssl ts -reply -in $2 -text -token_out
119 test $? != 0 && error
120 ../../util/shlib_wrap.sh ../../apps/openssl ts -reply -in $TOKEN_DER -token_in -text -token_out
121 test $? != 0 && error
122 ../../util/shlib_wrap.sh ../../apps/openssl ts -reply -queryfile $1 -text -token_out
123 test $? != 0 && error
124}
125
126verify_time_stamp_response () {
127
128 ../../util/shlib_wrap.sh ../../apps/openssl ts -verify -queryfile $1 -in $2 -CAfile tsaca.pem \
129 -untrusted tsa_cert1.pem
130 test $? != 0 && error
131 ../../util/shlib_wrap.sh ../../apps/openssl ts -verify -data $3 -in $2 -CAfile tsaca.pem \
132 -untrusted tsa_cert1.pem
133 test $? != 0 && error
134}
135
136verify_time_stamp_token () {
137
138 # create the token from the response first
139 ../../util/shlib_wrap.sh ../../apps/openssl ts -reply -in $2 -out $2.token -token_out
140 test $? != 0 && error
141 ../../util/shlib_wrap.sh ../../apps/openssl ts -verify -queryfile $1 -in $2.token -token_in \
142 -CAfile tsaca.pem -untrusted tsa_cert1.pem
143 test $? != 0 && error
144 ../../util/shlib_wrap.sh ../../apps/openssl ts -verify -data $3 -in $2.token -token_in \
145 -CAfile tsaca.pem -untrusted tsa_cert1.pem
146 test $? != 0 && error
147}
148
149verify_time_stamp_response_fail () {
150
151 ../../util/shlib_wrap.sh ../../apps/openssl ts -verify -queryfile $1 -in $2 -CAfile tsaca.pem \
152 -untrusted tsa_cert1.pem
153 # Checks if the verification failed, as it should have.
154 test $? = 0 && error
155 echo Ok
156}
157
158# main functions
159
160echo "Setting up TSA test directory..."
161setup_dir
162
163echo "Creating CA for TSA tests..."
164create_ca
165
166echo "Creating tsa_cert1.pem TSA server cert..."
167create_tsa_cert 1 tsa_cert
168
169echo "Creating tsa_cert2.pem non-TSA server cert..."
170create_tsa_cert 2 non_tsa_cert
171
172echo "Creating req1.req time stamp request for file testtsa..."
173create_time_stamp_request1
174
175echo "Printing req1.req..."
176print_request req1.tsq
177
178echo "Generating valid response for req1.req..."
179create_time_stamp_response req1.tsq resp1.tsr tsa_config1
180
181echo "Printing response..."
182print_response resp1.tsr
183
184echo "Verifying valid response..."
185verify_time_stamp_response req1.tsq resp1.tsr ../testtsa
186
187echo "Verifying valid token..."
188verify_time_stamp_token req1.tsq resp1.tsr ../testtsa
189
190# The tests below are commented out, because invalid signer certificates
191# can no longer be specified in the config file.
192
193# echo "Generating _invalid_ response for req1.req..."
194# create_time_stamp_response req1.tsq resp1_bad.tsr tsa_config2
195
196# echo "Printing response..."
197# print_response resp1_bad.tsr
198
199# echo "Verifying invalid response, it should fail..."
200# verify_time_stamp_response_fail req1.tsq resp1_bad.tsr
201
202echo "Creating req2.req time stamp request for file testtsa..."
203create_time_stamp_request2
204
205echo "Printing req2.req..."
206print_request req2.tsq
207
208echo "Generating valid response for req2.req..."
209create_time_stamp_response req2.tsq resp2.tsr tsa_config1
210
211echo "Checking '-token_in' and '-token_out' options with '-reply'..."
212time_stamp_response_token_test req2.tsq resp2.tsr
213
214echo "Printing response..."
215print_response resp2.tsr
216
217echo "Verifying valid response..."
218verify_time_stamp_response req2.tsq resp2.tsr ../testtsa
219
220echo "Verifying response against wrong request, it should fail..."
221verify_time_stamp_response_fail req1.tsq resp2.tsr
222
223echo "Verifying response against wrong request, it should fail..."
224verify_time_stamp_response_fail req2.tsq resp1.tsr
225
226echo "Creating req3.req time stamp request for file CAtsa.cnf..."
227create_time_stamp_request3
228
229echo "Printing req3.req..."
230print_request req3.tsq
231
232echo "Verifying response against wrong request, it should fail..."
233verify_time_stamp_response_fail req3.tsq resp1.tsr
234
235echo "Cleaning up..."
236clean_up_dir
237
238exit 0