From 5c6169fb309981b564a17bee31b367a18866d674 Mon Sep 17 00:00:00 2001
From: Robert Golebiowski <robert.golebiowski@oracle.com>
Date: Tue, 27 Sep 2016 11:17:38 +0200
Subject: Bug #24740291: YASSL UPDATE TO 2.4.2

---
 extra/yassl/README                       |  18 ++++
 extra/yassl/certs/dsa-cert.pem           |  38 +++----
 extra/yassl/include/openssl/ssl.h        |   2 +-
 extra/yassl/src/ssl.cpp                  |  60 ++++++++---
 extra/yassl/taocrypt/include/aes.hpp     |  58 +++++++++++
 extra/yassl/taocrypt/include/integer.hpp |   3 +
 extra/yassl/taocrypt/src/aes.cpp         | 172 +++++++++++++++++++------------
 extra/yassl/taocrypt/src/asn.cpp         |  24 ++---
 extra/yassl/taocrypt/src/dsa.cpp         |  16 +--
 extra/yassl/taocrypt/test/test.cpp       |   3 +
 extra/yassl/testsuite/test.hpp           |   2 +-
 11 files changed, 274 insertions(+), 122 deletions(-)

(limited to 'extra')

diff --git a/extra/yassl/README b/extra/yassl/README
index b5eb88824fb..a3d4f60f561 100644
--- a/extra/yassl/README
+++ b/extra/yassl/README
@@ -12,6 +12,24 @@ before calling SSL_new();
 
 *** end Note ***
 
+yaSSL Release notes, version 2.4.2 (9/22/2016)
+    This release of yaSSL fixes a medium security vulnerability. A fix for
+    potential AES side channel leaks is included that a local user monitoring
+    the same CPU core cache could exploit.  VM users, hyper-threading users,
+    and users where potential attackers have access to the CPU cache will need
+    to update if they utilize AES.
+
+    DSA padding fixes for unusual sizes is included as well.  Users with DSA
+    certficiates should update.
+
+yaSSL Release notes, version 2.4.0 (5/20/2016)
+    This release of yaSSL fixes the OpenSSL compatibility function
+    SSL_CTX_load_verify_locations() when using the path directory to allow
+    unlimited path sizes.  Minor Windows build fixes are included.
+    No high level security fixes in this version but we always recommend
+    updating.
+
+
 yaSSL Release notes, version 2.3.9b (2/03/2016)
     This release of yaSSL fixes the OpenSSL compatibility function
     X509_NAME_get_index_by_NID() to use the actual index of the common name
diff --git a/extra/yassl/certs/dsa-cert.pem b/extra/yassl/certs/dsa-cert.pem
index 10d533edc88..10794cbee73 100644
--- a/extra/yassl/certs/dsa-cert.pem
+++ b/extra/yassl/certs/dsa-cert.pem
@@ -1,22 +1,22 @@
 -----BEGIN CERTIFICATE-----
-MIIDqzCCA2ugAwIBAgIJAMGqrgDU6DyhMAkGByqGSM44BAMwgY4xCzAJBgNVBAYT
+MIIDrzCCA2+gAwIBAgIJAK1zRM7YFcNjMAkGByqGSM44BAMwgZAxCzAJBgNVBAYT
 AlVTMQ8wDQYDVQQIDAZPcmVnb24xETAPBgNVBAcMCFBvcnRsYW5kMRAwDgYDVQQK
