Import OpenSSL-0.9.8f.
authorPeter Avalos <pavalos@dragonflybsd.org>
Fri, 12 Oct 2007 19:40:12 +0000 (19:40 +0000)
committerPeter Avalos <pavalos@dragonflybsd.org>
Fri, 12 Oct 2007 19:40:12 +0000 (19:40 +0000)
111 files changed:
crypto/openssl-0.9/CHANGES
crypto/openssl-0.9/FAQ
crypto/openssl-0.9/NEWS
crypto/openssl-0.9/README
crypto/openssl-0.9/apps/CA.pl
crypto/openssl-0.9/apps/dgst.c
crypto/openssl-0.9/apps/dsa.c
crypto/openssl-0.9/apps/gendsa.c
crypto/openssl-0.9/apps/genrsa.c
crypto/openssl-0.9/apps/ocsp.c
crypto/openssl-0.9/apps/pkcs12.c
crypto/openssl-0.9/apps/progs.h
crypto/openssl-0.9/apps/rand.c
crypto/openssl-0.9/apps/rsa.c
crypto/openssl-0.9/apps/s_apps.h
crypto/openssl-0.9/apps/s_cb.c
crypto/openssl-0.9/apps/s_client.c
crypto/openssl-0.9/apps/s_server.c
crypto/openssl-0.9/apps/smime.c
crypto/openssl-0.9/apps/speed.c
crypto/openssl-0.9/crypto/aes/aes_ige.c
crypto/openssl-0.9/crypto/asn1/asn1.h
crypto/openssl-0.9/crypto/asn1/asn_moid.c
crypto/openssl-0.9/crypto/asn1/t_req.c
crypto/openssl-0.9/crypto/asn1/tasn_dec.c
crypto/openssl-0.9/crypto/asn1/tasn_enc.c
crypto/openssl-0.9/crypto/asn1/x_crl.c
crypto/openssl-0.9/crypto/asn1/x_name.c
crypto/openssl-0.9/crypto/bio/b_print.c
crypto/openssl-0.9/crypto/bio/b_sock.c
crypto/openssl-0.9/crypto/bio/bio.h
crypto/openssl-0.9/crypto/bn/bn.h
crypto/openssl-0.9/crypto/bn/bn_blind.c
crypto/openssl-0.9/crypto/bn/bn_div.c
crypto/openssl-0.9/crypto/bn/bn_err.c
crypto/openssl-0.9/crypto/bn/bn_exp.c
crypto/openssl-0.9/crypto/bn/bn_gcd.c
crypto/openssl-0.9/crypto/bn/bn_lib.c
crypto/openssl-0.9/crypto/bn/bn_mont.c
crypto/openssl-0.9/crypto/bn/bn_mul.c
crypto/openssl-0.9/crypto/bn/bn_prime.c
crypto/openssl-0.9/crypto/bn/bn_prime.h
crypto/openssl-0.9/crypto/conf/conf.h
crypto/openssl-0.9/crypto/conf/conf_api.c
crypto/openssl-0.9/crypto/conf/conf_mod.c
crypto/openssl-0.9/crypto/conf/conf_sap.c
crypto/openssl-0.9/crypto/cryptlib.c
crypto/openssl-0.9/crypto/des/set_key.c
crypto/openssl-0.9/crypto/dh/dh_check.c
crypto/openssl-0.9/crypto/dh/dh_key.c
crypto/openssl-0.9/crypto/dsa/dsa_gen.c
crypto/openssl-0.9/crypto/dsa/dsa_key.c
crypto/openssl-0.9/crypto/dsa/dsa_ossl.c
crypto/openssl-0.9/crypto/ec/ec.h
crypto/openssl-0.9/crypto/ec/ec_err.c
crypto/openssl-0.9/crypto/ec/ec_mult.c
crypto/openssl-0.9/crypto/engine/eng_padlock.c
crypto/openssl-0.9/crypto/engine/eng_table.c
crypto/openssl-0.9/crypto/evp/c_allc.c
crypto/openssl-0.9/crypto/evp/evp.h
crypto/openssl-0.9/crypto/evp/evp_lib.c
crypto/openssl-0.9/crypto/evp/evp_locl.h
crypto/openssl-0.9/crypto/ex_data.c
crypto/openssl-0.9/crypto/mem_clr.c
crypto/openssl-0.9/crypto/objects/obj_dat.h
crypto/openssl-0.9/crypto/objects/obj_mac.h
crypto/openssl-0.9/crypto/ocsp/ocsp.h
crypto/openssl-0.9/crypto/opensslv.h
crypto/openssl-0.9/crypto/pem/pem.h
crypto/openssl-0.9/crypto/pkcs7/pk7_mime.c
crypto/openssl-0.9/crypto/pkcs7/pk7_smime.c
crypto/openssl-0.9/crypto/pqueue/pq_compat.h
crypto/openssl-0.9/crypto/rand/randfile.c
crypto/openssl-0.9/crypto/rsa/rsa.h
crypto/openssl-0.9/crypto/rsa/rsa_eay.c
crypto/openssl-0.9/crypto/rsa/rsa_gen.c
crypto/openssl-0.9/crypto/rsa/rsa_lib.c
crypto/openssl-0.9/crypto/stack/safestack.h
crypto/openssl-0.9/crypto/store/str_lib.c
crypto/openssl-0.9/crypto/x509/x509_txt.c
crypto/openssl-0.9/crypto/x509/x509_vfy.c
crypto/openssl-0.9/crypto/x509/x509_vpm.c
crypto/openssl-0.9/crypto/x509v3/pcy_tree.c
crypto/openssl-0.9/crypto/x509v3/v3_pci.c
crypto/openssl-0.9/engines/e_ubsec.c
crypto/openssl-0.9/ssl/d1_both.c
crypto/openssl-0.9/ssl/d1_clnt.c
crypto/openssl-0.9/ssl/d1_lib.c
crypto/openssl-0.9/ssl/d1_pkt.c
crypto/openssl-0.9/ssl/d1_srvr.c
crypto/openssl-0.9/ssl/dtls1.h
crypto/openssl-0.9/ssl/s23_clnt.c
crypto/openssl-0.9/ssl/s2_clnt.c
crypto/openssl-0.9/ssl/s2_srvr.c
crypto/openssl-0.9/ssl/s3_clnt.c
crypto/openssl-0.9/ssl/s3_lib.c
crypto/openssl-0.9/ssl/s3_srvr.c
crypto/openssl-0.9/ssl/ssl.h
crypto/openssl-0.9/ssl/ssl3.h
crypto/openssl-0.9/ssl/ssl_algs.c
crypto/openssl-0.9/ssl/ssl_asn1.c
crypto/openssl-0.9/ssl/ssl_cert.c
crypto/openssl-0.9/ssl/ssl_ciph.c
crypto/openssl-0.9/ssl/ssl_err.c
crypto/openssl-0.9/ssl/ssl_lib.c
crypto/openssl-0.9/ssl/ssl_locl.h
crypto/openssl-0.9/ssl/ssl_sess.c
crypto/openssl-0.9/ssl/ssl_txt.c
crypto/openssl-0.9/ssl/t1_enc.c
crypto/openssl-0.9/ssl/t1_lib.c
crypto/openssl-0.9/ssl/tls1.h

index c5a639f..05bd75d 100644 (file)
  OpenSSL CHANGES
  _______________
 
- Changes between 0.9.8d and 0.9.8e  [23 Feb 2007]
+ Changes between 0.9.8e and 0.9.8f  [11 Oct 2007]
+
+  *) DTLS Handshake overhaul. There were longstanding issues with
+     OpenSSL DTLS implementation, which were making it impossible for
+     RFC 4347 compliant client to communicate with OpenSSL server.
+     Unfortunately just fixing these incompatibilities would "cut off"
+     pre-0.9.8f clients. To allow for hassle free upgrade post-0.9.8e
+     server keeps tolerating non RFC compliant syntax. The opposite is
+     not true, 0.9.8f client can not communicate with earlier server.
+     This update even addresses CVE-2007-4995.
+     [Andy Polyakov]
+
+  *) Changes to avoid need for function casts in OpenSSL: some compilers
+     (gcc 4.2 and later) reject their use.
+     [Kurt Roeckx <kurt@roeckx.be>, Peter Hartley <pdh@utter.chaos.org.uk>,
+      Steve Henson]
+  
+  *) Add RFC4507 support to OpenSSL. This includes the corrections in
+     RFC4507bis. The encrypted ticket format is an encrypted encoded
+     SSL_SESSION structure, that way new session features are automatically
+     supported.
+
+     If a client application caches session in an SSL_SESSION structure
+     support is transparent because tickets are now stored in the encoded
+     SSL_SESSION.
+     
+     The SSL_CTX structure automatically generates keys for ticket
+     protection in servers so again support should be possible
+     with no application modification.
+
+     If a client or server wishes to disable RFC4507 support then the option
+     SSL_OP_NO_TICKET can be set.
+
+     Add a TLS extension debugging callback to allow the contents of any client
+     or server extensions to be examined.
+
+     This work was sponsored by Google.
+     [Steve Henson]
+
+  *) Add initial support for TLS extensions, specifically for the server_name
+     extension so far.  The SSL_SESSION, SSL_CTX, and SSL data structures now
+     have new members for a host name.  The SSL data structure has an
+     additional member SSL_CTX *initial_ctx so that new sessions can be
+     stored in that context to allow for session resumption, even after the
+     SSL has been switched to a new SSL_CTX in reaction to a client's
+     server_name extension.
+
+     New functions (subject to change):
+
+         SSL_get_servername()
+         SSL_get_servername_type()
+         SSL_set_SSL_CTX()
+
+     New CTRL codes and macros (subject to change):
+
+         SSL_CTRL_SET_TLSEXT_SERVERNAME_CB
+                                 - SSL_CTX_set_tlsext_servername_callback()
+         SSL_CTRL_SET_TLSEXT_SERVERNAME_ARG
+                                      - SSL_CTX_set_tlsext_servername_arg()
+         SSL_CTRL_SET_TLSEXT_HOSTNAME           - SSL_set_tlsext_host_name()
+
+     openssl s_client has a new '-servername ...' option.
+
+     openssl s_server has new options '-servername_host ...', '-cert2 ...',
+     '-key2 ...', '-servername_fatal' (subject to change).  This allows
+     testing the HostName extension for a specific single host name ('-cert'
+     and '-key' remain fallbacks for handshakes without HostName
+     negotiation).  If the unrecogninzed_name alert has to be sent, this by
+     default is a warning; it becomes fatal with the '-servername_fatal'
+     option.
+
+     [Peter Sylvester,  Remy Allais, Christophe Renou, Steve Henson]
+
+  *) Add AES and SSE2 assembly language support to VC++ build.
+     [Steve Henson]
+
+  *) Mitigate attack on final subtraction in Montgomery reduction.
+     [Andy Polyakov]
+
+  *) Fix crypto/ec/ec_mult.c to work properly with scalars of value 0
+     (which previously caused an internal error).
+     [Bodo Moeller]
+
+  *) Squeeze another 10% out of IGE mode when in != out.
+     [Ben Laurie]
+
+  *) AES IGE mode speedup.
+     [Dean Gaudet (Google)]
+
+  *) Add the Korean symmetric 128-bit cipher SEED (see
+     http://www.kisa.or.kr/kisa/seed/jsp/seed_eng.jsp) and
+     add SEED ciphersuites from RFC 4162:
+
+        TLS_RSA_WITH_SEED_CBC_SHA      =  "SEED-SHA"
+        TLS_DHE_DSS_WITH_SEED_CBC_SHA  =  "DHE-DSS-SEED-SHA"
+        TLS_DHE_RSA_WITH_SEED_CBC_SHA  =  "DHE-RSA-SEED-SHA"
+        TLS_DH_anon_WITH_SEED_CBC_SHA  =  "ADH-SEED-SHA"
+
+     To minimize changes between patchlevels in the OpenSSL 0.9.8
+     series, SEED remains excluded from compilation unless OpenSSL
+     is configured with 'enable-seed'.
+     [KISA, Bodo Moeller]
+
+  *) Mitigate branch prediction attacks, which can be practical if a
+     single processor is shared, allowing a spy process to extract
+     information.  For detailed background information, see
+     http://eprint.iacr.org/2007/039 (O. Aciicmez, S. Gueron,
+     J.-P. Seifert, "New Branch Prediction Vulnerabilities in OpenSSL
+     and Necessary Software Countermeasures").  The core of the change
+     are new versions BN_div_no_branch() and
+     BN_mod_inverse_no_branch() of BN_div() and BN_mod_inverse(),
+     respectively, which are slower, but avoid the security-relevant
+     conditional branches.  These are automatically called by BN_div()
+     and BN_mod_inverse() if the flag BN_FLG_CONSTTIME is set for one
+     of the input BIGNUMs.  Also, BN_is_bit_set() has been changed to
+     remove a conditional branch.
+
+     BN_FLG_CONSTTIME is the new name for the previous
+     BN_FLG_EXP_CONSTTIME flag, since it now affects more than just
+     modular exponentiation.  (Since OpenSSL 0.9.7h, setting this flag
+     in the exponent causes BN_mod_exp_mont() to use the alternative
+     implementation in BN_mod_exp_mont_consttime().)  The old name
+     remains as a deprecated alias.
+
+     Similary, RSA_FLAG_NO_EXP_CONSTTIME is replaced by a more general
+     RSA_FLAG_NO_CONSTTIME flag since the RSA implementation now uses
+     constant-time implementations for more than just exponentiation.
+     Here too the old name is kept as a deprecated alias.
+
+     BN_BLINDING_new() will now use BN_dup() for the modulus so that
+     the BN_BLINDING structure gets an independent copy of the
+     modulus.  This means that the previous "BIGNUM *m" argument to
+     BN_BLINDING_new() and to BN_BLINDING_create_param() now
+     essentially becomes "const BIGNUM *m", although we can't actually
+     change this in the header file before 0.9.9.  It allows
+     RSA_setup_blinding() to use BN_with_flags() on the modulus to
+     enable BN_FLG_CONSTTIME.
+
+     [Matthew D Wood (Intel Corp)]
+
+  *) In the SSL/TLS server implementation, be strict about session ID
+     context matching (which matters if an application uses a single
+     external cache for different purposes).  Previously,
+     out-of-context reuse was forbidden only if SSL_VERIFY_PEER was
+     set.  This did ensure strict client verification, but meant that,
+     with applications using a single external cache for quite
+     different requirements, clients could circumvent ciphersuite
+     restrictions for a given session ID context by starting a session
+     in a different context.
+     [Bodo Moeller]
 
   *) Include "!eNULL" in SSL_DEFAULT_CIPHER_LIST to make sure that
      a ciphersuite string such as "DEFAULT:RSA" cannot enable
      authentication-only ciphersuites.
      [Bodo Moeller]
 
+ Changes between 0.9.8d and 0.9.8e  [23 Feb 2007]
+
   *) Since AES128 and AES256 (and similarly Camellia128 and
      Camellia256) share a single mask bit in the logic of
      ssl/ssl_ciph.c, the code for masking out disabled ciphers needs a
      differing sizes.
      [Richard Levitte]
 
- Changes between 0.9.7l and 0.9.7m  [xx XXX xxxx]
+ Changes between 0.9.7m and 0.9.7n  [xx XXX xxxx]
+
+  *) In the SSL/TLS server implementation, be strict about session ID
+     context matching (which matters if an application uses a single
+     external cache for different purposes).  Previously,
+     out-of-context reuse was forbidden only if SSL_VERIFY_PEER was
+     set.  This did ensure strict client verification, but meant that,
+     with applications using a single external cache for quite
+     different requirements, clients could circumvent ciphersuite
+     restrictions for a given session ID context by starting a session
+     in a different context.
+     [Bodo Moeller]
+
+ Changes between 0.9.7l and 0.9.7m  [23 Feb 2007]
 
   *) Cleanse PEM buffers before freeing them since they may contain 
      sensitive data.
      kludge to work properly if AES128 is available and AES256 isn't.
      [Victor Duchovni]
 
+  *) Expand security boundary to match 1.1.1 module.
+     [Steve Henson]
+
+  *) Remove redundant features: hash file source, editing of test vectors
+     modify fipsld to use external fips_premain.c signature.
+     [Steve Henson]
+
+  *) New perl script mkfipsscr.pl to create shell scripts or batch files to
+     run algorithm test programs.
+     [Steve Henson]
+
+  *) Make algorithm test programs more tolerant of whitespace.
+     [Steve Henson]
+
   *) Have SSL/TLS server implementation tolerate "mismatched" record
      protocol version while receiving ClientHello even if the
      ClientHello is fragmented.  (The server can't insist on the
index 74bf952..7cd71ca 100644 (file)
@@ -66,6 +66,7 @@ OpenSSL  -  Frequently Asked Questions
 * Why doesn't my server application receive a client certificate?
 * Why does compilation fail due to an undefined symbol NID_uniqueIdentifier?
 * I think I've detected a memory leak, is this a bug?
+* Why does Valgrind complain about the use of uninitialized data?
 
 ===============================================================================
 
@@ -74,7 +75,7 @@ OpenSSL  -  Frequently Asked Questions
 * Which is the current version of OpenSSL?
 
 The current version is available from <URL: http://www.openssl.org>.
-OpenSSL 0.9.8e was released on February 23rd, 2007.
+OpenSSL 0.9.8f was released on October 11th, 2007.
 
 In addition to the current stable release, you can also access daily
 snapshots of the OpenSSL development version at <URL:
@@ -894,5 +895,15 @@ thread-safe):
   ERR_free_strings(), EVP_cleanup() and CRYPTO_cleanup_all_ex_data().
 
 
+* Why does Valgrind complain about the use of uninitialized data?
+
+When OpenSSL's PRNG routines are called to generate random numbers the supplied
+buffer contents are mixed into the entropy pool: so it technically does not
+matter whether the buffer is initialized at this point or not.  Valgrind (and
+other test tools) will complain about this. When using Valgrind, make sure the
+OpenSSL library has been compiled with the PURIFY macro defined (-DPURIFY)
+to get rid of these warnings.
+
+
 ===============================================================================
 
index c808a76..ef90239 100644 (file)
@@ -5,6 +5,17 @@
   This file gives a brief overview of the major changes between each OpenSSL
   release. For more details please read the CHANGES file.
 
+  Major changes between OpenSSL 0.9.8e and OpenSSL 0.9.8f:
+
+      o Add gcc 4.2 support.
+      o Add support for AES and SSE2 assembly lanugauge optimization
+        for VC++ build.
+      o Support for RFC4507bis and server name extensions if explicitly 
+        selected at compile time.
+      o DTLS improvements.
+      o RFC4507bis support.
+      o TLS Extensions support.
+
   Major changes between OpenSSL 0.9.8d and OpenSSL 0.9.8e:
 
       o Various ciphersuite selection fixes.
index 907e235..6759d76 100644 (file)
@@ -1,5 +1,5 @@
 
- OpenSSL 0.9.8e 23 Feb 2007
+ OpenSSL 0.9.8f
 
  Copyright (c) 1998-2007 The OpenSSL Project
  Copyright (c) 1995-1998 Eric A. Young, Tim J. Hudson
      actually logically part of it. It includes routines for the following:
 
      Ciphers
-        libdes - EAY's libdes DES encryption package which has been floating
-                 around the net for a few years.  It includes 15
-                 'modes/variations' of DES (1, 2 and 3 key versions of ecb,
-                 cbc, cfb and ofb; pcbc and a more general form of cfb and
-                 ofb) including desx in cbc mode, a fast crypt(3), and
-                 routines to read passwords from the keyboard.
+        libdes - EAY's libdes DES encryption package which was floating
+                 around the net for a few years, and was then relicensed by
+                 him as part of SSLeay.  It includes 15 'modes/variations'
+                 of DES (1, 2 and 3 key versions of ecb, cbc, cfb and ofb;
+                 pcbc and a more general form of cfb and ofb) including desx
+                 in cbc mode, a fast crypt(3), and routines to read
+                 passwords from the keyboard.
         RC4 encryption,
         RC2 encryption      - 4 different modes, ecb, cbc, cfb and ofb.
         Blowfish encryption - 4 different modes, ecb, cbc, cfb and ofb.
index a3965ec..05f11dd 100644 (file)
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+#!/usr/bin/perl5
 #
 # CA - wrapper around ca to make it easier to use ... basically ca requires
 #      some setup stuff to be done before you can use it and this makes
index 09d0934..75ddec3 100644 (file)
@@ -231,29 +231,33 @@ int MAIN(int argc, char **argv)
                BIO_printf(bio_err,"-engine e       use engine e, possibly a hardware device.\n");
 #endif
 
