diff --git a/share/security/advisories/FreeBSD-SA-15:01.openssl.asc b/share/security/advisories/FreeBSD-SA-15:01.openssl.asc
new file mode 100644
index 0000000000..464ce21e47
--- /dev/null
+++ b/share/security/advisories/FreeBSD-SA-15:01.openssl.asc
@@ -0,0 +1,211 @@
+-----BEGIN PGP SIGNED MESSAGE-----
+Hash: SHA512
+
+=============================================================================
+FreeBSD-SA-15:01.openssl Security Advisory
+ The FreeBSD Project
+
+Topic: OpenSSL multiple vulnerabilities
+
+Category: contrib
+Module: openssl
+Announced: 2015-01-14
+Affects: All supported versions of FreeBSD.
+Corrected: 2015-01-09 00:58:20 UTC (stable/10, 10.1-STABLE)
+ 2015-01-14 21:27:46 UTC (releng/10.1, 10.1-RELEASE-p4)
+ 2015-01-14 21:27:46 UTC (releng/10.0, 10.0-RELEASE-p16)
+ 2015-01-09 01:11:43 UTC (stable/9, 9.3-STABLE)
+ 2015-01-14 21:27:46 UTC (releng/9.3, 9.3-RELEASE-p8)
+ 2015-01-09 01:11:43 UTC (stable/8, 8.4-STABLE)
+ 2015-01-14 21:27:46 UTC (releng/8.4, 8.4-RELEASE-p22)
+CVE Name: CVE-2014-3571, CVE-2015-0206, CVE-2014-3569, CVE-2014-3572
+ CVE-2015-0204, CVE-2015-0205, CVE-2014-8275, CVE-2014-3570
+
+For general information regarding FreeBSD Security Advisories,
+including descriptions of the fields above, security branches, and the
+following sections, please visit .
+
+I. Background
+
+FreeBSD includes software from the OpenSSL Project. The OpenSSL Project is
+a collaborative effort to develop a robust, commercial-grade, full-featured
+Open Source toolkit implementing the Secure Sockets Layer (SSL v2/v3)
+and Transport Layer Security (TLS v1) protocols as well as a full-strength
+general purpose cryptography library.
+
+II. Problem Description
+
+A carefully crafted DTLS message can cause a segmentation fault in OpenSSL
+due to a NULL pointer dereference. [CVE-2014-3571]
+
+A memory leak can occur in the dtls1_buffer_record function under certain
+conditions. [CVE-2015-0206]
+
+When OpenSSL is built with the no-ssl3 option and a SSL v3 ClientHello is
+received the ssl method would be set to NULL which could later result in
+a NULL pointer dereference. [CVE-2014-3569] This does not affect
+FreeBSD's default build.
+
+An OpenSSL client will accept a handshake using an ephemeral ECDH
+ciphersuite using an ECDSA certificate if the server key exchange message
+is omitted. [CVE-2014-3572]
+
+An OpenSSL client will accept the use of an RSA temporary key in a non-export
+RSA key exchange ciphersuite. [CVE-2015-0204]
+
+An OpenSSL server will accept a DH certificate for client authentication
+without the certificate verify message. [CVE-2015-0205]
+
+OpenSSL accepts several non-DER-variations of certificate signature
+algorithm and signature encodings. OpenSSL also does not enforce a
+match between the signature algorithm between the signed and unsigned
+portions of the certificate. [CVE-2014-8275]
+
+Bignum squaring (BN_sqr) may produce incorrect results on some
+platforms, including x86_64. [CVE-2014-3570]
+
+III. Impact
+
+An attacker who can send a carefully crafted DTLS message can cause server
+daemons that uses OpenSSL to crash, resulting a Denial of Service.
+[CVE-2014-3571]
+
+An attacker who can send repeated DTLS records with the same sequence number
+but for the next epoch can exhaust the server's memory and result in a Denial of
+Service. [CVE-2015-0206]
+
+A server can remove forward secrecy from the ciphersuite. [CVE-2014-3572]
+
+A server could present a weak temporary key and downgrade the security of
+the session. [CVE-2015-0204]
+
+A client could authenticate without the use of a private key. This only
+affects servers which trust a client certificate authority which issues
+certificates containing DH keys, which is extremely rare. [CVE-2015-0205]
+
+By modifying the contents of the signature algorithm or the encoding of
+the signature, it is possible to change the certificate's fingerprint.
+
+This does not allow an attacker to forge certificates, and does not
+affect certificate verification or OpenSSL servers/clients in any
+other way. It also does not affect common revocation mechanisms. Only
+custom applications that rely on the uniqueness of the fingerprint
+(e.g. certificate blacklists) may be affected. [CVE-2014-8275]
+
+IV. Workaround
+
+No workaround is available.
+
+V. Solution
+
+Perform one of the following:
+
+1) Upgrade your vulnerable system to a supported FreeBSD stable or
+release / security branch (releng) dated after the correction date.
+
+2) To update your vulnerable system via a binary patch:
+
+Systems running a RELEASE version of FreeBSD on the i386 or amd64
+platforms can be updated via the freebsd-update(8) utility:
+
+# freebsd-update fetch
+# freebsd-update install
+
+3) To update your vulnerable system via a source code patch:
+
+The following patches have been verified to apply to the applicable
+FreeBSD release branches.
+
+a) Download the relevant patch from the location below, and verify the
+detached PGP signature using your PGP utility.
+
+[FreeBSD 8.4 and FreeBSD 9.3]
+# fetch https://security.FreeBSD.org/patches/SA-15:01/openssl-9.3.patch
+# fetch https://security.FreeBSD.org/patches/SA-15:01/openssl-9.3.patch.asc
+# gpg --verify openssl-9.3.patch.asc
+
+[FreeBSD 10.0]
+# fetch https://security.FreeBSD.org/patches/SA-15:01/openssl-10.0.patch
+# fetch https://security.FreeBSD.org/patches/SA-15:01/openssl-10.0.patch.asc
+# gpg --verify openssl-10.0.patch.asc
+
+[FreeBSD 10.1]
+# fetch https://security.FreeBSD.org/patches/SA-15:01/openssl-10.1.patch
+# fetch https://security.FreeBSD.org/patches/SA-15:01/openssl-10.1.patch.asc
+# gpg --verify openssl-10.1.patch.asc
+
+b) Apply the patch. Execute the following commands as root:
+
+# cd /usr/src
+# patch < /path/to/patch
+
+c) Recompile the operating system using buildworld and installworld as
+described in .
+
+Restart all deamons using the library, or reboot the system.
+
+VI. Correction details
+
+The following list contains the correction revision numbers for each
+affected branch.
+
+Branch/path Revision
+- -------------------------------------------------------------------------
+stable/8/ r276865
+releng/8.4/ r277195
+stable/9/ r276865
+releng/9.3/ r277195
+stable/10/ r276864
+releng/10.0/ r277195
+releng/10.1/ r277195
+- -------------------------------------------------------------------------
+
+To see which files were modified by a particular revision, run the
+following command, replacing NNNNNN with the revision number, on a
+machine with Subversion installed:
+
+# svn diff -cNNNNNN --summarize svn://svn.freebsd.org/base
+
+Or visit the following URL, replacing NNNNNN with the revision number:
+
+
+
+VII. References
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+The latest revision of this advisory is available at
+
+-----BEGIN PGP SIGNATURE-----
+Version: GnuPG v2.1.1 (FreeBSD)
+
+iQIcBAEBCgAGBQJUtuEaAAoJEO1n7NZdz2rnQCcP/A19v5HUUhjz5nMbUumRwAmB
+QCxNKEy6SbAuxtIwGNYJyyxKIK3R9vTHwlgyQZVb4q8FgMHcu4yABeRfov10mO5Q
+U7RkLOJyca6eqEngkrh+AFfbhqfxtccIMUQkDdegsQcqZd2Ya0VeNfjA8H0XIDoL
+JSEoCifmxjv6v8ZcpugahsUOBmEWx+vyHJUSPVSv/AsLubzV3hqi4iLpzLky3/dR
+4LHGzPny07NkGPVqOBU7mjTs76SzCTS2c4NIVfvbphx8UojMvREbZ8ogCMEVGBXY
+fIWesi7Y6lhqbSgWj1EXyZF9NTo/Z4nr7Oh1ER5VSAfmhZAdyhEEEGQrg4Jq0VL3
+DJ1Y35Up79xXmVjB14COxodI5UO+55wWnXb8r/zy/eh+wv0sHwlTz56wxo7SxAOa
+xOrQj0VJ7zghLhBO7azacbVYIKpfQkJafb7XRUOqu4wt2y3/jeL+0UkWJnNMROrq
+aQUB6SdGUVDwQsmodgF0rsGcQYXhaQBPu4KQo8yG8+rpqc2zewi537BJr/PWJvH0
+sJ6yYcD7VGyIleVRDpxsg7uBWelnGn+AqHignbyUcic4j/N9lYlF00AVgka2TdOp
+i5eZtp7m95v53S4fEX2HGwWpOv+AfCrSKQZGpvdNx+9JyD3LyOvFBxs4k0oZWa6J
+6FLFZ38YkLcUIzW6I6Kc
+=ztFk
+-----END PGP SIGNATURE-----
diff --git a/share/security/patches/SA-15:01/openssl-10.0.patch b/share/security/patches/SA-15:01/openssl-10.0.patch
new file mode 100644
index 0000000000..c5124dda8e
--- /dev/null
+++ b/share/security/patches/SA-15:01/openssl-10.0.patch
@@ -0,0 +1,2083 @@
+Index: crypto/openssl/crypto/asn1/a_bitstr.c
+===================================================================
+--- crypto/openssl/crypto/asn1/a_bitstr.c (revision 276867)
++++ crypto/openssl/crypto/asn1/a_bitstr.c (working copy)
+@@ -136,11 +136,16 @@ ASN1_BIT_STRING *c2i_ASN1_BIT_STRING(ASN1_BIT_STRI
+
+ p= *pp;
+ i= *(p++);
++ if (i > 7)
++ {
++ i=ASN1_R_INVALID_BIT_STRING_BITS_LEFT;
++ goto err;
++ }
+ /* We do this to preserve the settings. If we modify
+ * the settings, via the _set_bit function, we will recalculate
+ * on output */
+ ret->flags&= ~(ASN1_STRING_FLAG_BITS_LEFT|0x07); /* clear */
+- ret->flags|=(ASN1_STRING_FLAG_BITS_LEFT|(i&0x07)); /* set */
++ ret->flags|=(ASN1_STRING_FLAG_BITS_LEFT|i); /* set */
+
+ if (len-- > 1) /* using one because of the bits left byte */
+ {
+Index: crypto/openssl/crypto/asn1/a_type.c
+===================================================================
+--- crypto/openssl/crypto/asn1/a_type.c (revision 276867)
++++ crypto/openssl/crypto/asn1/a_type.c (working copy)
+@@ -113,7 +113,7 @@ IMPLEMENT_STACK_OF(ASN1_TYPE)
+ IMPLEMENT_ASN1_SET_OF(ASN1_TYPE)
+
+ /* Returns 0 if they are equal, != 0 otherwise. */
+-int ASN1_TYPE_cmp(ASN1_TYPE *a, ASN1_TYPE *b)
++int ASN1_TYPE_cmp(const ASN1_TYPE *a, const ASN1_TYPE *b)
+ {
+ int result = -1;
+
+Index: crypto/openssl/crypto/asn1/a_verify.c
+===================================================================
+--- crypto/openssl/crypto/asn1/a_verify.c (revision 276867)
++++ crypto/openssl/crypto/asn1/a_verify.c (working copy)
+@@ -90,6 +90,12 @@ int ASN1_verify(i2d_of_void *i2d, X509_ALGOR *a, A
+ ASN1err(ASN1_F_ASN1_VERIFY,ASN1_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM);
+ goto err;
+ }
++
++ if (signature->type == V_ASN1_BIT_STRING && signature->flags & 0x7)
++ {
++ ASN1err(ASN1_F_ASN1_VERIFY, ASN1_R_INVALID_BIT_STRING_BITS_LEFT);
++ goto err;
++ }
+
+ inl=i2d(data,NULL);
+ buf_in=OPENSSL_malloc((unsigned int)inl);
+@@ -146,6 +152,12 @@ int ASN1_item_verify(const ASN1_ITEM *it, X509_ALG
+ return -1;
+ }
+
++ if (signature->type == V_ASN1_BIT_STRING && signature->flags & 0x7)
++ {
++ ASN1err(ASN1_F_ASN1_ITEM_VERIFY, ASN1_R_INVALID_BIT_STRING_BITS_LEFT);
++ return -1;
++ }
++
+ EVP_MD_CTX_init(&ctx);
+
+ /* Convert signature OID into digest and public key OIDs */
+Index: crypto/openssl/crypto/asn1/asn1.h
+===================================================================
+--- crypto/openssl/crypto/asn1/asn1.h (revision 276867)
++++ crypto/openssl/crypto/asn1/asn1.h (working copy)
+@@ -776,7 +776,7 @@ DECLARE_ASN1_FUNCTIONS_fname(ASN1_TYPE, ASN1_ANY,
+ int ASN1_TYPE_get(ASN1_TYPE *a);
+ void ASN1_TYPE_set(ASN1_TYPE *a, int type, void *value);
+ int ASN1_TYPE_set1(ASN1_TYPE *a, int type, const void *value);
+-int ASN1_TYPE_cmp(ASN1_TYPE *a, ASN1_TYPE *b);
++int ASN1_TYPE_cmp(const ASN1_TYPE *a, const ASN1_TYPE *b);
+
+ ASN1_OBJECT * ASN1_OBJECT_new(void );
+ void ASN1_OBJECT_free(ASN1_OBJECT *a);
+@@ -1329,6 +1329,7 @@ void ERR_load_ASN1_strings(void);
+ #define ASN1_R_ILLEGAL_TIME_VALUE 184
+ #define ASN1_R_INTEGER_NOT_ASCII_FORMAT 185
+ #define ASN1_R_INTEGER_TOO_LARGE_FOR_LONG 128
++#define ASN1_R_INVALID_BIT_STRING_BITS_LEFT 220
+ #define ASN1_R_INVALID_BMPSTRING_LENGTH 129
+ #define ASN1_R_INVALID_DIGIT 130
+ #define ASN1_R_INVALID_MIME_TYPE 205
+Index: crypto/openssl/crypto/asn1/asn1_err.c
+===================================================================
+--- crypto/openssl/crypto/asn1/asn1_err.c (revision 276867)
++++ crypto/openssl/crypto/asn1/asn1_err.c (working copy)
+@@ -246,6 +246,7 @@ static ERR_STRING_DATA ASN1_str_reasons[]=
+ {ERR_REASON(ASN1_R_ILLEGAL_TIME_VALUE) ,"illegal time value"},
+ {ERR_REASON(ASN1_R_INTEGER_NOT_ASCII_FORMAT),"integer not ascii format"},
+ {ERR_REASON(ASN1_R_INTEGER_TOO_LARGE_FOR_LONG),"integer too large for long"},
++{ERR_REASON(ASN1_R_INVALID_BIT_STRING_BITS_LEFT),"invalid bit string bits left"},
+ {ERR_REASON(ASN1_R_INVALID_BMPSTRING_LENGTH),"invalid bmpstring length"},
+ {ERR_REASON(ASN1_R_INVALID_DIGIT) ,"invalid digit"},
+ {ERR_REASON(ASN1_R_INVALID_MIME_TYPE) ,"invalid mime type"},
+Index: crypto/openssl/crypto/asn1/x_algor.c
+===================================================================
+--- crypto/openssl/crypto/asn1/x_algor.c (revision 276867)
++++ crypto/openssl/crypto/asn1/x_algor.c (working copy)
+@@ -142,3 +142,14 @@ void X509_ALGOR_set_md(X509_ALGOR *alg, const EVP_
+ X509_ALGOR_set0(alg, OBJ_nid2obj(EVP_MD_type(md)), param_type, NULL);
+
+ }
++
++int X509_ALGOR_cmp(const X509_ALGOR *a, const X509_ALGOR *b)
++ {
++ int rv;
++ rv = OBJ_cmp(a->algorithm, b->algorithm);
++ if (rv)
++ return rv;
++ if (!a->parameter && !b->parameter)
++ return 0;
++ return ASN1_TYPE_cmp(a->parameter, b->parameter);
++ }
+Index: crypto/openssl/crypto/bio/bss_dgram.c
+===================================================================
+--- crypto/openssl/crypto/bio/bss_dgram.c (revision 276867)
++++ crypto/openssl/crypto/bio/bss_dgram.c (working copy)
+@@ -982,7 +982,12 @@ static int dgram_sctp_free(BIO *a)
+ return 0;
+
+ data = (bio_dgram_sctp_data *)a->ptr;
+- if(data != NULL) OPENSSL_free(data);
++ if(data != NULL)
++ {
++ if(data->saved_message.data != NULL)
++ OPENSSL_free(data->saved_message.data);
++ OPENSSL_free(data);
++ }
+
+ return(1);
+ }
+@@ -1099,6 +1104,7 @@ static int dgram_sctp_read(BIO *b, char *out, int
+ dgram_sctp_write(data->saved_message.bio, data->saved_message.data,
+ data->saved_message.length);
+ OPENSSL_free(data->saved_message.data);
++ data->saved_message.data = NULL;
+ data->saved_message.length = 0;
+ }
+
+@@ -1258,9 +1264,11 @@ static int dgram_sctp_write(BIO *b, const char *in
+ if (data->save_shutdown && !BIO_dgram_sctp_wait_for_dry(b))
+ {
+ data->saved_message.bio = b;
+- data->saved_message.length = inl;
++ if (data->saved_message.data)
++ OPENSSL_free(data->saved_message.data);
+ data->saved_message.data = OPENSSL_malloc(inl);
+ memcpy(data->saved_message.data, in, inl);
++ data->saved_message.length = inl;
+ return inl;
+ }
+
+Index: crypto/openssl/crypto/bn/asm/mips.pl
+===================================================================
+--- crypto/openssl/crypto/bn/asm/mips.pl (revision 276867)
++++ crypto/openssl/crypto/bn/asm/mips.pl (working copy)
+@@ -1874,8 +1874,43 @@ ___
+
+ ($a_4,$a_5,$a_6,$a_7)=($b_0,$b_1,$b_2,$b_3);
+
++sub add_c2 () {
++my ($hi,$lo,$c0,$c1,$c2,
++ $warm, # !$warm denotes first call with specific sequence of
++ # $c_[XYZ] when there is no Z-carry to accumulate yet;
++ $an,$bn # these two are arguments for multiplication which
++ # result is used in *next* step [which is why it's
++ # commented as "forward multiplication" below];
++ )=@_;
+ $code.=<<___;
++ mflo $lo
++ mfhi $hi
++ $ADDU $c0,$lo
++ sltu $at,$c0,$lo
++ $MULTU $an,$bn # forward multiplication
++ $ADDU $c0,$lo
++ $ADDU $at,$hi
++ sltu $lo,$c0,$lo
++ $ADDU $c1,$at
++ $ADDU $hi,$lo
++___
++$code.=<<___ if (!$warm);
++ sltu $c2,$c1,$at
++ $ADDU $c1,$hi
++ sltu $hi,$c1,$hi
++ $ADDU $c2,$hi
++___
++$code.=<<___ if ($warm);
++ sltu $at,$c1,$at
++ $ADDU $c1,$hi
++ $ADDU $c2,$at
++ sltu $hi,$c1,$hi
++ $ADDU $c2,$hi
++___
++}
+
++$code.=<<___;
++
+ .align 5
+ .globl bn_sqr_comba8
+ .ent bn_sqr_comba8
+@@ -1922,25 +1957,14 @@ $code.=<<___;
+ sltu $at,$c_2,$t_1
+ $ADDU $c_3,$t_2,$at
+ $ST $c_2,$BNSZ($a0)
+-
++___
++ &add_c2($t_2,$t_1,$c_3,$c_1,$c_2,0,
++ $a_1,$a_1); # mul_add_c(a[1],b[1],c3,c1,c2);
++$code.=<<___;
+ mflo $t_1
+ mfhi $t_2
+- slt $c_2,$t_2,$zero
+- $SLL $t_2,1
+- $MULTU $a_1,$a_1 # mul_add_c(a[1],b[1],c3,c1,c2);
+- slt $a2,$t_1,$zero
+- $ADDU $t_2,$a2
+- $SLL $t_1,1
+ $ADDU $c_3,$t_1
+ sltu $at,$c_3,$t_1
+- $ADDU $t_2,$at
+- $ADDU $c_1,$t_2
+- sltu $at,$c_1,$t_2
+- $ADDU $c_2,$at
+- mflo $t_1
+- mfhi $t_2
+- $ADDU $c_3,$t_1
+- sltu $at,$c_3,$t_1
+ $MULTU $a_0,$a_3 # mul_add_c2(a[0],b[3],c1,c2,c3);
+ $ADDU $t_2,$at
+ $ADDU $c_1,$t_2
+@@ -1947,71 +1971,23 @@ $code.=<<___;
+ sltu $at,$c_1,$t_2
+ $ADDU $c_2,$at
+ $ST $c_3,2*$BNSZ($a0)
+-
+- mflo $t_1
+- mfhi $t_2
+- slt $c_3,$t_2,$zero
+- $SLL $t_2,1
+- $MULTU $a_1,$a_2 # mul_add_c2(a[1],b[2],c1,c2,c3);
+- slt $a2,$t_1,$zero
+- $ADDU $t_2,$a2
+- $SLL $t_1,1
+- $ADDU $c_1,$t_1
+- sltu $at,$c_1,$t_1
+- $ADDU $t_2,$at
+- $ADDU $c_2,$t_2
+- sltu $at,$c_2,$t_2
+- $ADDU $c_3,$at
+- mflo $t_1
+- mfhi $t_2
+- slt $at,$t_2,$zero
+- $ADDU $c_3,$at
+- $MULTU $a_4,$a_0 # mul_add_c2(a[4],b[0],c2,c3,c1);
+- $SLL $t_2,1
+- slt $a2,$t_1,$zero
+- $ADDU $t_2,$a2
+- $SLL $t_1,1
+- $ADDU $c_1,$t_1
+- sltu $at,$c_1,$t_1
+- $ADDU $t_2,$at
+- $ADDU $c_2,$t_2
+- sltu $at,$c_2,$t_2
+- $ADDU $c_3,$at
++___
++ &add_c2($t_2,$t_1,$c_1,$c_2,$c_3,0,
++ $a_1,$a_2); # mul_add_c2(a[1],b[2],c1,c2,c3);
++ &add_c2($t_2,$t_1,$c_1,$c_2,$c_3,1,
++ $a_4,$a_0); # mul_add_c2(a[4],b[0],c2,c3,c1);
++$code.=<<___;
+ $ST $c_1,3*$BNSZ($a0)
+-
++___
++ &add_c2($t_2,$t_1,$c_2,$c_3,$c_1,0,
++ $a_3,$a_1); # mul_add_c2(a[3],b[1],c2,c3,c1);
++ &add_c2($t_2,$t_1,$c_2,$c_3,$c_1,1,
++ $a_2,$a_2); # mul_add_c(a[2],b[2],c2,c3,c1);
++$code.=<<___;
+ mflo $t_1
+ mfhi $t_2
+- slt $c_1,$t_2,$zero
+- $SLL $t_2,1
+- $MULTU $a_3,$a_1 # mul_add_c2(a[3],b[1],c2,c3,c1);
+- slt $a2,$t_1,$zero
+- $ADDU $t_2,$a2
+- $SLL $t_1,1
+ $ADDU $c_2,$t_1
+ sltu $at,$c_2,$t_1
+- $ADDU $t_2,$at
+- $ADDU $c_3,$t_2
+- sltu $at,$c_3,$t_2
+- $ADDU $c_1,$at
+- mflo $t_1
+- mfhi $t_2
+- slt $at,$t_2,$zero
+- $ADDU $c_1,$at
+- $MULTU $a_2,$a_2 # mul_add_c(a[2],b[2],c2,c3,c1);
+- $SLL $t_2,1
+- slt $a2,$t_1,$zero
+- $ADDU $t_2,$a2
+- $SLL $t_1,1
+- $ADDU $c_2,$t_1
+- sltu $at,$c_2,$t_1
+- $ADDU $t_2,$at
+- $ADDU $c_3,$t_2
+- sltu $at,$c_3,$t_2
+- $ADDU $c_1,$at
+- mflo $t_1
+- mfhi $t_2
+- $ADDU $c_2,$t_1
+- sltu $at,$c_2,$t_1
+ $MULTU $a_0,$a_5 # mul_add_c2(a[0],b[5],c3,c1,c2);
+ $ADDU $t_2,$at
+ $ADDU $c_3,$t_2
+@@ -2018,101 +1994,27 @@ $code.=<<___;
+ sltu $at,$c_3,$t_2
+ $ADDU $c_1,$at
+ $ST $c_2,4*$BNSZ($a0)
+-
+- mflo $t_1
+- mfhi $t_2
+- slt $c_2,$t_2,$zero
+- $SLL $t_2,1
+- $MULTU $a_1,$a_4 # mul_add_c2(a[1],b[4],c3,c1,c2);
+- slt $a2,$t_1,$zero
+- $ADDU $t_2,$a2
+- $SLL $t_1,1
+- $ADDU $c_3,$t_1
+- sltu $at,$c_3,$t_1
+- $ADDU $t_2,$at
+- $ADDU $c_1,$t_2
+- sltu $at,$c_1,$t_2
+- $ADDU $c_2,$at
+- mflo $t_1
+- mfhi $t_2
+- slt $at,$t_2,$zero
+- $ADDU $c_2,$at
+- $MULTU $a_2,$a_3 # mul_add_c2(a[2],b[3],c3,c1,c2);
+- $SLL $t_2,1
+- slt $a2,$t_1,$zero
+- $ADDU $t_2,$a2
+- $SLL $t_1,1
+- $ADDU $c_3,$t_1
+- sltu $at,$c_3,$t_1
+- $ADDU $t_2,$at
+- $ADDU $c_1,$t_2
+- sltu $at,$c_1,$t_2
+- $ADDU $c_2,$at
+- mflo $t_1
+- mfhi $t_2
+- slt $at,$t_2,$zero
+- $MULTU $a_6,$a_0 # mul_add_c2(a[6],b[0],c1,c2,c3);
+- $ADDU $c_2,$at
+- $SLL $t_2,1
+- slt $a2,$t_1,$zero
+- $ADDU $t_2,$a2
+- $SLL $t_1,1
+- $ADDU $c_3,$t_1
+- sltu $at,$c_3,$t_1
+- $ADDU $t_2,$at
+- $ADDU $c_1,$t_2
+- sltu $at,$c_1,$t_2
+- $ADDU $c_2,$at
++___
++ &add_c2($t_2,$t_1,$c_3,$c_1,$c_2,0,
++ $a_1,$a_4); # mul_add_c2(a[1],b[4],c3,c1,c2);
++ &add_c2($t_2,$t_1,$c_3,$c_1,$c_2,1,
++ $a_2,$a_3); # mul_add_c2(a[2],b[3],c3,c1,c2);
++ &add_c2($t_2,$t_1,$c_3,$c_1,$c_2,1,
++ $a_6,$a_0); # mul_add_c2(a[6],b[0],c1,c2,c3);
++$code.=<<___;
+ $ST $c_3,5*$BNSZ($a0)
+-
++___
++ &add_c2($t_2,$t_1,$c_1,$c_2,$c_3,0,
++ $a_5,$a_1); # mul_add_c2(a[5],b[1],c1,c2,c3);
++ &add_c2($t_2,$t_1,$c_1,$c_2,$c_3,1,
++ $a_4,$a_2); # mul_add_c2(a[4],b[2],c1,c2,c3);
++ &add_c2($t_2,$t_1,$c_1,$c_2,$c_3,1,
++ $a_3,$a_3); # mul_add_c(a[3],b[3],c1,c2,c3);
++$code.=<<___;
+ mflo $t_1
+ mfhi $t_2
+- slt $c_3,$t_2,$zero
+- $SLL $t_2,1
+- $MULTU $a_5,$a_1 # mul_add_c2(a[5],b[1],c1,c2,c3);
+- slt $a2,$t_1,$zero
+- $ADDU $t_2,$a2
+- $SLL $t_1,1
+ $ADDU $c_1,$t_1
+ sltu $at,$c_1,$t_1
+- $ADDU $t_2,$at
+- $ADDU $c_2,$t_2
+- sltu $at,$c_2,$t_2
+- $ADDU $c_3,$at
+- mflo $t_1
+- mfhi $t_2
+- slt $at,$t_2,$zero
+- $ADDU $c_3,$at
+- $MULTU $a_4,$a_2 # mul_add_c2(a[4],b[2],c1,c2,c3);
+- $SLL $t_2,1
+- slt $a2,$t_1,$zero
+- $ADDU $t_2,$a2
+- $SLL $t_1,1
+- $ADDU $c_1,$t_1
+- sltu $at,$c_1,$t_1
+- $ADDU $t_2,$at
+- $ADDU $c_2,$t_2
+- sltu $at,$c_2,$t_2
+- $ADDU $c_3,$at
+- mflo $t_1
+- mfhi $t_2
+- slt $at,$t_2,$zero
+- $ADDU $c_3,$at
+- $MULTU $a_3,$a_3 # mul_add_c(a[3],b[3],c1,c2,c3);
+- $SLL $t_2,1
+- slt $a2,$t_1,$zero
+- $ADDU $t_2,$a2
+- $SLL $t_1,1
+- $ADDU $c_1,$t_1
+- sltu $at,$c_1,$t_1
+- $ADDU $t_2,$at
+- $ADDU $c_2,$t_2
+- sltu $at,$c_2,$t_2
+- $ADDU $c_3,$at
+- mflo $t_1
+- mfhi $t_2
+- $ADDU $c_1,$t_1
+- sltu $at,$c_1,$t_1
+ $MULTU $a_0,$a_7 # mul_add_c2(a[0],b[7],c2,c3,c1);
+ $ADDU $t_2,$at
+ $ADDU $c_2,$t_2
+@@ -2119,116 +2021,29 @@ $code.=<<___;
+ sltu $at,$c_2,$t_2
+ $ADDU $c_3,$at
+ $ST $c_1,6*$BNSZ($a0)
+-
+- mflo $t_1
+- mfhi $t_2
+- slt $c_1,$t_2,$zero
+- $SLL $t_2,1
+- $MULTU $a_1,$a_6 # mul_add_c2(a[1],b[6],c2,c3,c1);
+- slt $a2,$t_1,$zero
+- $ADDU $t_2,$a2
+- $SLL $t_1,1
+- $ADDU $c_2,$t_1
+- sltu $at,$c_2,$t_1
+- $ADDU $t_2,$at
+- $ADDU $c_3,$t_2
+- sltu $at,$c_3,$t_2
+- $ADDU $c_1,$at
+- mflo $t_1
+- mfhi $t_2
+- slt $at,$t_2,$zero
+- $ADDU $c_1,$at
+- $MULTU $a_2,$a_5 # mul_add_c2(a[2],b[5],c2,c3,c1);
+- $SLL $t_2,1
+- slt $a2,$t_1,$zero
+- $ADDU $t_2,$a2
+- $SLL $t_1,1
+- $ADDU $c_2,$t_1
+- sltu $at,$c_2,$t_1
+- $ADDU $t_2,$at
+- $ADDU $c_3,$t_2
+- sltu $at,$c_3,$t_2
+- $ADDU $c_1,$at
+- mflo $t_1
+- mfhi $t_2
+- slt $at,$t_2,$zero
+- $ADDU $c_1,$at
+- $MULTU $a_3,$a_4 # mul_add_c2(a[3],b[4],c2,c3,c1);
+- $SLL $t_2,1
+- slt $a2,$t_1,$zero
+- $ADDU $t_2,$a2
+- $SLL $t_1,1
+- $ADDU $c_2,$t_1
+- sltu $at,$c_2,$t_1
+- $ADDU $t_2,$at
+- $ADDU $c_3,$t_2
+- sltu $at,$c_3,$t_2
+- $ADDU $c_1,$at
+- mflo $t_1
+- mfhi $t_2
+- slt $at,$t_2,$zero
+- $ADDU $c_1,$at
+- $MULTU $a_7,$a_1 # mul_add_c2(a[7],b[1],c3,c1,c2);
+- $SLL $t_2,1
+- slt $a2,$t_1,$zero
+- $ADDU $t_2,$a2
+- $SLL $t_1,1
+- $ADDU $c_2,$t_1
+- sltu $at,$c_2,$t_1
+- $ADDU $t_2,$at
+- $ADDU $c_3,$t_2
+- sltu $at,$c_3,$t_2
+- $ADDU $c_1,$at
++___
++ &add_c2($t_2,$t_1,$c_2,$c_3,$c_1,0,
++ $a_1,$a_6); # mul_add_c2(a[1],b[6],c2,c3,c1);
++ &add_c2($t_2,$t_1,$c_2,$c_3,$c_1,1,
++ $a_2,$a_5); # mul_add_c2(a[2],b[5],c2,c3,c1);
++ &add_c2($t_2,$t_1,$c_2,$c_3,$c_1,1,
++ $a_3,$a_4); # mul_add_c2(a[3],b[4],c2,c3,c1);
++ &add_c2($t_2,$t_1,$c_2,$c_3,$c_1,1,
++ $a_7,$a_1); # mul_add_c2(a[7],b[1],c3,c1,c2);
++$code.=<<___;
+ $ST $c_2,7*$BNSZ($a0)
+-
++___
++ &add_c2($t_2,$t_1,$c_3,$c_1,$c_2,0,
++ $a_6,$a_2); # mul_add_c2(a[6],b[2],c3,c1,c2);
++ &add_c2($t_2,$t_1,$c_3,$c_1,$c_2,1,
++ $a_5,$a_3); # mul_add_c2(a[5],b[3],c3,c1,c2);
++ &add_c2($t_2,$t_1,$c_3,$c_1,$c_2,1,
++ $a_4,$a_4); # mul_add_c(a[4],b[4],c3,c1,c2);
++$code.=<<___;
+ mflo $t_1
+ mfhi $t_2
+- slt $c_2,$t_2,$zero
+- $SLL $t_2,1
+- $MULTU $a_6,$a_2 # mul_add_c2(a[6],b[2],c3,c1,c2);
+- slt $a2,$t_1,$zero
+- $ADDU $t_2,$a2
+- $SLL $t_1,1
+ $ADDU $c_3,$t_1
+ sltu $at,$c_3,$t_1
+- $ADDU $t_2,$at
+- $ADDU $c_1,$t_2
+- sltu $at,$c_1,$t_2
+- $ADDU $c_2,$at
+- mflo $t_1
+- mfhi $t_2
+- slt $at,$t_2,$zero
+- $ADDU $c_2,$at
+- $MULTU $a_5,$a_3 # mul_add_c2(a[5],b[3],c3,c1,c2);
+- $SLL $t_2,1
+- slt $a2,$t_1,$zero
+- $ADDU $t_2,$a2
+- $SLL $t_1,1
+- $ADDU $c_3,$t_1
+- sltu $at,$c_3,$t_1
+- $ADDU $t_2,$at
+- $ADDU $c_1,$t_2
+- sltu $at,$c_1,$t_2
+- $ADDU $c_2,$at
+- mflo $t_1
+- mfhi $t_2
+- slt $at,$t_2,$zero
+- $ADDU $c_2,$at
+- $MULTU $a_4,$a_4 # mul_add_c(a[4],b[4],c3,c1,c2);
+- $SLL $t_2,1
+- slt $a2,$t_1,$zero
+- $ADDU $t_2,$a2
+- $SLL $t_1,1
+- $ADDU $c_3,$t_1
+- sltu $at,$c_3,$t_1
+- $ADDU $t_2,$at
+- $ADDU $c_1,$t_2
+- sltu $at,$c_1,$t_2
+- $ADDU $c_2,$at
+- mflo $t_1
+- mfhi $t_2
+- $ADDU $c_3,$t_1
+- sltu $at,$c_3,$t_1
+ $MULTU $a_2,$a_7 # mul_add_c2(a[2],b[7],c1,c2,c3);
+ $ADDU $t_2,$at
+ $ADDU $c_1,$t_2
+@@ -2235,86 +2050,25 @@ $code.=<<___;
+ sltu $at,$c_1,$t_2
+ $ADDU $c_2,$at
+ $ST $c_3,8*$BNSZ($a0)
+-
+- mflo $t_1
+- mfhi $t_2
+- slt $c_3,$t_2,$zero
+- $SLL $t_2,1
+- $MULTU $a_3,$a_6 # mul_add_c2(a[3],b[6],c1,c2,c3);
+- slt $a2,$t_1,$zero
+- $ADDU $t_2,$a2
+- $SLL $t_1,1
+- $ADDU $c_1,$t_1
+- sltu $at,$c_1,$t_1
+- $ADDU $t_2,$at
+- $ADDU $c_2,$t_2
+- sltu $at,$c_2,$t_2
+- $ADDU $c_3,$at
+- mflo $t_1
+- mfhi $t_2
+- slt $at,$t_2,$zero
+- $ADDU $c_3,$at
+- $MULTU $a_4,$a_5 # mul_add_c2(a[4],b[5],c1,c2,c3);
+- $SLL $t_2,1
+- slt $a2,$t_1,$zero
+- $ADDU $t_2,$a2
+- $SLL $t_1,1
+- $ADDU $c_1,$t_1
+- sltu $at,$c_1,$t_1
+- $ADDU $t_2,$at
+- $ADDU $c_2,$t_2
+- sltu $at,$c_2,$t_2
+- $ADDU $c_3,$at
+- mflo $t_1
+- mfhi $t_2
+- slt $at,$t_2,$zero
+- $ADDU $c_3,$at
+- $MULTU $a_7,$a_3 # mul_add_c2(a[7],b[3],c2,c3,c1);
+- $SLL $t_2,1
+- slt $a2,$t_1,$zero
+- $ADDU $t_2,$a2
+- $SLL $t_1,1
+- $ADDU $c_1,$t_1
+- sltu $at,$c_1,$t_1
+- $ADDU $t_2,$at
+- $ADDU $c_2,$t_2
+- sltu $at,$c_2,$t_2
+- $ADDU $c_3,$at
++___
++ &add_c2($t_2,$t_1,$c_1,$c_2,$c_3,0,
++ $a_3,$a_6); # mul_add_c2(a[3],b[6],c1,c2,c3);
++ &add_c2($t_2,$t_1,$c_1,$c_2,$c_3,1,
++ $a_4,$a_5); # mul_add_c2(a[4],b[5],c1,c2,c3);
++ &add_c2($t_2,$t_1,$c_1,$c_2,$c_3,1,
++ $a_7,$a_3); # mul_add_c2(a[7],b[3],c2,c3,c1);
++$code.=<<___;
+ $ST $c_1,9*$BNSZ($a0)
+-
++___
++ &add_c2($t_2,$t_1,$c_2,$c_3,$c_1,0,
++ $a_6,$a_4); # mul_add_c2(a[6],b[4],c2,c3,c1);
++ &add_c2($t_2,$t_1,$c_2,$c_3,$c_1,1,
++ $a_5,$a_5); # mul_add_c(a[5],b[5],c2,c3,c1);
++$code.=<<___;
+ mflo $t_1
+ mfhi $t_2
+- slt $c_1,$t_2,$zero
+- $SLL $t_2,1
+- $MULTU $a_6,$a_4 # mul_add_c2(a[6],b[4],c2,c3,c1);
+- slt $a2,$t_1,$zero
+- $ADDU $t_2,$a2
+- $SLL $t_1,1
+ $ADDU $c_2,$t_1
+ sltu $at,$c_2,$t_1
+- $ADDU $t_2,$at
+- $ADDU $c_3,$t_2
+- sltu $at,$c_3,$t_2
+- $ADDU $c_1,$at
+- mflo $t_1
+- mfhi $t_2
+- slt $at,$t_2,$zero
+- $ADDU $c_1,$at
+- $MULTU $a_5,$a_5 # mul_add_c(a[5],b[5],c2,c3,c1);
+- $SLL $t_2,1
+- slt $a2,$t_1,$zero
+- $ADDU $t_2,$a2
+- $SLL $t_1,1
+- $ADDU $c_2,$t_1
+- sltu $at,$c_2,$t_1
+- $ADDU $t_2,$at
+- $ADDU $c_3,$t_2
+- sltu $at,$c_3,$t_2
+- $ADDU $c_1,$at
+- mflo $t_1
+- mfhi $t_2
+- $ADDU $c_2,$t_1
+- sltu $at,$c_2,$t_1
+ $MULTU $a_4,$a_7 # mul_add_c2(a[4],b[7],c3,c1,c2);
+ $ADDU $t_2,$at
+ $ADDU $c_3,$t_2
+@@ -2321,56 +2075,21 @@ $code.=<<___;
+ sltu $at,$c_3,$t_2
+ $ADDU $c_1,$at
+ $ST $c_2,10*$BNSZ($a0)
+-
+- mflo $t_1
+- mfhi $t_2
+- slt $c_2,$t_2,$zero
+- $SLL $t_2,1
+- $MULTU $a_5,$a_6 # mul_add_c2(a[5],b[6],c3,c1,c2);
+- slt $a2,$t_1,$zero
+- $ADDU $t_2,$a2
+- $SLL $t_1,1
+- $ADDU $c_3,$t_1
+- sltu $at,$c_3,$t_1
+- $ADDU $t_2,$at
+- $ADDU $c_1,$t_2
+- sltu $at,$c_1,$t_2
+- $ADDU $c_2,$at
+- mflo $t_1
+- mfhi $t_2
+- slt $at,$t_2,$zero
+- $ADDU $c_2,$at
+- $MULTU $a_7,$a_5 # mul_add_c2(a[7],b[5],c1,c2,c3);
+- $SLL $t_2,1
+- slt $a2,$t_1,$zero
+- $ADDU $t_2,$a2
+- $SLL $t_1,1
+- $ADDU $c_3,$t_1
+- sltu $at,$c_3,$t_1
+- $ADDU $t_2,$at
+- $ADDU $c_1,$t_2
+- sltu $at,$c_1,$t_2
+- $ADDU $c_2,$at
++___
++ &add_c2($t_2,$t_1,$c_3,$c_1,$c_2,0,
++ $a_5,$a_6); # mul_add_c2(a[5],b[6],c3,c1,c2);
++ &add_c2($t_2,$t_1,$c_3,$c_1,$c_2,1,
++ $a_7,$a_5); # mul_add_c2(a[7],b[5],c1,c2,c3);
++$code.=<<___;
+ $ST $c_3,11*$BNSZ($a0)
+-
++___
++ &add_c2($t_2,$t_1,$c_1,$c_2,$c_3,0,
++ $a_6,$a_6); # mul_add_c(a[6],b[6],c1,c2,c3);
++$code.=<<___;
+ mflo $t_1
+ mfhi $t_2
+- slt $c_3,$t_2,$zero
+- $SLL $t_2,1
+- $MULTU $a_6,$a_6 # mul_add_c(a[6],b[6],c1,c2,c3);
+- slt $a2,$t_1,$zero
+- $ADDU $t_2,$a2
+- $SLL $t_1,1
+ $ADDU $c_1,$t_1
+ sltu $at,$c_1,$t_1
+- $ADDU $t_2,$at
+- $ADDU $c_2,$t_2
+- sltu $at,$c_2,$t_2
+- $ADDU $c_3,$at
+- mflo $t_1
+- mfhi $t_2
+- $ADDU $c_1,$t_1
+- sltu $at,$c_1,$t_1
+ $MULTU $a_6,$a_7 # mul_add_c2(a[6],b[7],c2,c3,c1);
+ $ADDU $t_2,$at
+ $ADDU $c_2,$t_2
+@@ -2377,21 +2096,10 @@ $code.=<<___;
+ sltu $at,$c_2,$t_2
+ $ADDU $c_3,$at
+ $ST $c_1,12*$BNSZ($a0)
+-
+- mflo $t_1
+- mfhi $t_2
+- slt $c_1,$t_2,$zero
+- $SLL $t_2,1
+- $MULTU $a_7,$a_7 # mul_add_c(a[7],b[7],c3,c1,c2);
+- slt $a2,$t_1,$zero
+- $ADDU $t_2,$a2
+- $SLL $t_1,1
+- $ADDU $c_2,$t_1
+- sltu $at,$c_2,$t_1
+- $ADDU $t_2,$at
+- $ADDU $c_3,$t_2
+- sltu $at,$c_3,$t_2
+- $ADDU $c_1,$at
++___
++ &add_c2($t_2,$t_1,$c_2,$c_3,$c_1,0,
++ $a_7,$a_7); # mul_add_c(a[7],b[7],c3,c1,c2);
++$code.=<<___;
+ $ST $c_2,13*$BNSZ($a0)
+
+ mflo $t_1
+@@ -2459,25 +2167,14 @@ $code.=<<___;
+ sltu $at,$c_2,$t_1
+ $ADDU $c_3,$t_2,$at
+ $ST $c_2,$BNSZ($a0)
+-
++___
++ &add_c2($t_2,$t_1,$c_3,$c_1,$c_2,0,
++ $a_1,$a_1); # mul_add_c(a[1],b[1],c3,c1,c2);
++$code.=<<___;
+ mflo $t_1
+ mfhi $t_2
+- slt $c_2,$t_2,$zero
+- $SLL $t_2,1
+- $MULTU $a_1,$a_1 # mul_add_c(a[1],b[1],c3,c1,c2);
+- slt $a2,$t_1,$zero
+- $ADDU $t_2,$a2
+- $SLL $t_1,1
+ $ADDU $c_3,$t_1
+ sltu $at,$c_3,$t_1
+- $ADDU $t_2,$at
+- $ADDU $c_1,$t_2
+- sltu $at,$c_1,$t_2
+- $ADDU $c_2,$at
+- mflo $t_1
+- mfhi $t_2
+- $ADDU $c_3,$t_1
+- sltu $at,$c_3,$t_1
+ $MULTU $a_0,$a_3 # mul_add_c2(a[0],b[3],c1,c2,c3);
+ $ADDU $t_2,$at
+ $ADDU $c_1,$t_2
+@@ -2484,56 +2181,21 @@ $code.=<<___;
+ sltu $at,$c_1,$t_2
+ $ADDU $c_2,$at
+ $ST $c_3,2*$BNSZ($a0)
+-
+- mflo $t_1
+- mfhi $t_2
+- slt $c_3,$t_2,$zero
+- $SLL $t_2,1
+- $MULTU $a_1,$a_2 # mul_add_c(a2[1],b[2],c1,c2,c3);
+- slt $a2,$t_1,$zero
+- $ADDU $t_2,$a2
+- $SLL $t_1,1
+- $ADDU $c_1,$t_1
+- sltu $at,$c_1,$t_1
+- $ADDU $t_2,$at
+- $ADDU $c_2,$t_2
+- sltu $at,$c_2,$t_2
+- $ADDU $c_3,$at
+- mflo $t_1
+- mfhi $t_2
+- slt $at,$t_2,$zero
+- $ADDU $c_3,$at
+- $MULTU $a_3,$a_1 # mul_add_c2(a[3],b[1],c2,c3,c1);
+- $SLL $t_2,1
+- slt $a2,$t_1,$zero
+- $ADDU $t_2,$a2
+- $SLL $t_1,1
+- $ADDU $c_1,$t_1
+- sltu $at,$c_1,$t_1
+- $ADDU $t_2,$at
+- $ADDU $c_2,$t_2
+- sltu $at,$c_2,$t_2
+- $ADDU $c_3,$at
++___
++ &add_c2($t_2,$t_1,$c_1,$c_2,$c_3,0,
++ $a_1,$a_2); # mul_add_c2(a2[1],b[2],c1,c2,c3);
++ &add_c2($t_2,$t_1,$c_1,$c_2,$c_3,1,
++ $a_3,$a_1); # mul_add_c2(a[3],b[1],c2,c3,c1);
++$code.=<<___;
+ $ST $c_1,3*$BNSZ($a0)
+-
++___
++ &add_c2($t_2,$t_1,$c_2,$c_3,$c_1,0,
++ $a_2,$a_2); # mul_add_c(a[2],b[2],c2,c3,c1);
++$code.=<<___;
+ mflo $t_1
+ mfhi $t_2
+- slt $c_1,$t_2,$zero
+- $SLL $t_2,1
+- $MULTU $a_2,$a_2 # mul_add_c(a[2],b[2],c2,c3,c1);
+- slt $a2,$t_1,$zero
+- $ADDU $t_2,$a2
+- $SLL $t_1,1
+ $ADDU $c_2,$t_1
+ sltu $at,$c_2,$t_1
+- $ADDU $t_2,$at
+- $ADDU $c_3,$t_2
+- sltu $at,$c_3,$t_2
+- $ADDU $c_1,$at
+- mflo $t_1
+- mfhi $t_2
+- $ADDU $c_2,$t_1
+- sltu $at,$c_2,$t_1
+ $MULTU $a_2,$a_3 # mul_add_c2(a[2],b[3],c3,c1,c2);
+ $ADDU $t_2,$at
+ $ADDU $c_3,$t_2
+@@ -2540,21 +2202,10 @@ $code.=<<___;
+ sltu $at,$c_3,$t_2
+ $ADDU $c_1,$at
+ $ST $c_2,4*$BNSZ($a0)
+-
+- mflo $t_1
+- mfhi $t_2
+- slt $c_2,$t_2,$zero
+- $SLL $t_2,1
+- $MULTU $a_3,$a_3 # mul_add_c(a[3],b[3],c1,c2,c3);
+- slt $a2,$t_1,$zero
+- $ADDU $t_2,$a2
+- $SLL $t_1,1
+- $ADDU $c_3,$t_1
+- sltu $at,$c_3,$t_1
+- $ADDU $t_2,$at
+- $ADDU $c_1,$t_2
+- sltu $at,$c_1,$t_2
+- $ADDU $c_2,$at
++___
++ &add_c2($t_2,$t_1,$c_3,$c_1,$c_2,0,
++ $a_3,$a_3); # mul_add_c(a[3],b[3],c1,c2,c3);
++$code.=<<___;
+ $ST $c_3,5*$BNSZ($a0)
+
+ mflo $t_1
+Index: crypto/openssl/crypto/bn/asm/x86_64-gcc.c
+===================================================================
+--- crypto/openssl/crypto/bn/asm/x86_64-gcc.c (revision 276867)
++++ crypto/openssl/crypto/bn/asm/x86_64-gcc.c (working copy)
+@@ -273,6 +273,10 @@ BN_ULONG bn_sub_words(BN_ULONG *r, BN_ULONG *a, BN
+ /* sqr_add_c(a,i,c0,c1,c2) -- c+=a[i]^2 for three word number c=(c2,c1,c0) */
+ /* sqr_add_c2(a,i,c0,c1,c2) -- c+=2*a[i]*a[j] for three word number c=(c2,c1,c0) */
+
++/*
++ * Keep in mind that carrying into high part of multiplication result
++ * can not overflow, because it cannot be all-ones.
++ */
+ #if 0
+ /* original macros are kept for reference purposes */
+ #define mul_add_c(a,b,c0,c1,c2) { \
+@@ -287,10 +291,10 @@ BN_ULONG bn_sub_words(BN_ULONG *r, BN_ULONG *a, BN
+ BN_ULONG ta=(a),tb=(b),t0; \
+ t1 = BN_UMULT_HIGH(ta,tb); \
+ t0 = ta * tb; \
+- t2 = t1+t1; c2 += (t2neg=rand_neg();
++ BN_sqr(c,a,ctx);
+ if (bp != NULL)
+ {
+ if (!results)
+ {
+- BN_print(bp,&a);
++ BN_print(bp,a);
+ BIO_puts(bp," * ");
+- BN_print(bp,&a);
++ BN_print(bp,a);
+ BIO_puts(bp," - ");
+ }
+- BN_print(bp,&c);
++ BN_print(bp,c);
+ BIO_puts(bp,"\n");
+ }
+- BN_div(&d,&e,&c,&a,ctx);
+- BN_sub(&d,&d,&a);
+- if(!BN_is_zero(&d) || !BN_is_zero(&e))
+- {
+- fprintf(stderr,"Square test failed!\n");
+- return 0;
+- }
++ BN_div(d,e,c,a,ctx);
++ BN_sub(d,d,a);
++ if(!BN_is_zero(d) || !BN_is_zero(e))
++ {
++ fprintf(stderr,"Square test failed!\n");
++ goto err;
++ }
+ }
+- BN_free(&a);
+- BN_free(&c);
+- BN_free(&d);
+- BN_free(&e);
+- return(1);
++
++ /* Regression test for a BN_sqr overflow bug. */
++ BN_hex2bn(&a,
++ "80000000000000008000000000000001FFFFFFFFFFFFFFFE0000000000000000");
++ BN_sqr(c, a, ctx);
++ if (bp != NULL)
++ {
++ if (!results)
++ {
++ BN_print(bp,a);
++ BIO_puts(bp," * ");
++ BN_print(bp,a);
++ BIO_puts(bp," - ");
++ }
++ BN_print(bp,c);
++ BIO_puts(bp,"\n");
++ }
++ BN_mul(d, a, a, ctx);
++ if (BN_cmp(c, d))
++ {
++ fprintf(stderr, "Square test failed: BN_sqr and BN_mul produce "
++ "different results!\n");
++ goto err;
++ }
++
++ /* Regression test for a BN_sqr overflow bug. */
++ BN_hex2bn(&a,
++ "80000000000000000000000080000001FFFFFFFE000000000000000000000000");
++ BN_sqr(c, a, ctx);
++ if (bp != NULL)
++ {
++ if (!results)
++ {
++ BN_print(bp,a);
++ BIO_puts(bp," * ");
++ BN_print(bp,a);
++ BIO_puts(bp," - ");
++ }
++ BN_print(bp,c);
++ BIO_puts(bp,"\n");
++ }
++ BN_mul(d, a, a, ctx);
++ if (BN_cmp(c, d))
++ {
++ fprintf(stderr, "Square test failed: BN_sqr and BN_mul produce "
++ "different results!\n");
++ goto err;
++ }
++ ret = 1;
++err:
++ if (a != NULL) BN_free(a);
++ if (c != NULL) BN_free(c);
++ if (d != NULL) BN_free(d);
++ if (e != NULL) BN_free(e);
++ return ret;
+ }
+
+ int test_mont(BIO *bp, BN_CTX *ctx)
+Index: crypto/openssl/crypto/dsa/dsa_asn1.c
+===================================================================
+--- crypto/openssl/crypto/dsa/dsa_asn1.c (revision 276867)
++++ crypto/openssl/crypto/dsa/dsa_asn1.c (working copy)
+@@ -176,13 +176,25 @@ int DSA_verify(int type, const unsigned char *dgst
+ const unsigned char *sigbuf, int siglen, DSA *dsa)
+ {
+ DSA_SIG *s;
++ const unsigned char *p = sigbuf;
++ unsigned char *der = NULL;
++ int derlen = -1;
+ int ret=-1;
+
+ s = DSA_SIG_new();
+ if (s == NULL) return(ret);
+- if (d2i_DSA_SIG(&s,&sigbuf,siglen) == NULL) goto err;
++ if (d2i_DSA_SIG(&s,&p,siglen) == NULL) goto err;
++ /* Ensure signature uses DER and doesn't have trailing garbage */
++ derlen = i2d_DSA_SIG(s, &der);
++ if (derlen != siglen || memcmp(sigbuf, der, derlen))
++ goto err;
+ ret=DSA_do_verify(dgst,dgst_len,s,dsa);
+ err:
++ if (derlen > 0)
++ {
++ OPENSSL_cleanse(der, derlen);
++ OPENSSL_free(der);
++ }
+ DSA_SIG_free(s);
+ return(ret);
+ }
+Index: crypto/openssl/crypto/ecdsa/ecs_vrf.c
+===================================================================
+--- crypto/openssl/crypto/ecdsa/ecs_vrf.c (revision 276867)
++++ crypto/openssl/crypto/ecdsa/ecs_vrf.c (working copy)
+@@ -57,6 +57,7 @@
+ */
+
+ #include "ecs_locl.h"
++#include "cryptlib.h"
+ #ifndef OPENSSL_NO_ENGINE
+ #include
+ #endif
+@@ -84,13 +85,25 @@ int ECDSA_verify(int type, const unsigned char *dg
+ const unsigned char *sigbuf, int sig_len, EC_KEY *eckey)
+ {
+ ECDSA_SIG *s;
++ const unsigned char *p = sigbuf;
++ unsigned char *der = NULL;
++ int derlen = -1;
+ int ret=-1;
+
+ s = ECDSA_SIG_new();
+ if (s == NULL) return(ret);
+- if (d2i_ECDSA_SIG(&s, &sigbuf, sig_len) == NULL) goto err;
++ if (d2i_ECDSA_SIG(&s, &p, sig_len) == NULL) goto err;
++ /* Ensure signature uses DER and doesn't have trailing garbage */
++ derlen = i2d_ECDSA_SIG(s, &der);
++ if (derlen != sig_len || memcmp(sigbuf, der, derlen))
++ goto err;
+ ret=ECDSA_do_verify(dgst, dgst_len, s, eckey);
+ err:
++ if (derlen > 0)
++ {
++ OPENSSL_cleanse(der, derlen);
++ OPENSSL_free(der);
++ }
+ ECDSA_SIG_free(s);
+ return(ret);
+ }
+Index: crypto/openssl/crypto/x509/x509.h
+===================================================================
+--- crypto/openssl/crypto/x509/x509.h (revision 276867)
++++ crypto/openssl/crypto/x509/x509.h (working copy)
+@@ -768,6 +768,7 @@ int X509_ALGOR_set0(X509_ALGOR *alg, ASN1_OBJECT *
+ void X509_ALGOR_get0(ASN1_OBJECT **paobj, int *pptype, void **ppval,
+ X509_ALGOR *algor);
+ void X509_ALGOR_set_md(X509_ALGOR *alg, const EVP_MD *md);
++int X509_ALGOR_cmp(const X509_ALGOR *a, const X509_ALGOR *b);
+
+ X509_NAME *X509_NAME_dup(X509_NAME *xn);
+ X509_NAME_ENTRY *X509_NAME_ENTRY_dup(X509_NAME_ENTRY *ne);
+Index: crypto/openssl/crypto/x509/x_all.c
+===================================================================
+--- crypto/openssl/crypto/x509/x_all.c (revision 276867)
++++ crypto/openssl/crypto/x509/x_all.c (working copy)
+@@ -72,6 +72,8 @@
+
+ int X509_verify(X509 *a, EVP_PKEY *r)
+ {
++ if (X509_ALGOR_cmp(a->sig_alg, a->cert_info->signature))
++ return 0;
+ return(ASN1_item_verify(ASN1_ITEM_rptr(X509_CINF),a->sig_alg,
+ a->signature,a->cert_info,r));
+ }
+Index: crypto/openssl/doc/ssl/SSL_CTX_set_options.pod
+===================================================================
+--- crypto/openssl/doc/ssl/SSL_CTX_set_options.pod (revision 276867)
++++ crypto/openssl/doc/ssl/SSL_CTX_set_options.pod (working copy)
+@@ -151,15 +151,7 @@ temporary/ephemeral DH parameters are used.
+
+ =item SSL_OP_EPHEMERAL_RSA
+
+-Always use ephemeral (temporary) RSA key when doing RSA operations
+-(see L).
+-According to the specifications this is only done, when a RSA key
+-can only be used for signature operations (namely under export ciphers
+-with restricted RSA keylength). By setting this option, ephemeral
+-RSA keys are always used. This option breaks compatibility with the
+-SSL/TLS specifications and may lead to interoperability problems with
+-clients and should therefore never be used. Ciphers with EDH (ephemeral
+-Diffie-Hellman) key exchange should be used instead.
++This option is no longer implemented and is treated as no op.
+
+ =item SSL_OP_CIPHER_SERVER_PREFERENCE
+
+Index: crypto/openssl/doc/ssl/SSL_CTX_set_tmp_rsa_callback.pod
+===================================================================
+--- crypto/openssl/doc/ssl/SSL_CTX_set_tmp_rsa_callback.pod (revision 276867)
++++ crypto/openssl/doc/ssl/SSL_CTX_set_tmp_rsa_callback.pod (working copy)
+@@ -74,22 +74,15 @@ exchange and use EDH (Ephemeral Diffie-Hellman) ke
+ in order to achieve forward secrecy (see
+ L).
+
+-On OpenSSL servers ephemeral RSA key exchange is therefore disabled by default
+-and must be explicitly enabled using the SSL_OP_EPHEMERAL_RSA option of
+-L, violating the TLS/SSL
+-standard. When ephemeral RSA key exchange is required for export ciphers,
+-it will automatically be used without this option!
++An application may either directly specify the key or can supply the key via a
++callback function. The callback approach has the advantage, that the callback
++may generate the key only in case it is actually needed. As the generation of a
++RSA key is however costly, it will lead to a significant delay in the handshake
++procedure. Another advantage of the callback function is that it can supply
++keys of different size while the explicit setting of the key is only useful for
++key size of 512 bits to satisfy the export restricted ciphers and does give
++away key length if a longer key would be allowed.
+
+-An application may either directly specify the key or can supply the key via
+-a callback function. The callback approach has the advantage, that the
+-callback may generate the key only in case it is actually needed. As the
+-generation of a RSA key is however costly, it will lead to a significant
+-delay in the handshake procedure. Another advantage of the callback function
+-is that it can supply keys of different size (e.g. for SSL_OP_EPHEMERAL_RSA
+-usage) while the explicit setting of the key is only useful for key size of
+-512 bits to satisfy the export restricted ciphers and does give away key length
+-if a longer key would be allowed.
+-
+ The B is called with the B needed and
+ the B information. The B flag is set, when the
+ ephemeral RSA key exchange is performed with an export cipher.
+Index: crypto/openssl/ssl/d1_pkt.c
+===================================================================
+--- crypto/openssl/ssl/d1_pkt.c (revision 276867)
++++ crypto/openssl/ssl/d1_pkt.c (working copy)
+@@ -212,7 +212,7 @@ dtls1_buffer_record(SSL *s, record_pqueue *queue,
+ /* Limit the size of the queue to prevent DOS attacks */
+ if (pqueue_size(queue->q) >= 100)
+ return 0;
+-
++
+ rdata = OPENSSL_malloc(sizeof(DTLS1_RECORD_DATA));
+ item = pitem_new(priority, rdata);
+ if (rdata == NULL || item == NULL)
+@@ -239,14 +239,6 @@ dtls1_buffer_record(SSL *s, record_pqueue *queue,
+ }
+ #endif
+
+- /* insert should not fail, since duplicates are dropped */
+- if (pqueue_insert(queue->q, item) == NULL)
+- {
+- OPENSSL_free(rdata);
+- pitem_free(item);
+- return(0);
+- }
+-
+ s->packet = NULL;
+ s->packet_length = 0;
+ memset(&(s->s3->rbuf), 0, sizeof(SSL3_BUFFER));
+@@ -255,11 +247,24 @@ dtls1_buffer_record(SSL *s, record_pqueue *queue,
+ if (!ssl3_setup_buffers(s))
+ {
+ SSLerr(SSL_F_DTLS1_BUFFER_RECORD, ERR_R_INTERNAL_ERROR);
++ if (rdata->rbuf.buf != NULL)
++ OPENSSL_free(rdata->rbuf.buf);
+ OPENSSL_free(rdata);
+ pitem_free(item);
+- return(0);
++ return(-1);
+ }
+-
++
++ /* insert should not fail, since duplicates are dropped */
++ if (pqueue_insert(queue->q, item) == NULL)
++ {
++ SSLerr(SSL_F_DTLS1_BUFFER_RECORD, ERR_R_INTERNAL_ERROR);
++ if (rdata->rbuf.buf != NULL)
++ OPENSSL_free(rdata->rbuf.buf);
++ OPENSSL_free(rdata);
++ pitem_free(item);
++ return(-1);
++ }
++
+ return(1);
+ }
+
+@@ -313,8 +318,9 @@ dtls1_process_buffered_records(SSL *s)
+ dtls1_get_unprocessed_record(s);
+ if ( ! dtls1_process_record(s))
+ return(0);
+- dtls1_buffer_record(s, &(s->d1->processed_rcds),
+- s->s3->rrec.seq_num);
++ if(dtls1_buffer_record(s, &(s->d1->processed_rcds),
++ s->s3->rrec.seq_num)<0)
++ return -1;
+ }
+ }
+
+@@ -529,7 +535,6 @@ printf("\n");
+
+ /* we have pulled in a full packet so zero things */
+ s->packet_length=0;
+- dtls1_record_bitmap_update(s, &(s->d1->bitmap));/* Mark receipt of record. */
+ return(1);
+
+ f_err:
+@@ -562,7 +567,8 @@ int dtls1_get_record(SSL *s)
+
+ /* The epoch may have changed. If so, process all the
+ * pending records. This is a non-blocking operation. */
+- dtls1_process_buffered_records(s);
++ if(dtls1_process_buffered_records(s)<0)
++ return -1;
+
+ /* if we're renegotiating, then there may be buffered records */
+ if (dtls1_get_processed_record(s))
+@@ -641,8 +647,6 @@ again:
+ /* now s->packet_length == DTLS1_RT_HEADER_LENGTH */
+ i=rr->length;
+ n=ssl3_read_n(s,i,i,1);
+- if (n <= 0) return(n); /* error or non-blocking io */
+-
+ /* this packet contained a partial record, dump it */
+ if ( n != i)
+ {
+@@ -677,7 +681,8 @@ again:
+ * would be dropped unnecessarily.
+ */
+ if (!(s->d1->listen && rr->type == SSL3_RT_HANDSHAKE &&
+- *p == SSL3_MT_CLIENT_HELLO) &&
++ s->packet_length > DTLS1_RT_HEADER_LENGTH &&
++ s->packet[DTLS1_RT_HEADER_LENGTH] == SSL3_MT_CLIENT_HELLO) &&
+ !dtls1_record_replay_check(s, bitmap))
+ {
+ rr->length = 0;
+@@ -700,7 +705,9 @@ again:
+ {
+ if ((SSL_in_init(s) || s->in_handshake) && !s->d1->listen)
+ {
+- dtls1_buffer_record(s, &(s->d1->unprocessed_rcds), rr->seq_num);
++ if(dtls1_buffer_record(s, &(s->d1->unprocessed_rcds), rr->seq_num)<0)
++ return -1;
++ dtls1_record_bitmap_update(s, bitmap);/* Mark receipt of record. */
+ }
+ rr->length = 0;
+ s->packet_length = 0;
+@@ -713,6 +720,7 @@ again:
+ s->packet_length = 0; /* dump this record */
+ goto again; /* get another record */
+ }
++ dtls1_record_bitmap_update(s, bitmap);/* Mark receipt of record. */
+
+ return(1);
+
+@@ -858,7 +866,11 @@ start:
+ * buffer the application data for later processing rather
+ * than dropping the connection.
+ */
+- dtls1_buffer_record(s, &(s->d1->buffered_app_data), rr->seq_num);
++ if(dtls1_buffer_record(s, &(s->d1->buffered_app_data), rr->seq_num)<0)
++ {
++ SSLerr(SSL_F_DTLS1_READ_BYTES, ERR_R_INTERNAL_ERROR);
++ return -1;
++ }
+ rr->length = 0;
+ goto start;
+ }
+Index: crypto/openssl/ssl/d1_srvr.c
+===================================================================
+--- crypto/openssl/ssl/d1_srvr.c (revision 276867)
++++ crypto/openssl/ssl/d1_srvr.c (working copy)
+@@ -449,24 +449,15 @@ int dtls1_accept(SSL *s)
+ case SSL3_ST_SW_KEY_EXCH_B:
+ alg_k = s->s3->tmp.new_cipher->algorithm_mkey;
+
+- /* clear this, it may get reset by
+- * send_server_key_exchange */
+- if ((s->options & SSL_OP_EPHEMERAL_RSA)
+-#ifndef OPENSSL_NO_KRB5
+- && !(alg_k & SSL_kKRB5)
+-#endif /* OPENSSL_NO_KRB5 */
+- )
+- /* option SSL_OP_EPHEMERAL_RSA sends temporary RSA key
+- * even when forbidden by protocol specs
+- * (handshake may fail as clients are not required to
+- * be able to handle this) */
+- s->s3->tmp.use_rsa_tmp=1;
+- else
+- s->s3->tmp.use_rsa_tmp=0;
++ /*
++ * clear this, it may get reset by
++ * send_server_key_exchange
++ */
++ s->s3->tmp.use_rsa_tmp=0;
+
+ /* only send if a DH key exchange or
+ * RSA but we have a sign only certificate */
+- if (s->s3->tmp.use_rsa_tmp
++ if (0
+ /* PSK: send ServerKeyExchange if PSK identity
+ * hint if provided */
+ #ifndef OPENSSL_NO_PSK
+Index: crypto/openssl/ssl/s23_srvr.c
+===================================================================
+--- crypto/openssl/ssl/s23_srvr.c (revision 276867)
++++ crypto/openssl/ssl/s23_srvr.c (working copy)
+@@ -602,12 +602,14 @@ int ssl23_get_client_hello(SSL *s)
+ if ((type == 2) || (type == 3))
+ {
+ /* we have SSLv3/TLSv1 (type 2: SSL2 style, type 3: SSL3/TLS style) */
+- s->method = ssl23_get_server_method(s->version);
+- if (s->method == NULL)
++ const SSL_METHOD *new_method;
++ new_method = ssl23_get_server_method(s->version);
++ if (new_method == NULL)
+ {
+ SSLerr(SSL_F_SSL23_GET_CLIENT_HELLO,SSL_R_UNSUPPORTED_PROTOCOL);
+ goto err;
+ }
++ s->method = new_method;
+
+ if (!ssl_init_wbio_buffer(s,1)) goto err;
+
+Index: crypto/openssl/ssl/s3_clnt.c
+===================================================================
+--- crypto/openssl/ssl/s3_clnt.c (revision 276867)
++++ crypto/openssl/ssl/s3_clnt.c (working copy)
+@@ -1276,8 +1276,8 @@ int ssl3_get_key_exchange(SSL *s)
+ #endif
+ EVP_MD_CTX md_ctx;
+ unsigned char *param,*p;
+- int al,i,j,param_len,ok;
+- long n,alg_k,alg_a;
++ int al,j,ok;
++ long i,param_len,n,alg_k,alg_a;
+ EVP_PKEY *pkey=NULL;
+ const EVP_MD *md = NULL;
+ #ifndef OPENSSL_NO_RSA
+@@ -1294,6 +1294,8 @@ int ssl3_get_key_exchange(SSL *s)
+ int encoded_pt_len = 0;
+ #endif
+
++ EVP_MD_CTX_init(&md_ctx);
++
+ /* use same message size as in ssl3_get_certificate_request()
+ * as ServerKeyExchange message may be skipped */
+ n=s->method->ssl_get_message(s,
+@@ -1304,14 +1306,26 @@ int ssl3_get_key_exchange(SSL *s)
+ &ok);
+ if (!ok) return((int)n);
+
++ alg_k=s->s3->tmp.new_cipher->algorithm_mkey;
++
+ if (s->s3->tmp.message_type != SSL3_MT_SERVER_KEY_EXCHANGE)
+ {
++ /*
++ * Can't skip server key exchange if this is an ephemeral
++ * ciphersuite.
++ */
++ if (alg_k & (SSL_kEDH|SSL_kEECDH))
++ {
++ SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_UNEXPECTED_MESSAGE);
++ al = SSL_AD_UNEXPECTED_MESSAGE;
++ goto f_err;
++ }
+ #ifndef OPENSSL_NO_PSK
+ /* In plain PSK ciphersuite, ServerKeyExchange can be
+ omitted if no identity hint is sent. Set
+ session->sess_cert anyway to avoid problems
+ later.*/
+- if (s->s3->tmp.new_cipher->algorithm_mkey & SSL_kPSK)
++ if (alg_k & SSL_kPSK)
+ {
+ s->session->sess_cert=ssl_sess_cert_new();
+ if (s->ctx->psk_identity_hint)
+@@ -1353,19 +1367,27 @@ int ssl3_get_key_exchange(SSL *s)
+ s->session->sess_cert=ssl_sess_cert_new();
+ }
+
++ /* Total length of the parameters including the length prefix */
+ param_len=0;
+- alg_k=s->s3->tmp.new_cipher->algorithm_mkey;
++
+ alg_a=s->s3->tmp.new_cipher->algorithm_auth;
+- EVP_MD_CTX_init(&md_ctx);
+
++ al=SSL_AD_DECODE_ERROR;
++
+ #ifndef OPENSSL_NO_PSK
+ if (alg_k & SSL_kPSK)
+ {
+ char tmp_id_hint[PSK_MAX_IDENTITY_LEN+1];
+
+- al=SSL_AD_HANDSHAKE_FAILURE;
++ param_len = 2;
++ if (param_len > n)
++ {
++ SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,
++ SSL_R_LENGTH_TOO_SHORT);
++ goto f_err;
++ }
+ n2s(p,i);
+- param_len=i+2;
++
+ /* Store PSK identity hint for later use, hint is used
+ * in ssl3_send_client_key_exchange. Assume that the
+ * maximum length of a PSK identity hint can be as
+@@ -1372,17 +1394,19 @@ int ssl3_get_key_exchange(SSL *s)
+ * long as the maximum length of a PSK identity. */
+ if (i > PSK_MAX_IDENTITY_LEN)
+ {
++ al=SSL_AD_HANDSHAKE_FAILURE;
+ SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,
+ SSL_R_DATA_LENGTH_TOO_LONG);
+ goto f_err;
+ }
+- if (param_len > n)
++ if (i > n - param_len)
+ {
+- al=SSL_AD_DECODE_ERROR;
+ SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,
+ SSL_R_BAD_PSK_IDENTITY_HINT_LENGTH);
+ goto f_err;
+ }
++ param_len += i;
++
+ /* If received PSK identity hint contains NULL
+ * characters, the hint is truncated from the first
+ * NULL. p may not be ending with NULL, so create a
+@@ -1394,6 +1418,7 @@ int ssl3_get_key_exchange(SSL *s)
+ s->ctx->psk_identity_hint = BUF_strdup(tmp_id_hint);
+ if (s->ctx->psk_identity_hint == NULL)
+ {
++ al=SSL_AD_HANDSHAKE_FAILURE;
+ SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_MALLOC_FAILURE);
+ goto f_err;
+ }
+@@ -1406,14 +1431,22 @@ int ssl3_get_key_exchange(SSL *s)
+ #ifndef OPENSSL_NO_SRP
+ if (alg_k & SSL_kSRP)
+ {
+- n2s(p,i);
+- param_len=i+2;
++ param_len = 2;
+ if (param_len > n)
+ {
+- al=SSL_AD_DECODE_ERROR;
++ SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,
++ SSL_R_LENGTH_TOO_SHORT);
++ goto f_err;
++ }
++ n2s(p,i);
++
++ if (i > n - param_len)
++ {
+ SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_BAD_SRP_N_LENGTH);
+ goto f_err;
+ }
++ param_len += i;
++
+ if (!(s->srp_ctx.N=BN_bin2bn(p,i,NULL)))
+ {
+ SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,ERR_R_BN_LIB);
+@@ -1421,14 +1454,24 @@ int ssl3_get_key_exchange(SSL *s)
+ }
+ p+=i;
+
++
++ if (2 > n - param_len)
++ {
++ SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,
++ SSL_R_LENGTH_TOO_SHORT);
++ goto f_err;
++ }
++ param_len += 2;
++
+ n2s(p,i);
+- param_len+=i+2;
+- if (param_len > n)
++
++ if (i > n - param_len)
+ {
+- al=SSL_AD_DECODE_ERROR;
+ SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_BAD_SRP_G_LENGTH);
+ goto f_err;
+ }
++ param_len += i;
++
+ if (!(s->srp_ctx.g=BN_bin2bn(p,i,NULL)))
+ {
+ SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,ERR_R_BN_LIB);
+@@ -1436,15 +1479,25 @@ int ssl3_get_key_exchange(SSL *s)
+ }
+ p+=i;
+
++
++ if (1 > n - param_len)
++ {
++ SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,
++ SSL_R_LENGTH_TOO_SHORT);
++ goto f_err;
++ }
++ param_len += 1;
++
+ i = (unsigned int)(p[0]);
+ p++;
+- param_len+=i+1;
+- if (param_len > n)
++
++ if (i > n - param_len)
+ {
+- al=SSL_AD_DECODE_ERROR;
+ SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_BAD_SRP_S_LENGTH);
+ goto f_err;
+ }
++ param_len += i;
++
+ if (!(s->srp_ctx.s=BN_bin2bn(p,i,NULL)))
+ {
+ SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,ERR_R_BN_LIB);
+@@ -1452,14 +1505,23 @@ int ssl3_get_key_exchange(SSL *s)
+ }
+ p+=i;
+
++ if (2 > n - param_len)
++ {
++ SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,
++ SSL_R_LENGTH_TOO_SHORT);
++ goto f_err;
++ }
++ param_len += 2;
++
+ n2s(p,i);
+- param_len+=i+2;
+- if (param_len > n)
++
++ if (i > n - param_len)
+ {
+- al=SSL_AD_DECODE_ERROR;
+ SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_BAD_SRP_B_LENGTH);
+ goto f_err;
+ }
++ param_len += i;
++
+ if (!(s->srp_ctx.B=BN_bin2bn(p,i,NULL)))
+ {
+ SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,ERR_R_BN_LIB);
+@@ -1492,19 +1554,35 @@ int ssl3_get_key_exchange(SSL *s)
+ #ifndef OPENSSL_NO_RSA
+ if (alg_k & SSL_kRSA)
+ {
++ /* Temporary RSA keys only allowed in export ciphersuites */
++ if (!SSL_C_IS_EXPORT(s->s3->tmp.new_cipher))
++ {
++ al=SSL_AD_UNEXPECTED_MESSAGE;
++ SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_UNEXPECTED_MESSAGE);
++ goto f_err;
++ }
+ if ((rsa=RSA_new()) == NULL)
+ {
+ SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+- n2s(p,i);
+- param_len=i+2;
++
++ param_len = 2;
+ if (param_len > n)
+ {
+- al=SSL_AD_DECODE_ERROR;
++ SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,
++ SSL_R_LENGTH_TOO_SHORT);
++ goto f_err;
++ }
++ n2s(p,i);
++
++ if (i > n - param_len)
++ {
+ SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_BAD_RSA_MODULUS_LENGTH);
+ goto f_err;
+ }
++ param_len += i;
++
+ if (!(rsa->n=BN_bin2bn(p,i,rsa->n)))
+ {
+ SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,ERR_R_BN_LIB);
+@@ -1512,14 +1590,23 @@ int ssl3_get_key_exchange(SSL *s)
+ }
+ p+=i;
+
++ if (2 > n - param_len)
++ {
++ SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,
++ SSL_R_LENGTH_TOO_SHORT);
++ goto f_err;
++ }
++ param_len += 2;
++
+ n2s(p,i);
+- param_len+=i+2;
+- if (param_len > n)
++
++ if (i > n - param_len)
+ {
+- al=SSL_AD_DECODE_ERROR;
+ SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_BAD_RSA_E_LENGTH);
+ goto f_err;
+ }
++ param_len += i;
++
+ if (!(rsa->e=BN_bin2bn(p,i,rsa->e)))
+ {
+ SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,ERR_R_BN_LIB);
+@@ -1551,14 +1638,23 @@ int ssl3_get_key_exchange(SSL *s)
+ SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,ERR_R_DH_LIB);
+ goto err;
+ }
+- n2s(p,i);
+- param_len=i+2;
++
++ param_len = 2;
+ if (param_len > n)
+ {
+- al=SSL_AD_DECODE_ERROR;
++ SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,
++ SSL_R_LENGTH_TOO_SHORT);
++ goto f_err;
++ }
++ n2s(p,i);
++
++ if (i > n - param_len)
++ {
+ SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_BAD_DH_P_LENGTH);
+ goto f_err;
+ }
++ param_len += i;
++
+ if (!(dh->p=BN_bin2bn(p,i,NULL)))
+ {
+ SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,ERR_R_BN_LIB);
+@@ -1566,14 +1662,23 @@ int ssl3_get_key_exchange(SSL *s)
+ }
+ p+=i;
+
++ if (2 > n - param_len)
++ {
++ SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,
++ SSL_R_LENGTH_TOO_SHORT);
++ goto f_err;
++ }
++ param_len += 2;
++
+ n2s(p,i);
+- param_len+=i+2;
+- if (param_len > n)
++
++ if (i > n - param_len)
+ {
+- al=SSL_AD_DECODE_ERROR;
+ SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_BAD_DH_G_LENGTH);
+ goto f_err;
+ }
++ param_len += i;
++
+ if (!(dh->g=BN_bin2bn(p,i,NULL)))
+ {
+ SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,ERR_R_BN_LIB);
+@@ -1581,14 +1686,23 @@ int ssl3_get_key_exchange(SSL *s)
+ }
+ p+=i;
+
++ if (2 > n - param_len)
++ {
++ SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,
++ SSL_R_LENGTH_TOO_SHORT);
++ goto f_err;
++ }
++ param_len += 2;
++
+ n2s(p,i);
+- param_len+=i+2;
+- if (param_len > n)
++
++ if (i > n - param_len)
+ {
+- al=SSL_AD_DECODE_ERROR;
+ SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_BAD_DH_PUB_KEY_LENGTH);
+ goto f_err;
+ }
++ param_len += i;
++
+ if (!(dh->pub_key=BN_bin2bn(p,i,NULL)))
+ {
+ SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,ERR_R_BN_LIB);
+@@ -1640,13 +1754,20 @@ int ssl3_get_key_exchange(SSL *s)
+ */
+
+ /* XXX: For now we only support named (not generic) curves
+- * and the ECParameters in this case is just three bytes.
++ * and the ECParameters in this case is just three bytes. We
++ * also need one byte for the length of the encoded point
+ */
+- param_len=3;
+- if ((param_len > n) ||
+- (*p != NAMED_CURVE_TYPE) ||
+- ((curve_nid = tls1_ec_curve_id2nid(*(p + 2))) == 0))
++ param_len=4;
++ if (param_len > n)
+ {
++ SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,
++ SSL_R_LENGTH_TOO_SHORT);
++ goto f_err;
++ }
++
++ if ((*p != NAMED_CURVE_TYPE) ||
++ ((curve_nid = tls1_ec_curve_id2nid(*(p + 2))) == 0))
++ {
+ al=SSL_AD_INTERNAL_ERROR;
+ SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_UNABLE_TO_FIND_ECDH_PARAMETERS);
+ goto f_err;
+@@ -1687,15 +1808,15 @@ int ssl3_get_key_exchange(SSL *s)
+
+ encoded_pt_len = *p; /* length of encoded point */
+ p+=1;
+- param_len += (1 + encoded_pt_len);
+- if ((param_len > n) ||
++
++ if ((encoded_pt_len > n - param_len) ||
+ (EC_POINT_oct2point(group, srvr_ecpoint,
+ p, encoded_pt_len, bn_ctx) == 0))
+ {
+- al=SSL_AD_DECODE_ERROR;
+ SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_BAD_ECPOINT);
+ goto f_err;
+ }
++ param_len += encoded_pt_len;
+
+ n-=param_len;
+ p+=encoded_pt_len;
+@@ -1738,7 +1859,15 @@ int ssl3_get_key_exchange(SSL *s)
+ {
+ if (TLS1_get_version(s) >= TLS1_2_VERSION)
+ {
+- int sigalg = tls12_get_sigid(pkey);
++ int sigalg;
++ if (2 > n)
++ {
++ SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,
++ SSL_R_LENGTH_TOO_SHORT);
++ goto f_err;
++ }
++
++ sigalg = tls12_get_sigid(pkey);
+ /* Should never happen */
+ if (sigalg == -1)
+ {
+@@ -1756,7 +1885,6 @@ int ssl3_get_key_exchange(SSL *s)
+ if (md == NULL)
+ {
+ SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_UNKNOWN_DIGEST);
+- al=SSL_AD_DECODE_ERROR;
+ goto f_err;
+ }
+ #ifdef SSL_DEBUG
+@@ -1767,15 +1895,21 @@ fprintf(stderr, "USING TLSv1.2 HASH %s\n", EVP_MD_
+ }
+ else
+ md = EVP_sha1();
+-
++
++ if (2 > n)
++ {
++ SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,
++ SSL_R_LENGTH_TOO_SHORT);
++ goto f_err;
++ }
+ n2s(p,i);
+ n-=2;
+ j=EVP_PKEY_size(pkey);
+
++ /* Check signature length. If n is 0 then signature is empty */
+ if ((i != n) || (n > j) || (n <= 0))
+ {
+ /* wrong packet length */
+- al=SSL_AD_DECODE_ERROR;
+ SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_WRONG_SIGNATURE_LENGTH);
+ goto f_err;
+ }
+@@ -1843,7 +1977,6 @@ fprintf(stderr, "USING TLSv1.2 HASH %s\n", EVP_MD_
+ /* still data left over */
+ if (n != 0)
+ {
+- al=SSL_AD_DECODE_ERROR;
+ SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_EXTRA_DATA_IN_MESSAGE);
+ goto f_err;
+ }
+Index: crypto/openssl/ssl/s3_pkt.c
+===================================================================
+--- crypto/openssl/ssl/s3_pkt.c (revision 276867)
++++ crypto/openssl/ssl/s3_pkt.c (working copy)
+@@ -182,6 +182,8 @@ int ssl3_read_n(SSL *s, int n, int max, int extend
+ * at once (as long as it fits into the buffer). */
+ if (SSL_version(s) == DTLS1_VERSION || SSL_version(s) == DTLS1_BAD_VER)
+ {
++ if (left == 0 && extend)
++ return 0;
+ if (left > 0 && n > left)
+ n = left;
+ }
+Index: crypto/openssl/ssl/s3_srvr.c
+===================================================================
+--- crypto/openssl/ssl/s3_srvr.c (revision 276867)
++++ crypto/openssl/ssl/s3_srvr.c (working copy)
+@@ -441,20 +441,11 @@ int ssl3_accept(SSL *s)
+ case SSL3_ST_SW_KEY_EXCH_B:
+ alg_k = s->s3->tmp.new_cipher->algorithm_mkey;
+
+- /* clear this, it may get reset by
+- * send_server_key_exchange */
+- if ((s->options & SSL_OP_EPHEMERAL_RSA)
+-#ifndef OPENSSL_NO_KRB5
+- && !(alg_k & SSL_kKRB5)
+-#endif /* OPENSSL_NO_KRB5 */
+- )
+- /* option SSL_OP_EPHEMERAL_RSA sends temporary RSA key
+- * even when forbidden by protocol specs
+- * (handshake may fail as clients are not required to
+- * be able to handle this) */
+- s->s3->tmp.use_rsa_tmp=1;
+- else
+- s->s3->tmp.use_rsa_tmp=0;
++ /*
++ * clear this, it may get reset by
++ * send_server_key_exchange
++ */
++ s->s3->tmp.use_rsa_tmp=0;
+
+
+ /* only send if a DH key exchange, fortezza or
+@@ -468,7 +459,7 @@ int ssl3_accept(SSL *s)
+ * server certificate contains the server's
+ * public key for key exchange.
+ */
+- if (s->s3->tmp.use_rsa_tmp
++ if (0
+ /* PSK: send ServerKeyExchange if PSK identity
+ * hint if provided */
+ #ifndef OPENSSL_NO_PSK
+@@ -2957,7 +2948,7 @@ int ssl3_get_cert_verify(SSL *s)
+ if (s->s3->tmp.message_type != SSL3_MT_CERTIFICATE_VERIFY)
+ {
+ s->s3->tmp.reuse_message=1;
+- if ((peer != NULL) && (type & EVP_PKT_SIGN))
++ if (peer != NULL)
+ {
+ al=SSL_AD_UNEXPECTED_MESSAGE;
+ SSLerr(SSL_F_SSL3_GET_CERT_VERIFY,SSL_R_MISSING_VERIFY_MESSAGE);
+Index: crypto/openssl/ssl/ssl.h
+===================================================================
+--- crypto/openssl/ssl/ssl.h (revision 276867)
++++ crypto/openssl/ssl/ssl.h (working copy)
+@@ -591,9 +591,8 @@ struct ssl_session_st
+ #define SSL_OP_SINGLE_ECDH_USE 0x00080000L
+ /* If set, always create a new key when using tmp_dh parameters */
+ #define SSL_OP_SINGLE_DH_USE 0x00100000L
+-/* Set to always use the tmp_rsa key when doing RSA operations,
+- * even when this violates protocol specs */
+-#define SSL_OP_EPHEMERAL_RSA 0x00200000L
++/* Does nothing: retained for compatibiity */
++#define SSL_OP_EPHEMERAL_RSA 0x0
+ /* Set on servers to choose the cipher according to the server's
+ * preferences */
+ #define SSL_OP_CIPHER_SERVER_PREFERENCE 0x00400000L
+Index: crypto/openssl/ssl/ssl_lib.c
+===================================================================
+--- crypto/openssl/ssl/ssl_lib.c (revision 276867)
++++ crypto/openssl/ssl/ssl_lib.c (working copy)
+@@ -2972,6 +2972,7 @@ SSL_CTX *SSL_get_SSL_CTX(const SSL *ssl)
+
+ SSL_CTX *SSL_set_SSL_CTX(SSL *ssl, SSL_CTX* ctx)
+ {
++ CERT *ocert = ssl->cert;
+ if (ssl->ctx == ctx)
+ return ssl->ctx;
+ #ifndef OPENSSL_NO_TLSEXT
+@@ -2978,13 +2979,45 @@ SSL_CTX *SSL_set_SSL_CTX(SSL *ssl, SSL_CTX* ctx)
+ if (ctx == NULL)
+ ctx = ssl->initial_ctx;
+ #endif
+- if (ssl->cert != NULL)
+- ssl_cert_free(ssl->cert);
+ ssl->cert = ssl_cert_dup(ctx->cert);
++ if (ocert != NULL)
++ {
++ int i;
++ /* Copy negotiated digests from original */
++ for (i = 0; i < SSL_PKEY_NUM; i++)
++ {
++ CERT_PKEY *cpk = ocert->pkeys + i;
++ CERT_PKEY *rpk = ssl->cert->pkeys + i;
++ rpk->digest = cpk->digest;
++ }
++ ssl_cert_free(ocert);
++ }
++
++ /*
++ * Program invariant: |sid_ctx| has fixed size (SSL_MAX_SID_CTX_LENGTH),
++ * so setter APIs must prevent invalid lengths from entering the system.
++ */
++ OPENSSL_assert(ssl->sid_ctx_length <= sizeof(ssl->sid_ctx));
++
++ /*
++ * If the session ID context matches that of the parent SSL_CTX,
++ * inherit it from the new SSL_CTX as well. If however the context does
++ * not match (i.e., it was set per-ssl with SSL_set_session_id_context),
++ * leave it unchanged.
++ */
++ if ((ssl->ctx != NULL) &&
++ (ssl->sid_ctx_length == ssl->ctx->sid_ctx_length) &&
++ (memcmp(ssl->sid_ctx, ssl->ctx->sid_ctx, ssl->sid_ctx_length) == 0))
++ {
++ ssl->sid_ctx_length = ctx->sid_ctx_length;
++ memcpy(&ssl->sid_ctx, &ctx->sid_ctx, sizeof(ssl->sid_ctx));
++ }
++
+ CRYPTO_add(&ctx->references,1,CRYPTO_LOCK_SSL_CTX);
+ if (ssl->ctx != NULL)
+ SSL_CTX_free(ssl->ctx); /* decrement reference count */
+ ssl->ctx = ctx;
++
+ return(ssl->ctx);
+ }
+
+Index: crypto/openssl/util/libeay.num
+===================================================================
+--- crypto/openssl/util/libeay.num (revision 276867)
++++ crypto/openssl/util/libeay.num (working copy)
+@@ -1807,6 +1807,7 @@ ASN1_UTCTIME_get 2350 NOEXI
+ X509_REQ_digest 2362 EXIST::FUNCTION:EVP
+ X509_CRL_digest 2391 EXIST::FUNCTION:EVP
+ d2i_ASN1_SET_OF_PKCS7 2397 NOEXIST::FUNCTION:
++X509_ALGOR_cmp 2398 EXIST::FUNCTION:
+ EVP_CIPHER_CTX_set_key_length 2399 EXIST::FUNCTION:
+ EVP_CIPHER_CTX_ctrl 2400 EXIST::FUNCTION:
+ BN_mod_exp_mont_word 2401 EXIST::FUNCTION:
diff --git a/share/security/patches/SA-15:01/openssl-10.0.patch.asc b/share/security/patches/SA-15:01/openssl-10.0.patch.asc
new file mode 100644
index 0000000000..477494747f
--- /dev/null
+++ b/share/security/patches/SA-15:01/openssl-10.0.patch.asc
@@ -0,0 +1,17 @@
+-----BEGIN PGP SIGNATURE-----
+Version: GnuPG v2.1.1 (FreeBSD)
+
+iQIcBAABCgAGBQJUtuBQAAoJEO1n7NZdz2rnVsEP/3rKxcVxtP3DeRhMUwxLE3vK
+VulM4jE8yMiR6ipSWNuUyRPMMLtnkTkBUygIDr0J5Ivnqgeo0EtrQtYs8xGqkJYU
+a9jS0BKJdsLUX8zapixVdOEbu8ySL3F+ZRQPKLSg+LUfosuk8OT1z2h14CHdsdBJ
+23tSCMgk9KkRA4N1NDf/CHjYAPF5zyIh02DBF2m11CC2roaqUXxeGYqmTrzQONoY
+eMyGpvqdjrpy8oafw0mGDV5RxtWImhfeHnm0t/NRn9TMnPUWtNE+4KiO5DJprkiC
+9vbEt4uU/OUtxgZ6+0BhNs4piv1y7Bm42YprS3nrGWeDjO624rS1E7X25VxP0N70
+ALcMKQDr4OcqMUkn7RV09Vj7yfQRdgYMueVD5LHSZ8dOrf2fmTmX38DLkG0pTIJT
+FCdYERwur/79ErVF2dAUnWYhVOBytoTrQhpCoS5MFRkTa3YH/e1sywEnxDSLcrF4
+/QDFhTIuzoN6bYA95TYt6O4Quch6fG9yE0yutTU+pLiz4SVJ+XXOG6KLK+WosyG9
+uHpHoE4z/Ib2v32PVGRyOifg+7DwyWEvuVwEYD2ByKEZRrodxExwbdmYzZqdyCVF
+vp7+lYAfsiGewlSB210169wu9jE7OZZgUv8tmuZ+B2H4cdGpMZfWGhxTDKzFGNWA
+CpAEGl9qaZD+5GfHxt0Y
+=N0l/
+-----END PGP SIGNATURE-----
diff --git a/share/security/patches/SA-15:01/openssl-10.1.patch b/share/security/patches/SA-15:01/openssl-10.1.patch
new file mode 100644
index 0000000000..965a2fb00d
--- /dev/null
+++ b/share/security/patches/SA-15:01/openssl-10.1.patch
@@ -0,0 +1,1636 @@
+Index: crypto/openssl/crypto/asn1/a_bitstr.c
+===================================================================
+--- crypto/openssl/crypto/asn1/a_bitstr.c (revision 276867)
++++ crypto/openssl/crypto/asn1/a_bitstr.c (working copy)
+@@ -136,11 +136,16 @@ ASN1_BIT_STRING *c2i_ASN1_BIT_STRING(ASN1_BIT_STRI
+
+ p= *pp;
+ i= *(p++);
++ if (i > 7)
++ {
++ i=ASN1_R_INVALID_BIT_STRING_BITS_LEFT;
++ goto err;
++ }
+ /* We do this to preserve the settings. If we modify
+ * the settings, via the _set_bit function, we will recalculate
+ * on output */
+ ret->flags&= ~(ASN1_STRING_FLAG_BITS_LEFT|0x07); /* clear */
+- ret->flags|=(ASN1_STRING_FLAG_BITS_LEFT|(i&0x07)); /* set */
++ ret->flags|=(ASN1_STRING_FLAG_BITS_LEFT|i); /* set */
+
+ if (len-- > 1) /* using one because of the bits left byte */
+ {
+Index: crypto/openssl/crypto/asn1/a_type.c
+===================================================================
+--- crypto/openssl/crypto/asn1/a_type.c (revision 276867)
++++ crypto/openssl/crypto/asn1/a_type.c (working copy)
+@@ -113,7 +113,7 @@ IMPLEMENT_STACK_OF(ASN1_TYPE)
+ IMPLEMENT_ASN1_SET_OF(ASN1_TYPE)
+
+ /* Returns 0 if they are equal, != 0 otherwise. */
+-int ASN1_TYPE_cmp(ASN1_TYPE *a, ASN1_TYPE *b)
++int ASN1_TYPE_cmp(const ASN1_TYPE *a, const ASN1_TYPE *b)
+ {
+ int result = -1;
+
+Index: crypto/openssl/crypto/asn1/a_verify.c
+===================================================================
+--- crypto/openssl/crypto/asn1/a_verify.c (revision 276867)
++++ crypto/openssl/crypto/asn1/a_verify.c (working copy)
+@@ -90,6 +90,12 @@ int ASN1_verify(i2d_of_void *i2d, X509_ALGOR *a, A
+ ASN1err(ASN1_F_ASN1_VERIFY,ASN1_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM);
+ goto err;
+ }
++
++ if (signature->type == V_ASN1_BIT_STRING && signature->flags & 0x7)
++ {
++ ASN1err(ASN1_F_ASN1_VERIFY, ASN1_R_INVALID_BIT_STRING_BITS_LEFT);
++ goto err;
++ }
+
+ inl=i2d(data,NULL);
+ buf_in=OPENSSL_malloc((unsigned int)inl);
+@@ -146,6 +152,12 @@ int ASN1_item_verify(const ASN1_ITEM *it, X509_ALG
+ return -1;
+ }
+
++ if (signature->type == V_ASN1_BIT_STRING && signature->flags & 0x7)
++ {
++ ASN1err(ASN1_F_ASN1_ITEM_VERIFY, ASN1_R_INVALID_BIT_STRING_BITS_LEFT);
++ return -1;
++ }
++
+ EVP_MD_CTX_init(&ctx);
+
+ /* Convert signature OID into digest and public key OIDs */
+Index: crypto/openssl/crypto/asn1/asn1.h
+===================================================================
+--- crypto/openssl/crypto/asn1/asn1.h (revision 276867)
++++ crypto/openssl/crypto/asn1/asn1.h (working copy)
+@@ -776,7 +776,7 @@ DECLARE_ASN1_FUNCTIONS_fname(ASN1_TYPE, ASN1_ANY,
+ int ASN1_TYPE_get(ASN1_TYPE *a);
+ void ASN1_TYPE_set(ASN1_TYPE *a, int type, void *value);
+ int ASN1_TYPE_set1(ASN1_TYPE *a, int type, const void *value);
+-int ASN1_TYPE_cmp(ASN1_TYPE *a, ASN1_TYPE *b);
++int ASN1_TYPE_cmp(const ASN1_TYPE *a, const ASN1_TYPE *b);
+
+ ASN1_OBJECT * ASN1_OBJECT_new(void );
+ void ASN1_OBJECT_free(ASN1_OBJECT *a);
+@@ -1329,6 +1329,7 @@ void ERR_load_ASN1_strings(void);
+ #define ASN1_R_ILLEGAL_TIME_VALUE 184
+ #define ASN1_R_INTEGER_NOT_ASCII_FORMAT 185
+ #define ASN1_R_INTEGER_TOO_LARGE_FOR_LONG 128
++#define ASN1_R_INVALID_BIT_STRING_BITS_LEFT 220
+ #define ASN1_R_INVALID_BMPSTRING_LENGTH 129
+ #define ASN1_R_INVALID_DIGIT 130
+ #define ASN1_R_INVALID_MIME_TYPE 205
+Index: crypto/openssl/crypto/asn1/asn1_err.c
+===================================================================
+--- crypto/openssl/crypto/asn1/asn1_err.c (revision 276867)
++++ crypto/openssl/crypto/asn1/asn1_err.c (working copy)
+@@ -246,6 +246,7 @@ static ERR_STRING_DATA ASN1_str_reasons[]=
+ {ERR_REASON(ASN1_R_ILLEGAL_TIME_VALUE) ,"illegal time value"},
+ {ERR_REASON(ASN1_R_INTEGER_NOT_ASCII_FORMAT),"integer not ascii format"},
+ {ERR_REASON(ASN1_R_INTEGER_TOO_LARGE_FOR_LONG),"integer too large for long"},
++{ERR_REASON(ASN1_R_INVALID_BIT_STRING_BITS_LEFT),"invalid bit string bits left"},
+ {ERR_REASON(ASN1_R_INVALID_BMPSTRING_LENGTH),"invalid bmpstring length"},
+ {ERR_REASON(ASN1_R_INVALID_DIGIT) ,"invalid digit"},
+ {ERR_REASON(ASN1_R_INVALID_MIME_TYPE) ,"invalid mime type"},
+Index: crypto/openssl/crypto/asn1/x_algor.c
+===================================================================
+--- crypto/openssl/crypto/asn1/x_algor.c (revision 276867)
++++ crypto/openssl/crypto/asn1/x_algor.c (working copy)
+@@ -142,3 +142,14 @@ void X509_ALGOR_set_md(X509_ALGOR *alg, const EVP_
+ X509_ALGOR_set0(alg, OBJ_nid2obj(EVP_MD_type(md)), param_type, NULL);
+
+ }
++
++int X509_ALGOR_cmp(const X509_ALGOR *a, const X509_ALGOR *b)
++ {
++ int rv;
++ rv = OBJ_cmp(a->algorithm, b->algorithm);
++ if (rv)
++ return rv;
++ if (!a->parameter && !b->parameter)
++ return 0;
++ return ASN1_TYPE_cmp(a->parameter, b->parameter);
++ }
+Index: crypto/openssl/crypto/bio/bss_dgram.c
+===================================================================
+--- crypto/openssl/crypto/bio/bss_dgram.c (revision 276867)
++++ crypto/openssl/crypto/bio/bss_dgram.c (working copy)
+@@ -982,7 +982,12 @@ static int dgram_sctp_free(BIO *a)
+ return 0;
+
+ data = (bio_dgram_sctp_data *)a->ptr;
+- if(data != NULL) OPENSSL_free(data);
++ if(data != NULL)
++ {
++ if(data->saved_message.data != NULL)
++ OPENSSL_free(data->saved_message.data);
++ OPENSSL_free(data);
++ }
+
+ return(1);
+ }
+@@ -1099,6 +1104,7 @@ static int dgram_sctp_read(BIO *b, char *out, int
+ dgram_sctp_write(data->saved_message.bio, data->saved_message.data,
+ data->saved_message.length);
+ OPENSSL_free(data->saved_message.data);
++ data->saved_message.data = NULL;
+ data->saved_message.length = 0;
+ }
+
+@@ -1258,9 +1264,11 @@ static int dgram_sctp_write(BIO *b, const char *in
+ if (data->save_shutdown && !BIO_dgram_sctp_wait_for_dry(b))
+ {
+ data->saved_message.bio = b;
+- data->saved_message.length = inl;
++ if (data->saved_message.data)
++ OPENSSL_free(data->saved_message.data);
+ data->saved_message.data = OPENSSL_malloc(inl);
+ memcpy(data->saved_message.data, in, inl);
++ data->saved_message.length = inl;
+ return inl;
+ }
+
+Index: crypto/openssl/crypto/bn/asm/mips.pl
+===================================================================
+--- crypto/openssl/crypto/bn/asm/mips.pl (revision 276867)
++++ crypto/openssl/crypto/bn/asm/mips.pl (working copy)
+@@ -1872,8 +1872,43 @@ ___
+
+ ($a_4,$a_5,$a_6,$a_7)=($b_0,$b_1,$b_2,$b_3);
+
++sub add_c2 () {
++my ($hi,$lo,$c0,$c1,$c2,
++ $warm, # !$warm denotes first call with specific sequence of
++ # $c_[XYZ] when there is no Z-carry to accumulate yet;
++ $an,$bn # these two are arguments for multiplication which
++ # result is used in *next* step [which is why it's
++ # commented as "forward multiplication" below];
++ )=@_;
+ $code.=<<___;
++ mflo $lo
++ mfhi $hi
++ $ADDU $c0,$lo
++ sltu $at,$c0,$lo
++ $MULTU $an,$bn # forward multiplication
++ $ADDU $c0,$lo
++ $ADDU $at,$hi
++ sltu $lo,$c0,$lo
++ $ADDU $c1,$at
++ $ADDU $hi,$lo
++___
++$code.=<<___ if (!$warm);
++ sltu $c2,$c1,$at
++ $ADDU $c1,$hi
++ sltu $hi,$c1,$hi
++ $ADDU $c2,$hi
++___
++$code.=<<___ if ($warm);
++ sltu $at,$c1,$at
++ $ADDU $c1,$hi
++ $ADDU $c2,$at
++ sltu $hi,$c1,$hi
++ $ADDU $c2,$hi
++___
++}
+
++$code.=<<___;
++
+ .align 5
+ .globl bn_sqr_comba8
+ .ent bn_sqr_comba8
+@@ -1920,25 +1955,14 @@ $code.=<<___;
+ sltu $at,$c_2,$t_1
+ $ADDU $c_3,$t_2,$at
+ $ST $c_2,$BNSZ($a0)
+-
++___
++ &add_c2($t_2,$t_1,$c_3,$c_1,$c_2,0,
++ $a_1,$a_1); # mul_add_c(a[1],b[1],c3,c1,c2);
++$code.=<<___;
+ mflo $t_1
+ mfhi $t_2
+- slt $c_2,$t_2,$zero
+- $SLL $t_2,1
+- $MULTU $a_1,$a_1 # mul_add_c(a[1],b[1],c3,c1,c2);
+- slt $a2,$t_1,$zero
+- $ADDU $t_2,$a2
+- $SLL $t_1,1
+ $ADDU $c_3,$t_1
+ sltu $at,$c_3,$t_1
+- $ADDU $t_2,$at
+- $ADDU $c_1,$t_2
+- sltu $at,$c_1,$t_2
+- $ADDU $c_2,$at
+- mflo $t_1
+- mfhi $t_2
+- $ADDU $c_3,$t_1
+- sltu $at,$c_3,$t_1
+ $MULTU $a_0,$a_3 # mul_add_c2(a[0],b[3],c1,c2,c3);
+ $ADDU $t_2,$at
+ $ADDU $c_1,$t_2
+@@ -1945,71 +1969,23 @@ $code.=<<___;
+ sltu $at,$c_1,$t_2
+ $ADDU $c_2,$at
+ $ST $c_3,2*$BNSZ($a0)
+-
+- mflo $t_1
+- mfhi $t_2
+- slt $c_3,$t_2,$zero
+- $SLL $t_2,1
+- $MULTU $a_1,$a_2 # mul_add_c2(a[1],b[2],c1,c2,c3);
+- slt $a2,$t_1,$zero
+- $ADDU $t_2,$a2
+- $SLL $t_1,1
+- $ADDU $c_1,$t_1
+- sltu $at,$c_1,$t_1
+- $ADDU $t_2,$at
+- $ADDU $c_2,$t_2
+- sltu $at,$c_2,$t_2
+- $ADDU $c_3,$at
+- mflo $t_1
+- mfhi $t_2
+- slt $at,$t_2,$zero
+- $ADDU $c_3,$at
+- $MULTU $a_4,$a_0 # mul_add_c2(a[4],b[0],c2,c3,c1);
+- $SLL $t_2,1
+- slt $a2,$t_1,$zero
+- $ADDU $t_2,$a2
+- $SLL $t_1,1
+- $ADDU $c_1,$t_1
+- sltu $at,$c_1,$t_1
+- $ADDU $t_2,$at
+- $ADDU $c_2,$t_2
+- sltu $at,$c_2,$t_2
+- $ADDU $c_3,$at
++___
++ &add_c2($t_2,$t_1,$c_1,$c_2,$c_3,0,
++ $a_1,$a_2); # mul_add_c2(a[1],b[2],c1,c2,c3);
++ &add_c2($t_2,$t_1,$c_1,$c_2,$c_3,1,
++ $a_4,$a_0); # mul_add_c2(a[4],b[0],c2,c3,c1);
++$code.=<<___;
+ $ST $c_1,3*$BNSZ($a0)
+-
++___
++ &add_c2($t_2,$t_1,$c_2,$c_3,$c_1,0,
++ $a_3,$a_1); # mul_add_c2(a[3],b[1],c2,c3,c1);
++ &add_c2($t_2,$t_1,$c_2,$c_3,$c_1,1,
++ $a_2,$a_2); # mul_add_c(a[2],b[2],c2,c3,c1);
++$code.=<<___;
+ mflo $t_1
+ mfhi $t_2
+- slt $c_1,$t_2,$zero
+- $SLL $t_2,1
+- $MULTU $a_3,$a_1 # mul_add_c2(a[3],b[1],c2,c3,c1);
+- slt $a2,$t_1,$zero
+- $ADDU $t_2,$a2
+- $SLL $t_1,1
+ $ADDU $c_2,$t_1
+ sltu $at,$c_2,$t_1
+- $ADDU $t_2,$at
+- $ADDU $c_3,$t_2
+- sltu $at,$c_3,$t_2
+- $ADDU $c_1,$at
+- mflo $t_1
+- mfhi $t_2
+- slt $at,$t_2,$zero
+- $ADDU $c_1,$at
+- $MULTU $a_2,$a_2 # mul_add_c(a[2],b[2],c2,c3,c1);
+- $SLL $t_2,1
+- slt $a2,$t_1,$zero
+- $ADDU $t_2,$a2
+- $SLL $t_1,1
+- $ADDU $c_2,$t_1
+- sltu $at,$c_2,$t_1
+- $ADDU $t_2,$at
+- $ADDU $c_3,$t_2
+- sltu $at,$c_3,$t_2
+- $ADDU $c_1,$at
+- mflo $t_1
+- mfhi $t_2
+- $ADDU $c_2,$t_1
+- sltu $at,$c_2,$t_1
+ $MULTU $a_0,$a_5 # mul_add_c2(a[0],b[5],c3,c1,c2);
+ $ADDU $t_2,$at
+ $ADDU $c_3,$t_2
+@@ -2016,101 +1992,27 @@ $code.=<<___;
+ sltu $at,$c_3,$t_2
+ $ADDU $c_1,$at
+ $ST $c_2,4*$BNSZ($a0)
+-
+- mflo $t_1
+- mfhi $t_2
+- slt $c_2,$t_2,$zero
+- $SLL $t_2,1
+- $MULTU $a_1,$a_4 # mul_add_c2(a[1],b[4],c3,c1,c2);
+- slt $a2,$t_1,$zero
+- $ADDU $t_2,$a2
+- $SLL $t_1,1
+- $ADDU $c_3,$t_1
+- sltu $at,$c_3,$t_1
+- $ADDU $t_2,$at
+- $ADDU $c_1,$t_2
+- sltu $at,$c_1,$t_2
+- $ADDU $c_2,$at
+- mflo $t_1
+- mfhi $t_2
+- slt $at,$t_2,$zero
+- $ADDU $c_2,$at
+- $MULTU $a_2,$a_3 # mul_add_c2(a[2],b[3],c3,c1,c2);
+- $SLL $t_2,1
+- slt $a2,$t_1,$zero
+- $ADDU $t_2,$a2
+- $SLL $t_1,1
+- $ADDU $c_3,$t_1
+- sltu $at,$c_3,$t_1
+- $ADDU $t_2,$at
+- $ADDU $c_1,$t_2
+- sltu $at,$c_1,$t_2
+- $ADDU $c_2,$at
+- mflo $t_1
+- mfhi $t_2
+- slt $at,$t_2,$zero
+- $MULTU $a_6,$a_0 # mul_add_c2(a[6],b[0],c1,c2,c3);
+- $ADDU $c_2,$at
+- $SLL $t_2,1
+- slt $a2,$t_1,$zero
+- $ADDU $t_2,$a2
+- $SLL $t_1,1
+- $ADDU $c_3,$t_1
+- sltu $at,$c_3,$t_1
+- $ADDU $t_2,$at
+- $ADDU $c_1,$t_2
+- sltu $at,$c_1,$t_2
+- $ADDU $c_2,$at
++___
++ &add_c2($t_2,$t_1,$c_3,$c_1,$c_2,0,
++ $a_1,$a_4); # mul_add_c2(a[1],b[4],c3,c1,c2);
++ &add_c2($t_2,$t_1,$c_3,$c_1,$c_2,1,
++ $a_2,$a_3); # mul_add_c2(a[2],b[3],c3,c1,c2);
++ &add_c2($t_2,$t_1,$c_3,$c_1,$c_2,1,
++ $a_6,$a_0); # mul_add_c2(a[6],b[0],c1,c2,c3);
++$code.=<<___;
+ $ST $c_3,5*$BNSZ($a0)
+-
++___
++ &add_c2($t_2,$t_1,$c_1,$c_2,$c_3,0,
++ $a_5,$a_1); # mul_add_c2(a[5],b[1],c1,c2,c3);
++ &add_c2($t_2,$t_1,$c_1,$c_2,$c_3,1,
++ $a_4,$a_2); # mul_add_c2(a[4],b[2],c1,c2,c3);
++ &add_c2($t_2,$t_1,$c_1,$c_2,$c_3,1,
++ $a_3,$a_3); # mul_add_c(a[3],b[3],c1,c2,c3);
++$code.=<<___;
+ mflo $t_1
+ mfhi $t_2
+- slt $c_3,$t_2,$zero
+- $SLL $t_2,1
+- $MULTU $a_5,$a_1 # mul_add_c2(a[5],b[1],c1,c2,c3);
+- slt $a2,$t_1,$zero
+- $ADDU $t_2,$a2
+- $SLL $t_1,1
+ $ADDU $c_1,$t_1
+ sltu $at,$c_1,$t_1
+- $ADDU $t_2,$at
+- $ADDU $c_2,$t_2
+- sltu $at,$c_2,$t_2
+- $ADDU $c_3,$at
+- mflo $t_1
+- mfhi $t_2
+- slt $at,$t_2,$zero
+- $ADDU $c_3,$at
+- $MULTU $a_4,$a_2 # mul_add_c2(a[4],b[2],c1,c2,c3);
+- $SLL $t_2,1
+- slt $a2,$t_1,$zero
+- $ADDU $t_2,$a2
+- $SLL $t_1,1
+- $ADDU $c_1,$t_1
+- sltu $at,$c_1,$t_1
+- $ADDU $t_2,$at
+- $ADDU $c_2,$t_2
+- sltu $at,$c_2,$t_2
+- $ADDU $c_3,$at
+- mflo $t_1
+- mfhi $t_2
+- slt $at,$t_2,$zero
+- $ADDU $c_3,$at
+- $MULTU $a_3,$a_3 # mul_add_c(a[3],b[3],c1,c2,c3);
+- $SLL $t_2,1
+- slt $a2,$t_1,$zero
+- $ADDU $t_2,$a2
+- $SLL $t_1,1
+- $ADDU $c_1,$t_1
+- sltu $at,$c_1,$t_1
+- $ADDU $t_2,$at
+- $ADDU $c_2,$t_2
+- sltu $at,$c_2,$t_2
+- $ADDU $c_3,$at
+- mflo $t_1
+- mfhi $t_2
+- $ADDU $c_1,$t_1
+- sltu $at,$c_1,$t_1
+ $MULTU $a_0,$a_7 # mul_add_c2(a[0],b[7],c2,c3,c1);
+ $ADDU $t_2,$at
+ $ADDU $c_2,$t_2
+@@ -2117,116 +2019,29 @@ $code.=<<___;
+ sltu $at,$c_2,$t_2
+ $ADDU $c_3,$at
+ $ST $c_1,6*$BNSZ($a0)
+-
+- mflo $t_1
+- mfhi $t_2
+- slt $c_1,$t_2,$zero
+- $SLL $t_2,1
+- $MULTU $a_1,$a_6 # mul_add_c2(a[1],b[6],c2,c3,c1);
+- slt $a2,$t_1,$zero
+- $ADDU $t_2,$a2
+- $SLL $t_1,1
+- $ADDU $c_2,$t_1
+- sltu $at,$c_2,$t_1
+- $ADDU $t_2,$at
+- $ADDU $c_3,$t_2
+- sltu $at,$c_3,$t_2
+- $ADDU $c_1,$at
+- mflo $t_1
+- mfhi $t_2
+- slt $at,$t_2,$zero
+- $ADDU $c_1,$at
+- $MULTU $a_2,$a_5 # mul_add_c2(a[2],b[5],c2,c3,c1);
+- $SLL $t_2,1
+- slt $a2,$t_1,$zero
+- $ADDU $t_2,$a2
+- $SLL $t_1,1
+- $ADDU $c_2,$t_1
+- sltu $at,$c_2,$t_1
+- $ADDU $t_2,$at
+- $ADDU $c_3,$t_2
+- sltu $at,$c_3,$t_2
+- $ADDU $c_1,$at
+- mflo $t_1
+- mfhi $t_2
+- slt $at,$t_2,$zero
+- $ADDU $c_1,$at
+- $MULTU $a_3,$a_4 # mul_add_c2(a[3],b[4],c2,c3,c1);
+- $SLL $t_2,1
+- slt $a2,$t_1,$zero
+- $ADDU $t_2,$a2
+- $SLL $t_1,1
+- $ADDU $c_2,$t_1
+- sltu $at,$c_2,$t_1
+- $ADDU $t_2,$at
+- $ADDU $c_3,$t_2
+- sltu $at,$c_3,$t_2
+- $ADDU $c_1,$at
+- mflo $t_1
+- mfhi $t_2
+- slt $at,$t_2,$zero
+- $ADDU $c_1,$at
+- $MULTU $a_7,$a_1 # mul_add_c2(a[7],b[1],c3,c1,c2);
+- $SLL $t_2,1
+- slt $a2,$t_1,$zero
+- $ADDU $t_2,$a2
+- $SLL $t_1,1
+- $ADDU $c_2,$t_1
+- sltu $at,$c_2,$t_1
+- $ADDU $t_2,$at
+- $ADDU $c_3,$t_2
+- sltu $at,$c_3,$t_2
+- $ADDU $c_1,$at
++___
++ &add_c2($t_2,$t_1,$c_2,$c_3,$c_1,0,
++ $a_1,$a_6); # mul_add_c2(a[1],b[6],c2,c3,c1);
++ &add_c2($t_2,$t_1,$c_2,$c_3,$c_1,1,
++ $a_2,$a_5); # mul_add_c2(a[2],b[5],c2,c3,c1);
++ &add_c2($t_2,$t_1,$c_2,$c_3,$c_1,1,
++ $a_3,$a_4); # mul_add_c2(a[3],b[4],c2,c3,c1);
++ &add_c2($t_2,$t_1,$c_2,$c_3,$c_1,1,
++ $a_7,$a_1); # mul_add_c2(a[7],b[1],c3,c1,c2);
++$code.=<<___;
+ $ST $c_2,7*$BNSZ($a0)
+-
++___
++ &add_c2($t_2,$t_1,$c_3,$c_1,$c_2,0,
++ $a_6,$a_2); # mul_add_c2(a[6],b[2],c3,c1,c2);
++ &add_c2($t_2,$t_1,$c_3,$c_1,$c_2,1,
++ $a_5,$a_3); # mul_add_c2(a[5],b[3],c3,c1,c2);
++ &add_c2($t_2,$t_1,$c_3,$c_1,$c_2,1,
++ $a_4,$a_4); # mul_add_c(a[4],b[4],c3,c1,c2);
++$code.=<<___;
+ mflo $t_1
+ mfhi $t_2
+- slt $c_2,$t_2,$zero
+- $SLL $t_2,1
+- $MULTU $a_6,$a_2 # mul_add_c2(a[6],b[2],c3,c1,c2);
+- slt $a2,$t_1,$zero
+- $ADDU $t_2,$a2
+- $SLL $t_1,1
+ $ADDU $c_3,$t_1
+ sltu $at,$c_3,$t_1
+- $ADDU $t_2,$at
+- $ADDU $c_1,$t_2
+- sltu $at,$c_1,$t_2
+- $ADDU $c_2,$at
+- mflo $t_1
+- mfhi $t_2
+- slt $at,$t_2,$zero
+- $ADDU $c_2,$at
+- $MULTU $a_5,$a_3 # mul_add_c2(a[5],b[3],c3,c1,c2);
+- $SLL $t_2,1
+- slt $a2,$t_1,$zero
+- $ADDU $t_2,$a2
+- $SLL $t_1,1
+- $ADDU $c_3,$t_1
+- sltu $at,$c_3,$t_1
+- $ADDU $t_2,$at
+- $ADDU $c_1,$t_2
+- sltu $at,$c_1,$t_2
+- $ADDU $c_2,$at
+- mflo $t_1
+- mfhi $t_2
+- slt $at,$t_2,$zero
+- $ADDU $c_2,$at
+- $MULTU $a_4,$a_4 # mul_add_c(a[4],b[4],c3,c1,c2);
+- $SLL $t_2,1
+- slt $a2,$t_1,$zero
+- $ADDU $t_2,$a2
+- $SLL $t_1,1
+- $ADDU $c_3,$t_1
+- sltu $at,$c_3,$t_1
+- $ADDU $t_2,$at
+- $ADDU $c_1,$t_2
+- sltu $at,$c_1,$t_2
+- $ADDU $c_2,$at
+- mflo $t_1
+- mfhi $t_2
+- $ADDU $c_3,$t_1
+- sltu $at,$c_3,$t_1
+ $MULTU $a_2,$a_7 # mul_add_c2(a[2],b[7],c1,c2,c3);
+ $ADDU $t_2,$at
+ $ADDU $c_1,$t_2
+@@ -2233,86 +2048,25 @@ $code.=<<___;
+ sltu $at,$c_1,$t_2
+ $ADDU $c_2,$at
+ $ST $c_3,8*$BNSZ($a0)
+-
+- mflo $t_1
+- mfhi $t_2
+- slt $c_3,$t_2,$zero
+- $SLL $t_2,1
+- $MULTU $a_3,$a_6 # mul_add_c2(a[3],b[6],c1,c2,c3);
+- slt $a2,$t_1,$zero
+- $ADDU $t_2,$a2
+- $SLL $t_1,1
+- $ADDU $c_1,$t_1
+- sltu $at,$c_1,$t_1
+- $ADDU $t_2,$at
+- $ADDU $c_2,$t_2
+- sltu $at,$c_2,$t_2
+- $ADDU $c_3,$at
+- mflo $t_1
+- mfhi $t_2
+- slt $at,$t_2,$zero
+- $ADDU $c_3,$at
+- $MULTU $a_4,$a_5 # mul_add_c2(a[4],b[5],c1,c2,c3);
+- $SLL $t_2,1
+- slt $a2,$t_1,$zero
+- $ADDU $t_2,$a2
+- $SLL $t_1,1
+- $ADDU $c_1,$t_1
+- sltu $at,$c_1,$t_1
+- $ADDU $t_2,$at
+- $ADDU $c_2,$t_2
+- sltu $at,$c_2,$t_2
+- $ADDU $c_3,$at
+- mflo $t_1
+- mfhi $t_2
+- slt $at,$t_2,$zero
+- $ADDU $c_3,$at
+- $MULTU $a_7,$a_3 # mul_add_c2(a[7],b[3],c2,c3,c1);
+- $SLL $t_2,1
+- slt $a2,$t_1,$zero
+- $ADDU $t_2,$a2
+- $SLL $t_1,1
+- $ADDU $c_1,$t_1
+- sltu $at,$c_1,$t_1
+- $ADDU $t_2,$at
+- $ADDU $c_2,$t_2
+- sltu $at,$c_2,$t_2
+- $ADDU $c_3,$at
++___
++ &add_c2($t_2,$t_1,$c_1,$c_2,$c_3,0,
++ $a_3,$a_6); # mul_add_c2(a[3],b[6],c1,c2,c3);
++ &add_c2($t_2,$t_1,$c_1,$c_2,$c_3,1,
++ $a_4,$a_5); # mul_add_c2(a[4],b[5],c1,c2,c3);
++ &add_c2($t_2,$t_1,$c_1,$c_2,$c_3,1,
++ $a_7,$a_3); # mul_add_c2(a[7],b[3],c2,c3,c1);
++$code.=<<___;
+ $ST $c_1,9*$BNSZ($a0)
+-
++___
++ &add_c2($t_2,$t_1,$c_2,$c_3,$c_1,0,
++ $a_6,$a_4); # mul_add_c2(a[6],b[4],c2,c3,c1);
++ &add_c2($t_2,$t_1,$c_2,$c_3,$c_1,1,
++ $a_5,$a_5); # mul_add_c(a[5],b[5],c2,c3,c1);
++$code.=<<___;
+ mflo $t_1
+ mfhi $t_2
+- slt $c_1,$t_2,$zero
+- $SLL $t_2,1
+- $MULTU $a_6,$a_4 # mul_add_c2(a[6],b[4],c2,c3,c1);
+- slt $a2,$t_1,$zero
+- $ADDU $t_2,$a2
+- $SLL $t_1,1
+ $ADDU $c_2,$t_1
+ sltu $at,$c_2,$t_1
+- $ADDU $t_2,$at
+- $ADDU $c_3,$t_2
+- sltu $at,$c_3,$t_2
+- $ADDU $c_1,$at
+- mflo $t_1
+- mfhi $t_2
+- slt $at,$t_2,$zero
+- $ADDU $c_1,$at
+- $MULTU $a_5,$a_5 # mul_add_c(a[5],b[5],c2,c3,c1);
+- $SLL $t_2,1
+- slt $a2,$t_1,$zero
+- $ADDU $t_2,$a2
+- $SLL $t_1,1
+- $ADDU $c_2,$t_1
+- sltu $at,$c_2,$t_1
+- $ADDU $t_2,$at
+- $ADDU $c_3,$t_2
+- sltu $at,$c_3,$t_2
+- $ADDU $c_1,$at
+- mflo $t_1
+- mfhi $t_2
+- $ADDU $c_2,$t_1
+- sltu $at,$c_2,$t_1
+ $MULTU $a_4,$a_7 # mul_add_c2(a[4],b[7],c3,c1,c2);
+ $ADDU $t_2,$at
+ $ADDU $c_3,$t_2
+@@ -2319,56 +2073,21 @@ $code.=<<___;
+ sltu $at,$c_3,$t_2
+ $ADDU $c_1,$at
+ $ST $c_2,10*$BNSZ($a0)
+-
+- mflo $t_1
+- mfhi $t_2
+- slt $c_2,$t_2,$zero
+- $SLL $t_2,1
+- $MULTU $a_5,$a_6 # mul_add_c2(a[5],b[6],c3,c1,c2);
+- slt $a2,$t_1,$zero
+- $ADDU $t_2,$a2
+- $SLL $t_1,1
+- $ADDU $c_3,$t_1
+- sltu $at,$c_3,$t_1
+- $ADDU $t_2,$at
+- $ADDU $c_1,$t_2
+- sltu $at,$c_1,$t_2
+- $ADDU $c_2,$at
+- mflo $t_1
+- mfhi $t_2
+- slt $at,$t_2,$zero
+- $ADDU $c_2,$at
+- $MULTU $a_7,$a_5 # mul_add_c2(a[7],b[5],c1,c2,c3);
+- $SLL $t_2,1
+- slt $a2,$t_1,$zero
+- $ADDU $t_2,$a2
+- $SLL $t_1,1
+- $ADDU $c_3,$t_1
+- sltu $at,$c_3,$t_1
+- $ADDU $t_2,$at
+- $ADDU $c_1,$t_2
+- sltu $at,$c_1,$t_2
+- $ADDU $c_2,$at
++___
++ &add_c2($t_2,$t_1,$c_3,$c_1,$c_2,0,
++ $a_5,$a_6); # mul_add_c2(a[5],b[6],c3,c1,c2);
++ &add_c2($t_2,$t_1,$c_3,$c_1,$c_2,1,
++ $a_7,$a_5); # mul_add_c2(a[7],b[5],c1,c2,c3);
++$code.=<<___;
+ $ST $c_3,11*$BNSZ($a0)
+-
++___
++ &add_c2($t_2,$t_1,$c_1,$c_2,$c_3,0,
++ $a_6,$a_6); # mul_add_c(a[6],b[6],c1,c2,c3);
++$code.=<<___;
+ mflo $t_1
+ mfhi $t_2
+- slt $c_3,$t_2,$zero
+- $SLL $t_2,1
+- $MULTU $a_6,$a_6 # mul_add_c(a[6],b[6],c1,c2,c3);
+- slt $a2,$t_1,$zero
+- $ADDU $t_2,$a2
+- $SLL $t_1,1
+ $ADDU $c_1,$t_1
+ sltu $at,$c_1,$t_1
+- $ADDU $t_2,$at
+- $ADDU $c_2,$t_2
+- sltu $at,$c_2,$t_2
+- $ADDU $c_3,$at
+- mflo $t_1
+- mfhi $t_2
+- $ADDU $c_1,$t_1
+- sltu $at,$c_1,$t_1
+ $MULTU $a_6,$a_7 # mul_add_c2(a[6],b[7],c2,c3,c1);
+ $ADDU $t_2,$at
+ $ADDU $c_2,$t_2
+@@ -2375,21 +2094,10 @@ $code.=<<___;
+ sltu $at,$c_2,$t_2
+ $ADDU $c_3,$at
+ $ST $c_1,12*$BNSZ($a0)
+-
+- mflo $t_1
+- mfhi $t_2
+- slt $c_1,$t_2,$zero
+- $SLL $t_2,1
+- $MULTU $a_7,$a_7 # mul_add_c(a[7],b[7],c3,c1,c2);
+- slt $a2,$t_1,$zero
+- $ADDU $t_2,$a2
+- $SLL $t_1,1
+- $ADDU $c_2,$t_1
+- sltu $at,$c_2,$t_1
+- $ADDU $t_2,$at
+- $ADDU $c_3,$t_2
+- sltu $at,$c_3,$t_2
+- $ADDU $c_1,$at
++___
++ &add_c2($t_2,$t_1,$c_2,$c_3,$c_1,0,
++ $a_7,$a_7); # mul_add_c(a[7],b[7],c3,c1,c2);
++$code.=<<___;
+ $ST $c_2,13*$BNSZ($a0)
+
+ mflo $t_1
+@@ -2457,25 +2165,14 @@ $code.=<<___;
+ sltu $at,$c_2,$t_1
+ $ADDU $c_3,$t_2,$at
+ $ST $c_2,$BNSZ($a0)
+-
++___
++ &add_c2($t_2,$t_1,$c_3,$c_1,$c_2,0,
++ $a_1,$a_1); # mul_add_c(a[1],b[1],c3,c1,c2);
++$code.=<<___;
+ mflo $t_1
+ mfhi $t_2
+- slt $c_2,$t_2,$zero
+- $SLL $t_2,1
+- $MULTU $a_1,$a_1 # mul_add_c(a[1],b[1],c3,c1,c2);
+- slt $a2,$t_1,$zero
+- $ADDU $t_2,$a2
+- $SLL $t_1,1
+ $ADDU $c_3,$t_1
+ sltu $at,$c_3,$t_1
+- $ADDU $t_2,$at
+- $ADDU $c_1,$t_2
+- sltu $at,$c_1,$t_2
+- $ADDU $c_2,$at
+- mflo $t_1
+- mfhi $t_2
+- $ADDU $c_3,$t_1
+- sltu $at,$c_3,$t_1
+ $MULTU $a_0,$a_3 # mul_add_c2(a[0],b[3],c1,c2,c3);
+ $ADDU $t_2,$at
+ $ADDU $c_1,$t_2
+@@ -2482,56 +2179,21 @@ $code.=<<___;
+ sltu $at,$c_1,$t_2
+ $ADDU $c_2,$at
+ $ST $c_3,2*$BNSZ($a0)
+-
+- mflo $t_1
+- mfhi $t_2
+- slt $c_3,$t_2,$zero
+- $SLL $t_2,1
+- $MULTU $a_1,$a_2 # mul_add_c(a2[1],b[2],c1,c2,c3);
+- slt $a2,$t_1,$zero
+- $ADDU $t_2,$a2
+- $SLL $t_1,1
+- $ADDU $c_1,$t_1
+- sltu $at,$c_1,$t_1
+- $ADDU $t_2,$at
+- $ADDU $c_2,$t_2
+- sltu $at,$c_2,$t_2
+- $ADDU $c_3,$at
+- mflo $t_1
+- mfhi $t_2
+- slt $at,$t_2,$zero
+- $ADDU $c_3,$at
+- $MULTU $a_3,$a_1 # mul_add_c2(a[3],b[1],c2,c3,c1);
+- $SLL $t_2,1
+- slt $a2,$t_1,$zero
+- $ADDU $t_2,$a2
+- $SLL $t_1,1
+- $ADDU $c_1,$t_1
+- sltu $at,$c_1,$t_1
+- $ADDU $t_2,$at
+- $ADDU $c_2,$t_2
+- sltu $at,$c_2,$t_2
+- $ADDU $c_3,$at
++___
++ &add_c2($t_2,$t_1,$c_1,$c_2,$c_3,0,
++ $a_1,$a_2); # mul_add_c2(a2[1],b[2],c1,c2,c3);
++ &add_c2($t_2,$t_1,$c_1,$c_2,$c_3,1,
++ $a_3,$a_1); # mul_add_c2(a[3],b[1],c2,c3,c1);
++$code.=<<___;
+ $ST $c_1,3*$BNSZ($a0)
+-
++___
++ &add_c2($t_2,$t_1,$c_2,$c_3,$c_1,0,
++ $a_2,$a_2); # mul_add_c(a[2],b[2],c2,c3,c1);
++$code.=<<___;
+ mflo $t_1
+ mfhi $t_2
+- slt $c_1,$t_2,$zero
+- $SLL $t_2,1
+- $MULTU $a_2,$a_2 # mul_add_c(a[2],b[2],c2,c3,c1);
+- slt $a2,$t_1,$zero
+- $ADDU $t_2,$a2
+- $SLL $t_1,1
+ $ADDU $c_2,$t_1
+ sltu $at,$c_2,$t_1
+- $ADDU $t_2,$at
+- $ADDU $c_3,$t_2
+- sltu $at,$c_3,$t_2
+- $ADDU $c_1,$at
+- mflo $t_1
+- mfhi $t_2
+- $ADDU $c_2,$t_1
+- sltu $at,$c_2,$t_1
+ $MULTU $a_2,$a_3 # mul_add_c2(a[2],b[3],c3,c1,c2);
+ $ADDU $t_2,$at
+ $ADDU $c_3,$t_2
+@@ -2538,21 +2200,10 @@ $code.=<<___;
+ sltu $at,$c_3,$t_2
+ $ADDU $c_1,$at
+ $ST $c_2,4*$BNSZ($a0)
+-
+- mflo $t_1
+- mfhi $t_2
+- slt $c_2,$t_2,$zero
+- $SLL $t_2,1
+- $MULTU $a_3,$a_3 # mul_add_c(a[3],b[3],c1,c2,c3);
+- slt $a2,$t_1,$zero
+- $ADDU $t_2,$a2
+- $SLL $t_1,1
+- $ADDU $c_3,$t_1
+- sltu $at,$c_3,$t_1
+- $ADDU $t_2,$at
+- $ADDU $c_1,$t_2
+- sltu $at,$c_1,$t_2
+- $ADDU $c_2,$at
++___
++ &add_c2($t_2,$t_1,$c_3,$c_1,$c_2,0,
++ $a_3,$a_3); # mul_add_c(a[3],b[3],c1,c2,c3);
++$code.=<<___;
+ $ST $c_3,5*$BNSZ($a0)
+
+ mflo $t_1
+Index: crypto/openssl/crypto/bn/asm/x86_64-gcc.c
+===================================================================
+--- crypto/openssl/crypto/bn/asm/x86_64-gcc.c (revision 276867)
++++ crypto/openssl/crypto/bn/asm/x86_64-gcc.c (working copy)
+@@ -273,6 +273,10 @@ BN_ULONG bn_sub_words(BN_ULONG *r, BN_ULONG *a, BN
+ /* sqr_add_c(a,i,c0,c1,c2) -- c+=a[i]^2 for three word number c=(c2,c1,c0) */
+ /* sqr_add_c2(a,i,c0,c1,c2) -- c+=2*a[i]*a[j] for three word number c=(c2,c1,c0) */
+
++/*
++ * Keep in mind that carrying into high part of multiplication result
++ * can not overflow, because it cannot be all-ones.
++ */
+ #if 0
+ /* original macros are kept for reference purposes */
+ #define mul_add_c(a,b,c0,c1,c2) { \
+@@ -287,10 +291,10 @@ BN_ULONG bn_sub_words(BN_ULONG *r, BN_ULONG *a, BN
+ BN_ULONG ta=(a),tb=(b),t0; \
+ t1 = BN_UMULT_HIGH(ta,tb); \
+ t0 = ta * tb; \
+- t2 = t1+t1; c2 += (t2neg=rand_neg();
++ BN_sqr(c,a,ctx);
+ if (bp != NULL)
+ {
+ if (!results)
+ {
+- BN_print(bp,&a);
++ BN_print(bp,a);
+ BIO_puts(bp," * ");
+- BN_print(bp,&a);
++ BN_print(bp,a);
+ BIO_puts(bp," - ");
+ }
+- BN_print(bp,&c);
++ BN_print(bp,c);
+ BIO_puts(bp,"\n");
+ }
+- BN_div(&d,&e,&c,&a,ctx);
+- BN_sub(&d,&d,&a);
+- if(!BN_is_zero(&d) || !BN_is_zero(&e))
+- {
+- fprintf(stderr,"Square test failed!\n");
+- return 0;
+- }
++ BN_div(d,e,c,a,ctx);
++ BN_sub(d,d,a);
++ if(!BN_is_zero(d) || !BN_is_zero(e))
++ {
++ fprintf(stderr,"Square test failed!\n");
++ goto err;
++ }
+ }
+- BN_free(&a);
+- BN_free(&c);
+- BN_free(&d);
+- BN_free(&e);
+- return(1);
++
++ /* Regression test for a BN_sqr overflow bug. */
++ BN_hex2bn(&a,
++ "80000000000000008000000000000001FFFFFFFFFFFFFFFE0000000000000000");
++ BN_sqr(c, a, ctx);
++ if (bp != NULL)
++ {
++ if (!results)
++ {
++ BN_print(bp,a);
++ BIO_puts(bp," * ");
++ BN_print(bp,a);
++ BIO_puts(bp," - ");
++ }
++ BN_print(bp,c);
++ BIO_puts(bp,"\n");
++ }
++ BN_mul(d, a, a, ctx);
++ if (BN_cmp(c, d))
++ {
++ fprintf(stderr, "Square test failed: BN_sqr and BN_mul produce "
++ "different results!\n");
++ goto err;
++ }
++
++ /* Regression test for a BN_sqr overflow bug. */
++ BN_hex2bn(&a,
++ "80000000000000000000000080000001FFFFFFFE000000000000000000000000");
++ BN_sqr(c, a, ctx);
++ if (bp != NULL)
++ {
++ if (!results)
++ {
++ BN_print(bp,a);
++ BIO_puts(bp," * ");
++ BN_print(bp,a);
++ BIO_puts(bp," - ");
++ }
++ BN_print(bp,c);
++ BIO_puts(bp,"\n");
++ }
++ BN_mul(d, a, a, ctx);
++ if (BN_cmp(c, d))
++ {
++ fprintf(stderr, "Square test failed: BN_sqr and BN_mul produce "
++ "different results!\n");
++ goto err;
++ }
++ ret = 1;
++err:
++ if (a != NULL) BN_free(a);
++ if (c != NULL) BN_free(c);
++ if (d != NULL) BN_free(d);
++ if (e != NULL) BN_free(e);
++ return ret;
+ }
+
+ int test_mont(BIO *bp, BN_CTX *ctx)
+Index: crypto/openssl/crypto/dsa/dsa_asn1.c
+===================================================================
+--- crypto/openssl/crypto/dsa/dsa_asn1.c (revision 276867)
++++ crypto/openssl/crypto/dsa/dsa_asn1.c (working copy)
+@@ -176,13 +176,25 @@ int DSA_verify(int type, const unsigned char *dgst
+ const unsigned char *sigbuf, int siglen, DSA *dsa)
+ {
+ DSA_SIG *s;
++ const unsigned char *p = sigbuf;
++ unsigned char *der = NULL;
++ int derlen = -1;
+ int ret=-1;
+
+ s = DSA_SIG_new();
+ if (s == NULL) return(ret);
+- if (d2i_DSA_SIG(&s,&sigbuf,siglen) == NULL) goto err;
++ if (d2i_DSA_SIG(&s,&p,siglen) == NULL) goto err;
++ /* Ensure signature uses DER and doesn't have trailing garbage */
++ derlen = i2d_DSA_SIG(s, &der);
++ if (derlen != siglen || memcmp(sigbuf, der, derlen))
++ goto err;
+ ret=DSA_do_verify(dgst,dgst_len,s,dsa);
+ err:
++ if (derlen > 0)
++ {
++ OPENSSL_cleanse(der, derlen);
++ OPENSSL_free(der);
++ }
+ DSA_SIG_free(s);
+ return(ret);
+ }
+Index: crypto/openssl/crypto/ecdsa/ecs_vrf.c
+===================================================================
+--- crypto/openssl/crypto/ecdsa/ecs_vrf.c (revision 276867)
++++ crypto/openssl/crypto/ecdsa/ecs_vrf.c (working copy)
+@@ -57,6 +57,7 @@
+ */
+
+ #include "ecs_locl.h"
++#include "cryptlib.h"
+ #ifndef OPENSSL_NO_ENGINE
+ #include
+ #endif
+@@ -84,13 +85,25 @@ int ECDSA_verify(int type, const unsigned char *dg
+ const unsigned char *sigbuf, int sig_len, EC_KEY *eckey)
+ {
+ ECDSA_SIG *s;
++ const unsigned char *p = sigbuf;
++ unsigned char *der = NULL;
++ int derlen = -1;
+ int ret=-1;
+
+ s = ECDSA_SIG_new();
+ if (s == NULL) return(ret);
+- if (d2i_ECDSA_SIG(&s, &sigbuf, sig_len) == NULL) goto err;
++ if (d2i_ECDSA_SIG(&s, &p, sig_len) == NULL) goto err;
++ /* Ensure signature uses DER and doesn't have trailing garbage */
++ derlen = i2d_ECDSA_SIG(s, &der);
++ if (derlen != sig_len || memcmp(sigbuf, der, derlen))
++ goto err;
+ ret=ECDSA_do_verify(dgst, dgst_len, s, eckey);
+ err:
++ if (derlen > 0)
++ {
++ OPENSSL_cleanse(der, derlen);
++ OPENSSL_free(der);
++ }
+ ECDSA_SIG_free(s);
+ return(ret);
+ }
+Index: crypto/openssl/crypto/x509/x509.h
+===================================================================
+--- crypto/openssl/crypto/x509/x509.h (revision 276867)
++++ crypto/openssl/crypto/x509/x509.h (working copy)
+@@ -768,6 +768,7 @@ int X509_ALGOR_set0(X509_ALGOR *alg, ASN1_OBJECT *
+ void X509_ALGOR_get0(ASN1_OBJECT **paobj, int *pptype, void **ppval,
+ X509_ALGOR *algor);
+ void X509_ALGOR_set_md(X509_ALGOR *alg, const EVP_MD *md);
++int X509_ALGOR_cmp(const X509_ALGOR *a, const X509_ALGOR *b);
+
+ X509_NAME *X509_NAME_dup(X509_NAME *xn);
+ X509_NAME_ENTRY *X509_NAME_ENTRY_dup(X509_NAME_ENTRY *ne);
+Index: crypto/openssl/crypto/x509/x_all.c
+===================================================================
+--- crypto/openssl/crypto/x509/x_all.c (revision 276867)
++++ crypto/openssl/crypto/x509/x_all.c (working copy)
+@@ -72,6 +72,8 @@
+
+ int X509_verify(X509 *a, EVP_PKEY *r)
+ {
++ if (X509_ALGOR_cmp(a->sig_alg, a->cert_info->signature))
++ return 0;
+ return(ASN1_item_verify(ASN1_ITEM_rptr(X509_CINF),a->sig_alg,
+ a->signature,a->cert_info,r));
+ }
+Index: crypto/openssl/doc/ssl/SSL_CTX_set_options.pod
+===================================================================
+--- crypto/openssl/doc/ssl/SSL_CTX_set_options.pod (revision 276867)
++++ crypto/openssl/doc/ssl/SSL_CTX_set_options.pod (working copy)
+@@ -158,15 +158,7 @@ temporary/ephemeral DH parameters are used.
+
+ =item SSL_OP_EPHEMERAL_RSA
+
+-Always use ephemeral (temporary) RSA key when doing RSA operations
+-(see L).
+-According to the specifications this is only done, when a RSA key
+-can only be used for signature operations (namely under export ciphers
+-with restricted RSA keylength). By setting this option, ephemeral
+-RSA keys are always used. This option breaks compatibility with the
+-SSL/TLS specifications and may lead to interoperability problems with
+-clients and should therefore never be used. Ciphers with EDH (ephemeral
+-Diffie-Hellman) key exchange should be used instead.
++This option is no longer implemented and is treated as no op.
+
+ =item SSL_OP_CIPHER_SERVER_PREFERENCE
+
+Index: crypto/openssl/doc/ssl/SSL_CTX_set_tmp_rsa_callback.pod
+===================================================================
+--- crypto/openssl/doc/ssl/SSL_CTX_set_tmp_rsa_callback.pod (revision 276867)
++++ crypto/openssl/doc/ssl/SSL_CTX_set_tmp_rsa_callback.pod (working copy)
+@@ -74,22 +74,15 @@ exchange and use EDH (Ephemeral Diffie-Hellman) ke
+ in order to achieve forward secrecy (see
+ L).
+
+-On OpenSSL servers ephemeral RSA key exchange is therefore disabled by default
+-and must be explicitly enabled using the SSL_OP_EPHEMERAL_RSA option of
+-L, violating the TLS/SSL
+-standard. When ephemeral RSA key exchange is required for export ciphers,
+-it will automatically be used without this option!
++An application may either directly specify the key or can supply the key via a
++callback function. The callback approach has the advantage, that the callback
++may generate the key only in case it is actually needed. As the generation of a
++RSA key is however costly, it will lead to a significant delay in the handshake
++procedure. Another advantage of the callback function is that it can supply
++keys of different size while the explicit setting of the key is only useful for
++key size of 512 bits to satisfy the export restricted ciphers and does give
++away key length if a longer key would be allowed.
+
+-An application may either directly specify the key or can supply the key via
+-a callback function. The callback approach has the advantage, that the
+-callback may generate the key only in case it is actually needed. As the
+-generation of a RSA key is however costly, it will lead to a significant
+-delay in the handshake procedure. Another advantage of the callback function
+-is that it can supply keys of different size (e.g. for SSL_OP_EPHEMERAL_RSA
+-usage) while the explicit setting of the key is only useful for key size of
+-512 bits to satisfy the export restricted ciphers and does give away key length
+-if a longer key would be allowed.
+-
+ The B is called with the B needed and
+ the B information. The B flag is set, when the
+ ephemeral RSA key exchange is performed with an export cipher.
+Index: crypto/openssl/ssl/d1_pkt.c
+===================================================================
+--- crypto/openssl/ssl/d1_pkt.c (revision 276867)
++++ crypto/openssl/ssl/d1_pkt.c (working copy)
+@@ -212,7 +212,7 @@ dtls1_buffer_record(SSL *s, record_pqueue *queue,
+ /* Limit the size of the queue to prevent DOS attacks */
+ if (pqueue_size(queue->q) >= 100)
+ return 0;
+-
++
+ rdata = OPENSSL_malloc(sizeof(DTLS1_RECORD_DATA));
+ item = pitem_new(priority, rdata);
+ if (rdata == NULL || item == NULL)
+@@ -247,9 +247,11 @@ dtls1_buffer_record(SSL *s, record_pqueue *queue,
+ if (!ssl3_setup_buffers(s))
+ {
+ SSLerr(SSL_F_DTLS1_BUFFER_RECORD, ERR_R_INTERNAL_ERROR);
++ if (rdata->rbuf.buf != NULL)
++ OPENSSL_free(rdata->rbuf.buf);
+ OPENSSL_free(rdata);
+ pitem_free(item);
+- return(0);
++ return(-1);
+ }
+
+ /* insert should not fail, since duplicates are dropped */
+@@ -256,9 +258,11 @@ dtls1_buffer_record(SSL *s, record_pqueue *queue,
+ if (pqueue_insert(queue->q, item) == NULL)
+ {
+ SSLerr(SSL_F_DTLS1_BUFFER_RECORD, ERR_R_INTERNAL_ERROR);
++ if (rdata->rbuf.buf != NULL)
++ OPENSSL_free(rdata->rbuf.buf);
+ OPENSSL_free(rdata);
+ pitem_free(item);
+- return(0);
++ return(-1);
+ }
+
+ return(1);
+@@ -314,8 +318,9 @@ dtls1_process_buffered_records(SSL *s)
+ dtls1_get_unprocessed_record(s);
+ if ( ! dtls1_process_record(s))
+ return(0);
+- dtls1_buffer_record(s, &(s->d1->processed_rcds),
+- s->s3->rrec.seq_num);
++ if(dtls1_buffer_record(s, &(s->d1->processed_rcds),
++ s->s3->rrec.seq_num)<0)
++ return -1;
+ }
+ }
+
+@@ -530,7 +535,6 @@ printf("\n");
+
+ /* we have pulled in a full packet so zero things */
+ s->packet_length=0;
+- dtls1_record_bitmap_update(s, &(s->d1->bitmap));/* Mark receipt of record. */
+ return(1);
+
+ f_err:
+@@ -563,7 +567,8 @@ int dtls1_get_record(SSL *s)
+
+ /* The epoch may have changed. If so, process all the
+ * pending records. This is a non-blocking operation. */
+- dtls1_process_buffered_records(s);
++ if(dtls1_process_buffered_records(s)<0)
++ return -1;
+
+ /* if we're renegotiating, then there may be buffered records */
+ if (dtls1_get_processed_record(s))
+@@ -642,8 +647,6 @@ again:
+ /* now s->packet_length == DTLS1_RT_HEADER_LENGTH */
+ i=rr->length;
+ n=ssl3_read_n(s,i,i,1);
+- if (n <= 0) return(n); /* error or non-blocking io */
+-
+ /* this packet contained a partial record, dump it */
+ if ( n != i)
+ {
+@@ -678,7 +681,8 @@ again:
+ * would be dropped unnecessarily.
+ */
+ if (!(s->d1->listen && rr->type == SSL3_RT_HANDSHAKE &&
+- *p == SSL3_MT_CLIENT_HELLO) &&
++ s->packet_length > DTLS1_RT_HEADER_LENGTH &&
++ s->packet[DTLS1_RT_HEADER_LENGTH] == SSL3_MT_CLIENT_HELLO) &&
+ !dtls1_record_replay_check(s, bitmap))
+ {
+ rr->length = 0;
+@@ -701,7 +705,9 @@ again:
+ {
+ if ((SSL_in_init(s) || s->in_handshake) && !s->d1->listen)
+ {
+- dtls1_buffer_record(s, &(s->d1->unprocessed_rcds), rr->seq_num);
++ if(dtls1_buffer_record(s, &(s->d1->unprocessed_rcds), rr->seq_num)<0)
++ return -1;
++ dtls1_record_bitmap_update(s, bitmap);/* Mark receipt of record. */
+ }
+ rr->length = 0;
+ s->packet_length = 0;
+@@ -714,6 +720,7 @@ again:
+ s->packet_length = 0; /* dump this record */
+ goto again; /* get another record */
+ }
++ dtls1_record_bitmap_update(s, bitmap);/* Mark receipt of record. */
+
+ return(1);
+
+@@ -865,7 +872,11 @@ start:
+ * buffer the application data for later processing rather
+ * than dropping the connection.
+ */
+- dtls1_buffer_record(s, &(s->d1->buffered_app_data), rr->seq_num);
++ if(dtls1_buffer_record(s, &(s->d1->buffered_app_data), rr->seq_num)<0)
++ {
++ SSLerr(SSL_F_DTLS1_READ_BYTES, ERR_R_INTERNAL_ERROR);
++ return -1;
++ }
+ rr->length = 0;
+ goto start;
+ }
+Index: crypto/openssl/ssl/d1_srvr.c
+===================================================================
+--- crypto/openssl/ssl/d1_srvr.c (revision 276867)
++++ crypto/openssl/ssl/d1_srvr.c (working copy)
+@@ -450,24 +450,15 @@ int dtls1_accept(SSL *s)
+ case SSL3_ST_SW_KEY_EXCH_B:
+ alg_k = s->s3->tmp.new_cipher->algorithm_mkey;
+
+- /* clear this, it may get reset by
+- * send_server_key_exchange */
+- if ((s->options & SSL_OP_EPHEMERAL_RSA)
+-#ifndef OPENSSL_NO_KRB5
+- && !(alg_k & SSL_kKRB5)
+-#endif /* OPENSSL_NO_KRB5 */
+- )
+- /* option SSL_OP_EPHEMERAL_RSA sends temporary RSA key
+- * even when forbidden by protocol specs
+- * (handshake may fail as clients are not required to
+- * be able to handle this) */
+- s->s3->tmp.use_rsa_tmp=1;
+- else
+- s->s3->tmp.use_rsa_tmp=0;
++ /*
++ * clear this, it may get reset by
++ * send_server_key_exchange
++ */
++ s->s3->tmp.use_rsa_tmp=0;
+
+ /* only send if a DH key exchange or
+ * RSA but we have a sign only certificate */
+- if (s->s3->tmp.use_rsa_tmp
++ if (0
+ /* PSK: send ServerKeyExchange if PSK identity
+ * hint if provided */
+ #ifndef OPENSSL_NO_PSK
+Index: crypto/openssl/ssl/s23_srvr.c
+===================================================================
+--- crypto/openssl/ssl/s23_srvr.c (revision 276867)
++++ crypto/openssl/ssl/s23_srvr.c (working copy)
+@@ -602,12 +602,14 @@ int ssl23_get_client_hello(SSL *s)
+ if ((type == 2) || (type == 3))
+ {
+ /* we have SSLv3/TLSv1 (type 2: SSL2 style, type 3: SSL3/TLS style) */
+- s->method = ssl23_get_server_method(s->version);
+- if (s->method == NULL)
++ const SSL_METHOD *new_method;
++ new_method = ssl23_get_server_method(s->version);
++ if (new_method == NULL)
+ {
+ SSLerr(SSL_F_SSL23_GET_CLIENT_HELLO,SSL_R_UNSUPPORTED_PROTOCOL);
+ goto err;
+ }
++ s->method = new_method;
+
+ if (!ssl_init_wbio_buffer(s,1)) goto err;
+
+Index: crypto/openssl/ssl/s3_clnt.c
+===================================================================
+--- crypto/openssl/ssl/s3_clnt.c (revision 276867)
++++ crypto/openssl/ssl/s3_clnt.c (working copy)
+@@ -1295,6 +1295,8 @@ int ssl3_get_key_exchange(SSL *s)
+ int encoded_pt_len = 0;
+ #endif
+
++ EVP_MD_CTX_init(&md_ctx);
++
+ /* use same message size as in ssl3_get_certificate_request()
+ * as ServerKeyExchange message may be skipped */
+ n=s->method->ssl_get_message(s,
+@@ -1305,14 +1307,26 @@ int ssl3_get_key_exchange(SSL *s)
+ &ok);
+ if (!ok) return((int)n);
+
++ alg_k=s->s3->tmp.new_cipher->algorithm_mkey;
++
+ if (s->s3->tmp.message_type != SSL3_MT_SERVER_KEY_EXCHANGE)
+ {
++ /*
++ * Can't skip server key exchange if this is an ephemeral
++ * ciphersuite.
++ */
++ if (alg_k & (SSL_kEDH|SSL_kEECDH))
++ {
++ SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_UNEXPECTED_MESSAGE);
++ al = SSL_AD_UNEXPECTED_MESSAGE;
++ goto f_err;
++ }
+ #ifndef OPENSSL_NO_PSK
+ /* In plain PSK ciphersuite, ServerKeyExchange can be
+ omitted if no identity hint is sent. Set
+ session->sess_cert anyway to avoid problems
+ later.*/
+- if (s->s3->tmp.new_cipher->algorithm_mkey & SSL_kPSK)
++ if (alg_k & SSL_kPSK)
+ {
+ s->session->sess_cert=ssl_sess_cert_new();
+ if (s->ctx->psk_identity_hint)
+@@ -1357,9 +1371,7 @@ int ssl3_get_key_exchange(SSL *s)
+ /* Total length of the parameters including the length prefix */
+ param_len=0;
+
+- alg_k=s->s3->tmp.new_cipher->algorithm_mkey;
+ alg_a=s->s3->tmp.new_cipher->algorithm_auth;
+- EVP_MD_CTX_init(&md_ctx);
+
+ al=SSL_AD_DECODE_ERROR;
+
+@@ -1543,6 +1555,13 @@ int ssl3_get_key_exchange(SSL *s)
+ #ifndef OPENSSL_NO_RSA
+ if (alg_k & SSL_kRSA)
+ {
++ /* Temporary RSA keys only allowed in export ciphersuites */
++ if (!SSL_C_IS_EXPORT(s->s3->tmp.new_cipher))
++ {
++ al=SSL_AD_UNEXPECTED_MESSAGE;
++ SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_UNEXPECTED_MESSAGE);
++ goto f_err;
++ }
+ if ((rsa=RSA_new()) == NULL)
+ {
+ SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,ERR_R_MALLOC_FAILURE);
+Index: crypto/openssl/ssl/s3_pkt.c
+===================================================================
+--- crypto/openssl/ssl/s3_pkt.c (revision 276867)
++++ crypto/openssl/ssl/s3_pkt.c (working copy)
+@@ -183,6 +183,8 @@ int ssl3_read_n(SSL *s, int n, int max, int extend
+ * at once (as long as it fits into the buffer). */
+ if (SSL_version(s) == DTLS1_VERSION || SSL_version(s) == DTLS1_BAD_VER)
+ {
++ if (left == 0 && extend)
++ return 0;
+ if (left > 0 && n > left)
+ n = left;
+ }
+Index: crypto/openssl/ssl/s3_srvr.c
+===================================================================
+--- crypto/openssl/ssl/s3_srvr.c (revision 276867)
++++ crypto/openssl/ssl/s3_srvr.c (working copy)
+@@ -441,20 +441,11 @@ int ssl3_accept(SSL *s)
+ case SSL3_ST_SW_KEY_EXCH_B:
+ alg_k = s->s3->tmp.new_cipher->algorithm_mkey;
+
+- /* clear this, it may get reset by
+- * send_server_key_exchange */
+- if ((s->options & SSL_OP_EPHEMERAL_RSA)
+-#ifndef OPENSSL_NO_KRB5
+- && !(alg_k & SSL_kKRB5)
+-#endif /* OPENSSL_NO_KRB5 */
+- )
+- /* option SSL_OP_EPHEMERAL_RSA sends temporary RSA key
+- * even when forbidden by protocol specs
+- * (handshake may fail as clients are not required to
+- * be able to handle this) */
+- s->s3->tmp.use_rsa_tmp=1;
+- else
+- s->s3->tmp.use_rsa_tmp=0;
++ /*
++ * clear this, it may get reset by
++ * send_server_key_exchange
++ */
++ s->s3->tmp.use_rsa_tmp=0;
+
+
+ /* only send if a DH key exchange, fortezza or
+@@ -468,7 +459,7 @@ int ssl3_accept(SSL *s)
+ * server certificate contains the server's
+ * public key for key exchange.
+ */
+- if (s->s3->tmp.use_rsa_tmp
++ if (0
+ /* PSK: send ServerKeyExchange if PSK identity
+ * hint if provided */
+ #ifndef OPENSSL_NO_PSK
+@@ -2958,7 +2949,7 @@ int ssl3_get_cert_verify(SSL *s)
+ if (s->s3->tmp.message_type != SSL3_MT_CERTIFICATE_VERIFY)
+ {
+ s->s3->tmp.reuse_message=1;
+- if ((peer != NULL) && (type & EVP_PKT_SIGN))
++ if (peer != NULL)
+ {
+ al=SSL_AD_UNEXPECTED_MESSAGE;
+ SSLerr(SSL_F_SSL3_GET_CERT_VERIFY,SSL_R_MISSING_VERIFY_MESSAGE);
+Index: crypto/openssl/ssl/ssl.h
+===================================================================
+--- crypto/openssl/ssl/ssl.h (revision 276867)
++++ crypto/openssl/ssl/ssl.h (working copy)
+@@ -596,9 +596,8 @@ struct ssl_session_st
+ #define SSL_OP_SINGLE_ECDH_USE 0x00080000L
+ /* If set, always create a new key when using tmp_dh parameters */
+ #define SSL_OP_SINGLE_DH_USE 0x00100000L
+-/* Set to always use the tmp_rsa key when doing RSA operations,
+- * even when this violates protocol specs */
+-#define SSL_OP_EPHEMERAL_RSA 0x00200000L
++/* Does nothing: retained for compatibiity */
++#define SSL_OP_EPHEMERAL_RSA 0x0
+ /* Set on servers to choose the cipher according to the server's
+ * preferences */
+ #define SSL_OP_CIPHER_SERVER_PREFERENCE 0x00400000L
+Index: crypto/openssl/ssl/ssl_lib.c
+===================================================================
+--- crypto/openssl/ssl/ssl_lib.c (revision 276867)
++++ crypto/openssl/ssl/ssl_lib.c (working copy)
+@@ -2996,10 +2996,32 @@ SSL_CTX *SSL_set_SSL_CTX(SSL *ssl, SSL_CTX* ctx)
+ }
+ ssl_cert_free(ocert);
+ }
++
++ /*
++ * Program invariant: |sid_ctx| has fixed size (SSL_MAX_SID_CTX_LENGTH),
++ * so setter APIs must prevent invalid lengths from entering the system.
++ */
++ OPENSSL_assert(ssl->sid_ctx_length <= sizeof(ssl->sid_ctx));
++
++ /*
++ * If the session ID context matches that of the parent SSL_CTX,
++ * inherit it from the new SSL_CTX as well. If however the context does
++ * not match (i.e., it was set per-ssl with SSL_set_session_id_context),
++ * leave it unchanged.
++ */
++ if ((ssl->ctx != NULL) &&
++ (ssl->sid_ctx_length == ssl->ctx->sid_ctx_length) &&
++ (memcmp(ssl->sid_ctx, ssl->ctx->sid_ctx, ssl->sid_ctx_length) == 0))
++ {
++ ssl->sid_ctx_length = ctx->sid_ctx_length;
++ memcpy(&ssl->sid_ctx, &ctx->sid_ctx, sizeof(ssl->sid_ctx));
++ }
++
+ CRYPTO_add(&ctx->references,1,CRYPTO_LOCK_SSL_CTX);
+ if (ssl->ctx != NULL)
+ SSL_CTX_free(ssl->ctx); /* decrement reference count */
+ ssl->ctx = ctx;
++
+ return(ssl->ctx);
+ }
+
+Index: crypto/openssl/util/libeay.num
+===================================================================
+--- crypto/openssl/util/libeay.num (revision 276867)
++++ crypto/openssl/util/libeay.num (working copy)
+@@ -1807,6 +1807,7 @@ ASN1_UTCTIME_get 2350 NOEXI
+ X509_REQ_digest 2362 EXIST::FUNCTION:EVP
+ X509_CRL_digest 2391 EXIST::FUNCTION:EVP
+ d2i_ASN1_SET_OF_PKCS7 2397 NOEXIST::FUNCTION:
++X509_ALGOR_cmp 2398 EXIST::FUNCTION:
+ EVP_CIPHER_CTX_set_key_length 2399 EXIST::FUNCTION:
+ EVP_CIPHER_CTX_ctrl 2400 EXIST::FUNCTION:
+ BN_mod_exp_mont_word 2401 EXIST::FUNCTION:
diff --git a/share/security/patches/SA-15:01/openssl-10.1.patch.asc b/share/security/patches/SA-15:01/openssl-10.1.patch.asc
new file mode 100644
index 0000000000..6cec0ffd67
--- /dev/null
+++ b/share/security/patches/SA-15:01/openssl-10.1.patch.asc
@@ -0,0 +1,17 @@
+-----BEGIN PGP SIGNATURE-----
+Version: GnuPG v2.1.1 (FreeBSD)
+
+iQIcBAABCgAGBQJUtuBQAAoJEO1n7NZdz2rnQ8EP/2y6JS8OIAONv0dZbosjDfVL
+QA8/nV3Wla8RD9BceamC2lShwlhD4Zzf6DspQDyIHQ9jmSov7YPWkgSXBh2XwVu7
+0CURYvCllJa8u6ZM7bJMZSwDbvntcnl8oofOwnRCQgO2Jc36jJoASm8H2f1vvR0q
+8eC4488yXTrP+Q6QVW2QMWd8XMusk7pPDkx208h0C40PDEP7h+zgj4P+qrkfXfPo
+js2AL/QkgZtuNKUxruomoeABeFiIO6cFA3gYAdUaxHz++c9M+94fjgrvF6xZCpNj
+bYGe0beU5Sh7nIpH7ZaLOIB4rVNH/0cm+3RJRDeRv+QvF2dn/tL0xY5A8RTG0jff
+p9vvrjnOmVEIeDOkGT4fHUG5LOPRa53GxWGsuTMlq9nDV6nYAiDbeaRJY/UqrKId
+/cb6MQADKYCc1kN4UfZQuBfusVhHt0Dfn1L0QNBSvXvS27wakae+O765UNJ4Y3OB
+FRbvMJTJZyETQaW1fURQzKfVpjOImQ2yJxcxzhjvHU4v9nLCXHlk8aUZ+QWYMBgJ
+5PCM4j9vA2h13B4YrLceY5FFSGgu1UUVa4MLV1drxVzdbMtlbZbz1As7eVnWzMMG
+9cWqNZWMbsJBPQoc/c3RCwDDj74laj9RfvKZOctnC3JOslgd2ElulMqGVhMEBNrE
+2pI4TaI8z1hhlzn7svMN
+=X57u
+-----END PGP SIGNATURE-----
diff --git a/share/security/patches/SA-15:01/openssl-9.3.patch b/share/security/patches/SA-15:01/openssl-9.3.patch
new file mode 100644
index 0000000000..610f106912
--- /dev/null
+++ b/share/security/patches/SA-15:01/openssl-9.3.patch
@@ -0,0 +1,1582 @@
+Index: crypto/openssl/crypto/asn1/a_bitstr.c
+===================================================================
+--- crypto/openssl/crypto/asn1/a_bitstr.c (revision 276867)
++++ crypto/openssl/crypto/asn1/a_bitstr.c (working copy)
+@@ -136,11 +136,16 @@ ASN1_BIT_STRING *c2i_ASN1_BIT_STRING(ASN1_BIT_STRI
+
+ p= *pp;
+ i= *(p++);
++ if (i > 7)
++ {
++ i=ASN1_R_INVALID_BIT_STRING_BITS_LEFT;
++ goto err;
++ }
+ /* We do this to preserve the settings. If we modify
+ * the settings, via the _set_bit function, we will recalculate
+ * on output */
+ ret->flags&= ~(ASN1_STRING_FLAG_BITS_LEFT|0x07); /* clear */
+- ret->flags|=(ASN1_STRING_FLAG_BITS_LEFT|(i&0x07)); /* set */
++ ret->flags|=(ASN1_STRING_FLAG_BITS_LEFT|i); /* set */
+
+ if (len-- > 1) /* using one because of the bits left byte */
+ {
+Index: crypto/openssl/crypto/asn1/a_type.c
+===================================================================
+--- crypto/openssl/crypto/asn1/a_type.c (revision 276867)
++++ crypto/openssl/crypto/asn1/a_type.c (working copy)
+@@ -108,3 +108,49 @@ int ASN1_TYPE_set1(ASN1_TYPE *a, int type, const v
+
+ IMPLEMENT_STACK_OF(ASN1_TYPE)
+ IMPLEMENT_ASN1_SET_OF(ASN1_TYPE)
++
++/* Returns 0 if they are equal, != 0 otherwise. */
++int ASN1_TYPE_cmp(const ASN1_TYPE *a, const ASN1_TYPE *b)
++ {
++ int result = -1;
++
++ if (!a || !b || a->type != b->type) return -1;
++
++ switch (a->type)
++ {
++ case V_ASN1_OBJECT:
++ result = OBJ_cmp(a->value.object, b->value.object);
++ break;
++ case V_ASN1_NULL:
++ result = 0; /* They do not have content. */
++ break;
++ case V_ASN1_INTEGER:
++ case V_ASN1_NEG_INTEGER:
++ case V_ASN1_ENUMERATED:
++ case V_ASN1_NEG_ENUMERATED:
++ case V_ASN1_BIT_STRING:
++ case V_ASN1_OCTET_STRING:
++ case V_ASN1_SEQUENCE:
++ case V_ASN1_SET:
++ case V_ASN1_NUMERICSTRING:
++ case V_ASN1_PRINTABLESTRING:
++ case V_ASN1_T61STRING:
++ case V_ASN1_VIDEOTEXSTRING:
++ case V_ASN1_IA5STRING:
++ case V_ASN1_UTCTIME:
++ case V_ASN1_GENERALIZEDTIME:
++ case V_ASN1_GRAPHICSTRING:
++ case V_ASN1_VISIBLESTRING:
++ case V_ASN1_GENERALSTRING:
++ case V_ASN1_UNIVERSALSTRING:
++ case V_ASN1_BMPSTRING:
++ case V_ASN1_UTF8STRING:
++ case V_ASN1_OTHER:
++ default:
++ result = ASN1_STRING_cmp((ASN1_STRING *) a->value.ptr,
++ (ASN1_STRING *) b->value.ptr);
++ break;
++ }
++
++ return result;
++ }
+Index: crypto/openssl/crypto/asn1/a_verify.c
+===================================================================
+--- crypto/openssl/crypto/asn1/a_verify.c (revision 276867)
++++ crypto/openssl/crypto/asn1/a_verify.c (working copy)
+@@ -89,6 +89,12 @@ int ASN1_verify(i2d_of_void *i2d, X509_ALGOR *a, A
+ ASN1err(ASN1_F_ASN1_VERIFY,ASN1_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM);
+ goto err;
+ }
++
++ if (signature->type == V_ASN1_BIT_STRING && signature->flags & 0x7)
++ {
++ ASN1err(ASN1_F_ASN1_VERIFY, ASN1_R_INVALID_BIT_STRING_BITS_LEFT);
++ goto err;
++ }
+
+ inl=i2d(data,NULL);
+ buf_in=OPENSSL_malloc((unsigned int)inl);
+@@ -144,6 +150,12 @@ int ASN1_item_verify(const ASN1_ITEM *it, X509_ALG
+ return -1;
+ }
+
++ if (signature->type == V_ASN1_BIT_STRING && signature->flags & 0x7)
++ {
++ ASN1err(ASN1_F_ASN1_ITEM_VERIFY, ASN1_R_INVALID_BIT_STRING_BITS_LEFT);
++ return -1;
++ }
++
+ EVP_MD_CTX_init(&ctx);
+ i=OBJ_obj2nid(a->algorithm);
+ type=EVP_get_digestbyname(OBJ_nid2sn(i));
+Index: crypto/openssl/crypto/asn1/asn1.h
+===================================================================
+--- crypto/openssl/crypto/asn1/asn1.h (revision 276867)
++++ crypto/openssl/crypto/asn1/asn1.h (working copy)
+@@ -769,6 +769,7 @@ DECLARE_ASN1_FUNCTIONS_fname(ASN1_TYPE, ASN1_ANY,
+ int ASN1_TYPE_get(ASN1_TYPE *a);
+ void ASN1_TYPE_set(ASN1_TYPE *a, int type, void *value);
+ int ASN1_TYPE_set1(ASN1_TYPE *a, int type, const void *value);
++int ASN1_TYPE_cmp(const ASN1_TYPE *a, const ASN1_TYPE *b);
+
+ ASN1_OBJECT * ASN1_OBJECT_new(void );
+ void ASN1_OBJECT_free(ASN1_OBJECT *a);
+@@ -1260,6 +1261,7 @@ void ERR_load_ASN1_strings(void);
+ #define ASN1_R_ILLEGAL_TIME_VALUE 184
+ #define ASN1_R_INTEGER_NOT_ASCII_FORMAT 185
+ #define ASN1_R_INTEGER_TOO_LARGE_FOR_LONG 128
++#define ASN1_R_INVALID_BIT_STRING_BITS_LEFT 220
+ #define ASN1_R_INVALID_BMPSTRING_LENGTH 129
+ #define ASN1_R_INVALID_DIGIT 130
+ #define ASN1_R_INVALID_MIME_TYPE 200
+@@ -1308,6 +1310,7 @@ void ERR_load_ASN1_strings(void);
+ #define ASN1_R_TIME_NOT_ASCII_FORMAT 193
+ #define ASN1_R_TOO_LONG 155
+ #define ASN1_R_TYPE_NOT_CONSTRUCTED 156
++#define ASN1_R_TYPE_NOT_PRIMITIVE 218
+ #define ASN1_R_UNABLE_TO_DECODE_RSA_KEY 157
+ #define ASN1_R_UNABLE_TO_DECODE_RSA_PRIVATE_KEY 158
+ #define ASN1_R_UNEXPECTED_EOC 159
+Index: crypto/openssl/crypto/asn1/asn1_err.c
+===================================================================
+--- crypto/openssl/crypto/asn1/asn1_err.c (revision 276867)
++++ crypto/openssl/crypto/asn1/asn1_err.c (working copy)
+@@ -1,6 +1,6 @@
+ /* crypto/asn1/asn1_err.c */
+ /* ====================================================================
+- * Copyright (c) 1999-2008 The OpenSSL Project. All rights reserved.
++ * Copyright (c) 1999-2014 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
+@@ -235,6 +235,7 @@ static ERR_STRING_DATA ASN1_str_reasons[]=
+ {ERR_REASON(ASN1_R_ILLEGAL_TIME_VALUE) ,"illegal time value"},
+ {ERR_REASON(ASN1_R_INTEGER_NOT_ASCII_FORMAT),"integer not ascii format"},
+ {ERR_REASON(ASN1_R_INTEGER_TOO_LARGE_FOR_LONG),"integer too large for long"},
++{ERR_REASON(ASN1_R_INVALID_BIT_STRING_BITS_LEFT),"invalid bit string bits left"},
+ {ERR_REASON(ASN1_R_INVALID_BMPSTRING_LENGTH),"invalid bmpstring length"},
+ {ERR_REASON(ASN1_R_INVALID_DIGIT) ,"invalid digit"},
+ {ERR_REASON(ASN1_R_INVALID_MIME_TYPE) ,"invalid mime type"},
+@@ -283,6 +284,7 @@ static ERR_STRING_DATA ASN1_str_reasons[]=
+ {ERR_REASON(ASN1_R_TIME_NOT_ASCII_FORMAT),"time not ascii format"},
+ {ERR_REASON(ASN1_R_TOO_LONG) ,"too long"},
+ {ERR_REASON(ASN1_R_TYPE_NOT_CONSTRUCTED) ,"type not constructed"},
++{ERR_REASON(ASN1_R_TYPE_NOT_PRIMITIVE) ,"type not primitive"},
+ {ERR_REASON(ASN1_R_UNABLE_TO_DECODE_RSA_KEY),"unable to decode rsa key"},
+ {ERR_REASON(ASN1_R_UNABLE_TO_DECODE_RSA_PRIVATE_KEY),"unable to decode rsa private key"},
+ {ERR_REASON(ASN1_R_UNEXPECTED_EOC) ,"unexpected eoc"},
+Index: crypto/openssl/crypto/asn1/tasn_dec.c
+===================================================================
+--- crypto/openssl/crypto/asn1/tasn_dec.c (revision 276867)
++++ crypto/openssl/crypto/asn1/tasn_dec.c (working copy)
+@@ -866,6 +866,14 @@ static int asn1_d2i_ex_primitive(ASN1_VALUE **pval
+ }
+ else if (cst)
+ {
++ if (utype == V_ASN1_NULL || utype == V_ASN1_BOOLEAN
++ || utype == V_ASN1_OBJECT || utype == V_ASN1_INTEGER
++ || utype == V_ASN1_ENUMERATED)
++ {
++ ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE,
++ ASN1_R_TYPE_NOT_PRIMITIVE);
++ return 0;
++ }
+ buf.length = 0;
+ buf.max = 0;
+ buf.data = NULL;
+Index: crypto/openssl/crypto/asn1/x_algor.c
+===================================================================
+--- crypto/openssl/crypto/asn1/x_algor.c (revision 276867)
++++ crypto/openssl/crypto/asn1/x_algor.c (working copy)
+@@ -128,3 +128,13 @@ void X509_ALGOR_get0(ASN1_OBJECT **paobj, int *ppt
+ }
+ }
+
++int X509_ALGOR_cmp(const X509_ALGOR *a, const X509_ALGOR *b)
++ {
++ int rv;
++ rv = OBJ_cmp(a->algorithm, b->algorithm);
++ if (rv)
++ return rv;
++ if (!a->parameter && !b->parameter)
++ return 0;
++ return ASN1_TYPE_cmp(a->parameter, b->parameter);
++ }
+Index: crypto/openssl/crypto/bn/asm/mips3.s
+===================================================================
+--- crypto/openssl/crypto/bn/asm/mips3.s (revision 276867)
++++ crypto/openssl/crypto/bn/asm/mips3.s (working copy)
+@@ -1584,17 +1584,17 @@ LEAF(bn_sqr_comba8)
+ dmultu a_2,a_0 /* mul_add_c2(a[2],b[0],c3,c1,c2); */
+ mflo t_1
+ mfhi t_2
+- slt c_2,t_2,zero
+- dsll t_2,1
+- slt a2,t_1,zero
+- daddu t_2,a2
+- dsll t_1,1
+ daddu c_3,t_1
+ sltu AT,c_3,t_1
+- daddu t_2,AT
++ daddu c_3,t_1
++ daddu AT,t_2
++ sltu t_1,c_3,t_1
++ daddu c_1,AT
++ daddu t_2,t_1
++ sltu c_2,c_1,AT
+ daddu c_1,t_2
+- sltu AT,c_1,t_2
+- daddu c_2,AT
++ sltu t_2,c_1,t_2
++ daddu c_2,t_2
+ dmultu a_1,a_1 /* mul_add_c(a[1],b[1],c3,c1,c2); */
+ mflo t_1
+ mfhi t_2
+@@ -1609,63 +1609,63 @@ LEAF(bn_sqr_comba8)
+ dmultu a_0,a_3 /* mul_add_c2(a[0],b[3],c1,c2,c3); */
+ mflo t_1
+ mfhi t_2
+- slt c_3,t_2,zero
+- dsll t_2,1
+- slt a2,t_1,zero
+- daddu t_2,a2
+- dsll t_1,1
+ daddu c_1,t_1
+ sltu AT,c_1,t_1
+- daddu t_2,AT
++ daddu c_1,t_1
++ daddu AT,t_2
++ sltu t_1,c_1,t_1
++ daddu c_2,AT
++ daddu t_2,t_1
++ sltu c_3,c_2,AT
+ daddu c_2,t_2
+- sltu AT,c_2,t_2
+- daddu c_3,AT
++ sltu t_2,c_2,t_2
++ daddu c_3,t_2
+ dmultu a_1,a_2 /* mul_add_c2(a[1],b[2],c1,c2,c3); */
+ mflo t_1
+ mfhi t_2
+- slt AT,t_2,zero
+- daddu c_3,AT
+- dsll t_2,1
+- slt a2,t_1,zero
+- daddu t_2,a2
+- dsll t_1,1
+ daddu c_1,t_1
+ sltu AT,c_1,t_1
+- daddu t_2,AT
++ daddu c_1,t_1
++ daddu AT,t_2
++ sltu t_1,c_1,t_1
++ daddu c_2,AT
++ daddu t_2,t_1
++ sltu AT,c_2,AT
+ daddu c_2,t_2
+- sltu AT,c_2,t_2
+ daddu c_3,AT
++ sltu t_2,c_2,t_2
++ daddu c_3,t_2
+ sd c_1,24(a0)
+
+ dmultu a_4,a_0 /* mul_add_c2(a[4],b[0],c2,c3,c1); */
+ mflo t_1
+ mfhi t_2
+- slt c_1,t_2,zero
+- dsll t_2,1
+- slt a2,t_1,zero
+- daddu t_2,a2
+- dsll t_1,1
+ daddu c_2,t_1
+ sltu AT,c_2,t_1
+- daddu t_2,AT
++ daddu c_2,t_1
++ daddu AT,t_2
++ sltu t_1,c_2,t_1
++ daddu c_3,AT
++ daddu t_2,t_1
++ sltu c_1,c_3,AT
+ daddu c_3,t_2
+- sltu AT,c_3,t_2
+- daddu c_1,AT
++ sltu t_2,c_3,t_2
++ daddu c_1,t_2
+ dmultu a_3,a_1 /* mul_add_c2(a[3],b[1],c2,c3,c1); */
+ mflo t_1
+ mfhi t_2
+- slt AT,t_2,zero
+- daddu c_1,AT
+- dsll t_2,1
+- slt a2,t_1,zero
+- daddu t_2,a2
+- dsll t_1,1
+ daddu c_2,t_1
+ sltu AT,c_2,t_1
+- daddu t_2,AT
++ daddu c_2,t_1
++ daddu AT,t_2
++ sltu t_1,c_2,t_1
++ daddu c_3,AT
++ daddu t_2,t_1
++ sltu AT,c_3,AT
+ daddu c_3,t_2
+- sltu AT,c_3,t_2
+ daddu c_1,AT
++ sltu t_2,c_3,t_2
++ daddu c_1,t_2
+ dmultu a_2,a_2 /* mul_add_c(a[2],b[2],c2,c3,c1); */
+ mflo t_1
+ mfhi t_2
+@@ -1680,93 +1680,93 @@ LEAF(bn_sqr_comba8)
+ dmultu a_0,a_5 /* mul_add_c2(a[0],b[5],c3,c1,c2); */
+ mflo t_1
+ mfhi t_2
+- slt c_2,t_2,zero
+- dsll t_2,1
+- slt a2,t_1,zero
+- daddu t_2,a2
+- dsll t_1,1
+ daddu c_3,t_1
+ sltu AT,c_3,t_1
+- daddu t_2,AT
++ daddu c_3,t_1
++ daddu AT,t_2
++ sltu t_1,c_3,t_1
++ daddu c_1,AT
++ daddu t_2,t_1
++ sltu c_2,c_1,AT
+ daddu c_1,t_2
+- sltu AT,c_1,t_2
+- daddu c_2,AT
++ sltu t_2,c_1,t_2
++ daddu c_2,t_2
+ dmultu a_1,a_4 /* mul_add_c2(a[1],b[4],c3,c1,c2); */
+ mflo t_1
+ mfhi t_2
+- slt AT,t_2,zero
+- daddu c_2,AT
+- dsll t_2,1
+- slt a2,t_1,zero
+- daddu t_2,a2
+- dsll t_1,1
+ daddu c_3,t_1
+ sltu AT,c_3,t_1
+- daddu t_2,AT
++ daddu c_3,t_1
++ daddu AT,t_2
++ sltu t_1,c_3,t_1
++ daddu c_1,AT
++ daddu t_2,t_1
++ sltu AT,c_1,AT
+ daddu c_1,t_2
+- sltu AT,c_1,t_2
+ daddu c_2,AT
++ sltu t_2,c_1,t_2
++ daddu c_2,t_2
+ dmultu a_2,a_3 /* mul_add_c2(a[2],b[3],c3,c1,c2); */
+ mflo t_1
+ mfhi t_2
+- slt AT,t_2,zero
+- daddu c_2,AT
+- dsll t_2,1
+- slt a2,t_1,zero
+- daddu t_2,a2
+- dsll t_1,1
+ daddu c_3,t_1
+ sltu AT,c_3,t_1
+- daddu t_2,AT
++ daddu c_3,t_1
++ daddu AT,t_2
++ sltu t_1,c_3,t_1
++ daddu c_1,AT
++ daddu t_2,t_1
++ sltu AT,c_1,AT
+ daddu c_1,t_2
+- sltu AT,c_1,t_2
+ daddu c_2,AT
++ sltu t_2,c_1,t_2
++ daddu c_2,t_2
+ sd c_3,40(a0)
+
+ dmultu a_6,a_0 /* mul_add_c2(a[6],b[0],c1,c2,c3); */
+ mflo t_1
+ mfhi t_2
+- slt c_3,t_2,zero
+- dsll t_2,1
+- slt a2,t_1,zero
+- daddu t_2,a2
+- dsll t_1,1
+ daddu c_1,t_1
+ sltu AT,c_1,t_1
+- daddu t_2,AT
++ daddu c_1,t_1
++ daddu AT,t_2
++ sltu t_1,c_1,t_1
++ daddu c_2,AT
++ daddu t_2,t_1
++ sltu c_3,c_2,AT
+ daddu c_2,t_2
+- sltu AT,c_2,t_2
+- daddu c_3,AT
++ sltu t_2,c_2,t_2
++ daddu c_3,t_2
+ dmultu a_5,a_1 /* mul_add_c2(a[5],b[1],c1,c2,c3); */
+ mflo t_1
+ mfhi t_2
+- slt AT,t_2,zero
+- daddu c_3,AT
+- dsll t_2,1
+- slt a2,t_1,zero
+- daddu t_2,a2
+- dsll t_1,1
+ daddu c_1,t_1
+ sltu AT,c_1,t_1
+- daddu t_2,AT
++ daddu c_1,t_1
++ daddu AT,t_2
++ sltu t_1,c_1,t_1
++ daddu c_2,AT
++ daddu t_2,t_1
++ sltu AT,c_2,AT
+ daddu c_2,t_2
+- sltu AT,c_2,t_2
+ daddu c_3,AT
++ sltu t_2,c_2,t_2
++ daddu c_3,t_2
+ dmultu a_4,a_2 /* mul_add_c2(a[4],b[2],c1,c2,c3); */
+ mflo t_1
+ mfhi t_2
+- slt AT,t_2,zero
+- daddu c_3,AT
+- dsll t_2,1
+- slt a2,t_1,zero
+- daddu t_2,a2
+- dsll t_1,1
+ daddu c_1,t_1
+ sltu AT,c_1,t_1
+- daddu t_2,AT
++ daddu c_1,t_1
++ daddu AT,t_2
++ sltu t_1,c_1,t_1
++ daddu c_2,AT
++ daddu t_2,t_1
++ sltu AT,c_2,AT
+ daddu c_2,t_2
+- sltu AT,c_2,t_2
+ daddu c_3,AT
++ sltu t_2,c_2,t_2
++ daddu c_3,t_2
+ dmultu a_3,a_3 /* mul_add_c(a[3],b[3],c1,c2,c3); */
+ mflo t_1
+ mfhi t_2
+@@ -1781,108 +1781,108 @@ LEAF(bn_sqr_comba8)
+ dmultu a_0,a_7 /* mul_add_c2(a[0],b[7],c2,c3,c1); */
+ mflo t_1
+ mfhi t_2
+- slt c_1,t_2,zero
+- dsll t_2,1
+- slt a2,t_1,zero
+- daddu t_2,a2
+- dsll t_1,1
+ daddu c_2,t_1
+ sltu AT,c_2,t_1
+- daddu t_2,AT
++ daddu c_2,t_1
++ daddu AT,t_2
++ sltu t_1,c_2,t_1
++ daddu c_3,AT
++ daddu t_2,t_1
++ sltu c_1,c_3,AT
+ daddu c_3,t_2
+- sltu AT,c_3,t_2
+- daddu c_1,AT
++ sltu t_2,c_3,t_2
++ daddu c_1,t_2
+ dmultu a_1,a_6 /* mul_add_c2(a[1],b[6],c2,c3,c1); */
+ mflo t_1
+ mfhi t_2
+- slt AT,t_2,zero
+- daddu c_1,AT
+- dsll t_2,1
+- slt a2,t_1,zero
+- daddu t_2,a2
+- dsll t_1,1
+ daddu c_2,t_1
+ sltu AT,c_2,t_1
+- daddu t_2,AT
++ daddu c_2,t_1
++ daddu AT,t_2
++ sltu t_1,c_2,t_1
++ daddu c_3,AT
++ daddu t_2,t_1
++ sltu AT,c_3,AT
+ daddu c_3,t_2
+- sltu AT,c_3,t_2
+ daddu c_1,AT
++ sltu t_2,c_3,t_2
++ daddu c_1,t_2
+ dmultu a_2,a_5 /* mul_add_c2(a[2],b[5],c2,c3,c1); */
+ mflo t_1
+ mfhi t_2
+- slt AT,t_2,zero
+- daddu c_1,AT
+- dsll t_2,1
+- slt a2,t_1,zero
+- daddu t_2,a2
+- dsll t_1,1
+ daddu c_2,t_1
+ sltu AT,c_2,t_1
+- daddu t_2,AT
++ daddu c_2,t_1
++ daddu AT,t_2
++ sltu t_1,c_2,t_1
++ daddu c_3,AT
++ daddu t_2,t_1
++ sltu AT,c_3,AT
+ daddu c_3,t_2
+- sltu AT,c_3,t_2
+ daddu c_1,AT
++ sltu t_2,c_3,t_2
++ daddu c_1,t_2
+ dmultu a_3,a_4 /* mul_add_c2(a[3],b[4],c2,c3,c1); */
+ mflo t_1
+ mfhi t_2
+- slt AT,t_2,zero
+- daddu c_1,AT
+- dsll t_2,1
+- slt a2,t_1,zero
+- daddu t_2,a2
+- dsll t_1,1
+ daddu c_2,t_1
+ sltu AT,c_2,t_1
+- daddu t_2,AT
++ daddu c_2,t_1
++ daddu AT,t_2
++ sltu t_1,c_2,t_1
++ daddu c_3,AT
++ daddu t_2,t_1
++ sltu AT,c_3,AT
+ daddu c_3,t_2
+- sltu AT,c_3,t_2
+ daddu c_1,AT
++ sltu t_2,c_3,t_2
++ daddu c_1,t_2
+ sd c_2,56(a0)
+
+ dmultu a_7,a_1 /* mul_add_c2(a[7],b[1],c3,c1,c2); */
+ mflo t_1
+ mfhi t_2
+- slt c_2,t_2,zero
+- dsll t_2,1
+- slt a2,t_1,zero
+- daddu t_2,a2
+- dsll t_1,1
+ daddu c_3,t_1
+ sltu AT,c_3,t_1
+- daddu t_2,AT
++ daddu c_3,t_1
++ daddu AT,t_2
++ sltu t_1,c_3,t_1
++ daddu c_1,AT
++ daddu t_2,t_1
++ sltu c_2,c_1,AT
+ daddu c_1,t_2
+- sltu AT,c_1,t_2
+- daddu c_2,AT
++ sltu t_2,c_1,t_2
++ daddu c_2,t_2
+ dmultu a_6,a_2 /* mul_add_c2(a[6],b[2],c3,c1,c2); */
+ mflo t_1
+ mfhi t_2
+- slt AT,t_2,zero
+- daddu c_2,AT
+- dsll t_2,1
+- slt a2,t_1,zero
+- daddu t_2,a2
+- dsll t_1,1
+ daddu c_3,t_1
+ sltu AT,c_3,t_1
+- daddu t_2,AT
++ daddu c_3,t_1
++ daddu AT,t_2
++ sltu t_1,c_3,t_1
++ daddu c_1,AT
++ daddu t_2,t_1
++ sltu AT,c_1,AT
+ daddu c_1,t_2
+- sltu AT,c_1,t_2
+ daddu c_2,AT
++ sltu t_2,c_1,t_2
++ daddu c_2,t_2
+ dmultu a_5,a_3 /* mul_add_c2(a[5],b[3],c3,c1,c2); */
+ mflo t_1
+ mfhi t_2
+- slt AT,t_2,zero
+- daddu c_2,AT
+- dsll t_2,1
+- slt a2,t_1,zero
+- daddu t_2,a2
+- dsll t_1,1
+ daddu c_3,t_1
+ sltu AT,c_3,t_1
+- daddu t_2,AT
++ daddu c_3,t_1
++ daddu AT,t_2
++ sltu t_1,c_3,t_1
++ daddu c_1,AT
++ daddu t_2,t_1
++ sltu AT,c_1,AT
+ daddu c_1,t_2
+- sltu AT,c_1,t_2
+ daddu c_2,AT
++ sltu t_2,c_1,t_2
++ daddu c_2,t_2
+ dmultu a_4,a_4 /* mul_add_c(a[4],b[4],c3,c1,c2); */
+ mflo t_1
+ mfhi t_2
+@@ -1897,78 +1897,78 @@ LEAF(bn_sqr_comba8)
+ dmultu a_2,a_7 /* mul_add_c2(a[2],b[7],c1,c2,c3); */
+ mflo t_1
+ mfhi t_2
+- slt c_3,t_2,zero
+- dsll t_2,1
+- slt a2,t_1,zero
+- daddu t_2,a2
+- dsll t_1,1
+ daddu c_1,t_1
+ sltu AT,c_1,t_1
+- daddu t_2,AT
++ daddu c_1,t_1
++ daddu AT,t_2
++ sltu t_1,c_1,t_1
++ daddu c_2,AT
++ daddu t_2,t_1
++ sltu c_3,c_2,AT
+ daddu c_2,t_2
+- sltu AT,c_2,t_2
+- daddu c_3,AT
++ sltu t_2,c_2,t_2
++ daddu c_3,t_2
+ dmultu a_3,a_6 /* mul_add_c2(a[3],b[6],c1,c2,c3); */
+ mflo t_1
+ mfhi t_2
+- slt AT,t_2,zero
+- daddu c_3,AT
+- dsll t_2,1
+- slt a2,t_1,zero
+- daddu t_2,a2
+- dsll t_1,1
+ daddu c_1,t_1
+ sltu AT,c_1,t_1
+- daddu t_2,AT
++ daddu c_1,t_1
++ daddu AT,t_2
++ sltu t_1,c_1,t_1
++ daddu c_2,AT
++ daddu t_2,t_1
++ sltu AT,c_2,AT
+ daddu c_2,t_2
+- sltu AT,c_2,t_2
+ daddu c_3,AT
++ sltu t_2,c_2,t_2
++ daddu c_3,t_2
+ dmultu a_4,a_5 /* mul_add_c2(a[4],b[5],c1,c2,c3); */
+ mflo t_1
+ mfhi t_2
+- slt AT,t_2,zero
+- daddu c_3,AT
+- dsll t_2,1
+- slt a2,t_1,zero
+- daddu t_2,a2
+- dsll t_1,1
+ daddu c_1,t_1
+ sltu AT,c_1,t_1
+- daddu t_2,AT
++ daddu c_1,t_1
++ daddu AT,t_2
++ sltu t_1,c_1,t_1
++ daddu c_2,AT
++ daddu t_2,t_1
++ sltu AT,c_2,AT
+ daddu c_2,t_2
+- sltu AT,c_2,t_2
+ daddu c_3,AT
++ sltu t_2,c_2,t_2
++ daddu c_3,t_2
+ sd c_1,72(a0)
+
+ dmultu a_7,a_3 /* mul_add_c2(a[7],b[3],c2,c3,c1); */
+ mflo t_1
+ mfhi t_2
+- slt c_1,t_2,zero
+- dsll t_2,1
+- slt a2,t_1,zero
+- daddu t_2,a2
+- dsll t_1,1
+ daddu c_2,t_1
+ sltu AT,c_2,t_1
+- daddu t_2,AT
++ daddu c_2,t_1
++ daddu AT,t_2
++ sltu t_1,c_2,t_1
++ daddu c_3,AT
++ daddu t_2,t_1
++ sltu c_1,c_3,AT
+ daddu c_3,t_2
+- sltu AT,c_3,t_2
+- daddu c_1,AT
++ sltu t_2,c_3,t_2
++ daddu c_1,t_2
+ dmultu a_6,a_4 /* mul_add_c2(a[6],b[4],c2,c3,c1); */
+ mflo t_1
+ mfhi t_2
+- slt AT,t_2,zero
+- daddu c_1,AT
+- dsll t_2,1
+- slt a2,t_1,zero
+- daddu t_2,a2
+- dsll t_1,1
+ daddu c_2,t_1
+ sltu AT,c_2,t_1
+- daddu t_2,AT
++ daddu c_2,t_1
++ daddu AT,t_2
++ sltu t_1,c_2,t_1
++ daddu c_3,AT
++ daddu t_2,t_1
++ sltu AT,c_3,AT
+ daddu c_3,t_2
+- sltu AT,c_3,t_2
+ daddu c_1,AT
++ sltu t_2,c_3,t_2
++ daddu c_1,t_2
+ dmultu a_5,a_5 /* mul_add_c(a[5],b[5],c2,c3,c1); */
+ mflo t_1
+ mfhi t_2
+@@ -1983,48 +1983,48 @@ LEAF(bn_sqr_comba8)
+ dmultu a_4,a_7 /* mul_add_c2(a[4],b[7],c3,c1,c2); */
+ mflo t_1
+ mfhi t_2
+- slt c_2,t_2,zero
+- dsll t_2,1
+- slt a2,t_1,zero
+- daddu t_2,a2
+- dsll t_1,1
+ daddu c_3,t_1
+ sltu AT,c_3,t_1
+- daddu t_2,AT
++ daddu c_3,t_1
++ daddu AT,t_2
++ sltu t_1,c_3,t_1
++ daddu c_1,AT
++ daddu t_2,t_1
++ sltu c_2,c_1,AT
+ daddu c_1,t_2
+- sltu AT,c_1,t_2
+- daddu c_2,AT
++ sltu t_2,c_1,t_2
++ daddu c_2,t_2
+ dmultu a_5,a_6 /* mul_add_c2(a[5],b[6],c3,c1,c2); */
+ mflo t_1
+ mfhi t_2
+- slt AT,t_2,zero
+- daddu c_2,AT
+- dsll t_2,1
+- slt a2,t_1,zero
+- daddu t_2,a2
+- dsll t_1,1
+ daddu c_3,t_1
+ sltu AT,c_3,t_1
+- daddu t_2,AT
++ daddu c_3,t_1
++ daddu AT,t_2
++ sltu t_1,c_3,t_1
++ daddu c_1,AT
++ daddu t_2,t_1
++ sltu AT,c_1,AT
+ daddu c_1,t_2
+- sltu AT,c_1,t_2
+ daddu c_2,AT
++ sltu t_2,c_1,t_2
++ daddu c_2,t_2
+ sd c_3,88(a0)
+
+ dmultu a_7,a_5 /* mul_add_c2(a[7],b[5],c1,c2,c3); */
+ mflo t_1
+ mfhi t_2
+- slt c_3,t_2,zero
+- dsll t_2,1
+- slt a2,t_1,zero
+- daddu t_2,a2
+- dsll t_1,1
+ daddu c_1,t_1
+ sltu AT,c_1,t_1
+- daddu t_2,AT
++ daddu c_1,t_1
++ daddu AT,t_2
++ sltu t_1,c_1,t_1
++ daddu c_2,AT
++ daddu t_2,t_1
++ sltu c_3,c_2,AT
+ daddu c_2,t_2
+- sltu AT,c_2,t_2
+- daddu c_3,AT
++ sltu t_2,c_2,t_2
++ daddu c_3,t_2
+ dmultu a_6,a_6 /* mul_add_c(a[6],b[6],c1,c2,c3); */
+ mflo t_1
+ mfhi t_2
+@@ -2039,17 +2039,17 @@ LEAF(bn_sqr_comba8)
+ dmultu a_6,a_7 /* mul_add_c2(a[6],b[7],c2,c3,c1); */
+ mflo t_1
+ mfhi t_2
+- slt c_1,t_2,zero
+- dsll t_2,1
+- slt a2,t_1,zero
+- daddu t_2,a2
+- dsll t_1,1
+ daddu c_2,t_1
+ sltu AT,c_2,t_1
+- daddu t_2,AT
++ daddu c_2,t_1
++ daddu AT,t_2
++ sltu t_1,c_2,t_1
++ daddu c_3,AT
++ daddu t_2,t_1
++ sltu c_1,c_3,AT
+ daddu c_3,t_2
+- sltu AT,c_3,t_2
+- daddu c_1,AT
++ sltu t_2,c_3,t_2
++ daddu c_1,t_2
+ sd c_2,104(a0)
+
+ dmultu a_7,a_7 /* mul_add_c(a[7],b[7],c3,c1,c2); */
+@@ -2070,9 +2070,9 @@ LEAF(bn_sqr_comba4)
+ .set reorder
+ ld a_0,0(a1)
+ ld a_1,8(a1)
++ dmultu a_0,a_0 /* mul_add_c(a[0],b[0],c1,c2,c3); */
+ ld a_2,16(a1)
+ ld a_3,24(a1)
+- dmultu a_0,a_0 /* mul_add_c(a[0],b[0],c1,c2,c3); */
+ mflo c_1
+ mfhi c_2
+ sd c_1,0(a0)
+@@ -2093,17 +2093,17 @@ LEAF(bn_sqr_comba4)
+ dmultu a_2,a_0 /* mul_add_c2(a[2],b[0],c3,c1,c2); */
+ mflo t_1
+ mfhi t_2
+- slt c_2,t_2,zero
+- dsll t_2,1
+- slt a2,t_1,zero
+- daddu t_2,a2
+- dsll t_1,1
+ daddu c_3,t_1
+ sltu AT,c_3,t_1
+- daddu t_2,AT
++ daddu c_3,t_1
++ daddu AT,t_2
++ sltu t_1,c_3,t_1
++ daddu c_1,AT
++ daddu t_2,t_1
++ sltu c_2,c_1,AT
+ daddu c_1,t_2
+- sltu AT,c_1,t_2
+- daddu c_2,AT
++ sltu t_2,c_1,t_2
++ daddu c_2,t_2
+ dmultu a_1,a_1 /* mul_add_c(a[1],b[1],c3,c1,c2); */
+ mflo t_1
+ mfhi t_2
+@@ -2118,48 +2118,48 @@ LEAF(bn_sqr_comba4)
+ dmultu a_0,a_3 /* mul_add_c2(a[0],b[3],c1,c2,c3); */
+ mflo t_1
+ mfhi t_2
+- slt c_3,t_2,zero
+- dsll t_2,1
+- slt a2,t_1,zero
+- daddu t_2,a2
+- dsll t_1,1
+ daddu c_1,t_1
+ sltu AT,c_1,t_1
+- daddu t_2,AT
++ daddu c_1,t_1
++ daddu AT,t_2
++ sltu t_1,c_1,t_1
++ daddu c_2,AT
++ daddu t_2,t_1
++ sltu c_3,c_2,AT
+ daddu c_2,t_2
+- sltu AT,c_2,t_2
+- daddu c_3,AT
++ sltu t_2,c_2,t_2
++ daddu c_3,t_2
+ dmultu a_1,a_2 /* mul_add_c(a2[1],b[2],c1,c2,c3); */
+ mflo t_1
+ mfhi t_2
+- slt AT,t_2,zero
+- daddu c_3,AT
+- dsll t_2,1
+- slt a2,t_1,zero
+- daddu t_2,a2
+- dsll t_1,1
+ daddu c_1,t_1
+ sltu AT,c_1,t_1
+- daddu t_2,AT
++ daddu c_1,t_1
++ daddu AT,t_2
++ sltu t_1,c_1,t_1
++ daddu c_2,AT
++ daddu t_2,t_1
++ sltu AT,c_2,AT
+ daddu c_2,t_2
+- sltu AT,c_2,t_2
+ daddu c_3,AT
++ sltu t_2,c_2,t_2
++ daddu c_3,t_2
+ sd c_1,24(a0)
+
+ dmultu a_3,a_1 /* mul_add_c2(a[3],b[1],c2,c3,c1); */
+ mflo t_1
+ mfhi t_2
+- slt c_1,t_2,zero
+- dsll t_2,1
+- slt a2,t_1,zero
+- daddu t_2,a2
+- dsll t_1,1
+ daddu c_2,t_1
+ sltu AT,c_2,t_1
+- daddu t_2,AT
++ daddu c_2,t_1
++ daddu AT,t_2
++ sltu t_1,c_2,t_1
++ daddu c_3,AT
++ daddu t_2,t_1
++ sltu c_1,c_3,AT
+ daddu c_3,t_2
+- sltu AT,c_3,t_2
+- daddu c_1,AT
++ sltu t_2,c_3,t_2
++ daddu c_1,t_2
+ dmultu a_2,a_2 /* mul_add_c(a[2],b[2],c2,c3,c1); */
+ mflo t_1
+ mfhi t_2
+@@ -2174,17 +2174,17 @@ LEAF(bn_sqr_comba4)
+ dmultu a_2,a_3 /* mul_add_c2(a[2],b[3],c3,c1,c2); */
+ mflo t_1
+ mfhi t_2
+- slt c_2,t_2,zero
+- dsll t_2,1
+- slt a2,t_1,zero
+- daddu t_2,a2
+- dsll t_1,1
+ daddu c_3,t_1
+ sltu AT,c_3,t_1
+- daddu t_2,AT
++ daddu c_3,t_1
++ daddu AT,t_2
++ sltu t_1,c_3,t_1
++ daddu c_1,AT
++ daddu t_2,t_1
++ sltu c_2,c_1,AT
+ daddu c_1,t_2
+- sltu AT,c_1,t_2
+- daddu c_2,AT
++ sltu t_2,c_1,t_2
++ daddu c_2,t_2
+ sd c_3,40(a0)
+
+ dmultu a_3,a_3 /* mul_add_c(a[3],b[3],c1,c2,c3); */
+Index: crypto/openssl/crypto/bn/asm/x86_64-gcc.c
+===================================================================
+--- crypto/openssl/crypto/bn/asm/x86_64-gcc.c (revision 276867)
++++ crypto/openssl/crypto/bn/asm/x86_64-gcc.c (working copy)
+@@ -269,6 +269,10 @@ BN_ULONG bn_sub_words(BN_ULONG *r, BN_ULONG *a, BN
+ /* sqr_add_c(a,i,c0,c1,c2) -- c+=a[i]^2 for three word number c=(c2,c1,c0) */
+ /* sqr_add_c2(a,i,c0,c1,c2) -- c+=2*a[i]*a[j] for three word number c=(c2,c1,c0) */
+
++/*
++ * Keep in mind that carrying into high part of multiplication result
++ * can not overflow, because it cannot be all-ones.
++ */
+ #if 0
+ /* original macros are kept for reference purposes */
+ #define mul_add_c(a,b,c0,c1,c2) { \
+@@ -283,10 +287,10 @@ BN_ULONG bn_sub_words(BN_ULONG *r, BN_ULONG *a, BN
+ BN_ULONG ta=(a),tb=(b),t0; \
+ t1 = BN_UMULT_HIGH(ta,tb); \
+ t0 = ta * tb; \
+- t2 = t1+t1; c2 += (t2neg=rand_neg();
++ BN_sqr(c,a,ctx);
+ if (bp != NULL)
+ {
+ if (!results)
+ {
+- BN_print(bp,&a);
++ BN_print(bp,a);
+ BIO_puts(bp," * ");
+- BN_print(bp,&a);
++ BN_print(bp,a);
+ BIO_puts(bp," - ");
+ }
+- BN_print(bp,&c);
++ BN_print(bp,c);
+ BIO_puts(bp,"\n");
+ }
+- BN_div(&d,&e,&c,&a,ctx);
+- BN_sub(&d,&d,&a);
+- if(!BN_is_zero(&d) || !BN_is_zero(&e))
+- {
+- fprintf(stderr,"Square test failed!\n");
+- return 0;
+- }
++ BN_div(d,e,c,a,ctx);
++ BN_sub(d,d,a);
++ if(!BN_is_zero(d) || !BN_is_zero(e))
++ {
++ fprintf(stderr,"Square test failed!\n");
++ goto err;
++ }
+ }
+- BN_free(&a);
+- BN_free(&c);
+- BN_free(&d);
+- BN_free(&e);
+- return(1);
++
++ /* Regression test for a BN_sqr overflow bug. */
++ BN_hex2bn(&a,
++ "80000000000000008000000000000001FFFFFFFFFFFFFFFE0000000000000000");
++ BN_sqr(c, a, ctx);
++ if (bp != NULL)
++ {
++ if (!results)
++ {
++ BN_print(bp,a);
++ BIO_puts(bp," * ");
++ BN_print(bp,a);
++ BIO_puts(bp," - ");
++ }
++ BN_print(bp,c);
++ BIO_puts(bp,"\n");
++ }
++ BN_mul(d, a, a, ctx);
++ if (BN_cmp(c, d))
++ {
++ fprintf(stderr, "Square test failed: BN_sqr and BN_mul produce "
++ "different results!\n");
++ goto err;
++ }
++
++ /* Regression test for a BN_sqr overflow bug. */
++ BN_hex2bn(&a,
++ "80000000000000000000000080000001FFFFFFFE000000000000000000000000");
++ BN_sqr(c, a, ctx);
++ if (bp != NULL)
++ {
++ if (!results)
++ {
++ BN_print(bp,a);
++ BIO_puts(bp," * ");
++ BN_print(bp,a);
++ BIO_puts(bp," - ");
++ }
++ BN_print(bp,c);
++ BIO_puts(bp,"\n");
++ }
++ BN_mul(d, a, a, ctx);
++ if (BN_cmp(c, d))
++ {
++ fprintf(stderr, "Square test failed: BN_sqr and BN_mul produce "
++ "different results!\n");
++ goto err;
++ }
++ ret = 1;
++err:
++ if (a != NULL) BN_free(a);
++ if (c != NULL) BN_free(c);
++ if (d != NULL) BN_free(d);
++ if (e != NULL) BN_free(e);
++ return ret;
+ }
+
+ int test_mont(BIO *bp, BN_CTX *ctx)
+Index: crypto/openssl/crypto/dsa/dsa_asn1.c
+===================================================================
+--- crypto/openssl/crypto/dsa/dsa_asn1.c (revision 276867)
++++ crypto/openssl/crypto/dsa/dsa_asn1.c (working copy)
+@@ -200,7 +200,11 @@ int DSA_verify(int type, const unsigned char *dgst
+ const unsigned char *sigbuf, int siglen, DSA *dsa)
+ {
+ DSA_SIG *s;
++ const unsigned char *p = sigbuf;
++ unsigned char *der = NULL;
++ int derlen = -1;
+ int ret=-1;
++
+ #ifdef OPENSSL_FIPS
+ if(FIPS_mode() && !(dsa->flags & DSA_FLAG_NON_FIPS_ALLOW))
+ {
+@@ -211,10 +215,18 @@ int DSA_verify(int type, const unsigned char *dgst
+
+ s = DSA_SIG_new();
+ if (s == NULL) return(ret);
+- if (d2i_DSA_SIG(&s,&sigbuf,siglen) == NULL) goto err;
++ if (d2i_DSA_SIG(&s,&p,siglen) == NULL) goto err;
++ /* Ensure signature uses DER and doesn't have trailing garbage */
++ derlen = i2d_DSA_SIG(s, &der);
++ if (derlen != siglen || memcmp(sigbuf, der, derlen))
++ goto err;
+ ret=DSA_do_verify(dgst,dgst_len,s,dsa);
+ err:
++ if (derlen > 0)
++ {
++ OPENSSL_cleanse(der, derlen);
++ OPENSSL_free(der);
++ }
+ DSA_SIG_free(s);
+ return(ret);
+ }
+-
+Index: crypto/openssl/crypto/ecdsa/ecs_vrf.c
+===================================================================
+--- crypto/openssl/crypto/ecdsa/ecs_vrf.c (revision 276867)
++++ crypto/openssl/crypto/ecdsa/ecs_vrf.c (working copy)
+@@ -57,6 +57,7 @@
+ */
+
+ #include "ecs_locl.h"
++#include "cryptlib.h"
+ #ifndef OPENSSL_NO_ENGINE
+ #include
+ #endif
+@@ -84,13 +85,25 @@ int ECDSA_verify(int type, const unsigned char *dg
+ const unsigned char *sigbuf, int sig_len, EC_KEY *eckey)
+ {
+ ECDSA_SIG *s;
++ const unsigned char *p = sigbuf;
++ unsigned char *der = NULL;
++ int derlen = -1;
+ int ret=-1;
+
+ s = ECDSA_SIG_new();
+ if (s == NULL) return(ret);
+- if (d2i_ECDSA_SIG(&s, &sigbuf, sig_len) == NULL) goto err;
++ if (d2i_ECDSA_SIG(&s, &p, sig_len) == NULL) goto err;
++ /* Ensure signature uses DER and doesn't have trailing garbage */
++ derlen = i2d_ECDSA_SIG(s, &der);
++ if (derlen != sig_len || memcmp(sigbuf, der, derlen))
++ goto err;
+ ret=ECDSA_do_verify(dgst, dgst_len, s, eckey);
+ err:
++ if (derlen > 0)
++ {
++ OPENSSL_cleanse(der, derlen);
++ OPENSSL_free(der);
++ }
+ ECDSA_SIG_free(s);
+ return(ret);
+ }
+Index: crypto/openssl/crypto/x509/x509.h
+===================================================================
+--- crypto/openssl/crypto/x509/x509.h (revision 276867)
++++ crypto/openssl/crypto/x509/x509.h (working copy)
+@@ -870,6 +870,7 @@ X509_ALGOR *X509_ALGOR_dup(X509_ALGOR *xn);
+ int X509_ALGOR_set0(X509_ALGOR *alg, ASN1_OBJECT *aobj, int ptype, void *pval);
+ void X509_ALGOR_get0(ASN1_OBJECT **paobj, int *pptype, void **ppval,
+ X509_ALGOR *algor);
++int X509_ALGOR_cmp(const X509_ALGOR *a, const X509_ALGOR *b);
+
+ X509_NAME *X509_NAME_dup(X509_NAME *xn);
+ X509_NAME_ENTRY *X509_NAME_ENTRY_dup(X509_NAME_ENTRY *ne);
+Index: crypto/openssl/crypto/x509/x_all.c
+===================================================================
+--- crypto/openssl/crypto/x509/x_all.c (revision 276867)
++++ crypto/openssl/crypto/x509/x_all.c (working copy)
+@@ -73,6 +73,8 @@
+
+ int X509_verify(X509 *a, EVP_PKEY *r)
+ {
++ if (X509_ALGOR_cmp(a->sig_alg, a->cert_info->signature))
++ return 0;
+ return(ASN1_item_verify(ASN1_ITEM_rptr(X509_CINF),a->sig_alg,
+ a->signature,a->cert_info,r));
+ }
+Index: crypto/openssl/doc/ssl/SSL_CTX_set_options.pod
+===================================================================
+--- crypto/openssl/doc/ssl/SSL_CTX_set_options.pod (revision 276867)
++++ crypto/openssl/doc/ssl/SSL_CTX_set_options.pod (working copy)
+@@ -152,15 +152,7 @@ temporary/ephemeral DH parameters are used.
+
+ =item SSL_OP_EPHEMERAL_RSA
+
+-Always use ephemeral (temporary) RSA key when doing RSA operations
+-(see L).
+-According to the specifications this is only done, when a RSA key
+-can only be used for signature operations (namely under export ciphers
+-with restricted RSA keylength). By setting this option, ephemeral
+-RSA keys are always used. This option breaks compatibility with the
+-SSL/TLS specifications and may lead to interoperability problems with
+-clients and should therefore never be used. Ciphers with EDH (ephemeral
+-Diffie-Hellman) key exchange should be used instead.
++This option is no longer implemented and is treated as no op.
+
+ =item SSL_OP_CIPHER_SERVER_PREFERENCE
+
+Index: crypto/openssl/doc/ssl/SSL_CTX_set_tmp_rsa_callback.pod
+===================================================================
+--- crypto/openssl/doc/ssl/SSL_CTX_set_tmp_rsa_callback.pod (revision 276867)
++++ crypto/openssl/doc/ssl/SSL_CTX_set_tmp_rsa_callback.pod (working copy)
+@@ -74,22 +74,15 @@ exchange and use EDH (Ephemeral Diffie-Hellman) ke
+ in order to achieve forward secrecy (see
+ L).
+
+-On OpenSSL servers ephemeral RSA key exchange is therefore disabled by default
+-and must be explicitly enabled using the SSL_OP_EPHEMERAL_RSA option of
+-L, violating the TLS/SSL
+-standard. When ephemeral RSA key exchange is required for export ciphers,
+-it will automatically be used without this option!
++An application may either directly specify the key or can supply the key via a
++callback function. The callback approach has the advantage, that the callback
++may generate the key only in case it is actually needed. As the generation of a
++RSA key is however costly, it will lead to a significant delay in the handshake
++procedure. Another advantage of the callback function is that it can supply
++keys of different size while the explicit setting of the key is only useful for
++key size of 512 bits to satisfy the export restricted ciphers and does give
++away key length if a longer key would be allowed.
+
+-An application may either directly specify the key or can supply the key via
+-a callback function. The callback approach has the advantage, that the
+-callback may generate the key only in case it is actually needed. As the
+-generation of a RSA key is however costly, it will lead to a significant
+-delay in the handshake procedure. Another advantage of the callback function
+-is that it can supply keys of different size (e.g. for SSL_OP_EPHEMERAL_RSA
+-usage) while the explicit setting of the key is only useful for key size of
+-512 bits to satisfy the export restricted ciphers and does give away key length
+-if a longer key would be allowed.
+-
+ The B is called with the B needed and
+ the B information. The B flag is set, when the
+ ephemeral RSA key exchange is performed with an export cipher.
+Index: crypto/openssl/ssl/d1_pkt.c
+===================================================================
+--- crypto/openssl/ssl/d1_pkt.c (revision 276867)
++++ crypto/openssl/ssl/d1_pkt.c (working copy)
+@@ -595,8 +595,6 @@ again:
+ /* now s->packet_length == DTLS1_RT_HEADER_LENGTH */
+ i=rr->length;
+ n=ssl3_read_n(s,i,i,1);
+- if (n <= 0) return(n); /* error or non-blocking io */
+-
+ /* this packet contained a partial record, dump it */
+ if ( n != i)
+ {
+@@ -626,7 +624,8 @@ again:
+ * would be dropped unnecessarily.
+ */
+ if (!(s->d1->listen && rr->type == SSL3_RT_HANDSHAKE &&
+- *p == SSL3_MT_CLIENT_HELLO) &&
++ s->packet_length > DTLS1_RT_HEADER_LENGTH &&
++ s->packet[DTLS1_RT_HEADER_LENGTH] == SSL3_MT_CLIENT_HELLO) &&
+ ! dtls1_record_replay_check(s, bitmap, &(rr->seq_num)))
+ {
+ rr->length = 0;
+Index: crypto/openssl/ssl/d1_srvr.c
+===================================================================
+--- crypto/openssl/ssl/d1_srvr.c (revision 276867)
++++ crypto/openssl/ssl/d1_srvr.c (working copy)
+@@ -371,23 +371,11 @@ int dtls1_accept(SSL *s)
+
+ /* clear this, it may get reset by
+ * send_server_key_exchange */
+- if ((s->options & SSL_OP_EPHEMERAL_RSA)
+-#ifndef OPENSSL_NO_KRB5
+- && !(l & SSL_KRB5)
+-#endif /* OPENSSL_NO_KRB5 */
+- )
+- /* option SSL_OP_EPHEMERAL_RSA sends temporary RSA key
+- * even when forbidden by protocol specs
+- * (handshake may fail as clients are not required to
+- * be able to handle this) */
+- s->s3->tmp.use_rsa_tmp=1;
+- else
+- s->s3->tmp.use_rsa_tmp=0;
++ s->s3->tmp.use_rsa_tmp=0;
+
+ /* only send if a DH key exchange, fortezza or
+ * RSA but we have a sign only certificate */
+- if (s->s3->tmp.use_rsa_tmp
+- || (l & (SSL_DH|SSL_kFZA))
++ if ((l & (SSL_DH|SSL_kFZA))
+ || ((l & SSL_kRSA)
+ && (s->cert->pkeys[SSL_PKEY_RSA_ENC].privatekey == NULL
+ || (SSL_C_IS_EXPORT(s->s3->tmp.new_cipher)
+Index: crypto/openssl/ssl/s23_srvr.c
+===================================================================
+--- crypto/openssl/ssl/s23_srvr.c (revision 276867)
++++ crypto/openssl/ssl/s23_srvr.c (working copy)
+@@ -559,12 +559,14 @@ int ssl23_get_client_hello(SSL *s)
+ if ((type == 2) || (type == 3))
+ {
+ /* we have SSLv3/TLSv1 (type 2: SSL2 style, type 3: SSL3/TLS style) */
+- s->method = ssl23_get_server_method(s->version);
+- if (s->method == NULL)
++ SSL_METHOD *new_method;
++ new_method = ssl23_get_server_method(s->version);
++ if (new_method == NULL)
+ {
+ SSLerr(SSL_F_SSL23_GET_CLIENT_HELLO,SSL_R_UNSUPPORTED_PROTOCOL);
+ goto err;
+ }
++ s->method = new_method;
+
+ if (!ssl_init_wbio_buffer(s,1)) goto err;
+
+Index: crypto/openssl/ssl/s3_clnt.c
+===================================================================
+--- crypto/openssl/ssl/s3_clnt.c (revision 276867)
++++ crypto/openssl/ssl/s3_clnt.c (working copy)
+@@ -1122,8 +1122,21 @@ int ssl3_get_key_exchange(SSL *s)
+
+ if (!ok) return((int)n);
+
++ alg=s->s3->tmp.new_cipher->algorithms;
++ EVP_MD_CTX_init(&md_ctx);
++
+ if (s->s3->tmp.message_type != SSL3_MT_SERVER_KEY_EXCHANGE)
+ {
++ /*
++ * Can't skip server key exchange if this is an ephemeral
++ * ciphersuite.
++ */
++ if (alg & (SSL_kEDH|SSL_kECDHE))
++ {
++ SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_UNEXPECTED_MESSAGE);
++ al = SSL_AD_UNEXPECTED_MESSAGE;
++ goto f_err;
++ }
+ s->s3->tmp.reuse_message=1;
+ return(1);
+ }
+@@ -1160,12 +1173,17 @@ int ssl3_get_key_exchange(SSL *s)
+ }
+
+ param_len=0;
+- alg=s->s3->tmp.new_cipher->algorithms;
+- EVP_MD_CTX_init(&md_ctx);
+
+ #ifndef OPENSSL_NO_RSA
+ if (alg & SSL_kRSA)
+ {
++ /* Temporary RSA keys only allowed in export ciphersuites */
++ if (!SSL_C_IS_EXPORT(s->s3->tmp.new_cipher))
++ {
++ al=SSL_AD_UNEXPECTED_MESSAGE;
++ SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_UNEXPECTED_MESSAGE);
++ goto f_err;
++ }
+ if ((rsa=RSA_new()) == NULL)
+ {
+ SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,ERR_R_MALLOC_FAILURE);
+Index: crypto/openssl/ssl/s3_pkt.c
+===================================================================
+--- crypto/openssl/ssl/s3_pkt.c (revision 276867)
++++ crypto/openssl/ssl/s3_pkt.c (working copy)
+@@ -146,6 +146,8 @@ int ssl3_read_n(SSL *s, int n, int max, int extend
+ * at once (as long as it fits into the buffer). */
+ if (SSL_version(s) == DTLS1_VERSION)
+ {
++ if (s->s3->rbuf.left == 0 && extend)
++ return 0;
+ if ( s->s3->rbuf.left > 0 && n > s->s3->rbuf.left)
+ n = s->s3->rbuf.left;
+ }
+Index: crypto/openssl/ssl/s3_srvr.c
+===================================================================
+--- crypto/openssl/ssl/s3_srvr.c (revision 276867)
++++ crypto/openssl/ssl/s3_srvr.c (working copy)
+@@ -354,18 +354,7 @@ int ssl3_accept(SSL *s)
+
+ /* clear this, it may get reset by
+ * send_server_key_exchange */
+- if ((s->options & SSL_OP_EPHEMERAL_RSA)
+-#ifndef OPENSSL_NO_KRB5
+- && !(l & SSL_KRB5)
+-#endif /* OPENSSL_NO_KRB5 */
+- )
+- /* option SSL_OP_EPHEMERAL_RSA sends temporary RSA key
+- * even when forbidden by protocol specs
+- * (handshake may fail as clients are not required to
+- * be able to handle this) */
+- s->s3->tmp.use_rsa_tmp=1;
+- else
+- s->s3->tmp.use_rsa_tmp=0;
++ s->s3->tmp.use_rsa_tmp=0;
+
+
+ /* only send if a DH key exchange, fortezza or
+@@ -377,8 +366,7 @@ int ssl3_accept(SSL *s)
+ * server certificate contains the server's
+ * public key for key exchange.
+ */
+- if (s->s3->tmp.use_rsa_tmp
+- || (l & SSL_kECDHE)
++ if ((l & SSL_kECDHE)
+ || (l & (SSL_DH|SSL_kFZA))
+ || ((l & SSL_kRSA)
+ && (s->cert->pkeys[SSL_PKEY_RSA_ENC].privatekey == NULL
+@@ -2400,7 +2388,7 @@ int ssl3_get_cert_verify(SSL *s)
+ if (s->s3->tmp.message_type != SSL3_MT_CERTIFICATE_VERIFY)
+ {
+ s->s3->tmp.reuse_message=1;
+- if ((peer != NULL) && (type | EVP_PKT_SIGN))
++ if (peer != NULL)
+ {
+ al=SSL_AD_UNEXPECTED_MESSAGE;
+ SSLerr(SSL_F_SSL3_GET_CERT_VERIFY,SSL_R_MISSING_VERIFY_MESSAGE);
+Index: crypto/openssl/ssl/ssl.h
+===================================================================
+--- crypto/openssl/ssl/ssl.h (revision 276867)
++++ crypto/openssl/ssl/ssl.h (working copy)
+@@ -526,9 +526,8 @@ typedef struct ssl_session_st
+ #define SSL_OP_SINGLE_ECDH_USE 0x00080000L
+ /* If set, always create a new key when using tmp_dh parameters */
+ #define SSL_OP_SINGLE_DH_USE 0x00100000L
+-/* Set to always use the tmp_rsa key when doing RSA operations,
+- * even when this violates protocol specs */
+-#define SSL_OP_EPHEMERAL_RSA 0x00200000L
++/* Does nothing: retained for compatibiity */
++#define SSL_OP_EPHEMERAL_RSA 0x0
+ /* Set on servers to choose the cipher according to the server's
+ * preferences */
+ #define SSL_OP_CIPHER_SERVER_PREFERENCE 0x00400000L
+Index: crypto/openssl/util/libeay.num
+===================================================================
+--- crypto/openssl/util/libeay.num (revision 276867)
++++ crypto/openssl/util/libeay.num (working copy)
+@@ -1807,6 +1807,7 @@ ASN1_UTCTIME_get 2350 NOEXI
+ X509_REQ_digest 2362 EXIST::FUNCTION:EVP
+ X509_CRL_digest 2391 EXIST::FUNCTION:EVP
+ d2i_ASN1_SET_OF_PKCS7 2397 NOEXIST::FUNCTION:
++X509_ALGOR_cmp 2398 EXIST::FUNCTION:
+ EVP_CIPHER_CTX_set_key_length 2399 EXIST::FUNCTION:
+ EVP_CIPHER_CTX_ctrl 2400 EXIST::FUNCTION:
+ BN_mod_exp_mont_word 2401 EXIST::FUNCTION:
+@@ -3730,3 +3731,4 @@ JPAKE_STEP2_init 4113 EXIST
+ pqueue_size 4114 EXIST::FUNCTION:
+ OPENSSL_uni2asc 4115 EXIST:NETWARE:FUNCTION:
+ OPENSSL_asc2uni 4116 EXIST:NETWARE:FUNCTION:
++ASN1_TYPE_cmp 4428 EXIST::FUNCTION:
diff --git a/share/security/patches/SA-15:01/openssl-9.3.patch.asc b/share/security/patches/SA-15:01/openssl-9.3.patch.asc
new file mode 100644
index 0000000000..f909c88243
--- /dev/null
+++ b/share/security/patches/SA-15:01/openssl-9.3.patch.asc
@@ -0,0 +1,17 @@
+-----BEGIN PGP SIGNATURE-----
+Version: GnuPG v2.1.1 (FreeBSD)
+
+iQIcBAABCgAGBQJUtuBQAAoJEO1n7NZdz2rnafsQAJXvOF3kTb3JQqVlkxarVbDf
+bCOSx3VitagKVGgXGsdqNkf2ZzeoBB5DOvndJgKDuF9hgwPkOfVtAFiVPoOo4Njk
+/G38duk+ntkDjpBdjTHDkMzqniERsNPzo7kDFsHczzAGKX5KV9/C1Fyr3cHGIg1M
+f2Pl1UFhaOa16ZIGBw7xba2nEm0zsjmhWYFfQxPdihc0HXivn6Zyqt4Ys3zuieOC
+q4x1sFqAkYc4kCs0sNvFFfSE3nCd4bCo10rzGsv2AMKjadyA1q8np0W2uQ2PqjRM
+VSOiDSeIuNCKA3P01KLvV/K9oIv9YN3kE78wglshynC5OTHovqbdlrBglcPzt9tO
+NJ8xV8Mg8v8ivS5UIksd46w8zDcOLCxxdpILqzoZlv7aodErH1/nKvmAV1NEcUfy
+6o4ukL0YIghHr7fBqnMFKT1uDP5NQj+3z4FUOaBemWYExmTlAj3HqjoaAeaS3XUz
+v0uvpzgCY2G3xw6ne6wtwhM0VFF6YBxQfk/xnN56g3DWOdOhtrmxytN9DQUox9EE
+83pQN8IdDCX5Tb0E4cH1TZK1Kvd6DCUF6T6yvAhkvL2KaDBIQpDnbnLF019ELMOr
+IeJ/eKTBTyOBpardg21oWX01+ielRPSwVJB87z3lcdTaTHsmHDRvqnZ1kegrCcGz
+TQD7vmtNOOAdfp5gN6II
+=S4We
+-----END PGP SIGNATURE-----
diff --git a/share/xml/advisories.xml b/share/xml/advisories.xml
index 4d4b7654c9..739a6eca86 100644
--- a/share/xml/advisories.xml
+++ b/share/xml/advisories.xml
@@ -4,6 +4,22 @@
$FreeBSD$
+
+ 2015
+
+
+ 1
+
+
+ 14
+
+
+ FreeBSD-SA-15:01.openssl
+
+
+
+
+
2014