-DAd3b2xmU1NMMRAwDgYDVQQLDAd0ZXN0aW5nMRYwFAYDVQQDDA13d3cueWFzc2wu
-Y29tMR8wHQYJKoZIhvcNAQkBFhBpbmZvQHdvbGZzc2wuY29tMB4XDTEzMDQyMjIw
-MDk0NFoXDTE2MDExNzIwMDk0NFowgY4xCzAJBgNVBAYTAlVTMQ8wDQYDVQQIDAZP
-cmVnb24xETAPBgNVBAcMCFBvcnRsYW5kMRAwDgYDVQQKDAd3b2xmU1NMMRAwDgYD
-VQQLDAd0ZXN0aW5nMRYwFAYDVQQDDA13d3cueWFzc2wuY29tMR8wHQYJKoZIhvcN
-AQkBFhBpbmZvQHdvbGZzc2wuY29tMIIBuDCCASwGByqGSM44BAEwggEfAoGBAL1R
-7koy4IrH6sbh6nDEUUPPKgfhxxLCWCVexF2+qzANEr+hC9M002haJXFOfeS9DyoO
-WFbL0qMZOuqv+22CaHnoUWl7q3PjJOAI3JH0P54ZyUPuU1909RzgTdIDp5+ikbr7
-KYjnltL73FQVMbjTZQKthIpPn3MjYcF+4jp2W2zFAhUAkcntYND6MGf+eYzIJDN2
-L7SonHUCgYEAklpxErfqznIZjVvqqHFaq+mgAL5J8QrKVmdhYZh/Y8z4jCjoCA8o
-TDoFKxf7s2ZzgaPKvglaEKiYqLqic9qY78DYJswzQMLFvjsF4sFZ+pYCBdWPQI4N
-PgxCiznK6Ce+JH9ikSBvMvG+tevjr2UpawDIHX3+AWYaZBZwKADAaboDgYUAAoGB
-AJ3LY89yHyvQ/TsQ6zlYbovjbk/ogndsMqPdNUvL4RuPTgJP/caaDDa0XJ7ak6A7
-TJ+QheLNwOXoZPYJC4EGFSDAXpYniGhbWIrVTCGe6lmZDfnx40WXS0kk3m/DHaC0
-3ElLAiybxVGxyqoUfbT3Zv1JwftWMuiqHH5uADhdXuXVo1AwTjAdBgNVHQ4EFgQU
-IJjk416o4v8qpH9LBtXlR9v8gccwHwYDVR0jBBgwFoAUIJjk416o4v8qpH9LBtXl
-R9v8gccwDAYDVR0TBAUwAwEB/zAJBgcqhkjOOAQDAy8AMCwCFCjGKIdOSV12LcTu
-k08owGM6YkO1AhQe+K173VuaO/OsDNsxZlKpyH8+1g==
+DAd3b2xmU1NMMRAwDgYDVQQLDAd0ZXN0aW5nMRgwFgYDVQQDDA93d3cud29sZnNz
+bC5jb20xHzAdBgkqhkiG9w0BCQEWEGluZm9Ad29sZnNzbC5jb20wHhcNMTYwOTIy
+MjEyMzA0WhcNMjIwMzE1MjEyMzA0WjCBkDELMAkGA1UEBhMCVVMxDzANBgNVBAgM
+Bk9yZWdvbjERMA8GA1UEBwwIUG9ydGxhbmQxEDAOBgNVBAoMB3dvbGZTU0wxEDAO
+BgNVBAsMB3Rlc3RpbmcxGDAWBgNVBAMMD3d3dy53b2xmc3NsLmNvbTEfMB0GCSqG
+SIb3DQEJARYQaW5mb0B3b2xmc3NsLmNvbTCCAbgwggEsBgcqhkjOOAQBMIIBHwKB
+gQC9Ue5KMuCKx+rG4epwxFFDzyoH4ccSwlglXsRdvqswDRK/oQvTNNNoWiVxTn3k
+vQ8qDlhWy9KjGTrqr/ttgmh56FFpe6tz4yTgCNyR9D+eGclD7lNfdPUc4E3SA6ef
+opG6+ymI55bS+9xUFTG402UCrYSKT59zI2HBfuI6dltsxQIVAJHJ7WDQ+jBn/nmM
+yCQzdi+0qJx1AoGBAJJacRK36s5yGY1b6qhxWqvpoAC+SfEKylZnYWGYf2PM+Iwo
+6AgPKEw6BSsX+7Nmc4Gjyr4JWhComKi6onPamO/A2CbMM0DCxb47BeLBWfqWAgXV
+j0CODT4MQos5yugnviR/YpEgbzLxvrXr469lKWsAyB19/gFmGmQWcCgAwGm6A4GF
+AAKBgQCdy2PPch8r0P07EOs5WG6L425P6IJ3bDKj3TVLy+Ebj04CT/3Gmgw2tFye
+2pOgO0yfkIXizcDl6GT2CQuBBhUgwF6WJ4hoW1iK1UwhnupZmQ358eNFl0tJJN5v
+wx2gtNxJSwIsm8VRscqqFH2092b9ScH7VjLoqhx+bgA4XV7l1aNQME4wHQYDVR0O
+BBYEFCCY5ONeqOL/KqR/SwbV5Ufb/IHHMB8GA1UdIwQYMBaAFCCY5ONeqOL/KqR/
+SwbV5Ufb/IHHMAwGA1UdEwQFMAMBAf8wCQYHKoZIzjgEAwMvADAsAhQRYSCVN/Ge
+agV3mffU3qNZ92fI0QIUPH7Jp+iASI7U1ocaYDc10qXGaGY=
 -----END CERTIFICATE-----
diff --git a/extra/yassl/include/openssl/ssl.h b/extra/yassl/include/openssl/ssl.h
index 83daf3cc81f..0609dfc0592 100644
--- a/extra/yassl/include/openssl/ssl.h
+++ b/extra/yassl/include/openssl/ssl.h
@@ -35,7 +35,7 @@
 #include "rsa.h"
 
 
-#define YASSL_VERSION "2.3.9b"
+#define YASSL_VERSION "2.4.2"
 
 
 #if defined(__cplusplus)
diff --git a/extra/yassl/src/ssl.cpp b/extra/yassl/src/ssl.cpp
index cde32df4f43..1925e2f7592 100644
--- a/extra/yassl/src/ssl.cpp
+++ b/extra/yassl/src/ssl.cpp
@@ -161,7 +161,7 @@ int read_file(SSL_CTX* ctx, const char* file, int format, CertType type)
             TaoCrypt::DSA_PrivateKey dsaKey;
             dsaKey.Initialize(dsaSource);
 