-               BIO_printf(bio_err,"-%3s to use the %s message digest algorithm (default)\n",
+               BIO_printf(bio_err,"-%-14s to use the %s message digest algorithm (default)\n",
                        LN_md5,LN_md5);
-               BIO_printf(bio_err,"-%3s to use the %s message digest algorithm\n",
+               BIO_printf(bio_err,"-%-14s to use the %s message digest algorithm\n",
                        LN_md4,LN_md4);
-               BIO_printf(bio_err,"-%3s to use the %s message digest algorithm\n",
+               BIO_printf(bio_err,"-%-14s to use the %s message digest algorithm\n",
                        LN_md2,LN_md2);
 #ifndef OPENSSL_NO_SHA
-               BIO_printf(bio_err,"-%3s to use the %s message digest algorithm\n",
+               BIO_printf(bio_err,"-%-14s to use the %s message digest algorithm\n",
                        LN_sha1,LN_sha1);
-               BIO_printf(bio_err,"-%3s to use the %s message digest algorithm\n",
+               BIO_printf(bio_err,"-%-14s to use the %s message digest algorithm\n",
                        LN_sha,LN_sha);
 #ifndef OPENSSL_NO_SHA256
-               BIO_printf(bio_err,"-%3s to use the %s message digest algorithm\n",
+               BIO_printf(bio_err,"-%-14s to use the %s message digest algorithm\n",
+                       LN_sha224,LN_sha224);
+               BIO_printf(bio_err,"-%-14s to use the %s message digest algorithm\n",
                        LN_sha256,LN_sha256);
 #endif
 #ifndef OPENSSL_NO_SHA512
-               BIO_printf(bio_err,"-%3s to use the %s message digest algorithm\n",
+               BIO_printf(bio_err,"-%-14s to use the %s message digest algorithm\n",
+                       LN_sha384,LN_sha384);
+               BIO_printf(bio_err,"-%-14s to use the %s message digest algorithm\n",
                        LN_sha512,LN_sha512);
 #endif
 #endif
-               BIO_printf(bio_err,"-%3s to use the %s message digest algorithm\n",
+               BIO_printf(bio_err,"-%-14s to use the %s message digest algorithm\n",
                        LN_mdc2,LN_mdc2);
-               BIO_printf(bio_err,"-%3s to use the %s message digest algorithm\n",
+               BIO_printf(bio_err,"-%-14s to use the %s message digest algorithm\n",
                        LN_ripemd160,LN_ripemd160);
                err=1;
                goto end;
index d503031..9e10303 100644 (file)
@@ -87,6 +87,7 @@
  * -camellia128 - encrypt output if PEM format
  * -camellia192 - encrypt output if PEM format
  * -camellia256 - encrypt output if PEM format
+ * -seed        - encrypt output if PEM format
  * -text       - print a text version
  * -modulus    - print the DSA public key
  */
@@ -218,6 +219,9 @@ bad:
 #ifndef OPENSSL_NO_CAMELLIA
                BIO_printf(bio_err," -camellia128, -camellia192, -camellia256\n");
                BIO_printf(bio_err,"                 encrypt PEM output with cbc camellia\n");
+#endif
+#ifndef OPENSSL_NO_SEED
+               BIO_printf(bio_err," -seed           encrypt PEM output with cbc seed\n");
 #endif
                BIO_printf(bio_err," -text           print the key in text\n");
                BIO_printf(bio_err," -noout          don't print key out\n");
index 936a42b..8a296c6 100644 (file)
@@ -140,6 +140,10 @@ int MAIN(int argc, char **argv)
                else if (strcmp(*argv,"-idea") == 0)
                        enc=EVP_idea_cbc();
 #endif
+#ifndef OPENSSL_NO_SEED
+               else if (strcmp(*argv,"-seed") == 0)
+                       enc=EVP_seed_cbc();
+#endif
 #ifndef OPENSSL_NO_AES
                else if (strcmp(*argv,"-aes128") == 0)
                        enc=EVP_aes_128_cbc();
@@ -178,6 +182,10 @@ bad:
 #ifndef OPENSSL_NO_IDEA
                BIO_printf(bio_err," -idea     - encrypt the generated key with IDEA in cbc mode\n");
 #endif
+#ifndef OPENSSL_NO_SEED
+               BIO_printf(bio_err," -seed\n");
+               BIO_printf(bio_err,"                 encrypt PEM output with cbc seed\n");
+#endif
 #ifndef OPENSSL_NO_AES
                BIO_printf(bio_err," -aes128, -aes192, -aes256\n");
                BIO_printf(bio_err,"                 encrypt PEM output with cbc aes\n");
index d716a3c..1599bb7 100644 (file)
@@ -160,6 +160,10 @@ int MAIN(int argc, char **argv)
                else if (strcmp(*argv,"-idea") == 0)
                        enc=EVP_idea_cbc();
 #endif
+#ifndef OPENSSL_NO_SEED
+               else if (strcmp(*argv,"-seed") == 0)
+                       enc=EVP_seed_cbc();
+#endif
 #ifndef OPENSSL_NO_AES
                else if (strcmp(*argv,"-aes128") == 0)
                        enc=EVP_aes_128_cbc();
@@ -195,6 +199,10 @@ bad:
 #ifndef OPENSSL_NO_IDEA
                BIO_printf(bio_err," -idea           encrypt the generated key with IDEA in cbc mode\n");
 #endif
+#ifndef OPENSSL_NO_SEED
+               BIO_printf(bio_err," -seed\n");
+               BIO_printf(bio_err,"                 encrypt PEM output with cbc seed\n");
+#endif
 #ifndef OPENSSL_NO_AES
                BIO_printf(bio_err," -aes128, -aes192, -aes256\n");
                BIO_printf(bio_err,"                 encrypt PEM output with cbc aes\n");
index 3ee6dfb..3dc36c4 100644 (file)
@@ -1227,7 +1227,7 @@ static int send_ocsp_response(BIO *cbio, OCSP_RESPONSE *resp)
                return 0;
        BIO_printf(cbio, http_resp, i2d_OCSP_RESPONSE(resp, NULL));
        i2d_OCSP_RESPONSE_bio(cbio, resp);
-       BIO_flush(cbio);
+       (void)BIO_flush(cbio);
        return 1;
        }
 
index d5873e9..7c71b1a 100644 (file)
@@ -153,10 +153,13 @@ int MAIN(int argc, char **argv)
                        cert_pbe = NID_pbe_WithSHA1And3_Key_TripleDES_CBC;
                else if (!strcmp (*args, "-export")) export_cert = 1;
                else if (!strcmp (*args, "-des")) enc=EVP_des_cbc();
+               else if (!strcmp (*args, "-des3")) enc = EVP_des_ede3_cbc();
 #ifndef OPENSSL_NO_IDEA
                else if (!strcmp (*args, "-idea")) enc=EVP_idea_cbc();
 #endif
-               else if (!strcmp (*args, "-des3")) enc = EVP_des_ede3_cbc();
+#ifndef OPENSSL_NO_SEED
+               else if (!strcmp(*args, "-seed")) enc=EVP_seed_cbc();
+#endif
 #ifndef OPENSSL_NO_AES
                else if (!strcmp(*args,"-aes128")) enc=EVP_aes_128_cbc();
                else if (!strcmp(*args,"-aes192")) enc=EVP_aes_192_cbc();
@@ -306,6 +309,9 @@ int MAIN(int argc, char **argv)
 #ifndef OPENSSL_NO_IDEA
        BIO_printf (bio_err, "-idea         encrypt private keys with idea\n");
 #endif
+#ifndef OPENSSL_NO_SEED
+       BIO_printf (bio_err, "-seed         encrypt private keys with seed\n");
+#endif
 #ifndef OPENSSL_NO_AES
        BIO_printf (bio_err, "-aes128, -aes192, -aes256\n");
        BIO_printf (bio_err, "              encrypt PEM output with cbc aes\n");
@@ -471,7 +477,7 @@ int MAIN(int argc, char **argv)
                                        X509_keyid_set1(ucert, NULL, 0);
                                        X509_alias_set1(ucert, NULL, 0);
                                        /* Remove from list */
-                                       sk_X509_delete(certs, i);
+                                       (void)sk_X509_delete(certs, i);
                                        break;
                                        }
                                }
index 011974b..89e1e05 100644 (file)
@@ -197,6 +197,9 @@ FUNCTION functions[] = {
 #ifndef OPENSSL_NO_IDEA
        {FUNC_TYPE_CIPHER,"idea",enc_main},
 #endif
+#ifndef OPENSSL_NO_SEED
+       {FUNC_TYPE_CIPHER,"seed",enc_main},
+#endif
 #ifndef OPENSSL_NO_RC4
        {FUNC_TYPE_CIPHER,"rc4",enc_main},
 #endif
@@ -263,6 +266,18 @@ FUNCTION functions[] = {
 #ifndef OPENSSL_NO_IDEA
        {FUNC_TYPE_CIPHER,"idea-ofb",enc_main},
 #endif
+#ifndef OPENSSL_NO_SEED
+       {FUNC_TYPE_CIPHER,"seed-cbc",enc_main},
+#endif
+#ifndef OPENSSL_NO_SEED
+       {FUNC_TYPE_CIPHER,"seed-ecb",enc_main},
+#endif
+#ifndef OPENSSL_NO_SEED
+       {FUNC_TYPE_CIPHER,"seed-cfb",enc_main},
+#endif
+#ifndef OPENSSL_NO_SEED
+       {FUNC_TYPE_CIPHER,"seed-ofb",enc_main},
+#endif
 #ifndef OPENSSL_NO_RC2
        {FUNC_TYPE_CIPHER,"rc2-cbc",enc_main},
 #endif
index a893896..c3b26c4 100644 (file)
@@ -213,7 +213,7 @@ int MAIN(int argc, char **argv)
                BIO_write(out, buf, chunk);
                num -= chunk;
                }
-       BIO_flush(out);
+       (void)BIO_flush(out);
 
        app_RAND_write_file(NULL, bio_err);
        ret = 0;
index cf09a19..930f1f0 100644 (file)
@@ -81,6 +81,7 @@
  * -des                - encrypt output if PEM format with DES in cbc mode
  * -des3       - encrypt output if PEM format
  * -idea       - encrypt output if PEM format
+ * -seed       - encrypt output if PEM format
  * -aes128     - encrypt output if PEM format
  * -aes192     - encrypt output if PEM format
  * -aes256     - encrypt output if PEM format
@@ -211,6 +212,9 @@ bad:
 #ifndef OPENSSL_NO_IDEA
                BIO_printf(bio_err," -idea           encrypt PEM output with cbc idea\n");
 #endif
+#ifndef OPENSSL_NO_SEED
+               BIO_printf(bio_err," -seed           encrypt PEM output with cbc seed\n");
+#endif
 #ifndef OPENSSL_NO_AES
                BIO_printf(bio_err," -aes128, -aes192, -aes256\n");
                BIO_printf(bio_err,"                 encrypt PEM output with cbc aes\n");
index 886a95a..08fbbc2 100644 (file)
@@ -167,4 +167,7 @@ long MS_CALLBACK bio_dump_callback(BIO *bio, int cmd, const char *argp,
 #ifdef HEADER_SSL_H
 void MS_CALLBACK apps_ssl_info_callback(const SSL *s, int where, int ret);
 void MS_CALLBACK msg_cb(int write_p, int version, int content_type, const void *buf, size_t len, SSL *ssl, void *arg);
+void MS_CALLBACK tlsext_cb(SSL *s, int client_server, int type,
+                                       unsigned char *data, int len,
+                                       void *arg);
 #endif
index 9a35d46..a512589 100644 (file)
@@ -573,5 +573,64 @@ void MS_CALLBACK msg_cb(int write_p, int version, int content_type, const void *
                        BIO_printf(bio, " ...");
                BIO_printf(bio, "\n");
                }
-       BIO_flush(bio);
+       (void)BIO_flush(bio);
+       }
+
+void MS_CALLBACK tlsext_cb(SSL *s, int client_server, int type,
+                                       unsigned char *data, int len,
+                                       void *arg)
+       {
+       BIO *bio = arg;
+       char *extname;
+
+       switch(type)
+               {
+               case TLSEXT_TYPE_server_name:
+               extname = "server name";
+               break;
+
+               case TLSEXT_TYPE_max_fragment_length:
+               extname = "max fragment length";
+               break;
+
+               case TLSEXT_TYPE_client_certificate_url:
+               extname = "client certificate URL";
+               break;
+
+               case TLSEXT_TYPE_trusted_ca_keys:
+               extname = "trusted CA keys";
+               break;
+
+               case TLSEXT_TYPE_truncated_hmac:
+               extname = "truncated HMAC";
+               break;
+
+               case TLSEXT_TYPE_status_request:
+               extname = "status request";
+               break;
+
+               case TLSEXT_TYPE_elliptic_curves:
+               extname = "elliptic curves";
+               break;
+
+               case TLSEXT_TYPE_ec_point_formats:
+               extname = "EC point formats";
+               break;
+
+               case TLSEXT_TYPE_session_ticket:
+               extname = "server ticket";
+               break;
+
+
+               default:
+               extname = "unknown";
+               break;
+
+               }
+       
+       BIO_printf(bio, "TLS %s extension \"%s\" (id=%d), len=%d\n",
+                       client_server ? "server": "client",
+                       extname, type, len);
+       BIO_dump(bio, (char *)data, len);
+       (void)BIO_flush(bio);
        }
index 3f302c5..d240fe2 100644 (file)
@@ -171,6 +171,9 @@ static int c_nbio=0;
 #endif
 static int c_Pause=0;
 static int c_debug=0;
+#ifndef OPENSSL_NO_TLSEXT
+static int c_tlsextdebug=0;
+#endif
 static int c_msg=0;
 static int c_showcerts=0;
 
@@ -231,9 +234,36 @@ static void sc_usage(void)
        BIO_printf(bio_err," -engine id    - Initialise and use the specified engine\n");
 #endif
        BIO_printf(bio_err," -rand file%cfile%c...\n", LIST_SEPARATOR_CHAR, LIST_SEPARATOR_CHAR);
-
+       BIO_printf(bio_err," -sess_out arg - file to write SSL session to\n");
+       BIO_printf(bio_err," -sess_in arg  - file to read SSL session from\n");
+#ifndef OPENSSL_NO_TLSEXT
+       BIO_printf(bio_err," -servername host  - Set TLS extension servername in ClientHello\n");
+       BIO_printf(bio_err," -tlsextdebug      - hex dump of all TLS extensions received\n");
+       BIO_printf(bio_err," -no_ticket        - disable use of RFC4507bis session tickets\n");
+#endif
        }
 
+#ifndef OPENSSL_NO_TLSEXT
+
+/* This is a context that we pass to callbacks */
+typedef struct tlsextctx_st {
+   BIO * biodebug;
+   int ack;
+} tlsextctx;
+
+
+static int MS_CALLBACK ssl_servername_cb(SSL *s, int *ad, void *arg)
+       {
+       tlsextctx * p = (tlsextctx *) arg;
+       const char * hn= SSL_get_servername(s, TLSEXT_NAMETYPE_host_name);
+       if (SSL_get_servername_type(s) != -1) 
+               p->ack = !SSL_session_reused(s) && hn != NULL;
+       else 
+               BIO_printf(bio_err,"Can't use SSL_get_servername\n");
+       
+       return SSL_TLSEXT_ERR_OK;
+       }
+#endif
 enum
 {
        PROTO_OFF       = 0,
@@ -287,6 +317,13 @@ int MAIN(int argc, char **argv)
        struct timeval tv;
 #endif
 
+#ifndef OPENSSL_NO_TLSEXT
+       char *servername = NULL; 
+        tlsextctx tlsextcbp = 
+        {NULL,0};
+#endif
+       char *sess_in = NULL;
+       char *sess_out = NULL;
        struct sockaddr peer;
        int peerlen = sizeof(peer);
        int enable_timeouts = 0 ;
@@ -361,6 +398,16 @@ int MAIN(int argc, char **argv)
                        if (--argc < 1) goto bad;
                        cert_file= *(++argv);
                        }
+               else if (strcmp(*argv,"-sess_out") == 0)
+                       {
+                       if (--argc < 1) goto bad;
+                       sess_out = *(++argv);
+                       }
+               else if (strcmp(*argv,"-sess_in") == 0)
+                       {
+                       if (--argc < 1) goto bad;
+                       sess_in = *(++argv);
+                       }
                else if (strcmp(*argv,"-certform") == 0)
                        {
                        if (--argc < 1) goto bad;
@@ -385,6 +432,10 @@ int MAIN(int argc, char **argv)
                        c_Pause=1;
                else if (strcmp(*argv,"-debug") == 0)
                        c_debug=1;
+#ifndef OPENSSL_NO_TLSEXT
+               else if (strcmp(*argv,"-tlsextdebug") == 0)
+                       c_tlsextdebug=1;
+#endif
 #ifdef WATT32
                else if (strcmp(*argv,"-wdebug") == 0)
                        dbug_init();
@@ -460,6 +511,10 @@ int MAIN(int argc, char **argv)
                        off|=SSL_OP_NO_SSLv3;
                else if (strcmp(*argv,"-no_ssl2") == 0)
                        off|=SSL_OP_NO_SSLv2;
+#ifndef OPENSSL_NO_TLSEXT
+               else if (strcmp(*argv,"-no_ticket") == 0)
+                       { off|=SSL_OP_NO_TICKET; }
+#endif
                else if (strcmp(*argv,"-serverpref") == 0)
                        off|=SSL_OP_CIPHER_SERVER_PREFERENCE;
                else if (strcmp(*argv,"-cipher") == 0)
@@ -498,6 +553,14 @@ int MAIN(int argc, char **argv)
                        if (--argc < 1) goto bad;
                        inrand= *(++argv);
                        }
+#ifndef OPENSSL_NO_TLSEXT
+               else if (strcmp(*argv,"-servername") == 0)
+                       {
+                       if (--argc < 1) goto bad;
+                       servername= *(++argv);
+                       /* meth=TLSv1_client_method(); */
+                       }
+#endif
                else
                        {
                        BIO_printf(bio_err,"unknown option %s\n",*argv);
@@ -621,8 +684,51 @@ bad:
 
        store = SSL_CTX_get_cert_store(ctx);
        X509_STORE_set_flags(store, vflags);
+#ifndef OPENSSL_NO_TLSEXT
+       if (servername != NULL)
+               {
+               tlsextcbp.biodebug = bio_err;
+               SSL_CTX_set_tlsext_servername_callback(ctx, ssl_servername_cb);
+               SSL_CTX_set_tlsext_servername_arg(ctx, &tlsextcbp);
+               }
+#endif
 
        con=SSL_new(ctx);
+       if (sess_in)
+               {
+               SSL_SESSION *sess;
+               BIO *stmp = BIO_new_file(sess_in, "r");
+               if (!stmp)
+                       {
+                       BIO_printf(bio_err, "Can't open session file %s\n",
+                                               sess_in);
+                       ERR_print_errors(bio_err);
+                       goto end;
+                       }
+               sess = PEM_read_bio_SSL_SESSION(stmp, NULL, 0, NULL);
+               BIO_free(stmp);
+               if (!sess)
+                       {
+                       BIO_printf(bio_err, "Can't open session file %s\n",
+                                               sess_in);
+                       ERR_print_errors(bio_err);
+                       goto end;
+                       }
+               SSL_set_session(con, sess);
+               SSL_SESSION_free(sess);
+               }
+#ifndef OPENSSL_NO_TLSEXT
+       if (servername != NULL)
+               {
+               if (!SSL_set_tlsext_host_name(con,servername))
+                       {
+                       BIO_printf(bio_err,"Unable to set TLS servername extension.\n");
+                       ERR_print_errors(bio_err);
+                       goto end;
+                       }
+               }
+#endif
+
 #ifndef OPENSSL_NO_KRB5
        if (con  &&  (con->kssl_ctx = kssl_ctx_new()) != NULL)
                 {
@@ -668,7 +774,7 @@ re_start:
                        goto end;
                        }
 
-               BIO_ctrl_set_connected(sbio, 1, &peer);
+               (void)BIO_ctrl_set_connected(sbio, 1, &peer);
 
                if ( enable_timeouts)
                        {
@@ -714,6 +820,13 @@ re_start:
                SSL_set_msg_callback(con, msg_cb);
                SSL_set_msg_callback_arg(con, bio_c_out);
                }
+#ifndef OPENSSL_NO_TLSEXT
+       if (c_tlsextdebug)
+               {
+               SSL_set_tlsext_debug_callback(con, tlsext_cb);
+               SSL_set_tlsext_debug_arg(con, bio_c_out);
+               }
+#endif
 
        SSL_set_bio(con,sbio,sbio);
        SSL_set_connect_state(con);
@@ -752,7 +865,7 @@ re_start:
                while (mbuf_len>3 && mbuf[3]=='-');
                /* STARTTLS command requires EHLO... */
                BIO_printf(fbio,"EHLO openssl.client.net\r\n");
-               BIO_flush(fbio);
+               (void)BIO_flush(fbio);
                /* wait for multi-line response to end EHLO SMTP response */
                do
                        {
@@ -761,7 +874,7 @@ re_start:
                                foundit=1;
                        }
                while (mbuf_len>3 && mbuf[3]=='-');
-               BIO_flush(fbio);
+               (void)BIO_flush(fbio);
                BIO_pop(fbio);
                BIO_free(fbio);
                if (!foundit)
@@ -785,7 +898,7 @@ re_start:
                BIO_gets(fbio,mbuf,BUFSIZZ);
                /* STARTTLS command requires CAPABILITY... */
                BIO_printf(fbio,". CAPABILITY\r\n");
-               BIO_flush(fbio);
+               (void)BIO_flush(fbio);
                /* wait for multi-line CAPABILITY response */
                do
                        {
@@ -794,7 +907,7 @@ re_start:
                                foundit=1;
                        }
                while (mbuf_len>3 && mbuf[0]!='.');
-               BIO_flush(fbio);
+               (void)BIO_flush(fbio);
                BIO_pop(fbio);
                BIO_free(fbio);
                if (!foundit)
@@ -814,7 +927,7 @@ re_start:
                        mbuf_len = BIO_gets(fbio,mbuf,BUFSIZZ);
                        }
                while (mbuf_len>3 && mbuf[3]=='-');
-               BIO_flush(fbio);
+               (void)BIO_flush(fbio);
                BIO_pop(fbio);
                BIO_free(fbio);
                BIO_printf(sbio,"AUTH TLS\r\n");
@@ -837,6 +950,17 @@ re_start:
                        if (in_init)
                                {
                                in_init=0;
+                               if (sess_out)
+                                       {
+                                       BIO *stmp = BIO_new_file(sess_out, "w");
+                                       if (stmp)
+                                               {
+                                               PEM_write_bio_SSL_SESSION(stmp, SSL_get_session(con));
+                                               BIO_free(stmp);
+                                               }
+                                       else 
+                                               BIO_printf(bio_err, "Error writing session file %s\n", sess_out);
+                                       }
                                print_stuff(bio_c_out,con,full_log);
                                if (full_log > 0) full_log--;
 
@@ -1303,6 +1427,6 @@ static void print_stuff(BIO *bio, SSL *s, int full)
        if (peer != NULL)
                X509_free(peer);
        /* flush, or debugging output gets mixed with http response */
-       BIO_flush(bio);
+       (void)BIO_flush(bio);
        }
 
index 6c433e6..7c5775f 100644 (file)
@@ -238,6 +238,9 @@ static int bufsize=BUFSIZZ;
 static int accept_socket= -1;
 
 #define TEST_CERT      "server.pem"
+#ifndef OPENSSL_NO_TLSEXT
+#define TEST_CERT2     "server2.pem"
+#endif
 #undef PROG
 #define PROG           s_server_main
 
@@ -247,6 +250,9 @@ static char *cipher=NULL;
 static int s_server_verify=SSL_VERIFY_NONE;
 static int s_server_session_id_context = 1; /* anything will do */
 static const char *s_cert_file=TEST_CERT,*s_key_file=NULL;
+#ifndef OPENSSL_NO_TLSEXT
+static const char *s_cert_file2=TEST_CERT2,*s_key_file2=NULL;
+#endif
 static char *s_dcert_file=NULL,*s_dkey_file=NULL;
 #ifdef FIONBIO
 static int s_nbio=0;
@@ -254,10 +260,16 @@ static int s_nbio=0;
 static int s_nbio_test=0;
 int s_crlf=0;
 static SSL_CTX *ctx=NULL;
+#ifndef OPENSSL_NO_TLSEXT
+static SSL_CTX *ctx2=NULL;
+#endif
 static int www=0;
 
 static BIO *bio_s_out=NULL;
 static int s_debug=0;
+#ifndef OPENSSL_NO_TLSEXT
+static int s_tlsextdebug=0;
+#endif
 static int s_msg=0;
 static int s_quiet=0;
 
@@ -285,6 +297,11 @@ static void s_server_init(void)
        s_dkey_file=NULL;
        s_cert_file=TEST_CERT;
        s_key_file=NULL;
+#ifndef OPENSSL_NO_TLSEXT
+       s_cert_file2=TEST_CERT2;
+       s_key_file2=NULL;
+       ctx2=NULL;
+#endif
 #ifdef FIONBIO
        s_nbio=0;
 #endif
@@ -371,6 +388,16 @@ static void sv_usage(void)
 #endif
        BIO_printf(bio_err," -id_prefix arg - Generate SSL/TLS session IDs prefixed by 'arg'\n");
        BIO_printf(bio_err," -rand file%cfile%c...\n", LIST_SEPARATOR_CHAR, LIST_SEPARATOR_CHAR);
+#ifndef OPENSSL_NO_TLSEXT
+       BIO_printf(bio_err," -servername host - servername for HostName TLS extension\n");
+       BIO_printf(bio_err," -servername_fatal - on mismatch send fatal alert (default warning alert)\n");
+       BIO_printf(bio_err," -cert2 arg    - certificate file to use for servername\n");
+       BIO_printf(bio_err,"                 (default is %s)\n",TEST_CERT2);
+       BIO_printf(bio_err," -key2 arg     - Private Key file to use for servername, in cert file if\n");
+       BIO_printf(bio_err,"                 not specified (default is %s)\n",TEST_CERT2);
+       BIO_printf(bio_err," -tlsextdebug  - hex dump of all TLS extensions received\n");
+       BIO_printf(bio_err," -no_ticket    - disable use of RFC4507bis session tickets\n");
+#endif
        }
 
 static int local_argc=0;
@@ -526,6 +553,39 @@ static int ebcdic_puts(BIO *bp, const char *str)
 }
 #endif
 
+#ifndef OPENSSL_NO_TLSEXT
+
+/* This is a context that we pass to callbacks */
+typedef struct tlsextctx_st {
+   char * servername;
+   BIO * biodebug;
+   int extension_error;
+} tlsextctx;
+
+
+static int MS_CALLBACK ssl_servername_cb(SSL *s, int *ad, void *arg)
+       {
+       tlsextctx * p = (tlsextctx *) arg;
+       const char * servername = SSL_get_servername(s, TLSEXT_NAMETYPE_host_name);
+        if (servername && p->biodebug) 
+               BIO_printf(p->biodebug,"Hostname in TLS extension: \"%s\"\n",servername);
+        
+       if (!p->servername)
+               return SSL_TLSEXT_ERR_NOACK;
+       
+       if (servername)
+               {
+               if (strcmp(servername,p->servername)) 
+                       return p->extension_error;
+               if (ctx2)
+                       {
+                       BIO_printf(p->biodebug,"Swiching server context.\n");
+                       SSL_set_SSL_CTX(s,ctx2);
+                       }     
+               }
+       return SSL_TLSEXT_ERR_OK;
+}
+#endif
 int MAIN(int, char **);
 
 int MAIN(int argc, char *argv[])
@@ -545,10 +605,7 @@ int MAIN(int argc, char *argv[])
        int no_tmp_rsa=0,no_dhe=0,no_ecdhe=0,nocert=0;
        int state=0;
        SSL_METHOD *meth=NULL;
-#ifdef sock_type
-#undef sock_type
-#endif
-    int sock_type=SOCK_STREAM;
+        int socket_type=SOCK_STREAM;
 #ifndef OPENSSL_NO_ENGINE
        ENGINE *e=NULL;
 #endif
@@ -559,6 +616,14 @@ int MAIN(int argc, char *argv[])
        int s_dcert_format = FORMAT_PEM, s_dkey_format = FORMAT_PEM;
        X509 *s_cert = NULL, *s_dcert = NULL;
        EVP_PKEY *s_key = NULL, *s_dkey = NULL;
+#ifndef OPENSSL_NO_TLSEXT
+       EVP_PKEY *s_key2 = NULL;
+       X509 *s_cert2 = NULL;
+#endif
+
+#ifndef OPENSSL_NO_TLSEXT
+        tlsextctx tlsextcbp = {NULL, NULL, SSL_TLSEXT_ERR_ALERT_WARNING};
+#endif
 
 #if !defined(OPENSSL_NO_SSL2) && !defined(OPENSSL_NO_SSL3)
        meth=SSLv23_server_method();
@@ -724,6 +789,10 @@ int MAIN(int argc, char *argv[])
                        }
                else if (strcmp(*argv,"-debug") == 0)
                        { s_debug=1; }
+#ifndef OPENSSL_NO_TLSEXT
+               else if (strcmp(*argv,"-tlsextdebug") == 0)
+                       s_tlsextdebug=1;
+#endif
                else if (strcmp(*argv,"-msg") == 0)
                        { s_msg=1; }
                else if (strcmp(*argv,"-hack") == 0)
@@ -754,6 +823,10 @@ int MAIN(int argc, char *argv[])
                        { off|=SSL_OP_NO_SSLv3; }
                else if (strcmp(*argv,"-no_tls1") == 0)
                        { off|=SSL_OP_NO_TLSv1; }
+#ifndef OPENSSL_NO_TLSEXT
+               else if (strcmp(*argv,"-no_ticket") == 0)
+                       { off|=SSL_OP_NO_TICKET; }
+#endif
 #ifndef OPENSSL_NO_SSL2
                else if (strcmp(*argv,"-ssl2") == 0)
                        { meth=SSLv2_server_method(); }
@@ -770,7 +843,7 @@ int MAIN(int argc, char *argv[])
                else if (strcmp(*argv,"-dtls1") == 0)
                        { 
                        meth=DTLSv1_server_method();
-                       sock_type = SOCK_DGRAM;
+                       socket_type = SOCK_DGRAM;
                        }
                else if (strcmp(*argv,"-timeout") == 0)
                        enable_timeouts = 1;
@@ -799,6 +872,25 @@ int MAIN(int argc, char *argv[])
                        if (--argc < 1) goto bad;
                        inrand= *(++argv);
                        }
+#ifndef OPENSSL_NO_TLSEXT
+               else if (strcmp(*argv,"-servername") == 0)
+                       {
+                       if (--argc < 1) goto bad;
+                       tlsextcbp.servername= *(++argv);
+                       }
+               else if (strcmp(*argv,"-servername_fatal") == 0)
+                       { tlsextcbp.extension_error = SSL_TLSEXT_ERR_ALERT_FATAL; }
+               else if (strcmp(*argv,"-cert2") == 0)
+                       {
+                       if (--argc < 1) goto bad;
+                       s_cert_file2= *(++argv);
+                       }
+               else if (strcmp(*argv,"-key2") == 0)
+                       {
+                       if (--argc < 1) goto bad;
+                       s_key_file2= *(++argv);
+                       }
+#endif
                else
                        {
                        BIO_printf(bio_err,"unknown option %s\n",*argv);
@@ -831,6 +923,10 @@ bad:
 
        if (s_key_file == NULL)
                s_key_file = s_cert_file;
+#ifndef OPENSSL_NO_TLSEXT
+       if (s_key_file2 == NULL)
+               s_key_file2 = s_cert_file2;
+#endif
 
        if (nocert == 0)
                {
@@ -850,8 +946,29 @@ bad:
                        ERR_print_errors(bio_err);
                        goto end;
                        }
-               }
 
+#ifndef OPENSSL_NO_TLSEXT
+               if (tlsextcbp.servername) 
+                       {
+                       s_key2 = load_key(bio_err, s_key_file2, s_key_format, 0, pass, e,
+                               "second server certificate private key file");
+                       if (!s_key2)
+                               {
+                               ERR_print_errors(bio_err);
+                               goto end;
+                               }
+                       
+                       s_cert2 = load_cert(bio_err,s_cert_file2,s_cert_format,
+                               NULL, e, "second server certificate file");
+                       
+                       if (!s_cert2)
+                               {
+                               ERR_print_errors(bio_err);
+                               goto end;
+                               }
+                       }
+#endif
+               }
        if (s_dcert_file)
                {
 
@@ -908,6 +1025,10 @@ bad:
                s_key_file=NULL;
                s_dcert_file=NULL;
                s_dkey_file=NULL;
+#ifndef OPENSSL_NO_TLSEXT
+               s_cert_file2=NULL;
+               s_key_file2=NULL;
+#endif
                }
 
        ctx=SSL_CTX_new(meth);
@@ -939,7 +1060,7 @@ bad:
        /* DTLS: partial reads end up discarding unread UDP bytes :-( 
         * Setting read ahead solves this problem.
         */
-       if (sock_type == SOCK_DGRAM) SSL_CTX_set_read_ahead(ctx, 1);
+       if (socket_type == SOCK_DGRAM) SSL_CTX_set_read_ahead(ctx, 1);
 
        if (state) SSL_CTX_set_info_callback(ctx,apps_ssl_info_callback);
 
@@ -966,6 +1087,62 @@ bad:
                }
        store = SSL_CTX_get_cert_store(ctx);
        X509_STORE_set_flags(store, vflags);
+#ifndef OPENSSL_NO_TLSEXT
+       if (s_cert2)
+               {
+               ctx2=SSL_CTX_new(meth);
+               if (ctx2 == NULL)
+                       {
+                       ERR_print_errors(bio_err);
+                       goto end;
+                       }
+               }
+       
+       if (ctx2)
+               {
+               BIO_printf(bio_s_out,"Setting secondary ctx parameters\n");
+
+               if (session_id_prefix)
+                       {
+                       if(strlen(session_id_prefix) >= 32)
+                               BIO_printf(bio_err,
+                                       "warning: id_prefix is too long, only one new session will be possible\n");
+                       else if(strlen(session_id_prefix) >= 16)
+                               BIO_printf(bio_err,
+                                       "warning: id_prefix is too long if you use SSLv2\n");
+                       if(!SSL_CTX_set_generate_session_id(ctx2, generate_session_id))
+                               {
+                               BIO_printf(bio_err,"error setting 'id_prefix'\n");
+                               ERR_print_errors(bio_err);
+                               goto end;
+                               }
+                       BIO_printf(bio_err,"id_prefix '%s' set.\n", session_id_prefix);
+                       }
+               SSL_CTX_set_quiet_shutdown(ctx2,1);
+               if (bugs) SSL_CTX_set_options(ctx2,SSL_OP_ALL);
+               if (hack) SSL_CTX_set_options(ctx2,SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG);
+               SSL_CTX_set_options(ctx2,off);
+
+               /* DTLS: partial reads end up discarding unread UDP bytes :-( 
+                * Setting read ahead solves this problem.
+                */
+               if (socket_type == SOCK_DGRAM) SSL_CTX_set_read_ahead(ctx2, 1);
+
+
+               if (state) SSL_CTX_set_info_callback(ctx2,apps_ssl_info_callback);
+
+               SSL_CTX_sess_set_cache_size(ctx2,128);
+
+               if ((!SSL_CTX_load_verify_locations(ctx2,CAfile,CApath)) ||
+                       (!SSL_CTX_set_default_verify_paths(ctx2)))
+                       {
+                       ERR_print_errors(bio_err);
+                       }
+               store = SSL_CTX_get_cert_store(ctx2);
+               X509_STORE_set_flags(store, vflags);
+               }
+#endif 
+
 
 #ifndef OPENSSL_NO_DH
        if (!no_dhe)
@@ -989,6 +1166,24 @@ bad:
                (void)BIO_flush(bio_s_out);
 
                SSL_CTX_set_tmp_dh(ctx,dh);
+#ifndef OPENSSL_NO_TLSEXT
+               if (ctx2)
+                       {
+                       if (!dhfile)
+                               { 
+                               DH *dh2=load_dh_param(s_cert_file2);
+                               if (dh2 != NULL)
+                                       {
+                                       BIO_printf(bio_s_out,"Setting temp DH parameters\n");
+                                       (void)BIO_flush(bio_s_out);
+
+                                       DH_free(dh);
+                                       dh = dh2;
+                                       }
+                               }
+                       SSL_CTX_set_tmp_dh(ctx2,dh);
+                       }
+#endif
                DH_free(dh);
                }
 #endif
@@ -1034,12 +1229,20 @@ bad:
                (void)BIO_flush(bio_s_out);
 
                SSL_CTX_set_tmp_ecdh(ctx,ecdh);
+#ifndef OPENSSL_NO_TLSEXT
+               if (ctx2) 
+                       SSL_CTX_set_tmp_ecdh(ctx2,ecdh);
+#endif
                EC_KEY_free(ecdh);
                }
 #endif
        
        if (!set_cert_key_stuff(ctx,s_cert,s_key))
                goto end;
+#ifndef OPENSSL_NO_TLSEXT
+       if (ctx2 && !set_cert_key_stuff(ctx2,s_cert2,s_key2))
+               goto end; 
+#endif
        if (s_dcert != NULL)
                {
                if (!set_cert_key_stuff(ctx,s_dcert,s_dkey))
@@ -1049,7 +1252,13 @@ bad:
 #ifndef OPENSSL_NO_RSA
 #if 1
        if (!no_tmp_rsa)
+               {
                SSL_CTX_set_tmp_rsa_callback(ctx,tmp_rsa_cb);
+#ifndef OPENSSL_NO_TLSEXT
+               if (ctx2) 
+                       SSL_CTX_set_tmp_rsa_callback(ctx2,tmp_rsa_cb);
+#endif 
+               }
 #else
        if (!no_tmp_rsa && SSL_CTX_need_tmp_RSA(ctx))
                {
@@ -1065,6 +1274,16 @@ bad:
                        ERR_print_errors(bio_err);
                        goto end;
                        }
+#ifndef OPENSSL_NO_TLSEXT
+                       if (ctx2)
+                               {
+                               if (!SSL_CTX_set_tmp_rsa(ctx2,rsa))
+                                       {
+                                       ERR_print_errors(bio_err);
+                                       goto end;
+                                       }
+                               }
+#endif
                RSA_free(rsa);
                BIO_printf(bio_s_out,"\n");
                }
@@ -1076,19 +1295,46 @@ bad:
                BIO_printf(bio_err,"error setting cipher list\n");
                ERR_print_errors(bio_err);
                goto end;
+#ifndef OPENSSL_NO_TLSEXT
+               if (ctx2 && !SSL_CTX_set_cipher_list(ctx2,cipher))
+                       {
+                       BIO_printf(bio_err,"error setting cipher list\n");
+                       ERR_print_errors(bio_err);
+                       goto end;
+                       }
+#endif
        }
        SSL_CTX_set_verify(ctx,s_server_verify,verify_callback);
        SSL_CTX_set_session_id_context(ctx,(void*)&s_server_session_id_context,
                sizeof s_server_session_id_context);
 
+#ifndef OPENSSL_NO_TLSEXT
+       if (ctx2)
+               {
+               SSL_CTX_set_verify(ctx2,s_server_verify,verify_callback);
+               SSL_CTX_set_session_id_context(ctx2,(void*)&s_server_session_id_context,
+                       sizeof s_server_session_id_context);
+
+               tlsextcbp.biodebug = bio_s_out;
+               SSL_CTX_set_tlsext_servername_callback(ctx2, ssl_servername_cb);
+               SSL_CTX_set_tlsext_servername_arg(ctx2, &tlsextcbp);
+               SSL_CTX_set_tlsext_servername_callback(ctx, ssl_servername_cb);
+               SSL_CTX_set_tlsext_servername_arg(ctx, &tlsextcbp);
+               }
+#endif
        if (CAfile != NULL)
-           SSL_CTX_set_client_CA_list(ctx,SSL_load_client_CA_file(CAfile));
-
+               {
+               SSL_CTX_set_client_CA_list(ctx,SSL_load_client_CA_file(CAfile));
+#ifndef OPENSSL_NO_TLSEXT
+               if (ctx2) 
+                       SSL_CTX_set_client_CA_list(ctx2,SSL_load_client_CA_file(CAfile));
+#endif
+               }
        BIO_printf(bio_s_out,"ACCEPT\n");
        if (www)
-               do_server(port,sock_type,&accept_socket,www_body, context);
+               do_server(port,socket_type,&accept_socket,www_body, context);
        else
-               do_server(port,sock_type,&accept_socket,sv_body, context);
+               do_server(port,socket_type,&accept_socket,sv_body, context);
        print_stats(bio_s_out,ctx);
        ret=0;
 end:
@@ -1105,6 +1351,13 @@ end:
                OPENSSL_free(pass);
        if (dpass)
                OPENSSL_free(dpass);
