Import OpenSSL-1.0.1d.
authorPeter Avalos <pavalos@dragonflybsd.org>
Sun, 10 Feb 2013 09:23:52 +0000 (01:23 -0800)
committerPeter Avalos <pavalos@dragonflybsd.org>
Sun, 10 Feb 2013 09:27:30 +0000 (01:27 -0800)
      o Fix renegotiation in TLS 1.1, 1.2 by using the correct TLS version.
      o Fix OCSP bad key DoS attack CVE-2013-0166
      o Fix for SSL/TLS/DTLS CBC plaintext recovery attack CVE-2013-0169
      o Fix for TLS AESNI record handling flaw CVE-2012-2686

156 files changed:
crypto/openssl/CHANGES
crypto/openssl/FAQ
crypto/openssl/NEWS
crypto/openssl/PROBLEMS
crypto/openssl/README
crypto/openssl/README.DELETED
crypto/openssl/apps/apps.c
crypto/openssl/apps/ca.c
crypto/openssl/apps/cms.c
crypto/openssl/apps/dgst.c
crypto/openssl/apps/dhparam.c
crypto/openssl/apps/dsaparam.c
crypto/openssl/apps/genrsa.c
crypto/openssl/apps/ocsp.c
crypto/openssl/apps/s_cb.c
crypto/openssl/apps/s_client.c
crypto/openssl/apps/s_server.c
crypto/openssl/apps/speed.c
crypto/openssl/apps/srp.c
crypto/openssl/apps/verify.c
crypto/openssl/apps/x509.c
crypto/openssl/crypto/aes/asm/aes-x86_64.pl
crypto/openssl/crypto/aes/asm/aesni-sha1-x86_64.pl
crypto/openssl/crypto/aes/asm/aesni-x86_64.pl
crypto/openssl/crypto/aes/asm/bsaes-x86_64.pl
crypto/openssl/crypto/aes/asm/vpaes-x86_64.pl
crypto/openssl/crypto/asn1/a_strex.c
crypto/openssl/crypto/asn1/a_verify.c
crypto/openssl/crypto/asn1/x_pubkey.c
crypto/openssl/crypto/bio/bss_dgram.c
crypto/openssl/crypto/bn/asm/modexp512-x86_64.pl
crypto/openssl/crypto/bn/asm/x86_64-gf2m.pl
crypto/openssl/crypto/bn/asm/x86_64-mont.pl
crypto/openssl/crypto/bn/asm/x86_64-mont5.pl
crypto/openssl/crypto/bn/bn_div.c
crypto/openssl/crypto/bn/bn_gcd.c
crypto/openssl/crypto/bn/bn_lcl.h
crypto/openssl/crypto/bn/bn_word.c
crypto/openssl/crypto/camellia/asm/cmll-x86_64.pl
crypto/openssl/crypto/cms/cms_cd.c
crypto/openssl/crypto/cms/cms_enc.c
crypto/openssl/crypto/cms/cms_lib.c
crypto/openssl/crypto/conf/conf_mall.c
crypto/openssl/crypto/cryptlib.c
crypto/openssl/crypto/cryptlib.h
crypto/openssl/crypto/crypto.h
crypto/openssl/crypto/des/set_key.c
crypto/openssl/crypto/des/str2key.c
crypto/openssl/crypto/ec/ec.h
crypto/openssl/crypto/ec/ec_key.c
crypto/openssl/crypto/ec/ec_pmeth.c
crypto/openssl/crypto/ec/ecp_mont.c
crypto/openssl/crypto/ecdh/ech_key.c
crypto/openssl/crypto/ecdh/ech_lib.c
crypto/openssl/crypto/ecdsa/ecs_lib.c
crypto/openssl/crypto/err/err_all.c
crypto/openssl/crypto/evp/digest.c
crypto/openssl/crypto/evp/e_aes.c
crypto/openssl/crypto/evp/e_aes_cbc_hmac_sha1.c
crypto/openssl/crypto/evp/evp.h
crypto/openssl/crypto/evp/evp_cnf.c [copied from crypto/openssl/crypto/conf/conf_mall.c with 67% similarity]
crypto/openssl/crypto/evp/evp_err.c
crypto/openssl/crypto/evp/m_dss.c
crypto/openssl/crypto/evp/m_dss1.c
crypto/openssl/crypto/evp/m_sha1.c
crypto/openssl/crypto/evp/p_sign.c
crypto/openssl/crypto/evp/p_verify.c
crypto/openssl/crypto/md4/md4_dgst.c
crypto/openssl/crypto/md4/md4_locl.h
crypto/openssl/crypto/md5/asm/md5-x86_64.pl
crypto/openssl/crypto/md5/md5_locl.h
crypto/openssl/crypto/mdc2/mdc2dgst.c
crypto/openssl/crypto/mem.c
crypto/openssl/crypto/modes/asm/ghash-x86.pl
crypto/openssl/crypto/modes/asm/ghash-x86_64.pl
crypto/openssl/crypto/modes/gcm128.c
crypto/openssl/crypto/objects/o_names.c
crypto/openssl/crypto/ocsp/ocsp_vfy.c
crypto/openssl/crypto/opensslv.h
crypto/openssl/crypto/pem/pem_all.c
crypto/openssl/crypto/pem/pem_lib.c
crypto/openssl/crypto/pem/pem_seal.c
crypto/openssl/crypto/perlasm/cbc.pl
crypto/openssl/crypto/pkcs12/p12_key.c
crypto/openssl/crypto/pkcs7/bio_pk7.c
crypto/openssl/crypto/rand/md_rand.c
crypto/openssl/crypto/rand/rand_lib.c
crypto/openssl/crypto/rand/randfile.c
crypto/openssl/crypto/rc4/asm/rc4-md5-x86_64.pl
crypto/openssl/crypto/rc4/asm/rc4-x86_64.pl
crypto/openssl/crypto/ripemd/rmd_dgst.c
crypto/openssl/crypto/ripemd/rmd_locl.h
crypto/openssl/crypto/rsa/rsa.h
crypto/openssl/crypto/rsa/rsa_eay.c
crypto/openssl/crypto/rsa/rsa_oaep.c
crypto/openssl/crypto/sha/asm/sha1-x86_64.pl
crypto/openssl/crypto/sha/asm/sha512-586.pl
crypto/openssl/crypto/sha/asm/sha512-x86_64.pl
crypto/openssl/crypto/sha/sha1_one.c
crypto/openssl/crypto/sha/sha1dgst.c
crypto/openssl/crypto/sha/sha256.c
crypto/openssl/crypto/sha/sha_dgst.c
crypto/openssl/crypto/sha/sha_locl.h
crypto/openssl/crypto/srp/srp_vfy.c
crypto/openssl/crypto/symhacks.h
crypto/openssl/crypto/ui/ui_openssl.c
crypto/openssl/crypto/whrlpool/asm/wp-mmx.pl
crypto/openssl/crypto/whrlpool/asm/wp-x86_64.pl
crypto/openssl/crypto/x509/x509_cmp.c
crypto/openssl/crypto/x509/x509_vfy.c
crypto/openssl/crypto/x509v3/v3_purp.c
crypto/openssl/crypto/x86_64cpuid.pl
crypto/openssl/crypto/x86cpuid.pl
crypto/openssl/doc/apps/CA.pl.pod
crypto/openssl/doc/apps/verify.pod
crypto/openssl/doc/apps/x509.pod
crypto/openssl/doc/crypto/EVP_PKEY_CTX_ctrl.pod
crypto/openssl/doc/crypto/EVP_PKEY_decrypt.pod
crypto/openssl/doc/crypto/EVP_PKEY_derive.pod
crypto/openssl/doc/crypto/EVP_PKEY_encrypt.pod
crypto/openssl/doc/crypto/EVP_PKEY_get_default_digest.pod
crypto/openssl/doc/crypto/EVP_PKEY_keygen.pod
crypto/openssl/doc/crypto/EVP_PKEY_sign.pod
crypto/openssl/doc/crypto/EVP_PKEY_verify.pod
crypto/openssl/doc/crypto/EVP_PKEY_verify_recover.pod [moved from crypto/openssl/doc/crypto/EVP_PKEY_verifyrecover.pod with 76% similarity]
crypto/openssl/engines/ccgost/gost89.c
crypto/openssl/engines/ccgost/gost_crypt.c
crypto/openssl/engines/ccgost/gost_eng.c
crypto/openssl/engines/ccgost/gost_lcl.h
crypto/openssl/engines/ccgost/gosthash.c
crypto/openssl/engines/e_capi.c
crypto/openssl/ssl/d1_enc.c
crypto/openssl/ssl/d1_pkt.c
crypto/openssl/ssl/dtls1.h
crypto/openssl/ssl/s2_clnt.c
crypto/openssl/ssl/s2_pkt.c
crypto/openssl/ssl/s2_srvr.c
crypto/openssl/ssl/s3_both.c
crypto/openssl/ssl/s3_cbc.c [new file with mode: 0644]
crypto/openssl/ssl/s3_clnt.c
crypto/openssl/ssl/s3_enc.c
crypto/openssl/ssl/s3_lib.c
crypto/openssl/ssl/s3_pkt.c
crypto/openssl/ssl/s3_srvr.c
crypto/openssl/ssl/ssl.h
crypto/openssl/ssl/ssl3.h
crypto/openssl/ssl/ssl_algs.c
crypto/openssl/ssl/ssl_cert.c
crypto/openssl/ssl/ssl_ciph.c
crypto/openssl/ssl/ssl_err.c
crypto/openssl/ssl/ssl_lib.c
crypto/openssl/ssl/ssl_locl.h
crypto/openssl/ssl/ssl_rsa.c
crypto/openssl/ssl/t1_enc.c
crypto/openssl/ssl/t1_lib.c
crypto/openssl/ssl/tls_srp.c

index 7013e4c..b7d36c2 100644 (file)
@@ -2,6 +2,49 @@
  OpenSSL CHANGES
  _______________
 
+ Changes between 1.0.1c and 1.0.1d [5 Feb 2013]
+
+  *) Make the decoding of SSLv3, TLS and DTLS CBC records constant time.
+
+     This addresses the flaw in CBC record processing discovered by 
+     Nadhem Alfardan and Kenny Paterson. Details of this attack can be found
+     at: http://www.isg.rhul.ac.uk/tls/     
+
+     Thanks go to Nadhem Alfardan and Kenny Paterson of the Information
+     Security Group at Royal Holloway, University of London
+     (www.isg.rhul.ac.uk) for discovering this flaw and Adam Langley and
+     Emilia Käsper for the initial patch.
+     (CVE-2013-0169)
+     [Emilia Käsper, Adam Langley, Ben Laurie, Andy Polyakov, Steve Henson]
+
+  *) Fix flaw in AESNI handling of TLS 1.2 and 1.1 records for CBC mode
+     ciphersuites which can be exploited in a denial of service attack.
+     Thanks go to and to Adam Langley <agl@chromium.org> for discovering
+     and detecting this bug and to Wolfgang Ettlinger
+     <wolfgang.ettlinger@gmail.com> for independently discovering this issue.
+     (CVE-2012-2686)
+     [Adam Langley]
+
+  *) Return an error when checking OCSP signatures when key is NULL.
+     This fixes a DoS attack. (CVE-2013-0166)
+     [Steve Henson]
+
+  *) Make openssl verify return errors.
+     [Chris Palmer <palmer@google.com> and Ben Laurie]
+
+  *) Call OCSP Stapling callback after ciphersuite has been chosen, so
+     the right response is stapled. Also change SSL_get_certificate()
+     so it returns the certificate actually sent.
+     See http://rt.openssl.org/Ticket/Display.html?id=2836.
+     [Rob Stradling <rob.stradling@comodo.com>]
+
+  *) Fix possible deadlock when decoding public keys.
+     [Steve Henson]
+
+  *) Don't use TLS 1.0 record version number in initial client hello
+     if renegotiating.
+     [Steve Henson]
+
  Changes between 1.0.1b and 1.0.1c [10 May 2012]
 
   *) Sanity check record length before skipping explicit IV in TLS
index bb6f7e2..fcd6e1a 100644 (file)
@@ -83,7 +83,7 @@ OpenSSL  -  Frequently Asked Questions
 * Which is the current version of OpenSSL?
 
 The current version is available from <URL: http://www.openssl.org>.
-OpenSSL 1.0.1c was released on May 10th, 2012.
+OpenSSL 1.0.1d was released on Feb 5th, 2013.
 
 In addition to the current stable release, you can also access daily
 snapshots of the OpenSSL development version at <URL:
index 4f069cb..a5ba7dd 100644 (file)
@@ -5,6 +5,14 @@
   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 1.0.1c and OpenSSL 1.0.1d:
+
+      o Fix renegotiation in TLS 1.1, 1.2 by using the correct TLS version.
+      o Include the fips configuration module.
+      o Fix OCSP bad key DoS attack CVE-2013-0166
+      o Fix for SSL/TLS/DTLS CBC plaintext recovery attack CVE-2013-0169
+      o Fix for TLS AESNI record handling flaw CVE-2012-2686
+
   Major changes between OpenSSL 1.0.1b and OpenSSL 1.0.1c:
 
       o Fix TLS/DTLS record length checking bug CVE-2012-2333
index d247470..3eaab01 100644 (file)
@@ -197,3 +197,17 @@ reconfigure with additional no-sse2 [or 386] option passed to ./config.
 We don't have framework to associate -ldl with no-dso, therefore the only
 way is to edit Makefile right after ./config no-dso and remove -ldl from
 EX_LIBS line.
+
+* hpux-parisc2-cc no-asm build fails with SEGV in ECDSA/DH.
+
+Compiler bug, presumably at particular patch level. Remaining
+hpux*-parisc*-cc configurations can be affected too. Drop optimization
+level to +O2 when compiling bn_nist.o.
+
+* solaris64-sparcv9-cc link failure
+
+Solaris 8 ar can fail to maintain symbol table in .a, which results in
+link failures. Apply 109147-09 or later or modify Makefile generated
+by ./Configure solaris64-sparcv9-cc and replace RANLIB assignment with
+
+       RANLIB= /usr/ccs/bin/ar rs
index de51583..31bb2f0 100644 (file)
@@ -1,5 +1,5 @@
 
- OpenSSL 1.0.1c 10 May 2012
+ OpenSSL 1.0.1d 5 Feb 2013
 
  Copyright (c) 1998-2011 The OpenSSL Project
  Copyright (c) 1995-1998 Eric A. Young, Tim J. Hudson
index dbc047d..d17c4b6 100644 (file)
@@ -12,6 +12,7 @@ INSTALL.W64
 INSTALL.WCE
 MacOS/
 Makefile
+Makefile.bak
 Makefile.org
 Makefile.shared
 Netware/
index 4e11915..1096eee 100644 (file)
@@ -2132,7 +2132,7 @@ X509_NAME *parse_name(char *subject, long chtype, int multirdn)
        X509_NAME *n = NULL;
        int nid;
 
-       if (!buf || !ne_types || !ne_values)
+       if (!buf || !ne_types || !ne_values || !mval)
                {
                BIO_printf(bio_err, "malloc error\n");
                goto error;
@@ -2236,6 +2236,7 @@ X509_NAME *parse_name(char *subject, long chtype, int multirdn)
        OPENSSL_free(ne_values);
        OPENSSL_free(ne_types);
        OPENSSL_free(buf);
+       OPENSSL_free(mval);
        return n;
 
 error:
@@ -2244,6 +2245,8 @@ error:
                OPENSSL_free(ne_values);
        if (ne_types)
                OPENSSL_free(ne_types);
+       if (mval)
+               OPENSSL_free(mval);
        if (buf)
                OPENSSL_free(buf);
        return NULL;
index 2a83d19..1cf50e0 100644 (file)
@@ -1408,6 +1408,7 @@ bad:
                        if (!NCONF_get_number(conf,section,
                                ENV_DEFAULT_CRL_HOURS, &crlhours))
                                crlhours = 0;
+                       ERR_clear_error();
                        }
                if ((crldays == 0) && (crlhours == 0) && (crlsec == 0))
                        {
index d754140..5f77f8f 100644 (file)
@@ -233,6 +233,8 @@ int MAIN(int argc, char **argv)
                else if (!strcmp(*args,"-camellia256"))
                                cipher = EVP_camellia_256_cbc();
 #endif
+               else if (!strcmp (*args, "-debug_decrypt")) 
+                               flags |= CMS_DEBUG_DECRYPT;
                else if (!strcmp (*args, "-text")) 
                                flags |= CMS_TEXT;
                else if (!strcmp (*args, "-nointern")) 
@@ -1039,6 +1041,8 @@ int MAIN(int argc, char **argv)
        ret = 4;
        if (operation == SMIME_DECRYPT)
                {
+               if (flags & CMS_DEBUG_DECRYPT)
+                       CMS_decrypt(cms, NULL, NULL, NULL, NULL, flags);
 
                if (secret_key)
                        {
index b08e9a7..81bd870 100644 (file)
@@ -216,10 +216,10 @@ int MAIN(int argc, char **argv)
                        out_bin = 1;
                else if (strcmp(*argv,"-d") == 0)
                        debug=1;
-               else if (strcmp(*argv,"-non-fips-allow") == 0)
-                       non_fips_allow=1;
                else if (!strcmp(*argv,"-fips-fingerprint"))
                        hmac_key = "etaonrishdlcupfm";
+               else if (strcmp(*argv,"-non-fips-allow") == 0)
+                       non_fips_allow=1;
                else if (!strcmp(*argv,"-hmac"))
                        {
                        if (--argc < 1)
index b47097c..1297d6f 100644 (file)
@@ -332,7 +332,6 @@ bad:
                        BIO_printf(bio_err,"This is going to take a long time\n");
                        if(!dh || !DH_generate_parameters_ex(dh, num, g, &cb))
                                {
-                               if(dh) DH_free(dh);
                                ERR_print_errors(bio_err);
                                goto end;
                                }
index fe72c1d..683d513 100644 (file)
@@ -326,6 +326,7 @@ bad:
                                goto end;
                                }
 #endif
+                       ERR_print_errors(bio_err);
                        BIO_printf(bio_err,"Error, DSA key generation failed\n");
                        goto end;
                        }
@@ -429,13 +430,19 @@ bad:
 
                assert(need_rand);
                if ((dsakey=DSAparams_dup(dsa)) == NULL) goto end;
-               if (!DSA_generate_key(dsakey)) goto end;
+               if (!DSA_generate_key(dsakey))
+                       {
+                       ERR_print_errors(bio_err);
+                       DSA_free(dsakey);
+                       goto end;
+                       }
                if      (outformat == FORMAT_ASN1)
                        i=i2d_DSAPrivateKey_bio(out,dsakey);
                else if (outformat == FORMAT_PEM)
                        i=PEM_write_bio_DSAPrivateKey(out,dsakey,NULL,NULL,0,NULL,NULL);
                else    {
                        BIO_printf(bio_err,"bad output format specified for outfile\n");
+                       DSA_free(dsakey);
                        goto end;
                        }
                DSA_free(dsakey);
index 37e9310..ece114c 100644 (file)
@@ -78,7 +78,7 @@
 #include <openssl/pem.h>
 #include <openssl/rand.h>
 
-#define DEFBITS        512
+#define DEFBITS        1024
 #undef PROG
 #define PROG genrsa_main
 
index 01847df..83c5a76 100644 (file)
@@ -617,7 +617,7 @@ int MAIN(int argc, char **argv)
                BIO_printf (bio_err, "-ndays n           number of days before next update\n");
                BIO_printf (bio_err, "-resp_key_id       identify reponse by signing certificate key ID\n");
                BIO_printf (bio_err, "-nrequest n        number of requests to accept (default unlimited)\n");
-               BIO_printf (bio_err, "-<dgst alg>     use specified digest in the request");
+               BIO_printf (bio_err, "-<dgst alg>     use specified digest in the request\n");
                goto end;
                }
 
index 2cd7337..84c3b44 100644 (file)
@@ -237,8 +237,8 @@ int set_cert_stuff(SSL_CTX *ctx, char *cert_file, char *key_file)
 
                /* If we are using DSA, we can copy the parameters from
                 * the private key */
-               
-               
+
+
                /* Now we know that a key and cert have been set against
                 * the SSL context */
                if (!SSL_CTX_check_private_key(ctx))
@@ -436,6 +436,8 @@ void MS_CALLBACK msg_cb(int write_p, int version, int content_type, const void *
 
        if (version == SSL3_VERSION ||
            version == TLS1_VERSION ||
+           version == TLS1_1_VERSION ||
+           version == TLS1_2_VERSION ||
            version == DTLS1_VERSION ||
            version == DTLS1_BAD_VER)
                {
index fc806eb..0248447 100644 (file)
@@ -357,7 +357,7 @@ static void sc_usage(void)
        BIO_printf(bio_err," -tlsextdebug      - hex dump of all TLS extensions received\n");
        BIO_printf(bio_err," -status           - request certificate status from server\n");
        BIO_printf(bio_err," -no_ticket        - disable use of RFC4507bis session tickets\n");
-# if !defined(OPENSSL_NO_NEXTPROTONEG)
+# ifndef OPENSSL_NO_NEXTPROTONEG
        BIO_printf(bio_err," -nextprotoneg arg - enable NPN extension, considering named protocols supported (comma-separated list)\n");
 # endif
 #endif
@@ -536,7 +536,7 @@ static int next_proto_cb(SSL *s, unsigned char **out, unsigned char *outlen, con
        ctx->status = SSL_select_next_proto(out, outlen, in, inlen, ctx->data, ctx->len);
        return SSL_TLSEXT_ERR_OK;
        }
-# endif
+# endif  /* ndef OPENSSL_NO_NEXTPROTONEG */
 #endif
 
 enum
@@ -1890,6 +1890,10 @@ end:
                        print_stuff(bio_c_out,con,1);
                SSL_free(con);
                }
+#if !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_NEXTPROTONEG)
+       if (next_proto.data)
+               OPENSSL_free(next_proto.data);
+#endif
        if (ctx != NULL) SSL_CTX_free(ctx);
        if (cert)
                X509_free(cert);
@@ -1897,6 +1901,8 @@ end:
                EVP_PKEY_free(key);
        if (pass)
                OPENSSL_free(pass);
+       if (vpm)
+               X509_VERIFY_PARAM_free(vpm);
        if (cbuf != NULL) { OPENSSL_cleanse(cbuf,BUFSIZZ); OPENSSL_free(cbuf); }
        if (sbuf != NULL) { OPENSSL_cleanse(sbuf,BUFSIZZ); OPENSSL_free(sbuf); }
        if (mbuf != NULL) { OPENSSL_cleanse(mbuf,BUFSIZZ); OPENSSL_free(mbuf); }
index 3f9b370..4720c05 100644 (file)
@@ -1206,13 +1206,13 @@ int MAIN(int argc, char *argv[])
                        {
                        if (--argc < 1) goto bad;
                        srp_verifier_file = *(++argv);
-                       meth=TLSv1_server_method();
+                       meth = TLSv1_server_method();
                        }
                else if (strcmp(*argv, "-srpuserseed") == 0)
                        {
                        if (--argc < 1) goto bad;
                        srpuserseed = *(++argv);
-                       meth=TLSv1_server_method();
+                       meth = TLSv1_server_method();
                        }
 #endif
                else if (strcmp(*argv,"-www") == 0)
@@ -1431,25 +1431,24 @@ bad:
                                goto end;
                                }
                        }
-
-# ifndef OPENSSL_NO_NEXTPROTONEG
-               if (next_proto_neg_in)
-                       {
-                       unsigned short len;
-                       next_proto.data = next_protos_parse(&len,
-                               next_proto_neg_in);
-                       if (next_proto.data == NULL)
-                               goto end;
-                       next_proto.len = len;
-                       }
-               else
-                       {
-                       next_proto.data = NULL;
-                       }
-# endif
 #endif
                }
 
+#if !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_NEXTPROTONEG) 
+       if (next_proto_neg_in)
+               {
+               unsigned short len;
+               next_proto.data = next_protos_parse(&len, next_proto_neg_in);
+               if (next_proto.data == NULL)
+                       goto end;
+               next_proto.len = len;
+               }
+       else
+               {
+               next_proto.data = NULL;
+               }
+#endif
+
 
        if (s_dcert_file)
                {
@@ -1730,7 +1729,7 @@ bad:
                }
 #endif
        
-       if (!set_cert_key_stuff(ctx,s_cert,s_key))
+       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))
@@ -1738,7 +1737,7 @@ bad:
 #endif
        if (s_dcert != NULL)
                {
-               if (!set_cert_key_stuff(ctx,s_dcert,s_dkey))
+               if (!set_cert_key_stuff(ctx, s_dcert, s_dkey))
                        goto end;
                }
 
@@ -1893,7 +1892,15 @@ end:
                OPENSSL_free(pass);
        if (dpass)
                OPENSSL_free(dpass);
+       if (vpm)
+               X509_VERIFY_PARAM_free(vpm);
 #ifndef OPENSSL_NO_TLSEXT
+       if (tlscstatp.host)
+               OPENSSL_free(tlscstatp.host);
+       if (tlscstatp.port)
+               OPENSSL_free(tlscstatp.port);
+       if (tlscstatp.path)
+               OPENSSL_free(tlscstatp.path);
        if (ctx2 != NULL) SSL_CTX_free(ctx2);
        if (s_cert2)
                X509_free(s_cert2);
@@ -2433,6 +2440,7 @@ static int init_ssl_connection(SSL *con)
                BIO_printf(bio_s_out,"Shared ciphers:%s\n",buf);
        str=SSL_CIPHER_get_name(SSL_get_current_cipher(con));
        BIO_printf(bio_s_out,"CIPHER is %s\n",(str != NULL)?str:"(NONE)");
+
 #if !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_NEXTPROTONEG)
        SSL_get0_next_proto_negotiated(con, &next_proto_neg, &next_proto_neg_len);
        if (next_proto_neg)
@@ -2701,6 +2709,11 @@ static int www_body(char *hostname, int s, unsigned char *context)
                                }
                        BIO_puts(io,"\n");
 
+                       BIO_printf(io,
+                               "Secure Renegotiation IS%s supported\n",
+                               SSL_get_secure_renegotiation_support(con) ?
+                                                       "" : " NOT");
+
                        /* The following is evil and should not really
                         * be done */
                        BIO_printf(io,"Ciphers supported in s_server binary\n");
index 8358b12..9886ca3 100644 (file)
@@ -254,7 +254,7 @@ static const char *names[ALGOR_NUM]={
   "aes-128 cbc","aes-192 cbc","aes-256 cbc",
   "camellia-128 cbc","camellia-192 cbc","camellia-256 cbc",
   "evp","sha256","sha512","whirlpool",
-  "aes-128 ige","aes-192 ige","aes-256 ige","ghash"};
+  "aes-128 ige","aes-192 ige","aes-256 ige","ghash" };
 static double results[ALGOR_NUM][SIZE_NUM];
 static int lengths[SIZE_NUM]={16,64,256,1024,8*1024};
 #ifndef OPENSSL_NO_RSA
@@ -299,7 +299,7 @@ static SIGRETTYPE sig_done(int sig)
 #if defined(_WIN32)
 
 #if !defined(SIGALRM)
-#define SIGALRM
+# define SIGALRM
 #endif
 static unsigned int lapse,schlock;
 static void alarm_win32(unsigned int secs) { lapse = secs*1000; }