-            if (rsaSource.GetError().What()) {
+            if (dsaSource.GetError().What()) {
                 // neither worked
                 ret = SSL_FAILURE;
             }
@@ -784,40 +784,67 @@ int SSL_CTX_load_verify_locations(SSL_CTX* ctx, const char* file,
         WIN32_FIND_DATA FindFileData;
         HANDLE hFind;
 
-        char name[MAX_PATH + 1];  // directory specification
-        strncpy(name, path, MAX_PATH - 3);
-        strncat(name, "\\*", 3);
+        const int DELIMITER_SZ      = 2;
+        const int DELIMITER_STAR_SZ = 3;
+        int pathSz = (int)strlen(path);
+        int nameSz = pathSz + DELIMITER_STAR_SZ + 1; // plus 1 for terminator
+        char* name = NEW_YS char[nameSz];  // directory specification
+        memset(name, 0, nameSz);
+        strncpy(name, path, nameSz - DELIMITER_STAR_SZ - 1);
+        strncat(name, "\\*", DELIMITER_STAR_SZ);
 
         hFind = FindFirstFile(name, &FindFileData);
-        if (hFind == INVALID_HANDLE_VALUE) return SSL_BAD_PATH;
+        if (hFind == INVALID_HANDLE_VALUE) {
+            ysArrayDelete(name);
+            return SSL_BAD_PATH;
+        }
 
         do {
-            if (FindFileData.dwFileAttributes != FILE_ATTRIBUTE_DIRECTORY) {
-                strncpy(name, path, MAX_PATH - 2 - HALF_PATH);
-                strncat(name, "\\", 2);
-                strncat(name, FindFileData.cFileName, HALF_PATH);
+            if (!(FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
+                int curSz = (int)strlen(FindFileData.cFileName);
+                if (pathSz + curSz + DELIMITER_SZ + 1 > nameSz) {
+                    ysArrayDelete(name);
+                    // plus 1 for terminator
+                    nameSz = pathSz + curSz + DELIMITER_SZ + 1;
+                    name = NEW_YS char[nameSz];
+                }
+                memset(name, 0, nameSz);
+                strncpy(name, path, nameSz - curSz - DELIMITER_SZ - 1);
+                strncat(name, "\\", DELIMITER_SZ);
+                strncat(name, FindFileData.cFileName,
+                                            nameSz - pathSz - DELIMITER_SZ - 1);
                 ret = read_file(ctx, name, SSL_FILETYPE_PEM, CA);
             }
         } while (ret == SSL_SUCCESS && FindNextFile(hFind, &FindFileData));
 
+        ysArrayDelete(name);
         FindClose(hFind);
 
 #else   // _WIN32
-
-        const int MAX_PATH = 260;
-
         DIR* dir = opendir(path);
         if (!dir) return SSL_BAD_PATH;
 
         struct dirent* entry;
         struct stat    buf;
-        char           name[MAX_PATH + 1];
+        const int DELIMITER_SZ = 1;
+        int pathSz = (int)strlen(path);
+        int nameSz = pathSz + DELIMITER_SZ + 1; //plus 1 for null terminator
+        char* name = NEW_YS char[nameSz];  // directory specification
 
         while (ret == SSL_SUCCESS && (entry = readdir(dir))) {
-            strncpy(name, path, MAX_PATH - 1 - HALF_PATH);
-            strncat(name, "/", 1);
-            strncat(name, entry->d_name, HALF_PATH);
+            int curSz = (int)strlen(entry->d_name);
+            if (pathSz + curSz + DELIMITER_SZ + 1 > nameSz) {
+                ysArrayDelete(name);
+                nameSz = pathSz + DELIMITER_SZ + curSz + 1;
+                name = NEW_YS char[nameSz];
+            }
+            memset(name, 0, nameSz);
+            strncpy(name, path, nameSz - curSz - 1);
+            strncat(name, "/",  DELIMITER_SZ);
+            strncat(name, entry->d_name, nameSz - pathSz - DELIMITER_SZ - 1);
+
             if (stat(name, &buf) < 0) {
+                ysArrayDelete(name);
                 closedir(dir);
                 return SSL_BAD_STAT;
             }
@@ -826,6 +853,7 @@ int SSL_CTX_load_verify_locations(SSL_CTX* ctx, const char* file,
                 ret = read_file(ctx, name, SSL_FILETYPE_PEM, CA);
         }
 
+        ysArrayDelete(name);
         closedir(dir);
 
 #endif
diff --git a/extra/yassl/taocrypt/include/aes.hpp b/extra/yassl/taocrypt/include/aes.hpp
index 01763033156..bccf6e73fc7 100644
--- a/extra/yassl/taocrypt/include/aes.hpp
+++ b/extra/yassl/taocrypt/include/aes.hpp
@@ -60,6 +60,7 @@ private:
 
     static const word32 Te[5][256];
     static const word32 Td[5][256];
+    static const byte   CTd4[256];
 
     static const word32* Te0;
     static const word32* Te1;
@@ -80,11 +81,68 @@ private:
 
     void ProcessAndXorBlock(const byte*, const byte*, byte*) const;
 
+    word32 PreFetchTe() const;
+    word32 PreFetchTd() const;
+    word32 PreFetchCTd4() const;
+
     AES(const AES&);            // hide copy
     AES& operator=(const AES&); // and assign
 };
 
 
+#if defined(__x86_64__) || defined(_M_X64) || \
+           (defined(__ILP32__) && (__ILP32__ >= 1))
+    #define TC_CACHE_LINE_SZ 64
+#else
+    /* default cache line size */
+    #define TC_CACHE_LINE_SZ 32
+#endif
+
+inline word32 AES::PreFetchTe() const
+{
+    word32 x = 0;
+
+    /* 4 tables of 256 entries */
+    for (int i = 0; i < 4; i++) {
+        /* each entry is 4 bytes */
+        for (int j = 0; j < 256; j += TC_CACHE_LINE_SZ/4) {
+            x &= Te[i][j];
+        }
+    }
+
+    return x;
+}
+
+
+inline word32 AES::PreFetchTd() const
+{
+    word32 x = 0;
+
+    /* 4 tables of 256 entries */
+    for (int i = 0; i < 4; i++) {
+        /* each entry is 4 bytes */
+        for (int j = 0; j < 256; j += TC_CACHE_LINE_SZ/4) {
+            x &= Td[i][j];
+        }
+    }
+
+    return x;
+}
+
+
+inline word32 AES::PreFetchCTd4() const
+{
+    word32 x = 0;
+    int i;
+
+    for (i = 0; i < 256; i += TC_CACHE_LINE_SZ) {
+        x &= CTd4[i];
+    }
+
+    return x;
+}
+
+
 typedef BlockCipher<ENCRYPTION, AES, ECB> AES_ECB_Encryption;
 typedef BlockCipher<DECRYPTION, AES, ECB> AES_ECB_Decryption;
 
diff --git a/extra/yassl/taocrypt/include/integer.hpp b/extra/yassl/taocrypt/include/integer.hpp
index 75a3ee3d3df..05fe189fd58 100644
--- a/extra/yassl/taocrypt/include/integer.hpp
+++ b/extra/yassl/taocrypt/include/integer.hpp
@@ -119,6 +119,9 @@ namespace TaoCrypt {
 
 
 
+#ifdef _WIN32
+    #undef max // avoid name clash
+#endif
 // general MAX
 template<typename T> inline
 const T& max(const T& a, const T& b)
diff --git a/extra/yassl/taocrypt/src/aes.cpp b/extra/yassl/taocrypt/src/aes.cpp
index ee4c7a6e8a1..3fcf80ac202 100644
--- a/extra/yassl/taocrypt/src/aes.cpp
+++ b/extra/yassl/taocrypt/src/aes.cpp
@@ -109,10 +109,10 @@ void AES::SetKey(const byte* userKey, word32 keylen, CipherDir /*dummy*/)
         {
             temp  = rk[3];
             rk[4] = rk[0] ^
-                (Te4[GETBYTE(temp, 2)] & 0xff000000) ^
-                (Te4[GETBYTE(temp, 1)] & 0x00ff0000) ^
-                (Te4[GETBYTE(temp, 0)] & 0x0000ff00) ^
-                (Te4[GETBYTE(temp, 3)] & 0x000000ff) ^
+                (Te2[GETBYTE(temp, 2)] & 0xff000000) ^
+                (Te3[GETBYTE(temp, 1)] & 0x00ff0000) ^
+                (Te0[GETBYTE(temp, 0)] & 0x0000ff00) ^
+                (Te1[GETBYTE(temp, 3)] & 0x000000ff) ^
                 rcon_[i];
             rk[5] = rk[1] ^ rk[4];
             rk[6] = rk[2] ^ rk[5];
@@ -128,10 +128,10 @@ void AES::SetKey(const byte* userKey, word32 keylen, CipherDir /*dummy*/)
         {
             temp = rk[ 5];
             rk[ 6] = rk[ 0] ^
-                (Te4[GETBYTE(temp, 2)] & 0xff000000) ^
-                (Te4[GETBYTE(temp, 1)] & 0x00ff0000) ^
-                (Te4[GETBYTE(temp, 0)] & 0x0000ff00) ^
-                (Te4[GETBYTE(temp, 3)] & 0x000000ff) ^
+                (Te2[GETBYTE(temp, 2)] & 0xff000000) ^
+                (Te3[GETBYTE(temp, 1)] & 0x00ff0000) ^
+                (Te0[GETBYTE(temp, 0)] & 0x0000ff00) ^
+                (Te1[GETBYTE(temp, 3)] & 0x000000ff) ^
                 rcon_[i];
             rk[ 7] = rk[ 1] ^ rk[ 6];
             rk[ 8] = rk[ 2] ^ rk[ 7];
@@ -149,10 +149,10 @@ void AES::SetKey(const byte* userKey, word32 keylen, CipherDir /*dummy*/)
         {
             temp = rk[ 7];
             rk[ 8] = rk[ 0] ^
-                (Te4[GETBYTE(temp, 2)] & 0xff000000) ^
-                (Te4[GETBYTE(temp, 1)] & 0x00ff0000) ^
-                (Te4[GETBYTE(temp, 0)] & 0x0000ff00) ^
-                (Te4[GETBYTE(temp, 3)] & 0x000000ff) ^
+                (Te2[GETBYTE(temp, 2)] & 0xff000000) ^
+                (Te3[GETBYTE(temp, 1)] & 0x00ff0000) ^
+                (Te0[GETBYTE(temp, 0)] & 0x0000ff00) ^
+                (Te1[GETBYTE(temp, 3)] & 0x000000ff) ^
                 rcon_[i];
             rk[ 9] = rk[ 1] ^ rk[ 8];
             rk[10] = rk[ 2] ^ rk[ 9];
@@ -161,10 +161,10 @@ void AES::SetKey(const byte* userKey, word32 keylen, CipherDir /*dummy*/)
                 break;
             temp = rk[11];
             rk[12] = rk[ 4] ^
-                (Te4[GETBYTE(temp, 3)] & 0xff000000) ^
-                (Te4[GETBYTE(temp, 2)] & 0x00ff0000) ^
-                (Te4[GETBYTE(temp, 1)] & 0x0000ff00) ^
-                (Te4[GETBYTE(temp, 0)] & 0x000000ff);
+                (Te2[GETBYTE(temp, 3)] & 0xff000000) ^
+                (Te3[GETBYTE(temp, 2)] & 0x00ff0000) ^
+                (Te0[GETBYTE(temp, 1)] & 0x0000ff00) ^
+                (Te1[GETBYTE(temp, 0)] & 0x000000ff);
             rk[13] = rk[ 5] ^ rk[12];
             rk[14] = rk[ 6] ^ rk[13];
             rk[15] = rk[ 7] ^ rk[14];
@@ -191,25 +191,25 @@ void AES::SetKey(const byte* userKey, word32 keylen, CipherDir /*dummy*/)
         for (i = 1; i < rounds_; i++) {
             rk += 4;
             rk[0] =
-                Td0[Te4[GETBYTE(rk[0], 3)] & 0xff] ^
-                Td1[Te4[GETBYTE(rk[0], 2)] & 0xff] ^
-                Td2[Te4[GETBYTE(rk[0], 1)] & 0xff] ^
-                Td3[Te4[GETBYTE(rk[0], 0)] & 0xff];
+                Td0[Te1[GETBYTE(rk[0], 3)] & 0xff] ^
+                Td1[Te1[GETBYTE(rk[0], 2)] & 0xff] ^
+                Td2[Te1[GETBYTE(rk[0], 1)] & 0xff] ^
+                Td3[Te1[GETBYTE(rk[0], 0)] & 0xff];
             rk[1] =
-                Td0[Te4[GETBYTE(rk[1], 3)] & 0xff] ^
-                Td1[Te4[GETBYTE(rk[1], 2)] & 0xff] ^
-                Td2[Te4[GETBYTE(rk[1], 1)] & 0xff] ^
-                Td3[Te4[GETBYTE(rk[1], 0)] & 0xff];
+                Td0[Te1[GETBYTE(rk[1], 3)] & 0xff] ^
+                Td1[Te1[GETBYTE(rk[1], 2)] & 0xff] ^
+                Td2[Te1[GETBYTE(rk[1], 1)] & 0xff] ^
+                Td3[Te1[GETBYTE(rk[1], 0)] & 0xff];
             rk[2] =
-                Td0[Te4[GETBYTE(rk[2], 3)] & 0xff] ^
-                Td1[Te4[GETBYTE(rk[2], 2)] & 0xff] ^
-                Td2[Te4[GETBYTE(rk[2], 1)] & 0xff] ^
-                Td3[Te4[GETBYTE(rk[2], 0)] & 0xff];
+                Td0[Te1[GETBYTE(rk[2], 3)] & 0xff] ^
+                Td1[Te1[GETBYTE(rk[2], 2)] & 0xff] ^
+                Td2[Te1[GETBYTE(rk[2], 1)] & 0xff] ^
+                Td3[Te1[GETBYTE(rk[2], 0)] & 0xff];
             rk[3] =
-                Td0[Te4[GETBYTE(rk[3], 3)] & 0xff] ^
-                Td1[Te4[GETBYTE(rk[3], 2)] & 0xff] ^
-                Td2[Te4[GETBYTE(rk[3], 1)] & 0xff] ^
-                Td3[Te4[GETBYTE(rk[3], 0)] & 0xff];
+                Td0[Te1[GETBYTE(rk[3], 3)] & 0xff] ^
+                Td1[Te1[GETBYTE(rk[3], 2)] & 0xff] ^
+                Td2[Te1[GETBYTE(rk[3], 1)] & 0xff] ^
+                Td3[Te1[GETBYTE(rk[3], 0)] & 0xff];
         }
     }
 }
@@ -244,6 +244,7 @@ void AES::encrypt(const byte* inBlock, const byte* xorBlock,
     s2 ^= rk[2];
     s3 ^= rk[3];
    
+    s0 |= PreFetchTe();
     /*
      * Nr - 1 full rounds:
      */
@@ -312,28 +313,28 @@ void AES::encrypt(const byte* inBlock, const byte* xorBlock,
      */
 
     s0 =
-        (Te4[GETBYTE(t0, 3)] & 0xff000000) ^
-        (Te4[GETBYTE(t1, 2)] & 0x00ff0000) ^
-        (Te4[GETBYTE(t2, 1)] & 0x0000ff00) ^
-        (Te4[GETBYTE(t3, 0)] & 0x000000ff) ^
+        (Te2[GETBYTE(t0, 3)] & 0xff000000) ^
+        (Te3[GETBYTE(t1, 2)] & 0x00ff0000) ^
+        (Te0[GETBYTE(t2, 1)] & 0x0000ff00) ^
+        (Te1[GETBYTE(t3, 0)] & 0x000000ff) ^
         rk[0];
     s1 =
-        (Te4[GETBYTE(t1, 3)] & 0xff000000) ^
-        (Te4[GETBYTE(t2, 2)] & 0x00ff0000) ^
-        (Te4[GETBYTE(t3, 1)] & 0x0000ff00) ^
-        (Te4[GETBYTE(t0, 0)] & 0x000000ff) ^
+        (Te2[GETBYTE(t1, 3)] & 0xff000000) ^
+        (Te3[GETBYTE(t2, 2)] & 0x00ff0000) ^
+        (Te0[GETBYTE(t3, 1)] & 0x0000ff00) ^
+        (Te1[GETBYTE(t0, 0)] & 0x000000ff) ^
         rk[1];
     s2 =
-        (Te4[GETBYTE(t2, 3)] & 0xff000000) ^
-        (Te4[GETBYTE(t3, 2)] & 0x00ff0000) ^
-        (Te4[GETBYTE(t0, 1)] & 0x0000ff00) ^
-        (Te4[GETBYTE(t1, 0)] & 0x000000ff) ^
+        (Te2[GETBYTE(t2, 3)] & 0xff000000) ^
+        (Te3[GETBYTE(t3, 2)] & 0x00ff0000) ^
+        (Te0[GETBYTE(t0, 1)] & 0x0000ff00) ^
+        (Te1[GETBYTE(t1, 0)] & 0x000000ff) ^
         rk[2];
     s3 =
-        (Te4[GETBYTE(t3, 3)] & 0xff000000) ^
-        (Te4[GETBYTE(t0, 2)] & 0x00ff0000) ^
-        (Te4[GETBYTE(t1, 1)] & 0x0000ff00) ^
-        (Te4[GETBYTE(t2, 0)] & 0x000000ff) ^
+        (Te2[GETBYTE(t3, 3)] & 0xff000000) ^
+        (Te3[GETBYTE(t0, 2)] & 0x00ff0000) ^
+        (Te0[GETBYTE(t1, 1)] & 0x0000ff00) ^
+        (Te1[GETBYTE(t2, 0)] & 0x000000ff) ^
         rk[3];
 
 
@@ -358,6 +359,8 @@ void AES::decrypt(const byte* inBlock, const byte* xorBlock,
     s2 ^= rk[2];
     s3 ^= rk[3];
 
+    s0 |= PreFetchTd();
+
     /*
      * Nr - 1 full rounds:
      */
@@ -423,29 +426,32 @@ void AES::decrypt(const byte* inBlock, const byte* xorBlock,
      * apply last round and
      * map cipher state to byte array block:
      */
+
+    t0 |= PreFetchCTd4();
+
     s0 =
-        (Td4[GETBYTE(t0, 3)] & 0xff000000) ^
-        (Td4[GETBYTE(t3, 2)] & 0x00ff0000) ^
-        (Td4[GETBYTE(t2, 1)] & 0x0000ff00) ^
-        (Td4[GETBYTE(t1, 0)] & 0x000000ff) ^
+        ((word32)CTd4[GETBYTE(t0, 3)] << 24) ^
+        ((word32)CTd4[GETBYTE(t3, 2)] << 16) ^
+        ((word32)CTd4[GETBYTE(t2, 1)] <<  8) ^
+        ((word32)CTd4[GETBYTE(t1, 0)]) ^
         rk[0];
     s1 =
-        (Td4[GETBYTE(t1, 3)] & 0xff000000) ^
-        (Td4[GETBYTE(t0, 2)] & 0x00ff0000) ^
-        (Td4[GETBYTE(t3, 1)] & 0x0000ff00) ^
-        (Td4[GETBYTE(t2, 0)] & 0x000000ff) ^
+        ((word32)CTd4[GETBYTE(t1, 3)]  << 24) ^
+        ((word32)CTd4[GETBYTE(t0, 2)]  << 16) ^
+        ((word32)CTd4[GETBYTE(t3, 1)]  <<  8) ^
+        ((word32)CTd4[GETBYTE(t2, 0)]) ^
         rk[1];
     s2 =
-        (Td4[GETBYTE(t2, 3)] & 0xff000000) ^
-        (Td4[GETBYTE(t1, 2)] & 0x00ff0000) ^
-        (Td4[GETBYTE(t0, 1)] & 0x0000ff00) ^
-        (Td4[GETBYTE(t3, 0)] & 0x000000ff) ^
+        ((word32)CTd4[GETBYTE(t2, 3)] << 24  ) ^
+        ((word32)CTd4[GETBYTE(t1, 2)] << 16 ) ^
+        ((word32)CTd4[GETBYTE(t0, 1)] <<  8 ) ^
+        ((word32)CTd4[GETBYTE(t3, 0)]) ^
         rk[2];
     s3 =
-        (Td4[GETBYTE(t3, 3)] & 0xff000000) ^
-        (Td4[GETBYTE(t2, 2)] & 0x00ff0000) ^
-        (Td4[GETBYTE(t1, 1)] & 0x0000ff00) ^
-        (Td4[GETBYTE(t0, 0)] & 0x000000ff) ^
+        ((word32)CTd4[GETBYTE(t3, 3)] << 24) ^
+        ((word32)CTd4[GETBYTE(t2, 2)] << 16) ^
+        ((word32)CTd4[GETBYTE(t1, 1)] <<  8) ^
+        ((word32)CTd4[GETBYTE(t0, 0)]) ^
         rk[3];
 
     gpBlock::Put(xorBlock, outBlock)(s0)(s1)(s2)(s3);
@@ -1826,18 +1832,52 @@ const word32 AES::Td[5][256] = {
 }
 };
 
+const byte AES::CTd4[256] =
+{
+    0x52U, 0x09U, 0x6aU, 0xd5U, 0x30U, 0x36U, 0xa5U, 0x38U,
+    0xbfU, 0x40U, 0xa3U, 0x9eU, 0x81U, 0xf3U, 0xd7U, 0xfbU,
+    0x7cU, 0xe3U, 0x39U, 0x82U, 0x9bU, 0x2fU, 0xffU, 0x87U,
+    0x34U, 0x8eU, 0x43U, 0x44U, 0xc4U, 0xdeU, 0xe9U, 0xcbU,
+    0x54U, 0x7bU, 0x94U, 0x32U, 0xa6U, 0xc2U, 0x23U, 0x3dU,
+    0xeeU, 0x4cU, 0x95U, 0x0bU, 0x42U, 0xfaU, 0xc3U, 0x4eU,
+    0x08U, 0x2eU, 0xa1U, 0x66U, 0x28U, 0xd9U, 0x24U, 0xb2U,
+    0x76U, 0x5bU, 0xa2U, 0x49U, 0x6dU, 0x8bU, 0xd1U, 0x25U,
+    0x72U, 0xf8U, 0xf6U, 0x64U, 0x86U, 0x68U, 0x98U, 0x16U,
+    0xd4U, 0xa4U, 0x5cU, 0xccU, 0x5dU, 0x65U, 0xb6U, 0x92U,
+    0x6cU, 0x70U, 0x48U, 0x50U, 0xfdU, 0xedU, 0xb9U, 0xdaU,
+    0x5eU, 0x15U, 0x46U, 0x57U, 0xa7U, 0x8dU, 0x9dU, 0x84U,
+    0x90U, 0xd8U, 0xabU, 0x00U, 0x8cU, 0xbcU, 0xd3U, 0x0aU,
+    0xf7U, 0xe4U, 0x58U, 0x05U, 0xb8U, 0xb3U, 0x45U, 0x06U,
+    0xd0U, 0x2cU, 0x1eU, 0x8fU, 0xcaU, 0x3fU, 0x0fU, 0x02U,
+    0xc1U, 0xafU, 0xbdU, 0x03U, 0x01U, 0x13U, 0x8aU, 0x6bU,
+    0x3aU, 0x91U, 0x11U, 0x41U, 0x4fU, 0x67U, 0xdcU, 0xeaU,
+    0x97U, 0xf2U, 0xcfU, 0xceU, 0xf0U, 0xb4U, 0xe6U, 0x73U,
+    0x96U, 0xacU, 0x74U, 0x22U, 0xe7U, 0xadU, 0x35U, 0x85U,
+    0xe2U, 0xf9U, 0x37U, 0xe8U, 0x1cU, 0x75U, 0xdfU, 0x6eU,
+    0x47U, 0xf1U, 0x1aU, 0x71U, 0x1dU, 0x29U, 0xc5U, 0x89U,
+    0x6fU, 0xb7U, 0x62U, 0x0eU, 0xaaU, 0x18U, 0xbeU, 0x1bU,
+    0xfcU, 0x56U, 0x3eU, 0x4bU, 0xc6U, 0xd2U, 0x79U, 0x20U,
+    0x9aU, 0xdbU, 0xc0U, 0xfeU, 0x78U, 0xcdU, 0x5aU, 0xf4U,
+    0x1fU, 0xddU, 0xa8U, 0x33U, 0x88U, 0x07U, 0xc7U, 0x31U,
+    0xb1U, 0x12U, 0x10U, 0x59U, 0x27U, 0x80U, 0xecU, 0x5fU,
+    0x60U, 0x51U, 0x7fU, 0xa9U, 0x19U, 0xb5U, 0x4aU, 0x0dU,
+    0x2dU, 0xe5U, 0x7aU, 0x9fU, 0x93U, 0xc9U, 0x9cU, 0xefU,
+    0xa0U, 0xe0U, 0x3bU, 0x4dU, 0xaeU, 0x2aU, 0xf5U, 0xb0U,
+    0xc8U, 0xebU, 0xbbU, 0x3cU, 0x83U, 0x53U, 0x99U, 0x61U,
+    0x17U, 0x2bU, 0x04U, 0x7eU, 0xbaU, 0x77U, 0xd6U, 0x26U,
+    0xe1U, 0x69U, 0x14U, 0x63U, 0x55U, 0x21U, 0x0cU, 0x7dU,
+};
+
 
 const word32* AES::Te0 = AES::Te[0];
 const word32* AES::Te1 = AES::Te[1];
 const word32* AES::Te2 = AES::Te[2];
 const word32* AES::Te3 = AES::Te[3];
-const word32* AES::Te4 = AES::Te[4];
 
 const word32* AES::Td0 = AES::Td[0];
 const word32* AES::Td1 = AES::Td[1];
 const word32* AES::Td2 = AES::Td[2];
 const word32* AES::Td3 = AES::Td[3];
-const word32* AES::Td4 = AES::Td[4];
 
 
 
diff --git a/extra/yassl/taocrypt/src/asn.cpp b/extra/yassl/taocrypt/src/asn.cpp
index a210d805452..7ff3c7167d2 100644
--- a/extra/yassl/taocrypt/src/asn.cpp
+++ b/extra/yassl/taocrypt/src/asn.cpp
@@ -1209,17 +1209,17 @@ word32 DecodeDSA_Signature(byte* decoded, const byte* encoded, word32 sz)
     }
     word32 rLen = GetLength(source);
     if (rLen != 20) {
-        if (rLen == 21) {       // zero at front, eat
+        while (rLen > 20 && source.remaining() > 0) {  // zero's at front, eat
             source.next();
             --rLen;
         }
-        else if (rLen == 19) {  // add zero to front so 20 bytes
+        if (rLen < 20) { // add zero's to front so 20 bytes
+            word32 tmpLen = rLen;
+            while (tmpLen < 20) {
             decoded[0] = 0;
             decoded++;
+                tmpLen++;
         }
-        else {
-            source.SetError(DSA_SZ_E);
-            return 0;
         }
     }
     memcpy(decoded, source.get_buffer() + source.get_index(), rLen);
@@ -1232,17 +1232,17 @@ word32 DecodeDSA_Signature(byte* decoded, const byte* encoded, word32 sz)
     }
     word32 sLen = GetLength(source);
     if (sLen != 20) {
-        if (sLen == 21) {
-            source.next();          // zero at front, eat
+        while (sLen > 20 && source.remaining() > 0) {
+            source.next();          // zero's at front, eat
             --sLen;
         }
-        else if (sLen == 19) {
-            decoded[rLen] = 0;      // add zero to front so 20 bytes
+        if (sLen < 20) { // add zero's to front so 20 bytes
+            word32 tmpLen = sLen;
+            while (tmpLen < 20) {
+                decoded[rLen] = 0;
             decoded++;
+                tmpLen++;
         }
-        else {
-            source.SetError(DSA_SZ_E);
-            return 0;
         }
     }
     memcpy(decoded + rLen, source.get_buffer() + source.get_index(), sLen);
diff --git a/extra/yassl/taocrypt/src/dsa.cpp b/extra/yassl/taocrypt/src/dsa.cpp
index bf116d3e48d..b19fed9235b 100644
--- a/extra/yassl/taocrypt/src/dsa.cpp
+++ b/extra/yassl/taocrypt/src/dsa.cpp
@@ -172,6 +172,7 @@ word32 DSA_Signer::Sign(const byte* sha_digest, byte* sig,
     const Integer& q = key_.GetSubGroupOrder();
     const Integer& g = key_.GetSubGroupGenerator();
     const Integer& x = key_.GetPrivatePart();
+    byte* tmpPtr = sig;  // initial signature output
 
     Integer k(rng, 1, q - 1);
 
@@ -187,22 +188,23 @@ word32 DSA_Signer::Sign(const byte* sha_digest, byte* sig,
         return -1;
 
     int rSz = r_.ByteCount();
+    int tmpSz = rSz;
 
-    if (rSz == 19) {
-        sig[0] = 0;
-        sig++;
+    while (tmpSz++ < SHA::DIGEST_SIZE) {
+        *sig++ = 0;
     }
     
     r_.Encode(sig,  rSz);
 
+    sig = tmpPtr + SHA::DIGEST_SIZE;  // advance sig output to s
     int sSz = s_.ByteCount();
+    tmpSz = sSz;
 
-    if (sSz == 19) {
-        sig[rSz] = 0;
-        sig++;
+    while (tmpSz++ < SHA::DIGEST_SIZE) {
+        *sig++ = 0;
     }
 
-    s_.Encode(sig + rSz, sSz);
+    s_.Encode(sig, sSz);
 
     return 40;
 }
diff --git a/extra/yassl/taocrypt/test/test.cpp b/extra/yassl/taocrypt/test/test.cpp
index a7d5cb3e8af..fc1f0e8762d 100644
--- a/extra/yassl/taocrypt/test/test.cpp
+++ b/extra/yassl/taocrypt/test/test.cpp
@@ -1277,6 +1277,9 @@ int dsa_test()
     if (!verifier.Verify(digest, decoded))
         return -90;
 
+    if (!verifier.Verify(digest, signature))
+        return -91;
+
     return 0;
 }
 
diff --git a/extra/yassl/testsuite/test.hpp b/extra/yassl/testsuite/test.hpp
index 5c9dc7ce117..e2e44c24027 100644
--- a/extra/yassl/testsuite/test.hpp
+++ b/extra/yassl/testsuite/test.hpp
@@ -22,7 +22,6 @@
 #define yaSSL_TEST_HPP
 
 #include "runtime.hpp"
-#include "openssl/ssl.h"   /* openssl compatibility test */
 #include "error.hpp"
 #include <stdio.h>
 #include <stdlib.h>
@@ -56,6 +55,7 @@
 #endif
     #define SOCKET_T int
 #endif /* _WIN32 */
+#include "openssl/ssl.h"   /* openssl compatibility test */
 
 
 #ifdef _MSC_VER
-- 
cgit v1.2.1