+#ifndef OPENSSL_NO_TLSEXT
+       if (ctx2 != NULL) SSL_CTX_free(ctx2);
+       if (s_cert2)
+               X509_free(s_cert2);
+       if (s_key2)
+               EVP_PKEY_free(s_key2);
+#endif
        if (bio_s_out != NULL)
                {
         BIO_free(bio_s_out);
@@ -1171,6 +1424,13 @@ static int sv_body(char *hostname, int s, unsigned char *context)
 
        if (con == NULL) {
                con=SSL_new(ctx);
+#ifndef OPENSSL_NO_TLSEXT
+       if (s_tlsextdebug)
+               {
+               SSL_set_tlsext_debug_callback(con, tlsext_cb);
+               SSL_set_tlsext_debug_arg(con, bio_s_out);
+               }
+#endif
 #ifndef OPENSSL_NO_KRB5
                if ((con->kssl_ctx = kssl_ctx_new()) != NULL)
                         {
@@ -1241,6 +1501,13 @@ static int sv_body(char *hostname, int s, unsigned char *context)
                SSL_set_msg_callback(con, msg_cb);
                SSL_set_msg_callback_arg(con, bio_s_out);
                }
+#ifndef OPENSSL_NO_TLSEXT
+       if (s_tlsextdebug)
+               {
+               SSL_set_tlsext_debug_callback(con, tlsext_cb);
+               SSL_set_tlsext_debug_arg(con, bio_s_out);
+               }
+#endif
 
        width=s+1;
        for (;;)
@@ -1606,6 +1873,13 @@ static int www_body(char *hostname, int s, unsigned char *context)
        if (!BIO_set_write_buffer_size(io,bufsize)) goto err;
 
        if ((con=SSL_new(ctx)) == NULL) goto err;
+#ifndef OPENSSL_NO_TLSEXT
+               if (s_tlsextdebug)
+                       {
+                       SSL_set_tlsext_debug_callback(con, tlsext_cb);
+                       SSL_set_tlsext_debug_arg(con, bio_s_out);
+                       }
+#endif
 #ifndef OPENSSL_NO_KRB5
        if ((con->kssl_ctx = kssl_ctx_new()) != NULL)
                {
index 830f18c..ce8a1cb 100644 (file)
@@ -145,6 +145,10 @@ int MAIN(int argc, char **argv)
                else if (!strcmp (*args, "-des")) 
                                cipher = EVP_des_cbc();
 #endif
+#ifndef OPENSSL_NO_SEED
+               else if (!strcmp (*args, "-seed")) 
+                               cipher = EVP_seed_cbc();
+#endif
 #ifndef OPENSSL_NO_RC2
                else if (!strcmp (*args, "-rc2-40")) 
                                cipher = EVP_rc2_40_cbc();
@@ -423,6 +427,9 @@ int MAIN(int argc, char **argv)
                BIO_printf (bio_err, "-des3          encrypt with triple DES\n");
                BIO_printf (bio_err, "-des           encrypt with DES\n");
 #endif
+#ifndef OPENSSL_NO_SEED
+               BIO_printf (bio_err, "-seed          encrypt with SEED\n");
+#endif
 #ifndef OPENSSL_NO_RC2
                BIO_printf (bio_err, "-rc2-40        encrypt with RC2-40 (default)\n");
                BIO_printf (bio_err, "-rc2-64        encrypt with RC2-64\n");
index 7858aee..85f559e 100644 (file)
 #ifndef OPENSSL_NO_IDEA
 #include <openssl/idea.h>
 #endif
+#ifndef OPENSSL_NO_SEED
+#include <openssl/seed.h>
+#endif
 #ifndef OPENSSL_NO_BF
 #include <openssl/blowfish.h>
 #endif
@@ -272,7 +275,7 @@ static void print_result(int alg,int run_no,int count,double time_used);
 static int do_multi(int multi);
 #endif
 
-#define ALGOR_NUM      24
+#define ALGOR_NUM      28
 #define SIZE_NUM       5
 #define RSA_NUM                4
 #define DSA_NUM                3
@@ -282,11 +285,12 @@ static int do_multi(int multi);
 
 static const char *names[ALGOR_NUM]={
   "md2","mdc2","md4","md5","hmac(md5)","sha1","rmd160","rc4",
-  "des cbc","des ede3","idea cbc",
+  "des cbc","des ede3","idea cbc","seed cbc",
   "rc2 cbc","rc5-32/12 cbc","blowfish cbc","cast cbc",
   "aes-128 cbc","aes-192 cbc","aes-256 cbc",
   "camellia-128 cbc","camellia-192 cbc","camellia-256 cbc",
-  "evp","sha256","sha512"};
+  "evp","sha256","sha512",
+  "aes-128 ige","aes-192 ige","aes-256 ige"};
 static double results[ALGOR_NUM][SIZE_NUM];
 static int lengths[SIZE_NUM]={16,64,256,1024,8*1024};
 static double rsa_results[RSA_NUM][2];
@@ -533,6 +537,9 @@ int MAIN(int argc, char **argv)
 #ifndef OPENSSL_NO_IDEA
        IDEA_KEY_SCHEDULE idea_ks;
 #endif
+#ifndef OPENSSL_NO_SEED
+       SEED_KEY_SCHEDULE seed_ks;
+#endif
 #ifndef OPENSSL_NO_BF
        BF_KEY bf_ks;
 #endif
@@ -597,19 +604,23 @@ int MAIN(int argc, char **argv)
 #define        D_CBC_DES       8
 #define        D_EDE3_DES      9
 #define        D_CBC_IDEA      10
-#define        D_CBC_RC2       11
-#define        D_CBC_RC5       12
-#define        D_CBC_BF        13
-#define        D_CBC_CAST      14
-#define D_CBC_128_AES  15
-#define D_CBC_192_AES  16
-#define D_CBC_256_AES  17
-#define D_CBC_128_CML   18 
-#define D_CBC_192_CML   19
-#define D_CBC_256_CML   20 
-#define D_EVP          21
-#define D_SHA256       22      
-#define D_SHA512       23
+#define        D_CBC_SEED      11
+#define        D_CBC_RC2       12
+#define        D_CBC_RC5       13
+#define        D_CBC_BF        14
+#define        D_CBC_CAST      15
+#define D_CBC_128_AES  16
+#define D_CBC_192_AES  17
+#define D_CBC_256_AES  18
+#define D_CBC_128_CML   19 
+#define D_CBC_192_CML   20
+#define D_CBC_256_CML   21 
+#define D_EVP          22
+#define D_SHA256       23      
+#define D_SHA512       24
+#define D_IGE_128_AES   25
+#define D_IGE_192_AES   26
+#define D_IGE_256_AES   27
        double d=0.0;
        long c[ALGOR_NUM][SIZE_NUM];
 #define        R_DSA_512       0
@@ -950,7 +961,10 @@ int MAIN(int argc, char **argv)
                        if (strcmp(*argv,"aes-128-cbc") == 0) doit[D_CBC_128_AES]=1;
                else    if (strcmp(*argv,"aes-192-cbc") == 0) doit[D_CBC_192_AES]=1;
                else    if (strcmp(*argv,"aes-256-cbc") == 0) doit[D_CBC_256_AES]=1;
-               else
+               else    if (strcmp(*argv,"aes-128-ige") == 0) doit[D_IGE_128_AES]=1;
+               else    if (strcmp(*argv,"aes-192-ige") == 0) doit[D_IGE_192_AES]=1;
+               else    if (strcmp(*argv,"aes-256-ige") == 0) doit[D_IGE_256_AES]=1;
+                else
 #endif
 #ifndef OPENSSL_NO_CAMELLIA
                        if (strcmp(*argv,"camellia-128-cbc") == 0) doit[D_CBC_128_CML]=1;
@@ -999,6 +1013,11 @@ int MAIN(int argc, char **argv)
                else if (strcmp(*argv,"idea") == 0) doit[D_CBC_IDEA]=1;
                else
 #endif
+#ifndef OPENSSL_NO_SEED
+                    if (strcmp(*argv,"seed-cbc") == 0) doit[D_CBC_SEED]=1;
+               else if (strcmp(*argv,"seed") == 0) doit[D_CBC_SEED]=1;
+               else
+#endif
 #ifndef OPENSSL_NO_BF
                     if (strcmp(*argv,"bf-cbc") == 0) doit[D_CBC_BF]=1;
                else if (strcmp(*argv,"blowfish") == 0) doit[D_CBC_BF]=1;
@@ -1144,6 +1163,9 @@ int MAIN(int argc, char **argv)
 #ifndef OPENSSL_NO_IDEA
                        BIO_printf(bio_err,"idea-cbc ");
 #endif
+#ifndef OPENSSL_NO_SEED
+                       BIO_printf(bio_err,"seed-cbc ");
+#endif
 #ifndef OPENSSL_NO_RC2
                        BIO_printf(bio_err,"rc2-cbc  ");
 #endif
@@ -1153,7 +1175,7 @@ int MAIN(int argc, char **argv)
 #ifndef OPENSSL_NO_BF
                        BIO_printf(bio_err,"bf-cbc");
 #endif
-#if !defined(OPENSSL_NO_IDEA) || !defined(OPENSSL_NO_RC2) || \
+#if !defined(OPENSSL_NO_IDEA) || !defined(OPENSSL_NO_SEED) || !defined(OPENSSL_NO_RC2) || \
     !defined(OPENSSL_NO_BF) || !defined(OPENSSL_NO_RC5)
                        BIO_printf(bio_err,"\n");
 #endif
@@ -1162,6 +1184,7 @@ int MAIN(int argc, char **argv)
 #endif
 #ifndef OPENSSL_NO_AES
                        BIO_printf(bio_err,"aes-128-cbc aes-192-cbc aes-256-cbc ");
+                       BIO_printf(bio_err,"aes-128-ige aes-192-ige aes-256-ige ");
 #endif
 #ifndef OPENSSL_NO_CAMELLIA
                        BIO_printf(bio_err,"\n");
@@ -1195,6 +1218,9 @@ int MAIN(int argc, char **argv)
 #ifndef OPENSSL_NO_IDEA
                        BIO_printf(bio_err,"idea     ");
 #endif
+#ifndef OPENSSL_NO_SEED
+                       BIO_printf(bio_err,"seed     ");
+#endif
 #ifndef OPENSSL_NO_RC2
                        BIO_printf(bio_err,"rc2      ");
 #endif
@@ -1213,10 +1239,10 @@ int MAIN(int argc, char **argv)
 #ifndef OPENSSL_NO_BF
                        BIO_printf(bio_err,"blowfish");
 #endif
-#if !defined(OPENSSL_NO_IDEA) || !defined(OPENSSL_NO_RC2) || \
-    !defined(OPENSSL_NO_DES) || !defined(OPENSSL_NO_RSA) || \
-    !defined(OPENSSL_NO_BF) || !defined(OPENSSL_NO_AES) || \
-    !defined(OPENSSL_NO_CAMELLIA) 
+#if !defined(OPENSSL_NO_IDEA) || !defined(OPENSSL_NO_SEED) || \
+    !defined(OPENSSL_NO_RC2) || !defined(OPENSSL_NO_DES) || \
+    !defined(OPENSSL_NO_RSA) || !defined(OPENSSL_NO_BF) || \
+    !defined(OPENSSL_NO_AES) || !defined(OPENSSL_NO_CAMELLIA)
                        BIO_printf(bio_err,"\n");
 #endif
 
@@ -1318,6 +1344,9 @@ int MAIN(int argc, char **argv)
 #ifndef OPENSSL_NO_IDEA
        idea_set_encrypt_key(key16,&idea_ks);
 #endif
+#ifndef OPENSSL_NO_SEED
+       SEED_set_key(key16,&seed_ks);
+#endif
 #ifndef OPENSSL_NO_RC4
        RC4_set_key(&rc4_ks,16,key16);
 #endif
@@ -1361,6 +1390,7 @@ int MAIN(int argc, char **argv)
        c[D_CBC_DES][0]=count;
        c[D_EDE3_DES][0]=count/3;
        c[D_CBC_IDEA][0]=count;
+       c[D_CBC_SEED][0]=count;
        c[D_CBC_RC2][0]=count;
        c[D_CBC_RC5][0]=count;
        c[D_CBC_BF][0]=count;
@@ -1373,6 +1403,9 @@ int MAIN(int argc, char **argv)
        c[D_CBC_256_CML][0]=count;
        c[D_SHA256][0]=count;
        c[D_SHA512][0]=count;
+       c[D_IGE_128_AES][0]=count;
+       c[D_IGE_192_AES][0]=count;
+       c[D_IGE_256_AES][0]=count;
 
        for (i=1; i<SIZE_NUM; i++)
                {
@@ -1396,6 +1429,7 @@ int MAIN(int argc, char **argv)
                c[D_CBC_DES][i]=c[D_CBC_DES][i-1]*l0/l1;
                c[D_EDE3_DES][i]=c[D_EDE3_DES][i-1]*l0/l1;
                c[D_CBC_IDEA][i]=c[D_CBC_IDEA][i-1]*l0/l1;
+               c[D_CBC_SEED][i]=c[D_CBC_SEED][i-1]*l0/l1;
                c[D_CBC_RC2][i]=c[D_CBC_RC2][i-1]*l0/l1;
                c[D_CBC_RC5][i]=c[D_CBC_RC5][i-1]*l0/l1;
                c[D_CBC_BF][i]=c[D_CBC_BF][i-1]*l0/l1;
@@ -1406,6 +1440,9 @@ int MAIN(int argc, char **argv)
                c[D_CBC_128_CML][i]=c[D_CBC_128_CML][i-1]*l0/l1;
                c[D_CBC_192_CML][i]=c[D_CBC_192_CML][i-1]*l0/l1;
                c[D_CBC_256_CML][i]=c[D_CBC_256_CML][i-1]*l0/l1;
+               c[D_IGE_128_AES][i]=c[D_IGE_128_AES][i-1]*l0/l1;
+               c[D_IGE_192_AES][i]=c[D_IGE_192_AES][i-1]*l0/l1;
+               c[D_IGE_256_AES][i]=c[D_IGE_256_AES][i-1]*l0/l1;
                }
 #ifndef OPENSSL_NO_RSA
        rsa_c[R_RSA_512][0]=count/2000;
@@ -1799,6 +1836,48 @@ int MAIN(int argc, char **argv)
                        }
                }
 
+       if (doit[D_IGE_128_AES])
+               {
+               for (j=0; j<SIZE_NUM; j++)
+                       {
+                       print_message(names[D_IGE_128_AES],c[D_IGE_128_AES][j],lengths[j]);
+                       Time_F(START);
+                       for (count=0,run=1; COND(c[D_IGE_128_AES][j]); count++)
+                               AES_ige_encrypt(buf,buf2,
+                                       (unsigned long)lengths[j],&aes_ks1,
+                                       iv,AES_ENCRYPT);
+                       d=Time_F(STOP);
+                       print_result(D_IGE_128_AES,j,count,d);
+                       }
+               }
+       if (doit[D_IGE_192_AES])
+               {
+               for (j=0; j<SIZE_NUM; j++)
+                       {
+                       print_message(names[D_IGE_192_AES],c[D_IGE_192_AES][j],lengths[j]);
+                       Time_F(START);
+                       for (count=0,run=1; COND(c[D_IGE_192_AES][j]); count++)
+                               AES_ige_encrypt(buf,buf2,
+                                       (unsigned long)lengths[j],&aes_ks2,
+                                       iv,AES_ENCRYPT);
+                       d=Time_F(STOP);
+                       print_result(D_IGE_192_AES,j,count,d);
+                       }
+               }
+       if (doit[D_IGE_256_AES])
+               {
+               for (j=0; j<SIZE_NUM; j++)
+                       {
+                       print_message(names[D_IGE_256_AES],c[D_IGE_256_AES][j],lengths[j]);
+                       Time_F(START);
+                       for (count=0,run=1; COND(c[D_IGE_256_AES][j]); count++)
+                               AES_ige_encrypt(buf,buf2,
+                                       (unsigned long)lengths[j],&aes_ks3,
+                                       iv,AES_ENCRYPT);
+                       d=Time_F(STOP);
+                       print_result(D_IGE_256_AES,j,count,d);
+                       }
+               }
 #endif
 #ifndef OPENSSL_NO_CAMELLIA
        if (doit[D_CBC_128_CML])
@@ -1861,6 +1940,21 @@ int MAIN(int argc, char **argv)
                        }
                }
 #endif