index 80e1b8a..9c7ae18 100644 (file)
@@ -125,13 +125,13 @@ static int get_index(CA_DB *db, char* id, char type)
        if (type == DB_SRP_INDEX) 
        for (i = 0; i < sk_OPENSSL_PSTRING_num(db->db->data); i++)
                {
-               pp = (char **)sk_OPENSSL_PSTRING_value(db->db->data, i);
-               if (pp[DB_srptype][0] == DB_SRP_INDEX  && !strcmp(id, pp[DB_srpid])) 
+               pp = sk_OPENSSL_PSTRING_value(db->db->data,i);
+               if (pp[DB_srptype][0] == DB_SRP_INDEX  && !strcmp(id,pp[DB_srpid])) 
                        return i;
                }
        else for (i = 0; i < sk_OPENSSL_PSTRING_num(db->db->data); i++)
                {
-               pp = (char **)sk_OPENSSL_PSTRING_value(db->db->data, i);
+               pp = sk_OPENSSL_PSTRING_value(db->db->data,i);
 
                if (pp[DB_srptype][0] != DB_SRP_INDEX && !strcmp(id,pp[DB_srpid])) 
                        return i;
@@ -145,7 +145,7 @@ static void print_entry(CA_DB *db, BIO *bio, int indx, int verbose, char *s)
        if (indx >= 0 && verbose)
                {
                int j;
-               char **pp = (char **)sk_OPENSSL_PSTRING_value(db->db->data, indx);
+               char **pp = sk_OPENSSL_PSTRING_value(db->db->data, indx);
                BIO_printf(bio, "%s \"%s\"\n", s, pp[DB_srpid]);
                for (j = 0; j < DB_NUMBER; j++)
                        {
@@ -163,7 +163,7 @@ static void print_user(CA_DB *db, BIO *bio, int userindex, int verbose)
        {
        if (verbose > 0)
                {
-               char **pp = (char **)sk_OPENSSL_PSTRING_value(db->db->data, userindex);
+               char **pp = sk_OPENSSL_PSTRING_value(db->db->data,userindex);
 
                if (pp[DB_srptype][0] != 'I')
                        {
@@ -517,7 +517,7 @@ bad:
        /* Lets check some fields */
        for (i = 0; i < sk_OPENSSL_PSTRING_num(db->db->data); i++)
                {
-               pp = (char **)sk_OPENSSL_PSTRING_value(db->db->data, i);
+               pp = sk_OPENSSL_PSTRING_value(db->db->data, i);
        
                if (pp[DB_srptype][0] == DB_SRP_INDEX)
                        {
@@ -533,8 +533,8 @@ bad:
 
        if (gNindex >= 0)
                {
-               gNrow = (char **)sk_OPENSSL_PSTRING_value(db->db->data, gNindex);
-               print_entry(db, bio_err, gNindex, verbose > 1, "Default g and N") ;
+               gNrow = sk_OPENSSL_PSTRING_value(db->db->data,gNindex);
+               print_entry(db, bio_err, gNindex, verbose > 1, "Default g and N");
                }
        else if (maxgN > 0 && !SRP_get_default_gN(gN))
                {
@@ -587,7 +587,7 @@ bad:
                        if (userindex >= 0)
                                {
                                /* reactivation of a new user */
-                               char **row = (char **)sk_OPENSSL_PSTRING_value(db->db->data, userindex);
+                               char **row = sk_OPENSSL_PSTRING_value(db->db->data, userindex);
                                BIO_printf(bio_err, "user \"%s\" reactivated.\n", user);
                                row[DB_srptype][0] = 'V';
 
@@ -634,7 +634,7 @@ bad:
                        else
                                {
 
-                               char **row = (char **)sk_OPENSSL_PSTRING_value(db->db->data, userindex);
+                               char **row = sk_OPENSSL_PSTRING_value(db->db->data, userindex);
                                char type = row[DB_srptype][0];
                                if (type == 'v')
                                        {
@@ -664,9 +664,9 @@ bad:
 
                                        if (!(gNid=srp_create_user(user,&(row[DB_srpverifier]), &(row[DB_srpsalt]),gNrow?gNrow[DB_srpsalt]:NULL, gNrow?gNrow[DB_srpverifier]:NULL, passout, bio_err,verbose)))
                                                {
-                                                       BIO_printf(bio_err, "Cannot create srp verifier for user \"%s\", operation abandoned.\n", user);
-                                                       errors++;
-                                                       goto err;
+                                               BIO_printf(bio_err, "Cannot create srp verifier for user \"%s\", operation abandoned.\n", user);
+                                               errors++;
+                                               goto err;
                                                }
 
                                        row[DB_srptype][0] = 'v';
@@ -689,7 +689,7 @@ bad:
                                }
                        else
                                {
-                               char **xpp = (char **)sk_OPENSSL_PSTRING_value(db->db->data, userindex);
+                               char **xpp = sk_OPENSSL_PSTRING_value(db->db->data,userindex);
                                BIO_printf(bio_err, "user \"%s\" revoked. t\n", user);
 
                                xpp[DB_srptype][0] = 'R';
@@ -714,7 +714,7 @@ bad:
                /* Lets check some fields */
                for (i = 0; i < sk_OPENSSL_PSTRING_num(db->db->data); i++)
                        {
-                       pp = (char **)sk_OPENSSL_PSTRING_value(db->db->data, i);
+                       pp = sk_OPENSSL_PSTRING_value(db->db->data,i);
        
                        if (pp[DB_srptype][0] == 'v')
                                {
index b9749dc..893670f 100644 (file)
@@ -222,11 +222,19 @@ int MAIN(int argc, char **argv)
                        goto end;
                }
 
-       if (argc < 1) check(cert_ctx, NULL, untrusted, trusted, crls, e);
+       ret = 0;
+       if (argc < 1)
+               { 
+               if (1 != check(cert_ctx, NULL, untrusted, trusted, crls, e))
+                       ret = -1;
+               }
        else
+               {
                for (i=0; i<argc; i++)
-                       check(cert_ctx,argv[i], untrusted, trusted, crls, e);
-       ret=0;
+                       if (1 != check(cert_ctx,argv[i], untrusted, trusted, crls, e))
+                               ret = -1;
+               }
+
 end:
        if (ret == 1) {
                BIO_printf(bio_err,"usage: verify [-verbose] [-CApath path] [-CAfile file] [-purpose purpose] [-crl_check]");
@@ -235,13 +243,16 @@ end:
                BIO_printf(bio_err," [-engine e]");
 #endif
                BIO_printf(bio_err," cert1 cert2 ...\n");
+
                BIO_printf(bio_err,"recognized usages:\n");
-               for(i = 0; i < X509_PURPOSE_get_count(); i++) {
+               for(i = 0; i < X509_PURPOSE_get_count(); i++)
+                       {
                        X509_PURPOSE *ptmp;
                        ptmp = X509_PURPOSE_get0(i);
-                       BIO_printf(bio_err, "\t%-10s\t%s\n", X509_PURPOSE_get0_sname(ptmp),
-                                                               X509_PURPOSE_get0_name(ptmp));
-               }
+                       BIO_printf(bio_err, "\t%-10s\t%s\n",
+                                  X509_PURPOSE_get0_sname(ptmp),
+                                  X509_PURPOSE_get0_name(ptmp));
+                       }
        }
        if (vpm) X509_VERIFY_PARAM_free(vpm);
        if (cert_ctx != NULL) X509_STORE_free(cert_ctx);
@@ -249,7 +260,7 @@ end:
        sk_X509_pop_free(trusted, X509_free);
        sk_X509_CRL_pop_free(crls, X509_CRL_free);
        apps_shutdown();
-       OPENSSL_EXIT(ret);
+       OPENSSL_EXIT(ret < 0 ? 2 : ret);
        }
 
 static int check(X509_STORE *ctx, char *file,
index e6e5e0d..3863ab9 100644 (file)
@@ -288,7 +288,7 @@ int MAIN(int argc, char **argv)
                        days=atoi(*(++argv));
                        if (days == 0)
                                {
-                               BIO_printf(STDout,"bad number of days\n");
+                               BIO_printf(bio_err,"bad number of days\n");
                                goto bad;
                                }
                        }
@@ -912,7 +912,7 @@ bad:
                                }
                        else if (text == i)
                                {
-                               X509_print_ex(out,x,nmflag, certflag);
+                               X509_print_ex(STDout,x,nmflag, certflag);
                                }
                        else if (startdate == i)
                                {
index 48fa857..34cbb5d 100755 (executable)
@@ -36,7 +36,8 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
 ( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or
 die "can't locate x86_64-xlate.pl";
 
-open STDOUT,"| $^X $xlate $flavour $output";
+open OUT,"| \"$^X\" $xlate $flavour $output";
+*STDOUT=*OUT;
 
 $verticalspin=1;       # unlike 32-bit version $verticalspin performs
                        # ~15% better on both AMD and Intel cores
index c6f6b33..3c8f6c1 100644 (file)
@@ -69,7 +69,8 @@ $avx=1 if (!$avx && $win64 && ($flavour =~ /masm/ || $ENV{ASM} =~ /ml64/) &&
           `ml64 2>&1` =~ /Version ([0-9]+)\./ &&
           $1>=10);
 
-open STDOUT,"| $^X $xlate $flavour $output";
+open OUT,"| \"$^X\" $xlate $flavour $output";
+*STDOUT=*OUT;
 
 # void aesni_cbc_sha1_enc(const void *inp,
 #                      void *out,
index 499f3b3..0dbb194 100644 (file)
@@ -172,7 +172,8 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
 ( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or
 die "can't locate x86_64-xlate.pl";
 
-open STDOUT,"| $^X $xlate $flavour $output";
+open OUT,"| \"$^X\" $xlate $flavour $output";
+*STDOUT=*OUT;
 
 $movkey = $PREFIX eq "aesni" ? "movups" : "movups";
 @_4args=$win64?        ("%rcx","%rdx","%r8", "%r9") :  # Win64 order
index c9c6312..ceb02b5 100644 (file)
@@ -105,7 +105,8 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
 ( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or
 die "can't locate x86_64-xlate.pl";
 
-open STDOUT,"| $^X $xlate $flavour $output";
+open OUT,"| \"$^X\" $xlate $flavour $output";
+*STDOUT=*OUT;
 
 my ($inp,$out,$len,$key,$ivp)=("%rdi","%rsi","%rdx","%rcx");
 my @XMM=map("%xmm$_",(15,0..14));      # best on Atom, +10% over (0..15)
index 37998db..41f2e46 100644 (file)
@@ -56,7 +56,8 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
 ( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or
 die "can't locate x86_64-xlate.pl";
 
-open STDOUT,"| $^X $xlate $flavour $output";
+open OUT,"| \"$^X\" $xlate $flavour $output";
+*STDOUT=*OUT;
 
 $PREFIX="vpaes";
 
index 264ebf2..ead37ac 100644 (file)
@@ -567,6 +567,7 @@ int ASN1_STRING_to_UTF8(unsigned char **out, ASN1_STRING *in)
        if(mbflag == -1) return -1;
        mbflag |= MBSTRING_FLAG;
        stmp.data = NULL;
+       stmp.length = 0;
        ret = ASN1_mbstring_copy(&str, in->data, in->length, mbflag, B_ASN1_UTF8STRING);
        if(ret < 0) return ret;
        *out = stmp.data;
index 432722e..fc84cd3 100644 (file)
@@ -140,6 +140,12 @@ int ASN1_item_verify(const ASN1_ITEM *it, X509_ALGOR *a,
 
        int mdnid, pknid;
 
+       if (!pkey)
+               {
+               ASN1err(ASN1_F_ASN1_ITEM_VERIFY, ERR_R_PASSED_NULL_PARAMETER);
+               return -1;
+               }
+
        EVP_MD_CTX_init(&ctx);
 
        /* Convert signature OID into digest and public key OIDs */
index 627ec87..b649e1f 100644 (file)
@@ -175,12 +175,15 @@ EVP_PKEY *X509_PUBKEY_get(X509_PUBKEY *key)
        CRYPTO_w_lock(CRYPTO_LOCK_EVP_PKEY);
        if (key->pkey)
                {
+               CRYPTO_w_unlock(CRYPTO_LOCK_EVP_PKEY);
                EVP_PKEY_free(ret);
                ret = key->pkey;
                }
        else
+               {
                key->pkey = ret;
-       CRYPTO_w_unlock(CRYPTO_LOCK_EVP_PKEY);
+               CRYPTO_w_unlock(CRYPTO_LOCK_EVP_PKEY);
+               }
        CRYPTO_add(&ret->references, 1, CRYPTO_LOCK_EVP_PKEY);
 
        return ret;
index 1b1e4be..8990909 100644 (file)
 #define OPENSSL_SCTP_FORWARD_CUM_TSN_CHUNK_TYPE 0xc0
 #endif
 
-#ifdef OPENSSL_SYS_LINUX
+#if defined(OPENSSL_SYS_LINUX) && !defined(IP_MTU)
 #define IP_MTU      14 /* linux is lame */
 #endif
 
+#if defined(__FreeBSD__) && defined(IN6_IS_ADDR_V4MAPPED)
+/* Standard definition causes type-punning problems. */
+#undef IN6_IS_ADDR_V4MAPPED
+#define s6_addr32 __u6_addr.__u6_addr32
+#define IN6_IS_ADDR_V4MAPPED(a)               \
+        (((a)->s6_addr32[0] == 0) &&          \
+         ((a)->s6_addr32[1] == 0) &&          \
+         ((a)->s6_addr32[2] == htonl(0x0000ffff)))
+#endif
+
 #ifdef WATT32
 #define sock_write SockWrite  /* Watt-32 uses same names */
 #define sock_read  SockRead
@@ -255,7 +265,7 @@ static void dgram_adjust_rcv_timeout(BIO *b)
        {
 #if defined(SO_RCVTIMEO)
        bio_dgram_data *data = (bio_dgram_data *)b->ptr;
-       int sz = sizeof(int);
+       union { size_t s; int i; } sz = {0};
 
        /* Is a timer active? */
        if (data->next_timeout.tv_sec > 0 || data->next_timeout.tv_usec > 0)
@@ -265,8 +275,10 @@ static void dgram_adjust_rcv_timeout(BIO *b)
                /* Read current socket timeout */
 #ifdef OPENSSL_SYS_WINDOWS
                int timeout;
+
+               sz.i = sizeof(timeout);
                if (getsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO,
-                                          (void*)&timeout, &sz) < 0)
+                                          (void*)&timeout, &sz.i) < 0)
                        { perror("getsockopt"); }
                else
                        {
@@ -274,9 +286,12 @@ static void dgram_adjust_rcv_timeout(BIO *b)
                        data->socket_timeout.tv_usec = (timeout % 1000) * 1000;
                        }
 #else
+               sz.i = sizeof(data->socket_timeout);
                if ( getsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO, 
                                                &(data->socket_timeout), (void *)&sz) < 0)
                        { perror("getsockopt"); }
+               else if (sizeof(sz.s)!=sizeof(sz.i) && sz.i==0)
+                       OPENSSL_assert(sz.s<=sizeof(data->socket_timeout));
 #endif
 
                /* Get current time */
@@ -445,11 +460,10 @@ static long dgram_ctrl(BIO *b, int cmd, long num, void *ptr)
        int *ip;
        struct sockaddr *to = NULL;
        bio_dgram_data *data = NULL;
-#if defined(IP_MTU_DISCOVER) || defined(IP_MTU)
-       long sockopt_val = 0;
-       unsigned int sockopt_len = 0;
-#endif
-#ifdef OPENSSL_SYS_LINUX
+#if defined(OPENSSL_SYS_LINUX) && (defined(IP_MTU_DISCOVER) || defined(IP_MTU))
+       int sockopt_val = 0;
+       socklen_t sockopt_len;  /* assume that system supporting IP_MTU is
+                                * modern enough to define socklen_t */
        socklen_t addr_len;
        union   {
                struct sockaddr sa;
@@ -531,7 +545,7 @@ static long dgram_ctrl(BIO *b, int cmd, long num, void *ptr)
                break;
                /* (Linux)kernel sets DF bit on outgoing IP packets */
        case BIO_CTRL_DGRAM_MTU_DISCOVER:
-#ifdef OPENSSL_SYS_LINUX
+#if defined(OPENSSL_SYS_LINUX) && defined(IP_MTU_DISCOVER) && defined(IP_PMTUDISC_DO)
                addr_len = (socklen_t)sizeof(addr);
                memset((void *)&addr, 0, sizeof(addr));
                if (getsockname(b->num, &addr.sa, &addr_len) < 0)
@@ -539,7 +553,6 @@ static long dgram_ctrl(BIO *b, int cmd, long num, void *ptr)
                        ret = 0;
                        break;
                        }
-               sockopt_len = sizeof(sockopt_val);
                switch (addr.sa.sa_family)
                        {
                case AF_INET:
@@ -548,7 +561,7 @@ static long dgram_ctrl(BIO *b, int cmd, long num, void *ptr)
                                &sockopt_val, sizeof(sockopt_val))) < 0)
                                perror("setsockopt");
                        break;
-#if OPENSSL_USE_IPV6 && defined(IPV6_MTU_DISCOVER)
+#if OPENSSL_USE_IPV6 && defined(IPV6_MTU_DISCOVER) && defined(IPV6_PMTUDISC_DO)
                case AF_INET6:
                        sockopt_val = IPV6_PMTUDISC_DO;
                        if ((ret = setsockopt(b->num, IPPROTO_IPV6, IPV6_MTU_DISCOVER,
@@ -565,7 +578,7 @@ static long dgram_ctrl(BIO *b, int cmd, long num, void *ptr)
                break;
 #endif
        case BIO_CTRL_DGRAM_QUERY_MTU:
-#ifdef OPENSSL_SYS_LINUX
+#if defined(OPENSSL_SYS_LINUX) && defined(IP_MTU)
                addr_len = (socklen_t)sizeof(addr);
                memset((void *)&addr, 0, sizeof(addr));
                if (getsockname(b->num, &addr.sa, &addr_len) < 0)
@@ -727,12 +740,15 @@ static long dgram_ctrl(BIO *b, int cmd, long num, void *ptr)
 #endif
                break;
        case BIO_CTRL_DGRAM_GET_RECV_TIMEOUT:
-#ifdef OPENSSL_SYS_WINDOWS
                {
-               int timeout, sz = sizeof(timeout);
+               union { size_t s; int i; } sz = {0};
+#ifdef OPENSSL_SYS_WINDOWS
+               int timeout;
                struct timeval *tv = (struct timeval *)ptr;
+
+               sz.i = sizeof(timeout);
                if (getsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO,
-                       (void*)&timeout, &sz) < 0)
+                       (void*)&timeout, &sz.i) < 0)
                        { perror("getsockopt"); ret = -1; }
                else
                        {
@@ -740,12 +756,20 @@ static long dgram_ctrl(BIO *b, int cmd, long num, void *ptr)
                        tv->tv_usec = (timeout % 1000) * 1000;
                        ret = sizeof(*tv);
                        }
-               }
 #else
+               sz.i = sizeof(struct timeval);
                if ( getsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO, 
-                       ptr, (void *)&ret) < 0)
+                       ptr, (void *)&sz) < 0)
                        { perror("getsockopt"); ret = -1; }
+               else if (sizeof(sz.s)!=sizeof(sz.i) && sz.i==0)
+                       {
+                       OPENSSL_assert(sz.s<=sizeof(struct timeval));
+                       ret = (int)sz.s;
+                       }
+               else
+                       ret = sz.i;
 #endif
+               }
                break;
 #endif
 #if defined(SO_SNDTIMEO)
@@ -765,12 +789,15 @@ static long dgram_ctrl(BIO *b, int cmd, long num, void *ptr)
 #endif
                break;
        case BIO_CTRL_DGRAM_GET_SEND_TIMEOUT:
-#ifdef OPENSSL_SYS_WINDOWS
                {
-               int timeout, sz = sizeof(timeout);
+               union { size_t s; int i; } sz = {0};
+#ifdef OPENSSL_SYS_WINDOWS
+               int timeout;
                struct timeval *tv = (struct timeval *)ptr;
+
+               sz.i = sizeof(timeout);
                if (getsockopt(b->num, SOL_SOCKET, SO_SNDTIMEO,
-                       (void*)&timeout, &sz) < 0)
+                       (void*)&timeout, &sz.i) < 0)
                        { perror("getsockopt"); ret = -1; }
                else
                        {
@@ -778,12 +805,20 @@ static long dgram_ctrl(BIO *b, int cmd, long num, void *ptr)
                        tv->tv_usec = (timeout % 1000) * 1000;
                        ret = sizeof(*tv);
                        }
-               }
 #else
+               sz.i = sizeof(struct timeval);
                if ( getsockopt(b->num, SOL_SOCKET, SO_SNDTIMEO, 
-                       ptr, (void *)&ret) < 0)
+                       ptr, (void *)&sz) < 0)
                        { perror("getsockopt"); ret = -1; }
+               else if (sizeof(sz.s)!=sizeof(sz.i) && sz.i==0)
+                       {
+                       OPENSSL_assert(sz.s<=sizeof(struct timeval));
+                       ret = (int)sz.s;
+                       }
+               else
+                       ret = sz.i;
 #endif
+               }
                break;
 #endif
        case BIO_CTRL_DGRAM_GET_SEND_TIMER_EXP:
@@ -955,7 +990,6 @@ static int dgram_sctp_free(BIO *a)
 #ifdef SCTP_AUTHENTICATION_EVENT
 void dgram_sctp_handle_auth_free_key_event(BIO *b, union sctp_notification *snp)
        {
-       unsigned int sockopt_len = 0;
        int ret;
        struct sctp_authkey_event* authkeyevent = &snp->sn_auth_event;
 
@@ -965,9 +999,8 @@ void dgram_sctp_handle_auth_free_key_event(BIO *b, union sctp_notification *snp)
 
                /* delete key */
                authkeyid.scact_keynumber = authkeyevent->auth_keynumber;
-               sockopt_len = sizeof(struct sctp_authkeyid);
                ret = setsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_DELETE_KEY,
-                     &authkeyid, sockopt_len);
+                     &authkeyid, sizeof(struct sctp_authkeyid));
                }
        }
 #endif
