Sfoglia il codice sorgente

Merge branch 'TI_hash' of https://github.com/kojo1/wolfssl into kojo-ti

toddouska 9 anni fa
parent
commit
9e7cb81d5a
5 ha cambiato i file con 321 aggiunte e 212 eliminazioni
  1. 271 201
      src/internal.c
  2. 12 10
      wolfcrypt/src/hash.c
  3. 21 1
      wolfcrypt/src/port/ti/ti-hash.c
  4. 6 0
      wolfssl/wolfcrypt/hash.h
  5. 11 0
      wolfssl/wolfcrypt/settings.h

+ 271 - 201
src/internal.c

@@ -1843,7 +1843,7 @@ void SSL_ResourceFree(WOLFSSL* ssl)
 
 #ifdef WOLFSSL_TI_HASH
 static void HashFinal(WOLFSSL * ssl) {
-	byte dummyHash[32] ;
+    byte dummyHash[32] ;
 #ifndef NO_MD5
     wc_Md5Final(&(ssl->hsHashes->hashMd5), dummyHash) ;
 #endif
@@ -3033,22 +3033,44 @@ static const byte PAD2[PAD_MD5] =
                               };
 
 /* calculate MD5 hash for finished */
+#ifdef WOLFSSL_TI_HASH
+#include <wolfssl/wolfcrypt/hash.h>
+#endif
+
 static void BuildMD5(WOLFSSL* ssl, Hashes* hashes, const byte* sender)
 {
+
     byte md5_result[MD5_DIGEST_SIZE];
 
+#ifdef WOLFSSL_SMALL_STACK
+        Md5* md5   = (Md5*)XMALLOC(sizeof(Md5), NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        Md5* md5_2 = (Md5*)XMALLOC(sizeof(Md5), NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#else
+        Md5 md5[1];
+        Md5 md5_2[1];
+#endif
+
     /* make md5 inner */
+    md5[0] = ssl->hsHashes->hashMd5 ; /* Save current position */
+
     wc_Md5Update(&ssl->hsHashes->hashMd5, sender, SIZEOF_SENDER);
     wc_Md5Update(&ssl->hsHashes->hashMd5, ssl->arrays->masterSecret,SECRET_LEN);
     wc_Md5Update(&ssl->hsHashes->hashMd5, PAD1, PAD_MD5);
     wc_Md5GetHash(&ssl->hsHashes->hashMd5, md5_result);
+    wc_Md5RestorePos(&ssl->hsHashes->hashMd5, md5) ; /* Restore current position */
 
     /* make md5 outer */
-    wc_Md5Update(&ssl->hsHashes->hashMd5, ssl->arrays->masterSecret,SECRET_LEN);
-    wc_Md5Update(&ssl->hsHashes->hashMd5, PAD2, PAD_MD5);
-    wc_Md5Update(&ssl->hsHashes->hashMd5, md5_result, MD5_DIGEST_SIZE);
+    wc_InitMd5(md5_2) ;
+    wc_Md5Update(md5_2, ssl->arrays->masterSecret,SECRET_LEN);
+    wc_Md5Update(md5_2, PAD2, PAD_MD5);
+    wc_Md5Update(md5_2, md5_result, MD5_DIGEST_SIZE);
+    wc_Md5Final(md5_2, hashes->md5);
+
+#ifdef WOLFSSL_SMALL_STACK
+    XFREE(md5, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    XFREE(md5_2, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
 
-    wc_Md5GetHash(&ssl->hsHashes->hashMd5, hashes->md5);
 }
 
 
@@ -3057,21 +3079,36 @@ static void BuildSHA(WOLFSSL* ssl, Hashes* hashes, const byte* sender)
 {
     byte sha_result[SHA_DIGEST_SIZE];
 
+#ifdef WOLFSSL_SMALL_STACK
+        Sha* sha = (Sha*)XMALLOC(sizeof(Sha), NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        Sha* sha2 = (Sha*)XMALLOC(sizeof(Sha), NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#else
+        Sha sha[1];
+        Sha sha2[1] ;
+#endif
     /* make sha inner */
+    sha[0] = ssl->hsHashes->hashSha ; /* Save current position */
+
     wc_ShaUpdate(&ssl->hsHashes->hashSha, sender, SIZEOF_SENDER);
     wc_ShaUpdate(&ssl->hsHashes->hashSha, ssl->arrays->masterSecret,SECRET_LEN);
     wc_ShaUpdate(&ssl->hsHashes->hashSha, PAD1, PAD_SHA);
     wc_ShaGetHash(&ssl->hsHashes->hashSha, sha_result);
+    wc_ShaRestorePos(&ssl->hsHashes->hashSha, sha) ; /* Restore current position */
 
     /* make sha outer */
-    wc_ShaUpdate(&ssl->hsHashes->hashSha, ssl->arrays->masterSecret,SECRET_LEN);
-    wc_ShaUpdate(&ssl->hsHashes->hashSha, PAD2, PAD_SHA);
-    wc_ShaUpdate(&ssl->hsHashes->hashSha, sha_result, SHA_DIGEST_SIZE);
+    wc_InitSha(sha2) ;
+    wc_ShaUpdate(sha2, ssl->arrays->masterSecret,SECRET_LEN);
+    wc_ShaUpdate(sha2, PAD2, PAD_SHA);
+    wc_ShaUpdate(sha2, sha_result, SHA_DIGEST_SIZE);
+    wc_ShaFinal(sha2, hashes->sha);
 
-    wc_ShaGetHash(&ssl->hsHashes->hashSha, hashes->sha);
-}
+#ifdef WOLFSSL_SMALL_STACK
+    XFREE(sha, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    XFREE(sha2, NULL, DYNAMIC_TYPE_TMP_BUFFER);
 #endif
 
+}
+#endif
 
 /* Finished doesn't support SHA512, not SHA512 cipher suites yet */
 static int BuildFinished(WOLFSSL* ssl, Hashes* hashes, const byte* sender)
@@ -5128,7 +5165,7 @@ static int Poly1305Tag(WOLFSSL* ssl, byte* additional, const byte* out,
     if ((ret = wc_Poly1305SetKey(ssl->auth.poly1305, cipher, keySz)) != 0)
         return ret;
 
-	/* additional input to poly1305 */
+    /* additional input to poly1305 */
     if ((ret = wc_Poly1305Update(ssl->auth.poly1305, additional, blockSz)) != 0)
         return ret;
 
@@ -5187,7 +5224,7 @@ static int Poly1305TagOld(WOLFSSL* ssl, byte* additional, const byte* out,
     if ((ret = wc_Poly1305SetKey(ssl->auth.poly1305, cipher, keySz)) != 0)
         return ret;
 
-	/* add TLS compressed length and additional input to poly1305 */
+    /* add TLS compressed length and additional input to poly1305 */
     additional[AEAD_AUTH_DATA_SZ - 2] = (msglen >> 8) & 0xff;
     additional[AEAD_AUTH_DATA_SZ - 1] =  msglen       & 0xff;
     if ((ret = wc_Poly1305Update(ssl->auth.poly1305, additional,
@@ -5227,201 +5264,201 @@ static int Poly1305TagOld(WOLFSSL* ssl, byte* additional, const byte* out,
 static int  ChachaAEADEncrypt(WOLFSSL* ssl, byte* out, const byte* input,
                               word16 sz)
 {
-	const byte* additionalSrc = input - RECORD_HEADER_SZ;
-	int ret = 0;
-	byte tag[POLY1305_AUTH_SZ];
-	byte additional[CHACHA20_BLOCK_SIZE];
-	byte nonce[AEAD_NONCE_SZ];
-	byte cipher[CHACHA20_256_KEY_SIZE]; /* generated key for poly1305 */
+    const byte* additionalSrc = input - RECORD_HEADER_SZ;
+    int ret = 0;
+    byte tag[POLY1305_AUTH_SZ];
+    byte additional[CHACHA20_BLOCK_SIZE];
+    byte nonce[AEAD_NONCE_SZ];
+    byte cipher[CHACHA20_256_KEY_SIZE]; /* generated key for poly1305 */
     #ifdef CHACHA_AEAD_TEST
         int i;
     #endif
 
-	XMEMSET(tag, 0, sizeof(tag));
-	XMEMSET(nonce, 0, AEAD_NONCE_SZ);
-	XMEMSET(cipher, 0, sizeof(cipher));
-	XMEMSET(additional, 0, CHACHA20_BLOCK_SIZE);
-
-	/* get nonce */
-	c32toa(ssl->keys.sequence_number, nonce + AEAD_IMP_IV_SZ
-	       + AEAD_SEQ_OFFSET);
-
-	/* opaque SEQ number stored for AD */
-	c32toa(GetSEQIncrement(ssl, 0), additional + AEAD_SEQ_OFFSET);
-
-	/* Store the type, version. Unfortunately, they are in
-	 * the input buffer ahead of the plaintext. */
-	#ifdef WOLFSSL_DTLS
-	    if (ssl->options.dtls) {
-	        c16toa(ssl->keys.dtls_epoch, additional);
-	        additionalSrc -= DTLS_HANDSHAKE_EXTRA;
-	    }
-	#endif
-
-	XMEMCPY(additional + AEAD_TYPE_OFFSET, additionalSrc, 3);
-
-	#ifdef CHACHA_AEAD_TEST
-		printf("Encrypt Additional : ");
-		for (i = 0; i < CHACHA20_BLOCK_SIZE; i++) {
-		    printf("%02x", additional[i]);
-		}
-		printf("\n\n");
-		printf("input before encryption :\n");
-		for (i = 0; i < sz; i++) {
-		    printf("%02x", input[i]);
-		    if ((i + 1) % 16 == 0)
-		        printf("\n");
-		}
-		printf("\n");
-	#endif
-
-	/* set the nonce for chacha and get poly1305 key */
-	if ((ret = wc_Chacha_SetIV(ssl->encrypt.chacha, nonce, 0)) != 0)
-	    return ret;
-
-		if ((ret = wc_Chacha_Process(ssl->encrypt.chacha, cipher,
-	                cipher, sizeof(cipher))) != 0)
-	    return ret;
-
-	/* encrypt the plain text */
-	if ((ret = wc_Chacha_Process(ssl->encrypt.chacha, out, input,
-	               sz - ssl->specs.aead_mac_size)) != 0)
-	    return ret;
-
-	/* get the tag : future use of hmac could go here*/
-	if (ssl->options.oldPoly == 1) {
-	    if ((ret = Poly1305TagOld(ssl, additional, (const byte* )out,
-	                cipher, sz, tag)) != 0)
-	        return ret;
-	}
-	else {
-	    if ((ret = Poly1305Tag(ssl, additional, (const byte* )out,
-	                cipher, sz, tag)) != 0)
-	        return ret;
-	}
-
-	/* append tag to ciphertext */
-	XMEMCPY(out + sz - ssl->specs.aead_mac_size, tag, sizeof(tag));
-
-	AeadIncrementExpIV(ssl);
-	ForceZero(nonce, AEAD_NONCE_SZ);
-
-	#ifdef CHACHA_AEAD_TEST
-	   printf("mac tag :\n");
-	    for (i = 0; i < 16; i++) {
-	       printf("%02x", tag[i]);
-	       if ((i + 1) % 16 == 0)
-	           printf("\n");
-	    }
-	   printf("\n\noutput after encrypt :\n");
-	    for (i = 0; i < sz; i++) {
-	       printf("%02x", out[i]);
-	       if ((i + 1) % 16 == 0)
-	           printf("\n");
-	    }
-	    printf("\n");
-	#endif
-
-	return ret;
+    XMEMSET(tag, 0, sizeof(tag));
+    XMEMSET(nonce, 0, AEAD_NONCE_SZ);
+    XMEMSET(cipher, 0, sizeof(cipher));
+    XMEMSET(additional, 0, CHACHA20_BLOCK_SIZE);
+
+    /* get nonce */
+    c32toa(ssl->keys.sequence_number, nonce + AEAD_IMP_IV_SZ
+           + AEAD_SEQ_OFFSET);
+
+    /* opaque SEQ number stored for AD */
+    c32toa(GetSEQIncrement(ssl, 0), additional + AEAD_SEQ_OFFSET);
+
+    /* Store the type, version. Unfortunately, they are in
+     * the input buffer ahead of the plaintext. */
+    #ifdef WOLFSSL_DTLS
+        if (ssl->options.dtls) {
+            c16toa(ssl->keys.dtls_epoch, additional);
+            additionalSrc -= DTLS_HANDSHAKE_EXTRA;
+        }
+    #endif
+
+    XMEMCPY(additional + AEAD_TYPE_OFFSET, additionalSrc, 3);
+
+    #ifdef CHACHA_AEAD_TEST
+        printf("Encrypt Additional : ");
+        for (i = 0; i < CHACHA20_BLOCK_SIZE; i++) {
+            printf("%02x", additional[i]);
+        }
+        printf("\n\n");
+        printf("input before encryption :\n");
+        for (i = 0; i < sz; i++) {
+            printf("%02x", input[i]);
+            if ((i + 1) % 16 == 0)
+                printf("\n");
+        }
+        printf("\n");
+    #endif
+
+    /* set the nonce for chacha and get poly1305 key */
+    if ((ret = wc_Chacha_SetIV(ssl->encrypt.chacha, nonce, 0)) != 0)
+        return ret;
+
+        if ((ret = wc_Chacha_Process(ssl->encrypt.chacha, cipher,
+                    cipher, sizeof(cipher))) != 0)
+        return ret;
+
+    /* encrypt the plain text */
+    if ((ret = wc_Chacha_Process(ssl->encrypt.chacha, out, input,
+                   sz - ssl->specs.aead_mac_size)) != 0)
+        return ret;
+
+    /* get the tag : future use of hmac could go here*/
+    if (ssl->options.oldPoly == 1) {
+        if ((ret = Poly1305TagOld(ssl, additional, (const byte* )out,
+                    cipher, sz, tag)) != 0)
+            return ret;
+    }
+    else {
+        if ((ret = Poly1305Tag(ssl, additional, (const byte* )out,
+                    cipher, sz, tag)) != 0)
+            return ret;
+    }
+
+    /* append tag to ciphertext */
+    XMEMCPY(out + sz - ssl->specs.aead_mac_size, tag, sizeof(tag));
+
+    AeadIncrementExpIV(ssl);
+    ForceZero(nonce, AEAD_NONCE_SZ);
+
+    #ifdef CHACHA_AEAD_TEST
+       printf("mac tag :\n");
+        for (i = 0; i < 16; i++) {
+           printf("%02x", tag[i]);
+           if ((i + 1) % 16 == 0)
+               printf("\n");
+        }
+       printf("\n\noutput after encrypt :\n");
+        for (i = 0; i < sz; i++) {
+           printf("%02x", out[i]);
+           if ((i + 1) % 16 == 0)
+               printf("\n");
+        }
+        printf("\n");
+    #endif
+
+    return ret;
 }
 
 
 static int ChachaAEADDecrypt(WOLFSSL* ssl, byte* plain, const byte* input,
                            word16 sz)
 {
-	byte additional[CHACHA20_BLOCK_SIZE];
-	byte nonce[AEAD_NONCE_SZ];
-	byte tag[POLY1305_AUTH_SZ];
-	byte cipher[CHACHA20_256_KEY_SIZE]; /* generated key for mac */
-	int ret = 0;
+    byte additional[CHACHA20_BLOCK_SIZE];
+    byte nonce[AEAD_NONCE_SZ];
+    byte tag[POLY1305_AUTH_SZ];
+    byte cipher[CHACHA20_256_KEY_SIZE]; /* generated key for mac */
+    int ret = 0;
 
-	XMEMSET(tag, 0, sizeof(tag));
-	XMEMSET(cipher, 0, sizeof(cipher));
-	XMEMSET(nonce, 0, AEAD_NONCE_SZ);
-	XMEMSET(additional, 0, CHACHA20_BLOCK_SIZE);
+    XMEMSET(tag, 0, sizeof(tag));
+    XMEMSET(cipher, 0, sizeof(cipher));
+    XMEMSET(nonce, 0, AEAD_NONCE_SZ);
+    XMEMSET(additional, 0, CHACHA20_BLOCK_SIZE);
 
     #ifdef CHACHA_AEAD_TEST
        int i;
-	   printf("input before decrypt :\n");
-	    for (i = 0; i < sz; i++) {
-	       printf("%02x", input[i]);
-	       if ((i + 1) % 16 == 0)
-	           printf("\n");
-	    }
-	    printf("\n");
-	#endif
-
-	/* get nonce */
-	c32toa(ssl->keys.peer_sequence_number, nonce + AEAD_IMP_IV_SZ
-	        + AEAD_SEQ_OFFSET);
-
-	/* sequence number field is 64-bits, we only use 32-bits */
-	c32toa(GetSEQIncrement(ssl, 1), additional + AEAD_SEQ_OFFSET);
-
-	/* get AD info */
-	additional[AEAD_TYPE_OFFSET] = ssl->curRL.type;
-	additional[AEAD_VMAJ_OFFSET] = ssl->curRL.pvMajor;
-	additional[AEAD_VMIN_OFFSET] = ssl->curRL.pvMinor;
-
-	/* Store the type, version. */
-	#ifdef WOLFSSL_DTLS
-	    if (ssl->options.dtls)
-	        c16toa(ssl->keys.dtls_state.curEpoch, additional);
-	#endif
-
-	#ifdef CHACHA_AEAD_TEST
-		printf("Decrypt Additional : ");
-		for (i = 0; i < CHACHA20_BLOCK_SIZE; i++) {
-		    printf("%02x", additional[i]);
-		}
-		printf("\n\n");
-	#endif
-
-	/* set nonce and get poly1305 key */
-	if ((ret = wc_Chacha_SetIV(ssl->decrypt.chacha, nonce, 0)) != 0)
-	    return ret;
-
-	if ((ret = wc_Chacha_Process(ssl->decrypt.chacha, cipher,
-	                cipher, sizeof(cipher))) != 0)
-	    return ret;
-
-	/* get the tag : future use of hmac could go here*/
-	if (ssl->options.oldPoly == 1) {
-	    if ((ret = Poly1305TagOld(ssl, additional, input, cipher,
-	                    sz, tag)) != 0)
-	        return ret;
-	}
-	else {
-	    if ((ret = Poly1305Tag(ssl, additional, input, cipher,
-	                    sz, tag)) != 0)
-	        return ret;
-	}
-
-	/* check mac sent along with packet */
+       printf("input before decrypt :\n");
+        for (i = 0; i < sz; i++) {
+           printf("%02x", input[i]);
+           if ((i + 1) % 16 == 0)
+               printf("\n");
+        }
+        printf("\n");
+    #endif
+
+    /* get nonce */
+    c32toa(ssl->keys.peer_sequence_number, nonce + AEAD_IMP_IV_SZ
+            + AEAD_SEQ_OFFSET);
+
+    /* sequence number field is 64-bits, we only use 32-bits */
+    c32toa(GetSEQIncrement(ssl, 1), additional + AEAD_SEQ_OFFSET);
+
+    /* get AD info */
+    additional[AEAD_TYPE_OFFSET] = ssl->curRL.type;
+    additional[AEAD_VMAJ_OFFSET] = ssl->curRL.pvMajor;
+    additional[AEAD_VMIN_OFFSET] = ssl->curRL.pvMinor;
+
+    /* Store the type, version. */
+    #ifdef WOLFSSL_DTLS
+        if (ssl->options.dtls)
+            c16toa(ssl->keys.dtls_state.curEpoch, additional);
+    #endif
+
+    #ifdef CHACHA_AEAD_TEST
+        printf("Decrypt Additional : ");
+        for (i = 0; i < CHACHA20_BLOCK_SIZE; i++) {
+            printf("%02x", additional[i]);
+        }
+        printf("\n\n");
+    #endif
+
+    /* set nonce and get poly1305 key */
+    if ((ret = wc_Chacha_SetIV(ssl->decrypt.chacha, nonce, 0)) != 0)
+        return ret;
+
+    if ((ret = wc_Chacha_Process(ssl->decrypt.chacha, cipher,
+                    cipher, sizeof(cipher))) != 0)
+        return ret;
+
+    /* get the tag : future use of hmac could go here*/
+    if (ssl->options.oldPoly == 1) {
+        if ((ret = Poly1305TagOld(ssl, additional, input, cipher,
+                        sz, tag)) != 0)
+            return ret;
+    }
+    else {
+        if ((ret = Poly1305Tag(ssl, additional, input, cipher,
+                        sz, tag)) != 0)
+            return ret;
+    }
+
+    /* check mac sent along with packet */
     if (ConstantCompare(input + sz - ssl->specs.aead_mac_size, tag,
                 ssl->specs.aead_mac_size) != 0) {
-	    WOLFSSL_MSG("Mac did not match");
-	    SendAlert(ssl, alert_fatal, bad_record_mac);
-	    ForceZero(nonce, AEAD_NONCE_SZ);
-	    return VERIFY_MAC_ERROR;
-	}
-
-	/* if mac was good decrypt message */
-	if ((ret = wc_Chacha_Process(ssl->decrypt.chacha, plain, input,
-	               sz - ssl->specs.aead_mac_size)) != 0)
-	    return ret;
-
-	#ifdef CHACHA_AEAD_TEST
-	   printf("plain after decrypt :\n");
-	    for (i = 0; i < sz; i++) {
-	       printf("%02x", plain[i]);
-	       if ((i + 1) % 16 == 0)
-	           printf("\n");
-	    }
-	    printf("\n");
-	#endif
-
-	return ret;
+        WOLFSSL_MSG("Mac did not match");
+        SendAlert(ssl, alert_fatal, bad_record_mac);
+        ForceZero(nonce, AEAD_NONCE_SZ);
+        return VERIFY_MAC_ERROR;
+    }
+
+    /* if mac was good decrypt message */
+    if ((ret = wc_Chacha_Process(ssl->decrypt.chacha, plain, input,
+                   sz - ssl->specs.aead_mac_size)) != 0)
+        return ret;
+
+    #ifdef CHACHA_AEAD_TEST
+       printf("plain after decrypt :\n");
+        for (i = 0; i < sz; i++) {
+           printf("%02x", plain[i]);
+           if ((i + 1) % 16 == 0)
+               printf("\n");
+        }
+        printf("\n");
+    #endif
+
+    return ret;
 }
 #endif /* HAVE_CHACHA && HAVE_POLY1305 */
 #endif /* HAVE_AEAD */
@@ -6814,17 +6851,33 @@ static void BuildMD5_CertVerify(WOLFSSL* ssl, byte* digest)
 {
     byte md5_result[MD5_DIGEST_SIZE];
 
+#ifdef WOLFSSL_SMALL_STACK
+        Md5* md5   = (Md5*)XMALLOC(sizeof(Md5), NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        Md5* md5_2 = (Md5*)XMALLOC(sizeof(Md5), NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#else
+        Md5 md5[1];
+        Md5 md5_2[1];
+#endif
+
     /* make md5 inner */
+    md5[0] = ssl->hsHashes->hashMd5 ; /* Save current position */
     wc_Md5Update(&ssl->hsHashes->hashMd5, ssl->arrays->masterSecret,SECRET_LEN);
     wc_Md5Update(&ssl->hsHashes->hashMd5, PAD1, PAD_MD5);
-    wc_Md5Final(&ssl->hsHashes->hashMd5, md5_result);
+    wc_Md5GetHash(&ssl->hsHashes->hashMd5, md5_result);
+    wc_Md5RestorePos(&ssl->hsHashes->hashMd5, md5) ; /* Restore current position */
 
     /* make md5 outer */
-    wc_Md5Update(&ssl->hsHashes->hashMd5, ssl->arrays->masterSecret, SECRET_LEN);
-    wc_Md5Update(&ssl->hsHashes->hashMd5, PAD2, PAD_MD5);
-    wc_Md5Update(&ssl->hsHashes->hashMd5, md5_result, MD5_DIGEST_SIZE);
+    wc_InitMd5(md5_2) ;
+    wc_Md5Update(md5_2, ssl->arrays->masterSecret, SECRET_LEN);
+    wc_Md5Update(md5_2, PAD2, PAD_MD5);
+    wc_Md5Update(md5_2, md5_result, MD5_DIGEST_SIZE);
 
-    wc_Md5Final(&ssl->hsHashes->hashMd5, digest);
+    wc_Md5Final(md5_2, digest);
+
+#ifdef WOLFSSL_SMALL_STACK
+    XFREE(md5, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    XFREE(md5_2, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
 }
 
 
@@ -6832,17 +6885,34 @@ static void BuildSHA_CertVerify(WOLFSSL* ssl, byte* digest)
 {
     byte sha_result[SHA_DIGEST_SIZE];
 
+#ifdef WOLFSSL_SMALL_STACK
+        Sha* sha   = (Sha*)XMALLOC(sizeof(Sha), NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        Sha* sha2 = (Sha*)XMALLOC(sizeof(Sha), NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#else
+        Sha sha[1];
+        Sha sha2[1];
+#endif
+
     /* make sha inner */
+    sha[0] = ssl->hsHashes->hashSha ; /* Save current position */
     wc_ShaUpdate(&ssl->hsHashes->hashSha, ssl->arrays->masterSecret,SECRET_LEN);
     wc_ShaUpdate(&ssl->hsHashes->hashSha, PAD1, PAD_SHA);
-    wc_ShaFinal(&ssl->hsHashes->hashSha, sha_result);
+    wc_ShaGetHash(&ssl->hsHashes->hashSha, sha_result);
+    wc_ShaRestorePos(&ssl->hsHashes->hashSha, sha) ; /* Restore current position */
 
     /* make sha outer */
-    wc_ShaUpdate(&ssl->hsHashes->hashSha, ssl->arrays->masterSecret,SECRET_LEN);
-    wc_ShaUpdate(&ssl->hsHashes->hashSha, PAD2, PAD_SHA);
-    wc_ShaUpdate(&ssl->hsHashes->hashSha, sha_result, SHA_DIGEST_SIZE);
+    wc_InitSha(sha2) ;
+    wc_ShaUpdate(sha2, ssl->arrays->masterSecret,SECRET_LEN);
+    wc_ShaUpdate(sha2, PAD2, PAD_SHA);
+    wc_ShaUpdate(sha2, sha_result, SHA_DIGEST_SIZE);
+
+    wc_ShaFinal(sha2, digest);
+
+#ifdef WOLFSSL_SMALL_STACK
+    XFREE(sha, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    XFREE(sha2, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
 
-    wc_ShaFinal(&ssl->hsHashes->hashSha, digest);
 }
 #endif /* NO_CERTS */
 #endif /* NO_OLD_TLS */

+ 12 - 10
wolfcrypt/src/hash.c

@@ -27,16 +27,6 @@
 
 #if !defined(WOLFSSL_TI_HASH)
 
-#if !defined(NO_MD5)
-#include <wolfssl/wolfcrypt/md5.h>
-#endif
-#if !defined(NO_SHA)
-#include <wolfssl/wolfcrypt/sha.h>
-#endif
-#if !defined(NO_SHA256)
-#include <wolfssl/wolfcrypt/sha256.h>
-#endif
-
 #include <wolfssl/wolfcrypt/hash.h>
 
 #if !defined(NO_MD5)
@@ -46,6 +36,10 @@ void wc_Md5GetHash(Md5* md5, byte* hash)
     wc_Md5Final(md5, hash) ;
     *md5 = save ;
 }
+
+WOLFSSL_API void wc_Md5RestorePos(Md5* m1, Md5* m2) {
+    *m1 = *m2 ;
+}
 #endif
 
 #if !defined(NO_SHA)
@@ -57,6 +51,10 @@ int wc_ShaGetHash(Sha* sha, byte* hash)
     *sha = save ;
     return ret ;
 }
+
+WOLFSSL_API void wc_ShaRestorePos(Sha* s1, Sha* s2) {
+    *s1 = *s2 ;
+}
 #endif
 
 #if !defined(NO_SHA256)
@@ -68,6 +66,10 @@ int wc_Sha256GetHash(Sha256* sha256, byte* hash)
     *sha256 = save ;
     return ret ;
 }
+
+WOLFSSL_API void wc_Sha256RestorePos(Sha256* s1, Sha256* s2) {
+    *s1 = *s2 ;
+}
 #endif
 
 #endif

+ 21 - 1
wolfcrypt/src/port/ti/ti-hash.c

@@ -107,6 +107,10 @@ static int hashGetHash(wolfssl_TI_Hash *hash, byte* result, word32 algo, word32
     return 0 ;
 }
 
+static void hashRestorePos(wolfssl_TI_Hash *h1, wolfssl_TI_Hash *h2) {
+	h1->used = h2->used ;
+}
+
 static int hashFinal(wolfssl_TI_Hash *hash, byte* result, word32 algo, word32 hsize)
 {   
     hashGetHash(hash, result, algo, hsize) ;
@@ -166,7 +170,11 @@ WOLFSSL_API void wc_Md5Final(Md5* md5, byte* hash)
 
 WOLFSSL_API void wc_Md5GetHash(Md5* md5, byte* hash)
 {
-    hashGetHash(md5, hash, SHAMD5_ALGO_MD5, MD5_DIGEST_SIZE) ;
+    hashGetHash((wolfssl_TI_Hash *)md5, hash, SHAMD5_ALGO_MD5, MD5_DIGEST_SIZE) ;
+}
+
+WOLFSSL_API void wc_Md5RestorePos(Md5* m1, Md5* m2) {
+	hashRestorePos((wolfssl_TI_Hash *)m1, (wolfssl_TI_Hash *)m2) ;
 }
 
 WOLFSSL_API int wc_Md5Hash(const byte*data, word32 len, byte*hash)
@@ -200,6 +208,10 @@ WOLFSSL_API int wc_ShaGetHash(Sha* sha, byte* hash)
     return hashGetHash(sha, hash, SHAMD5_ALGO_SHA1, SHA_DIGEST_SIZE) ;
 }
 
+WOLFSSL_API void wc_ShaRestorePos(Sha* s1, Sha* s2) {
+	hashRestorePos((wolfssl_TI_Hash *)s1, (wolfssl_TI_Hash *)s2) ;
+}
+
 WOLFSSL_API int wc_ShaHash(const byte*data, word32 len, byte*hash)
 { 
     return hashHash(data, len, hash, SHAMD5_ALGO_SHA1, SHA_DIGEST_SIZE) ;
@@ -231,6 +243,10 @@ WOLFSSL_API int wc_Sha224GetHash(Sha224* sha224, byte* hash)
     return hashGetHash(sha224, hash, SHAMD5_ALGO_SHA224, SHA224_DIGEST_SIZE) ;
 }
 
+WOLFSSL_API void wc_Sha224RestorePos(Sha224* s1, Sha224* s2) {
+	hashRestorePos((wolfssl_TI_Hash *)s1, (wolfssl_TI_Hash *)s2) ;
+}
+
 WOLFSSL_API int wc_Sha224Hash(const byte* data, word32 len, byte*hash)
 { 
     return hashHash(data, len, hash, SHAMD5_ALGO_SHA224, SHA224_DIGEST_SIZE) ;
@@ -262,6 +278,10 @@ WOLFSSL_API int wc_Sha256GetHash(Sha256* sha256, byte* hash)
     return hashGetHash(sha256, hash, SHAMD5_ALGO_SHA256, SHA256_DIGEST_SIZE) ;
 }
 
+WOLFSSL_API void wc_Sha256RestorePos(Sha256* s1, Sha256* s2) {
+	hashRestorePos((wolfssl_TI_Hash *)s1, (wolfssl_TI_Hash *)s2) ;
+}
+
 WOLFSSL_API int wc_Sha256Hash(const byte* data, word32 len, byte*hash)
 {
     return hashHash(data, len, hash, SHAMD5_ALGO_SHA256, SHA256_DIGEST_SIZE) ;

+ 6 - 0
wolfssl/wolfcrypt/hash.h

@@ -23,13 +23,19 @@
 #define WOLF_CRYPT_HASH_H
 
 #ifndef NO_MD5
+#include <wolfssl/wolfcrypt/md5.h>
 WOLFSSL_API void wc_Md5GetHash(Md5*, byte*);
+WOLFSSL_API void wc_Md5RestorePos(Md5*, Md5*) ;
 #endif
 #ifndef NO_SHA
+#include <wolfssl/wolfcrypt/sha.h>
 WOLFSSL_API int wc_ShaGetHash(Sha*, byte*);
+WOLFSSL_API void wc_ShaRestorePos(Sha*, Sha*) ;
 #endif
 #ifndef NO_SHA256
+#include <wolfssl/wolfcrypt/sha256.h>
 WOLFSSL_API int wc_Sha256GetHash(Sha256*, byte*);
+WOLFSSL_API void wc_Sha256RestorePos(Sha256*, Sha256*) ;
 #endif
 
 #endif

+ 11 - 0
wolfssl/wolfcrypt/settings.h

@@ -156,6 +156,17 @@
     #define NO_FILESYSTEM
 #endif
 
+#if defined(WOLFSSL_IAR_ARM)
+    #define NO_MAIN_DRIVER
+    #define SINGLE_THREADED
+    #define USE_CERT_BUFFERS_1024
+    #define BENCH_EMBEDDED
+    #define NO_FILESYSTEM
+    #define NO_WRITEV
+    #define WOLFSSL_USER_IO
+    #define  BENCH_EMBEDDED
+#endif
+
 #ifdef MICROCHIP_PIC32
     /* #define WOLFSSL_MICROCHIP_PIC32MZ */
     #define SIZEOF_LONG_LONG 8