+#ifndef OPENSSL_NO_SEED
+       if (doit[D_CBC_SEED])
+               {
+               for (j=0; j<SIZE_NUM; j++)
+                       {
+                       print_message(names[D_CBC_SEED],c[D_CBC_SEED][j],lengths[j]);
+                       Time_F(START);
+                       for (count=0,run=1; COND(c[D_CBC_SEED][j]); count++)
+                               SEED_cbc_encrypt(buf,buf,
+                                       (unsigned long)lengths[j],&seed_ks,iv,1);
+                       d=Time_F(STOP);
+                       print_result(D_CBC_SEED,j,count,d);
+                       }
+               }
+#endif
 #ifndef OPENSSL_NO_RC2
        if (doit[D_CBC_RC2])
                {
index 2082d06..45d7096 100644 (file)
 #include <openssl/aes.h>
 #include "aes_locl.h"
 
-/*
-static void hexdump(FILE *f,const char *title,const unsigned char *s,int l)
-    {
-    int n=0;
+#define N_WORDS (AES_BLOCK_SIZE / sizeof(unsigned long))
+typedef struct {
+        unsigned long data[N_WORDS];
+} aes_block_t;
 
-    fprintf(f,"%s",title);
-    for( ; n < l ; ++n)
-               {
-               if((n%16) == 0)
-                       fprintf(f,"\n%04x",n);
-               fprintf(f," %02x",s[n]);
-               }
-    fprintf(f,"\n");
-    }
-*/
+/* XXX: probably some better way to do this */
+#if defined(__i386__) || defined(__x86_64__)
+#define UNALIGNED_MEMOPS_ARE_FAST 1
+#else
+#define UNALIGNED_MEMOPS_ARE_FAST 0
+#endif
+
+#if UNALIGNED_MEMOPS_ARE_FAST
+#define load_block(d, s)        (d) = *(const aes_block_t *)(s)
+#define store_block(d, s)       *(aes_block_t *)(d) = (s)
+#else
+#define load_block(d, s)        memcpy((d).data, (s), AES_BLOCK_SIZE)
+#define store_block(d, s)       memcpy((d), (s).data, AES_BLOCK_SIZE)
+#endif
 
 /* N.B. The IV for this mode is _twice_ the block size */
 
@@ -77,68 +81,125 @@ void AES_ige_encrypt(const unsigned char *in, unsigned char *out,
                                         unsigned char *ivec, const int enc)
        {
        unsigned long n;
-       unsigned long len = length;
-       unsigned char tmp[AES_BLOCK_SIZE];
-       unsigned char tmp2[AES_BLOCK_SIZE];
-       unsigned char prev[AES_BLOCK_SIZE];
-       const unsigned char *iv = ivec;
-       const unsigned char *iv2 = ivec + AES_BLOCK_SIZE;
+       unsigned long len;
 
        OPENSSL_assert(in && out && key && ivec);
        OPENSSL_assert((AES_ENCRYPT == enc)||(AES_DECRYPT == enc));
        OPENSSL_assert((length%AES_BLOCK_SIZE) == 0);
 
+       len = length / AES_BLOCK_SIZE;
+
        if (AES_ENCRYPT == enc)
                {
-               /* XXX: Do a separate case for when in != out (strictly should
-                  check for overlap, too) */
-               while (len >= AES_BLOCK_SIZE)
+               if (in != out &&
+                   (UNALIGNED_MEMOPS_ARE_FAST || ((size_t)in|(size_t)out|(size_t)ivec)%sizeof(long)==0))
                        {
-                       /*                      hexdump(stdout, "in", in, AES_BLOCK_SIZE); */
-                       /*                      hexdump(stdout, "iv", iv, AES_BLOCK_SIZE); */
-                       for(n=0 ; n < AES_BLOCK_SIZE ; ++n)
-                               out[n] = in[n] ^ iv[n];
-                       /*                      hexdump(stdout, "in ^ iv", out, AES_BLOCK_SIZE); */
-                       AES_encrypt(out, out, key);
-                       /*                      hexdump(stdout,"enc", out, AES_BLOCK_SIZE); */
-                       /*                      hexdump(stdout,"iv2", iv2, AES_BLOCK_SIZE); */
-                       for(n=0 ; n < AES_BLOCK_SIZE ; ++n)
-                               out[n] ^= iv2[n];
-                       /*                      hexdump(stdout,"out", out, AES_BLOCK_SIZE); */
-                       iv = out;
-                       memcpy(prev, in, AES_BLOCK_SIZE);
-                       iv2 = prev;
-                       len -= AES_BLOCK_SIZE;
-                       in += AES_BLOCK_SIZE;
-                       out += AES_BLOCK_SIZE;
+                       aes_block_t *ivp = (aes_block_t *)ivec;
+                       aes_block_t *iv2p = (aes_block_t *)(ivec + AES_BLOCK_SIZE);
+
+                       while (len)
+                               {
+                               aes_block_t *inp = (aes_block_t *)in;
+                               aes_block_t *outp = (aes_block_t *)out;
+
+                               for(n=0 ; n < N_WORDS; ++n)
+                                       outp->data[n] = inp->data[n] ^ ivp->data[n];
+                               AES_encrypt((unsigned char *)outp->data, (unsigned char *)outp->data, key);
+                               for(n=0 ; n < N_WORDS; ++n)
+                                       outp->data[n] ^= iv2p->data[n];
+                               ivp = outp;
+                               iv2p = inp;
+                               --len;
+                               in += AES_BLOCK_SIZE;
+                               out += AES_BLOCK_SIZE;
+                               }
+                       memcpy(ivec, ivp->data, AES_BLOCK_SIZE);
+                       memcpy(ivec + AES_BLOCK_SIZE, iv2p->data, AES_BLOCK_SIZE);
+                       }
+               else
+                       {
+                       aes_block_t tmp, tmp2;
+                       aes_block_t iv;
+                       aes_block_t iv2;
+
+                       load_block(iv, ivec);
+                       load_block(iv2, ivec + AES_BLOCK_SIZE);
+
+                       while (len)
+                               {
+                               load_block(tmp, in);
+                               for(n=0 ; n < N_WORDS; ++n)
+                                       tmp2.data[n] = tmp.data[n] ^ iv.data[n];
+                               AES_encrypt((unsigned char *)tmp2.data, (unsigned char *)tmp2.data, key);
+                               for(n=0 ; n < N_WORDS; ++n)
+                                       tmp2.data[n] ^= iv2.data[n];
+                               store_block(out, tmp2);
+                               iv = tmp2;
+                               iv2 = tmp;
+                               --len;
+                               in += AES_BLOCK_SIZE;
+                               out += AES_BLOCK_SIZE;
+                               }
+                       memcpy(ivec, iv.data, AES_BLOCK_SIZE);
+                       memcpy(ivec + AES_BLOCK_SIZE, iv2.data, AES_BLOCK_SIZE);
                        }
-               memcpy(ivec, iv, AES_BLOCK_SIZE);
-               memcpy(ivec + AES_BLOCK_SIZE, iv2, AES_BLOCK_SIZE);
                }
        else
                {
-               while (len >= AES_BLOCK_SIZE)
+               if (in != out &&
+                   (UNALIGNED_MEMOPS_ARE_FAST || ((size_t)in|(size_t)out|(size_t)ivec)%sizeof(long)==0))
                        {
-                       memcpy(tmp, in, AES_BLOCK_SIZE);
-                       memcpy(tmp2, in, AES_BLOCK_SIZE);
-                       /*                      hexdump(stdout, "in", in, AES_BLOCK_SIZE); */
-                       /*                      hexdump(stdout, "iv2", iv2, AES_BLOCK_SIZE); */
-                       for(n=0 ; n < AES_BLOCK_SIZE ; ++n)
-                               tmp[n] ^= iv2[n];
-                       /*                      hexdump(stdout, "in ^ iv2", tmp, AES_BLOCK_SIZE); */
-                       AES_decrypt(tmp, out, key);
-                       /*                      hexdump(stdout, "dec", out, AES_BLOCK_SIZE); */
-                       /*                      hexdump(stdout, "iv", ivec, AES_BLOCK_SIZE); */
-                       for(n=0 ; n < AES_BLOCK_SIZE ; ++n)
-                               out[n] ^= ivec[n];
-                       /*                      hexdump(stdout, "out", out, AES_BLOCK_SIZE); */
-                       memcpy(ivec, tmp2, AES_BLOCK_SIZE);
-                       iv2 = out;
-                       len -= AES_BLOCK_SIZE;
-                       in += AES_BLOCK_SIZE;
-                       out += AES_BLOCK_SIZE;
+                       aes_block_t *ivp = (aes_block_t *)ivec;
+                       aes_block_t *iv2p = (aes_block_t *)(ivec + AES_BLOCK_SIZE);
+
+                       while (len)
+                               {
+                               aes_block_t tmp;
+                               aes_block_t *inp = (aes_block_t *)in;
+                               aes_block_t *outp = (aes_block_t *)out;
+
+                               for(n=0 ; n < N_WORDS; ++n)
+                                       tmp.data[n] = inp->data[n] ^ iv2p->data[n];
+                               AES_decrypt((unsigned char *)tmp.data, (unsigned char *)outp->data, key);
+                               for(n=0 ; n < N_WORDS; ++n)
+                                       outp->data[n] ^= ivp->data[n];
+                               ivp = inp;
+                               iv2p = outp;
+                               --len;
+                               in += AES_BLOCK_SIZE;
+                               out += AES_BLOCK_SIZE;
+                               }
+                       memcpy(ivec, ivp->data, AES_BLOCK_SIZE);
+                       memcpy(ivec + AES_BLOCK_SIZE, iv2p->data, AES_BLOCK_SIZE);
+                       }
+               else
+                       {
+                       aes_block_t tmp, tmp2;
+                       aes_block_t iv;
+                       aes_block_t iv2;
+
+                       load_block(iv, ivec);
+                       load_block(iv2, ivec + AES_BLOCK_SIZE);
+
+                       while (len)
+                               {
+                               load_block(tmp, in);
+                               tmp2 = tmp;
+                               for(n=0 ; n < N_WORDS; ++n)
+                                       tmp.data[n] ^= iv2.data[n];
+                               AES_decrypt((unsigned char *)tmp.data, (unsigned char *)tmp.data, key);
+                               for(n=0 ; n < N_WORDS; ++n)
+                                       tmp.data[n] ^= iv.data[n];
+                               store_block(out, tmp);
+                               iv = tmp2;
+                               iv2 = tmp;
+                               --len;
+                               in += AES_BLOCK_SIZE;
+                               out += AES_BLOCK_SIZE;
+                               }
+                       memcpy(ivec, iv.data, AES_BLOCK_SIZE);
+                       memcpy(ivec + AES_BLOCK_SIZE, iv2.data, AES_BLOCK_SIZE);
                        }
-               memcpy(ivec + AES_BLOCK_SIZE, iv2, AES_BLOCK_SIZE);
                }
        }
 
@@ -177,17 +238,11 @@ void AES_bi_ige_encrypt(const unsigned char *in, unsigned char *out,
                iv2 = ivec + AES_BLOCK_SIZE;
                while (len >= AES_BLOCK_SIZE)
                        {
-                       /*                      hexdump(stdout, "in", in, AES_BLOCK_SIZE); */
-                       /*                      hexdump(stdout, "iv", iv, AES_BLOCK_SIZE); */
                        for(n=0 ; n < AES_BLOCK_SIZE ; ++n)
                                out[n] = in[n] ^ iv[n];
-                       /*                      hexdump(stdout, "in ^ iv", out, AES_BLOCK_SIZE); */
                        AES_encrypt(out, out, key);
-                       /*                      hexdump(stdout,"enc", out, AES_BLOCK_SIZE); */
-                       /*                      hexdump(stdout,"iv2", iv2, AES_BLOCK_SIZE); */
                        for(n=0 ; n < AES_BLOCK_SIZE ; ++n)
                                out[n] ^= iv2[n];
-                       /*                      hexdump(stdout,"out", out, AES_BLOCK_SIZE); */
                        iv = out;
                        memcpy(prev, in, AES_BLOCK_SIZE);
                        iv2 = prev;
@@ -203,8 +258,6 @@ void AES_bi_ige_encrypt(const unsigned char *in, unsigned char *out,
                while(len >= AES_BLOCK_SIZE)
                        {
                        out -= AES_BLOCK_SIZE;
-                       /*                      hexdump(stdout, "intermediate", out, AES_BLOCK_SIZE); */
-                       /*                      hexdump(stdout, "iv", iv, AES_BLOCK_SIZE); */
                        /* XXX: reduce copies by alternating between buffers */
                        memcpy(tmp, out, AES_BLOCK_SIZE);
                        for(n=0 ; n < AES_BLOCK_SIZE ; ++n)
@@ -235,17 +288,11 @@ void AES_bi_ige_encrypt(const unsigned char *in, unsigned char *out,
                        out -= AES_BLOCK_SIZE;
                        memcpy(tmp, in, AES_BLOCK_SIZE);
                        memcpy(tmp2, in, AES_BLOCK_SIZE);
-                       /*                      hexdump(stdout, "in", in, AES_BLOCK_SIZE); */
-                       /*                      hexdump(stdout, "iv2", iv2, AES_BLOCK_SIZE); */
                        for(n=0 ; n < AES_BLOCK_SIZE ; ++n)
                                tmp[n] ^= iv2[n];
-                       /*                      hexdump(stdout, "in ^ iv2", tmp, AES_BLOCK_SIZE); */
                        AES_decrypt(tmp, out, key);
-                       /*                      hexdump(stdout, "dec", out, AES_BLOCK_SIZE); */
-                       /*                      hexdump(stdout, "iv", iv, AES_BLOCK_SIZE); */
                        for(n=0 ; n < AES_BLOCK_SIZE ; ++n)
                                out[n] ^= iv[n];
-                       /*                      hexdump(stdout, "out", out, AES_BLOCK_SIZE); */
                        memcpy(tmp3, tmp2, AES_BLOCK_SIZE);
                        iv = tmp3;
                        iv2 = out;
@@ -260,17 +307,11 @@ void AES_bi_ige_encrypt(const unsigned char *in, unsigned char *out,
                        {
                        memcpy(tmp, out, AES_BLOCK_SIZE);
                        memcpy(tmp2, out, AES_BLOCK_SIZE);
-                       /*                      hexdump(stdout, "intermediate", out, AES_BLOCK_SIZE); */
-                       /*                      hexdump(stdout, "iv2", iv2, AES_BLOCK_SIZE); */
                        for(n=0 ; n < AES_BLOCK_SIZE ; ++n)
                                tmp[n] ^= iv2[n];
-                       /*                      hexdump(stdout, "out ^ iv2", tmp, AES_BLOCK_SIZE); */
                        AES_decrypt(tmp, out, key);
-                       /*                      hexdump(stdout, "dec", out, AES_BLOCK_SIZE); */
-                       /*                      hexdump(stdout, "iv", ivec, AES_BLOCK_SIZE); */
                        for(n=0 ; n < AES_BLOCK_SIZE ; ++n)
                                out[n] ^= iv[n];
-                       /*                      hexdump(stdout, "out", out, AES_BLOCK_SIZE); */
                        memcpy(tmp3, tmp2, AES_BLOCK_SIZE);
                        iv = tmp3;
                        iv2 = out;
@@ -278,6 +319,5 @@ void AES_bi_ige_encrypt(const unsigned char *in, unsigned char *out,
                        in += AES_BLOCK_SIZE;
                        out += AES_BLOCK_SIZE;
                        }
-
                }
        }
index 30f1eec..f15131e 100644 (file)
@@ -322,6 +322,17 @@ typedef struct ASN1_VALUE_st ASN1_VALUE;
 #define I2D_OF(type) int (*)(type *,unsigned char **)
 #define I2D_OF_const(type) int (*)(const type *,unsigned char **)
 
+#define CHECKED_D2I_OF(type, d2i) \
+    ((d2i_of_void*) (1 ? d2i : ((D2I_OF(type))0)))
+#define CHECKED_I2D_OF(type, i2d) \
+    ((i2d_of_void*) (1 ? i2d : ((I2D_OF(type))0)))
+#define CHECKED_NEW_OF(type, xnew) \
+    ((void *(*)(void)) (1 ? xnew : ((type *(*)(void))0)))
+#define CHECKED_PTR_OF(type, p) \
+    ((void*) (1 ? p : (type*)0))
+#define CHECKED_PPTR_OF(type, p) \
+    ((void**) (1 ? p : (type**)0))
+
 #define TYPEDEF_D2I_OF(type) typedef type *d2i_of_##type(type **,const unsigned char **,long)
 #define TYPEDEF_I2D_OF(type) typedef int i2d_of_##type(type *,unsigned char **)
 #define TYPEDEF_D2I2D_OF(type) TYPEDEF_D2I_OF(type); TYPEDEF_I2D_OF(type)
@@ -902,23 +913,41 @@ int ASN1_object_size(int constructed, int length, int tag);
 
 /* Used to implement other functions */
 void *ASN1_dup(i2d_of_void *i2d, d2i_of_void *d2i, char *x);
+
 #define ASN1_dup_of(type,i2d,d2i,x) \
-       ((type *(*)(I2D_OF(type),D2I_OF(type),type *))openssl_fcast(ASN1_dup))(i2d,d2i,x)
+    ((type*)ASN1_dup(CHECKED_I2D_OF(type, i2d), \
+                    CHECKED_D2I_OF(type, d2i), \
+                    CHECKED_PTR_OF(type, x)))
+
 #define ASN1_dup_of_const(type,i2d,d2i,x) \
-       ((type *(*)(I2D_OF_const(type),D2I_OF(type),type *))openssl_fcast(ASN1_dup))(i2d,d2i,x)
+    ((type*)ASN1_dup(CHECKED_I2D_OF(const type, i2d), \
+                    CHECKED_D2I_OF(type, d2i), \
+                    CHECKED_PTR_OF(const type, x)))
 
 void *ASN1_item_dup(const ASN1_ITEM *it, void *x);
 
 #ifndef OPENSSL_NO_FP_API
 void *ASN1_d2i_fp(void *(*xnew)(void), d2i_of_void *d2i, FILE *in, void **x);
+
 #define ASN1_d2i_fp_of(type,xnew,d2i,in,x) \
-       ((type *(*)(type *(*)(void),D2I_OF(type),FILE *,type **))openssl_fcast(ASN1_d2i_fp))(xnew,d2i,in,x)
+    ((type*)ASN1_d2i_fp(CHECKED_NEW_OF(type, xnew), \
+                       CHECKED_D2I_OF(type, d2i), \
+                       in, \
+                       CHECKED_PPTR_OF(type, x)))
+
 void *ASN1_item_d2i_fp(const ASN1_ITEM *it, FILE *in, void *x);
 int ASN1_i2d_fp(i2d_of_void *i2d,FILE *out,void *x);
+
 #define ASN1_i2d_fp_of(type,i2d,out,x) \
-       ((int (*)(I2D_OF(type),FILE *,type *))openssl_fcast(ASN1_i2d_fp))(i2d,out,x)
+    (ASN1_i2d_fp(CHECKED_I2D_OF(type, i2d), \
+                out, \
+                CHECKED_PTR_OF(type, x)))
+
 #define ASN1_i2d_fp_of_const(type,i2d,out,x) \
-       ((int (*)(I2D_OF_const(type),FILE *,type *))openssl_fcast(ASN1_i2d_fp))(i2d,out,x)
+    (ASN1_i2d_fp(CHECKED_I2D_OF(const type, i2d), \
+                out, \
+                CHECKED_PTR_OF(const type, x)))
+
 int ASN1_item_i2d_fp(const ASN1_ITEM *it, FILE *out, void *x);
 int ASN1_STRING_print_ex_fp(FILE *fp, ASN1_STRING *str, unsigned long flags);
 #endif
@@ -927,14 +956,26 @@ int ASN1_STRING_to_UTF8(unsigned char **out, ASN1_STRING *in);
 
 #ifndef OPENSSL_NO_BIO
 void *ASN1_d2i_bio(void *(*xnew)(void), d2i_of_void *d2i, BIO *in, void **x);
+
 #define ASN1_d2i_bio_of(type,xnew,d2i,in,x) \
-       ((type *(*)(type *(*)(void),D2I_OF(type),BIO *,type **))openssl_fcast(ASN1_d2i_bio))(xnew,d2i,in,x)
+    ((type*)ASN1_d2i_bio( CHECKED_NEW_OF(type, xnew), \
+                         CHECKED_D2I_OF(type, d2i), \
+                         in, \
+                         CHECKED_PPTR_OF(type, x)))
+
 void *ASN1_item_d2i_bio(const ASN1_ITEM *it, BIO *in, void *x);
 int ASN1_i2d_bio(i2d_of_void *i2d,BIO *out, unsigned char *x);
+
 #define ASN1_i2d_bio_of(type,i2d,out,x) \
-       ((int (*)(I2D_OF(type),BIO *,type *))openssl_fcast(ASN1_i2d_bio))(i2d,out,x)
+    (ASN1_i2d_bio(CHECKED_I2D_OF(type, i2d), \
+                 out, \
+                 CHECKED_PTR_OF(type, x)))
+
 #define ASN1_i2d_bio_of_const(type,i2d,out,x) \
-       ((int (*)(I2D_OF_const(type),BIO *,const type *))openssl_fcast(ASN1_i2d_bio))(i2d,out,x)
+    (ASN1_i2d_bio(CHECKED_I2D_OF(const type, i2d), \
+                 out, \
+                 CHECKED_PTR_OF(const type, x)))
+
 int ASN1_item_i2d_bio(const ASN1_ITEM *it, BIO *out, void *x);
 int ASN1_UTCTIME_print(BIO *fp,ASN1_UTCTIME *a);
 int ASN1_GENERALIZEDTIME_print(BIO *fp,ASN1_GENERALIZEDTIME *a);
@@ -977,8 +1018,12 @@ void *ASN1_unpack_string(ASN1_STRING *oct, d2i_of_void *d2i);
 void *ASN1_item_unpack(ASN1_STRING *oct, const ASN1_ITEM *it);
 ASN1_STRING *ASN1_pack_string(void *obj, i2d_of_void *i2d,
                              ASN1_OCTET_STRING **oct);
+
 #define ASN1_pack_string_of(type,obj,i2d,oct) \
-       ((ASN1_STRING *(*)(type *,I2D_OF(type),ASN1_OCTET_STRING **))openssl_fcast(ASN1_pack_string))(obj,i2d,oct)
+    (ASN1_pack_string(CHECKED_PTR_OF(type, obj), \
+                     CHECKED_I2D_OF(type, i2d), \
+                     oct))
+
 ASN1_STRING *ASN1_item_pack(void *obj, const ASN1_ITEM *it, ASN1_OCTET_STRING **oct);
 
 void ASN1_STRING_set_default_mask(unsigned long mask);
index 72cc121..9132350 100644 (file)
@@ -149,7 +149,7 @@ static int do_create(char *value, char *name)
                if (lntmp == NULL)
                        return 0;
                memcpy(lntmp, ln, p - ln);
-               lntmp[p - ln + 1] = 0;
+               lntmp[p - ln] = 0;
                oid = OBJ_nid2obj(nid);
                oid->ln = lntmp;
                }
index c779a9b..5557e06 100644 (file)
@@ -244,7 +244,7 @@ get_next:
                                }
                        }
                }
-       if(!(cflag & X509_FLAG_NO_ATTRIBUTES))
+       if(!(cflag & X509_FLAG_NO_EXTENSIONS))
                {
                exts = X509_REQ_get_extensions(x);
                if(exts)
@@ -262,7 +262,7 @@ get_next:
                                j=X509_EXTENSION_get_critical(ex);
                                if (BIO_printf(bp,": %s\n",j?"critical":"") <= 0)
                                        goto err;
-                               if(!X509V3_EXT_print(bp, ex, 0, 16))
+                               if(!X509V3_EXT_print(bp, ex, cflag, 16))
                                        {
                                        BIO_printf(bp, "%16s", "");
                                        M_ASN1_OCTET_STRING_print(bp,ex->value);
index 66d229b..c4a3abe 100644 (file)
@@ -130,7 +130,7 @@ ASN1_VALUE *ASN1_item_d2i(ASN1_VALUE **pval,
        ASN1_VALUE *ptmpval = NULL;
        if (!pval)
                pval = &ptmpval;
-       asn1_tlc_clear(&c);
+       c.valid = 0;
        if (ASN1_item_ex_d2i(pval, in, len, it, -1, 0, 0, &c) > 0) 
                return *pval;
        return NULL;
@@ -140,7 +140,7 @@ int ASN1_template_d2i(ASN1_VALUE **pval,
                const unsigned char **in, long len, const ASN1_TEMPLATE *tt)
        {
        ASN1_TLC c;
-       asn1_tlc_clear(&c);
+       c.valid = 0;
        return asn1_template_ex_d2i(pval, in, len, tt, 0, &c);
        }
 
index 25c94aa..ed892e2 100644 (file)
@@ -494,7 +494,7 @@ static int asn1_set_seq_out(STACK_OF(ASN1_VALUE) *sk, unsigned char **out,
                {
                for (i = 0, tder = derlst; i < sk_ASN1_VALUE_num(sk);
                                                        i++, tder++)
-                       sk_ASN1_VALUE_set(sk, i, tder->field);
+                       (void)sk_ASN1_VALUE_set(sk, i, tder->field);
                }
        OPENSSL_free(derlst);
        OPENSSL_free(tmpdat);
index b99f8fc..70d56a6 100644 (file)
@@ -84,7 +84,7 @@ static int crl_inf_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it)
                 * would affect the output of X509_CRL_print().
                 */
                case ASN1_OP_D2I_POST:
-               sk_X509_REVOKED_set_cmp_func(a->revoked,X509_REVOKED_cmp);
+               (void)sk_X509_REVOKED_set_cmp_func(a->revoked,X509_REVOKED_cmp);
                break;
        }
        return 1;
index 681e5d1..04380ab 100644 (file)
@@ -160,40 +160,40 @@ static int x509_name_ex_d2i(ASN1_VALUE **val, const unsigned char **in, long len
                                        int tag, int aclass, char opt, ASN1_TLC *ctx)
 {
        const unsigned char *p = *in, *q;
-       STACK *intname = NULL, **intname_pp = &intname;
+       union { STACK *s; ASN1_VALUE *a; } intname = {NULL};
+       union { X509_NAME *x; ASN1_VALUE *a; } nm = {NULL};
        int i, j, ret;
-       X509_NAME *nm = NULL, **nm_pp = &nm;
        STACK_OF(X509_NAME_ENTRY) *entries;
        X509_NAME_ENTRY *entry;
        q = p;
 
        /* Get internal representation of Name */
-       ret = ASN1_item_ex_d2i((ASN1_VALUE **)intname_pp,
+       ret = ASN1_item_ex_d2i(&intname.a,
                               &p, len, ASN1_ITEM_rptr(X509_NAME_INTERNAL),
                               tag, aclass, opt, ctx);
        
        if(ret <= 0) return ret;
 
        if(*val) x509_name_ex_free(val, NULL);
-       if(!x509_name_ex_new((ASN1_VALUE **)nm_pp, NULL)) goto err;
+       if(!x509_name_ex_new(&nm.a, NULL)) goto err;
        /* We've decoded it: now cache encoding */
-       if(!BUF_MEM_grow(nm->bytes, p - q)) goto err;
-       memcpy(nm->bytes->data, q, p - q);
+       if(!BUF_MEM_grow(nm.x->bytes, p - q)) goto err;
+       memcpy(nm.x->bytes->data, q, p - q);
 
        /* Convert internal representation to X509_NAME structure */
-       for(i = 0; i < sk_num(intname); i++) {
-               entries = (STACK_OF(X509_NAME_ENTRY) *)sk_value(intname, i);
+       for(i = 0; i < sk_num(intname.s); i++) {
+               entries = (STACK_OF(X509_NAME_ENTRY) *)sk_value(intname.s, i);
                for(j = 0; j < sk_X509_NAME_ENTRY_num(entries); j++) {
                        entry = sk_X509_NAME_ENTRY_value(entries, j);
                        entry->set = i;
-                       if(!sk_X509_NAME_ENTRY_push(nm->entries, entry))
+                       if(!sk_X509_NAME_ENTRY_push(nm.x->entries, entry))
                                goto err;
                }
                sk_X509_NAME_ENTRY_free(entries);
        }
-       sk_free(intname);
-       nm->modified = 0;
-       *val = (ASN1_VALUE *)nm;
+       sk_free(intname.s);
+       nm.x->modified = 0;
+       *val = nm.a;
        *in = p;
        return ret;
        err:
@@ -219,35 +219,35 @@ static int x509_name_ex_i2d(ASN1_VALUE **val, unsigned char **out, const ASN1_IT
 
 static int x509_name_encode(X509_NAME *a)
 {
-       STACK *intname = NULL, **intname_pp = &intname;
+       union { STACK *s; ASN1_VALUE *a; } intname = {NULL};
        int len;
        unsigned char *p;
        STACK_OF(X509_NAME_ENTRY) *entries = NULL;
        X509_NAME_ENTRY *entry;
        int i, set = -1;
-       intname = sk_new_null();
-       if(!intname) goto memerr;
+       intname.s = sk_new_null();
+       if(!intname.s) goto memerr;
        for(i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) {
                entry = sk_X509_NAME_ENTRY_value(a->entries, i);
                if(entry->set != set) {
                        entries = sk_X509_NAME_ENTRY_new_null();
                        if(!entries) goto memerr;
-                       if(!sk_push(intname, (char *)entries)) goto memerr;
+                       if(!sk_push(intname.s, (char *)entries)) goto memerr;
                        set = entry->set;
                }
                if(!sk_X509_NAME_ENTRY_push(entries, entry)) goto memerr;
        }
-       len = ASN1_item_ex_i2d((ASN1_VALUE **)intname_pp, NULL,
+       len = ASN1_item_ex_i2d(&intname.a, NULL,
                               ASN1_ITEM_rptr(X509_NAME_INTERNAL), -1, -1);
        if (!BUF_MEM_grow(a->bytes,len)) goto memerr;
        p=(unsigned char *)a->bytes->data;
-       ASN1_item_ex_i2d((ASN1_VALUE **)intname_pp,
+       ASN1_item_ex_i2d(&intname.a,
                         &p, ASN1_ITEM_rptr(X509_NAME_INTERNAL), -1, -1);
-       sk_pop_free(intname, sk_internal_free);
+       sk_pop_free(intname.s, sk_internal_free);
        a->modified = 0;
        return len;
        memerr:
-       sk_pop_free(intname, sk_internal_free);
+       sk_pop_free(intname.s, sk_internal_free);
        ASN1err(ASN1_F_X509_NAME_ENCODE, ERR_R_MALLOC_FAILURE);
        return -1;
 }
index 4857cfe..3a87b0e 100644 (file)
@@ -79,7 +79,7 @@
 #include <openssl/bn.h>         /* To get BN_LLONG properly defined */
 #include <openssl/bio.h>
 
-#ifdef BN_LLONG
+#if defined(BN_LLONG) || defined(SIXTY_FOUR_BIT)
 # ifndef HAVE_LONG_LONG
 #  define HAVE_LONG_LONG 1
 # endif
 
 #if HAVE_LONG_LONG
 # if defined(OPENSSL_SYS_WIN32) && !defined(__GNUC__)
-# define LLONG _int64
+# define LLONG __int64
 # else
 # define LLONG long long
 # endif
index 4b3860b..cd78de1 100644 (file)
@@ -456,9 +456,6 @@ int BIO_sock_init(void)
                {
                int err;
          
-#ifdef SIGINT
-               signal(SIGINT,(void (*)(int))BIO_sock_cleanup);
-#endif
                wsa_init_done=1;
                memset(&wsa_state,0,sizeof(wsa_state));
                if (WSAStartup(0x0101,&wsa_state)!=0)
@@ -484,11 +481,6 @@ int BIO_sock_init(void)
 
     if (!wsa_init_done)
     {
-   
-# ifdef SIGINT
-        signal(SIGINT,(void (*)(int))BIO_sock_cleanup);
-# endif
-
         wsa_init_done=1;
         wVerReq = MAKEWORD( 2, 0 );
         err = WSAStartup(wVerReq,&wsaData);
@@ -511,7 +503,7 @@ void BIO_sock_cleanup(void)
                {
                wsa_init_done=0;
 #ifndef OPENSSL_SYS_WINCE
-               WSACancelBlockingCall();
+               WSACancelBlockingCall();        /* Winsock 1.1 specific */
 #endif
                WSACleanup();
                }
index 2c9e8a7..0362bb9 100644 (file)
@@ -129,8 +129,8 @@ extern "C" {
 /* dgram BIO stuff */
 #define BIO_CTRL_DGRAM_CONNECT       31  /* BIO dgram special */
 #define BIO_CTRL_DGRAM_SET_CONNECTED 32  /* allow for an externally
-                                                                                 * connected socket to be
-                                                                                 * passed in */ 
+                                         * connected socket to be
+                                         * passed in */ 
 #define BIO_CTRL_DGRAM_SET_RECV_TIMEOUT 33 /* setsockopt, essentially */
 #define BIO_CTRL_DGRAM_GET_RECV_TIMEOUT 34 /* getsockopt, essentially */
 #define BIO_CTRL_DGRAM_SET_SEND_TIMEOUT 35 /* setsockopt, essentially */
@@ -146,14 +146,14 @@ extern "C" {
 #define BIO_CTRL_DGRAM_QUERY_MTU          40 /* as kernel for current MTU */
 #define BIO_CTRL_DGRAM_GET_MTU            41 /* get cached value for MTU */
 #define BIO_CTRL_DGRAM_SET_MTU            42 /* set cached value for
-                                                                                         * MTU. want to use this
-                                              * if asking the kernel
-                                              * fails */
+                                             * MTU. want to use this
+                                             * if asking the kernel
+                                             * fails */
 
 #define BIO_CTRL_DGRAM_MTU_EXCEEDED       43 /* check whether the MTU
-                                                                                         * was exceed in the
-                                                                                         * previous write
-                                                                                         * operation */
+                                             * was exceed in the
+                                             * previous write
+                                             * operation */
 
 #define BIO_CTRL_DGRAM_SET_PEER           44 /* Destination for the data */
 
index 95c5d64..df6eea2 100644 (file)
@@ -245,8 +245,18 @@ extern "C" {
 
 #define BN_FLG_MALLOCED                0x01
 #define BN_FLG_STATIC_DATA     0x02
-#define BN_FLG_EXP_CONSTTIME   0x04 /* avoid leaking exponent information through timings
-                                     * (BN_mod_exp_mont() will call BN_mod_exp_mont_consttime) */
+#define BN_FLG_CONSTTIME       0x04 /* avoid leaking exponent information through timing,
+                                      * BN_mod_exp_mont() will call BN_mod_exp_mont_consttime,
+                                      * BN_div() will call BN_div_no_branch,
+                                      * BN_mod_inverse() will call BN_mod_inverse_no_branch.
+                                      */
+
+#ifndef OPENSSL_NO_DEPRECATED
+#define BN_FLG_EXP_CONSTTIME BN_FLG_CONSTTIME /* deprecated name for the flag */
+                                      /* avoid leaking exponent information through timings
+                                      * (BN_mod_exp_mont() will call BN_mod_exp_mont_consttime) */
+#endif
+
 #ifndef OPENSSL_NO_DEPRECATED
 #define BN_FLG_FREE            0x8000  /* used for debuging */
 #endif
@@ -534,7 +544,7 @@ BN_MONT_CTX *BN_MONT_CTX_set_locked(BN_MONT_CTX **pmont, int lock,
 #define        BN_BLINDING_NO_UPDATE   0x00000001
 #define        BN_BLINDING_NO_RECREATE 0x00000002
 
-BN_BLINDING *BN_BLINDING_new(const BIGNUM *A, const BIGNUM *Ai, BIGNUM *mod);
+BN_BLINDING *BN_BLINDING_new(const BIGNUM *A, const BIGNUM *Ai, /* const */ BIGNUM *mod);
 void BN_BLINDING_free(BN_BLINDING *b);
 int BN_BLINDING_update(BN_BLINDING *b,BN_CTX *ctx);
 int BN_BLINDING_convert(BIGNUM *n, BN_BLINDING *b, BN_CTX *ctx);
@@ -546,7 +556,7 @@ void BN_BLINDING_set_thread_id(BN_BLINDING *, unsigned long);
 unsigned long BN_BLINDING_get_flags(const BN_BLINDING *);
 void BN_BLINDING_set_flags(BN_BLINDING *, unsigned long);
 BN_BLINDING *BN_BLINDING_create_param(BN_BLINDING *b,
-       const BIGNUM *e, BIGNUM *m, BN_CTX *ctx,
+       const BIGNUM *e, /* const */ BIGNUM *m, BN_CTX *ctx,
        int (*bn_mod_exp)(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
                          const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx),
        BN_MONT_CTX *m_ctx);
@@ -775,6 +785,7 @@ void ERR_load_BN_strings(void);
 #define BN_F_BN_CTX_NEW                                         106
 #define BN_F_BN_CTX_START                               129
 #define BN_F_BN_DIV                                     107
+#define BN_F_BN_DIV_NO_BRANCH                           138
 #define BN_F_BN_DIV_RECP                                130
 #define BN_F_BN_EXP                                     123
 #define BN_F_BN_EXPAND2                                         108
@@ -793,6 +804,7 @@ void ERR_load_BN_strings(void);
 #define BN_F_BN_MOD_EXP_RECP                            125
 #define BN_F_BN_MOD_EXP_SIMPLE                          126
 #define BN_F_BN_MOD_INVERSE                             110
+#define BN_F_BN_MOD_INVERSE_NO_BRANCH                   139
 #define BN_F_BN_MOD_LSHIFT_QUICK                        119
 #define BN_F_BN_MOD_MUL_RECIPROCAL                      111
 #define BN_F_BN_MOD_SQRT                                121
index ca22d4f..c11fb4c 100644 (file)
@@ -131,7 +131,7 @@ struct bn_blinding_st
                          BN_MONT_CTX *m_ctx);
        };
 
-BN_BLINDING *BN_BLINDING_new(const BIGNUM *A, const BIGNUM *Ai, BIGNUM *mod)
+BN_BLINDING *BN_BLINDING_new(const BIGNUM *A, const BIGNUM *Ai, /* const */ BIGNUM *mod)
        {
        BN_BLINDING *ret=NULL;
 
@@ -151,7 +151,12 @@ BN_BLINDING *BN_BLINDING_new(const BIGNUM *A, const BIGNUM *Ai, BIGNUM *mod)
                {
                if ((ret->Ai = BN_dup(Ai)) == NULL) goto err;
                }
-       ret->mod = mod;
+
+       /* save a copy of mod in the BN_BLINDING structure */
+       if ((ret->mod = BN_dup(mod)) == NULL) goto err;
+       if (BN_get_flags(mod, BN_FLG_CONSTTIME) != 0)
+               BN_set_flags(ret->mod, BN_FLG_CONSTTIME);
+
        ret->counter = BN_BLINDING_COUNTER;
        return(ret);
 err:
@@ -167,6 +172,7 @@ void BN_BLINDING_free(BN_BLINDING *r)
        if (r->A  != NULL) BN_free(r->A );
        if (r->Ai != NULL) BN_free(r->Ai);
        if (r->e  != NULL) BN_free(r->e );
+       if (r->mod != NULL) BN_free(r->mod); 
        OPENSSL_free(r);
        }
 
@@ -278,7 +284,7 @@ void BN_BLINDING_set_flags(BN_BLINDING *b, unsigned long flags)
        }
 
 BN_BLINDING *BN_BLINDING_create_param(BN_BLINDING *b,
-       const BIGNUM *e, BIGNUM *m, BN_CTX *ctx,
+       const BIGNUM *e, /* const */ BIGNUM *m, BN_CTX *ctx,
        int (*bn_mod_exp)(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
                          const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx),
        BN_MONT_CTX *m_ctx)
index 2857f44..8655eb1 100644 (file)
@@ -169,13 +169,15 @@ int BN_div(BIGNUM *dv, BIGNUM *rem, const BIGNUM *m, const BIGNUM *d,
 #endif /* OPENSSL_NO_ASM */
 
 
-/* BN_div computes  dv := num / divisor,  rounding towards zero, and sets up
- * rm  such that  dv*divisor + rm = num  holds.
+/* BN_div[_no_branch] computes  dv := num / divisor,  rounding towards
+ * zero, and sets up rm  such that  dv*divisor + rm = num  holds.
  * Thus:
  *     dv->neg == num->neg ^ divisor->neg  (unless the result is zero)
  *     rm->neg == num->neg                 (unless the remainder is zero)
  * If 'dv' or 'rm' is NULL, the respective value is not returned.
  */
+static int BN_div_no_branch(BIGNUM *dv, BIGNUM *rm, const BIGNUM *num,
+        const BIGNUM *divisor, BN_CTX *ctx);
 int BN_div(BIGNUM *dv, BIGNUM *rm, const BIGNUM *num, const BIGNUM *divisor,
           BN_CTX *ctx)
        {
@@ -185,6 +187,11 @@ int BN_div(BIGNUM *dv, BIGNUM *rm, const BIGNUM *num, const BIGNUM *divisor,
        BN_ULONG d0,d1;
        int num_n,div_n;
 
+       if ((BN_get_flags(num, BN_FLG_CONSTTIME) != 0) || (BN_get_flags(divisor, BN_FLG_CONSTTIME) != 0))
+               {
+               return BN_div_no_branch(dv, rm, num, divisor, ctx);
+               }
+
        bn_check_top(dv);
        bn_check_top(rm);
        bn_check_top(num);
@@ -397,4 +404,229 @@ err:
        return(0);
        }
 
+
+/* BN_div_no_branch is a special version of BN_div. It does not contain
+ * branches that may leak sensitive information.
+ */
+static int BN_div_no_branch(BIGNUM *dv, BIGNUM *rm, const BIGNUM *num, 
+       const BIGNUM *divisor, BN_CTX *ctx)
+       {
+       int norm_shift,i,loop;
+       BIGNUM *tmp,wnum,*snum,*sdiv,*res;
+       BN_ULONG *resp,*wnump;
+       BN_ULONG d0,d1;
+       int num_n,div_n;
+
+       bn_check_top(dv);
+       bn_check_top(rm);
+       bn_check_top(num);
+       bn_check_top(divisor);
+
+       if (BN_is_zero(divisor))
+               {
+               BNerr(BN_F_BN_DIV_NO_BRANCH,BN_R_DIV_BY_ZERO);
+               return(0);
+               }
+
+       BN_CTX_start(ctx);
+       tmp=BN_CTX_get(ctx);
+       snum=BN_CTX_get(ctx);
+       sdiv=BN_CTX_get(ctx);
+       if (dv == NULL)
+               res=BN_CTX_get(ctx);
+       else    res=dv;
+       if (sdiv == NULL || res == NULL) goto err;
+
+       /* First we normalise the numbers */
+       norm_shift=BN_BITS2-((BN_num_bits(divisor))%BN_BITS2);
+       if (!(BN_lshift(sdiv,divisor,norm_shift))) goto err;
+       sdiv->neg=0;
+       norm_shift+=BN_BITS2;
+       if (!(BN_lshift(snum,num,norm_shift))) goto err;
+       snum->neg=0;
+
+       /* Since we don't know whether snum is larger than sdiv,
+        * we pad snum with enough zeroes without changing its
+        * value. 
+        */
+       if (snum->top <= sdiv->top+1) 
+               {
+               if (bn_wexpand(snum, sdiv->top + 2) == NULL) goto err;
+               for (i = snum->top; i < sdiv->top + 2; i++) snum->d[i] = 0;
+               snum->top = sdiv->top + 2;
+               }
+       else
+               {
+               if (bn_wexpand(snum, snum->top + 1) == NULL) goto err;
+               snum->d[snum->top] = 0;
+               snum->top ++;
+               }
+
+       div_n=sdiv->top;
+       num_n=snum->top;
+       loop=num_n-div_n;
+       /* Lets setup a 'window' into snum
+        * This is the part that corresponds to the current
+        * 'area' being divided */
+       wnum.neg   = 0;
+       wnum.d     = &(snum->d[loop]);
+       wnum.top   = div_n;
+       /* only needed when BN_ucmp messes up the values between top and max */
+       wnum.dmax  = snum->dmax - loop; /* so we don't step out of bounds */
+
+       /* Get the top 2 words of sdiv */
+       /* div_n=sdiv->top; */
+       d0=sdiv->d[div_n-1];
+       d1=(div_n == 1)?0:sdiv->d[div_n-2];
+
+       /* pointer to the 'top' of snum */
+       wnump= &(snum->d[num_n-1]);
+
+       /* Setup to 'res' */
+       res->neg= (num->neg^divisor->neg);
+       if (!bn_wexpand(res,(loop+1))) goto err;
+       res->top=loop-1;
+       resp= &(res->d[loop-1]);
+
+       /* space for temp */
+       if (!bn_wexpand(tmp,(div_n+1))) goto err;
+
+       /* if res->top == 0 then clear the neg value otherwise decrease
+        * the resp pointer */
+       if (res->top == 0)
+               res->neg = 0;
+       else
+               resp--;
+
+       for (i=0; i<loop-1; i++, wnump--, resp--)
+               {
+               BN_ULONG q,l0;
+               /* the first part of the loop uses the top two words of
+                * snum and sdiv to calculate a BN_ULONG q such that
+                * | wnum - sdiv * q | < sdiv */
+#if defined(BN_DIV3W) && !defined(OPENSSL_NO_ASM)
+               BN_ULONG bn_div_3_words(BN_ULONG*,BN_ULONG,BN_ULONG);
+               q=bn_div_3_words(wnump,d1,d0);
+#else
+               BN_ULONG n0,n1,rem=0;
+
+               n0=wnump[0];
+               n1=wnump[-1];
+               if (n0 == d0)
+                       q=BN_MASK2;
+               else                    /* n0 < d0 */
+                       {
+#ifdef BN_LLONG
+                       BN_ULLONG t2;
+
+#if defined(BN_LLONG) && defined(BN_DIV2W) && !defined(bn_div_words)
+                       q=(BN_ULONG)(((((BN_ULLONG)n0)<<BN_BITS2)|n1)/d0);
+#else
+                       q=bn_div_words(n0,n1,d0);
+#ifdef BN_DEBUG_LEVITTE
+                       fprintf(stderr,"DEBUG: bn_div_words(0x%08X,0x%08X,0x%08\
+X) -> 0x%08X\n",
+                               n0, n1, d0, q);
+#endif
+#endif
+
+#ifndef REMAINDER_IS_ALREADY_CALCULATED
+                       /*
+                        * rem doesn't have to be BN_ULLONG. The least we
+                        * know it's less that d0, isn't it?
+                        */
+                       rem=(n1-q*d0)&BN_MASK2;
+#endif
+                       t2=(BN_ULLONG)d1*q;
+
+                       for (;;)
+                               {
+                               if (t2 <= ((((BN_ULLONG)rem)<<BN_BITS2)|wnump[-2]))
+                                       break;
+                               q--;
+                               rem += d0;
+                               if (rem < d0) break; /* don't let rem overflow */
+                               t2 -= d1;
+                               }
+#else /* !BN_LLONG */
+                       BN_ULONG t2l,t2h,ql,qh;
+
+                       q=bn_div_words(n0,n1,d0);
+#ifdef BN_DEBUG_LEVITTE
+                       fprintf(stderr,"DEBUG: bn_div_words(0x%08X,0x%08X,0x%08\
+X) -> 0x%08X\n",
+                               n0, n1, d0, q);
+#endif
+#ifndef REMAINDER_IS_ALREADY_CALCULATED
+                       rem=(n1-q*d0)&BN_MASK2;
+#endif
+
+#if defined(BN_UMULT_LOHI)
+                       BN_UMULT_LOHI(t2l,t2h,d1,q);
+#elif defined(BN_UMULT_HIGH)
+                       t2l = d1 * q;
+                       t2h = BN_UMULT_HIGH(d1,q);
+#else
+                       t2l=LBITS(d1); t2h=HBITS(d1);
+                       ql =LBITS(q);  qh =HBITS(q);
+                       mul64(t2l,t2h,ql,qh); /* t2=(BN_ULLONG)d1*q; */
+#endif
+
+                       for (;;)
+                               {
+                               if ((t2h < rem) ||
+                                       ((t2h == rem) && (t2l <= wnump[-2])))
+                                       break;
+                               q--;
+                               rem += d0;
+                               if (rem < d0) break; /* don't let rem overflow */
+                               if (t2l < d1) t2h--; t2l -= d1;
+                               }
+#endif /* !BN_LLONG */
+                       }
+#endif /* !BN_DIV3W */
+
+               l0=bn_mul_words(tmp->d,sdiv->d,div_n,q);
+               tmp->d[div_n]=l0;
+               wnum.d--;
+               /* ingore top values of the bignums just sub the two 
+                * BN_ULONG arrays with bn_sub_words */
+               if (bn_sub_words(wnum.d, wnum.d, tmp->d, div_n+1))
+                       {
+                       /* Note: As we have considered only the leading
+                        * two BN_ULONGs in the calculation of q, sdiv * q
+                        * might be greater than wnum (but then (q-1) * sdiv
+                        * is less or equal than wnum)
+                        */
+                       q--;
+                       if (bn_add_words(wnum.d, wnum.d, sdiv->d, div_n))
+                               /* we can't have an overflow here (assuming
+                                * that q != 0, but if q == 0 then tmp is
+                                * zero anyway) */
+                               (*wnump)++;
+                       }
+               /* store part of the result */
+               *resp = q;
+               }
+       bn_correct_top(snum);
+       if (rm != NULL)
+               {
+               /* Keep a copy of the neg flag in num because if rm==num
+                * BN_rshift() will overwrite it.
+                */
+               int neg = num->neg;
+               BN_rshift(rm,snum,norm_shift);
+               if (!BN_is_zero(rm))
+                       rm->neg = neg;
+               bn_check_top(rm);
+               }
+       bn_correct_top(res);
+       BN_CTX_end(ctx);
+       return(1);
+err:
+       bn_check_top(rm);
+       BN_CTX_end(ctx);
+       return(0);
+       }
+
 #endif
index 24fbbb7..cfe2eb9 100644 (file)
@@ -1,6 +1,6 @@
 /* crypto/bn/bn_err.c */
 /* ====================================================================
- * Copyright (c) 1999-2005 The OpenSSL Project.  All rights reserved.
+ * Copyright (c) 1999-2007 The OpenSSL Project.  All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -82,6 +82,7 @@ static ERR_STRING_DATA BN_str_functs[]=
 {ERR_FUNC(BN_F_BN_CTX_NEW),    "BN_CTX_new"},
 {ERR_FUNC(BN_F_BN_CTX_START),  "BN_CTX_start"},
 {ERR_FUNC(BN_F_BN_DIV),        "BN_div"},
+{ERR_FUNC(BN_F_BN_DIV_NO_BRANCH),      "BN_div_no_branch"},
 {ERR_FUNC(BN_F_BN_DIV_RECP),   "BN_div_recp"},
 {ERR_FUNC(BN_F_BN_EXP),        "BN_exp"},
 {ERR_FUNC(BN_F_BN_EXPAND2),    "bn_expand2"},
@@ -100,6 +101,7 @@ static ERR_STRING_DATA BN_str_functs[]=
 {ERR_FUNC(BN_F_BN_MOD_EXP_RECP),       "BN_mod_exp_recp"},
 {ERR_FUNC(BN_F_BN_MOD_EXP_SIMPLE),     "BN_mod_exp_simple"},
 {ERR_FUNC(BN_F_BN_MOD_INVERSE),        "BN_mod_inverse"},
+{ERR_FUNC(BN_F_BN_MOD_INVERSE_NO_BRANCH),      "BN_mod_inverse_no_branch"},
 {ERR_FUNC(BN_F_BN_MOD_LSHIFT_QUICK),   "BN_mod_lshift_quick"},
 {ERR_FUNC(BN_F_BN_MOD_MUL_RECIPROCAL), "BN_mod_mul_reciprocal"},
 {ERR_FUNC(BN_F_BN_MOD_SQRT),   "BN_mod_sqrt"},
index 8f8c694..70a33f0 100644 (file)
@@ -122,9 +122,9 @@ int BN_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx)
        int i,bits,ret=0;
        BIGNUM *v,*rr;
 
-       if (BN_get_flags(p, BN_FLG_EXP_CONSTTIME) != 0)
+       if (BN_get_flags(p, BN_FLG_CONSTTIME) != 0)
                {
-               /* BN_FLG_EXP_CONSTTIME only supported by BN_mod_exp_mont() */
+               /* BN_FLG_CONSTTIME only supported by BN_mod_exp_mont() */
                BNerr(BN_F_BN_EXP,ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
                return -1;
                }
@@ -213,7 +213,7 @@ int BN_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, const BIGNUM *m,
        if (BN_is_odd(m))
                {
 #  ifdef MONT_EXP_WORD
-               if (a->top == 1 && !a->neg && (BN_get_flags(p, BN_FLG_EXP_CONSTTIME) == 0))
+               if (a->top == 1 && !a->neg && (BN_get_flags(p, BN_FLG_CONSTTIME) == 0))
                        {
                        BN_ULONG A = a->d[0];
                        ret=BN_mod_exp_mont_word(r,A,p,m,ctx,NULL);
@@ -245,9 +245,9 @@ int BN_mod_exp_recp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
        BIGNUM *val[TABLE_SIZE];
        BN_RECP_CTX recp;
 
-       if (BN_get_flags(p, BN_FLG_EXP_CONSTTIME) != 0)
+       if (BN_get_flags(p, BN_FLG_CONSTTIME) != 0)
                {
-               /* BN_FLG_EXP_CONSTTIME only supported by BN_mod_exp_mont() */
+               /* BN_FLG_CONSTTIME only supported by BN_mod_exp_mont() */
                BNerr(BN_F_BN_MOD_EXP_RECP,ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
                return -1;
                }
@@ -379,7 +379,7 @@ int BN_mod_exp_mont(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
        BIGNUM *val[TABLE_SIZE];
        BN_MONT_CTX *mont=NULL;
 
-       if (BN_get_flags(p, BN_FLG_EXP_CONSTTIME) != 0)
+       if (BN_get_flags(p, BN_FLG_CONSTTIME) != 0)
                {
                return BN_mod_exp_mont_consttime(rr, a, p, m, ctx, in_mont);
                }
@@ -745,9 +745,9 @@ int BN_mod_exp_mont_word(BIGNUM *rr, BN_ULONG a, const BIGNUM *p,
 #define BN_TO_MONTGOMERY_WORD(r, w, mont) \
                (BN_set_word(r, (w)) && BN_to_montgomery(r, r, (mont), ctx))
 
-       if (BN_get_flags(p, BN_FLG_EXP_CONSTTIME) != 0)
+       if (BN_get_flags(p, BN_FLG_CONSTTIME) != 0)
                {
-               /* BN_FLG_EXP_CONSTTIME only supported by BN_mod_exp_mont() */
+               /* BN_FLG_CONSTTIME only supported by BN_mod_exp_mont() */
                BNerr(BN_F_BN_MOD_EXP_MONT_WORD,ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
                return -1;
                }
@@ -881,9 +881,9 @@ int BN_mod_exp_simple(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
        /* Table of variables obtained from 'ctx' */
        BIGNUM *val[TABLE_SIZE];
 
-       if (BN_get_flags(p, BN_FLG_EXP_CONSTTIME) != 0)
+       if (BN_get_flags(p, BN_FLG_CONSTTIME) != 0)
                {
-               /* BN_FLG_EXP_CONSTTIME only supported by BN_mod_exp_mont() */
+               /* BN_FLG_CONSTTIME only supported by BN_mod_exp_mont() */
                BNerr(BN_F_BN_MOD_EXP_SIMPLE,ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
                return -1;
                }
index f02e6fc..4a35211 100644 (file)
@@ -203,6 +203,8 @@ err:
 
 
 /* solves ax == 1 (mod n) */
+static BIGNUM *BN_mod_inverse_no_branch(BIGNUM *in,
+        const BIGNUM *a, const BIGNUM *n, BN_CTX *ctx);
 BIGNUM *BN_mod_inverse(BIGNUM *in,
        const BIGNUM *a, const BIGNUM *n, BN_CTX *ctx)
        {
@@ -210,6 +212,11 @@ BIGNUM *BN_mod_inverse(BIGNUM *in,
        BIGNUM *ret=NULL;
        int sign;
 
+       if ((BN_get_flags(a, BN_FLG_CONSTTIME) != 0) || (BN_get_flags(n, BN_FLG_CONSTTIME) != 0))
+               {
+               return BN_mod_inverse_no_branch(in, a, n, ctx);
+               }
+
        bn_check_top(a);
        bn_check_top(n);
 
@@ -491,3 +498,157 @@ err:
        bn_check_top(ret);
        return(ret);
        }
+
+
+/* BN_mod_inverse_no_branch is a special version of BN_mod_inverse. 
+ * It does not contain branches that may leak sensitive information.
+ */
+static BIGNUM *BN_mod_inverse_no_branch(BIGNUM *in,
+       const BIGNUM *a, const BIGNUM *n, BN_CTX *ctx)
+       {
+       BIGNUM *A,*B,*X,*Y,*M,*D,*T,*R=NULL;
+       BIGNUM local_A, local_B;
+       BIGNUM *pA, *pB;
+       BIGNUM *ret=NULL;
+       int sign;
+
+       bn_check_top(a);
+       bn_check_top(n);
+
+       BN_CTX_start(ctx);
+       A = BN_CTX_get(ctx);
+       B = BN_CTX_get(ctx);
+       X = BN_CTX_get(ctx);
+       D = BN_CTX_get(ctx);
+       M = BN_CTX_get(ctx);
+       Y = BN_CTX_get(ctx);
+       T = BN_CTX_get(ctx);
+       if (T == NULL) goto err;
+
+       if (in == NULL)
+               R=BN_new();
+       else
+               R=in;
+       if (R == NULL) goto err;
+
+       BN_one(X);
+       BN_zero(Y);
+       if (BN_copy(B,a) == NULL) goto err;
+       if (BN_copy(A,n) == NULL) goto err;
+       A->neg = 0;
+
+       if (B->neg || (BN_ucmp(B, A) >= 0))
+               {
+               /* Turn BN_FLG_CONSTTIME flag on, so that when BN_div is invoked,
+                * BN_div_no_branch will be called eventually.
+                */
+               pB = &local_B;
+               BN_with_flags(pB, B, BN_FLG_CONSTTIME); 
+               if (!BN_nnmod(B, pB, A, ctx)) goto err;
+               }
+       sign = -1;
+       /* From  B = a mod |n|,  A = |n|  it follows that
+        *
+        *      0 <= B < A,
+        *     -sign*X*a  ==  B   (mod |n|),
+        *      sign*Y*a  ==  A   (mod |n|).
+        */
+
+       while (!BN_is_zero(B))
+               {
+               BIGNUM *tmp;
+               
+               /*
+                *      0 < B < A,
+                * (*) -sign*X*a  ==  B   (mod |n|),
+                *      sign*Y*a  ==  A   (mod |n|)
+                */
+
+               /* Turn BN_FLG_CONSTTIME flag on, so that when BN_div is invoked,
+                * BN_div_no_branch will be called eventually.
+                */
+               pA = &local_A;
+               BN_with_flags(pA, A, BN_FLG_CONSTTIME); 
+               
+               /* (D, M) := (A/B, A%B) ... */          
+               if (!BN_div(D,M,pA,B,ctx)) goto err;
+               
+               /* Now
+                *      A = D*B + M;
+                * thus we have
+                * (**)  sign*Y*a  ==  D*B + M   (mod |n|).
+                */
+               
+               tmp=A; /* keep the BIGNUM object, the value does not matter */
+               
+               /* (A, B) := (B, A mod B) ... */
+               A=B;
+               B=M;
+               /* ... so we have  0 <= B < A  again */
+               
+               /* Since the former  M  is now  B  and the former  B  is now  A,
+                * (**) translates into
+                *       sign*Y*a  ==  D*A + B    (mod |n|),
+                * i.e.
+                *       sign*Y*a - D*A  ==  B    (mod |n|).
+                * Similarly, (*) translates into
+                *      -sign*X*a  ==  A          (mod |n|).
+                *
+                * Thus,
+                *   sign*Y*a + D*sign*X*a  ==  B  (mod |n|),
+                * i.e.
+                *        sign*(Y + D*X)*a  ==  B  (mod |n|).
+                *
+                * So if we set  (X, Y, sign) := (Y + D*X, X, -sign),  we arrive back at
+                *      -sign*X*a  ==  B   (mod |n|),
+                *       sign*Y*a  ==  A   (mod |n|).
+                * Note that  X  and  Y  stay non-negative all the time.
+                */
+                       
+               if (!BN_mul(tmp,D,X,ctx)) goto err;
+               if (!BN_add(tmp,tmp,Y)) goto err;
+
+               M=Y; /* keep the BIGNUM object, the value does not matter */
+               Y=X;
+               X=tmp;
+               sign = -sign;
+               }
+               
+       /*
+        * The while loop (Euclid's algorithm) ends when
+        *      A == gcd(a,n);
+        * we have
+        *       sign*Y*a  ==  A  (mod |n|),
+        * where  Y  is non-negative.
+        */
+
+       if (sign < 0)
+               {
+               if (!BN_sub(Y,n,Y)) goto err;
+               }
+       /* Now  Y*a  ==  A  (mod |n|).  */
+
+       if (BN_is_one(A))
+               {
+               /* Y*a == 1  (mod |n|) */
+               if (!Y->neg && BN_ucmp(Y,n) < 0)
+                       {
+                       if (!BN_copy(R,Y)) goto err;
+                       }
+               else
+                       {
+                       if (!BN_nnmod(R,Y,n,ctx)) goto err;
+                       }
+               }
+       else
+               {
+               BNerr(BN_F_BN_MOD_INVERSE_NO_BRANCH,BN_R_NO_INVERSE);
+               goto err;
+               }
+       ret=R;
+err:
+       if ((ret == NULL) && (in == NULL)) BN_free(R);
+       BN_CTX_end(ctx);
+       bn_check_top(ret);
+       return(ret);
+       }
index 210ccb4..2649b8c 100644 (file)
@@ -763,7 +763,7 @@ int BN_is_bit_set(const BIGNUM *a, int n)
        i=n/BN_BITS2;
        j=n%BN_BITS2;
        if (a->top <= i) return 0;
-       return((a->d[i]&(((BN_ULONG)1)<<j))?1:0);
+       return(((a->d[i])>>j)&((BN_ULONG)1));
        }
 
 int BN_mask_bits(BIGNUM *a, int n)
index 961ca67..b5d35d1 100644 (file)
@@ -176,7 +176,6 @@ int BN_from_montgomery(BIGNUM *ret, const BIGNUM *a, BN_MONT_CTX *mont,
 
        max=(nl+al+1); /* allow for overflow (no?) XXX */
        if (bn_wexpand(r,max) == NULL) goto err;
-       if (bn_wexpand(ret,max) == NULL) goto err;
 
        r->neg=a->neg^n->neg;
        np=n->d;
@@ -228,19 +227,72 @@ int BN_from_montgomery(BIGNUM *ret, const BIGNUM *a, BN_MONT_CTX *mont,
                }
        bn_correct_top(r);
        
-       /* mont->ri will be a multiple of the word size */
-#if 0
-       BN_rshift(ret,r,mont->ri);
-#else
-       ret->neg = r->neg;
-       x=ri;
+       /* mont->ri will be a multiple of the word size and below code
+        * is kind of BN_rshift(ret,r,mont->ri) equivalent */
+       if (r->top <= ri)
+               {
+               ret->top=0;
+               retn=1;
+               goto err;
+               }
+       al=r->top-ri;
+
+# define BRANCH_FREE 1
+# if BRANCH_FREE
+       if (bn_wexpand(ret,ri) == NULL) goto err;
+       x=0-(((al-ri)>>(sizeof(al)*8-1))&1);
+       ret->top=x=(ri&~x)|(al&x);      /* min(ri,al) */
+       ret->neg=r->neg;
+
        rp=ret->d;
-       ap= &(r->d[x]);
-       if (r->top < x)
-               al=0;
-       else
-               al=r->top-x;
+       ap=&(r->d[ri]);
+
+       {
+       size_t m1,m2;
+
+       v=bn_sub_words(rp,ap,np,ri);
+       /* this ----------------^^ works even in al<ri case
+        * thanks to zealous zeroing of top of the vector in the
+        * beginning. */
+
+       /* if (al==ri && !v) || al>ri) nrp=rp; else nrp=ap; */
+       /* in other words if subtraction result is real, then
+        * trick unconditional memcpy below to perform in-place
+        * "refresh" instead of actual copy. */
+       m1=0-(size_t)(((al-ri)>>(sizeof(al)*8-1))&1);   /* al<ri */
+       m2=0-(size_t)(((ri-al)>>(sizeof(al)*8-1))&1);   /* al>ri */
+       m1|=m2;                 /* (al!=ri) */
+       m1|=(0-(size_t)v);      /* (al!=ri || v) */
+       m1&=~m2;                /* (al!=ri || v) && !al>ri */
+       nrp=(BN_ULONG *)(((size_t)rp&~m1)|((size_t)ap&m1));
+       }
+
+       /* 'i<ri' is chosen to eliminate dependency on input data, even
+        * though it results in redundant copy in al<ri case. */
+       for (i=0,ri-=4; i<ri; i+=4)
+               {
+               BN_ULONG t1,t2,t3,t4;
+               
+               t1=nrp[i+0];
+               t2=nrp[i+1];
+               t3=nrp[i+2];    ap[i+0]=0;
+               t4=nrp[i+3];    ap[i+1]=0;
+               rp[i+0]=t1;     ap[i+2]=0;
+               rp[i+1]=t2;     ap[i+3]=0;
+               rp[i+2]=t3;
+               rp[i+3]=t4;
+               }
+       for (ri+=4; i<ri; i++)
+               rp[i]=nrp[i], ap[i]=0;
+       bn_correct_top(r);
+       bn_correct_top(ret);
+# else
+       if (bn_wexpand(ret,al) == NULL) goto err;
        ret->top=al;
+       ret->neg=r->neg;
+
+       rp=ret->d;
+       ap=&(r->d[ri]);
        al-=4;
        for (i=0; i<al; i+=4)
                {
@@ -258,7 +310,7 @@ int BN_from_montgomery(BIGNUM *ret, const BIGNUM *a, BN_MONT_CTX *mont,
        al+=4;
        for (; i<al; i++)
                rp[i]=ap[i];
-#endif
+# endif
 #else /* !MONT_WORD */ 
        BIGNUM *t1,*t2;
 
@@ -278,10 +330,12 @@ int BN_from_montgomery(BIGNUM *ret, const BIGNUM *a, BN_MONT_CTX *mont,
        if (!BN_rshift(ret,t2,mont->ri)) goto err;
 #endif /* MONT_WORD */
 
+#if !defined(BRANCH_FREE) || BRANCH_FREE==0
        if (BN_ucmp(ret, &(mont->N)) >= 0)
                {
                if (!BN_usub(ret,ret,&(mont->N))) goto err;
                }
+#endif
        retn=1;
        bn_check_top(ret);
  err:
index aec1eaf..312b467 100644 (file)
@@ -655,16 +655,16 @@ void bn_mul_part_recursive(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n,
                                for (;;)
                                        {
                                        i/=2;
-                                       if (i < tna && i < tnb)
+                                       if (i <= tna && tna == tnb)
                                                {
-                                               bn_mul_part_recursive(&(r[n2]),
+                                               bn_mul_recursive(&(r[n2]),
                                                        &(a[n]),&(b[n]),
                                                        i,tna-i,tnb-i,p);
                                                break;
                                                }
-                                       else if (i <= tna && i <= tnb)
+                                       else if (i < tna || i < tnb)
                                                {
-                                               bn_mul_recursive(&(r[n2]),
+                                               bn_mul_part_recursive(&(r[n2]),
                                                        &(a[n]),&(b[n]),
                                                        i,tna-i,tnb-i,p);
                                                break;
index 5bab019..7b25979 100644 (file)
@@ -377,14 +377,14 @@ static int witness(BIGNUM *w, const BIGNUM *a, const BIGNUM *a1,
 static int probable_prime(BIGNUM *rnd, int bits)
        {
        int i;
-       BN_ULONG mods[NUMPRIMES];
+       prime_t mods[NUMPRIMES];
        BN_ULONG delta,maxdelta;
 
 again:
        if (!BN_rand(rnd,bits,1,1)) return(0);
        /* we now have a random number 'rand' to test. */
        for (i=1; i<NUMPRIMES; i++)
-               mods[i]=BN_mod_word(rnd,(BN_ULONG)primes[i]);
+               mods[i]=(prime_t)BN_mod_word(rnd,(BN_ULONG)primes[i]);
        maxdelta=BN_MASK2 - primes[NUMPRIMES-1];
        delta=0;
        loop: for (i=1; i<NUMPRIMES; i++)
index b7cf9a9..51d2194 100644 (file)
 
 #ifndef EIGHT_BIT
 #define NUMPRIMES 2048
+typedef unsigned short prime_t;
 #else
 #define NUMPRIMES 54
+typedef unsigned char prime_t;
 #endif
-static const unsigned int primes[NUMPRIMES]=
+static const prime_t primes[NUMPRIMES]=
        {
           2,   3,   5,   7,  11,  13,  17,  19,
          23,  29,  31,  37,  41,  43,  47,  53,
index 4c073dd..8aa06bc 100644 (file)
@@ -114,6 +114,7 @@ typedef void conf_finish_func(CONF_IMODULE *md);
 #define CONF_MFLAGS_SILENT             0x4
 #define CONF_MFLAGS_NO_DSO             0x8
 #define CONF_MFLAGS_IGNORE_MISSING_FILE        0x10
+#define CONF_MFLAGS_DEFAULT_SECTION    0x20
 
 int CONF_set_default_method(CONF_METHOD *meth);
 void CONF_set_nconf(CONF *conf,LHASH *hash);
index 0032baa..909d72b 100644 (file)
@@ -121,7 +121,7 @@ int _CONF_add_string(CONF *conf, CONF_VALUE *section, CONF_VALUE *value)
        v = (CONF_VALUE *)lh_insert(conf->data, value);
        if (v != NULL)
                {
-               sk_CONF_VALUE_delete_ptr(ts,v);
+               (void)sk_CONF_VALUE_delete_ptr(ts,v);
                OPENSSL_free(v->name);
                OPENSSL_free(v->value);
                OPENSSL_free(v);
index 587211a..628e833 100644 (file)
@@ -126,17 +126,18 @@ int CONF_modules_load(const CONF *cnf, const char *appname,
        {
        STACK_OF(CONF_VALUE) *values;
        CONF_VALUE *vl;
-       char *vsection;
+       char *vsection = NULL;
 
        int ret, i;
 
        if (!cnf)
                return 1;
 
-       if (appname == NULL)
-               appname = "openssl_conf";
+       if (appname)
+               vsection = NCONF_get_string(cnf, NULL, appname);
 
-       vsection = NCONF_get_string(cnf, NULL, appname); 
+       if (!appname || (!vsection && (flags & CONF_MFLAGS_DEFAULT_SECTION)))
+               vsection = NCONF_get_string(cnf, NULL, "openssl_conf");
 
        if (!vsection)
                {
@@ -431,7 +432,7 @@ void CONF_modules_unload(int all)
                if (((md->links > 0) || !md->dso) && !all)
                        continue;
                /* Since we're working in reverse this is OK */
-               sk_CONF_MODULE_delete(supported_modules, i);
+               (void)sk_CONF_MODULE_delete(supported_modules, i);
                module_free(md);
                }
        if (sk_CONF_MODULE_num(supported_modules) == 0)
index e15c2e5..9c53bac 100644 (file)
@@ -88,8 +88,8 @@ void OPENSSL_config(const char *config_name)
 
 
        ERR_clear_error();
-       if (CONF_modules_load_file(NULL, NULL,
-                                       CONF_MFLAGS_IGNORE_MISSING_FILE) <= 0)
+       if (CONF_modules_load_file(NULL, config_name,
+       CONF_MFLAGS_DEFAULT_SECTION|CONF_MFLAGS_IGNORE_MISSING_FILE) <= 0)
                {
                BIO *bio_err;
                ERR_load_crypto_strings();
index 86af760..8c68623 100644 (file)
@@ -277,7 +277,7 @@ int CRYPTO_get_new_dynlockid(void)
        else
                /* If we found a place with a NULL pointer, put our pointer
                   in it.  */
-               sk_CRYPTO_dynlock_set(dyn_locks,i,pointer);
+               (void)sk_CRYPTO_dynlock_set(dyn_locks,i,pointer);
        CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK);
 
        if (i == -1)
@@ -319,7 +319,7 @@ void CRYPTO_destroy_dynlockid(int i)
 #endif
                        if (pointer->references <= 0)
                                {
-                               sk_CRYPTO_dynlock_set(dyn_locks, i, NULL);
+                               (void)sk_CRYPTO_dynlock_set(dyn_locks, i, NULL);
                                }
                        else
                                pointer = NULL;
index 55efe03..a43ef3c 100644 (file)
@@ -115,7 +115,7 @@ int DES_check_key_parity(const_DES_cblock *key)
  * (and actual cblock values).
  */
 #define NUM_WEAK_KEY   16
-static DES_cblock weak_keys[NUM_WEAK_KEY]={
+static const DES_cblock weak_keys[NUM_WEAK_KEY]={
        /* weak keys */
        {0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01},
        {0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE},
index 058aec7..b846913 100644 (file)
@@ -62,7 +62,7 @@
 #include <openssl/dh.h>
 
 /* Check that p is a safe prime and
- * if g is 2, 3 or 5, check that is is a suitable generator
+ * if g is 2, 3 or 5, check that it is a suitable generator
  * where
  * for 2, p mod 24 == 11
  * for 3, p mod 12 == 5
index 37a2c1b..e7db440 100644 (file)
@@ -150,7 +150,7 @@ static int generate_key(DH *dh)
                        {
                        BN_init(&local_prk);
                        prk = &local_prk;
-                       BN_with_flags(prk, priv_key, BN_FLG_EXP_CONSTTIME);
+                       BN_with_flags(prk, priv_key, BN_FLG_CONSTTIME);
                        }
                else
                        prk = priv_key;
@@ -203,7 +203,7 @@ static int compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh)
                if ((dh->flags & DH_FLAG_NO_EXP_CONSTTIME) == 0)
                        {
                        /* XXX */
-                       BN_set_flags(dh->priv_key, BN_FLG_EXP_CONSTTIME);
+                       BN_set_flags(dh->priv_key, BN_FLG_CONSTTIME);
                        }
                if (!mont)
                        goto err;
index 6a6be3b..ca0b86a 100644 (file)
@@ -117,13 +117,20 @@ static int dsa_builtin_paramgen(DSA *ret, int bits,
        if (bits < 512) bits=512;
        bits=(bits+63)/64*64;
 
-       if (seed_len < 20)
+       /* NB: seed_len == 0 is special case: copy generated seed to
+        * seed_in if it is not NULL.
+        */
+       if (seed_len && (seed_len < 20))
                seed_in = NULL; /* seed buffer too small -- ignore */
        if (seed_len > 20) 
                seed_len = 20; /* App. 2.2 of FIPS PUB 186 allows larger SEED,
                                * but our internal buffers are restricted to 160 bits*/
        if ((seed_in != NULL) && (seed_len == 20))
+               {
                memcpy(seed,seed_in,seed_len);
+               /* set seed_in to NULL to avoid it being copied back */
+               seed_in = NULL;
+               }
 
        if ((ctx=BN_CTX_new()) == NULL) goto err;
 
@@ -300,7 +307,7 @@ err:
                        ok=0;
                        goto err;
                        }
-               if ((m > 1) && (seed_in != NULL)) memcpy(seed_in,seed,20);
+               if (seed_in != NULL) memcpy(seed_in,seed,20);
                if (counter_ret != NULL) *counter_ret=counter;
                if (h_ret != NULL) *h_ret=h;
                }
index 0423f2e..c4aa86b 100644 (file)
@@ -107,7 +107,7 @@ static int dsa_builtin_keygen(DSA *dsa)
                        {
                        BN_init(&local_prk);
                        prk = &local_prk;
-                       BN_with_flags(prk, priv_key, BN_FLG_EXP_CONSTTIME);
+                       BN_with_flags(prk, priv_key, BN_FLG_CONSTTIME);
                        }
                else
                        prk = priv_key;
index e6aad85..75ff7cc 100644 (file)
@@ -229,7 +229,7 @@ static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp)
        while (BN_is_zero(&k));
        if ((dsa->flags & DSA_FLAG_NO_EXP_CONSTTIME) == 0)
                {
-               BN_set_flags(&k, BN_FLG_EXP_CONSTTIME);
+               BN_set_flags(&k, BN_FLG_CONSTTIME);
                }
 
        if (dsa->flags & DSA_FLAG_CACHE_MONT_P)
index 3c96fbd..8bc2a23 100644 (file)
@@ -471,6 +471,7 @@ void ERR_load_EC_strings(void);
 #define EC_F_EC_POINT_SET_JPROJECTIVE_COORDINATES_GFP   126
 #define EC_F_EC_POINT_SET_TO_INFINITY                   127
 #define EC_F_EC_PRE_COMP_DUP                            207
+#define EC_F_EC_PRE_COMP_NEW                            196
 #define EC_F_EC_WNAF_MUL                                187
 #define EC_F_EC_WNAF_PRECOMPUTE_MULT                    188
 #define EC_F_I2D_ECPARAMETERS                           190
index 7be315b..d04c895 100644 (file)
@@ -1,6 +1,6 @@
 /* crypto/ec/ec_err.c */
 /* ====================================================================
- * Copyright (c) 1999-2005 The OpenSSL Project.  All rights reserved.
+ * Copyright (c) 1999-2007 The OpenSSL Project.  All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -170,6 +170,7 @@ static ERR_STRING_DATA EC_str_functs[]=
 {ERR_FUNC(EC_F_EC_POINT_SET_JPROJECTIVE_COORDINATES_GFP),      "EC_POINT_set_Jprojective_coordinates_GFp"},
 {ERR_FUNC(EC_F_EC_POINT_SET_TO_INFINITY),      "EC_POINT_set_to_infinity"},
 {ERR_FUNC(EC_F_EC_PRE_COMP_DUP),       "EC_PRE_COMP_DUP"},
+{ERR_FUNC(EC_F_EC_PRE_COMP_NEW),       "EC_PRE_COMP_NEW"},
 {ERR_FUNC(EC_F_EC_WNAF_MUL),   "ec_wNAF_mul"},
 {ERR_FUNC(EC_F_EC_WNAF_PRECOMPUTE_MULT),       "ec_wNAF_precompute_mult"},
 {ERR_FUNC(EC_F_I2D_ECPARAMETERS),      "i2d_ECParameters"},
index a045139..2ba173e 100644 (file)
@@ -3,7 +3,7 @@
  * Originally written by Bodo Moeller and Nils Larsch for the OpenSSL project.
  */
 /* ====================================================================
- * Copyright (c) 1998-2003 The OpenSSL Project.  All rights reserved.
+ * Copyright (c) 1998-2007 The OpenSSL Project.  All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -104,7 +104,10 @@ static EC_PRE_COMP *ec_pre_comp_new(const EC_GROUP *group)
 
        ret = (EC_PRE_COMP *)OPENSSL_malloc(sizeof(EC_PRE_COMP));
        if (!ret)
+               {
+               ECerr(EC_F_EC_PRE_COMP_NEW, ERR_R_MALLOC_FAILURE);
                return ret;
+               }
        ret->group = group;
        ret->blocksize = 8; /* default */
        ret->numblocks = 0;
@@ -194,6 +197,19 @@ static signed char *compute_wNAF(const BIGNUM *scalar, int w, size_t *ret_len)
        int bit, next_bit, mask;
        size_t len = 0, j;
        
+       if (BN_is_zero(scalar))
+               {
+               r = OPENSSL_malloc(1);
+               if (!r)
+                       {
+                       ECerr(EC_F_COMPUTE_WNAF, ERR_R_MALLOC_FAILURE);
+                       goto err;
+                       }
+               r[0] = 0;
+               *ret_len = 1;
+               return r;
+               }
+               
        if (w <= 0 || w > 7) /* 'signed char' can represent integers with absolute values less than 2^7 */
                {
                ECerr(EC_F_COMPUTE_WNAF, ERR_R_INTERNAL_ERROR);
@@ -212,7 +228,11 @@ static signed char *compute_wNAF(const BIGNUM *scalar, int w, size_t *ret_len)
        r = OPENSSL_malloc(len + 1); /* modified wNAF may be one digit longer than binary representation
                                      * (*ret_len will be set to the actual length, i.e. at most
                                      * BN_num_bits(scalar) + 1) */
-       if (r == NULL) goto err;
+       if (r == NULL)
+               {
+               ECerr(EC_F_COMPUTE_WNAF, ERR_R_MALLOC_FAILURE);
+               goto err;
+               }
 
        if (scalar->d == NULL || scalar->top == 0)
                {
@@ -425,7 +445,10 @@ int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
        val_sub  = OPENSSL_malloc(totalnum * sizeof val_sub[0]);
                 
        if (!wsize || !wNAF_len || !wNAF || !val_sub)
+               {
+               ECerr(EC_F_EC_WNAF_MUL, ERR_R_MALLOC_FAILURE);
                goto err;
+               }
 
        wNAF[0] = NULL; /* preliminary pivot */
 
@@ -538,6 +561,7 @@ int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
                                        wNAF[i] = OPENSSL_malloc(wNAF_len[i]);
                                        if (wNAF[i] == NULL)
                                                {
+                                               ECerr(EC_F_EC_WNAF_MUL, ERR_R_MALLOC_FAILURE);
                                                OPENSSL_free(tmp_wNAF);
                                                goto err;
                                                }
@@ -564,7 +588,11 @@ int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
         * 'val_sub[i]' is a pointer to the subarray for the i-th point,
         * or to a subarray of 'pre_comp->points' if we already have precomputation. */
        val = OPENSSL_malloc((num_val + 1) * sizeof val[0]);
-       if (val == NULL) goto err;
+       if (val == NULL)
+               {
+               ECerr(EC_F_EC_WNAF_MUL, ERR_R_MALLOC_FAILURE);
+               goto err;
+               }
        val[num_val] = NULL; /* pivot element */
 
        /* allocate points for precomputation */
index e1d66ea..8531bde 100644 (file)
@@ -436,7 +436,7 @@ static inline void *name(size_t cnt,                \
                        rep_xcrypt "\n"         \
                "       popl    %%ebx"          \
                : "=a"(iv), "=c"(cnt), "=D"(out), "=S"(inp) \
-               : "0"(cdata), "1"(cnt), "2"(out), "3"(inp), "m"(*cdata)  \
+               : "0"(cdata), "1"(cnt), "2"(out), "3"(inp)  \
                : "edx", "cc", "memory");       \
        return iv;                              \
 }
index a83c389..0c16561 100644 (file)
@@ -147,7 +147,7 @@ int engine_table_register(ENGINE_TABLE **table, ENGINE_CLEANUP_CB *cleanup,
                        lh_insert(&(*table)->piles, fnd);
                        }
                /* A registration shouldn't add duplciate entries */
-               sk_ENGINE_delete_ptr(fnd->sk, e);
+               (void)sk_ENGINE_delete_ptr(fnd->sk, e);
                /* if 'setdefault', this ENGINE goes to the head of the list */
                if(!sk_ENGINE_push(fnd->sk, e))
                        goto end;
@@ -178,7 +178,7 @@ static void int_unregister_cb(ENGINE_PILE *pile, ENGINE *e)
        /* Iterate the 'c->sk' stack removing any occurance of 'e' */
        while((n = sk_ENGINE_find(pile->sk, e)) >= 0)
                {
-               sk_ENGINE_delete(pile->sk, n);
+               (void)sk_ENGINE_delete(pile->sk, n);
                /* "touch" this ENGINE_CIPHER */
                pile->uptodate = 1;
                }
index 9ba4d0c..7054d81 100644 (file)
@@ -107,6 +107,15 @@ void OpenSSL_add_all_ciphers(void)
        EVP_add_cipher_alias(SN_idea_cbc,"idea");
 #endif
 
+#ifndef OPENSSL_NO_SEED
+       EVP_add_cipher(EVP_seed_ecb());
+       EVP_add_cipher(EVP_seed_cfb());
+       EVP_add_cipher(EVP_seed_ofb());
+       EVP_add_cipher(EVP_seed_cbc());
+       EVP_add_cipher_alias(SN_seed_cbc,"SEED");
+       EVP_add_cipher_alias(SN_seed_cbc,"seed");
+#endif
+
 #ifndef OPENSSL_NO_RC2
        EVP_add_cipher(EVP_rc2_ecb());
        EVP_add_cipher(EVP_rc2_cfb());
index 636f426..bdd3b7e 100644 (file)
@@ -766,6 +766,14 @@ const EVP_CIPHER *EVP_camellia_256_cfb128(void);
 const EVP_CIPHER *EVP_camellia_256_ofb(void);
 #endif
 
+#ifndef OPENSSL_NO_SEED
+const EVP_CIPHER *EVP_seed_ecb(void);
+const EVP_CIPHER *EVP_seed_cbc(void);
+const EVP_CIPHER *EVP_seed_cfb128(void);
+# define EVP_seed_cfb EVP_seed_cfb128
+const EVP_CIPHER *EVP_seed_ofb(void);
+#endif
+
 void OPENSSL_add_all_algorithms_noconf(void);
 void OPENSSL_add_all_algorithms_conf(void);
 
@@ -963,6 +971,7 @@ void ERR_load_EVP_strings(void);
 #define EVP_R_UNSUPPORTED_SALT_TYPE                     126
 #define EVP_R_WRONG_FINAL_BLOCK_LENGTH                  109
 #define EVP_R_WRONG_PUBLIC_KEY_TYPE                     110
+#define EVP_R_SEED_KEY_SETUP_FAILED                     162
 
 #ifdef  __cplusplus
 }
index f92db23..edb28ef 100644 (file)
@@ -225,7 +225,7 @@ int EVP_CIPHER_key_length(const EVP_CIPHER *cipher)
 
 int EVP_CIPHER_CTX_key_length(const EVP_CIPHER_CTX *ctx)
        {
-       return ctx->cipher->key_len;
+       return ctx->key_len;
        }
 
 int EVP_CIPHER_nid(const EVP_CIPHER *cipher)
index 20139d2..073b0ad 100644 (file)
@@ -92,7 +92,7 @@ static int cname##_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const uns
 #define BLOCK_CIPHER_func_cfb(cname, cprefix, cbits, kstruct, ksched) \
 static int cname##_cfb##cbits##_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, unsigned int inl) \
 {\
-       cprefix##_cfb##cbits##_encrypt(in, out, (long)inl, &((kstruct *)ctx->cipher_data)->ksched, ctx->iv, &ctx->num, ctx->encrypt);\
+       cprefix##_cfb##cbits##_encrypt(in, out, (long)(cbits==1?inl*8:inl), &((kstruct *)ctx->cipher_data)->ksched, ctx->iv, &ctx->num, ctx->encrypt);\
        return 1;\
 }
 
index 8914218..3b11e7a 100644 (file)
@@ -354,7 +354,7 @@ static int def_add_index(EX_CLASS_ITEM *item, long argl, void *argp,
                        }
                }
        toret = item->meth_num++;
-       sk_CRYPTO_EX_DATA_FUNCS_set(item->meth, toret, a);
+       (void)sk_CRYPTO_EX_DATA_FUNCS_set(item->meth, toret, a);
 err:
        CRYPTO_w_unlock(CRYPTO_LOCK_EX_DATA);
        return toret;
index 75cbfb3..add1f78 100644 (file)
@@ -64,12 +64,14 @@ unsigned char cleanse_ctr = 0;
 void OPENSSL_cleanse(void *ptr, size_t len)
        {
        unsigned char *p = ptr;
-       size_t loop = len;
+       size_t loop = len, ctr = cleanse_ctr;
        while(loop--)
                {
-               *(p++) = cleanse_ctr;
-               cleanse_ctr += (17 + (unsigned char)((unsigned long)p & 0xF));
+               *(p++) = (unsigned char)ctr;
+               ctr += (17 + ((size_t)p & 0xF));
                }
-       if(memchr(ptr, cleanse_ctr, len))
-               cleanse_ctr += 63;
+       p=memchr(ptr, (unsigned char)ctr, len);
+       if(p)
+               ctr += (63 + (size_t)p);
+       cleanse_ctr = (unsigned char)ctr;
        }
index a116bb7..a9528d5 100644 (file)
  * [including the GNU Public Licence.]
  */
 
-#define NUM_NID 772
-#define NUM_SN 768
-#define NUM_LN 768
-#define NUM_OBJ 724
+#define NUM_NID 780
+#define NUM_SN 773
+#define NUM_LN 773
+#define NUM_OBJ 729
 
-static unsigned char lvalues[5116]={
+static unsigned char lvalues[5154]={
 0x00,                                        /* [  0] OBJ_undef */
 0x2A,0x86,0x48,0x86,0xF7,0x0D,               /* [  1] OBJ_rsadsi */
 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,          /* [  7] OBJ_pkcs */
@@ -792,6 +792,11 @@ static unsigned char lvalues[5116]={
 0x55,0x1D,0x09,                              /* [5106] OBJ_subject_directory_attributes */
 0x55,0x1D,0x1C,                              /* [5109] OBJ_issuing_distribution_point */
 0x55,0x1D,0x1D,                              /* [5112] OBJ_certificate_issuer */
+0x2A,0x83,0x1A,0x8C,0x9A,0x44,               /* [5115] OBJ_kisa */
+0x2A,0x83,0x1A,0x8C,0x9A,0x44,0x01,0x03,     /* [5121] OBJ_seed_ecb */
+0x2A,0x83,0x1A,0x8C,0x9A,0x44,0x01,0x04,     /* [5129] OBJ_seed_cbc */
+0x2A,0x83,0x1A,0x8C,0x9A,0x44,0x01,0x06,     /* [5137] OBJ_seed_ofb128 */
+0x2A,0x83,0x1A,0x8C,0x9A,0x44,0x01,0x05,     /* [5145] OBJ_seed_cfb128 */
 };
 
 static ASN1_OBJECT nid_objs[NUM_NID]={
@@ -1996,6 +2001,14 @@ static ASN1_OBJECT nid_objs[NUM_NID]={
        NID_issuing_distribution_point,3,&(lvalues[5109]),0},
 {"certificateIssuer","X509v3 Certificate Issuer",
        NID_certificate_issuer,3,&(lvalues[5112]),0},
+{NULL,NULL,NID_undef,0,NULL,0},
+{"KISA","kisa",NID_kisa,6,&(lvalues[5115]),0},
+{NULL,NULL,NID_undef,0,NULL,0},
+{NULL,NULL,NID_undef,0,NULL,0},
+{"SEED-ECB","seed-ecb",NID_seed_ecb,8,&(lvalues[5121]),0},
+{"SEED-CBC","seed-cbc",NID_seed_cbc,8,&(lvalues[5129]),0},
+{"SEED-OFB","seed-ofb",NID_seed_ofb128,8,&(lvalues[5137]),0},
+{"SEED-CFB","seed-cfb",NID_seed_cfb128,8,&(lvalues[5145]),0},
 };
 
 static ASN1_OBJECT *sn_objs[NUM_SN]={
@@ -2085,6 +2098,7 @@ static ASN1_OBJECT *sn_objs[NUM_SN]={
 &(nid_objs[183]),/* "ISO-US" */
 &(nid_objs[645]),/* "ITU-T" */
 &(nid_objs[646]),/* "JOINT-ISO-ITU-T" */
+&(nid_objs[773]),/* "KISA" */
 &(nid_objs[15]),/* "L" */
 &(nid_objs[ 3]),/* "MD2" */
 &(nid_objs[257]),/* "MD4" */
@@ -2147,6 +2161,10 @@ static ASN1_OBJECT *sn_objs[NUM_SN]={
 &(nid_objs[668]),/* "RSA-SHA256" */
 &(nid_objs[669]),/* "RSA-SHA384" */
 &(nid_objs[670]),/* "RSA-SHA512" */
+&(nid_objs[777]),/* "SEED-CBC" */
+&(nid_objs[779]),/* "SEED-CFB" */
+&(nid_objs[776]),/* "SEED-ECB" */
+&(nid_objs[778]),/* "SEED-OFB" */
 &(nid_objs[41]),/* "SHA" */
 &(nid_objs[64]),/* "SHA1" */
 &(nid_objs[675]),/* "SHA224" */
@@ -3221,6 +3239,7 @@ static ASN1_OBJECT *ln_objs[NUM_LN]={
 &(nid_objs[492]),/* "janetMailbox" */
 &(nid_objs[646]),/* "joint-iso-itu-t" */
 &(nid_objs[150]),/* "keyBag" */
+&(nid_objs[773]),/* "kisa" */
 &(nid_objs[477]),/* "lastModifiedBy" */
 &(nid_objs[476]),/* "lastModifiedTime" */
 &(nid_objs[157]),/* "localKeyID" */
@@ -3371,6 +3390,10 @@ static ASN1_OBJECT *ln_objs[NUM_LN]={
 &(nid_objs[733]),/* "sect571k1" */
 &(nid_objs[734]),/* "sect571r1" */
 &(nid_objs[635]),/* "secure device signature" */
+&(nid_objs[777]),/* "seed-cbc" */
+&(nid_objs[779]),/* "seed-cfb" */
+&(nid_objs[776]),/* "seed-ecb" */
+&(nid_objs[778]),/* "seed-ofb" */
 &(nid_objs[105]),/* "serialNumber" */
 &(nid_objs[625]),/* "set-addPolicy" */
 &(nid_objs[515]),/* "set-attr" */
@@ -3811,6 +3834,7 @@ static ASN1_OBJECT *obj_objs[NUM_OBJ]={
 &(nid_objs[745]),/* OBJ_wap_wsg_idm_ecid_wtls12      2 23 43 13 4 12 */
 &(nid_objs[124]),/* OBJ_rle_compression              1 1 1 1 666 1 */
 &(nid_objs[125]),/* OBJ_zlib_compression             1 1 1 1 666 2 */
+&(nid_objs[773]),/* OBJ_kisa                         1 2 410 200004 */
 &(nid_objs[ 1]),/* OBJ_rsadsi                       1 2 840 113549 */
 &(nid_objs[185]),/* OBJ_X9cm                         1 2 840 10040 4 */
 &(nid_objs[127]),/* OBJ_id_pkix                      1 3 6 1 5 5 7 */
@@ -3861,6 +3885,10 @@ static ASN1_OBJECT *obj_objs[NUM_OBJ]={
 &(nid_objs[768]),/* OBJ_camellia_256_ofb128          0 3 4401 5 3 1 9 43 */
 &(nid_objs[759]),/* OBJ_camellia_256_cfb128          0 3 4401 5 3 1 9 44 */
 &(nid_objs[437]),/* OBJ_pilot                        0 9 2342 19200300 100 */
+&(nid_objs[776]),/* OBJ_seed_ecb                     1 2 410 200004 1 3 */
+&(nid_objs[777]),/* OBJ_seed_cbc                     1 2 410 200004 1 4 */
+&(nid_objs[779]),/* OBJ_seed_cfb128                  1 2 410 200004 1 5 */
+&(nid_objs[778]),/* OBJ_seed_ofb128                  1 2 410 200004 1 6 */
 &(nid_objs[186]),/* OBJ_pkcs1                        1 2 840 113549 1 1 */
 &(nid_objs[27]),/* OBJ_pkcs3                        1 2 840 113549 1 3 */
 &(nid_objs[187]),/* OBJ_pkcs5                        1 2 840 113549 1 5 */
index f447bbe..68b6e31 100644 (file)
 #define LN_camellia_256_cfb8           "camellia-256-cfb8"
 #define NID_camellia_256_cfb8          765
 
+#define SN_kisa                "KISA"
+#define LN_kisa                "kisa"
+#define NID_kisa               773
+#define OBJ_kisa               OBJ_member_body,410L,200004L
+
+#define SN_seed_ecb            "SEED-ECB"
+#define LN_seed_ecb            "seed-ecb"
+#define NID_seed_ecb           776
+#define OBJ_seed_ecb           OBJ_kisa,1L,3L
+
+#define SN_seed_cbc            "SEED-CBC"
+#define LN_seed_cbc            "seed-cbc"
+#define NID_seed_cbc           777
+#define OBJ_seed_cbc           OBJ_kisa,1L,4L
+
+#define SN_seed_cfb128         "SEED-CFB"
+#define LN_seed_cfb128         "seed-cfb"
+#define NID_seed_cfb128                779
+#define OBJ_seed_cfb128                OBJ_kisa,1L,5L
+
+#define SN_seed_ofb128         "SEED-OFB"
+#define LN_seed_ofb128         "seed-ofb"
+#define NID_seed_ofb128                778
+#define OBJ_seed_ofb128                OBJ_kisa,1L,6L
+
index 53f3364..8163411 100644 (file)
@@ -469,7 +469,7 @@ int OCSP_basic_sign(OCSP_BASICRESP *brsp,
 ASN1_STRING *ASN1_STRING_encode(ASN1_STRING *s, i2d_of_void *i2d,
                                void *data, STACK_OF(ASN1_OBJECT) *sk);
 #define ASN1_STRING_encode_of(type,s,i2d,data,sk) \
-((ASN1_STRING *(*)(ASN1_STRING *,I2D_OF(type),type *,STACK_OF(ASN1_OBJECT) *))openssl_fcast(ASN1_STRING_encode))(s,i2d,data,sk)
+       ASN1_STRING_encode(s, CHECKED_I2D_OF(type, i2d), data, sk)
 
 X509_EXTENSION *OCSP_crlID_new(char *url, long *n, char *tim);
 
index 8a5b34e..b237c2f 100644 (file)
  * (Prior to 0.9.5a beta1, a different scheme was used: MMNNFFRBB for
  *  major minor fix final patch/beta)
  */
-#define OPENSSL_VERSION_NUMBER 0x0090805fL
+#define OPENSSL_VERSION_NUMBER 0x00908070L
 #ifdef OPENSSL_FIPS
-#define OPENSSL_VERSION_TEXT   "OpenSSL 0.9.8e-fips 23 Feb 2007"
+#define OPENSSL_VERSION_TEXT   "OpenSSL 0.9.8f-fips 11 Oct 2007"
 #else
-#define OPENSSL_VERSION_TEXT   "OpenSSL 0.9.8e 23 Feb 2007"
+#define OPENSSL_VERSION_TEXT   "OpenSSL 0.9.8f 11 Oct 2007"
 #endif
 #define OPENSSL_VERSION_PTEXT  " part of " OPENSSL_VERSION_TEXT
 
index c28706d..4e24cc5 100644 (file)
@@ -220,19 +220,28 @@ typedef struct pem_ctx_st
 #define IMPLEMENT_PEM_read_fp(name, type, str, asn1) \
 type *PEM_read_##name(FILE *fp, type **x, pem_password_cb *cb, void *u)\
 { \
-return(((type *(*)(D2I_OF(type),char *,FILE *,type **,pem_password_cb *,void *))openssl_fcast(PEM_ASN1_read))(d2i_##asn1, str,fp,x,cb,u)); \
+    return (type*)PEM_ASN1_read(CHECKED_D2I_OF(type, d2i_##asn1), \
+                               str, fp, \
+                               CHECKED_PPTR_OF(type, x), \
+                               cb, u); \
 } 
 
 #define IMPLEMENT_PEM_write_fp(name, type, str, asn1) \
 int PEM_write_##name(FILE *fp, type *x) \
 { \
-return(((int (*)(I2D_OF(type),const char *,FILE *,type *, const EVP_CIPHER *,unsigned char *,int, pem_password_cb *,void *))openssl_fcast(PEM_ASN1_write))(i2d_##asn1,str,fp,x,NULL,NULL,0,NULL,NULL)); \
+    return PEM_ASN1_write(CHECKED_I2D_OF(type, i2d_##asn1), \
+                         str, fp, \
+                         CHECKED_PTR_OF(type, x), \
+                         NULL, NULL, 0, NULL, NULL); \
 }
 
 #define IMPLEMENT_PEM_write_fp_const(name, type, str, asn1) \
 int PEM_write_##name(FILE *fp, const type *x) \
 { \
-return(((int (*)(I2D_OF_const(type),const char *,FILE *, const type *, const EVP_CIPHER *,unsigned char *,int, pem_password_cb *,void *))openssl_fcast(PEM_ASN1_write))(i2d_##asn1,str,fp,x,NULL,NULL,0,NULL,NULL)); \
+    return PEM_ASN1_write(CHECKED_I2D_OF(const type, i2d_##asn1), \
+                         str, fp, \
+                         CHECKED_PTR_OF(const type, x), \
+                         NULL, NULL, 0, NULL, NULL); \
 }
 
 #define IMPLEMENT_PEM_write_cb_fp(name, type, str, asn1) \
@@ -240,7 +249,10 @@ int PEM_write_##name(FILE *fp, type *x, const EVP_CIPHER *enc, \
             unsigned char *kstr, int klen, pem_password_cb *cb, \
                  void *u) \
        { \
-       return(((int (*)(I2D_OF(type),const char *,FILE *,type *, const EVP_CIPHER *,unsigned char *,int, pem_password_cb *,void *))openssl_fcast(PEM_ASN1_write))(i2d_##asn1,str,fp,x,enc,kstr,klen,cb,u)); \
+           return PEM_ASN1_write(CHECKED_I2D_OF(type, i2d_##asn1), \
+                                 str, fp, \
+                                 CHECKED_PTR_OF(type, x), \
+                                 enc, kstr, klen, cb, u); \
        }
 
 #define IMPLEMENT_PEM_write_cb_fp_const(name, type, str, asn1) \
@@ -248,7 +260,10 @@ int PEM_write_##name(FILE *fp, type *x, const EVP_CIPHER *enc, \
             unsigned char *kstr, int klen, pem_password_cb *cb, \
                  void *u) \
        { \
-       return(((int (*)(I2D_OF_const(type),const char *,FILE *,type *, const EVP_CIPHER *,unsigned char *,int, pem_password_cb *,void *))openssl_fcast(PEM_ASN1_write))(i2d_##asn1,str,fp,x,enc,kstr,klen,cb,u)); \
+           return PEM_ASN1_write(CHECKED_I2D_OF(const type, i2d_##asn1), \
+                                 str, fp, \
+                                 CHECKED_PTR_OF(const type, x), \
+                                 enc, kstr, klen, cb, u); \
        }
 
 #endif
@@ -256,33 +271,48 @@ int PEM_write_##name(FILE *fp, type *x, const EVP_CIPHER *enc, \
 #define IMPLEMENT_PEM_read_bio(name, type, str, asn1) \
 type *PEM_read_bio_##name(BIO *bp, type **x, pem_password_cb *cb, void *u)\
 { \
-return(((type *(*)(D2I_OF(type),const char *,BIO *,type **,pem_password_cb *,void *))openssl_fcast(PEM_ASN1_read_bio))(d2i_##asn1, str,bp,x,cb,u)); \
+    return (type*)PEM_ASN1_read_bio(CHECKED_D2I_OF(type, d2i_##asn1), \
+                                   str, bp, \
+                                   CHECKED_PPTR_OF(type, x), \
+                                   cb, u); \
 }
 
 #define IMPLEMENT_PEM_write_bio(name, type, str, asn1) \
 int PEM_write_bio_##name(BIO *bp, type *x) \
 { \
-return(((int (*)(I2D_OF(type),const char *,BIO *,type *, const EVP_CIPHER *,unsigned char *,int, pem_password_cb *,void *))openssl_fcast(PEM_ASN1_write_bio))(i2d_##asn1,str,bp,x,NULL,NULL,0,NULL,NULL)); \
+    return PEM_ASN1_write_bio(CHECKED_I2D_OF(type, i2d_##asn1), \
+                             str, bp, \
+                             CHECKED_PTR_OF(type, x), \
+                             NULL, NULL, 0, NULL, NULL); \
 }
 
 #define IMPLEMENT_PEM_write_bio_const(name, type, str, asn1) \
 int PEM_write_bio_##name(BIO *bp, const type *x) \
 { \
-return(((int (*)(I2D_OF_const(type),const char *,BIO *,const type *, const EVP_CIPHER *,unsigned char *,int, pem_password_cb *,void *))openssl_fcast(PEM_ASN1_write_bio))(i2d_##asn1,str,bp,x,NULL,NULL,0,NULL,NULL)); \
+    return PEM_ASN1_write_bio(CHECKED_I2D_OF(const type, i2d_##asn1), \
+                             str, bp, \
+                             CHECKED_PTR_OF(const type, x), \
+                             NULL, NULL, 0, NULL, NULL); \
 }
 
 #define IMPLEMENT_PEM_write_cb_bio(name, type, str, asn1) \
 int PEM_write_bio_##name(BIO *bp, type *x, const EVP_CIPHER *enc, \
             unsigned char *kstr, int klen, pem_password_cb *cb, void *u) \
        { \
-       return(((int (*)(I2D_OF(type),const char *,BIO *,type *,const EVP_CIPHER *,unsigned char *,int,pem_password_cb *,void *))openssl_fcast(PEM_ASN1_write_bio))(i2d_##asn1,str,bp,x,enc,kstr,klen,cb,u)); \
+           return PEM_ASN1_write_bio(CHECKED_I2D_OF(type, i2d_##asn1), \
+                                     str, bp, \
+                                     CHECKED_PTR_OF(type, x), \
+                                     enc, kstr, klen, cb, u); \
        }
 
 #define IMPLEMENT_PEM_write_cb_bio_const(name, type, str, asn1) \
 int PEM_write_bio_##name(BIO *bp, type *x, const EVP_CIPHER *enc, \
             unsigned char *kstr, int klen, pem_password_cb *cb, void *u) \
        { \
-       return(((int (*)(I2D_OF_const(type),const char *,BIO *,type *,const EVP_CIPHER *,unsigned char *,int,pem_password_cb *,void *))openssl_fcast(PEM_ASN1_write_bio))(i2d_##asn1,str,bp,x,enc,kstr,klen,cb,u)); \
+           return PEM_ASN1_write_bio(CHECKED_I2D_OF(const type, i2d_##asn1), \
+                                     str, bp, \
+                                     CHECKED_PTR_OF(const type, x), \
+                                     enc, kstr, klen, cb, u); \
        }
 
 #define IMPLEMENT_PEM_write(name, type, str, asn1) \
@@ -545,13 +575,22 @@ int PEM_bytes_read_bio(unsigned char **pdata, long *plen, char **pnm, const char
             pem_password_cb *cb, void *u);
 void * PEM_ASN1_read_bio(d2i_of_void *d2i, const char *name, BIO *bp,
                          void **x, pem_password_cb *cb, void *u);
+
 #define PEM_ASN1_read_bio_of(type,d2i,name,bp,x,cb,u) \
-((type *(*)(D2I_OF(type),const char *,BIO *,type **,pem_password_cb *,void *))openssl_fcast(PEM_ASN1_read_bio))(d2i,name,bp,x,cb,u)
+    ((type*)PEM_ASN1_read_bio(CHECKED_D2I_OF(type, d2i), \
+                             name, bp,                 \
+                             CHECKED_PPTR_OF(type, x), \
+                             cb, u))
+
 int    PEM_ASN1_write_bio(i2d_of_void *i2d,const char *name,BIO *bp,char *x,
                           const EVP_CIPHER *enc,unsigned char *kstr,int klen,
                           pem_password_cb *cb, void *u);
+
 #define PEM_ASN1_write_bio_of(type,i2d,name,bp,x,enc,kstr,klen,cb,u) \
-       ((int (*)(I2D_OF(type),const char *,BIO *,type *, const EVP_CIPHER *,unsigned char *,int, pem_password_cb *,void *))openssl_fcast(PEM_ASN1_write_bio))(i2d,name,bp,x,enc,kstr,klen,cb,u)
+    (PEM_ASN1_write_bio(CHECKED_I2D_OF(type, i2d), \
+                       name, bp,                  \
+                       CHECKED_PTR_OF(type, x), \
+                       enc, kstr, klen, cb, u))
 
 STACK_OF(X509_INFO) *  PEM_X509_INFO_read_bio(BIO *bp, STACK_OF(X509_INFO) *sk, pem_password_cb *cb, void *u);
 int    PEM_X509_INFO_write_bio(BIO *bp,X509_INFO *xi, EVP_CIPHER *enc,
index 134746c..25566a4 100644 (file)
@@ -121,7 +121,7 @@ static int B64_write_PKCS7(BIO *bio, PKCS7 *p7)
        }
        bio = BIO_push(b64, bio);
        i2d_PKCS7_bio(bio, p7);
-       BIO_flush(bio);
+       (void)BIO_flush(bio);
        bio = BIO_pop(bio);
        BIO_free(b64);
        return 1;
@@ -138,7 +138,7 @@ static PKCS7 *B64_read_PKCS7(BIO *bio)
        bio = BIO_push(b64, bio);
        if(!(p7 = d2i_PKCS7_bio(bio, NULL))) 
                PKCS7err(PKCS7_F_B64_READ_PKCS7,PKCS7_R_DECODE_ERROR);
-       BIO_flush(bio);
+       (void)BIO_flush(bio);
        bio = BIO_pop(bio);
        BIO_free(b64);
        return p7;
index fab8513..5c6b0fe 100644 (file)
@@ -426,7 +426,7 @@ PKCS7 *PKCS7_encrypt(STACK_OF(X509) *certs, BIO *in, const EVP_CIPHER *cipher,
 
        SMIME_crlf_copy(in, p7bio, flags);
 
-       BIO_flush(p7bio);
+       (void)BIO_flush(p7bio);
 
         if (!PKCS7_dataFinal(p7,p7bio)) {
                PKCS7err(PKCS7_F_PKCS7_ENCRYPT,PKCS7_R_PKCS7_DATAFINAL_ERROR);
index 28c58a0..fd36578 100644 (file)
@@ -57,7 +57,7 @@
  *
  */
 
-#include "opensslconf.h"
+#include <openssl/opensslconf.h>
 #include <openssl/bn.h>
 
 /* 
index d69bdf8..cec5880 100644 (file)
@@ -102,10 +102,8 @@ int RAND_load_file(const char *file, long bytes)
 
        if (file == NULL) return(0);
 
-       i=stat(file,&sb);
-       /* If the state fails, put some crap in anyway */
+       if (stat(file,&sb) < 0) return(0);
        RAND_add(&sb,sizeof(sb),0.0);
-       if (i < 0) return(0);
        if (bytes == 0) return(ret);
 
        in=fopen(file,"rb");
index b19c556..6b5e4f8 100644 (file)
@@ -195,13 +195,27 @@ struct rsa_st
                                                 * default (ignoring RSA_FLAG_BLINDING),
                                                 * but other engines might not need it
                                                 */
-#define RSA_FLAG_NO_EXP_CONSTTIME      0x0100 /* new with 0.9.7h; the built-in RSA
+#define RSA_FLAG_NO_CONSTTIME          0x0100 /* new with 0.9.8f; the built-in RSA
+                                               * implementation now uses constant time
+                                               * operations by default in private key operations,
+                                               * e.g., constant time modular exponentiation, 
+                                                * modular inverse without leaking branches, 
+                                                * division without leaking branches. This 
+                                                * flag disables these constant time 
+                                                * operations and results in faster RSA 
+                                                * private key operations.
+                                                */ 
+#ifndef OPENSSL_NO_DEPRECATED
+#define RSA_FLAG_NO_EXP_CONSTTIME RSA_FLAG_NO_CONSTTIME /* deprecated name for the flag*/
+                                                /* new with 0.9.7h; the built-in RSA
                                                 * implementation now uses constant time
                                                 * modular exponentiation for secret exponents
                                                 * by default. This flag causes the
                                                 * faster variable sliding window method to
                                                 * be used for all exponents.
                                                 */
+#endif
+
 
 #define RSA_PKCS1_PADDING      1
 #define RSA_SSLV23_PADDING     2
index e7b7a9c..9e79374 100644 (file)
@@ -429,11 +429,11 @@ static int RSA_eay_private_encrypt(int flen, const unsigned char *from,
                BIGNUM local_d;
                BIGNUM *d = NULL;
                
-               if (!(rsa->flags & RSA_FLAG_NO_EXP_CONSTTIME))
+               if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME))
                        {
                        BN_init(&local_d);
                        d = &local_d;
-                       BN_with_flags(d, rsa->d, BN_FLG_EXP_CONSTTIME);
+                       BN_with_flags(d, rsa->d, BN_FLG_CONSTTIME);
                        }
                else
                        d = rsa->d;
@@ -551,10 +551,10 @@ static int RSA_eay_private_decrypt(int flen, const unsigned char *from,
                BIGNUM local_d;
                BIGNUM *d = NULL;
                
-               if (!(rsa->flags & RSA_FLAG_NO_EXP_CONSTTIME))
+               if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME))
                        {
                        d = &local_d;
-                       BN_with_flags(d, rsa->d, BN_FLG_EXP_CONSTTIME);
+                       BN_with_flags(d, rsa->d, BN_FLG_CONSTTIME);
                        }
                else
                        d = rsa->d;
@@ -715,8 +715,9 @@ err:
 static int RSA_eay_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx)
        {
        BIGNUM *r1,*m1,*vrfy;
-       BIGNUM local_dmp1, local_dmq1;
-       BIGNUM *dmp1, *dmq1;
+       BIGNUM local_dmp1,local_dmq1,local_c,local_r1;
+       BIGNUM *dmp1,*dmq1,*c,*pr1;
+       int bn_flags;
        int ret=0;
 
        BN_CTX_start(ctx);
@@ -724,26 +725,72 @@ static int RSA_eay_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx)
        m1 = BN_CTX_get(ctx);
        vrfy = BN_CTX_get(ctx);
 
+       /* Make sure mod_inverse in montgomerey intialization use correct 
+        * BN_FLG_CONSTTIME flag.
+        */
+       bn_flags = rsa->p->flags;
+       if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME))
+               {
+               rsa->p->flags |= BN_FLG_CONSTTIME;
+               }
        MONT_HELPER(rsa, ctx, p, rsa->flags & RSA_FLAG_CACHE_PRIVATE, goto err);
+       /* We restore bn_flags back */
+       rsa->p->flags = bn_flags;
+
+        /* Make sure mod_inverse in montgomerey intialization use correct
+         * BN_FLG_CONSTTIME flag.
+         */
+       bn_flags = rsa->q->flags;
+       if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME))
+               {
+               rsa->q->flags |= BN_FLG_CONSTTIME;
+               }
        MONT_HELPER(rsa, ctx, q, rsa->flags & RSA_FLAG_CACHE_PRIVATE, goto err);
+       /* We restore bn_flags back */
+       rsa->q->flags = bn_flags;       
+
        MONT_HELPER(rsa, ctx, n, rsa->flags & RSA_FLAG_CACHE_PUBLIC, goto err);
 
-       if (!BN_mod(r1,I,rsa->q,ctx)) goto err;
-       if (!(rsa->flags & RSA_FLAG_NO_EXP_CONSTTIME))
+       /* compute I mod q */
+       if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME))
+               {
+               c = &local_c;
+               BN_with_flags(c, I, BN_FLG_CONSTTIME);
+               if (!BN_mod(r1,c,rsa->q,ctx)) goto err;
+               }
+       else
+               {
+               if (!BN_mod(r1,I,rsa->q,ctx)) goto err;
+               }
+
+       /* compute r1^dmq1 mod q */
+       if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME))
                {
                dmq1 = &local_dmq1;
-               BN_with_flags(dmq1, rsa->dmq1, BN_FLG_EXP_CONSTTIME);
+               BN_with_flags(dmq1, rsa->dmq1, BN_FLG_CONSTTIME);
                }
        else
                dmq1 = rsa->dmq1;
        if (!rsa->meth->bn_mod_exp(m1,r1,dmq1,rsa->q,ctx,
                rsa->_method_mod_q)) goto err;
 
-       if (!BN_mod(r1,I,rsa->p,ctx)) goto err;
-       if (!(rsa->flags & RSA_FLAG_NO_EXP_CONSTTIME))
+       /* compute I mod p */
+       if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME))
+               {
+               c = &local_c;
+               BN_with_flags(c, I, BN_FLG_CONSTTIME);
+               if (!BN_mod(r1,c,rsa->p,ctx)) goto err;
+               }
+       else
+               {
+               if (!BN_mod(r1,I,rsa->p,ctx)) goto err;
+               }
+
+       /* compute r1^dmp1 mod p */
+       if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME))
                {
                dmp1 = &local_dmp1;
-               BN_with_flags(dmp1, rsa->dmp1, BN_FLG_EXP_CONSTTIME);
+               BN_with_flags(dmp1, rsa->dmp1, BN_FLG_CONSTTIME);
                }
        else
                dmp1 = rsa->dmp1;
@@ -757,7 +804,17 @@ static int RSA_eay_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx)
                if (!BN_add(r0,r0,rsa->p)) goto err;
 
        if (!BN_mul(r1,r0,rsa->iqmp,ctx)) goto err;
-       if (!BN_mod(r0,r1,rsa->p,ctx)) goto err;
+
+       /* Turn BN_FLG_CONSTTIME flag on before division operation */
+       if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME))
+               {
+               pr1 = &local_r1;
+               BN_with_flags(pr1, r1, BN_FLG_CONSTTIME);
+               }
+       else
+               pr1 = r1;
+       if (!BN_mod(r0,pr1,rsa->p,ctx)) goto err;
+
        /* If p < q it is occasionally possible for the correction of
          * adding 'p' if r0 is negative above to leave the result still
         * negative. This can break the private key operations: the following
@@ -790,10 +847,10 @@ static int RSA_eay_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx)
                        BIGNUM local_d;
                        BIGNUM *d = NULL;
                
-                       if (!(rsa->flags & RSA_FLAG_NO_EXP_CONSTTIME))
+                       if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME))
                                {
                                d = &local_d;
-                               BN_with_flags(d, rsa->d, BN_FLG_EXP_CONSTTIME);
+                               BN_with_flags(d, rsa->d, BN_FLG_CONSTTIME);
                                }
                        else
                                d = rsa->d;
index 742f8b1..767f7ab 100644 (file)
@@ -85,6 +85,8 @@ int RSA_generate_key_ex(RSA *rsa, int bits, BIGNUM *e_value, BN_GENCB *cb)
 static int rsa_builtin_keygen(RSA *rsa, int bits, BIGNUM *e_value, BN_GENCB *cb)
        {
        BIGNUM *r0=NULL,*r1=NULL,*r2=NULL,*r3=NULL,*tmp;
+       BIGNUM local_r0,local_d,local_p;
+       BIGNUM *pr0,*d,*p;
        int bitsp,bitsq,ok= -1,n=0;
        BN_CTX *ctx=NULL;
 
@@ -165,16 +167,39 @@ static int rsa_builtin_keygen(RSA *rsa, int bits, BIGNUM *e_value, BN_GENCB *cb)
        if (!BN_sub(r1,rsa->p,BN_value_one())) goto err;        /* p-1 */
        if (!BN_sub(r2,rsa->q,BN_value_one())) goto err;        /* q-1 */
        if (!BN_mul(r0,r1,r2,ctx)) goto err;    /* (p-1)(q-1) */
-       if (!BN_mod_inverse(rsa->d,rsa->e,r0,ctx)) goto err;    /* d */
+       if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME))
+               {
+                 pr0 = &local_r0;
+                 BN_with_flags(pr0, r0, BN_FLG_CONSTTIME);
+               }
+       else
+         pr0 = r0;
+       if (!BN_mod_inverse(rsa->d,rsa->e,pr0,ctx)) goto err;   /* d */
+
+       /* set up d for correct BN_FLG_CONSTTIME flag */
+       if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME))
+               {
+               d = &local_d;
+               BN_with_flags(d, rsa->d, BN_FLG_CONSTTIME);
+               }
+       else
+               d = rsa->d;
 
        /* calculate d mod (p-1) */
-       if (!BN_mod(rsa->dmp1,rsa->d,r1,ctx)) goto err;
+       if (!BN_mod(rsa->dmp1,d,r1,ctx)) goto err;
 
        /* calculate d mod (q-1) */
-       if (!BN_mod(rsa->dmq1,rsa->d,r2,ctx)) goto err;
+       if (!BN_mod(rsa->dmq1,d,r2,ctx)) goto err;
 
        /* calculate inverse of q mod p */
-       if (!BN_mod_inverse(rsa->iqmp,rsa->q,rsa->p,ctx)) goto err;
+       if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME))
+               {
+               p = &local_p;
+               BN_with_flags(p, rsa->p, BN_FLG_CONSTTIME);
+               }
+       else
+               p = rsa->p;
+       if (!BN_mod_inverse(rsa->iqmp,rsa->q,p,ctx)) goto err;
 
        ok=1;
 err:
index cca32c0..104aa4c 100644 (file)
@@ -361,7 +361,8 @@ err:
 
 BN_BLINDING *RSA_setup_blinding(RSA *rsa, BN_CTX *in_ctx)
 {
-       BIGNUM *e;
+       BIGNUM local_n;
+       BIGNUM *e,*n;
        BN_CTX *ctx;
        BN_BLINDING *ret = NULL;
 
@@ -400,7 +401,16 @@ BN_BLINDING *RSA_setup_blinding(RSA *rsa, BN_CTX *in_ctx)
                RAND_add(rsa->d->d, rsa->d->dmax * sizeof rsa->d->d[0], 0.0);
                }
 
-       ret = BN_BLINDING_create_param(NULL, e, rsa->n, ctx,
+       if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME))
+               {
+               /* Set BN_FLG_CONSTTIME flag */
+               n = &local_n;
+               BN_with_flags(n, rsa->n, BN_FLG_CONSTTIME);
+               }
+       else
+               n = rsa->n;
+
+       ret = BN_BLINDING_create_param(NULL, e, n, ctx,
                        rsa->meth->bn_mod_exp, rsa->_method_mod_n);
        if (ret == NULL)
                {
index d496f36..53df649 100644 (file)
 
 #include <openssl/stack.h>
 
-typedef void (*openssl_fptr)(void);
-#define openssl_fcast(f) ((openssl_fptr)f)
-
 #ifdef DEBUG_SAFESTACK
 
+#ifndef CHECKED_PTR_OF
+#define CHECKED_PTR_OF(type, p) \
+    ((void*) (1 ? p : (type*)0))
+#endif
+
+#define CHECKED_SK_FREE_FUNC(type, p) \
+    ((void (*)(void *)) ((1 ? p : (void (*)(type *))0)))
+
+#define CHECKED_SK_CMP_FUNC(type, p) \
+    ((int (*)(const char * const *, const char * const *)) \
+       ((1 ? p : (int (*)(const type * const *, const type * const *))0)))
+
 #define STACK_OF(type) struct stack_st_##type
 #define PREDECLARE_STACK_OF(type) STACK_OF(type);
 
@@ -76,76 +85,71 @@ STACK_OF(type) \
 /* SKM_sk_... stack macros are internal to safestack.h:
  * never use them directly, use sk_<type>_... instead */
 #define SKM_sk_new(type, cmp) \
-       ((STACK_OF(type) * (*)(int (*)(const type * const *, const type * const *)))openssl_fcast(sk_new))(cmp)
+       ((STACK_OF(type) *)sk_new(CHECKED_SK_CMP_FUNC(type, cmp)))
 #define SKM_sk_new_null(type) \
-       ((STACK_OF(type) * (*)(void))openssl_fcast(sk_new_null))()
+       ((STACK_OF(type) *)sk_new_null())
 #define SKM_sk_free(type, st) \
-       ((void (*)(STACK_OF(type) *))openssl_fcast(sk_free))(st)
+       sk_free(CHECKED_PTR_OF(STACK_OF(type), st))
 #define SKM_sk_num(type, st) \
-       ((int (*)(const STACK_OF(type) *))openssl_fcast(sk_num))(st)
+       sk_num(CHECKED_PTR_OF(STACK_OF(type), st))
 #define SKM_sk_value(type, st,i) \
-       ((type * (*)(const STACK_OF(type) *, int))openssl_fcast(sk_value))(st, i)
+       ((type *)sk_value(CHECKED_PTR_OF(STACK_OF(type), st), i))
 #define SKM_sk_set(type, st,i,val) \
-       ((type * (*)(STACK_OF(type) *, int, type *))openssl_fcast(sk_set))(st, i, val)
+       sk_set(CHECKED_PTR_OF(STACK_OF(type), st), i, CHECKED_PTR_OF(type, val))
 #define SKM_sk_zero(type, st) \
-       ((void (*)(STACK_OF(type) *))openssl_fcast(sk_zero))(st)
+       sk_zero(CHECKED_PTR_OF(STACK_OF(type), st))
 #define SKM_sk_push(type, st,val) \
-       ((int (*)(STACK_OF(type) *, type *))openssl_fcast(sk_push))(st, val)
+       sk_push(CHECKED_PTR_OF(STACK_OF(type), st), CHECKED_PTR_OF(type, val))
 #define SKM_sk_unshift(type, st,val) \
-       ((int (*)(STACK_OF(type) *, type *))openssl_fcast(sk_unshift))(st, val)
+       sk_unshift(CHECKED_PTR_OF(STACK_OF(type), st), CHECKED_PTR_OF(type, val))
 #define SKM_sk_find(type, st,val) \
-       ((int (*)(STACK_OF(type) *, type *))openssl_fcast(sk_find))(st, val)
+       sk_find(CHECKED_PTR_OF(STACK_OF(type), st), CHECKED_PTR_OF(type, val))
 #define SKM_sk_delete(type, st,i) \
-       ((type * (*)(STACK_OF(type) *, int))openssl_fcast(sk_delete))(st, i)
+       (type *)sk_delete(CHECKED_PTR_OF(STACK_OF(type), st), i)
 #define SKM_sk_delete_ptr(type, st,ptr) \
-       ((type * (*)(STACK_OF(type) *, type *))openssl_fcast(sk_delete_ptr))(st, ptr)
+       (type *)sk_delete_ptr(CHECKED_PTR_OF(STACK_OF(type), st), CHECKED_PTR_OF(type, ptr))
 #define SKM_sk_insert(type, st,val,i) \
-       ((int (*)(STACK_OF(type) *, type *, int))openssl_fcast(sk_insert))(st, val, i)
+       sk_insert(CHECKED_PTR_OF(STACK_OF(type), st), CHECKED_PTR_OF(type, val), i)
 #define SKM_sk_set_cmp_func(type, st,cmp) \
-       ((int (*(*)(STACK_OF(type) *, int (*)(const type * const *, const type * const *))) \
-         (const type * const *, const type * const *))openssl_fcast(sk_set_cmp_func))\
-       (st, cmp)
+       ((int (*)(const type * const *,const type * const *)) \
+       sk_set_cmp_func(CHECKED_PTR_OF(STACK_OF(type), st), CHECKED_SK_CMP_FUNC(type, cmp)))
 #define SKM_sk_dup(type, st) \
-       ((STACK_OF(type) *(*)(STACK_OF(type) *))openssl_fcast(sk_dup))(st)
+       (STACK_OF(type) *)sk_dup(CHECKED_PTR_OF(STACK_OF(type), st))
 #define SKM_sk_pop_free(type, st,free_func) \
-       ((void (*)(STACK_OF(type) *, void (*)(type *)))openssl_fcast(sk_pop_free))\
-       (st, free_func)
+       sk_pop_free(CHECKED_PTR_OF(STACK_OF(type), st), CHECKED_SK_FREE_FUNC(type, free_func))
 #define SKM_sk_shift(type, st) \
-       ((type * (*)(STACK_OF(type) *))openssl_fcast(sk_shift))(st)
+       (type *)sk_shift(CHECKED_PTR_OF(STACK_OF(type), st))
 #define SKM_sk_pop(type, st) \
-       ((type * (*)(STACK_OF(type) *))openssl_fcast(sk_pop))(st)
+       (type *)sk_pop(CHECKED_PTR_OF(STACK_OF(type), st))
 #define SKM_sk_sort(type, st) \
-       ((void (*)(STACK_OF(type) *))openssl_fcast(sk_sort))(st)
+       sk_sort(CHECKED_PTR_OF(STACK_OF(type), st))
 #define SKM_sk_is_sorted(type, st) \
-       ((int (*)(const STACK_OF(type) *))openssl_fcast(sk_is_sorted))(st)
+       sk_is_sorted(CHECKED_PTR_OF(STACK_OF(type), st))
 
 #define        SKM_ASN1_SET_OF_d2i(type, st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
-((STACK_OF(type) * (*) (STACK_OF(type) **,const unsigned char **, long , \
-                         type *(*)(type **, const unsigned char **,long), \
-                                void (*)(type *), int ,int )) openssl_fcast(d2i_ASN1_SET)) \
-                       (st,pp,length, d2i_func, free_func, ex_tag,ex_class)
+       (STACK_OF(type) *)d2i_ASN1_SET(CHECKED_PTR_OF(STACK_OF(type), st), \
+                               pp, length, \
+                               CHECKED_D2I_OF(type, d2i_func), \
+                               CHECKED_SK_FREE_FUNC(type, free_func), \
+                               ex_tag, ex_class)
+
 #define        SKM_ASN1_SET_OF_i2d(type, st, pp, i2d_func, ex_tag, ex_class, is_set) \
-       ((int (*)(STACK_OF(type) *,unsigned char **, \
-        int (*)(type *,unsigned char **), int , int , int)) openssl_fcast(i2d_ASN1_SET)) \
-                                               (st,pp,i2d_func,ex_tag,ex_class,is_set)
+       i2d_ASN1_SET(CHECKED_PTR_OF(STACK_OF(type), st), pp, \
+                               CHECKED_I2D_OF(type, i2d_func), \
+                               ex_tag, ex_class, is_set)
 
 #define        SKM_ASN1_seq_pack(type, st, i2d_func, buf, len) \
-       ((unsigned char *(*)(STACK_OF(type) *, \
-        int (*)(type *,unsigned char **), unsigned char **,int *)) openssl_fcast(ASN1_seq_pack)) \
-                               (st, i2d_func, buf, len)
+       ASN1_seq_pack(CHECKED_PTR_OF(STACK_OF(type), st), \
+                       CHECKED_I2D_OF(type, i2d_func), buf, len)
+
 #define        SKM_ASN1_seq_unpack(type, buf, len, d2i_func, free_func) \
-       ((STACK_OF(type) * (*)(const unsigned char *,int, \
-                              type *(*)(type **,const unsigned char **, long), \
-                              void (*)(type *)))openssl_fcast(ASN1_seq_unpack)) \
-                                       (buf,len,d2i_func, free_func)
+       (STACK_OF(type) *)ASN1_seq_unpack(buf, len, CHECKED_D2I_OF(type, d2i_func), CHECKED_SK_FREE_FUNC(type, free_func))
 
 #define SKM_PKCS12_decrypt_d2i(type, algor, d2i_func, free_func, pass, passlen, oct, seq) \
-       ((STACK_OF(type) * (*)(X509_ALGOR *, \
-                       type *(*)(type **, const unsigned char **, long), \
-                               void (*)(type *), \
-                                const char *, int, \
-                                ASN1_STRING *, int))PKCS12_decrypt_d2i) \
-                               (algor,d2i_func,free_func,pass,passlen,oct,seq)
+       (STACK_OF(type) *)PKCS12_decrypt_d2i(algor, \
+                               CHECKED_D2I_OF(type, d2i_func), \
+                               CHECKED_SK_FREE_FUNC(type, free_func), \
+                               pass, passlen, oct, seq)
 
 #else
 
index c0ad763..32ae5bd 100644 (file)
@@ -236,7 +236,7 @@ const STORE_METHOD *STORE_set_method(STORE *store, const STORE_METHOD *meth)
 #define check_store(s,fncode,fnname,fnerrcode) \
        do \
                { \
-               if ((s) == NULL || (s)->meth) \
+               if ((s) == NULL || (s)->meth == NULL) \
                        { \
                        STOREerr((fncode), ERR_R_PASSED_NULL_PARAMETER); \
                        return 0; \
index a80c87e..73a8ec7 100644 (file)
@@ -129,7 +129,7 @@ const char *X509_verify_cert_error_string(long n)
        case X509_V_ERR_PROXY_PATH_LENGTH_EXCEEDED:
                return("proxy path length constraint exceeded");
        case X509_V_ERR_PROXY_CERTIFICATES_NOT_ALLOWED:
-               return("proxy cerificates not allowed, please set the appropriate flag");
+               return("proxy certificates not allowed, please set the appropriate flag");
        case X509_V_ERR_INVALID_PURPOSE:
                return ("unsupported certificate purpose");
        case X509_V_ERR_CERT_UNTRUSTED:
index 07df21f..9a62ebc 100644 (file)
@@ -164,7 +164,7 @@ int X509_verify_cert(X509_STORE_CTX *ctx)
                                        goto end;
                                        }
                                CRYPTO_add(&xtmp->references,1,CRYPTO_LOCK_X509);
-                               sk_X509_delete_ptr(sktmp,xtmp);
+                               (void)sk_X509_delete_ptr(sktmp,xtmp);
                                ctx->last_untrusted++;
                                x=xtmp;
                                num++;
@@ -214,7 +214,7 @@ int X509_verify_cert(X509_STORE_CTX *ctx)
                                 */
                                X509_free(x);
                                x = xtmp;
-                               sk_X509_set(ctx->chain, i - 1, x);
+                               (void)sk_X509_set(ctx->chain, i - 1, x);
                                ctx->last_untrusted=0;
                                }
                        }
index 5e69259..e9db6d6 100644 (file)
@@ -385,7 +385,7 @@ int X509_VERIFY_PARAM_add0_table(X509_VERIFY_PARAM *param)
                        {
                        ptmp = sk_X509_VERIFY_PARAM_value(param_table, idx);
                        X509_VERIFY_PARAM_free(ptmp);
-                       sk_X509_VERIFY_PARAM_delete(param_table, idx);
+                       (void)sk_X509_VERIFY_PARAM_delete(param_table, idx);
                        }
                }
        if (!sk_X509_VERIFY_PARAM_push(param_table, param))
index 27d29f2..4fda1d4 100644 (file)
@@ -345,7 +345,7 @@ static int tree_prune(X509_POLICY_TREE *tree, X509_POLICY_LEVEL *curr)
                        {
                        node->parent->nchild--;
                        OPENSSL_free(node);
-                       sk_X509_POLICY_NODE_delete(curr->nodes, i);
+                       (void)sk_X509_POLICY_NODE_delete(curr->nodes, i);
                        }
                }
 
@@ -358,7 +358,7 @@ static int tree_prune(X509_POLICY_TREE *tree, X509_POLICY_LEVEL *curr)
                                {
                                node->parent->nchild--;
                                OPENSSL_free(node);
-                               sk_X509_POLICY_NODE_delete(curr->nodes, i);
+                               (void)sk_X509_POLICY_NODE_delete(curr->nodes, i);
                                }
                        }
                if (curr->anyPolicy && !curr->anyPolicy->nchild)
index 5158b1d..601211f 100644 (file)
@@ -286,12 +286,6 @@ static PROXY_CERT_INFO_EXTENSION *r2i_pci(X509V3_EXT_METHOD *method,
                X509V3err(X509V3_F_R2I_PCI,ERR_R_MALLOC_FAILURE);
                goto err;
                }
-       pci->proxyPolicy = PROXY_POLICY_new();
-       if (!pci->proxyPolicy)
-               {
-               X509V3err(X509V3_F_R2I_PCI,ERR_R_MALLOC_FAILURE);
-               goto err;
-               }
 
        pci->proxyPolicy->policyLanguage = language; language = NULL;
        pci->proxyPolicy->policy = policy; policy = NULL;
@@ -301,11 +295,6 @@ err:
        if (language) { ASN1_OBJECT_free(language); language = NULL; }
        if (pathlen) { ASN1_INTEGER_free(pathlen); pathlen = NULL; }
        if (policy) { ASN1_OCTET_STRING_free(policy); policy = NULL; }
-       if (pci && pci->proxyPolicy)
-               {
-               PROXY_POLICY_free(pci->proxyPolicy);
-               pci->proxyPolicy = NULL;
-               }
        if (pci) { PROXY_CERT_INFO_EXTENSION_free(pci); pci = NULL; }
 end:
        sk_CONF_VALUE_pop_free(vals, X509V3_conf_free);
index 8b6c98b..e8389de 100644 (file)
@@ -822,11 +822,11 @@ static int ubsec_dsa_verify(const unsigned char *dgst, int dgst_len,
        int v_len, d_len;
        int to_return = 0;
        int fd;
-       BIGNUM v;
+       BIGNUM v, *pv = &v;
 
        BN_init(&v);
 
-       if(!bn_wexpand(&v, dsa->p->top)) {
+       if(!bn_wexpand(pv, dsa->p->top)) {
                UBSECerr(UBSEC_F_UBSEC_DSA_VERIFY, UBSEC_R_BN_EXPAND_FAIL);
                goto err;
        }
index b746a50..22bd28a 100644 (file)
@@ -138,38 +138,40 @@ static void dtls1_set_message_header_int(SSL *s, unsigned char mt,
        unsigned long frag_len);
 static int dtls1_retransmit_buffered_messages(SSL *s);
 static long dtls1_get_message_fragment(SSL *s, int st1, int stn, 
-    long max, int *ok);
-static void dtls1_process_handshake_fragment(SSL *s, int frag_len);
+       long max, int *ok);
 
 static hm_fragment *
 dtls1_hm_fragment_new(unsigned long frag_len)
-    {
-    hm_fragment *frag = NULL;
-    unsigned char *buf = NULL;
-
-    frag = (hm_fragment *)OPENSSL_malloc(sizeof(hm_fragment));
-    if ( frag == NULL)
-        return NULL;
-
-    buf = (unsigned char *)OPENSSL_malloc(frag_len 
-        + DTLS1_HM_HEADER_LENGTH);
-    if ( buf == NULL)
-        {
-        OPENSSL_free(frag);
-        return NULL;
-        }
-    
-    frag->fragment = buf;
-
-    return frag;
-    }
+       {
+       hm_fragment *frag = NULL;
+       unsigned char *buf = NULL;
+
+       frag = (hm_fragment *)OPENSSL_malloc(sizeof(hm_fragment));
+       if ( frag == NULL)
+               return NULL;
+
+       if (frag_len)
+               {
+               buf = (unsigned char *)OPENSSL_malloc(frag_len);
+               if ( buf == NULL)
+                       {
+                       OPENSSL_free(frag);
+                       return NULL;
+                       }
+               }
+
+       /* zero length fragment gets zero frag->fragment */
+       frag->fragment = buf;
+
+       return frag;
+       }
 
 static void
 dtls1_hm_fragment_free(hm_fragment *frag)
-    {
-    OPENSSL_free(frag->fragment);
-    OPENSSL_free(frag);
-    }
+       {
+       if (frag->fragment) OPENSSL_free(frag->fragment);
+       OPENSSL_free(frag);
+       }
 
 /* send s->init_buf in records of type 'type' (SSL3_RT_HANDSHAKE or SSL3_RT_CHANGE_CIPHER_SPEC) */
 int dtls1_do_write(SSL *s, int type)
@@ -180,7 +182,7 @@ int dtls1_do_write(SSL *s, int type)
 
        /* AHA!  Figure out the MTU, and stick to the right size */
        if ( ! (SSL_get_options(s) & SSL_OP_NO_QUERY_MTU))
-        {
+               {
                s->d1->mtu = 
                        BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_QUERY_MTU, 0, NULL);
 
@@ -207,7 +209,7 @@ int dtls1_do_write(SSL *s, int type)
                mtu = curr_mtu;
        else if ( ( ret = BIO_flush(SSL_get_wbio(s))) <= 0)
                return ret;
-               
+
        if ( BIO_wpending(SSL_get_wbio(s)) + s->init_num >= mtu)
                {
                ret = BIO_flush(SSL_get_wbio(s));
@@ -254,11 +256,11 @@ int dtls1_do_write(SSL *s, int type)
                                s->init_off -= DTLS1_HM_HEADER_LENGTH;
                                s->init_num += DTLS1_HM_HEADER_LENGTH;
 
-                /* write atleast DTLS1_HM_HEADER_LENGTH bytes */
+                               /* write atleast DTLS1_HM_HEADER_LENGTH bytes */
                                if ( len <= DTLS1_HM_HEADER_LENGTH)  
                                        len += DTLS1_HM_HEADER_LENGTH;
                                }
-                       
+
                        dtls1_fix_message_header(s, frag_off, 
                                len - DTLS1_HM_HEADER_LENGTH);
 
@@ -286,18 +288,40 @@ int dtls1_do_write(SSL *s, int type)
                        }
                else
                        {
-                       
+
                        /* bad if this assert fails, only part of the handshake
                         * message got sent.  but why would this happen? */
-                       OPENSSL_assert(len == (unsigned int)ret); 
-                       
+                       OPENSSL_assert(len == (unsigned int)ret);
+
                        if (type == SSL3_RT_HANDSHAKE && ! s->d1->retransmitting)
+                               {
                                /* should not be done for 'Hello Request's, but in that case
                                 * we'll ignore the result anyway */
-                               ssl3_finish_mac(s, 
-                                       (unsigned char *)&s->init_buf->data[s->init_off + 
-                                               DTLS1_HM_HEADER_LENGTH], ret - DTLS1_HM_HEADER_LENGTH);
-                       
+                               unsigned char *p = &s->init_buf->data[s->init_off];
+                               const struct hm_header_st *msg_hdr = &s->d1->w_msg_hdr;
+                               int len;
+
+                               if (frag_off == 0 && s->client_version != DTLS1_BAD_VER)
+                                       {
+                                       /* reconstruct message header is if it
+                                        * is being sent in single fragment */
+                                       *p++ = msg_hdr->type;
+                                       l2n3(msg_hdr->msg_len,p);
+                                       s2n (msg_hdr->seq,p);
+                                       l2n3(0,p);
+                                       l2n3(msg_hdr->msg_len,p);
+                                       p  -= DTLS1_HM_HEADER_LENGTH;
+                                       len = ret;
+                                       }
+                               else
+                                       {
+                                       p  += DTLS1_HM_HEADER_LENGTH;
+                                       len = ret - DTLS1_HM_HEADER_LENGTH;
+                                       }
+
+                               ssl3_finish_mac(s, p, len);
+                               }
+
                        if (ret == s->init_num)
                                {
                                if (s->msg_callback)
@@ -307,7 +331,7 @@ int dtls1_do_write(SSL *s, int type)
 
                                s->init_off = 0;  /* done writing this message */
                                s->init_num = 0;
-                               
+
                                return(1);
                                }
                        s->init_off+=ret;
@@ -327,6 +351,7 @@ int dtls1_do_write(SSL *s, int type)
 long dtls1_get_message(SSL *s, int st1, int stn, int mt, long max, int *ok)
        {
        int i, al;
+       struct hm_header_st *msg_hdr;
 
        /* s3->tmp is used to store messages that are unexpected, caused
         * by the absence of an optional handshake message */
@@ -344,25 +369,56 @@ long dtls1_get_message(SSL *s, int st1, int stn, int mt, long max, int *ok)
                s->init_num = (int)s->s3->tmp.message_size;
                return s->init_num;
                }
-       
+
+       msg_hdr = &s->d1->r_msg_hdr;
        do
                {
-               if ( s->d1->r_msg_hdr.frag_off == 0)
+               if ( msg_hdr->frag_off == 0)
                        {
                        /* s->d1->r_message_header.msg_len = 0; */
-                       memset(&(s->d1->r_msg_hdr), 0x00, sizeof(struct hm_header_st));
+                       memset(msg_hdr, 0x00, sizeof(struct hm_header_st));
                        }
 
                i = dtls1_get_message_fragment(s, st1, stn, max, ok);
                if ( i == DTLS1_HM_BAD_FRAGMENT ||
-            i == DTLS1_HM_FRAGMENT_RETRY)  /* bad fragment received */
+                       i == DTLS1_HM_FRAGMENT_RETRY)  /* bad fragment received */
                        continue;
                else if ( i <= 0 && !*ok)
                        return i;
 
-               if (s->d1->r_msg_hdr.msg_len == (unsigned int)s->init_num - DTLS1_HM_HEADER_LENGTH)
+               /* Note that s->init_sum is used as a counter summing
+                * up fragments' lengths: as soon as they sum up to
+                * handshake packet length, we assume we have got all
+                * the fragments. Overlapping fragments would cause
+                * premature termination, so we don't expect overlaps.
+                * Well, handling overlaps would require something more
+                * drastic. Indeed, as it is now there is no way to
+                * tell if out-of-order fragment from the middle was
+                * the last. '>=' is the best/least we can do to control
+                * the potential damage caused by malformed overlaps. */
+               if ((unsigned int)s->init_num >= msg_hdr->msg_len)
                        {
-                       memset(&(s->d1->r_msg_hdr), 0x00, sizeof(struct hm_header_st));
+                       unsigned char *p = s->init_buf->data;
+                       unsigned long msg_len = msg_hdr->msg_len;
+
+                       /* reconstruct message header as if it was
+                        * sent in single fragment */
+                       *(p++) = msg_hdr->type;
+                       l2n3(msg_len,p);
+                       s2n (msg_hdr->seq,p);
+                       l2n3(0,p);
+                       l2n3(msg_len,p);
+                       if (s->client_version != DTLS1_BAD_VER)
+                               p       -= DTLS1_HM_HEADER_LENGTH,
+                               msg_len += DTLS1_HM_HEADER_LENGTH;
+
+                       ssl3_finish_mac(s, p, msg_len);
+                       if (s->msg_callback)
+                               s->msg_callback(0, s->version, SSL3_RT_HANDSHAKE,
+                                       p, msg_len,
+                                       s, s->msg_callback_arg);
+
+                       memset(msg_hdr, 0x00, sizeof(struct hm_header_st));
 
                        s->d1->handshake_read_seq++;
                        /* we just read a handshake message from the other side:
@@ -379,11 +435,11 @@ long dtls1_get_message(SSL *s, int st1, int stn, int mt, long max, int *ok)
                         * first data  segment, but is there a better way?  */
                        dtls1_clear_record_buffer(s);
 
-            s->init_msg = s->init_buf->data + DTLS1_HM_HEADER_LENGTH;
-                       return s->init_num - DTLS1_HM_HEADER_LENGTH;
+                       s->init_msg = s->init_buf->data + DTLS1_HM_HEADER_LENGTH;
+                       return s->init_num;
                        }
                else
-                       s->d1->r_msg_hdr.frag_off = i;
+                       msg_hdr->frag_off = i;
                } while(1) ;
 
 f_err:
@@ -393,161 +449,183 @@ f_err:
        }
 
 
-static int
-dtls1_retrieve_buffered_fragment(SSL *s, unsigned long *copied)
-    {
-    /* (0) check whether the desired fragment is available
-     * if so:
-     * (1) copy over the fragment to s->init_buf->data[]
-     * (2) update s->init_num
-     */
-    pitem *item;
-    hm_fragment *frag;
-    unsigned long overlap;
-    unsigned char *p;
-
-    item = pqueue_peek(s->d1->buffered_messages);
-    if ( item == NULL)
-        return 0;
-
-    frag = (hm_fragment *)item->data;
-    
-    if ( s->d1->handshake_read_seq == frag->msg_header.seq &&
-        frag->msg_header.frag_off <= (unsigned int)s->init_num - DTLS1_HM_HEADER_LENGTH)
-        {
-        pqueue_pop(s->d1->buffered_messages);
-        overlap = s->init_num - DTLS1_HM_HEADER_LENGTH 
-            - frag->msg_header.frag_off;
-
-        p = frag->fragment;
-
-        memcpy(&s->init_buf->data[s->init_num],
-            p + DTLS1_HM_HEADER_LENGTH + overlap,
-            frag->msg_header.frag_len - overlap);
-    
-        OPENSSL_free(frag->fragment);
-        OPENSSL_free(frag);
-        pitem_free(item);
-
-        *copied = frag->msg_header.frag_len - overlap;
-        return *copied;
-        }
-    else
-        return 0;
-    }
+static int dtls1_preprocess_fragment(SSL *s,struct hm_header_st *msg_hdr,int max)
+       {
+       size_t frag_off,frag_len,msg_len;
 
+       msg_len  = msg_hdr->msg_len;
+       frag_off = msg_hdr->frag_off;
+       frag_len = msg_hdr->frag_len;
 
-static int
-dtls1_buffer_handshake_fragment(SSL *s, struct hm_header_st* msg_hdr)
-{
-    hm_fragment *frag = NULL;
-    pitem *item = NULL;
-       PQ_64BIT seq64;
+       /* sanity checking */
+       if ( (frag_off+frag_len) > msg_len)
+               {
+               SSLerr(SSL_F_DTLS1_PREPROCESS_FRAGMENT,SSL_R_EXCESSIVE_MESSAGE_SIZE);
+               return SSL_AD_ILLEGAL_PARAMETER;
+               }
 
-    frag = dtls1_hm_fragment_new(msg_hdr->frag_len);
-    if ( frag == NULL)
-        goto err;
+       if ( (frag_off+frag_len) > (unsigned long)max)
+               {
+               SSLerr(SSL_F_DTLS1_PREPROCESS_FRAGMENT,SSL_R_EXCESSIVE_MESSAGE_SIZE);
+               return SSL_AD_ILLEGAL_PARAMETER;
+               }
 
-    memcpy(frag->fragment, &(s->init_buf->data[s->init_num]),
-        msg_hdr->frag_len + DTLS1_HM_HEADER_LENGTH);
+       if ( s->d1->r_msg_hdr.frag_off == 0) /* first fragment */
+               {
+               /* msg_len is limited to 2^24, but is effectively checked
+                * against max above */
+               if (!BUF_MEM_grow_clean(s->init_buf,(int)msg_len+DTLS1_HM_HEADER_LENGTH))
+                       {
+                       SSLerr(SSL_F_DTLS1_PREPROCESS_FRAGMENT,ERR_R_BUF_LIB);
+                       return SSL_AD_INTERNAL_ERROR;
+                       }
 
-    memcpy(&(frag->msg_header), msg_hdr, sizeof(*msg_hdr));
+               s->s3->tmp.message_size  = msg_len;
+               s->d1->r_msg_hdr.msg_len = msg_len;
+               s->s3->tmp.message_type  = msg_hdr->type;
+               s->d1->r_msg_hdr.type    = msg_hdr->type;
+               s->d1->r_msg_hdr.seq     = msg_hdr->seq;
+               }
+       else if (msg_len != s->d1->r_msg_hdr.msg_len)
+               {
+               /* They must be playing with us! BTW, failure to enforce
+                * upper limit would open possibility for buffer overrun. */
+               SSLerr(SSL_F_DTLS1_PREPROCESS_FRAGMENT,SSL_R_EXCESSIVE_MESSAGE_SIZE);
+               return SSL_AD_ILLEGAL_PARAMETER;
+               }
+
+       return 0; /* no error */
+       }
 
-    pq_64bit_init(&seq64);
-    pq_64bit_assign_word(&seq64, msg_hdr->seq);
 
-    item = pitem_new(seq64, frag);
-    if ( item == NULL)
-        goto err;
+static int
+dtls1_retrieve_buffered_fragment(SSL *s, long max, int *ok)
+       {
+       /* (0) check whether the desired fragment is available
+        * if so:
+        * (1) copy over the fragment to s->init_buf->data[]
+        * (2) update s->init_num
+        */
+       pitem *item;
+       hm_fragment *frag;
+       int al;
 
-    pq_64bit_free(&seq64);
+       *ok = 0;
+       item = pqueue_peek(s->d1->buffered_messages);
+       if ( item == NULL)
+               return 0;
 
-    pqueue_insert(s->d1->buffered_messages, item);
-    return 1;
+       frag = (hm_fragment *)item->data;
 
-err:
-    if ( frag != NULL) dtls1_hm_fragment_free(frag);
-    if ( item != NULL) OPENSSL_free(item);
-    return 0;
-}
+       if ( s->d1->handshake_read_seq == frag->msg_header.seq)
+               {
+               pqueue_pop(s->d1->buffered_messages);
 
+               al=dtls1_preprocess_fragment(s,&frag->msg_header,max);
 
-static void
-dtls1_process_handshake_fragment(SSL *s, int frag_len)
-    {
-    unsigned char *p;
+               if (al==0) /* no alert */
+                       {
+                       unsigned char *p = s->init_buf->data+DTLS1_HM_HEADER_LENGTH;
+                       memcpy(&p[frag->msg_header.frag_off],
+                               frag->fragment,frag->msg_header.frag_len);
+                       }
 
-    p = (unsigned char *)s->init_buf->data;
+               dtls1_hm_fragment_free(frag);
+               pitem_free(item);
 
-       ssl3_finish_mac(s, &p[s->init_num - frag_len], frag_len);
-    }
+               if (al==0)
+                       {
+                       *ok = 1;
+                       return frag->msg_header.frag_len;
+                       }
+
+               ssl3_send_alert(s,SSL3_AL_FATAL,al);
+               s->init_num = 0;
+               *ok = 0;
+               return -1;
+               }
+       else
+               return 0;
+       }
 
 
 static int
-dtls1_process_out_of_seq_message(SSL *s, struct hm_header_st *msg_hdr, int *ok)
-    {
-    int i;
-    unsigned char *p;
-
-    /* make sure there's enough room to read this fragment */
-    if ( (int)msg_hdr->frag_len && !BUF_MEM_grow_clean(s->init_buf, 
-             (int)msg_hdr->frag_len + DTLS1_HM_HEADER_LENGTH + s->init_num))
-        {
-        SSLerr(SSL_F_DTLS1_PROCESS_OUT_OF_SEQ_MESSAGE,ERR_R_BUF_LIB);
-        goto err;
-        }
-
-    p = (unsigned char *)s->init_buf->data;
-
-    /* read the body of the fragment (header has already been read */
-    if ( msg_hdr->frag_len > 0)
+dtls1_process_out_of_seq_message(SSL *s, struct hm_header_st* msg_hdr, int *ok)
+{
+       int i=-1;
+       hm_fragment *frag = NULL;
+       pitem *item = NULL;
+       PQ_64BIT seq64;
+       unsigned long frag_len = msg_hdr->frag_len;
+
+       if ((msg_hdr->frag_off+frag_len) > msg_hdr->msg_len)
+               goto err;
+
+       if (msg_hdr->seq <= s->d1->handshake_read_seq)
                {
-               i=s->method->ssl_read_bytes(s,SSL3_RT_HANDSHAKE,
-            &p[s->init_num], 
-            msg_hdr->frag_len,0);
-               if (i <= 0)
+               unsigned char devnull [256];
+
+               while (frag_len)
                        {
-                       *ok = 0;
-                       return i;
+                       i = s->method->ssl_read_bytes(s,SSL3_RT_HANDSHAKE,
+                               devnull,
+                               frag_len>sizeof(devnull)?sizeof(devnull):frag_len,0);
+                       if (i<=0) goto err;
+                       frag_len -= i;
                        }
                }
 
-    if ( msg_hdr->seq > s->d1->handshake_read_seq)
-        dtls1_buffer_handshake_fragment(s, msg_hdr);
-    else
-        OPENSSL_assert(msg_hdr->seq < s->d1->handshake_read_seq);
+       frag = dtls1_hm_fragment_new(frag_len);
+       if ( frag == NULL)
+               goto err;
+
+       memcpy(&(frag->msg_header), msg_hdr, sizeof(*msg_hdr));
+
+       if (frag_len)
+               {
+               /* read the body of the fragment (header has already been read */
+               i = s->method->ssl_read_bytes(s,SSL3_RT_HANDSHAKE,
+                       frag->fragment,frag_len,0);
+               if (i<=0 || (unsigned long)i!=frag_len)
+                       goto err;
+               }
+
+       pq_64bit_init(&seq64);
+       pq_64bit_assign_word(&seq64, msg_hdr->seq);
+
+       item = pitem_new(seq64, frag);
+       pq_64bit_free(&seq64);
+       if ( item == NULL)
+               goto err;
+
+       pqueue_insert(s->d1->buffered_messages, item);
+       return DTLS1_HM_FRAGMENT_RETRY;
 
-    return DTLS1_HM_FRAGMENT_RETRY;
 err:
-    *ok = 0;
-    return -1;
-    }
+       if ( frag != NULL) dtls1_hm_fragment_free(frag);
+       if ( item != NULL) OPENSSL_free(item);
+       *ok = 0;
+       return i;
+       }
 
 
 static long
 dtls1_get_message_fragment(SSL *s, int st1, int stn, long max, int *ok)
        {
-       unsigned char *p;
+       unsigned char wire[DTLS1_HM_HEADER_LENGTH];
        unsigned long l, frag_off, frag_len;
        int i,al;
        struct hm_header_st msg_hdr;
-    unsigned long overlap;
-    
-    /* see if we have the required fragment already */
-    if (dtls1_retrieve_buffered_fragment(s, &l))
-    {
-        /* compute MAC, remove fragment headers */
-        dtls1_process_handshake_fragment(s, l);
-        s->init_msg = s->init_buf->data + DTLS1_HM_HEADER_LENGTH;
-        s->state = stn;
-        return 1;
-    }
-
-    /* get a handshake fragment from the record layer */
-       p = (unsigned char *)s->init_buf->data;
-
-    /* read handshake message header */
-       i=s->method->ssl_read_bytes(s,SSL3_RT_HANDSHAKE,&p[s->init_num],
+
+       /* see if we have the required fragment already */
+       if ((frag_len = dtls1_retrieve_buffered_fragment(s,max,ok)) || *ok)
+               {
+               if (*ok)        s->init_num += frag_len;
+               return frag_len;
+               }
+
+       /* read handshake message header */
+       i=s->method->ssl_read_bytes(s,SSL3_RT_HANDSHAKE,wire,
                DTLS1_HM_HEADER_LENGTH, 0);
        if (i <= 0)     /* nbio, or an error */
                {
@@ -555,130 +633,61 @@ dtls1_get_message_fragment(SSL *s, int st1, int stn, long max, int *ok)
                *ok = 0;
                return i;
                }
-
        OPENSSL_assert(i == DTLS1_HM_HEADER_LENGTH);
 
-       p += s->init_num;
-    /* parse the message fragment header */
-    
-    dtls1_get_message_header(p, &msg_hdr);
+       /* parse the message fragment header */
+       dtls1_get_message_header(wire, &msg_hdr);
 
-    /* 
-     * if this is a future (or stale) message it gets buffered
-     * (or dropped)--no further processing at this time 
-     */
-    if ( msg_hdr.seq != s->d1->handshake_read_seq)
-        return dtls1_process_out_of_seq_message(s, &msg_hdr, ok);
+       /* 
+        * if this is a future (or stale) message it gets buffered
+        * (or dropped)--no further processing at this time 
+        */
+       if ( msg_hdr.seq != s->d1->handshake_read_seq)
+               return dtls1_process_out_of_seq_message(s, &msg_hdr, ok);
 
-    l = msg_hdr.msg_len;
-    frag_off = msg_hdr.frag_off;
+       l = msg_hdr.msg_len;
+       frag_off = msg_hdr.frag_off;
        frag_len = msg_hdr.frag_len;
 
-    /* sanity checking */
-    if ( frag_off + frag_len > l)
-        {
-        al=SSL_AD_ILLEGAL_PARAMETER;
-        SSLerr(SSL_F_DTLS1_GET_MESSAGE_FRAGMENT,SSL_R_EXCESSIVE_MESSAGE_SIZE);
-        goto f_err;
-        }
-
        if (!s->server && s->d1->r_msg_hdr.frag_off == 0 &&
-        p[0] == SSL3_MT_HELLO_REQUEST)
-        {
-        /* The server may always send 'Hello Request' messages --
-         * we are doing a handshake anyway now, so ignore them
-         * if their format is correct. Does not count for
-         * 'Finished' MAC. */
-        if (p[1] == 0 && p[2] == 0 &&p[3] == 0)
-            {
-            if (s->msg_callback)
-                s->msg_callback(0, s->version, SSL3_RT_HANDSHAKE, 
-                    p, DTLS1_HM_HEADER_LENGTH, s, 
-                    s->msg_callback_arg);
-            
-            s->init_num = 0;
-            return dtls1_get_message_fragment(s, st1, stn,
-                max, ok);
-            }
-        else /* Incorrectly formated Hello request */
-            {
-            al=SSL_AD_UNEXPECTED_MESSAGE;
-            SSLerr(SSL_F_DTLS1_GET_MESSAGE_FRAGMENT,SSL_R_UNEXPECTED_MESSAGE);
-            goto f_err;
-            }
-        }
-
-    /* XDTLS: do a sanity check on the fragment */
-
-    s->init_num += i;
-
-       if ( s->d1->r_msg_hdr.frag_off == 0) /* first fragment */
+               wire[0] == SSL3_MT_HELLO_REQUEST)
                {
-               /* BUF_MEM_grow takes an 'int' parameter */
-               if (l > (INT_MAX-DTLS1_HM_HEADER_LENGTH)) 
-                       {
-                       al=SSL_AD_ILLEGAL_PARAMETER;
-                       SSLerr(SSL_F_DTLS1_GET_MESSAGE_FRAGMENT,SSL_R_EXCESSIVE_MESSAGE_SIZE);
-                       goto f_err;
-                       }
-               if (l && !BUF_MEM_grow_clean(s->init_buf,(int)l
-                       + DTLS1_HM_HEADER_LENGTH))
+               /* The server may always send 'Hello Request' messages --
+                * we are doing a handshake anyway now, so ignore them
+                * if their format is correct. Does not count for
+                * 'Finished' MAC. */
+               if (wire[1] == 0 && wire[2] == 0 && wire[3] == 0)
                        {
-                       SSLerr(SSL_F_DTLS1_GET_MESSAGE_FRAGMENT,ERR_R_BUF_LIB);
-                       goto err;
+                       if (s->msg_callback)
+                               s->msg_callback(0, s->version, SSL3_RT_HANDSHAKE, 
+                                       wire, DTLS1_HM_HEADER_LENGTH, s, 
+                                       s->msg_callback_arg);
+                       
+                       s->init_num = 0;
+                       return dtls1_get_message_fragment(s, st1, stn,
+                               max, ok);
                        }
-        /* Only do this test when we're reading the expected message.
-         * Stale messages will be dropped and future messages will be buffered */
-        if ( l > (unsigned long)max)
+               else /* Incorrectly formated Hello request */
                        {
-                       al=SSL_AD_ILLEGAL_PARAMETER;
-                       SSLerr(SSL_F_DTLS1_GET_MESSAGE_FRAGMENT,SSL_R_EXCESSIVE_MESSAGE_SIZE);
+                       al=SSL_AD_UNEXPECTED_MESSAGE;
+                       SSLerr(SSL_F_DTLS1_GET_MESSAGE_FRAGMENT,SSL_R_UNEXPECTED_MESSAGE);
                        goto f_err;
                        }
-
-               s->s3->tmp.message_size=l;
                }
 
-    if ( frag_len > (unsigned long)max)
-        {
-        al=SSL_AD_ILLEGAL_PARAMETER;
-        SSLerr(SSL_F_DTLS1_GET_MESSAGE_FRAGMENT,SSL_R_EXCESSIVE_MESSAGE_SIZE);
-        goto f_err;
-        }
-    if ( frag_len + s->init_num > (INT_MAX - DTLS1_HM_HEADER_LENGTH))
-        {
-        al=SSL_AD_ILLEGAL_PARAMETER;
-        SSLerr(SSL_F_DTLS1_GET_MESSAGE_FRAGMENT,SSL_R_EXCESSIVE_MESSAGE_SIZE);
-        goto f_err;
-        }
-
-    if ( frag_len & !BUF_MEM_grow_clean(s->init_buf, (int)frag_len 
-             + DTLS1_HM_HEADER_LENGTH + s->init_num))
-        {
-        SSLerr(SSL_F_DTLS1_GET_MESSAGE_FRAGMENT,ERR_R_BUF_LIB);
-        goto err;
-        }
-
-       if ( s->d1->r_msg_hdr.frag_off == 0)
-               {
-               s->s3->tmp.message_type = msg_hdr.type;
-               s->d1->r_msg_hdr.type = msg_hdr.type;
-               s->d1->r_msg_hdr.msg_len = l;
-               /* s->d1->r_msg_hdr.seq = seq_num; */
-               }
+       if ((al=dtls1_preprocess_fragment(s,&msg_hdr,max)))
+               goto f_err;
 
        /* XDTLS:  ressurect this when restart is in place */
        s->state=stn;
-       
-       /* next state (stn) */
-       p = (unsigned char *)s->init_buf->data;
 
        if ( frag_len > 0)
                {
+               unsigned char *p=s->init_buf->data+DTLS1_HM_HEADER_LENGTH;
+
                i=s->method->ssl_read_bytes(s,SSL3_RT_HANDSHAKE,
-            &p[s->init_num], 
-            frag_len,0);
-        /* XDTLS:  fix this--message fragments cannot span multiple packets */
+                       &p[frag_off],frag_len,0);
+               /* XDTLS:  fix this--message fragments cannot span multiple packets */
                if (i <= 0)
                        {
                        s->rwstate=SSL_READING;
@@ -689,70 +698,23 @@ dtls1_get_message_fragment(SSL *s, int st1, int stn, long max, int *ok)
        else
                i = 0;
 
-    /* XDTLS:  an incorrectly formatted fragment should cause the 
-     * handshake to fail */
+       /* XDTLS:  an incorrectly formatted fragment should cause the 
+        * handshake to fail */
        OPENSSL_assert(i == (int)frag_len);
 
-#if 0
-    /* Successfully read a fragment.
-     * It may be (1) out of order, or
-     *           (2) it's a repeat, in which case we dump it
-     *           (3) the one we are expecting next (maybe with overlap)
-     * If it is next one, it may overlap with previously read bytes
-     */
-
-    /* case (1): buffer the future fragment 
-     * (we can treat fragments from a future message the same
-     * as future fragments from the message being currently read, since
-     * they are sematically simply out of order.
-     */
-    if ( msg_hdr.seq > s->d1->handshake_read_seq ||
-        frag_off > s->init_num - DTLS1_HM_HEADER_LENGTH)
-    {
-        dtls1_buffer_handshake_fragment(s, &msg_hdr);
-        return DTLS1_HM_FRAGMENT_RETRY;
-    }
-
-    /* case (2):  drop the entire fragment, and try again */
-    if ( msg_hdr.seq < s->d1->handshake_read_seq ||
-        frag_off + frag_len < s->init_num - DTLS1_HM_HEADER_LENGTH)
-        {
-        s->init_num -= DTLS1_HM_HEADER_LENGTH;
-        return DTLS1_HM_FRAGMENT_RETRY;
-        }
-#endif
+       *ok = 1;
 
-    /* case (3): received a immediately useful fragment.  Determine the 
-     * possible overlap and copy the fragment.
-     */
-    overlap = (s->init_num - DTLS1_HM_HEADER_LENGTH) - frag_off;
-        
-    /* retain the header for the first fragment */
-    if ( s->init_num > DTLS1_HM_HEADER_LENGTH)
-        {
-        memmove(&(s->init_buf->data[s->init_num]),
-            &(s->init_buf->data[s->init_num + DTLS1_HM_HEADER_LENGTH + overlap]),
-            frag_len - overlap);
-
-        s->init_num += frag_len - overlap;
-        }
-    else
-        s->init_num += frag_len;
-
-    dtls1_process_handshake_fragment(s, frag_len - overlap);
-
-       if (s->msg_callback)
-               s->msg_callback(0, s->version, SSL3_RT_HANDSHAKE, s->init_buf->data, 
-                       (size_t)s->init_num, s, 
-                       s->msg_callback_arg);
-       *ok=1;
-
-       return s->init_num;
+       /* Note that s->init_num is *not* used as current offset in
+        * s->init_buf->data, but as a counter summing up fragments'
+        * lengths: as soon as they sum up to handshake packet
+        * length, we assume we have got all the fragments. */
+       s->init_num += frag_len;
+       return frag_len;
 
 f_err:
        ssl3_send_alert(s,SSL3_AL_FATAL,al);
-    s->init_num = 0;
-err:
+       s->init_num = 0;
+
        *ok=0;
        return(-1);
        }
@@ -790,7 +752,7 @@ int dtls1_send_finished(SSL *s, int a, int b, const char *sender, int slen)
 
                /* buffer the message to handle re-xmits */
                dtls1_buffer_message(s, 0);
-               
+
                s->state=b;
                }
 
@@ -816,9 +778,14 @@ int dtls1_send_change_cipher_spec(SSL *s, int a, int b)
                *p++=SSL3_MT_CCS;
                s->d1->handshake_write_seq = s->d1->next_handshake_write_seq;
                s->d1->next_handshake_write_seq++;
-               s2n(s->d1->handshake_write_seq,p);
-
                s->init_num=DTLS1_CCS_HEADER_LENGTH;
+
+               if (s->client_version == DTLS1_BAD_VER)
+                       {
+                       s2n(s->d1->handshake_write_seq,p);
+                       s->init_num+=2;
+                       }
+
                s->init_off=0;
 
                dtls1_set_message_header_int(s, SSL3_MT_CCS, 0, 
@@ -915,316 +882,278 @@ unsigned long dtls1_output_cert_chain(SSL *s, X509 *x)
        }
 
 int dtls1_read_failed(SSL *s, int code)
-    {
-    DTLS1_STATE *state;
-    BIO *bio;
-    int send_alert = 0;
-
-    if ( code > 0)
-        {
-        fprintf( stderr, "invalid state reached %s:%d", __FILE__, __LINE__);
-        return 1;
-        }
-
-    bio = SSL_get_rbio(s);
-    if ( ! BIO_dgram_recv_timedout(bio))
-        {
-        /* not a timeout, none of our business, 
-           let higher layers handle this.  in fact it's probably an error */
-        return code;
-        }
-
-    if ( ! SSL_in_init(s))  /* done, no need to send a retransmit */
-        {
-        BIO_set_flags(SSL_get_rbio(s), BIO_FLAGS_READ);
-        return code;
-        }
-
-    state = s->d1;
-    state->timeout.num_alerts++;
-    if ( state->timeout.num_alerts > DTLS1_TMO_ALERT_COUNT)
-        {
-        /* fail the connection, enough alerts have been sent */
-        SSLerr(SSL_F_DTLS1_READ_FAILED,SSL_R_READ_TIMEOUT_EXPIRED);
-        return 0;
-        }
-       
-    state->timeout.read_timeouts++;
-    if ( state->timeout.read_timeouts > DTLS1_TMO_READ_COUNT)
-        {
-        send_alert = 1;
-        state->timeout.read_timeouts = 1;
-        }
-
-       
+       {
+       DTLS1_STATE *state;
+       BIO *bio;
+       int send_alert = 0;
+
+       if ( code > 0)
+               {
+               fprintf( stderr, "invalid state reached %s:%d", __FILE__, __LINE__);
+               return 1;
+               }
+
+       bio = SSL_get_rbio(s);
+       if ( ! BIO_dgram_recv_timedout(bio))
+               {
+               /* not a timeout, none of our business, 
+                  let higher layers handle this.  in fact it's probably an error */
+               return code;
+               }
+
+       if ( ! SSL_in_init(s))  /* done, no need to send a retransmit */
+               {
+               BIO_set_flags(SSL_get_rbio(s), BIO_FLAGS_READ);
+               return code;
+               }
+
+       state = s->d1;
+       state->timeout.num_alerts++;
+       if ( state->timeout.num_alerts > DTLS1_TMO_ALERT_COUNT)
+               {
+               /* fail the connection, enough alerts have been sent */
+               SSLerr(SSL_F_DTLS1_READ_FAILED,SSL_R_READ_TIMEOUT_EXPIRED);
+               return 0;
+               }
+
+       state->timeout.read_timeouts++;
+       if ( state->timeout.read_timeouts > DTLS1_TMO_READ_COUNT)
+               {
+               send_alert = 1;
+               state->timeout.read_timeouts = 1;
+               }
+
+
 #if 0 /* for now, each alert contains only one record number */
-    item = pqueue_peek(state->rcvd_records);
-    if ( item )
-        {
-        /* send an alert immediately for all the missing records */
-        }
-    else
+       item = pqueue_peek(state->rcvd_records);
+       if ( item )
+               {
+               /* send an alert immediately for all the missing records */
+               }
+       else
 #endif
 
 #if 0  /* no more alert sending, just retransmit the last set of messages */
-        if ( send_alert)
-            ssl3_send_alert(s,SSL3_AL_WARNING,
-                DTLS1_AD_MISSING_HANDSHAKE_MESSAGE);
+               if ( send_alert)
+                       ssl3_send_alert(s,SSL3_AL_WARNING,
+                               DTLS1_AD_MISSING_HANDSHAKE_MESSAGE);
 #endif
 
-    return dtls1_retransmit_buffered_messages(s) ;
-    }
+       return dtls1_retransmit_buffered_messages(s) ;
+       }
 
 
 static int
 dtls1_retransmit_buffered_messages(SSL *s)
-    {
-    pqueue sent = s->d1->sent_messages;
-    piterator iter;
-    pitem *item;
-    hm_fragment *frag;
-    int found = 0;
-
-    iter = pqueue_iterator(sent);
-
-    for ( item = pqueue_next(&iter); item != NULL; item = pqueue_next(&iter))
-        {
-        frag = (hm_fragment *)item->data;
-        if ( dtls1_retransmit_message(s, frag->msg_header.seq, 0, &found) <= 0 &&
-            found)
-            {
-            fprintf(stderr, "dtls1_retransmit_message() failed\n");
-            return -1;
-            }
-        }
-
-    return 1;
-    }
+       {
+       pqueue sent = s->d1->sent_messages;
+       piterator iter;
+       pitem *item;
+       hm_fragment *frag;
+       int found = 0;
 
-#if 0
-static dtls1_message_buffer *
-dtls1_message_buffer_new(unsigned int len)
-    {
-    dtls1_message_buffer *msg_buf;
-
-    msg_buf = (dtls1_message_buffer *) 
-        OPENSSL_malloc(sizeof(dtls1_message_buffer)); 
-    if ( msg_buf == NULL)
-        return NULL;
-
-    memset(msg_buf, 0x00, sizeof(dtls1_message_buffer));
-
-    msg_buf->data = (unsigned char *) OPENSSL_malloc(len);
-    if ( msg_buf->data == NULL)
-        {
-        OPENSSL_free(msg_buf);
-        return NULL;
-        }
-
-    memset(msg_buf->data, 0x00, len);
-    return msg_buf;
-    }
-#endif
+       iter = pqueue_iterator(sent);
 
-#if 0
-static void
-dtls1_message_buffer_free(dtls1_message_buffer *msg_buf)
-    {
-    if (msg_buf != NULL)
-        {
-        OPENSSL_free(msg_buf->data);
-        OPENSSL_free(msg_buf);
-        }
-    }
-#endif
+       for ( item = pqueue_next(&iter); item != NULL; item = pqueue_next(&iter))
+               {
+               frag = (hm_fragment *)item->data;
+               if ( dtls1_retransmit_message(s, frag->msg_header.seq, 0, &found) <= 0 &&
+                       found)
+                       {
+                       fprintf(stderr, "dtls1_retransmit_message() failed\n");
+                       return -1;
+                       }
+               }
+
+       return 1;
+       }
 
 int
 dtls1_buffer_message(SSL *s, int is_ccs)
-    {
-    pitem *item;
-    hm_fragment *frag;
+       {
+       pitem *item;
+       hm_fragment *frag;
        PQ_64BIT seq64;
 
-    /* this function is called immediately after a message has 
-     * been serialized */
-    OPENSSL_assert(s->init_off == 0);
-
-    frag = dtls1_hm_fragment_new(s->init_num);
-
-    memcpy(frag->fragment, s->init_buf->data, s->init_num);
-
-    if ( is_ccs)
-        {
-        OPENSSL_assert(s->d1->w_msg_hdr.msg_len + 
-            DTLS1_CCS_HEADER_LENGTH == (unsigned int)s->init_num);
-        }
-    else
-        {
-        OPENSSL_assert(s->d1->w_msg_hdr.msg_len + 
-            DTLS1_HM_HEADER_LENGTH == (unsigned int)s->init_num);
-        }
-
-    frag->msg_header.msg_len = s->d1->w_msg_hdr.msg_len;
-    frag->msg_header.seq = s->d1->w_msg_hdr.seq;
-    frag->msg_header.type = s->d1->w_msg_hdr.type;
-    frag->msg_header.frag_off = 0;
-    frag->msg_header.frag_len = s->d1->w_msg_hdr.msg_len;
-    frag->msg_header.is_ccs = is_ccs;
-
-    pq_64bit_init(&seq64);
-    pq_64bit_assign_word(&seq64, frag->msg_header.seq);
-
-    item = pitem_new(seq64, frag);
-    pq_64bit_free(&seq64);
-    if ( item == NULL)
-        {
-        dtls1_hm_fragment_free(frag);
-        return 0;
-        }
+       /* this function is called immediately after a message has 
+        * been serialized */
+       OPENSSL_assert(s->init_off == 0);
+
+       frag = dtls1_hm_fragment_new(s->init_num);
+
+       memcpy(frag->fragment, s->init_buf->data, s->init_num);
+
+       if ( is_ccs)
+               {
+               OPENSSL_assert(s->d1->w_msg_hdr.msg_len + 
+                       DTLS1_CCS_HEADER_LENGTH <= (unsigned int)s->init_num);
+               }
+       else
+               {
+               OPENSSL_assert(s->d1->w_msg_hdr.msg_len + 
+                       DTLS1_HM_HEADER_LENGTH == (unsigned int)s->init_num);
+               }
+
+       frag->msg_header.msg_len = s->d1->w_msg_hdr.msg_len;
+       frag->msg_header.seq = s->d1->w_msg_hdr.seq;
+       frag->msg_header.type = s->d1->w_msg_hdr.type;
+       frag->msg_header.frag_off = 0;
+       frag->msg_header.frag_len = s->d1->w_msg_hdr.msg_len;
+       frag->msg_header.is_ccs = is_ccs;
+
+       pq_64bit_init(&seq64);
+       pq_64bit_assign_word(&seq64, frag->msg_header.seq);
+
+       item = pitem_new(seq64, frag);
+       pq_64bit_free(&seq64);
+       if ( item == NULL)
+               {
+               dtls1_hm_fragment_free(frag);
+               return 0;
+               }
 
 #if 0
-    fprintf( stderr, "buffered messge: \ttype = %xx\n", msg_buf->type);
-    fprintf( stderr, "\t\t\t\t\tlen = %d\n", msg_buf->len);
-    fprintf( stderr, "\t\t\t\t\tseq_num = %d\n", msg_buf->seq_num);
+       fprintf( stderr, "buffered messge: \ttype = %xx\n", msg_buf->type);
+       fprintf( stderr, "\t\t\t\t\tlen = %d\n", msg_buf->len);
+       fprintf( stderr, "\t\t\t\t\tseq_num = %d\n", msg_buf->seq_num);
 #endif
 
-    pqueue_insert(s->d1->sent_messages, item);
-    return 1;
-    }
+       pqueue_insert(s->d1->sent_messages, item);
+       return 1;
+       }
 
 int
 dtls1_retransmit_message(SSL *s, unsigned short seq, unsigned long frag_off,
-    int *found)
-    {
-    int ret;
-    /* XDTLS: for now assuming that read/writes are blocking */
-    pitem *item;
-    hm_fragment *frag ;
-    unsigned long header_length;
+       int *found)
+       {
+       int ret;
+       /* XDTLS: for now assuming that read/writes are blocking */
+       pitem *item;
+       hm_fragment *frag ;
+       unsigned long header_length;
        PQ_64BIT seq64;
 
-    /*
-      OPENSSL_assert(s->init_num == 0);
-      OPENSSL_assert(s->init_off == 0);
-     */
-
-    /* XDTLS:  the requested message ought to be found, otherwise error */
-    pq_64bit_init(&seq64);
-    pq_64bit_assign_word(&seq64, seq);
-
-    item = pqueue_find(s->d1->sent_messages, seq64);
-    pq_64bit_free(&seq64);
-    if ( item == NULL)
-        {
-        fprintf(stderr, "retransmit:  message %d non-existant\n", seq);
-        *found = 0;
-        return 0;
-        }
-
-    *found = 1;
-    frag = (hm_fragment *)item->data;
-
-    if ( frag->msg_header.is_ccs)
-        header_length = DTLS1_CCS_HEADER_LENGTH;
-    else
-        header_length = DTLS1_HM_HEADER_LENGTH;
-
-    memcpy(s->init_buf->data, frag->fragment, 
-        frag->msg_header.msg_len + header_length);
-        s->init_num = frag->msg_header.msg_len + header_length;
-    
-    dtls1_set_message_header_int(s, frag->msg_header.type, 
-        frag->msg_header.msg_len, frag->msg_header.seq, 0, 
-        frag->msg_header.frag_len);
-
-    s->d1->retransmitting = 1;
-    ret = dtls1_do_write(s, frag->msg_header.is_ccs ? 
-        SSL3_RT_CHANGE_CIPHER_SPEC : SSL3_RT_HANDSHAKE);
-    s->d1->retransmitting = 0;
-
-    BIO_flush(SSL_get_wbio(s));
-    return ret;
-    }
+       /*
+         OPENSSL_assert(s->init_num == 0);
+         OPENSSL_assert(s->init_off == 0);
+        */
+
+       /* XDTLS:  the requested message ought to be found, otherwise error */
+       pq_64bit_init(&seq64);
+       pq_64bit_assign_word(&seq64, seq);
+
+       item = pqueue_find(s->d1->sent_messages, seq64);
+       pq_64bit_free(&seq64);
+       if ( item == NULL)
+               {
+               fprintf(stderr, "retransmit:  message %d non-existant\n", seq);
+               *found = 0;
+               return 0;
+               }
+
+       *found = 1;
+       frag = (hm_fragment *)item->data;
+
+       if ( frag->msg_header.is_ccs)
+               header_length = DTLS1_CCS_HEADER_LENGTH;
+       else
+               header_length = DTLS1_HM_HEADER_LENGTH;
+
+       memcpy(s->init_buf->data, frag->fragment, 
+               frag->msg_header.msg_len + header_length);
+               s->init_num = frag->msg_header.msg_len + header_length;
+
+       dtls1_set_message_header_int(s, frag->msg_header.type, 
+               frag->msg_header.msg_len, frag->msg_header.seq, 0, 
+               frag->msg_header.frag_len);
+
+       s->d1->retransmitting = 1;
+       ret = dtls1_do_write(s, frag->msg_header.is_ccs ? 
+               SSL3_RT_CHANGE_CIPHER_SPEC : SSL3_RT_HANDSHAKE);
+       s->d1->retransmitting = 0;
+
+       (void)BIO_flush(SSL_get_wbio(s));
+       return ret;
+       }
 
 /* call this function when the buffered messages are no longer needed */
 void
 dtls1_clear_record_buffer(SSL *s)
-    {
-    pitem *item;
-    
-    for(item = pqueue_pop(s->d1->sent_messages);
-        item != NULL; item = pqueue_pop(s->d1->sent_messages))
-        {
-        dtls1_hm_fragment_free((hm_fragment *)item->data);
-        pitem_free(item);
-        }
-    }
+       {
+       pitem *item;
+
+       for(item = pqueue_pop(s->d1->sent_messages);
+               item != NULL;