@@ -1298,7 +1331,7 @@ static long dgram_sctp_ctrl(BIO *b, int cmd, long num, void *ptr)
        {
        long ret=1;
        bio_dgram_sctp_data *data = NULL;
-       unsigned int sockopt_len = 0;
+       socklen_t sockopt_len = 0;
        struct sctp_authkeyid authkeyid;
        struct sctp_authkey *authkey;
 
index 54aeb01..bfd6e97 100644 (file)
@@ -68,7 +68,8 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
 ( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or
 die "can't locate x86_64-xlate.pl";
 
-open STDOUT,"| $^X $xlate $flavour $output";
+open OUT,"| \"$^X\" $xlate $flavour $output";
+*STDOUT=*OUT;
 
 use strict;
 my $code=".text\n\n";
index 1658acb..a30d4ef 100644 (file)
@@ -31,7 +31,7 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
 ( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or
 die "can't locate x86_64-xlate.pl";
 
-open STDOUT,"| $^X $xlate $flavour $output";
+open STDOUT,"| \"$^X\" $xlate $flavour $output";
 
 ($lo,$hi)=("%rax","%rdx");     $a=$lo;
 ($i0,$i1)=("%rsi","%rdi");
index 5d79b35..17fb94c 100755 (executable)
@@ -40,7 +40,8 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
 ( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or
 die "can't locate x86_64-xlate.pl";
 
-open STDOUT,"| $^X $xlate $flavour $output";
+open OUT,"| \"$^X\" $xlate $flavour $output";
+*STDOUT=*OUT;
 
 # int bn_mul_mont(
 $rp="%rdi";    # BN_ULONG *rp,
index 057cda2..8f8dc5a 100755 (executable)
@@ -28,7 +28,8 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
 ( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or
 die "can't locate x86_64-xlate.pl";
 
-open STDOUT,"| $^X $xlate $flavour $output";
+open OUT,"| \"$^X\" $xlate $flavour $output";
+*STDOUT=*OUT;
 
 # int bn_mul_mont_gather5(
 $rp="%rdi";    # BN_ULONG *rp,
index 52b3304..7b24031 100644 (file)
@@ -141,6 +141,7 @@ int BN_div(BIGNUM *dv, BIGNUM *rem, const BIGNUM *m, const BIGNUM *d,
     *
     *                                  <appro@fy.chalmers.se>
     */
+#undef bn_div_words
 #  define bn_div_words(n0,n1,d0)               \
        ({  asm volatile (                      \
                "divl   %4"                     \
@@ -155,6 +156,7 @@ int BN_div(BIGNUM *dv, BIGNUM *rem, const BIGNUM *m, const BIGNUM *d,
     * Same story here, but it's 128-bit by 64-bit division. Wow!
     *                                  <appro@fy.chalmers.se>
     */
+#  undef bn_div_words
 #  define bn_div_words(n0,n1,d0)               \
        ({  asm volatile (                      \
                "divq   %4"                     \
index 4a35211..a808f53 100644 (file)
@@ -205,6 +205,7 @@ 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)
        {
index eecfd8c..817c773 100644 (file)
@@ -282,16 +282,23 @@ extern "C" {
 #  endif
 # elif defined(__mips) && (defined(SIXTY_FOUR_BIT) || defined(SIXTY_FOUR_BIT_LONG))
 #  if defined(__GNUC__) && __GNUC__>=2
-#   define BN_UMULT_HIGH(a,b)  ({      \
+#   if __GNUC__>=4 && __GNUC_MINOR__>=4 /* "h" constraint is no more since 4.4 */
+#     define BN_UMULT_HIGH(a,b)                 (((__uint128_t)(a)*(b))>>64)
+#     define BN_UMULT_LOHI(low,high,a,b) ({    \
+       __uint128_t ret=(__uint128_t)(a)*(b);   \
+       (high)=ret>>64; (low)=ret;       })
+#   else
+#     define BN_UMULT_HIGH(a,b)        ({      \
        register BN_ULONG ret;          \
        asm ("dmultu    %1,%2"          \
             : "=h"(ret)                \
             : "r"(a), "r"(b) : "l");   \
        ret;                    })
-#   define BN_UMULT_LOHI(low,high,a,b) \
+#     define BN_UMULT_LOHI(low,high,a,b)\
        asm ("dmultu    %2,%3"          \
             : "=l"(low),"=h"(high)     \
             : "r"(a), "r"(b));
+#    endif
 #  endif
 # endif                /* cpu */
 #endif         /* OPENSSL_NO_ASM */
index ee7b87c..de83a15 100644 (file)
@@ -144,26 +144,17 @@ int BN_add_word(BIGNUM *a, BN_ULONG w)
                        a->neg=!(a->neg);
                return(i);
                }
-       /* Only expand (and risk failing) if it's possibly necessary */
-       if (((BN_ULONG)(a->d[a->top - 1] + 1) == 0) &&
-                       (bn_wexpand(a,a->top+1) == NULL))
-               return(0);
-       i=0;
-       for (;;)
+       for (i=0;w!=0 && i<a->top;i++)
                {
-               if (i >= a->top)
-                       l=w;
-               else
-                       l=(a->d[i]+w)&BN_MASK2;
-               a->d[i]=l;
-               if (w > l)
-                       w=1;
-               else
-                       break;
-               i++;
+               a->d[i] = l = (a->d[i]+w)&BN_MASK2;
+               w = (w>l)?1:0;
                }
-       if (i >= a->top)
+       if (w && i==a->top)
+               {
+               if (bn_wexpand(a,a->top+1) == NULL) return 0;
                a->top++;
+               a->d[i]=w;
+               }
        bn_check_top(a);
        return(1);
        }
index 76955e4..9f4b82f 100644 (file)
@@ -40,7 +40,8 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
 ( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or
 die "can't locate x86_64-xlate.pl";
 
-open STDOUT,"| $^X $xlate $flavour $output";
+open OUT,"| \"$^X\" $xlate $flavour $output";
+*STDOUT=*OUT;
 
 sub hi() { my $r=shift; $r =~ s/%[er]([a-d])x/%\1h/;    $r; }
 sub lo() { my $r=shift; $r =~ s/%[er]([a-d])x/%\1l/;
index a5fc2c4..2021688 100644 (file)
@@ -58,7 +58,9 @@
 #include <openssl/err.h>
 #include <openssl/cms.h>
 #include <openssl/bio.h>
+#ifndef OPENSSL_NO_COMP
 #include <openssl/comp.h>
+#endif
 #include "cms_lcl.h"
 
 DECLARE_ASN1_ITEM(CMS_CompressedData)
index f873ce3..bebeaf2 100644 (file)
@@ -74,7 +74,7 @@ BIO *cms_EncryptedContent_init_bio(CMS_EncryptedContentInfo *ec)
        X509_ALGOR *calg = ec->contentEncryptionAlgorithm;
        unsigned char iv[EVP_MAX_IV_LENGTH], *piv = NULL;
        unsigned char *tkey = NULL;
-       size_t tkeylen;
+       size_t tkeylen = 0;
 
        int ok = 0;
 
index f88e8f3..b62d1bf 100644 (file)
@@ -411,9 +411,7 @@ int cms_DigestAlgorithm_find_ctx(EVP_MD_CTX *mctx, BIO *chain,
                 * algorithm  OID instead of digest.
                 */
                        || EVP_MD_pkey_type(EVP_MD_CTX_md(mtmp)) == nid)
-                       {
                        return EVP_MD_CTX_copy_ex(mctx, mtmp);
-                       }
                chain = BIO_next(chain);
                }
        }
index c6f4cb2..213890e 100644 (file)
@@ -76,5 +76,6 @@ void OPENSSL_load_builtin_modules(void)
 #ifndef OPENSSL_NO_ENGINE
        ENGINE_add_conf_module();
 #endif
+       EVP_add_alg_module();
        }
 
index 766ea8c..304c6b7 100644 (file)
@@ -504,7 +504,7 @@ void CRYPTO_THREADID_current(CRYPTO_THREADID *id)
        CRYPTO_THREADID_set_numeric(id, (unsigned long)find_thread(NULL));
 #else
        /* For everything else, default to using the address of 'errno' */
-       CRYPTO_THREADID_set_pointer(id, &errno);
+       CRYPTO_THREADID_set_pointer(id, (void*)&errno);
 #endif
        }
 
@@ -704,6 +704,7 @@ void OPENSSL_cpuid_setup(void)
     }
     else
        vec = OPENSSL_ia32_cpuid();
+
     /*
      * |(1<<10) sets a reserved bit to signal that variable
      * was initialized already... This is to avoid interference
@@ -924,3 +925,16 @@ void OpenSSLDie(const char *file,int line,const char *assertion)
        }
 
 void *OPENSSL_stderr(void)     { return stderr; }
+
+int CRYPTO_memcmp(const void *in_a, const void *in_b, size_t len)
+       {
+       size_t i;
+       const unsigned char *a = in_a;
+       const unsigned char *b = in_b;
+       unsigned char x = 0;
+
+       for (i = 0; i < len; i++)
+               x |= a[i] ^ b[i];
+
+       return x;
+       }
index 1761f6b..d26f963 100644 (file)
@@ -100,7 +100,7 @@ extern "C" {
 
 void OPENSSL_cpuid_setup(void);
 extern unsigned int OPENSSL_ia32cap_P[];
-void OPENSSL_showfatal(const char *,...);
+void OPENSSL_showfatal(const char *fmta,...);
 void *OPENSSL_stderr(void);
 extern int OPENSSL_NONPIC_relocated;
 
index 6aeda0a..f92fc51 100644 (file)
@@ -488,10 +488,10 @@ void CRYPTO_get_mem_debug_functions(void (**m)(void *,int,const char *,int,int),
                                    long (**go)(void));
 
 void *CRYPTO_malloc_locked(int num, const char *file, int line);
-void CRYPTO_free_locked(void *);
+void CRYPTO_free_locked(void *ptr);
 void *CRYPTO_malloc(int num, const char *file, int line);
 char *CRYPTO_strdup(const char *str, const char *file, int line);
-void CRYPTO_free(void *);
+void CRYPTO_free(void *ptr);
 void *CRYPTO_realloc(void *addr,int num, const char *file, int line);
 void *CRYPTO_realloc_clean(void *addr,int old_num,int num,const char *file,
                           int line);
@@ -574,6 +574,13 @@ void OPENSSL_init(void);
 #define fips_cipher_abort(alg) while(0)
 #endif
 
+/* CRYPTO_memcmp returns zero iff the |len| bytes at |a| and |b| are equal. It
+ * takes an amount of time dependent on |len|, but independent of the contents
+ * of |a| and |b|. Unlike memcmp, it cannot be used to put elements into a
+ * defined order as the return value when a != b is undefined, other than to be
+ * non-zero. */
+int CRYPTO_memcmp(const void *a, const void *b, size_t len);
+
 /* BEGIN ERROR CODES */
 /* The following lines are auto generated by the script mkerr.pl. Any changes
  * made after this point may be overwritten when the script is next run.
index d3e69ca..da4d62e 100644 (file)
@@ -63,9 +63,8 @@
  * 1.1 added norm_expand_bits
  * 1.0 First working version
  */
-#include "des_locl.h"
-
 #include <openssl/crypto.h>
+#include "des_locl.h"
 
 OPENSSL_IMPLEMENT_GLOBAL(int,DES_check_key,0)  /* defaults to false */
 
index 9c2054b..1077f99 100644 (file)
@@ -56,8 +56,8 @@
  * [including the GNU Public Licence.]
  */
 
-#include "des_locl.h"
 #include <openssl/crypto.h>
+#include "des_locl.h"
 
 void DES_string_to_key(const char *str, DES_cblock *key)
        {
index 9d01325..dfe8710 100644 (file)
@@ -274,10 +274,10 @@ int EC_GROUP_get_curve_name(const EC_GROUP *group);
 void EC_GROUP_set_asn1_flag(EC_GROUP *group, int flag);
 int EC_GROUP_get_asn1_flag(const EC_GROUP *group);
 
-void EC_GROUP_set_point_conversion_form(EC_GROUP *, point_conversion_form_t);
+void EC_GROUP_set_point_conversion_form(EC_GROUP *group, point_conversion_form_t form);
 point_conversion_form_t EC_GROUP_get_point_conversion_form(const EC_GROUP *);
 
-unsigned char *EC_GROUP_get0_seed(const EC_GROUP *);
+unsigned char *EC_GROUP_get0_seed(const EC_GROUP *x);
 size_t EC_GROUP_get_seed_len(const EC_GROUP *);
 size_t EC_GROUP_set_seed(EC_GROUP *, const unsigned char *, size_t len);
 
@@ -626,8 +626,8 @@ int EC_POINT_is_on_curve(const EC_GROUP *group, const EC_POINT *point, BN_CTX *c
  */
 int EC_POINT_cmp(const EC_GROUP *group, const EC_POINT *a, const EC_POINT *b, BN_CTX *ctx);
 
-int EC_POINT_make_affine(const EC_GROUP *, EC_POINT *, BN_CTX *);
-int EC_POINTs_make_affine(const EC_GROUP *, size_t num, EC_POINT *[], BN_CTX *);
+int EC_POINT_make_affine(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx);
+int EC_POINTs_make_affine(const EC_GROUP *group, size_t num, EC_POINT *points[], BN_CTX *ctx);
 
 /** Computes r = generator * n sum_{i=0}^num p[i] * m[i]
  *  \param  group  underlying EC_GROUP object
@@ -800,16 +800,24 @@ const EC_POINT *EC_KEY_get0_public_key(const EC_KEY *key);
 int EC_KEY_set_public_key(EC_KEY *key, const EC_POINT *pub);
 
 unsigned EC_KEY_get_enc_flags(const EC_KEY *key);
-void EC_KEY_set_enc_flags(EC_KEY *, unsigned int);
-point_conversion_form_t EC_KEY_get_conv_form(const EC_KEY *);
-void EC_KEY_set_conv_form(EC_KEY *, point_conversion_form_t);
+void EC_KEY_set_enc_flags(EC_KEY *eckey, unsigned int flags);
+point_conversion_form_t EC_KEY_get_conv_form(const EC_KEY *key);
+void EC_KEY_set_conv_form(EC_KEY *eckey, point_conversion_form_t cform);
 /* functions to set/get method specific data  */
-void *EC_KEY_get_key_method_data(EC_KEY *, 
+void *EC_KEY_get_key_method_data(EC_KEY *key
        void *(*dup_func)(void *), void (*free_func)(void *), void (*clear_free_func)(void *));
-void EC_KEY_insert_key_method_data(EC_KEY *, void *data,
+/** Sets the key method data of an EC_KEY object, if none has yet been set.
+ *  \param  key              EC_KEY object
+ *  \param  data             opaque data to install.
+ *  \param  dup_func         a function that duplicates |data|.
+ *  \param  free_func        a function that frees |data|.
+ *  \param  clear_free_func  a function that wipes and frees |data|.
+ *  \return the previously set data pointer, or NULL if |data| was inserted.
+ */
+void *EC_KEY_insert_key_method_data(EC_KEY *key, void *data,
        void *(*dup_func)(void *), void (*free_func)(void *), void (*clear_free_func)(void *));
 /* wrapper functions for the underlying EC_GROUP object */
-void EC_KEY_set_asn1_flag(EC_KEY *, int);
+void EC_KEY_set_asn1_flag(EC_KEY *eckey, int asn1_flag);
 
 /** Creates a table of pre-computed multiples of the generator to 
  *  accelerate further EC_KEY operations.
index bf9fd2d..7fa2475 100644 (file)
@@ -520,18 +520,27 @@ void EC_KEY_set_conv_form(EC_KEY *key, point_conversion_form_t cform)
 void *EC_KEY_get_key_method_data(EC_KEY *key,
        void *(*dup_func)(void *), void (*free_func)(void *), void (*clear_free_func)(void *))
        {
-       return EC_EX_DATA_get_data(key->method_data, dup_func, free_func, clear_free_func);
+       void *ret;
+
+       CRYPTO_r_lock(CRYPTO_LOCK_EC);
+       ret = EC_EX_DATA_get_data(key->method_data, dup_func, free_func, clear_free_func);
+       CRYPTO_r_unlock(CRYPTO_LOCK_EC);
+
+       return ret;
        }
 
-void EC_KEY_insert_key_method_data(EC_KEY *key, void *data,
+void *EC_KEY_insert_key_method_data(EC_KEY *key, void *data,
        void *(*dup_func)(void *), void (*free_func)(void *), void (*clear_free_func)(void *))
        {
        EC_EXTRA_DATA *ex_data;
+
        CRYPTO_w_lock(CRYPTO_LOCK_EC);
        ex_data = EC_EX_DATA_get_data(key->method_data, dup_func, free_func, clear_free_func);
        if (ex_data == NULL)
                EC_EX_DATA_set_data(&key->method_data, data, dup_func, free_func, clear_free_func);
        CRYPTO_w_unlock(CRYPTO_LOCK_EC);
+
+       return ex_data;
        }
 
 void EC_KEY_set_asn1_flag(EC_KEY *key, int flag)
index d1ed66c..66ee397 100644 (file)
@@ -188,7 +188,7 @@ static int pkey_ec_derive(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen)
 
        pubkey = EC_KEY_get0_public_key(ctx->peerkey->pkey.ec);
 
-       /* NB: unlike PKS#3 DH, if *outlen is less than maximum size this is
+       /* NB: unlike PKCS#3 DH, if *outlen is less than maximum size this is
         * not an error, the result is truncated.
         */
 
index 079e474..f04f132 100644 (file)
@@ -114,7 +114,6 @@ const EC_METHOD *EC_GFp_mont_method(void)
                ec_GFp_mont_field_decode,
                ec_GFp_mont_field_set_to_one };
 
-
        return &ret;
 #endif
        }
index f44da92..2988899 100644 (file)
@@ -68,9 +68,6 @@
  */
 
 #include "ech_locl.h"
-#ifndef OPENSSL_NO_ENGINE
-#include <openssl/engine.h>
-#endif
 
 int ECDH_compute_key(void *out, size_t outlen, const EC_POINT *pub_key,
        EC_KEY *eckey,
index dadbfd3..0644431 100644 (file)
@@ -222,8 +222,15 @@ ECDH_DATA *ecdh_check(EC_KEY *key)
                ecdh_data = (ECDH_DATA *)ecdh_data_new();
                if (ecdh_data == NULL)
                        return NULL;
-               EC_KEY_insert_key_method_data(key, (void *)ecdh_data,
-                       ecdh_data_dup, ecdh_data_free, ecdh_data_free);
+               data = EC_KEY_insert_key_method_data(key, (void *)ecdh_data,
+                          ecdh_data_dup, ecdh_data_free, ecdh_data_free);
+               if (data != NULL)
+                       {
+                       /* Another thread raced us to install the key_method
+                        * data and won. */
+                       ecdh_data_free(ecdh_data);
+                       ecdh_data = (ECDH_DATA *)data;
+                       }
        }
        else
                ecdh_data = (ECDH_DATA *)data;
index e477da4..814a6bf 100644 (file)
@@ -200,8 +200,15 @@ ECDSA_DATA *ecdsa_check(EC_KEY *key)
                ecdsa_data = (ECDSA_DATA *)ecdsa_data_new();
                if (ecdsa_data == NULL)
                        return NULL;
-               EC_KEY_insert_key_method_data(key, (void *)ecdsa_data,
-                       ecdsa_data_dup, ecdsa_data_free, ecdsa_data_free);
+               data = EC_KEY_insert_key_method_data(key, (void *)ecdsa_data,
+                          ecdsa_data_dup, ecdsa_data_free, ecdsa_data_free);
+               if (data != NULL)
+                       {
+                       /* Another thread raced us to install the key_method
+                        * data and won. */
+                       ecdsa_data_free(ecdsa_data);
+                       ecdsa_data = (ECDSA_DATA *)data;
+                       }
        }
        else
                ecdsa_data = (ECDSA_DATA *)data;
index bd8946d..8eb547d 100644 (file)
@@ -64,7 +64,9 @@
 #endif
 #include <openssl/buffer.h>
 #include <openssl/bio.h>
+#ifndef OPENSSL_NO_COMP
 #include <openssl/comp.h>
+#endif
 #ifndef OPENSSL_NO_RSA
 #include <openssl/rsa.h>
 #endif
@@ -95,6 +97,9 @@
 #include <openssl/ui.h>
 #include <openssl/ocsp.h>
 #include <openssl/err.h>
+#ifdef OPENSSL_FIPS
+#include <openssl/fips.h>
+#endif
 #include <openssl/ts.h>
 #ifndef OPENSSL_NO_CMS
 #include <openssl/cms.h>
 #ifndef OPENSSL_NO_JPAKE
 #include <openssl/jpake.h>
 #endif
-#include <openssl/comp.h>
-
-#ifdef OPENSSL_FIPS
-#include <openssl/fips.h>
-#endif
 
 void ERR_load_crypto_strings(void)
        {
@@ -130,7 +130,9 @@ void ERR_load_crypto_strings(void)
        ERR_load_ASN1_strings();
        ERR_load_CONF_strings();
        ERR_load_CRYPTO_strings();
+#ifndef OPENSSL_NO_COMP
        ERR_load_COMP_strings();
+#endif
 #ifndef OPENSSL_NO_EC
        ERR_load_EC_strings();
 #endif
@@ -153,15 +155,14 @@ void ERR_load_crypto_strings(void)
 #endif
        ERR_load_OCSP_strings();
        ERR_load_UI_strings();
+#ifdef OPENSSL_FIPS
+       ERR_load_FIPS_strings();
+#endif
 #ifndef OPENSSL_NO_CMS
        ERR_load_CMS_strings();
 #endif
 #ifndef OPENSSL_NO_JPAKE
        ERR_load_JPAKE_strings();
 #endif
-       ERR_load_COMP_strings();
-#endif
-#ifdef OPENSSL_FIPS
-       ERR_load_FIPS_strings();
 #endif
        }
index 467e6b5..6fc469f 100644 (file)
@@ -267,6 +267,7 @@ int EVP_DigestFinal_ex(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *size)
        return FIPS_digestfinal(ctx, md, size);
 #else
        int ret;
+
        OPENSSL_assert(ctx->digest->md_size <= EVP_MAX_MD_SIZE);
        ret=ctx->digest->final(ctx,md);
        if (size != NULL)
index 1e4af0c..1bfb5d9 100644 (file)
@@ -969,8 +969,6 @@ static int aes_gcm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
 
        if (!gctx->iv_set)
                return -1;
-       if (!ctx->encrypt && gctx->taglen < 0)
-               return -1;
        if (in)
                {
                if (out == NULL)
@@ -1012,6 +1010,8 @@ static int aes_gcm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
                {
                if (!ctx->encrypt)
                        {
+                       if (gctx->taglen < 0)
+                               return -1;
                        if (CRYPTO_gcm128_finish(&gctx->gcm,
                                        ctx->buf, gctx->taglen) != 0)
                                return -1;
@@ -1217,6 +1217,7 @@ static int aes_ccm_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
                        vpaes_set_encrypt_key(key, ctx->key_len*8, &cctx->ks);
                        CRYPTO_ccm128_init(&cctx->ccm, cctx->M, cctx->L,
                                        &cctx->ks, (block128_f)vpaes_encrypt);
+                       cctx->str = NULL;
                        cctx->key_set = 1;
                        break;
                        }
index 710fb79..b7aff44 100644 (file)
@@ -1,5 +1,5 @@
 /* ====================================================================
- * Copyright (c) 2011 The OpenSSL Project.  All rights reserved.
+ * Copyright (c) 2011-2013 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
@@ -90,6 +90,10 @@ typedef struct
        defined(_M_AMD64)       || defined(_M_X64)      || \
        defined(__INTEL__)      )
 
+#if defined(__GNUC__) && __GNUC__>=2 && !defined(PEDANTIC)
+# define BSWAP(x) ({ unsigned int r=(x); asm ("bswapl %0":"=r"(r):"0"(r)); r; })
+#endif
+
 extern unsigned int OPENSSL_ia32cap_P[2];
 #define AESNI_CAPABLE   (1<<(57-32))
 
@@ -167,6 +171,9 @@ static void sha1_update(SHA_CTX *c,const void *data,size_t len)
                SHA1_Update(c,ptr,res);
 }
 
+#ifdef SHA1_Update
+#undef SHA1_Update
+#endif
 #define SHA1_Update sha1_update
 
 static int aesni_cbc_hmac_sha1_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
@@ -184,6 +191,8 @@ static int aesni_cbc_hmac_sha1_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
        sha_off = SHA_CBLOCK-key->md.num;
 #endif
 
+       key->payload_length = NO_PAYLOAD_LENGTH;
+
        if (len%AES_BLOCK_SIZE) return 0;
 
        if (ctx->encrypt) {
@@ -234,47 +243,203 @@ static int aesni_cbc_hmac_sha1_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
                                        &key->ks,ctx->iv,1);
                }
        } else {
-               unsigned char mac[SHA_DIGEST_LENGTH];
+               union { unsigned int  u[SHA_DIGEST_LENGTH/sizeof(unsigned int)];
+                       unsigned char c[SHA_DIGEST_LENGTH]; } mac;
 
                /* decrypt HMAC|padding at once */
                aesni_cbc_encrypt(in,out,len,
                                &key->ks,ctx->iv,0);
 
                if (plen) {     /* "TLS" mode of operation */
-                       /* figure out payload length */
-                       if (len<(size_t)(out[len-1]+1+SHA_DIGEST_LENGTH))
-                               return 0;
-
-                       len -= (out[len-1]+1+SHA_DIGEST_LENGTH);
+                       size_t inp_len, mask, j, i;
+                       unsigned int res, maxpad, pad, bitlen;
+                       int ret = 1;
+                       union { unsigned int  u[SHA_LBLOCK];
+                               unsigned char c[SHA_CBLOCK]; }
+                               *data = (void *)key->md.data;
 
                        if ((key->aux.tls_aad[plen-4]<<8|key->aux.tls_aad[plen-3])
-                           >= TLS1_1_VERSION) {
-                               len -= AES_BLOCK_SIZE;
+                           >= TLS1_1_VERSION)
                                iv = AES_BLOCK_SIZE;
-                       }
 
-                       key->aux.tls_aad[plen-2] = len>>8;
-                       key->aux.tls_aad[plen-1] = len;
+                       if (len<(iv+SHA_DIGEST_LENGTH+1))
+                               return 0;
+
+                       /* omit explicit iv */
+                       out += iv;
+                       len -= iv;
+
+                       /* figure out payload length */
+                       pad = out[len-1];
+                       maxpad = len-(SHA_DIGEST_LENGTH+1);
+                       maxpad |= (255-maxpad)>>(sizeof(maxpad)*8-8);
+                       maxpad &= 255;
+
+                       inp_len = len - (SHA_DIGEST_LENGTH+pad+1);
+                       mask = (0-((inp_len-len)>>(sizeof(inp_len)*8-1)));
+                       inp_len &= mask;
+                       ret &= (int)mask;
 
-                       /* calculate HMAC and verify it */
+                       key->aux.tls_aad[plen-2] = inp_len>>8;
+                       key->aux.tls_aad[plen-1] = inp_len;
+
+                       /* calculate HMAC */
                        key->md = key->head;
                        SHA1_Update(&key->md,key->aux.tls_aad,plen);
-                       SHA1_Update(&key->md,out+iv,len);
-                       SHA1_Final(mac,&key->md);
 
+#if 1
+                       len -= SHA_DIGEST_LENGTH;               /* amend mac */
+                       if (len>=(256+SHA_CBLOCK)) {
+                               j = (len-(256+SHA_CBLOCK))&(0-SHA_CBLOCK);
+                               j += SHA_CBLOCK-key->md.num;
+                               SHA1_Update(&key->md,out,j);
+                               out += j;
+                               len -= j;
+                               inp_len -= j;
+                       }
+
+                       /* but pretend as if we hashed padded payload */
+                       bitlen = key->md.Nl+(inp_len<<3);       /* at most 18 bits */
+                       mac.c[0] = 0;
+                       mac.c[1] = (unsigned char)(bitlen>>16);
+                       mac.c[2] = (unsigned char)(bitlen>>8);
+                       mac.c[3] = (unsigned char)bitlen;
+                       bitlen = mac.u[0];
+
+                       mac.u[0]=0;
+                       mac.u[1]=0;
+                       mac.u[2]=0;
+                       mac.u[3]=0;
+                       mac.u[4]=0;
+
+                       for (res=key->md.num, j=0;j<len;j++) {
+                               size_t c = out[j];
+                               mask = (j-inp_len)>>(sizeof(j)*8-8);
+                               c &= mask;
+                               c |= 0x80&~mask&~((inp_len-j)>>(sizeof(j)*8-8));
+                               data->c[res++]=(unsigned char)c;
+
+                               if (res!=SHA_CBLOCK) continue;
+
+                               mask = 0-((inp_len+8-j)>>(sizeof(j)*8-1));
+                               data->u[SHA_LBLOCK-1] |= bitlen&mask;
+                               sha1_block_data_order(&key->md,data,1);
+                               mask &= 0-((j-inp_len-73)>>(sizeof(j)*8-1));
+                               mac.u[0] |= key->md.h0 & mask;
+                               mac.u[1] |= key->md.h1 & mask;
+                               mac.u[2] |= key->md.h2 & mask;
+                               mac.u[3] |= key->md.h3 & mask;
+                               mac.u[4] |= key->md.h4 & mask;
+                               res=0;
+                       }
+
+                       for(i=res;i<SHA_CBLOCK;i++,j++) data->c[i]=0;
+
+                       if (res>SHA_CBLOCK-8) {
+                               mask = 0-((inp_len+8-j)>>(sizeof(j)*8-1));
+                               data->u[SHA_LBLOCK-1] |= bitlen&mask;
+                               sha1_block_data_order(&key->md,data,1);
+                               mask &= 0-((j-inp_len-73)>>(sizeof(j)*8-1));
+                               mac.u[0] |= key->md.h0 & mask;
+                               mac.u[1] |= key->md.h1 & mask;
+                               mac.u[2] |= key->md.h2 & mask;
+                               mac.u[3] |= key->md.h3 & mask;
+                               mac.u[4] |= key->md.h4 & mask;
+
+                               memset(data,0,SHA_CBLOCK);
+                               j+=64;
+                       }
+                       data->u[SHA_LBLOCK-1] = bitlen;
+                       sha1_block_data_order(&key->md,data,1);
+                       mask = 0-((j-inp_len-73)>>(sizeof(j)*8-1));
+                       mac.u[0] |= key->md.h0 & mask;
+                       mac.u[1] |= key->md.h1 & mask;
+                       mac.u[2] |= key->md.h2 & mask;
+                       mac.u[3] |= key->md.h3 & mask;
+                       mac.u[4] |= key->md.h4 & mask;
+
+#ifdef BSWAP
+                       mac.u[0] = BSWAP(mac.u[0]);
+                       mac.u[1] = BSWAP(mac.u[1]);
+                       mac.u[2] = BSWAP(mac.u[2]);
+                       mac.u[3] = BSWAP(mac.u[3]);
+                       mac.u[4] = BSWAP(mac.u[4]);
+#else
+                       for (i=0;i<5;i++) {
+                               res = mac.u[i];
+                               mac.c[4*i+0]=(unsigned char)(res>>24);
+                               mac.c[4*i+1]=(unsigned char)(res>>16);
+                               mac.c[4*i+2]=(unsigned char)(res>>8);
+                               mac.c[4*i+3]=(unsigned char)res;
+                       }
+#endif
+                       len += SHA_DIGEST_LENGTH;
+#else
+                       SHA1_Update(&key->md,out,inp_len);
+                       res = key->md.num;
+                       SHA1_Final(mac.c,&key->md);
+
+                       {
+                       unsigned int inp_blocks, pad_blocks;
+
+                       /* but pretend as if we hashed padded payload */
+                       inp_blocks = 1+((SHA_CBLOCK-9-res)>>(sizeof(res)*8-1));
+                       res += (unsigned int)(len-inp_len);
+                       pad_blocks = res / SHA_CBLOCK;
+                       res %= SHA_CBLOCK;
+                       pad_blocks += 1+((SHA_CBLOCK-9-res)>>(sizeof(res)*8-1));
+                       for (;inp_blocks<pad_blocks;inp_blocks++)
+                               sha1_block_data_order(&key->md,data,1);
+                       }
+#endif
                        key->md = key->tail;
-                       SHA1_Update(&key->md,mac,SHA_DIGEST_LENGTH);
-                       SHA1_Final(mac,&key->md);
+                       SHA1_Update(&key->md,mac.c,SHA_DIGEST_LENGTH);
+                       SHA1_Final(mac.c,&key->md);
 
-                       if (memcmp(out+iv+len,mac,SHA_DIGEST_LENGTH))
-                               return 0;
+                       /* verify HMAC */
+                       out += inp_len;
+                       len -= inp_len;
+#if 1
+                       {
+                       unsigned char *p = out+len-1-maxpad-SHA_DIGEST_LENGTH;
+                       size_t off = out-p;
+                       unsigned int c, cmask;
+
+                       maxpad += SHA_DIGEST_LENGTH;
+                       for (res=0,i=0,j=0;j<maxpad;j++) {
+                               c = p[j];
+                               cmask = ((int)(j-off-SHA_DIGEST_LENGTH))>>(sizeof(int)*8-1);
+                               res |= (c^pad)&~cmask;  /* ... and padding */
+                               cmask &= ((int)(off-1-j))>>(sizeof(int)*8-1);
+                               res |= (c^mac.c[i])&cmask;
+                               i += 1&cmask;
+                       }
+                       maxpad -= SHA_DIGEST_LENGTH;
+
+                       res = 0-((0-res)>>(sizeof(res)*8-1));
+                       ret &= (int)~res;
+                       }
+#else
+                       for (res=0,i=0;i<SHA_DIGEST_LENGTH;i++)
+                               res |= out[i]^mac.c[i];
+                       res = 0-((0-res)>>(sizeof(res)*8-1));
+                       ret &= (int)~res;
+
+                       /* verify padding */
+                       pad = (pad&~res) | (maxpad&res);
+                       out = out+len-1-pad;
+                       for (res=0,i=0;i<pad;i++)
+                               res |= out[i]^pad;
+
+                       res = (0-res)>>(sizeof(res)*8-1);
+                       ret &= (int)~res;
+#endif
+                       return ret;
                } else {
                        SHA1_Update(&key->md,out,len);
                }
        }
 
-       key->payload_length = NO_PAYLOAD_LENGTH;
-
        return 1;
        }
 
@@ -309,6 +474,8 @@ static int aesni_cbc_hmac_sha1_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void
                SHA1_Init(&key->tail);
                SHA1_Update(&key->tail,hmac_key,sizeof(hmac_key));
 
+               OPENSSL_cleanse(hmac_key,sizeof(hmac_key));
+
                return 1;
                }
        case EVP_CTRL_AEAD_TLS1_AAD:
index 0d1b20a..faeb3c2 100644 (file)
@@ -402,7 +402,6 @@ struct evp_cipher_st
 /* Length of tag for TLS */
 #define EVP_GCM_TLS_TAG_LEN                            16
 
-
 typedef struct evp_cipher_info_st
        {
        const EVP_CIPHER *cipher;
@@ -789,8 +788,8 @@ const EVP_CIPHER *EVP_aes_128_cfb128(void);
 # define EVP_aes_128_cfb EVP_aes_128_cfb128
 const EVP_CIPHER *EVP_aes_128_ofb(void);
 const EVP_CIPHER *EVP_aes_128_ctr(void);
-const EVP_CIPHER *EVP_aes_128_gcm(void);
 const EVP_CIPHER *EVP_aes_128_ccm(void);
+const EVP_CIPHER *EVP_aes_128_gcm(void);
 const EVP_CIPHER *EVP_aes_128_xts(void);
 const EVP_CIPHER *EVP_aes_192_ecb(void);
 const EVP_CIPHER *EVP_aes_192_cbc(void);
@@ -800,8 +799,8 @@ const EVP_CIPHER *EVP_aes_192_cfb128(void);
 # define EVP_aes_192_cfb EVP_aes_192_cfb128
 const EVP_CIPHER *EVP_aes_192_ofb(void);
 const EVP_CIPHER *EVP_aes_192_ctr(void);
-const EVP_CIPHER *EVP_aes_192_gcm(void);
 const EVP_CIPHER *EVP_aes_192_ccm(void);
+const EVP_CIPHER *EVP_aes_192_gcm(void);
 const EVP_CIPHER *EVP_aes_256_ecb(void);
 const EVP_CIPHER *EVP_aes_256_cbc(void);
 const EVP_CIPHER *EVP_aes_256_cfb1(void);
@@ -810,8 +809,8 @@ const EVP_CIPHER *EVP_aes_256_cfb128(void);
 # define EVP_aes_256_cfb EVP_aes_256_cfb128
 const EVP_CIPHER *EVP_aes_256_ofb(void);
 const EVP_CIPHER *EVP_aes_256_ctr(void);
-const EVP_CIPHER *EVP_aes_256_gcm(void);
 const EVP_CIPHER *EVP_aes_256_ccm(void);
+const EVP_CIPHER *EVP_aes_256_gcm(void);
 const EVP_CIPHER *EVP_aes_256_xts(void);
 #if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_SHA1)
 const EVP_CIPHER *EVP_aes_128_cbc_hmac_sha1(void);
@@ -1243,6 +1242,8 @@ void EVP_PKEY_meth_set_ctrl(EVP_PKEY_METHOD *pmeth,
        int (*ctrl_str)(EVP_PKEY_CTX *ctx,
                                        const char *type, const char *value));
 
+void EVP_add_alg_module(void);
+
 /* BEGIN ERROR CODES */
 /* The following lines are auto generated by the script mkerr.pl. Any changes
  * made after this point may be overwritten when the script is next run.
@@ -1257,6 +1258,7 @@ void ERR_load_EVP_strings(void);
 #define EVP_F_AES_INIT_KEY                              133
 #define EVP_F_AES_XTS                                   172
 #define EVP_F_AES_XTS_CIPHER                            175
+#define EVP_F_ALG_MODULE_INIT                           177
 #define EVP_F_CAMELLIA_INIT_KEY                                 159
 #define EVP_F_CMAC_INIT                                         173
 #define EVP_F_D2I_PKEY                                  100
@@ -1350,15 +1352,19 @@ void ERR_load_EVP_strings(void);
 #define EVP_R_DIFFERENT_PARAMETERS                      153
 #define EVP_R_DISABLED_FOR_FIPS                                 163
 #define EVP_R_ENCODE_ERROR                              115
+#define EVP_R_ERROR_LOADING_SECTION                     165
+#define EVP_R_ERROR_SETTING_FIPS_MODE                   166
 #define EVP_R_EVP_PBE_CIPHERINIT_ERROR                  119
 #define EVP_R_EXPECTING_AN_RSA_KEY                      127
 #define EVP_R_EXPECTING_A_DH_KEY                        128
 #define EVP_R_EXPECTING_A_DSA_KEY                       129
 #define EVP_R_EXPECTING_A_ECDSA_KEY                     141
 #define EVP_R_EXPECTING_A_EC_KEY                        142
+#define EVP_R_FIPS_MODE_NOT_SUPPORTED                   167
 #define EVP_R_INITIALIZATION_ERROR                      134
 #define EVP_R_INPUT_NOT_INITIALIZED                     111
 #define EVP_R_INVALID_DIGEST                            152
+#define EVP_R_INVALID_FIPS_MODE                                 168
 #define EVP_R_INVALID_KEY_LENGTH                        130
 #define EVP_R_INVALID_OPERATION                                 148
 #define EVP_R_IV_TOO_LARGE                              102
@@ -1383,6 +1389,7 @@ void ERR_load_EVP_strings(void);
 #define EVP_R_TOO_LARGE                                         164
 #define EVP_R_UNKNOWN_CIPHER                            160
 #define EVP_R_UNKNOWN_DIGEST                            161
+#define EVP_R_UNKNOWN_OPTION                            169
 #define EVP_R_UNKNOWN_PBE_ALGORITHM                     121
 #define EVP_R_UNSUPORTED_NUMBER_OF_ROUNDS               135
 #define EVP_R_UNSUPPORTED_ALGORITHM                     156
similarity index 67%
copy from crypto/openssl/crypto/conf/conf_mall.c
copy to crypto/openssl/crypto/evp/evp_cnf.c
index c6f4cb2..2e4db30 100644 (file)
@@ -1,9 +1,9 @@
-/* conf_mall.c */
+/* evp_cnf.c */
 /* Written by Stephen Henson (steve@openssl.org) for the OpenSSL
- * project 2001.
+ * project 2007.
  */
 /* ====================================================================
- * Copyright (c) 2001 The OpenSSL Project.  All rights reserved.
+ * Copyright (c) 2007 The OpenSSL Project.  All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  */
 
 #include <stdio.h>
+#include <ctype.h>
 #include <openssl/crypto.h>
 #include "cryptlib.h"
 #include <openssl/conf.h>
 #include <openssl/dso.h>
 #include <openssl/x509.h>
-#include <openssl/asn1.h>
-#ifndef OPENSSL_NO_ENGINE
-#include <openssl/engine.h>
+#include <openssl/x509v3.h>
+#ifdef OPENSSL_FIPS
+#include <openssl/fips.h>
 #endif
 
-/* Load all OpenSSL builtin modules */
 
-void OPENSSL_load_builtin_modules(void)
+/* Algorithm configuration module. */
+
+static int alg_module_init(CONF_IMODULE *md, const CONF *cnf)
        {
-       /* Add builtin modules here */
-       ASN1_add_oid_module();
-#ifndef OPENSSL_NO_ENGINE
-       ENGINE_add_conf_module();
+       int i;
+       const char *oid_section;
+       STACK_OF(CONF_VALUE) *sktmp;
+       CONF_VALUE *oval;
+       oid_section = CONF_imodule_get_value(md);
+       if(!(sktmp = NCONF_get_section(cnf, oid_section)))
+               {
+               EVPerr(EVP_F_ALG_MODULE_INIT, EVP_R_ERROR_LOADING_SECTION);
+               return 0;
+               }
+       for(i = 0; i < sk_CONF_VALUE_num(sktmp); i++)
+               {
+               oval = sk_CONF_VALUE_value(sktmp, i);
+               if (!strcmp(oval->name, "fips_mode"))
+                       {
+                       int m;
+                       if (!X509V3_get_value_bool(oval, &m))
+                               {
+                               EVPerr(EVP_F_ALG_MODULE_INIT, EVP_R_INVALID_FIPS_MODE);
+                               return 0;
+                               }
+                       if (m > 0)
+                               {
+#ifdef OPENSSL_FIPS
+                               if (!FIPS_mode() && !FIPS_mode_set(1))
+                                       {
+                                       EVPerr(EVP_F_ALG_MODULE_INIT, EVP_R_ERROR_SETTING_FIPS_MODE);
+                                       return 0;
+                                       }
+#else
+                               EVPerr(EVP_F_ALG_MODULE_INIT, EVP_R_FIPS_MODE_NOT_SUPPORTED);
+                               return 0;
 #endif
+                               }
+                       }
+               else
+                       {
+                       EVPerr(EVP_F_ALG_MODULE_INIT, EVP_R_UNKNOWN_OPTION);
+                       ERR_add_error_data(4, "name=", oval->name,
+                                               ", value=", oval->value);
+                       }
+                               
+               }
+       return 1;
        }
 
+void EVP_add_alg_module(void)
+       {
+       CONF_module_add("alg_section", alg_module_init, 0);
+       }
index db0f76d..08eab98 100644 (file)
@@ -75,6 +75,7 @@ static ERR_STRING_DATA EVP_str_functs[]=
 {ERR_FUNC(EVP_F_AES_INIT_KEY), "AES_INIT_KEY"},
 {ERR_FUNC(EVP_F_AES_XTS),      "AES_XTS"},
 {ERR_FUNC(EVP_F_AES_XTS_CIPHER),       "AES_XTS_CIPHER"},
+{ERR_FUNC(EVP_F_ALG_MODULE_INIT),      "ALG_MODULE_INIT"},
 {ERR_FUNC(EVP_F_CAMELLIA_INIT_KEY),    "CAMELLIA_INIT_KEY"},
 {ERR_FUNC(EVP_F_CMAC_INIT),    "CMAC_INIT"},
 {ERR_FUNC(EVP_F_D2I_PKEY),     "D2I_PKEY"},
@@ -171,15 +172,19 @@ static ERR_STRING_DATA EVP_str_reasons[]=
 {ERR_REASON(EVP_R_DIFFERENT_PARAMETERS)  ,"different parameters"},
 {ERR_REASON(EVP_R_DISABLED_FOR_FIPS)     ,"disabled for fips"},
 {ERR_REASON(EVP_R_ENCODE_ERROR)          ,"encode error"},
+{ERR_REASON(EVP_R_ERROR_LOADING_SECTION) ,"error loading section"},
+{ERR_REASON(EVP_R_ERROR_SETTING_FIPS_MODE),"error setting fips mode"},
 {ERR_REASON(EVP_R_EVP_PBE_CIPHERINIT_ERROR),"evp pbe cipherinit error"},
 {ERR_REASON(EVP_R_EXPECTING_AN_RSA_KEY)  ,"expecting an rsa key"},
 {ERR_REASON(EVP_R_EXPECTING_A_DH_KEY)    ,"expecting a dh key"},
 {ERR_REASON(EVP_R_EXPECTING_A_DSA_KEY)   ,"expecting a dsa key"},
 {ERR_REASON(EVP_R_EXPECTING_A_ECDSA_KEY) ,"expecting a ecdsa key"},
 {ERR_REASON(EVP_R_EXPECTING_A_EC_KEY)    ,"expecting a ec key"},
+{ERR_REASON(EVP_R_FIPS_MODE_NOT_SUPPORTED),"fips mode not supported"},
 {ERR_REASON(EVP_R_INITIALIZATION_ERROR)  ,"initialization error"},
 {ERR_REASON(EVP_R_INPUT_NOT_INITIALIZED) ,"input not initialized"},
 {ERR_REASON(EVP_R_INVALID_DIGEST)        ,"invalid digest"},
+{ERR_REASON(EVP_R_INVALID_FIPS_MODE)     ,"invalid fips mode"},
 {ERR_REASON(EVP_R_INVALID_KEY_LENGTH)    ,"invalid key length"},
 {ERR_REASON(EVP_R_INVALID_OPERATION)     ,"invalid operation"},
 {ERR_REASON(EVP_R_IV_TOO_LARGE)          ,"iv too large"},
@@ -204,6 +209,7 @@ static ERR_STRING_DATA EVP_str_reasons[]=
 {ERR_REASON(EVP_R_TOO_LARGE)             ,"too large"},
 {ERR_REASON(EVP_R_UNKNOWN_CIPHER)        ,"unknown cipher"},
 {ERR_REASON(EVP_R_UNKNOWN_DIGEST)        ,"unknown digest"},
+{ERR_REASON(EVP_R_UNKNOWN_OPTION)        ,"unknown option"},
 {ERR_REASON(EVP_R_UNKNOWN_PBE_ALGORITHM) ,"unknown pbe algorithm"},
 {ERR_REASON(EVP_R_UNSUPORTED_NUMBER_OF_ROUNDS),"unsuported number of rounds"},
 {ERR_REASON(EVP_R_UNSUPPORTED_ALGORITHM) ,"unsupported algorithm"},
index 4ad63ad..6fb7e9a 100644 (file)
@@ -60,7 +60,7 @@
 #include "cryptlib.h"
 #include <openssl/evp.h>
 #include <openssl/objects.h>
-#include <openssl/x509.h>
+#include <openssl/sha.h>
 #ifndef OPENSSL_NO_DSA
 #include <openssl/dsa.h>
 #endif
index f80170e..2df362a 100644 (file)
@@ -63,7 +63,7 @@
 
 #include <openssl/evp.h>
 #include <openssl/objects.h>
-#include <openssl/x509.h>
+#include <openssl/sha.h>
 #ifndef OPENSSL_NO_DSA
 #include <openssl/dsa.h>
 #endif
index 3cb11f1..bd0c01a 100644 (file)
@@ -65,7 +65,7 @@
 
 #include <openssl/evp.h>
 #include <openssl/objects.h>
-#include <openssl/x509.h>
+#include <openssl/sha.h>
 #ifndef OPENSSL_NO_RSA
 #include <openssl/rsa.h>
 #endif
index dfa48c1..8afb664 100644 (file)
@@ -80,7 +80,7 @@ int EVP_SignFinal(EVP_MD_CTX *ctx, unsigned char *sigret, unsigned int *siglen,
        {
        unsigned char m[EVP_MAX_MD_SIZE];
        unsigned int m_len;
-       int i=0,ok=0,v;
+       int i = 0,ok = 0,v;
        EVP_MD_CTX tmp_ctx;
        EVP_PKEY_CTX *pkctx = NULL;
 
index 5f5c409..c66d63c 100644 (file)
@@ -67,7 +67,7 @@ int EVP_VerifyFinal(EVP_MD_CTX *ctx, const unsigned char *sigbuf,
        {
        unsigned char m[EVP_MAX_MD_SIZE];
        unsigned int m_len;
-       int i=-1,ok=0,v;
+       int i = 0,ok = 0,v;
        EVP_MD_CTX tmp_ctx;
        EVP_PKEY_CTX *pkctx = NULL;
 
index 82c2cb2..b5b165b 100644 (file)
@@ -106,22 +106,23 @@ void md4_block_data_order (MD4_CTX *c, const void *data_, size_t num)
 
        for (;num--;)
                {
-       HOST_c2l(data,l); X( 0)=l;              HOST_c2l(data,l); X( 1)=l;
+       (void)HOST_c2l(data,l); X( 0)=l;
+       (void)HOST_c2l(data,l); X( 1)=l;
        /* Round 0 */
-       R0(A,B,C,D,X( 0), 3,0); HOST_c2l(data,l); X( 2)=l;
-       R0(D,A,B,C,X( 1), 7,0); HOST_c2l(data,l); X( 3)=l;
-       R0(C,D,A,B,X( 2),11,0); HOST_c2l(data,l); X( 4)=l;
-       R0(B,C,D,A,X( 3),19,0); HOST_c2l(data,l); X( 5)=l;
-       R0(A,B,C,D,X( 4), 3,0); HOST_c2l(data,l); X( 6)=l;
-       R0(D,A,B,C,X( 5), 7,0); HOST_c2l(data,l); X( 7)=l;
-       R0(C,D,A,B,X( 6),11,0); HOST_c2l(data,l); X( 8)=l;
-       R0(B,C,D,A,X( 7),19,0); HOST_c2l(data,l); X( 9)=l;
-       R0(A,B,C,D,X( 8), 3,0); HOST_c2l(data,l); X(10)=l;
-       R0(D,A,B,C,X( 9), 7,0); HOST_c2l(data,l); X(11)=l;
-       R0(C,D,A,B,X(10),11,0); HOST_c2l(data,l); X(12)=l;
-       R0(B,C,D,A,X(11),19,0); HOST_c2l(data,l); X(13)=l;
-       R0(A,B,C,D,X(12), 3,0); HOST_c2l(data,l); X(14)=l;
-       R0(D,A,B,C,X(13), 7,0); HOST_c2l(data,l); X(15)=l;
+       R0(A,B,C,D,X( 0), 3,0); (void)HOST_c2l(data,l); X( 2)=l;
+       R0(D,A,B,C,X( 1), 7,0); (void)HOST_c2l(data,l); X( 3)=l;
+       R0(C,D,A,B,X( 2),11,0); (void)HOST_c2l(data,l); X( 4)=l;
+       R0(B,C,D,A,X( 3),19,0); (void)HOST_c2l(data,l); X( 5)=l;
+       R0(A,B,C,D,X( 4), 3,0); (void)HOST_c2l(data,l); X( 6)=l;
+       R0(D,A,B,C,X( 5), 7,0); (void)HOST_c2l(data,l); X( 7)=l;
+       R0(C,D,A,B,X( 6),11,0); (void)HOST_c2l(data,l); X( 8)=l;
+       R0(B,C,D,A,X( 7),19,0); (void)HOST_c2l(data,l); X( 9)=l;
+       R0(A,B,C,D,X( 8), 3,0); (void)HOST_c2l(data,l); X(10)=l;
+       R0(D,A,B,C,X( 9), 7,0); (void)HOST_c2l(data,l); X(11)=l;
+       R0(C,D,A,B,X(10),11,0); (void)HOST_c2l(data,l); X(12)=l;
+       R0(B,C,D,A,X(11),19,0); (void)HOST_c2l(data,l); X(13)=l;
+       R0(A,B,C,D,X(12), 3,0); (void)HOST_c2l(data,l); X(14)=l;
+       R0(D,A,B,C,X(13), 7,0); (void)HOST_c2l(data,l); X(15)=l;
        R0(C,D,A,B,X(14),11,0);
        R0(B,C,D,A,X(15),19,0);
        /* Round 1 */
index c8085b0..99c3e50 100644 (file)
@@ -77,10 +77,10 @@ void md4_block_data_order (MD4_CTX *c, const void *p,size_t num);
 #define HASH_FINAL             MD4_Final
 #define        HASH_MAKE_STRING(c,s)   do {    \
        unsigned long ll;               \
-       ll=(c)->A; HOST_l2c(ll,(s));    \
-       ll=(c)->B; HOST_l2c(ll,(s));    \
-       ll=(c)->C; HOST_l2c(ll,(s));    \
-       ll=(c)->D; HOST_l2c(ll,(s));    \
+       ll=(c)->A; (void)HOST_l2c(ll,(s));      \
+       ll=(c)->B; (void)HOST_l2c(ll,(s));      \
+       ll=(c)->C; (void)HOST_l2c(ll,(s));      \
+       ll=(c)->D; (void)HOST_l2c(ll,(s));      \
        } while (0)
 #define        HASH_BLOCK_DATA_ORDER   md4_block_data_order
 
index 8678854..f11224d 100755 (executable)
@@ -120,7 +120,8 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; my $dir=$1; my $xlate;
 die "can't locate x86_64-xlate.pl";
 
 no warnings qw(uninitialized);
-open STDOUT,"| $^X $xlate $flavour $output";
+open OUT,"| \"$^X\" $xlate $flavour $output";
+*STDOUT=*OUT;
 
 $code .= <<EOF;
 .text
index 968d577..74d63d1 100644 (file)
@@ -86,10 +86,10 @@ void md5_block_data_order (MD5_CTX *c, const void *p,size_t num);
 #define HASH_FINAL             MD5_Final
 #define        HASH_MAKE_STRING(c,s)   do {    \
        unsigned long ll;               \
-       ll=(c)->A; HOST_l2c(ll,(s));    \
-       ll=(c)->B; HOST_l2c(ll,(s));    \
-       ll=(c)->C; HOST_l2c(ll,(s));    \
-       ll=(c)->D; HOST_l2c(ll,(s));    \
+       ll=(c)->A; (void)HOST_l2c(ll,(s));      \
+       ll=(c)->B; (void)HOST_l2c(ll,(s));      \
+       ll=(c)->C; (void)HOST_l2c(ll,(s));      \
+       ll=(c)->D; (void)HOST_l2c(ll,(s));      \
        } while (0)
 #define        HASH_BLOCK_DATA_ORDER   md5_block_data_order
 
index b74bb1a..d66ed6a 100644 (file)
@@ -59,9 +59,9 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <openssl/crypto.h>
 #include <openssl/des.h>
 #include <openssl/mdc2.h>
-#include <openssl/crypto.h>
 
 #undef c2l
 #define c2l(c,l)       (l =((DES_LONG)(*((c)++)))    , \
index 21c0011..1cc62ea 100644 (file)
@@ -121,10 +121,10 @@ static void (*set_debug_options_func)(long) = NULL;
 static long (*get_debug_options_func)(void) = NULL;
 #endif
 
-
 int CRYPTO_set_mem_functions(void *(*m)(size_t), void *(*r)(void *, size_t),
        void (*f)(void *))
        {
+       /* Dummy call just to ensure OPENSSL_init() gets linked in */
        OPENSSL_init();
        if (!allow_customize)
                return 0;
index 6b09669..83c727e 100644 (file)
@@ -635,7 +635,7 @@ sub mmx_loop() {
     { my @lo  = ("mm0","mm1","mm2");
       my @hi  = ("mm3","mm4","mm5");
       my @tmp = ("mm6","mm7");
-      my $off1=0,$off2=0,$i;
+      my ($off1,$off2,$i) = (0,0,);
 
       &add     ($Htbl,128);                    # optimize for size
       &lea     ("edi",&DWP(16+128,"esp"));
@@ -883,7 +883,7 @@ sub reduction_alg9 {        # 17/13 times faster than Intel version
 my ($Xhi,$Xi) = @_;
 
        # 1st phase
-       &movdqa         ($T1,$Xi)               #
+       &movdqa         ($T1,$Xi);              #
        &psllq          ($Xi,1);
        &pxor           ($Xi,$T1);              #
        &psllq          ($Xi,5);                #
@@ -1019,7 +1019,7 @@ my ($Xhi,$Xi) = @_;
        &movdqa         ($Xhn,$Xn);
         &pxor          ($Xhi,$T1);             # "Ii+Xi", consume early
 
-         &movdqa       ($T1,$Xi)               #&reduction_alg9($Xhi,$Xi); 1st phase
+         &movdqa       ($T1,$Xi);              #&reduction_alg9($Xhi,$Xi); 1st phase
          &psllq        ($Xi,1);
          &pxor         ($Xi,$T1);              #
          &psllq        ($Xi,5);                #
index a5ae180..38d779e 100644 (file)
@@ -50,7 +50,8 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
 ( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or
 die "can't locate x86_64-xlate.pl";
 
-open STDOUT,"| $^X $xlate $flavour $output";
+open OUT,"| \"$^X\" $xlate $flavour $output";
+*STDOUT=*OUT;
 
 # common register layout
 $nlo="%rax";
index 7d6d034..0e6ff8b 100644 (file)
@@ -723,7 +723,7 @@ void CRYPTO_gcm128_init(GCM128_CONTEXT *ctx,void *key,block128_f block)
 #  endif
        gcm_init_4bit(ctx->Htable,ctx->H.u);
 #  if  defined(GHASH_ASM_X86)                  /* x86 only */
-#   if defined(OPENSSL_IA32_SSE2)
+#   if defined(OPENSSL_IA32_SSE2)
        if (OPENSSL_ia32cap_P[0]&(1<<25)) {     /* check SSE bit */
 #   else
        if (OPENSSL_ia32cap_P[0]&(1<<23)) {     /* check MMX bit */
@@ -1398,7 +1398,7 @@ int CRYPTO_gcm128_finish(GCM128_CONTEXT *ctx,const unsigned char *tag,
        void (*gcm_gmult_p)(u64 Xi[2],const u128 Htable[16])    = ctx->gmult;
 #endif
 
-       if (ctx->mres)
+       if (ctx->mres || ctx->ares)
                GCM_MUL(ctx,Xi);
 
        if (is_endian.little) {
index 84380a9..4a548c2 100644 (file)
@@ -73,7 +73,7 @@ int OBJ_NAME_new_index(unsigned long (*hash_func)(const char *),
                name_funcs_stack=sk_NAME_FUNCS_new_null();
                MemCheck_on();
                }
-       if ((name_funcs_stack == NULL))
+       if (name_funcs_stack == NULL)
                {
                /* ERROR */
                return(0);
index 415d67e..2767183 100644 (file)
@@ -91,9 +91,12 @@ int OCSP_basic_verify(OCSP_BASICRESP *bs, STACK_OF(X509) *certs,
                {
                EVP_PKEY *skey;
                skey = X509_get_pubkey(signer);
-               ret = OCSP_BASICRESP_verify(bs, skey, 0);
-               EVP_PKEY_free(skey);
-               if(ret <= 0)
+               if (skey)
+                       {
+                       ret = OCSP_BASICRESP_verify(bs, skey, 0);
+                       EVP_PKEY_free(skey);
+                       }
+               if(!skey || ret <= 0)
                        {
                        OCSPerr(OCSP_F_OCSP_BASIC_VERIFY, OCSP_R_SIGNATURE_FAILURE);
                        goto end;
@@ -108,6 +111,7 @@ int OCSP_basic_verify(OCSP_BASICRESP *bs, STACK_OF(X509) *certs,
                        init_res = X509_STORE_CTX_init(&ctx, st, signer, bs->certs);
                if(!init_res)
                        {
+                       ret = -1;
                        OCSPerr(OCSP_F_OCSP_BASIC_VERIFY,ERR_R_X509_LIB);
                        goto end;
                        }
index 71be359..dbea4ad 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 0x1000103fL
+#define OPENSSL_VERSION_NUMBER 0x1000104fL
 #ifdef OPENSSL_FIPS
-#define OPENSSL_VERSION_TEXT   "OpenSSL 1.0.1c-fips 10 May 2012"
+#define OPENSSL_VERSION_TEXT   "OpenSSL 1.0.1d-fips 5 Feb 2013"
 #else
-#define OPENSSL_VERSION_TEXT   "OpenSSL 1.0.1c 10 May 2012"
+#define OPENSSL_VERSION_TEXT   "OpenSSL 1.0.1d 5 Feb 2013"
 #endif
 #define OPENSSL_VERSION_PTEXT  " part of " OPENSSL_VERSION_TEXT
 
index 3e7a609..eac0460 100644 (file)
@@ -193,7 +193,61 @@ RSA *PEM_read_RSAPrivateKey(FILE *fp, RSA **rsa, pem_password_cb *cb,
 
 #endif
 
+#ifdef OPENSSL_FIPS
+
+int PEM_write_bio_RSAPrivateKey(BIO *bp, RSA *x, const EVP_CIPHER *enc,
+                                               unsigned char *kstr, int klen,
+                                               pem_password_cb *cb, void *u)
+{
+       if (FIPS_mode())
+               {
+               EVP_PKEY *k;
+               int ret;
+               k = EVP_PKEY_new();
+               if (!k)
+                       return 0;
+               EVP_PKEY_set1_RSA(k, x);
+
+               ret = PEM_write_bio_PrivateKey(bp, k, enc, kstr, klen, cb, u);
+               EVP_PKEY_free(k);
+               return ret;
+               }
+       else
+               return PEM_ASN1_write_bio((i2d_of_void *)i2d_RSAPrivateKey,
+                                       PEM_STRING_RSA,bp,x,enc,kstr,klen,cb,u);
+}
+
+#ifndef OPENSSL_NO_FP_API
+int PEM_write_RSAPrivateKey(FILE *fp, RSA *x, const EVP_CIPHER *enc,
+                                               unsigned char *kstr, int klen,
+                                               pem_password_cb *cb, void *u)
+{
+       if (FIPS_mode())
+               {
+               EVP_PKEY *k;
+               int ret;
+               k = EVP_PKEY_new();
+               if (!k)
+                       return 0;
+
+               EVP_PKEY_set1_RSA(k, x);
+
+               ret = PEM_write_PrivateKey(fp, k, enc, kstr, klen, cb, u);
+               EVP_PKEY_free(k);
+               return ret;
+               }
+       else
+               return PEM_ASN1_write((i2d_of_void *)i2d_RSAPrivateKey,
+                                       PEM_STRING_RSA,fp,x,enc,kstr,klen,cb,u);
+}
+#endif
+
+#else
+
 IMPLEMENT_PEM_write_cb_const(RSAPrivateKey, RSA, PEM_STRING_RSA, RSAPrivateKey)
+
+#endif
+
 IMPLEMENT_PEM_rw_const(RSAPublicKey, RSA, PEM_STRING_RSA_PUBLIC, RSAPublicKey)
 IMPLEMENT_PEM_rw(RSA_PUBKEY, RSA, PEM_STRING_PUBLIC, RSA_PUBKEY)
 
@@ -223,7 +277,59 @@ DSA *PEM_read_bio_DSAPrivateKey(BIO *bp, DSA **dsa, pem_password_cb *cb,
        return pkey_get_dsa(pktmp, dsa);        /* will free pktmp */
 }
 
+#ifdef OPENSSL_FIPS
+
+int PEM_write_bio_DSAPrivateKey(BIO *bp, DSA *x, const EVP_CIPHER *enc,
+                                               unsigned char *kstr, int klen,
+                                               pem_password_cb *cb, void *u)
+{
+       if (FIPS_mode())
+               {
+               EVP_PKEY *k;
+               int ret;
+               k = EVP_PKEY_new();
+               if (!k)
+                       return 0;
+               EVP_PKEY_set1_DSA(k, x);
+
+               ret = PEM_write_bio_PrivateKey(bp, k, enc, kstr, klen, cb, u);
+               EVP_PKEY_free(k);
+               return ret;
+               }
+       else
+               return PEM_ASN1_write_bio((i2d_of_void *)i2d_DSAPrivateKey,
+                                       PEM_STRING_DSA,bp,x,enc,kstr,klen,cb,u);
+}
+
+#ifndef OPENSSL_NO_FP_API
+int PEM_write_DSAPrivateKey(FILE *fp, DSA *x, const EVP_CIPHER *enc,
+                                               unsigned char *kstr, int klen,
+                                               pem_password_cb *cb, void *u)
+{
+       if (FIPS_mode())
+               {
+               EVP_PKEY *k;
+               int ret;
+               k = EVP_PKEY_new();
+               if (!k)
+                       return 0;
+               EVP_PKEY_set1_DSA(k, x);
+               ret = PEM_write_PrivateKey(fp, k, enc, kstr, klen, cb, u);
+               EVP_PKEY_free(k);
+               return ret;
+               }
+       else
+               return PEM_ASN1_write((i2d_of_void *)i2d_DSAPrivateKey,
+                                       PEM_STRING_DSA,fp,x,enc,kstr,klen,cb,u);
+}
+#endif
+
+#else
+
 IMPLEMENT_PEM_write_cb_const(DSAPrivateKey, DSA, PEM_STRING_DSA, DSAPrivateKey)
+
+#endif
+
 IMPLEMENT_PEM_rw(DSA_PUBKEY, DSA, PEM_STRING_PUBLIC, DSA_PUBKEY)
 
 #ifndef OPENSSL_NO_FP_API
@@ -269,8 +375,63 @@ EC_KEY *PEM_read_bio_ECPrivateKey(BIO *bp, EC_KEY **key, pem_password_cb *cb,
 
 IMPLEMENT_PEM_rw_const(ECPKParameters, EC_GROUP, PEM_STRING_ECPARAMETERS, ECPKParameters)
 
+
+
+#ifdef OPENSSL_FIPS
+
+int PEM_write_bio_ECPrivateKey(BIO *bp, EC_KEY *x, const EVP_CIPHER *enc,
+                                               unsigned char *kstr, int klen,
+                                               pem_password_cb *cb, void *u)
+{
+       if (FIPS_mode())
+               {
+               EVP_PKEY *k;
+               int ret;
+               k = EVP_PKEY_new();
+               if (!k)
+                       return 0;
+               EVP_PKEY_set1_EC_KEY(k, x);
+
+               ret = PEM_write_bio_PrivateKey(bp, k, enc, kstr, klen, cb, u);
+               EVP_PKEY_free(k);
+               return ret;
+               }
+       else
+               return PEM_ASN1_write_bio((i2d_of_void *)i2d_ECPrivateKey,
+                                               PEM_STRING_ECPRIVATEKEY,
+                                               bp,x,enc,kstr,klen,cb,u);
+}
+
+#ifndef OPENSSL_NO_FP_API
+int PEM_write_ECPrivateKey(FILE *fp, EC_KEY *x, const EVP_CIPHER *enc,
+                                               unsigned char *kstr, int klen,
+                                               pem_password_cb *cb, void *u)
+{
+       if (FIPS_mode())
+               {
+               EVP_PKEY *k;
+               int ret;
+               k = EVP_PKEY_new();
+               if (!k)
+                       return 0;
+               EVP_PKEY_set1_EC_KEY(k, x);
+               ret = PEM_write_PrivateKey(fp, k, enc, kstr, klen, cb, u);
+               EVP_PKEY_free(k);
+               return ret;
+               }
+       else
+               return PEM_ASN1_write((i2d_of_void *)i2d_ECPrivateKey,
+                                               PEM_STRING_ECPRIVATEKEY,
+                                               fp,x,enc,kstr,klen,cb,u);
+}
+#endif
+
+#else
+
 IMPLEMENT_PEM_write_cb(ECPrivateKey, EC_KEY, PEM_STRING_ECPRIVATEKEY, ECPrivateKey)
 
+#endif
+
 IMPLEMENT_PEM_rw(EC_PUBKEY, EC_KEY, PEM_STRING_PUBLIC, EC_PUBKEY)
 
 #ifndef OPENSSL_NO_FP_API
index cfc89a9..5a421fc 100644 (file)
@@ -394,7 +394,8 @@ int PEM_ASN1_write_bio(i2d_of_void *i2d, const char *name, BIO *bp,
                        goto err;
                /* The 'iv' is used as the iv and as a salt.  It is
                 * NOT taken from the BytesToKey function */
-               EVP_BytesToKey(enc,EVP_md5(),iv,kstr,klen,1,key,NULL);
+               if (!EVP_BytesToKey(enc,EVP_md5(),iv,kstr,klen,1,key,NULL))
+                       goto err;
 
                if (kstr == (unsigned char *)buf) OPENSSL_cleanse(buf,PEM_BUFSIZE);
 
@@ -406,12 +407,15 @@ int PEM_ASN1_write_bio(i2d_of_void *i2d, const char *name, BIO *bp,
                /* k=strlen(buf); */
 
                EVP_CIPHER_CTX_init(&ctx);
-               EVP_EncryptInit_ex(&ctx,enc,NULL,key,iv);
-               EVP_EncryptUpdate(&ctx,data,&j,data,i);
-               EVP_EncryptFinal_ex(&ctx,&(data[j]),&i);
+               ret = 1;
+               if (!EVP_EncryptInit_ex(&ctx,enc,NULL,key,iv)
+                       || !EVP_EncryptUpdate(&ctx,data,&j,data,i)
+                       || !EVP_EncryptFinal_ex(&ctx,&(data[j]),&i))
+                       ret = 0;
                EVP_CIPHER_CTX_cleanup(&ctx);
+               if (ret == 0)
+                       goto err;
                i+=j;
-               ret=1;
                }
        else
                {
@@ -459,14 +463,17 @@ int PEM_do_header(EVP_CIPHER_INFO *cipher, unsigned char *data, long *plen,
        ebcdic2ascii(buf, buf, klen);
 #endif
 
-       EVP_BytesToKey(cipher->cipher,EVP_md5(),&(cipher->iv[0]),
-               (unsigned char *)buf,klen,1,key,NULL);
+       if (!EVP_BytesToKey(cipher->cipher,EVP_md5(),&(cipher->iv[0]),
+               (unsigned char *)buf,klen,1,key,NULL))
+               return 0;
 
        j=(int)len;
        EVP_CIPHER_CTX_init(&ctx);
-       EVP_DecryptInit_ex(&ctx,cipher->cipher,NULL, key,&(cipher->iv[0]));
-       EVP_DecryptUpdate(&ctx,data,&i,data,j);
-       o=EVP_DecryptFinal_ex(&ctx,&(data[i]),&j);
+       o = EVP_DecryptInit_ex(&ctx,cipher->cipher,NULL, key,&(cipher->iv[0]));
+       if (o)
+               o = EVP_DecryptUpdate(&ctx,data,&i,data,j);
+       if (o)
+               o = EVP_DecryptFinal_ex(&ctx,&(data[i]),&j);
        EVP_CIPHER_CTX_cleanup(&ctx);
        OPENSSL_cleanse((char *)buf,sizeof(buf));
        OPENSSL_cleanse((char *)key,sizeof(key));
index 59690b5..b6b4e13 100644 (file)
@@ -96,7 +96,8 @@ int PEM_SealInit(PEM_ENCODE_SEAL_CTX *ctx, EVP_CIPHER *type, EVP_MD *md_type,
        EVP_EncodeInit(&ctx->encode);
 
        EVP_MD_CTX_init(&ctx->md);
-       EVP_SignInit(&ctx->md,md_type);
+       if (!EVP_SignInit(&ctx->md,md_type))
+               goto err;
 
        EVP_CIPHER_CTX_init(&ctx->cipher);
        ret=EVP_SealInit(&ctx->cipher,type,ek,ekl,iv,pubk,npubk);
@@ -163,7 +164,8 @@ int PEM_SealFinal(PEM_ENCODE_SEAL_CTX *ctx, unsigned char *sig, int *sigl,
                goto err;
                }
 
-       EVP_EncryptFinal_ex(&ctx->cipher,s,(int *)&i);
+       if (!EVP_EncryptFinal_ex(&ctx->cipher,s,(int *)&i))
+               goto err;
        EVP_EncodeUpdate(&ctx->encode,out,&j,s,i);
        *outl=j;
        out+=j;
index 6fc2510..24561e7 100644 (file)
@@ -150,7 +150,7 @@ sub cbc
 &set_label("PIC_point");
        &blindpop("edx");
        &lea("ecx",&DWP(&label("cbc_enc_jmp_table")."-".&label("PIC_point"),"edx"));
-       &mov($count,&DWP(0,"ecx",$count,4))
+       &mov($count,&DWP(0,"ecx",$count,4));
        &add($count,"edx");
        &xor("ecx","ecx");
        &xor("edx","edx");
index c55c7b6..61d5850 100644 (file)
@@ -176,24 +176,32 @@ int PKCS12_key_gen_uni(unsigned char *pass, int passlen, unsigned char *salt,
                out += u;
                for (j = 0; j < v; j++) B[j] = Ai[j % u];
                /* Work out B + 1 first then can use B as tmp space */
-               if (!BN_bin2bn (B, v, Bpl1)) goto err;
-               if (!BN_add_word (Bpl1, 1)) goto err;
+               if (!BN_bin2bn (B, v, Bpl1))
+                       goto err;
+               if (!BN_add_word (Bpl1, 1))
+                       goto err;
                for (j = 0; j < Ilen ; j+=v) {
-                       if (!BN_bin2bn (I + j, v, Ij)) goto err;
-                       if (!BN_add (Ij, Ij, Bpl1)) goto err;
-                       BN_bn2bin (Ij, B);
+                       if (!BN_bin2bn(I + j, v, Ij))
+                               goto err;
+                       if (!BN_add(Ij, Ij, Bpl1))
+                               goto err;
+                       if (!BN_bn2bin(Ij, B))
+                               goto err;
                        Ijlen = BN_num_bytes (Ij);
                        /* If more than 2^(v*8) - 1 cut off MSB */
                        if (Ijlen > v) {
-                               BN_bn2bin (Ij, B);
+                               if (!BN_bn2bin (Ij, B))
+                                       goto err;
                                memcpy (I + j, B + 1, v);
 #ifndef PKCS12_BROKEN_KEYGEN
                        /* If less than v bytes pad with zeroes */
                        } else if (Ijlen < v) {
                                memset(I + j, 0, v - Ijlen);
-                               BN_bn2bin(Ij, I + j + v - Ijlen); 
+                               if (!BN_bn2bin(Ij, I + j + v - Ijlen))
+                                       goto err;
 #endif
-                       } else BN_bn2bin (Ij, I + j);
+                       } else if (!BN_bn2bin (Ij, I + j))
+                               goto err;
                }
        }
 
index c8d06d6..0fd31e7 100644 (file)
@@ -56,7 +56,7 @@
 #include <openssl/pkcs7.h>
 #include <openssl/bio.h>
 
-#ifndef OPENSSL_SYSNAME_NETWARE
+#if !defined(OPENSSL_SYSNAME_NETWARE) && !defined(OPENSSL_SYSNAME_VXWORKS)
 #include <memory.h>
 #endif
 #include <stdio.h>
index fcdd3f2..1e3bcb9 100644 (file)
 
 #include "e_os.h"
 
+#include <openssl/crypto.h>
 #include <openssl/rand.h>
 #include "rand_lcl.h"
 
-#include <openssl/crypto.h>
 #include <openssl/err.h>
 
 #ifdef BN_DEBUG
index daf1dab..476a0cd 100644 (file)
@@ -210,8 +210,11 @@ static size_t drbg_get_entropy(DRBG_CTX *ctx, unsigned char **pout,
 
 static void drbg_free_entropy(DRBG_CTX *ctx, unsigned char *out, size_t olen)
        {
-       OPENSSL_cleanse(out, olen);
-       OPENSSL_free(out);
+       if (out)
+               {
+               OPENSSL_cleanse(out, olen);
+               OPENSSL_free(out);
+               }
        }
 
 /* Set "additional input" when generating random data. This uses the
index 030e07f..7f14280 100644 (file)
@@ -57,7 +57,9 @@
  */
 
 /* We need to define this to get macros like S_IFBLK and S_IFCHR */
+#if !defined(OPENSSL_SYS_VXWORKS)
 #define _XOPEN_SOURCE 500
+#endif
 
 #include <errno.h>
 #include <stdio.h>
index 7f68409..272fa91 100644 (file)
@@ -51,7 +51,8 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; my $dir=$1; my $xlate;
 ( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or
 die "can't locate x86_64-xlate.pl";
 
-open STDOUT,"| $^X $xlate $flavour $output";
+open OUT,"| \"$^X\" $xlate $flavour $output";
+*STDOUT=*OUT;
 
 my ($dat,$in0,$out,$ctx,$inp,$len, $func,$nargs);
 
index d6eac20..75750db 100755 (executable)
@@ -112,7 +112,8 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
 ( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or
 die "can't locate x86_64-xlate.pl";
 
-open STDOUT,"| $^X $xlate $flavour $output";
+open OUT,"| \"$^X\" $xlate $flavour $output";
+*STDOUT=*OUT;
 
 $dat="%rdi";       # arg1
 $len="%rsi";       # arg2
index 63f0d98..d8e72da 100644 (file)
@@ -105,21 +105,21 @@ void ripemd160_block_data_order (RIPEMD160_CTX *ctx, const void *p, size_t num)
 
        A=ctx->A; B=ctx->B; C=ctx->C; D=ctx->D; E=ctx->E;
 
-       HOST_c2l(data,l); X( 0)=l;      HOST_c2l(data,l); X( 1)=l;
-       RIP1(A,B,C,D,E,WL00,SL00);      HOST_c2l(data,l); X( 2)=l;
-       RIP1(E,A,B,C,D,WL01,SL01);      HOST_c2l(data,l); X( 3)=l;
-       RIP1(D,E,A,B,C,WL02,SL02);      HOST_c2l(data,l); X( 4)=l;
-       RIP1(C,D,E,A,B,WL03,SL03);      HOST_c2l(data,l); X( 5)=l;
-       RIP1(B,C,D,E,A,WL04,SL04);      HOST_c2l(data,l); X( 6)=l;
-       RIP1(A,B,C,D,E,WL05,SL05);      HOST_c2l(data,l); X( 7)=l;
-       RIP1(E,A,B,C,D,WL06,SL06);      HOST_c2l(data,l); X( 8)=l;
-       RIP1(D,E,A,B,C,WL07,SL07);      HOST_c2l(data,l); X( 9)=l;
-       RIP1(C,D,E,A,B,WL08,SL08);      HOST_c2l(data,l); X(10)=l;
-       RIP1(B,C,D,E,A,WL09,SL09);      HOST_c2l(data,l); X(11)=l;
-       RIP1(A,B,C,D,E,WL10,SL10);      HOST_c2l(data,l); X(12)=l;
-       RIP1(E,A,B,C,D,WL11,SL11);      HOST_c2l(data,l); X(13)=l;
-       RIP1(D,E,A,B,C,WL12,SL12);      HOST_c2l(data,l); X(14)=l;
-       RIP1(C,D,E,A,B,WL13,SL13);      HOST_c2l(data,l); X(15)=l;
+       (void)HOST_c2l(data,l); X( 0)=l;(void)HOST_c2l(data,l); X( 1)=l;
+       RIP1(A,B,C,D,E,WL00,SL00);      (void)HOST_c2l(data,l); X( 2)=l;
+       RIP1(E,A,B,C,D,WL01,SL01);      (void)HOST_c2l(data,l); X( 3)=l;
+       RIP1(D,E,A,B,C,WL02,SL02);      (void)HOST_c2l(data,l); X( 4)=l;
+       RIP1(C,D,E,A,B,WL03,SL03);      (void)HOST_c2l(data,l); X( 5)=l;
+       RIP1(B,C,D,E,A,WL04,SL04);      (void)HOST_c2l(data,l); X( 6)=l;
+       RIP1(A,B,C,D,E,WL05,SL05);      (void)HOST_c2l(data,l); X( 7)=l;
+       RIP1(E,A,B,C,D,WL06,SL06);      (void)HOST_c2l(data,l); X( 8)=l;
+       RIP1(D,E,A,B,C,WL07,SL07);      (void)HOST_c2l(data,l); X( 9)=l;
+       RIP1(C,D,E,A,B,WL08,SL08);      (void)HOST_c2l(data,l); X(10)=l;
+       RIP1(B,C,D,E,A,WL09,SL09);      (void)HOST_c2l(data,l); X(11)=l;
+       RIP1(A,B,C,D,E,WL10,SL10);      (void)HOST_c2l(data,l); X(12)=l;
+       RIP1(E,A,B,C,D,WL11,SL11);      (void)HOST_c2l(data,l); X(13)=l;
+       RIP1(D,E,A,B,C,WL12,SL12);      (void)HOST_c2l(data,l); X(14)=l;
+       RIP1(C,D,E,A,B,WL13,SL13);      (void)HOST_c2l(data,l); X(15)=l;
        RIP1(B,C,D,E,A,WL14,SL14);
        RIP1(A,B,C,D,E,WL15,SL15);
 
index f14b346..2bd8957 100644 (file)
@@ -88,11 +88,11 @@ void ripemd160_block_data_order (RIPEMD160_CTX *c, const void *p,size_t num);
 #define HASH_FINAL              RIPEMD160_Final
 #define        HASH_MAKE_STRING(c,s)   do {    \
        unsigned long ll;               \
-       ll=(c)->A; HOST_l2c(ll,(s));    \
-       ll=(c)->B; HOST_l2c(ll,(s));    \
-       ll=(c)->C; HOST_l2c(ll,(s));    \
-       ll=(c)->D; HOST_l2c(ll,(s));    \
-       ll=(c)->E; HOST_l2c(ll,(s));    \
+       ll=(c)->A; (void)HOST_l2c(ll,(s));      \
+       ll=(c)->B; (void)HOST_l2c(ll,(s));      \
+       ll=(c)->C; (void)HOST_l2c(ll,(s));      \
+       ll=(c)->D; (void)HOST_l2c(ll,(s));      \
+       ll=(c)->E; (void)HOST_l2c(ll,(s));      \
        } while (0)
 #define HASH_BLOCK_DATA_ORDER   ripemd160_block_data_order
 
index 4814a2f..5f269e5 100644 (file)
@@ -280,7 +280,7 @@ struct rsa_st
 
 RSA *  RSA_new(void);
 RSA *  RSA_new_method(ENGINE *engine);
-int    RSA_size(const RSA *);
+int    RSA_size(const RSA *rsa);
 
 /* Deprecated version */
 #ifndef OPENSSL_NO_DEPRECATED
index 2e1ddd4..88ee2cb 100644 (file)
@@ -847,12 +847,12 @@ static int RSA_eay_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx)
        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
+        * adding 'p' if r0 is negative above to leave the result still
         * negative. This can break the private key operations: the following
         * second correction should *always* correct this rare occurrence.
         * This will *never* happen with OpenSSL generated keys because
-         * they ensure p > q [steve]
-         */
+        * they ensure p > q [steve]
+        */
        if (BN_is_negative(r0))
                if (!BN_add(r0,r0,rsa->p)) goto err;
        if (!BN_mul(r1,r0,rsa->q,ctx)) goto err;
index 553d212..af4d24a 100644 (file)
@@ -149,7 +149,7 @@ int RSA_padding_check_PKCS1_OAEP(unsigned char *to, int tlen,
        if (!EVP_Digest((void *)param, plen, phash, NULL, EVP_sha1(), NULL))
                return -1;
 
-       if (memcmp(db, phash, SHA_DIGEST_LENGTH) != 0 || bad)
+       if (CRYPTO_memcmp(db, phash, SHA_DIGEST_LENGTH) != 0 || bad)
                goto decoding_err;
        else
                {
index f27c1e3..cfdc45c 100755 (executable)
@@ -82,7 +82,8 @@ $avx=1 if (!$avx && $win64 && ($flavour =~ /masm/ || $ENV{ASM} =~ /ml64/) &&
           `ml64 2>&1` =~ /Version ([0-9]+)\./ &&
           $1>=10);
 
-open STDOUT,"| $^X $xlate $flavour $output";
+open OUT,"| \"$^X\" $xlate $flavour $output";
+*STDOUT=*OUT;
 
 $ctx="%rdi";   # 1st arg
 $inp="%rsi";   # 2nd arg
index 5b9f333..7eab6a5 100644 (file)
@@ -142,9 +142,9 @@ sub BODY_00_15_x86 {
        &mov    ("edx",$Ehi);
        &mov    ("esi","ecx");
 
-       &shr    ("ecx",9)       # lo>>9
+       &shr    ("ecx",9);      # lo>>9
        &mov    ("edi","edx");
-       &shr    ("edx",9)       # hi>>9
+       &shr    ("edx",9);      # hi>>9
        &mov    ("ebx","ecx");
        &shl    ("esi",14);     # lo<<14
        &mov    ("eax","edx");
@@ -207,9 +207,9 @@ sub BODY_00_15_x86 {
        &mov    ($Dhi,"ebx");
        &mov    ("esi","ecx");
 
-       &shr    ("ecx",2)       # lo>>2
+       &shr    ("ecx",2);      # lo>>2
        &mov    ("edi","edx");
-       &shr    ("edx",2)       # hi>>2
+       &shr    ("edx",2);      # hi>>2
        &mov    ("ebx","ecx");
        &shl    ("esi",4);      # lo<<4
        &mov    ("eax","edx");
@@ -452,9 +452,9 @@ if ($sse2) {
        &mov    ("edx",&DWP(8*(9+15+16-1)+4,"esp"));
        &mov    ("esi","ecx");
 
-       &shr    ("ecx",1)       # lo>>1
+       &shr    ("ecx",1);      # lo>>1
        &mov    ("edi","edx");
-       &shr    ("edx",1)       # hi>>1
+       &shr    ("edx",1);      # hi>>1
        &mov    ("eax","ecx");
        &shl    ("esi",24);     # lo<<24
        &mov    ("ebx","edx");
@@ -488,9 +488,9 @@ if ($sse2) {
        &mov    ("edx",&DWP(8*(9+15+16-14)+4,"esp"));
        &mov    ("esi","ecx");
 
-       &shr    ("ecx",6)       # lo>>6
+       &shr    ("ecx",6);      # lo>>6
        &mov    ("edi","edx");
-       &shr    ("edx",6)       # hi>>6
+       &shr    ("edx",6);      # hi>>6
        &mov    ("eax","ecx");
        &shl    ("esi",3);      # lo<<3
        &mov    ("ebx","edx");
index f611a2d..8d51678 100755 (executable)
@@ -51,7 +51,8 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
 ( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or
 die "can't locate x86_64-xlate.pl";
 
-open STDOUT,"| $^X $xlate $flavour $output";
+open OUT,"| \"$^X\" $xlate $flavour $output";
+*STDOUT=*OUT;
 
 if ($output =~ /512/) {
        $func="sha512_block_data_order";
index 7c65b60..c56ec94 100644 (file)
@@ -58,8 +58,8 @@
 
 #include <stdio.h>
 #include <string.h>
-#include <openssl/sha.h>
 #include <openssl/crypto.h>
+#include <openssl/sha.h>
 
 #ifndef OPENSSL_NO_SHA1
 unsigned char *SHA1(const unsigned char *d, size_t n, unsigned char *md)
index 81219af..a986902 100644 (file)
@@ -56,8 +56,8 @@
  * [including the GNU Public Licence.]
  */
 
-#include <openssl/opensslconf.h>
 #include <openssl/crypto.h>
+#include <openssl/opensslconf.h>
 #if !defined(OPENSSL_NO_SHA1) && !defined(OPENSSL_NO_SHA)
 
 #undef  SHA_0
index f88d3d6..4eae074 100644 (file)
@@ -88,17 +88,17 @@ int SHA224_Final (unsigned char *md, SHA256_CTX *c)
        switch ((c)->md_len)            \
        {   case SHA224_DIGEST_LENGTH:  \
                for (nn=0;nn<SHA224_DIGEST_LENGTH/4;nn++)       \
-               {   ll=(c)->h[nn]; HOST_l2c(ll,(s));   }        \
+               {   ll=(c)->h[nn]; (void)HOST_l2c(ll,(s));   }  \
                break;                  \
            case SHA256_DIGEST_LENGTH:  \
                for (nn=0;nn<SHA256_DIGEST_LENGTH/4;nn++)       \
-               {   ll=(c)->h[nn]; HOST_l2c(ll,(s));   }        \
+               {   ll=(c)->h[nn]; (void)HOST_l2c(ll,(s));   }  \
                break;                  \
            default:                    \
                if ((c)->md_len > SHA256_DIGEST_LENGTH) \
                    return 0;                           \
                for (nn=0;nn<(c)->md_len/4;nn++)                \
-               {   ll=(c)->h[nn]; HOST_l2c(ll,(s));   }        \
+               {   ll=(c)->h[nn]; (void)HOST_l2c(ll,(s));   }  \
                break;                  \
        }                               \
        } while (0)
index c946ad8..fb63b17 100644 (file)
@@ -56,8 +56,8 @@
  * [including the GNU Public Licence.]
  */
 
-#include <openssl/opensslconf.h>
 #include <openssl/crypto.h>
+#include <openssl/opensslconf.h>
 #if !defined(OPENSSL_NO_SHA0) && !defined(OPENSSL_NO_SHA)
 
 #undef  SHA_1
index 7a0c3ca..d673255 100644 (file)
 #define HASH_CBLOCK             SHA_CBLOCK
 #define HASH_MAKE_STRING(c,s)   do {   \
        unsigned long ll;               \
-       ll=(c)->h0; HOST_l2c(ll,(s));   \
-       ll=(c)->h1; HOST_l2c(ll,(s));   \
-       ll=(c)->h2; HOST_l2c(ll,(s));   \
-       ll=(c)->h3; HOST_l2c(ll,(s));   \
-       ll=(c)->h4; HOST_l2c(ll,(s));   \
+       ll=(c)->h0; (void)HOST_l2c(ll,(s));     \
+       ll=(c)->h1; (void)HOST_l2c(ll,(s));     \
+       ll=(c)->h2; (void)HOST_l2c(ll,(s));     \
+       ll=(c)->h3; (void)HOST_l2c(ll,(s));     \
+       ll=(c)->h4; (void)HOST_l2c(ll,(s));     \
        } while (0)
 
 #if defined(SHA_0)
@@ -256,21 +256,21 @@ static void HASH_BLOCK_DATA_ORDER (SHA_CTX *c, const void *p, size_t num)
                }
        else
                {
-               HOST_c2l(data,l); X( 0)=l;              HOST_c2l(data,l); X( 1)=l;
-               BODY_00_15( 0,A,B,C,D,E,T,X( 0));       HOST_c2l(data,l); X( 2)=l;
-               BODY_00_15( 1,T,A,B,C,D,E,X( 1));       HOST_c2l(data,l); X( 3)=l;
-               BODY_00_15( 2,E,T,A,B,C,D,X( 2));       HOST_c2l(data,l); X( 4)=l;
-               BODY_00_15( 3,D,E,T,A,B,C,X( 3));       HOST_c2l(data,l); X( 5)=l;
-               BODY_00_15( 4,C,D,E,T,A,B,X( 4));       HOST_c2l(data,l); X( 6)=l;
-               BODY_00_15( 5,B,C,D,E,T,A,X( 5));       HOST_c2l(data,l); X( 7)=l;
-               BODY_00_15( 6,A,B,C,D,E,T,X( 6));       HOST_c2l(data,l); X( 8)=l;
-               BODY_00_15( 7,T,A,B,C,D,E,X( 7));       HOST_c2l(data,l); X( 9)=l;
-               BODY_00_15( 8,E,T,A,B,C,D,X( 8));       HOST_c2l(data,l); X(10)=l;
-               BODY_00_15( 9,D,E,T,A,B,C,X( 9));       HOST_c2l(data,l); X(11)=l;
-               BODY_00_15(10,C,D,E,T,A,B,X(10));       HOST_c2l(data,l); X(12)=l;
-               BODY_00_15(11,B,C,D,E,T,A,X(11));       HOST_c2l(data,l); X(13)=l;
-               BODY_00_15(12,A,B,C,D,E,T,X(12));       HOST_c2l(data,l); X(14)=l;
-               BODY_00_15(13,T,A,B,C,D,E,X(13));       HOST_c2l(data,l); X(15)=l;
+               (void)HOST_c2l(data,l); X( 0)=l;        (void)HOST_c2l(data,l); X( 1)=l;
+               BODY_00_15( 0,A,B,C,D,E,T,X( 0));       (void)HOST_c2l(data,l); X( 2)=l;
+               BODY_00_15( 1,T,A,B,C,D,E,X( 1));       (void)HOST_c2l(data,l); X( 3)=l;
+               BODY_00_15( 2,E,T,A,B,C,D,X( 2));       (void)HOST_c2l(data,l); X( 4)=l;
+               BODY_00_15( 3,D,E,T,A,B,C,X( 3));       (void)HOST_c2l(data,l); X( 5)=l;
+               BODY_00_15( 4,C,D,E,T,A,B,X( 4));       (void)HOST_c2l(data,l); X( 6)=l;
+               BODY_00_15( 5,B,C,D,E,T,A,X( 5));       (void)HOST_c2l(data,l); X( 7)=l;
+               BODY_00_15( 6,A,B,C,D,E,T,X( 6));       (void)HOST_c2l(data,l); X( 8)=l;
+               BODY_00_15( 7,T,A,B,C,D,E,X( 7));       (void)HOST_c2l(data,l); X( 9)=l;
+               BODY_00_15( 8,E,T,A,B,C,D,X( 8));       (void)HOST_c2l(data,l); X(10)=l;
+               BODY_00_15( 9,D,E,T,A,B,C,X( 9));       (void)HOST_c2l(data,l); X(11)=l;
+               BODY_00_15(10,C,D,E,T,A,B,X(10));       (void)HOST_c2l(data,l); X(12)=l;
+               BODY_00_15(11,B,C,D,E,T,A,X(11));       (void)HOST_c2l(data,l); X(13)=l;
+               BODY_00_15(12,A,B,C,D,E,T,X(12));       (void)HOST_c2l(data,l); X(14)=l;
+               BODY_00_15(13,T,A,B,C,D,E,X(13));       (void)HOST_c2l(data,l); X(15)=l;
                BODY_00_15(14,E,T,A,B,C,D,X(14));
                BODY_00_15(15,D,E,T,A,B,C,X(15));
                }
index c8be907..4a3d13e 100644 (file)
@@ -390,7 +390,7 @@ int SRP_VBASE_init(SRP_VBASE *vb, char *verifier_file)
                }
        for (i = 0; i < sk_OPENSSL_PSTRING_num(tmpdb->data); i++)
                {
-               pp = (char **)sk_OPENSSL_PSTRING_value(tmpdb->data,i);
+               pp = sk_OPENSSL_PSTRING_value(tmpdb->data,i);
                if (pp[DB_srptype][0] == DB_SRP_INDEX)
                        {
                        /*we add this couple in the internal Stack */
@@ -581,7 +581,8 @@ char *SRP_create_verifier(const char *user, const char *pass, char **salt,
        if (*salt == NULL)
                {
                char *tmp_salt;
-               if ((tmp_salt = (char *)OPENSSL_malloc(SRP_RANDOM_SALT_LEN * 2)) == NULL)
+
+               if ((tmp_salt = OPENSSL_malloc(SRP_RANDOM_SALT_LEN * 2)) == NULL)
                        {
                        OPENSSL_free(vf);
                        goto err;
index 403f592..07a412f 100644 (file)
 #undef SSL_CTX_set_srp_username_callback
 #define SSL_CTX_set_srp_username_callback      SSL_CTX_set_srp_un_cb
 #undef ssl_add_clienthello_use_srtp_ext
-#define ssl_add_clienthello_use_srtp_ext ssl_add_clihello_use_srtp_ext
+#define ssl_add_clienthello_use_srtp_ext       ssl_add_clihello_use_srtp_ext
 #undef ssl_add_serverhello_use_srtp_ext
-#define ssl_add_serverhello_use_srtp_ext ssl_add_serhello_use_srtp_ext
+#define ssl_add_serverhello_use_srtp_ext       ssl_add_serhello_use_srtp_ext
 #undef ssl_parse_clienthello_use_srtp_ext
-#define ssl_parse_clienthello_use_srtp_ext ssl_parse_clihello_use_srtp_ext
+#define ssl_parse_clienthello_use_srtp_ext     ssl_parse_clihello_use_srtp_ext
 #undef ssl_parse_serverhello_use_srtp_ext
-#define ssl_parse_serverhello_use_srtp_ext ssl_parse_serhello_use_srtp_ext
+#define ssl_parse_serverhello_use_srtp_ext     ssl_parse_serhello_use_srtp_ext
 #undef SSL_CTX_set_next_protos_advertised_cb
-#define SSL_CTX_set_next_protos_advertised_cb SSL_CTX_set_next_protos_adv_cb
+#define SSL_CTX_set_next_protos_advertised_cb  SSL_CTX_set_next_protos_adv_cb
 #undef SSL_CTX_set_next_proto_select_cb
-#define SSL_CTX_set_next_proto_select_cb SSL_CTX_set_next_proto_sel_cb
+#define SSL_CTX_set_next_proto_select_cb       SSL_CTX_set_next_proto_sel_cb
 
 /* Hack some long ENGINE names */
 #undef ENGINE_get_default_BN_mod_exp_crt
 #define ec_GFp_simple_point_set_to_infinity     ec_GFp_simple_pt_set_to_inf
 #undef ec_GFp_simple_points_make_affine
 #define ec_GFp_simple_points_make_affine       ec_GFp_simple_pts_make_affine
-#undef ec_GFp_simple_group_get_curve_GFp
-#define ec_GFp_simple_group_get_curve_GFp       ec_GFp_simple_grp_get_curve_GFp
 #undef ec_GFp_simple_set_Jprojective_coordinates_GFp
 #define ec_GFp_simple_set_Jprojective_coordinates_GFp \
                                                 ec_GFp_smp_set_Jproj_coords_GFp
index 5832a73..a38c758 100644 (file)
  * sigaction and fileno included. -pedantic would be more appropriate for
  * the intended purposes, but we can't prevent users from adding -ansi.
  */
+#if defined(OPENSSL_SYSNAME_VXWORKS)
+#include <sys/types.h>
+#endif
+
 #if !defined(_POSIX_C_SOURCE) && defined(OPENSSL_SYS_VMS)
+#ifndef _POSIX_C_SOURCE
 #define _POSIX_C_SOURCE 2
 #endif
+#endif
 #include <signal.h>
 #include <stdio.h>
 #include <string.h>
index 32cf163..cb2381c 100644 (file)
@@ -119,7 +119,7 @@ $tbl="ebp";
        &mov    ("eax",&DWP(0,"esp"));
        &mov    ("ebx",&DWP(4,"esp"));
 for($i=0;$i<8;$i++) {
-    my $func = ($i==0)? movq : pxor;
+    my $func = ($i==0)? \&movq : \&pxor;
        &movb   (&LB("ecx"),&LB("eax"));
        &movb   (&LB("edx"),&HB("eax"));
        &scale  ("esi","ecx");
index 87c0843..24b2ff6 100644 (file)
@@ -41,7 +41,8 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; my $dir=$1; my $xlate;
 ( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or
 die "can't locate x86_64-xlate.pl";
 
-open STDOUT,"| $^X $xlate $flavour $output";
+open OUT,"| \"$^X\" $xlate $flavour $output";
+*STDOUT=*OUT;
 
 sub L() { $code.=".byte        ".join(',',@_)."\n"; }
 sub LL(){ $code.=".byte        ".join(',',@_).",".join(',',@_)."\n"; }
index 7c2aaee..352aa37 100644 (file)
@@ -86,10 +86,9 @@ unsigned long X509_issuer_and_serial_hash(X509 *a)
 
        EVP_MD_CTX_init(&ctx);
        f=X509_NAME_oneline(a->cert_info->issuer,NULL,0);
-       ret=strlen(f);
        if (!EVP_DigestInit_ex(&ctx, EVP_md5(), NULL))
                goto err;
-       if (!EVP_DigestUpdate(&ctx,(unsigned char *)f,ret))
+       if (!EVP_DigestUpdate(&ctx,(unsigned char *)f,strlen(f)))
                goto err;
        OPENSSL_free(f);
        if(!EVP_DigestUpdate(&ctx,(unsigned char *)a->cert_info->serialNumber->data,
@@ -249,14 +248,14 @@ unsigned long X509_NAME_hash_old(X509_NAME *x)
        i2d_X509_NAME(x,NULL);
        EVP_MD_CTX_init(&md_ctx);
        EVP_MD_CTX_set_flags(&md_ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
-       EVP_DigestInit_ex(&md_ctx, EVP_md5(), NULL);
-       EVP_DigestUpdate(&md_ctx, x->bytes->data, x->bytes->length);
-       EVP_DigestFinal_ex(&md_ctx,md,NULL);
+       if (EVP_DigestInit_ex(&md_ctx, EVP_md5(), NULL)
+           && EVP_DigestUpdate(&md_ctx, x->bytes->data, x->bytes->length)
+           && EVP_DigestFinal_ex(&md_ctx,md,NULL))
+               ret=(((unsigned long)md[0]     )|((unsigned long)md[1]<<8L)|
+                    ((unsigned long)md[2]<<16L)|((unsigned long)md[3]<<24L)
+                    )&0xffffffffL;
        EVP_MD_CTX_cleanup(&md_ctx);
 
-       ret=(   ((unsigned long)md[0]     )|((unsigned long)md[1]<<8L)|
-               ((unsigned long)md[2]<<16L)|((unsigned long)md[3]<<24L)
-               )&0xffffffffL;
        return(ret);
        }
 #endif
index b0779db..12d71f5 100644 (file)
@@ -872,7 +872,7 @@ static int crl_extension_match(X509_CRL *a, X509_CRL *b, int nid)
        {
        ASN1_OCTET_STRING *exta, *extb;
        int i;
-       i = X509_CRL_get_ext_by_NID(a, nid, 0);
+       i = X509_CRL_get_ext_by_NID(a, nid, -1);
        if (i >= 0)
                {
                /* Can't have multiple occurrences */
@@ -883,7 +883,7 @@ static int crl_extension_match(X509_CRL *a, X509_CRL *b, int nid)
        else
                exta = NULL;
 
-       i = X509_CRL_get_ext_by_NID(b, nid, 0);
+       i = X509_CRL_get_ext_by_NID(b, nid, -1);
 
        if (i >= 0)
                {
index 181bd34..ad68865 100644 (file)
@@ -474,11 +474,11 @@ static void x509v3_cache_extensions(X509 *x)
        for (i = 0; i < X509_get_ext_count(x); i++)
                {
                ex = X509_get_ext(x, i);
-               if (!X509_EXTENSION_get_critical(ex))
-                       continue;
                if (OBJ_obj2nid(X509_EXTENSION_get_object(ex))
                                        == NID_freshest_crl)
                        x->ex_flags |= EXFLAG_FRESHEST;
+               if (!X509_EXTENSION_get_critical(ex))
+                       continue;
                if (!X509_supported_extension(ex))
                        {
                        x->ex_flags |= EXFLAG_CRITICAL;
index 7b7b93b..6ebfd01 100644 (file)
@@ -11,7 +11,8 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
 ( $xlate="${dir}perlasm/x86_64-xlate.pl" and -f $xlate) or
 die "can't locate x86_64-xlate.pl";
 
-open STDOUT,"| $^X $xlate $flavour $output";
+open OUT,"| \"$^X\" $xlate $flavour $output";
+*STDOUT=*OUT;
 
 ($arg1,$arg2,$arg3,$arg4)=$win64?("%rcx","%rdx","%r8", "%r9") :        # Win64 order
                                 ("%rdi","%rsi","%rdx","%rcx"); # Unix order
index 39fd8f2..c18b0e2 100644 (file)
@@ -165,7 +165,7 @@ for (@ARGV) { $sse2=1 if (/-DOPENSSL_IA32_SSE2/); }
        &jnz    (&label("nohalt"));     # not enough privileges
 
        &pushf  ();
-       &pop    ("eax")
+       &pop    ("eax");
        &bt     ("eax",9);
        &jnc    (&label("nohalt"));     # interrupts are disabled
 
@@ -280,7 +280,7 @@ for (@ARGV) { $sse2=1 if (/-DOPENSSL_IA32_SSE2/); }
 #      arguments is 1 or 2!
 &function_begin_B("OPENSSL_indirect_call");
        {
-       my $i,$max=7;           # $max has to be chosen as 4*n-1
+       my ($max,$i)=(7,);      # $max has to be chosen as 4*n-1
                                # in order to preserve eventual
                                # stack alignment
        &push   ("ebp");
index ed69952..d326101 100644 (file)
@@ -39,13 +39,13 @@ prints a usage message.
 
 =item B<-newcert>
 
-creates a new self signed certificate. The private key and certificate are
-written to the file "newreq.pem".
+creates a new self signed certificate. The private key is written to the file
+"newkey.pem" and the request written to the file "newreq.pem".
 
 =item B<-newreq>
 
-creates a new certificate request. The private key and request are
-written to the file "newreq.pem".
+creates a new certificate request. The private key is written to the file
+"newkey.pem" and the request written to the file "newreq.pem".
 
 =item B<-newreq-nodes>
 
index 336098f..da68300 100644 (file)
@@ -54,35 +54,37 @@ in PEM format concatenated together.
 =item B<-untrusted file>
 
 A file of untrusted certificates. The file should contain multiple certificates
+in PEM format concatenated together.
 
 =item B<-purpose purpose>
 
-the intended use for the certificate. Without this option no chain verification
-will be done. Currently accepted uses are B<sslclient>, B<sslserver>,
-B<nssslserver>, B<smimesign>, B<smimeencrypt>. See the B<VERIFY OPERATION>
-section for more information.
+The intended use for the certificate. If this option is not specified,
+B<verify> will not consider certificate purpose during chain verification.
+Currently accepted uses are B<sslclient>, B<sslserver>, B<nssslserver>,
+B<smimesign>, B<smimeencrypt>. See the B<VERIFY OPERATION> section for more
+information.
 
 =item B<-help>
 
-prints out a usage message.
+Print out a usage message.
 
 =item B<-verbose>
 
-print extra information about the operations being performed.
+Print extra information about the operations being performed.
 
 =item B<-issuer_checks>
 
-print out diagnostics relating to searches for the issuer certificate
-of the current certificate. This shows why each candidate issuer
-certificate was rejected. However the presence of rejection messages
-does not itself imply that anything is wrong: during the normal
-verify process several rejections may take place.
+Print out diagnostics relating to searches for the issuer certificate of the
+current certificate. This shows why each candidate issuer certificate was
+rejected. The presence of rejection messages does not itself imply that
+anything is wrong; during the normal verification process, several
+rejections may take place.
 
 =item B<-policy arg>
 
-Enable policy processing and add B<arg> to the user-initial-policy-set
-(see RFC3280 et al). The policy B<arg> can be an object name an OID in numeric
-form. This argument can appear more than once.
+Enable policy processing and add B<arg> to the user-initial-policy-set (see
+RFC5280). The policy B<arg> can be an object name an OID in numeric form.
+This argument can appear more than once.
 
 =item B<-policy_check>
 
@@ -90,41 +92,40 @@ Enables certificate policy processing.
 
 =item B<-explicit_policy>
 
-Set policy variable require-explicit-policy (see RFC3280 et al).
+Set policy variable require-explicit-policy (see RFC5280).
 
 =item B<-inhibit_any>
 
-Set policy variable inhibit-any-policy (see RFC3280 et al).
+Set policy variable inhibit-any-policy (see RFC5280).
 
 =item B<-inhibit_map>
 
-Set policy variable inhibit-policy-mapping (see RFC3280 et al).
+Set policy variable inhibit-policy-mapping (see RFC5280).
 
 =item B<-policy_print>
 
-Print out diagnostics, related to policy checking
+Print out diagnostics related to policy processing.
 
 =item B<-crl_check>
 
-Checks end entity certificate validity by attempting to lookup a valid CRL.
+Checks end entity certificate validity by attempting to look up a valid CRL.
 If a valid CRL cannot be found an error occurs. 
 
 =item B<-crl_check_all>
 
 Checks the validity of B<all> certificates in the chain by attempting
-to lookup valid CRLs.
+to look up valid CRLs.
 
 =item B<-ignore_critical>
 
 Normally if an unhandled critical extension is present which is not
-supported by OpenSSL the certificate is rejected (as required by
-RFC3280 et al). If this option is set critical extensions are
-ignored.
+supported by OpenSSL the certificate is rejected (as required by RFC5280).
+If this option is set critical extensions are ignored.
 
 =item B<-x509_strict>
 
-Disable workarounds for broken certificates which have to be disabled
-for strict X.509 compliance.
+For strict X.509 compliance, disable non-compliant workarounds for broken
+certificates.
 
 =item B<-extended_crl>
 
@@ -142,16 +143,15 @@ because it doesn't add any security.
 
 =item B<->
 
-marks the last option. All arguments following this are assumed to be
+Indicates the last option. All arguments following this are assumed to be
 certificate files. This is useful if the first certificate filename begins
 with a B<->.
 
 =item B<certificates>
 
-one or more certificates to verify. If no certificate filenames are included
-then an attempt is made to read a certificate from standard input. They should
-all be in PEM format.
-
+One or more certificates to verify. If no certificates are given, B<verify>
+will attempt to read a certificate from standard input. Certificates must be
+in PEM format.
 
 =back
 
index 3002b08..d2d9eb8 100644 (file)
@@ -29,6 +29,7 @@ B<openssl> B<x509>
 [B<-purpose>]
 [B<-dates>]
 [B<-modulus>]
+[B<-pubkey>]
 [B<-fingerprint>]
 [B<-alias>]
 [B<-noout>]
@@ -135,6 +136,10 @@ section for more information.
 
 this option prevents output of the encoded version of the request.
 
+=item B<-pubkey>
+
+outputs the the certificate's SubjectPublicKeyInfo block in PEM format.
+
 =item B<-modulus>
 
 this option prints out the value of the modulus of the public key
index f2f4559..13b91f1 100644 (file)
@@ -117,7 +117,7 @@ L<EVP_PKEY_encrypt(3)|EVP_PKEY_encrypt(3)>,
 L<EVP_PKEY_decrypt(3)|EVP_PKEY_decrypt(3)>,
 L<EVP_PKEY_sign(3)|EVP_PKEY_sign(3)>,
 L<EVP_PKEY_verify(3)|EVP_PKEY_verify(3)>,
-L<EVP_PKEY_verifyrecover(3)|EVP_PKEY_verifyrecover(3)>,
+L<EVP_PKEY_verify_recover(3)|EVP_PKEY_verify_recover(3)>,
 L<EVP_PKEY_derive(3)|EVP_PKEY_derive(3)> 
 L<EVP_PKEY_keygen(3)|EVP_PKEY_keygen(3)> 
 
index 42b2a8c..8479832 100644 (file)
@@ -83,7 +83,7 @@ L<EVP_PKEY_CTX_new(3)|EVP_PKEY_CTX_new(3)>,
 L<EVP_PKEY_encrypt(3)|EVP_PKEY_encrypt(3)>,
 L<EVP_PKEY_sign(3)|EVP_PKEY_sign(3)>,
 L<EVP_PKEY_verify(3)|EVP_PKEY_verify(3)>,
-L<EVP_PKEY_verifyrecover(3)|EVP_PKEY_verifyrecover(3)>,
+L<EVP_PKEY_verify_recover(3)|EVP_PKEY_verify_recover(3)>,
 L<EVP_PKEY_derive(3)|EVP_PKEY_derive(3)> 
 
 =head1 HISTORY
index d9d6d76..27464be 100644 (file)
@@ -84,7 +84,7 @@ L<EVP_PKEY_encrypt(3)|EVP_PKEY_encrypt(3)>,
 L<EVP_PKEY_decrypt(3)|EVP_PKEY_decrypt(3)>,
 L<EVP_PKEY_sign(3)|EVP_PKEY_sign(3)>,
 L<EVP_PKEY_verify(3)|EVP_PKEY_verify(3)>,
-L<EVP_PKEY_verifyrecover(3)|EVP_PKEY_verifyrecover(3)>,
+L<EVP_PKEY_verify_recover(3)|EVP_PKEY_verify_recover(3)>,
 
 =head1 HISTORY
 
index 91c9c5d..e495a81 100644 (file)
@@ -83,7 +83,7 @@ L<EVP_PKEY_CTX_new(3)|EVP_PKEY_CTX_new(3)>,
 L<EVP_PKEY_decrypt(3)|EVP_PKEY_decrypt(3)>,
 L<EVP_PKEY_sign(3)|EVP_PKEY_sign(3)>,
 L<EVP_PKEY_verify(3)|EVP_PKEY_verify(3)>,
-L<EVP_PKEY_verifyrecover(3)|EVP_PKEY_verifyrecover(3)>,
+L<EVP_PKEY_verify_recover(3)|EVP_PKEY_verify_recover(3)>,
 L<EVP_PKEY_derive(3)|EVP_PKEY_derive(3)> 
 
 =head1 HISTORY
index 1a9c795..8ff597d 100644 (file)
@@ -32,7 +32,7 @@ public key algorithm.
 L<EVP_PKEY_CTX_new(3)|EVP_PKEY_CTX_new(3)>,
 L<EVP_PKEY_sign(3)|EVP_PKEY_sign(3)>,
 L<EVP_PKEY_verify(3)|EVP_PKEY_verify(3)>,
-L<EVP_PKEY_verifyrecover(3)|EVP_PKEY_verifyrecover(3)>,
+L<EVP_PKEY_verify_recover(3)|EVP_PKEY_verify_recover(3)>,
 
 =head1 HISTORY
 
index 37c6fe9..fd431ac 100644 (file)
@@ -151,7 +151,7 @@ L<EVP_PKEY_encrypt(3)|EVP_PKEY_encrypt(3)>,
 L<EVP_PKEY_decrypt(3)|EVP_PKEY_decrypt(3)>,
 L<EVP_PKEY_sign(3)|EVP_PKEY_sign(3)>,
 L<EVP_PKEY_verify(3)|EVP_PKEY_verify(3)>,
-L<EVP_PKEY_verifyrecover(3)|EVP_PKEY_verifyrecover(3)>,
+L<EVP_PKEY_verify_recover(3)|EVP_PKEY_verify_recover(3)>,
 L<EVP_PKEY_derive(3)|EVP_PKEY_derive(3)> 
 
 =head1 HISTORY
index 2fb52c3..a044f2c 100644 (file)
@@ -86,7 +86,7 @@ L<EVP_PKEY_CTX_new(3)|EVP_PKEY_CTX_new(3)>,
 L<EVP_PKEY_encrypt(3)|EVP_PKEY_encrypt(3)>,
 L<EVP_PKEY_decrypt(3)|EVP_PKEY_decrypt(3)>,
 L<EVP_PKEY_verify(3)|EVP_PKEY_verify(3)>,
-L<EVP_PKEY_verifyrecover(3)|EVP_PKEY_verifyrecover(3)>,
+L<EVP_PKEY_verify_recover(3)|EVP_PKEY_verify_recover(3)>,
 L<EVP_PKEY_derive(3)|EVP_PKEY_derive(3)> 
 
 =head1 HISTORY
index f93e5fc..90612ba 100644 (file)
@@ -81,7 +81,7 @@ L<EVP_PKEY_CTX_new(3)|EVP_PKEY_CTX_new(3)>,
 L<EVP_PKEY_encrypt(3)|EVP_PKEY_encrypt(3)>,
 L<EVP_PKEY_decrypt(3)|EVP_PKEY_decrypt(3)>,
 L<EVP_PKEY_sign(3)|EVP_PKEY_sign(3)>,
-L<EVP_PKEY_verifyrecover(3)|EVP_PKEY_verifyrecover(3)>,
+L<EVP_PKEY_verify_recover(3)|EVP_PKEY_verify_recover(3)>,
 L<EVP_PKEY_derive(3)|EVP_PKEY_derive(3)> 
 
 =head1 HISTORY
@@ -2,23 +2,23 @@
 
 =head1 NAME
 
-EVP_PKEY_verifyrecover_init, EVP_PKEY_verifyrecover - recover signature using a public key algorithm
+EVP_PKEY_verify_recover_init, EVP_PKEY_verify_recover - recover signature using a public key algorithm
 
 =head1 SYNOPSIS
 
  #include <openssl/evp.h>
 
- int EVP_PKEY_verifyrecover_init(EVP_PKEY_CTX *ctx);
- int EVP_PKEY_verifyrecover(EVP_PKEY_CTX *ctx,
+ int EVP_PKEY_verify_recover_init(EVP_PKEY_CTX *ctx);
+ int EVP_PKEY_verify_recover(EVP_PKEY_CTX *ctx,
                        unsigned char *rout, size_t *routlen,
                        const unsigned char *sig, size_t siglen);
 
 =head1 DESCRIPTION
 
-The EVP_PKEY_verifyrecover_init() function initializes a public key algorithm
+The EVP_PKEY_verify_recover_init() function initializes a public key algorithm
 context using key B<pkey> for a verify recover operation.
 
-The EVP_PKEY_verifyrecover() function recovers signed data
+The EVP_PKEY_verify_recover() function recovers signed data
 using B<ctx>. The signature is specified using the B<sig> and
 B<siglen> parameters. If B<rout> is B<NULL> then the maximum size of the output
 buffer is written to the B<routlen> parameter. If B<rout> is not B<NULL> then
@@ -36,16 +36,16 @@ Sometimes however it is useful to obtain the data originally signed using a
 signing operation. Only certain public key algorithms can recover a signature
 in this way (for example RSA in PKCS padding mode).
 
-After the call to EVP_PKEY_verifyrecover_init() algorithm specific control
+After the call to EVP_PKEY_verify_recover_init() algorithm specific control
 operations can be performed to set any appropriate parameters for the
 operation.
 
-The function EVP_PKEY_verifyrecover() can be called more than once on the same
+The function EVP_PKEY_verify_recover() can be called more than once on the same
 context if several operations are performed using the same parameters.
 
 =head1 RETURN VALUES
 
-EVP_PKEY_verifyrecover_init() and EVP_PKEY_verifyrecover() return 1 for success
+EVP_PKEY_verify_recover_init() and EVP_PKEY_verify_recover() return 1 for success
 and 0 or a negative value for failure. In particular a return value of -2
 indicates the operation is not supported by the public key algorithm.
 
@@ -66,7 +66,7 @@ Recover digest originally signed using PKCS#1 and SHA256 digest:
  ctx = EVP_PKEY_CTX_new(verify_key);
  if (!ctx)
        /* Error occurred */
- if (EVP_PKEY_verifyrecover_init(ctx) <= 0)
+ if (EVP_PKEY_verify_recover_init(ctx) <= 0)
        /* Error */
  if (EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_PADDING) <= 0)
        /* Error */
@@ -74,7 +74,7 @@ Recover digest originally signed using PKCS#1 and SHA256 digest:
        /* Error */
 
  /* Determine buffer length */
- if (EVP_PKEY_verifyrecover(ctx, NULL, &routlen, sig, siglen) <= 0)
+ if (EVP_PKEY_verify_recover(ctx, NULL, &routlen, sig, siglen) <= 0)
        /* Error */
 
  rout = OPENSSL_malloc(routlen);
@@ -82,7 +82,7 @@ Recover digest originally signed using PKCS#1 and SHA256 digest:
  if (!rout)
        /* malloc failure */
  
- if (EVP_PKEY_verifyrecover(ctx, rout, &routlen, sig, siglen) <= 0)
+ if (EVP_PKEY_verify_recover(ctx, rout, &routlen, sig, siglen) <= 0)
        /* Error */
 
  /* Recovered data is routlen bytes written to buffer rout */
index 7ebae0f..b0568c6 100644 (file)
@@ -369,7 +369,13 @@ int gost_mac(gost_ctx *ctx,int mac_len,const unsigned char *data,
                memset(buf2,0,8);
                memcpy(buf2,data+i,data_len-i);
                mac_block(ctx,buffer,buf2);
-               }       
+               i+=8;
+               }
+       if (i==8)
+               {
+               memset(buf2,0,8);
+               mac_block(ctx,buffer,buf2);
+               }
        get_mac(buffer,mac_len,mac);
        return 1;
        }
@@ -389,7 +395,13 @@ int gost_mac_iv(gost_ctx *ctx,int mac_len,const unsigned char *iv,const unsigned
                memset(buf2,0,8);
                memcpy(buf2,data+i,data_len-i);
                mac_block(ctx,buffer,buf2);
+               i+=8;
                }       
+       if (i==8)
+               {
+               memset(buf2,0,8);
+               mac_block(ctx,buffer,buf2);
+               }
        get_mac(buffer,mac_len,mac);
        return 1;
        }
index cde58c0..52aef15 100644 (file)
 #include <openssl/rand.h>
 #include "e_gost_err.h"
 #include "gost_lcl.h"
+
+#if !defined(CCGOST_DEBUG) && !defined(DEBUG)
+# ifndef NDEBUG
+#  define NDEBUG
+# endif
+#endif
+#include <assert.h>
+
 static int gost_cipher_init(EVP_CIPHER_CTX *ctx, const unsigned char *key, 
        const unsigned char *iv, int enc);
 static int     gost_cipher_init_cpa(EVP_CIPHER_CTX *ctx, const unsigned char *key,
@@ -206,12 +214,13 @@ int gost_cipher_init(EVP_CIPHER_CTX *ctx, const unsigned char *key,
 static void gost_crypt_mesh (void *ctx,unsigned char *iv,unsigned char *buf)
        {
        struct ossl_gost_cipher_ctx *c = ctx;
-       if (c->count&&c->key_meshing && c->count%1024==0)
+       assert(c->count%8 == 0 && c->count <= 1024);
+       if (c->key_meshing && c->count==1024)
                {
                cryptopro_key_meshing(&(c->cctx),iv);
                }       
        gostcrypt(&(c->cctx),iv,buf);
-       c->count+=8;
+       c->count = c->count%1024 + 8;
        }
 
 static void gost_cnt_next (void *ctx, unsigned char *iv, unsigned char *buf)
@@ -219,7 +228,8 @@ static void gost_cnt_next (void *ctx, unsigned char *iv, unsigned char *buf)
        struct ossl_gost_cipher_ctx *c = ctx;
        word32 g,go;
        unsigned char buf1[8];
-       if (c->count && c->key_meshing && c->count %1024 ==0)
+       assert(c->count%8 == 0 && c->count <= 1024);
+       if (c->key_meshing && c->count==1024)
                {
                cryptopro_key_meshing(&(c->cctx),iv);
                }
@@ -248,7 +258,7 @@ static void gost_cnt_next (void *ctx, unsigned char *iv, unsigned char *buf)
        buf1[7]=(unsigned char)((g>>24)&0xff);
        memcpy(iv,buf1,8);
        gostcrypt(&(c->cctx),buf1,buf);
-       c->count +=8;
+       c->count = c->count%1024 + 8;
        }
 
 /* GOST encryption in CFB mode */
@@ -511,12 +521,13 @@ static void mac_block_mesh(struct ossl_gost_imit_ctx *c,const unsigned char *dat
         * interpret internal state of MAC algorithm as iv during keymeshing
         * (but does initialize internal state from iv in key transport
         */
-       if (c->key_meshing&& c->count && c->count %1024 ==0)
+       assert(c->count%8 == 0 && c->count <= 1024);
+       if (c->key_meshing && c->count==1024)
                {
                cryptopro_key_meshing(&(c->cctx),buffer);
                }
        mac_block(&(c->cctx),c->buffer,data);
-       c->count +=8;
+       c->count = c->count%1024 + 8;
        }
 
 int gost_imit_update(EVP_MD_CTX *ctx, const void *data, size_t count)
@@ -565,6 +576,12 @@ int gost_imit_final(EVP_MD_CTX *ctx,unsigned char *md)
                GOSTerr(GOST_F_GOST_IMIT_FINAL, GOST_R_MAC_KEY_NOT_SET);
                return 0;
        }
+       if (c->count==0 && c->bytes_left)
+               {
+               unsigned char buffer[8];
+               memset(buffer, 0, 8);
+               gost_imit_update(ctx, buffer, 8);
+               }
        if (c->bytes_left)
                {
                int i;
index d2cbe3b..8f29bf6 100644 (file)
@@ -64,6 +64,13 @@ static int gost_engine_finish(ENGINE *e)
 static int gost_engine_destroy(ENGINE *e)
        { 
        gost_param_free();
+
+       pmeth_GostR3410_94 = NULL;
+       pmeth_GostR3410_2001 = NULL;
+       pmeth_Gost28147_MAC = NULL;
+       ameth_GostR3410_94 = NULL;
+       ameth_GostR3410_2001 = NULL;
+       ameth_Gost28147_MAC = NULL;
        return 1;
        }
 
@@ -71,6 +78,11 @@ static int bind_gost (ENGINE *e,const char *id)
        {
        int ret = 0;
        if (id && strcmp(id, engine_gost_id)) return 0;
+       if (ameth_GostR3410_94)
+               {
+               printf("GOST engine already loaded\n");
+               goto end;
+               }
 
        if (!ENGINE_set_id(e, engine_gost_id)) 
                {
@@ -263,7 +275,10 @@ static ENGINE *engine_gost(void)
        
 void ENGINE_load_gost(void)
        {
-       ENGINE *toadd =engine_gost();
+       ENGINE *toadd;
+       if (pmeth_GostR3410_94)
+               return;
+       toadd = engine_gost();
        if (!toadd) return;
        ENGINE_add(toadd);
        ENGINE_free(toadd);
index 437a48c..00aa42c 100644 (file)
@@ -136,7 +136,7 @@ extern EVP_MD imit_gost_cpa;
 /* Cipher context used for EVP_CIPHER operation */
 struct ossl_gost_cipher_ctx {
        int paramNID;
-       off_t count;
+       unsigned int count;
        int key_meshing;
        gost_ctx cctx;
 };     
@@ -151,7 +151,7 @@ struct ossl_gost_imit_ctx {
        gost_ctx cctx;
        unsigned char buffer[8];
        unsigned char partial_block[8];
-       off_t count;
+       unsigned int count;
        int key_meshing;
        int bytes_left;
        int key_set;
index a5c0662..8c278aa 100644 (file)
@@ -42,7 +42,7 @@ static void circle_xor8 (const byte *w, byte *k)
        byte buf[8];
        int i;
        memcpy(buf,w,8);
-       memcpy(k,w+8,24);
+       memmove(k,w+8,24);
        for(i=0;i<8;i++) 
                k[i+24]=buf[i]^k[i];
        }
index bfedde0..c1085b5 100644 (file)
@@ -1432,10 +1432,13 @@ static PCCERT_CONTEXT capi_find_cert(CAPI_CTX *ctx, const char *id, HCERTSTORE h
 static CAPI_KEY *capi_get_key(CAPI_CTX *ctx, const char *contname, char *provname, DWORD ptype, DWORD keyspec)
        {
        CAPI_KEY *key;
+    DWORD dwFlags = 0; 
        key = OPENSSL_malloc(sizeof(CAPI_KEY));
        CAPI_trace(ctx, "capi_get_key, contname=%s, provname=%s, type=%d\n", 
                                                contname, provname, ptype);
-       if (!CryptAcquireContextA(&key->hprov, contname, provname, ptype, 0))
+    if(ctx->store_flags & CERT_SYSTEM_STORE_LOCAL_MACHINE)
+        dwFlags = CRYPT_MACHINE_KEYSET;
+    if (!CryptAcquireContextA(&key->hprov, contname, provname, ptype, dwFlags)) 
                {
                CAPIerr(CAPI_F_CAPI_GET_KEY, CAPI_R_CRYPTACQUIRECONTEXT_ERROR);
                capi_addlasterror();
index 07a5e97..712c464 100644 (file)
 #include <openssl/des.h>
 #endif
 
+/* dtls1_enc encrypts/decrypts the record in |s->wrec| / |s->rrec|, respectively.
+ *
+ * Returns:
+ *   0: (in non-constant time) if the record is publically invalid (i.e. too
+ *       short etc).
+ *   1: if the record's padding is valid / the encryption was successful.
+ *   -1: if the record's padding/AEAD-authenticator is invalid or, if sending,
+ *       an internal error occured. */
 int dtls1_enc(SSL *s, int send)
        {
        SSL3_RECORD *rec;
        EVP_CIPHER_CTX *ds;
        unsigned long l;
-       int bs,i,ii,j,k,n=0;
+       int bs,i,j,k,mac_size=0;
        const EVP_CIPHER *enc;
 
        if (send)
                {
                if (EVP_MD_CTX_md(s->write_hash))
                        {
-                       n=EVP_MD_CTX_size(s->write_hash);
-                       if (n < 0)
+                       mac_size=EVP_MD_CTX_size(s->write_hash);
+                       if (mac_size < 0)
                                return -1;
                        }
                ds=s->enc_write_ctx;
@@ -164,9 +172,8 @@ int dtls1_enc(SSL *s, int send)
                {
                if (EVP_MD_CTX_md(s->read_hash))
                        {
-                       n=EVP_MD_CTX_size(s->read_hash);
-                       if (n < 0)
-                               return -1;
+                       mac_size=EVP_MD_CTX_size(s->read_hash);
+                       OPENSSL_assert(mac_size >= 0);
                        }
                ds=s->enc_read_ctx;
                rec= &(s->s3->rrec);
@@ -231,7 +238,7 @@ int dtls1_enc(SSL *s, int send)
                if (!send)
                        {
                        if (l == 0 || l%bs != 0)
-                               return -1;
+                               return 0;
                        }
                
                EVP_Cipher(ds,rec->data,rec->input,l);
@@ -246,43 +253,7 @@ int dtls1_enc(SSL *s, int send)
 #endif /* KSSL_DEBUG */
 
                if ((bs != 1) && !send)
-                       {
-                       ii=i=rec->data[l-1]; /* padding_length */
-                       i++;
-                       if (s->options&SSL_OP_TLS_BLOCK_PADDING_BUG)
-                               {
-                               /* First packet is even in size, so check */
-                               if ((memcmp(s->s3->read_sequence,
-                                       "\0\0\0\0\0\0\0\0",8) == 0) && !(ii & 1))
-                                       s->s3->flags|=TLS1_FLAGS_TLS_PADDING_BUG;
-                               if (s->s3->flags & TLS1_FLAGS_TLS_PADDING_BUG)
-                                       i--;
-                               }
-                       /* TLS 1.0 does not bound the number of padding bytes by the block size.
-                        * All of them must have value 'padding_length'. */
-                       if (i + bs > (int)rec->length)
-                               {
-                               /* Incorrect padding. SSLerr() and ssl3_alert are done
-                                * by caller: we don't want to reveal whether this is
-                                * a decryption error or a MAC verification failure
-                                * (see http://www.openssl.org/~bodo/tls-cbc.txt) 
-                                */
-                               return -1;
-                               }
-                       for (j=(int)(l-i); j<(int)l; j++)
-                               {
-                               if (rec->data[j] != ii)
-                                       {
-                                       /* Incorrect padding */
-                                       return -1;
-                                       }
-                               }
-                       rec->length-=i;
-
-                       rec->data += bs;    /* skip the implicit IV */
-                       rec->input += bs;
-                       rec->length -= bs;
-                       }
+                       return tls1_cbc_remove_padding(s, rec, bs, mac_size);
                }
        return(1);
        }
index 987af60..b0302a7 100644 (file)
@@ -376,15 +376,11 @@ static int
 dtls1_process_record(SSL *s)
 {
        int i,al;
-       int clear=0;
        int enc_err;
        SSL_SESSION *sess;
        SSL3_RECORD *rr;
-       unsigned int mac_size;
+       unsigned int mac_size, orig_len;
        unsigned char md[EVP_MAX_MD_SIZE];
-       int decryption_failed_or_bad_record_mac = 0;
-       unsigned char *mac = NULL;
-
 
        rr= &(s->s3->rrec);
        sess = s->session;
@@ -414,14 +410,19 @@ dtls1_process_record(SSL *s)
 
        /* decrypt in place in 'rr->input' */
        rr->data=rr->input;
+       orig_len=rr->length;
 
        enc_err = s->method->ssl3_enc->enc(s,0);
-       if (enc_err <= 0)
+       /* enc_err is:
+        *    0: (in non-constant time) if the record is publically invalid.
+        *    1: if the padding is valid
+        *    -1: if the padding is invalid */
+       if (enc_err == 0)
                {
-               /* To minimize information leaked via timing, we will always
-                * perform all computations before discarding the message.
-                */
-               decryption_failed_or_bad_record_mac = 1;
+               /* For DTLS we simply ignore bad packets. */
+               rr->length = 0;
+               s->packet_length = 0;
+               goto err;
                }
 
 #ifdef TLS_DEBUG
@@ -431,45 +432,59 @@ printf("\n");
 #endif
 
        /* r->length is now the compressed data plus mac */
-       if (    (sess == NULL) ||
-               (s->enc_read_ctx == NULL) ||
-               (s->read_hash == NULL))
-               clear=1;
-
-       if (!clear)
+       if ((sess != NULL) &&
+           (s->enc_read_ctx != NULL) &&
+           (EVP_MD_CTX_md(s->read_hash) != NULL))
                {
-               /* !clear => s->read_hash != NULL => mac_size != -1 */
-               int t;
-               t=EVP_MD_CTX_size(s->read_hash);
-               OPENSSL_assert(t >= 0);
-               mac_size=t;
-
-               if (rr->length > SSL3_RT_MAX_COMPRESSED_LENGTH+mac_size)
+               /* s->read_hash != NULL => mac_size != -1 */
+               unsigned char *mac = NULL;
+               unsigned char mac_tmp[EVP_MAX_MD_SIZE];
+               mac_size=EVP_MD_CTX_size(s->read_hash);
+               OPENSSL_assert(mac_size <= EVP_MAX_MD_SIZE);
+
+               /* orig_len is the length of the record before any padding was
+                * removed. This is public information, as is the MAC in use,
+                * therefore we can safely process the record in a different
+                * amount of time if it's too short to possibly contain a MAC.
+                */
+               if (orig_len < mac_size ||
+                   /* CBC records must have a padding length byte too. */
+                   (EVP_CIPHER_CTX_mode(s->enc_read_ctx) == EVP_CIPH_CBC_MODE &&
+                    orig_len < mac_size+1))
                        {
-#if 0 /* OK only for stream ciphers (then rr->length is visible from ciphertext anyway) */
-                       al=SSL_AD_RECORD_OVERFLOW;
-                       SSLerr(SSL_F_DTLS1_PROCESS_RECORD,SSL_R_PRE_MAC_LENGTH_TOO_LONG);
+                       al=SSL_AD_DECODE_ERROR;
+                       SSLerr(SSL_F_DTLS1_PROCESS_RECORD,SSL_R_LENGTH_TOO_SHORT);
                        goto f_err;
-#else
-                       decryption_failed_or_bad_record_mac = 1;
-#endif                 
                        }
-               /* check the MAC for rr->input (it's in mac_size bytes at the tail) */
-               if (rr->length >= mac_size)
+
+               if (EVP_CIPHER_CTX_mode(s->enc_read_ctx) == EVP_CIPH_CBC_MODE)
                        {
+                       /* We update the length so that the TLS header bytes
+                        * can be constructed correctly but we need to extract
+                        * the MAC in constant time from within the record,
+                        * without leaking the contents of the padding bytes.
+                        * */
+                       mac = mac_tmp;
+                       ssl3_cbc_copy_mac(mac_tmp, rr, mac_size, orig_len);
                        rr->length -= mac_size;
-                       mac = &rr->data[rr->length];
                        }
                else
-                       rr->length = 0;
-               i=s->method->ssl3_enc->mac(s,md,0);
-               if (i < 0 || mac == NULL || memcmp(md, mac, mac_size) != 0)
                        {
-                       decryption_failed_or_bad_record_mac = 1;
+                       /* In this case there's no padding, so |orig_len|
+                        * equals |rec->length| and we checked that there's
+                        * enough bytes for |mac_size| above. */
+                       rr->length -= mac_size;
+                       mac = &rr->data[rr->length];
                        }
+
+               i=s->method->ssl3_enc->mac(s,md,0 /* not send */);
+               if (i < 0 || mac == NULL || CRYPTO_memcmp(md, mac, (size_t)mac_size) != 0)
+                       enc_err = -1;
+               if (rr->length > SSL3_RT_MAX_COMPRESSED_LENGTH+mac_size)
+                       enc_err = -1;
                }
 
-       if (decryption_failed_or_bad_record_mac)
+       if (enc_err < 0)
                {
                /* decryption failed, silently discard message */
                rr->length = 0;
index 5008bf6..e65d501 100644 (file)
@@ -57,8 +57,8 @@
  *
  */
 
-#ifndef HEADER_DTLS1_H 
-#define HEADER_DTLS1_H 
+#ifndef HEADER_DTLS1_H
+#define HEADER_DTLS1_H
 
 #include <openssl/buffer.h>
 #include <openssl/pqueue.h>
 #elif defined(OPENSSL_SYS_NETWARE) && !defined(_WINSOCK2API_)
 #include <sys/timeval.h>
 #else
+#if defined(OPENSSL_SYS_VXWORKS)
+#include <sys/times.h>
+#else
 #include <sys/time.h>
 #endif
+#endif
 
 #ifdef  __cplusplus
 extern "C" {
index 00ac158..03b6cf9 100644 (file)
@@ -359,12 +359,14 @@ static int get_server_hello(SSL *s)
                                        SSL_R_PEER_ERROR);
                        return(-1);
                        }
-#ifdef __APPLE_CC__
-               /* The Rhapsody 5.5 (a.k.a. MacOS X) compiler bug
-                * workaround. <appro@fy.chalmers.se> */
-               s->hit=(i=*(p++))?1:0;
-#else
+#if 0
                s->hit=(*(p++))?1:0;
+               /* Some [PPC?] compilers fail to increment p in above
+                  statement, e.g. one provided with Rhapsody 5.5, but
+                  most recent example XL C 11.1 for AIX, even without
+                  optimization flag... */
+#else
+               s->hit=(*p)?1:0; p++;
 #endif
                s->s2->tmp.cert_type= *(p++);
                n2s(p,i);
@@ -937,7 +939,7 @@ static int get_server_verify(SSL *s)
                s->msg_callback(0, s->version, 0, p, len, s, s->msg_callback_arg); /* SERVER-VERIFY */
        p += 1;
 
-       if (memcmp(p,s->s2->challenge,s->s2->challenge_length) != 0)
+       if (CRYPTO_memcmp(p,s->s2->challenge,s->s2->challenge_length) != 0)
                {
                ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
                SSLerr(SSL_F_GET_SERVER_VERIFY,SSL_R_CHALLENGE_IS_DIFFERENT);
index ac963b2..8bb6ab8 100644 (file)
@@ -269,8 +269,7 @@ static int ssl2_read_internal(SSL *s, void *buf, int len, int peek)
                        s->s2->ract_data_length-=mac_size;
                        ssl2_mac(s,mac,0);
                        s->s2->ract_data_length-=s->s2->padding;
-                       if (    (memcmp(mac,s->s2->mac_data,
-                               (unsigned int)mac_size) != 0) ||
+                       if (    (CRYPTO_memcmp(mac,s->s2->mac_data,mac_size) != 0) ||
                                (s->s2->rlength%EVP_CIPHER_CTX_block_size(s->enc_read_ctx) != 0))
                                {
                                SSLerr(SSL_F_SSL2_READ_INTERNAL,SSL_R_BAD_MAC_DECODE);
index bc885e8..2cba426 100644 (file)
@@ -1059,10 +1059,12 @@ static int request_certificate(SSL *s)
                EVP_PKEY *pkey=NULL;
 
                EVP_MD_CTX_init(&ctx);
-               EVP_VerifyInit_ex(&ctx,s->ctx->rsa_md5, NULL);
-               EVP_VerifyUpdate(&ctx,s->s2->key_material,
-                                s->s2->key_material_length);
-               EVP_VerifyUpdate(&ctx,ccd,SSL2_MIN_CERT_CHALLENGE_LENGTH);
+               if (!EVP_VerifyInit_ex(&ctx,s->ctx->rsa_md5, NULL)
+                   || !EVP_VerifyUpdate(&ctx,s->s2->key_material,
+                                        s->s2->key_material_length)
+                   || !EVP_VerifyUpdate(&ctx,ccd,
+                                        SSL2_MIN_CERT_CHALLENGE_LENGTH))
+                       goto msg_end;
 
                i=i2d_X509(s->cert->pkeys[SSL_PKEY_RSA_ENC].x509,NULL);
                buf2=OPENSSL_malloc((unsigned int)i);
@@ -1073,7 +1075,11 @@ static int request_certificate(SSL *s)
                        }
                p2=buf2;
                i=i2d_X509(s->cert->pkeys[SSL_PKEY_RSA_ENC].x509,&p2);
-               EVP_VerifyUpdate(&ctx,buf2,(unsigned int)i);
+               if (!EVP_VerifyUpdate(&ctx,buf2,(unsigned int)i))
+                       {
+                       OPENSSL_free(buf2);
+                       goto msg_end;
+                       }
                OPENSSL_free(buf2);
 
                pkey=X509_get_pubkey(x509);
index b63460a..ead01c8 100644 (file)
@@ -204,7 +204,8 @@ int ssl3_send_finished(SSL *s, int a, int b, const char *sender, int slen)
 
 #ifndef OPENSSL_NO_NEXTPROTONEG
 /* ssl3_take_mac calculates the Finished MAC for the handshakes messages seen to far. */
-static void ssl3_take_mac(SSL *s) {
+static void ssl3_take_mac(SSL *s)
+       {
        const char *sender;
        int slen;
 
@@ -221,7 +222,7 @@ static void ssl3_take_mac(SSL *s) {
 
        s->s3->tmp.peer_finish_md_len = s->method->ssl3_enc->final_finish_mac(s,
                sender,slen,s->s3->tmp.peer_finish_md);
-}
+       }
 #endif
 
 int ssl3_get_finished(SSL *s, int a, int b)
@@ -231,8 +232,9 @@ int ssl3_get_finished(SSL *s, int a, int b)
        unsigned char *p;
 
 #ifdef OPENSSL_NO_NEXTPROTONEG
-       /* the mac has already been generated when we received the change
-        * cipher spec message and is in s->s3->tmp.peer_finish_md. */
+       /* the mac has already been generated when we received the
+        * change cipher spec message and is in s->s3->tmp.peer_finish_md.
+        */ 
 #endif
 
        n=s->method->ssl_get_message(s,
@@ -263,7 +265,7 @@ int ssl3_get_finished(SSL *s, int a, int b)
                goto f_err;
                }
 
-       if (memcmp(p, s->s3->tmp.peer_finish_md, i) != 0)
+       if (CRYPTO_memcmp(p, s->s3->tmp.peer_finish_md, i) != 0)
                {
                al=SSL_AD_DECRYPT_ERROR;
                SSLerr(SSL_F_SSL3_GET_FINISHED,SSL_R_DIGEST_CHECK_FAILED);
@@ -537,12 +539,14 @@ long ssl3_get_message(SSL *s, int st1, int stn, int mt, long max, int *ok)
                s->init_num += i;
                n -= i;
                }
+
 #ifndef OPENSSL_NO_NEXTPROTONEG
        /* If receiving Finished, record MAC of prior handshake messages for
         * Finished verification. */
        if (*s->init_buf->data == SSL3_MT_FINISHED)
                ssl3_take_mac(s);
 #endif
+
        /* Feed this message into MAC computation. */
        ssl3_finish_mac(s, (unsigned char *)s->init_buf->data, s->init_num + 4);
        if (s->msg_callback)
diff --git a/crypto/openssl/ssl/s3_cbc.c b/crypto/openssl/ssl/s3_cbc.c
new file mode 100644 (file)
index 0000000..3c2c165
--- /dev/null
@@ -0,0 +1,770 @@
+/* ssl/s3_cbc.c */
+/* ====================================================================
+ * Copyright (c) 2012 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include "ssl_locl.h"
+
+#include <openssl/md5.h>
+#include <openssl/sha.h>
+
+/* MAX_HASH_BIT_COUNT_BYTES is the maximum number of bytes in the hash's length
+ * field. (SHA-384/512 have 128-bit length.) */
+#define MAX_HASH_BIT_COUNT_BYTES 16
+
+/* MAX_HASH_BLOCK_SIZE is the maximum hash block size that we'll support.
+ * Currently SHA-384/512 has a 128-byte block size and that's the largest
+ * supported by TLS.) */
+#define MAX_HASH_BLOCK_SIZE 128
+
+/* Some utility functions are needed:
+ *
+ * These macros return the given value with the MSB copied to all the other
+ * bits. They use the fact that arithmetic shift shifts-in the sign bit.
+ * However, this is not ensured by the C standard so you may need to replace
+ * them with something else on odd CPUs. */
+#define DUPLICATE_MSB_TO_ALL(x) ( (unsigned)( (int)(x) >> (sizeof(int)*8-1) ) )
+#define DUPLICATE_MSB_TO_ALL_8(x) ((unsigned char)(DUPLICATE_MSB_TO_ALL(x)))
+
+/* constant_time_ge returns 0xff if a>=b and 0x00 otherwise. */
+static unsigned constant_time_ge(unsigned a, unsigned b)
+       {
+       a -= b;
+       return DUPLICATE_MSB_TO_ALL(~a);
+       }
+
+/* constant_time_eq_8 returns 0xff if a==b and 0x00 otherwise. */
+static unsigned char constant_time_eq_8(unsigned char a, unsigned char b)
+       {
+       unsigned c = a ^ b;
+       c--;
+       return DUPLICATE_MSB_TO_ALL_8(c);
+       }
+
+/* ssl3_cbc_remove_padding removes padding from the decrypted, SSLv3, CBC
+ * record in |rec| by updating |rec->length| in constant time.
+ *
+ * block_size: the block size of the cipher used to encrypt the record.
+ * returns:
+ *   0: (in non-constant time) if the record is publicly invalid.
+ *   1: if the padding was valid
+ *  -1: otherwise. */
+int ssl3_cbc_remove_padding(const SSL* s,
+                           SSL3_RECORD *rec,
+                           unsigned block_size,
+                           unsigned mac_size)
+       {
+       unsigned padding_length, good;
+       const unsigned overhead = 1 /* padding length byte */ + mac_size;
+
+       /* These lengths are all public so we can test them in non-constant
+        * time. */
+       if (overhead > rec->length)
+               return 0;
+
+       padding_length = rec->data[rec->length-1];
+       good = constant_time_ge(rec->length, padding_length+overhead);
+       /* SSLv3 requires that the padding is minimal. */
+       good &= constant_time_ge(block_size, padding_length+1);
+       padding_length = good & (padding_length+1);
+       rec->length -= padding_length;
+       rec->type |= padding_length<<8; /* kludge: pass padding length */
+       return (int)((good & 1) | (~good & -1));
+}
+
+/* tls1_cbc_remove_padding removes the CBC padding from the decrypted, TLS, CBC
+ * record in |rec| in constant time and returns 1 if the padding is valid and
+ * -1 otherwise. It also removes any explicit IV from the start of the record
+ * without leaking any timing about whether there was enough space after the
+ * padding was removed.
+ *
+ * block_size: the block size of the cipher used to encrypt the record.
+ * returns:
+ *   0: (in non-constant time) if the record is publicly invalid.
+ *   1: if the padding was valid
+ *  -1: otherwise. */
+int tls1_cbc_remove_padding(const SSL* s,
+                           SSL3_RECORD *rec,
+                           unsigned block_size,
+                           unsigned mac_size)
+       {
+       unsigned padding_length, good, to_check, i;
+       const char has_explicit_iv =
+               s->version >= TLS1_1_VERSION || s->version == DTLS1_VERSION;
+       const unsigned overhead = 1 /* padding length byte */ +
+                                 mac_size +
+                                 (has_explicit_iv ? block_size : 0);
+
+       /* These lengths are all public so we can test them in non-constant
+        * time. */
+       if (overhead > rec->length)
+               return 0;
+
+       /* We can always safely skip the explicit IV. We check at the beginning
+        * of this function that the record has at least enough space for the
+        * IV, MAC and padding length byte. (These can be checked in
+        * non-constant time because it's all public information.) So, if the
+        * padding was invalid, then we didn't change |rec->length| and this is
+        * safe. If the padding was valid then we know that we have at least
+        * overhead+padding_length bytes of space and so this is still safe
+        * because overhead accounts for the explicit IV. */
+       if (has_explicit_iv)
+               {
+               rec->data += block_size;
+               rec->input += block_size;
+               rec->length -= block_size;
+               }
+
+       padding_length = rec->data[rec->length-1];
+
+       /* NB: if compression is in operation the first packet may not be of
+        * even length so the padding bug check cannot be performed. This bug
+        * workaround has been around since SSLeay so hopefully it is either
+        * fixed now or no buggy implementation supports compression [steve]
+        */
+       if ( (s->options&SSL_OP_TLS_BLOCK_PADDING_BUG) && !s->expand)
+               {
+               /* First packet is even in size, so check */
+               if ((memcmp(s->s3->read_sequence, "\0\0\0\0\0\0\0\0",8) == 0) &&
+                   !(padding_length & 1))
+                       {
+                       s->s3->flags|=TLS1_FLAGS_TLS_PADDING_BUG;
+                       }
+               if ((s->s3->flags & TLS1_FLAGS_TLS_PADDING_BUG) &&
+                   padding_length > 0)
+                       {
+                       padding_length--;
+                       }
+               }
+
+       if (EVP_CIPHER_flags(s->enc_read_ctx->cipher)&EVP_CIPH_FLAG_AEAD_CIPHER)
+               {
+               /* padding is already verified */
+               rec->length -= padding_length;
+               return 1;
+               }
+
+       good = constant_time_ge(rec->length, overhead+padding_length);
+       /* The padding consists of a length byte at the end of the record and
+        * then that many bytes of padding, all with the same value as the
+        * length byte. Thus, with the length byte included, there are i+1
+        * bytes of padding.
+        *
+        * We can't check just |padding_length+1| bytes because that leaks
+        * decrypted information. Therefore we always have to check the maximum
+        * amount of padding possible. (Again, the length of the record is
+        * public information so we can use it.) */
+       to_check = 255; /* maximum amount of padding. */
+       if (to_check > rec->length-1)
+               to_check = rec->length-1;
+
+       for (i = 0; i < to_check; i++)
+               {
+               unsigned char mask = constant_time_ge(padding_length, i);
+               unsigned char b = rec->data[rec->length-1-i];
+               /* The final |padding_length+1| bytes should all have the value
+                * |padding_length|. Therefore the XOR should be zero. */
+               good &= ~(mask&(padding_length ^ b));
+               }
+
+       /* If any of the final |padding_length+1| bytes had the wrong value,
+        * one or more of the lower eight bits of |good| will be cleared. We
+        * AND the bottom 8 bits together and duplicate the result to all the
+        * bits. */
+       good &= good >> 4;
+       good &= good >> 2;
+       good &= good >> 1;
+       good <<= sizeof(good)*8-1;
+       good = DUPLICATE_MSB_TO_ALL(good);
+
+       padding_length = good & (padding_length+1);
+       rec->length -= padding_length;
+       rec->type |= padding_length<<8; /* kludge: pass padding length */
+
+       return (int)((good & 1) | (~good & -1));
+       }
+
+#if defined(_M_AMD64) || defined(__x86_64__)
+#define CBC_MAC_ROTATE_IN_PLACE
+#endif
+
+/* ssl3_cbc_copy_mac copies |md_size| bytes from the end of |rec| to |out| in
+ * constant time (independent of the concrete value of rec->length, which may
+ * vary within a 256-byte window).
+ *
+ * ssl3_cbc_remove_padding or tls1_cbc_remove_padding must be called prior to
+ * this function.
+ *
+ * On entry:
+ *   rec->orig_len >= md_size
+ *   md_size <= EVP_MAX_MD_SIZE
+ *
+ * If CBC_MAC_ROTATE_IN_PLACE is defined then the rotation is performed with
+ * variable accesses in a 64-byte-aligned buffer. Assuming that this fits into
+ * a single cache-line, then the variable memory accesses don't actually affect
+ * the timing. This has been tested to be true on Intel amd64 chips.
+ */
+void ssl3_cbc_copy_mac(unsigned char* out,
+                      const SSL3_RECORD *rec,
+                      unsigned md_size,unsigned orig_len)
+       {
+#if defined(CBC_MAC_ROTATE_IN_PLACE)
+       unsigned char rotated_mac_buf[EVP_MAX_MD_SIZE*2];
+       unsigned char *rotated_mac;
+#else
+       unsigned char rotated_mac[EVP_MAX_MD_SIZE];
+#endif
+
+       /* mac_end is the index of |rec->data| just after the end of the MAC. */
+       unsigned mac_end = rec->length;
+       unsigned mac_start = mac_end - md_size;
+       /* scan_start contains the number of bytes that we can ignore because
+        * the MAC's position can only vary by 255 bytes. */
+       unsigned scan_start = 0;
+       unsigned i, j;
+       unsigned div_spoiler;
+       unsigned rotate_offset;
+
+       OPENSSL_assert(orig_len >= md_size);
+       OPENSSL_assert(md_size <= EVP_MAX_MD_SIZE);
+
+#if defined(CBC_MAC_ROTATE_IN_PLACE)
+       rotated_mac = (unsigned char*) (((intptr_t)(rotated_mac_buf + 64)) & ~63);
+#endif
+
+       /* This information is public so it's safe to branch based on it. */
+       if (orig_len > md_size + 255 + 1)
+               scan_start = orig_len - (md_size + 255 + 1);
+       /* div_spoiler contains a multiple of md_size that is used to cause the
+        * modulo operation to be constant time. Without this, the time varies
+        * based on the amount of padding when running on Intel chips at least.
+        *
+        * The aim of right-shifting md_size is so that the compiler doesn't
+        * figure out that it can remove div_spoiler as that would require it
+        * to prove that md_size is always even, which I hope is beyond it. */
+       div_spoiler = md_size >> 1;
+       div_spoiler <<= (sizeof(div_spoiler)-1)*8;
+       rotate_offset = (div_spoiler + mac_start - scan_start) % md_size;
+
+       memset(rotated_mac, 0, md_size);
+       for (i = scan_start; i < orig_len;)
+               {
+               for (j = 0; j < md_size && i < orig_len; i++, j++)
+                       {
+                       unsigned char mac_started = constant_time_ge(i, mac_start);
+                       unsigned char mac_ended = constant_time_ge(i, mac_end);
+                       unsigned char b = 0;
+                       b = rec->data[i];
+                       rotated_mac[j] |= b & mac_started & ~mac_ended;
+                       }
+               }
+
+       /* Now rotate the MAC */
+#if defined(CBC_MAC_ROTATE_IN_PLACE)
+       j = 0;
+       for (i = 0; i < md_size; i++)
+               {
+               unsigned char offset = (div_spoiler + rotate_offset + i) % md_size;
+               out[j++] = rotated_mac[offset];
+               }
+#else
+       memset(out, 0, md_size);
+       for (i = 0; i < md_size; i++)
+               {
+               unsigned char offset = (div_spoiler + md_size - rotate_offset + i) % md_size;
+               for (j = 0; j < md_size; j++)
+                       out[j] |= rotated_mac[i] & constant_time_eq_8(j, offset);
+               }
+#endif
+       }
+
+/* These functions serialize the state of a hash and thus perform the standard
+ * "final" operation without adding the padding and length that such a function
+ * typically does. */
+static void tls1_md5_final_raw(void* ctx, unsigned char *md_out)
+       {
+       MD5_CTX *md5 = ctx;
+       l2n(md5->A, md_out);
+       l2n(md5->B, md_out);
+       l2n(md5->C, md_out);
+       l2n(md5->D, md_out);
+       }
+
+static void tls1_sha1_final_raw(void* ctx, unsigned char *md_out)
+       {
+       SHA_CTX *sha1 = ctx;
+       l2n(sha1->h0, md_out);
+       l2n(sha1->h1, md_out);
+       l2n(sha1->h2, md_out);
+       l2n(sha1->h3, md_out);
+       l2n(sha1->h4, md_out);
+       }
+#define LARGEST_DIGEST_CTX SHA_CTX
+
+#ifndef OPENSSL_NO_SHA256
+static void tls1_sha256_final_raw(void* ctx, unsigned char *md_out)
+       {
+       SHA256_CTX *sha256 = ctx;
+       unsigned i;
+
+       for (i = 0; i < 8; i++)
+               {
+               l2n(sha256->h[i], md_out);
+               }
+       }
+#undef  LARGEST_DIGEST_CTX
+#define LARGEST_DIGEST_CTX SHA256_CTX
+#endif
+
+#ifndef OPENSSL_NO_SHA512
+static void tls1_sha512_final_raw(void* ctx, unsigned char *md_out)
+       {
+       SHA512_CTX *sha512 = ctx;
+       unsigned i;
+
+       for (i = 0; i < 8; i++)
+               {
+               l2n8(sha512->h[i], md_out);
+               }
+       }
+#undef  LARGEST_DIGEST_CTX
+#define LARGEST_DIGEST_CTX SHA512_CTX
+#endif
+
+/* ssl3_cbc_record_digest_supported returns 1 iff |ctx| uses a hash function
+ * which ssl3_cbc_digest_record supports. */
+char ssl3_cbc_record_digest_supported(const EVP_MD_CTX *ctx)
+       {
+#ifdef OPENSSL_FIPS
+       if (FIPS_mode())
+               return 0;
+#endif
+       switch (EVP_MD_CTX_type(ctx))
+               {
+               case NID_md5:
+               case NID_sha1:
+#ifndef OPENSSL_NO_SHA256
+               case NID_sha224:
+               case NID_sha256:
+#endif
+#ifndef OPENSSL_NO_SHA512
+               case NID_sha384:
+               case NID_sha512:
+#endif
+                       return 1;
+               default:
+                       return 0;
+               }
+       }
+
+/* ssl3_cbc_digest_record computes the MAC of a decrypted, padded SSLv3/TLS
+ * record.
+ *
+ *   ctx: the EVP_MD_CTX from which we take the hash function.
+ *     ssl3_cbc_record_digest_supported must return true for this EVP_MD_CTX.
+ *   md_out: the digest output. At most EVP_MAX_MD_SIZE bytes will be written.
+ *   md_out_size: if non-NULL, the number of output bytes is written here.
+ *   header: the 13-byte, TLS record header.
+ *   data: the record data itself, less any preceeding explicit IV.
+ *   data_plus_mac_size: the secret, reported length of the data and MAC
+ *     once the padding has been removed.
+ *   data_plus_mac_plus_padding_size: the public length of the whole
+ *     record, including padding.
+ *   is_sslv3: non-zero if we are to use SSLv3. Otherwise, TLS.
+ *
+ * On entry: by virtue of having been through one of the remove_padding
+ * functions, above, we know that data_plus_mac_size is large enough to contain
+ * a padding byte and MAC. (If the padding was invalid, it might contain the
+ * padding too. ) */
+void ssl3_cbc_digest_record(
+       const EVP_MD_CTX *ctx,
+       unsigned char* md_out,
+       size_t* md_out_size,
+       const unsigned char header[13],
+       const unsigned char *data,
+       size_t data_plus_mac_size,
+       size_t data_plus_mac_plus_padding_size,
+       const unsigned char *mac_secret,
+       unsigned mac_secret_length,
+       char is_sslv3)
+       {
+       union { double align;
+               unsigned char c[sizeof(LARGEST_DIGEST_CTX)]; } md_state;
+       void (*md_final_raw)(void *ctx, unsigned char *md_out);
+       void (*md_transform)(void *ctx, const unsigned char *block);
+       unsigned md_size, md_block_size = 64;
+       unsigned sslv3_pad_length = 40, header_length, variance_blocks,
+                len, max_mac_bytes, num_blocks,
+                num_starting_blocks, k, mac_end_offset, c, index_a, index_b;
+       unsigned int bits;      /* at most 18 bits */
+       unsigned char length_bytes[MAX_HASH_BIT_COUNT_BYTES];
+       /* hmac_pad is the masked HMAC key. */
+       unsigned char hmac_pad[MAX_HASH_BLOCK_SIZE];
+       unsigned char first_block[MAX_HASH_BLOCK_SIZE];
+       unsigned char mac_out[EVP_MAX_MD_SIZE];
+       unsigned i, j, md_out_size_u;
+       EVP_MD_CTX md_ctx;
+       /* mdLengthSize is the number of bytes in the length field that terminates
+       * the hash. */
+       unsigned md_length_size = 8;
+
+       /* This is a, hopefully redundant, check that allows us to forget about
+        * many possible overflows later in this function. */
+       OPENSSL_assert(data_plus_mac_plus_padding_size < 1024*1024);
+
+       switch (EVP_MD_CTX_type(ctx))
+               {
+               case NID_md5:
+                       MD5_Init((MD5_CTX*)md_state.c);
+                       md_final_raw = tls1_md5_final_raw;
+                       md_transform = (void(*)(void *ctx, const unsigned char *block)) MD5_Transform;
+                       md_size = 16;
+                       sslv3_pad_length = 48;
+                       break;
+               case NID_sha1:
+                       SHA1_Init((SHA_CTX*)md_state.c);
+                       md_final_raw = tls1_sha1_final_raw;
+                       md_transform = (void(*)(void *ctx, const unsigned char *block)) SHA1_Transform;
+                       md_size = 20;
+                       break;
+#ifndef OPENSSL_NO_SHA256
+               case NID_sha224:
+                       SHA224_Init((SHA256_CTX*)md_state.c);
+                       md_final_raw = tls1_sha256_final_raw;
+                       md_transform = (void(*)(void *ctx, const unsigned char *block)) SHA256_Transform;
+                       md_size = 224/8;
+                       break;
+               case NID_sha256:
+                       SHA256_Init((SHA256_CTX*)md_state.c);
+                       md_final_raw = tls1_sha256_final_raw;
+                       md_transform = (void(*)(void *ctx, const unsigned char *block)) SHA256_Transform;
+                       md_size = 32;
+                       break;
+#endif
+#ifndef OPENSSL_NO_SHA512
+               case NID_sha384:
+                       SHA384_Init((SHA512_CTX*)md_state.c);
+                       md_final_raw = tls1_sha512_final_raw;
+                       md_transform = (void(*)(void *ctx, const unsigned char *block)) SHA512_Transform;
+                       md_size = 384/8;
+                       md_block_size = 128;
+                       md_length_size = 16;
+                       break;
+               case NID_sha512:
+                       SHA512_Init((SHA512_CTX*)md_state.c);
+                       md_final_raw = tls1_sha512_final_raw;
+                       md_transform = (void(*)(void *ctx, const unsigned char *block)) SHA512_Transform;
+                       md_size = 64;
+                       md_block_size = 128;
+                       md_length_size = 16;
+                       break;
+#endif
+               default:
+                       /* ssl3_cbc_record_digest_supported should have been
+                        * called first to check that the hash function is
+                        * supported. */
+                       OPENSSL_assert(0);
+                       if (md_out_size)
+                               *md_out_size = -1;
+                       return;
+               }
+
+       OPENSSL_assert(md_length_size <= MAX_HASH_BIT_COUNT_BYTES);
+       OPENSSL_assert(md_block_size <= MAX_HASH_BLOCK_SIZE);
+       OPENSSL_assert(md_size <= EVP_MAX_MD_SIZE);
+
+       header_length = 13;
+       if (is_sslv3)
+               {
+               header_length =
+                       mac_secret_length +
+                       sslv3_pad_length +
+                       8 /* sequence number */ +
+                       1 /* record type */ +
+                       2 /* record length */;
+               }
+
+       /* variance_blocks is the number of blocks of the hash that we have to
+        * calculate in constant time because they could be altered by the
+        * padding value.
+        *
+        * In SSLv3, the padding must be minimal so the end of the plaintext
+        * varies by, at most, 15+20 = 35 bytes. (We conservatively assume that
+        * the MAC size varies from 0..20 bytes.) In case the 9 bytes of hash
+        * termination (0x80 + 64-bit length) don't fit in the final block, we
+        * say that the final two blocks can vary based on the padding.
+        *
+        * TLSv1 has MACs up to 48 bytes long (SHA-384) and the padding is not
+        * required to be minimal. Therefore we say that the final six blocks
+        * can vary based on the padding.
+        *
+        * Later in the function, if the message is short and there obviously
+        * cannot be this many blocks then variance_blocks can be reduced. */
+       variance_blocks = is_sslv3 ? 2 : 6;
+       /* From now on we're dealing with the MAC, which conceptually has 13
+        * bytes of `header' before the start of the data (TLS) or 71/75 bytes
+        * (SSLv3) */
+       len = data_plus_mac_plus_padding_size + header_length;
+       /* max_mac_bytes contains the maximum bytes of bytes in the MAC, including
+       * |header|, assuming that there's no padding. */
+       max_mac_bytes = len - md_size - 1;
+       /* num_blocks is the maximum number of hash blocks. */
+       num_blocks = (max_mac_bytes + 1 + md_length_size + md_block_size - 1) / md_block_size;
+       /* In order to calculate the MAC in constant time we have to handle
+        * the final blocks specially because the padding value could cause the
+        * end to appear somewhere in the final |variance_blocks| blocks and we
+        * can't leak where. However, |num_starting_blocks| worth of data can
+        * be hashed right away because no padding value can affect whether
+        * they are plaintext. */
+       num_starting_blocks = 0;
+       /* k is the starting byte offset into the conceptual header||data where
+        * we start processing. */
+       k = 0;
+       /* mac_end_offset is the index just past the end of the data to be
+        * MACed. */
+       mac_end_offset = data_plus_mac_size + header_length - md_size;
+       /* c is the index of the 0x80 byte in the final hash block that
+        * contains application data. */
+       c = mac_end_offset % md_block_size;
+       /* index_a is the hash block number that contains the 0x80 terminating
+        * value. */
+       index_a = mac_end_offset / md_block_size;
+       /* index_b is the hash block number that contains the 64-bit hash
+        * length, in bits. */
+       index_b = (mac_end_offset + md_length_size) / md_block_size;
+       /* bits is the hash-length in bits. It includes the additional hash
+        * block for the masked HMAC key, or whole of |header| in the case of
+        * SSLv3. */
+
+       /* For SSLv3, if we're going to have any starting blocks then we need
+        * at least two because the header is larger than a single block. */
+       if (num_blocks > variance_blocks + (is_sslv3 ? 1 : 0))
+               {
+               num_starting_blocks = num_blocks - variance_blocks;
+               k = md_block_size*num_starting_blocks;
+               }
+
+       bits = 8*mac_end_offset;
+       if (!is_sslv3)
+               {
+               /* Compute the initial HMAC block. For SSLv3, the padding and
+                * secret bytes are included in |header| because they take more
+                * than a single block. */
+               bits += 8*md_block_size;
+               memset(hmac_pad, 0, md_block_size);
+               OPENSSL_assert(mac_secret_length <= sizeof(hmac_pad));
+               memcpy(hmac_pad, mac_secret, mac_secret_length);
+               for (i = 0; i < md_block_size; i++)
+                       hmac_pad[i] ^= 0x36;
+
+               md_transform(md_state.c, hmac_pad);
+               }
+
+       memset(length_bytes,0,md_length_size-4);
+       length_bytes[md_length_size-4] = (unsigned char)(bits>>24);
+       length_bytes[md_length_size-3] = (unsigned char)(bits>>16);
+       length_bytes[md_length_size-2] = (unsigned char)(bits>>8);
+       length_bytes[md_length_size-1] = (unsigned char)bits;
+
+       if (k > 0)
+               {
+               if (is_sslv3)
+                       {
+                       /* The SSLv3 header is larger than a single block.
+                        * overhang is the number of bytes beyond a single
+                        * block that the header consumes: either 7 bytes
+                        * (SHA1) or 11 bytes (MD5). */
+                       unsigned overhang = header_length-md_block_size;
+                       md_transform(md_state.c, header);
+                       memcpy(first_block, header + md_block_size, overhang);
+                       memcpy(first_block + overhang, data, md_block_size-overhang);
+                       md_transform(md_state.c, first_block);
+                       for (i = 1; i < k/md_block_size - 1; i++)
+                               md_transform(md_state.c, data + md_block_size*i - overhang);
+                       }
+               else
+                       {
+                       /* k is a multiple of md_block_size. */
+                       memcpy(first_block, header, 13);
+                       memcpy(first_block+13, data, md_block_size-13);
+                       md_transform(md_state.c, first_block);
+                       for (i = 1; i < k/md_block_size; i++)
+                               md_transform(md_state.c, data + md_block_size*i - 13);
+                       }
+               }
+
+       memset(mac_out, 0, sizeof(mac_out));
+
+       /* We now process the final hash blocks. For each block, we construct
+        * it in constant time. If the |i==index_a| then we'll include the 0x80
+        * bytes and zero pad etc. For each block we selectively copy it, in
+        * constant time, to |mac_out|. */
+       for (i = num_starting_blocks; i <= num_starting_blocks+variance_blocks; i++)
+               {
+               unsigned char block[MAX_HASH_BLOCK_SIZE];
+               unsigned char is_block_a = constant_time_eq_8(i, index_a);
+               unsigned char is_block_b = constant_time_eq_8(i, index_b);
+               for (j = 0; j < md_block_size; j++)
+                       {
+                       unsigned char b = 0, is_past_c, is_past_cp1;
+                       if (k < header_length)
+                               b = header[k];
+                       else if (k < data_plus_mac_plus_padding_size + header_length)
+                               b = data[k-header_length];
+                       k++;
+
+                       is_past_c = is_block_a & constant_time_ge(j, c);
+                       is_past_cp1 = is_block_a & constant_time_ge(j, c+1);
+                       /* If this is the block containing the end of the
+                        * application data, and we are at the offset for the
+                        * 0x80 value, then overwrite b with 0x80. */
+                       b = (b&~is_past_c) | (0x80&is_past_c);
+                       /* If this the the block containing the end of the
+                        * application data and we're past the 0x80 value then
+                        * just write zero. */
+                       b = b&~is_past_cp1;
+                       /* If this is index_b (the final block), but not
+                        * index_a (the end of the data), then the 64-bit
+                        * length didn't fit into index_a and we're having to
+                        * add an extra block of zeros. */
+                       b &= ~is_block_b | is_block_a;
+
+                       /* The final bytes of one of the blocks contains the
+                        * length. */
+                       if (j >= md_block_size - md_length_size)
+                               {
+                               /* If this is index_b, write a length byte. */
+                               b = (b&~is_block_b) | (is_block_b&length_bytes[j-(md_block_size-md_length_size)]);
+                               }
+                       block[j] = b;
+                       }
+
+               md_transform(md_state.c, block);
+               md_final_raw(md_state.c, block);
+               /* If this is index_b, copy the hash value to |mac_out|. */
+               for (j = 0; j < md_size; j++)
+                       mac_out[j] |= block[j]&is_block_b;
+               }
+
+       EVP_MD_CTX_init(&md_ctx);
+       EVP_DigestInit_ex(&md_ctx, ctx->digest, NULL /* engine */);
+       if (is_sslv3)
+               {
+               /* We repurpose |hmac_pad| to contain the SSLv3 pad2 block. */
+               memset(hmac_pad, 0x5c, sslv3_pad_length);
+
+               EVP_DigestUpdate(&md_ctx, mac_secret, mac_secret_length);
+               EVP_DigestUpdate(&md_ctx, hmac_pad, sslv3_pad_length);
+               EVP_DigestUpdate(&md_ctx, mac_out, md_size);
+               }
+       else
+               {
+               /* Complete the HMAC in the standard manner. */
+               for (i = 0; i < md_block_size; i++)
+                       hmac_pad[i] ^= 0x6a;
+
+               EVP_DigestUpdate(&md_ctx, hmac_pad, md_block_size);
+               EVP_DigestUpdate(&md_ctx, mac_out, md_size);
+               }
+       EVP_DigestFinal(&md_ctx, md_out, &md_out_size_u);
+       if (md_out_size)
+               *md_out_size = md_out_size_u;
+       EVP_MD_CTX_cleanup(&md_ctx);
+       }
+
+#ifdef OPENSSL_FIPS
+
+/* Due to the need to use EVP in FIPS mode we can't reimplement digests but
+ * we can ensure the number of blocks processed is equal for all cases
+ * by digesting additional data.
+ */
+
+void tls_fips_digest_extra(
+       const EVP_CIPHER_CTX *cipher_ctx, EVP_MD_CTX *mac_ctx,
+       const unsigned char *data, size_t data_len, size_t orig_len)
+       {
+       size_t block_size, digest_pad, blocks_data, blocks_orig;
+       if (EVP_CIPHER_CTX_mode(cipher_ctx) != EVP_CIPH_CBC_MODE)
+               return;
+       block_size = EVP_MD_CTX_block_size(mac_ctx);
+       /* We are in FIPS mode if we get this far so we know we have only SHA*
+        * digests and TLS to deal with.
+        * Minimum digest padding length is 17 for SHA384/SHA512 and 9
+        * otherwise.
+        * Additional header is 13 bytes. To get the number of digest blocks
+        * processed round up the amount of data plus padding to the nearest
+        * block length. Block length is 128 for SHA384/SHA512 and 64 otherwise.
+        * So we have:
+        * blocks = (payload_len + digest_pad + 13 + block_size - 1)/block_size
+        * equivalently:
+        * blocks = (payload_len + digest_pad + 12)/block_size + 1
+        * HMAC adds a constant overhead.
+        * We're ultimately only interested in differences so this becomes
+        * blocks = (payload_len + 29)/128
+        * for SHA384/SHA512 and
+        * blocks = (payload_len + 21)/64
+        * otherwise.
+        */
+       digest_pad = block_size == 64 ? 21 : 29;
+       blocks_orig = (orig_len + digest_pad)/block_size;
+       blocks_data = (data_len + digest_pad)/block_size;
+       /* MAC enough blocks to make up the difference between the original
+        * and actual lengths plus one extra block to ensure this is never a
+        * no op. The "data" pointer should always have enough space to
+        * perform this operation as it is large enough for a maximum
+        * length TLS buffer. 
+        */
+       EVP_DigestSignUpdate(mac_ctx, data,
+                               (blocks_orig - blocks_data + 1) * block_size);
+       }
+#endif
index b80d052..7b4bc63 100644 (file)
@@ -459,7 +459,6 @@ int ssl3_connect(SSL *s)
                                SSL3_ST_CW_CHANGE_A,SSL3_ST_CW_CHANGE_B);
                        if (ret <= 0) goto end;
 
-
 #if defined(OPENSSL_NO_TLSEXT) || defined(OPENSSL_NO_NEXTPROTONEG)
                        s->state=SSL3_ST_CW_FINISHED_A;
 #else
index c5df2cb..e3cd4f0 100644 (file)
@@ -466,12 +466,21 @@ void ssl3_cleanup_key_block(SSL *s)
        s->s3->tmp.key_block_length=0;
        }
 
+/* ssl3_enc encrypts/decrypts the record in |s->wrec| / |s->rrec|, respectively.
+ *
+ * Returns:
+ *   0: (in non-constant time) if the record is publically invalid (i.e. too
+ *       short etc).
+ *   1: if the record's padding is valid / the encryption was successful.
+ *   -1: if the record's padding is invalid or, if sending, an internal error
+ *       occured.
+ */
 int ssl3_enc(SSL *s, int send)
        {
        SSL3_RECORD *rec;
        EVP_CIPHER_CTX *ds;
        unsigned long l;
-       int bs,i;
+       int bs,i,mac_size=0;
        const EVP_CIPHER *enc;
 
        if (send)
@@ -522,32 +531,16 @@ int ssl3_enc(SSL *s, int send)
                if (!send)
                        {
                        if (l == 0 || l%bs != 0)
-                               {
-                               SSLerr(SSL_F_SSL3_ENC,SSL_R_BLOCK_CIPHER_PAD_IS_WRONG);
-                               ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_DECRYPTION_FAILED);
                                return 0;
-                               }
                        /* otherwise, rec->length >= bs */
                        }
                
                EVP_Cipher(ds,rec->data,rec->input,l);
 
+               if (EVP_MD_CTX_md(s->read_hash) != NULL)
+                       mac_size = EVP_MD_CTX_size(s->read_hash);
                if ((bs != 1) && !send)
-                       {
-                       i=rec->data[l-1]+1;
-                       /* SSL 3.0 bounds the number of padding bytes by the block size;
-                        * padding bytes (except the last one) are arbitrary */
-                       if (i > bs)
-                               {
-                               /* Incorrect padding. SSLerr() and ssl3_alert are done
-                                * by caller: we don't want to reveal whether this is
-                                * a decryption error or a MAC verification failure
-                                * (see http://www.openssl.org/~bodo/tls-cbc.txt) */
-                               return -1;
-                               }
-                       /* now i <= bs <= rec->length */
-                       rec->length-=i;
-                       }
+                       return ssl3_cbc_remove_padding(s, rec, bs, mac_size);
                }
        return(1);
        }
@@ -716,7 +709,7 @@ int n_ssl3_mac(SSL *ssl, unsigned char *md, int send)
        EVP_MD_CTX md_ctx;
        const EVP_MD_CTX *hash;
        unsigned char *p,rec_char;
-       unsigned int md_size;
+       size_t md_size, orig_len;
        int npad;
        int t;
 
@@ -741,28 +734,72 @@ int n_ssl3_mac(SSL *ssl, unsigned char *md, int send)
        md_size=t;
        npad=(48/md_size)*md_size;
 
-       /* Chop the digest off the end :-) */
-       EVP_MD_CTX_init(&md_ctx);
-
-       EVP_MD_CTX_copy_ex( &md_ctx,hash);
-       EVP_DigestUpdate(&md_ctx,mac_sec,md_size);
-       EVP_DigestUpdate(&md_ctx,ssl3_pad_1,npad);
-       EVP_DigestUpdate(&md_ctx,seq,8);
-       rec_char=rec->type;
-       EVP_DigestUpdate(&md_ctx,&rec_char,1);
-       p=md;
-       s2n(rec->length,p);
-       EVP_DigestUpdate(&md_ctx,md,2);
-       EVP_DigestUpdate(&md_ctx,rec->input,rec->length);
-       EVP_DigestFinal_ex( &md_ctx,md,NULL);
-
-       EVP_MD_CTX_copy_ex( &md_ctx,hash);
-       EVP_DigestUpdate(&md_ctx,mac_sec,md_size);
-       EVP_DigestUpdate(&md_ctx,ssl3_pad_2,npad);
-       EVP_DigestUpdate(&md_ctx,md,md_size);
-       EVP_DigestFinal_ex( &md_ctx,md,&md_size);
-
-       EVP_MD_CTX_cleanup(&md_ctx);
+       /* kludge: ssl3_cbc_remove_padding passes padding length in rec->type */
+       orig_len = rec->length+md_size+((unsigned int)rec->type>>8);
+       rec->type &= 0xff;
+
+       if (!send &&
+           EVP_CIPHER_CTX_mode(ssl->enc_read_ctx) == EVP_CIPH_CBC_MODE &&
+           ssl3_cbc_record_digest_supported(hash))
+               {
+               /* This is a CBC-encrypted record. We must avoid leaking any
+                * timing-side channel information about how many blocks of
+                * data we are hashing because that gives an attacker a
+                * timing-oracle. */
+
+               /* npad is, at most, 48 bytes and that's with MD5:
+                *   16 + 48 + 8 (sequence bytes) + 1 + 2 = 75.
+                *
+                * With SHA-1 (the largest hash speced for SSLv3) the hash size
+                * goes up 4, but npad goes down by 8, resulting in a smaller
+                * total size. */
+               unsigned char header[75];
+               unsigned j = 0;
+               memcpy(header+j, mac_sec, md_size);
+               j += md_size;
+               memcpy(header+j, ssl3_pad_1, npad);
+               j += npad;
+               memcpy(header+j, seq, 8);
+               j += 8;
+               header[j++] = rec->type;
+               header[j++] = rec->length >> 8;
+               header[j++] = rec->length & 0xff;
+
+               ssl3_cbc_digest_record(
+                       hash,
+                       md, &md_size,
+                       header, rec->input,
+                       rec->length + md_size, orig_len,
+                       mac_sec, md_size,
+                       1 /* is SSLv3 */);
+               }
+       else
+               {
+               unsigned int md_size_u;
+               /* Chop the digest off the end :-) */
+               EVP_MD_CTX_init(&md_ctx);
+
+               EVP_MD_CTX_copy_ex( &md_ctx,hash);
+               EVP_DigestUpdate(&md_ctx,mac_sec,md_size);
+               EVP_DigestUpdate(&md_ctx,ssl3_pad_1,npad);
+               EVP_DigestUpdate(&md_ctx,seq,8);
+               rec_char=rec->type;
+               EVP_DigestUpdate(&md_ctx,&rec_char,1);
+               p=md;
+               s2n(rec->length,p);
+               EVP_DigestUpdate(&md_ctx,md,2);
+               EVP_DigestUpdate(&md_ctx,rec->input,rec->length);
+               EVP_DigestFinal_ex( &md_ctx,md,NULL);
+
+               EVP_MD_CTX_copy_ex( &md_ctx,hash);
+               EVP_DigestUpdate(&md_ctx,mac_sec,md_size);
+               EVP_DigestUpdate(&md_ctx,ssl3_pad_2,npad);
+               EVP_DigestUpdate(&md_ctx,md,md_size);
+               EVP_DigestFinal_ex( &md_ctx,md,&md_size_u);
+               md_size = md_size_u;
+
+               EVP_MD_CTX_cleanup(&md_ctx);
+       }
 
        ssl3_record_sequence_update(seq);
        return(md_size);
index fb60cde..e7c5dcb 100644 (file)
@@ -1125,7 +1125,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[]={
        0, /* not implemented (non-ephemeral DH) */
        TLS1_TXT_DH_DSS_WITH_AES_128_SHA256,
        TLS1_CK_DH_DSS_WITH_AES_128_SHA256,
-       SSL_kDHr,
+       SSL_kDHd,
        SSL_aDH,
        SSL_AES128,
        SSL_SHA256,
@@ -1407,7 +1407,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[]={
        0, /* not implemented (non-ephemeral DH) */
        TLS1_TXT_DH_DSS_WITH_AES_256_SHA256,
        TLS1_CK_DH_DSS_WITH_AES_256_SHA256,
-       SSL_kDHr,
+       SSL_kDHd,
        SSL_aDH,
        SSL_AES256,
        SSL_SHA256,
@@ -1958,7 +1958,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[]={
        0,
        TLS1_TXT_DH_DSS_WITH_AES_128_GCM_SHA256,
        TLS1_CK_DH_DSS_WITH_AES_128_GCM_SHA256,
-       SSL_kDHr,
+       SSL_kDHd,
        SSL_aDH,
        SSL_AES128GCM,
        SSL_AEAD,
@@ -1974,7 +1974,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[]={
        0,
        TLS1_TXT_DH_DSS_WITH_AES_256_GCM_SHA384,
        TLS1_CK_DH_DSS_WITH_AES_256_GCM_SHA384,
-       SSL_kDHr,
+       SSL_kDHd,
        SSL_aDH,
        SSL_AES256GCM,
        SSL_AEAD,
@@ -2669,7 +2669,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[]={
        1,
        TLS1_TXT_ECDH_RSA_WITH_AES_128_SHA256,
        TLS1_CK_ECDH_RSA_WITH_AES_128_SHA256,
-       SSL_kECDHe,
+       SSL_kECDHr,
        SSL_aECDH,
        SSL_AES128,
        SSL_SHA256,
@@ -2685,7 +2685,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[]={
        1,
        TLS1_TXT_ECDH_RSA_WITH_AES_256_SHA384,
        TLS1_CK_ECDH_RSA_WITH_AES_256_SHA384,
-       SSL_kECDHe,
+       SSL_kECDHr,
        SSL_aECDH,
        SSL_AES256,
        SSL_SHA384,
@@ -2799,7 +2799,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[]={
        1,
        TLS1_TXT_ECDH_RSA_WITH_AES_128_GCM_SHA256,
        TLS1_CK_ECDH_RSA_WITH_AES_128_GCM_SHA256,
-       SSL_kECDHe,
+       SSL_kECDHr,
        SSL_aECDH,
        SSL_AES128GCM,
        SSL_AEAD,
@@ -2815,7 +2815,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[]={
        1,
        TLS1_TXT_ECDH_RSA_WITH_AES_256_GCM_SHA384,
        TLS1_CK_ECDH_RSA_WITH_AES_256_GCM_SHA384,
-       SSL_kECDHe,
+       SSL_kECDHr,
        SSL_aECDH,
        SSL_AES256GCM,
        SSL_AEAD,
index adf8c38..bf8da98 100644 (file)
@@ -290,11 +290,8 @@ static int ssl3_get_record(SSL *s)
        unsigned char *p;
        unsigned char md[EVP_MAX_MD_SIZE];
        short version;
-       int mac_size;
-       int clear=0;
+       unsigned mac_size, orig_len;
        size_t extra;
-       int decryption_failed_or_bad_record_mac = 0;
-       unsigned char *mac = NULL;
 
        rr= &(s->s3->rrec);
        sess=s->session;
@@ -401,19 +398,18 @@ fprintf(stderr, "Record type=%d, Length=%d\n", rr->type, rr->length);
 
        /* decrypt in place in 'rr->input' */
        rr->data=rr->input;
+       orig_len=rr->length;
 
        enc_err = s->method->ssl3_enc->enc(s,0);
-       if (enc_err <= 0)
+       /* enc_err is:
+        *    0: (in non-constant time) if the record is publically invalid.
+        *    1: if the padding is valid
+        *    -1: if the padding is invalid */
+       if (enc_err == 0)
                {
-               if (enc_err == 0)
-                       /* SSLerr() and ssl3_send_alert() have been called */
-                       goto err;
-
-               /* Otherwise enc_err == -1, which indicates bad padding
-                * (rec->length has not been changed in this case).
-                * To minimize information leaked via timing, we will perform
-                * the MAC computation anyway. */
-               decryption_failed_or_bad_record_mac = 1;
+               al=SSL_AD_DECRYPTION_FAILED;
+               SSLerr(SSL_F_SSL3_GET_RECORD,SSL_R_BLOCK_CIPHER_PAD_IS_WRONG);
+               goto f_err;
                }
 
 #ifdef TLS_DEBUG
@@ -423,53 +419,59 @@ printf("\n");
 #endif
 
        /* r->length is now the compressed data plus mac */
-       if (    (sess == NULL) ||
-               (s->enc_read_ctx == NULL) ||
-               (EVP_MD_CTX_md(s->read_hash) == NULL))
-               clear=1;
-
-       if (!clear)
+       if ((sess != NULL) &&
+           (s->enc_read_ctx != NULL) &&
+           (EVP_MD_CTX_md(s->read_hash) != NULL))
                {
-               /* !clear => s->read_hash != NULL => mac_size != -1 */
+               /* s->read_hash != NULL => mac_size != -1 */
+               unsigned char *mac = NULL;
+               unsigned char mac_tmp[EVP_MAX_MD_SIZE];
                mac_size=EVP_MD_CTX_size(s->read_hash);
-               OPENSSL_assert(mac_size >= 0);
+               OPENSSL_assert(mac_size <= EVP_MAX_MD_SIZE);
 
-               if (rr->length > SSL3_RT_MAX_COMPRESSED_LENGTH+extra+mac_size)
+               /* orig_len is the length of the record before any padding was
+                * removed. This is public information, as is the MAC in use,
+                * therefore we can safely process the record in a different
+                * amount of time if it's too short to possibly contain a MAC.
+                */
+               if (orig_len < mac_size ||
+                   /* CBC records must have a padding length byte too. */
+                   (EVP_CIPHER_CTX_mode(s->enc_read_ctx) == EVP_CIPH_CBC_MODE &&
+                    orig_len < mac_size+1))
                        {
-#if 0 /* OK only for stream ciphers (then rr->length is visible from ciphertext anyway) */
-                       al=SSL_AD_RECORD_OVERFLOW;
-                       SSLerr(SSL_F_SSL3_GET_RECORD,SSL_R_PRE_MAC_LENGTH_TOO_LONG);
+                       al=SSL_AD_DECODE_ERROR;
+                       SSLerr(SSL_F_SSL3_GET_RECORD,SSL_R_LENGTH_TOO_SHORT);
                        goto f_err;
-#else
-                       decryption_failed_or_bad_record_mac = 1;
-#endif                 
                        }
-               /* check the MAC for rr->input (it's in mac_size bytes at the tail) */
-               if (rr->length >= (unsigned int)mac_size)
+
+               if (EVP_CIPHER_CTX_mode(s->enc_read_ctx) == EVP_CIPH_CBC_MODE)
                        {
+                       /* We update the length so that the TLS header bytes
+                        * can be constructed correctly but we need to extract
+                        * the MAC in constant time from within the record,
+                        * without leaking the contents of the padding bytes.
+                        * */
+                       mac = mac_tmp;
+                       ssl3_cbc_copy_mac(mac_tmp, rr, mac_size, orig_len);
                        rr->length -= mac_size;
-                       mac = &rr->data[rr->length];
                        }
                else
                        {
-                       /* record (minus padding) is too short to contain a MAC */
-#if 0 /* OK only for stream ciphers */
-                       al=SSL_AD_DECODE_ERROR;
-                       SSLerr(SSL_F_SSL3_GET_RECORD,SSL_R_LENGTH_TOO_SHORT);
-                       goto f_err;
-#else
-                       decryption_failed_or_bad_record_mac = 1;
-                       rr->length = 0;
-#endif
-                       }
-               i=s->method->ssl3_enc->mac(s,md,0);
-               if (i < 0 || mac == NULL || memcmp(md, mac, (size_t)mac_size) != 0)
-                       {
-                       decryption_failed_or_bad_record_mac = 1;
+                       /* In this case there's no padding, so |orig_len|
+                        * equals |rec->length| and we checked that there's
+                        * enough bytes for |mac_size| above. */
+                       rr->length -= mac_size;
+                       mac = &rr->data[rr->length];
                        }
+
+               i=s->method->ssl3_enc->mac(s,md,0 /* not send */);
+               if (i < 0 || mac == NULL || CRYPTO_memcmp(md, mac, (size_t)mac_size) != 0)
+                       enc_err = -1;
+               if (rr->length > SSL3_RT_MAX_COMPRESSED_LENGTH+extra+mac_size)
+                       enc_err = -1;
                }
 
-       if (decryption_failed_or_bad_record_mac)
+       if (enc_err < 0)
                {
                /* A separate 'decryption_failed' alert was introduced with TLS 1.0,
                 * SSL 3.0 only has 'bad_record_mac'.  But unless a decryption
@@ -744,6 +746,7 @@ static int do_ssl3_write(SSL *s, int type, const unsigned char *buf,
         * bytes and record version number > TLS 1.0
         */
        if (s->state == SSL3_ST_CW_CLNT_HELLO_B
+                               && !s->renegotiate
                                && TLS1_get_version(s) > TLS1_VERSION)
                *(p++) = 0x1;
        else
@@ -1238,7 +1241,7 @@ start:
                                goto f_err;
                                }
 #ifdef SSL_AD_MISSING_SRP_USERNAME
-                       if (alert_descr == SSL_AD_MISSING_SRP_USERNAME)
+                       else if (alert_descr == SSL_AD_MISSING_SRP_USERNAME)
                                return(0);
 #endif
                        }