diff --git a/wolfcrypt/src/sha256.c b/wolfcrypt/src/sha256.c index cad6f8028..059f224a7 100644 --- a/wolfcrypt/src/sha256.c +++ b/wolfcrypt/src/sha256.c @@ -25,6 +25,24 @@ #include +/* + * SHA256 Build Options: + * USE_SLOW_SHA256: Reduces code size by not partially unrolling + (~2KB smaller and ~25% slower) (default OFF) + * WOLFSSL_SHA256_BY_SPEC: Uses the Ch/Maj based on SHA256 specification + (default ON) + * WOLFSSL_SHA256_ALT_CH_MAJ: Alternate Ch/Maj that is easier for compilers to + optimize and recognize as SHA256 (default OFF) + * SHA256_MANY_REGISTERS: A SHA256 version that keeps all data in registers + and partial unrolled (default OFF) + */ + +/* Default SHA256 to use Ch/Maj based on specification */ +#if !defined(WOLFSSL_SHA256_BY_SPEC) && !defined(WOLFSSL_SHA256_ALT_CH_MAJ) + #define WOLFSSL_SHA256_BY_SPEC +#endif + + #if !defined(NO_SHA256) && !defined(WOLFSSL_ARMASM) #if defined(HAVE_FIPS) && \ @@ -582,10 +600,14 @@ static int InitSha256(wc_Sha256* sha256) 0x90BEFFFAL, 0xA4506CEBL, 0xBEF9A3F7L, 0xC67178F2L }; +/* Both versions of Ch and Maj are logically the same, but with the second set + the compilers can recognize them better for optimization */ #ifdef WOLFSSL_SHA256_BY_SPEC + /* SHA256 math based on specification */ #define Ch(x,y,z) ((z) ^ ((x) & ((y) ^ (z)))) #define Maj(x,y,z) ((((x) | (y)) & (z)) | ((x) & (y))) #else + /* SHA256 math reworked for easier compiler optimization */ #define Ch(x,y,z) ((((y) ^ (z)) & (x)) ^ (z)) #define Maj(x,y,z) ((((x) ^ (y)) & ((y) ^ (z))) ^ (y)) #endif @@ -679,6 +701,7 @@ static int InitSha256(wc_Sha256* sha256) return 0; } #else + /* SHA256 version that keeps all data in registers */ #define SCHED1(j) (W[j] = sha256->buffer[j]) #define SCHED(j) ( \ W[ j & 15] += \ @@ -707,7 +730,7 @@ static int InitSha256(wc_Sha256* sha256) { word32 S[8], t0, t1; int i; - word32 W[16]; + word32 W[WC_SHA256_BLOCK_SIZE/sizeof(word32)]; /* Copy digest to working vars */ S[0] = sha256->digest[0]; @@ -744,7 +767,7 @@ static int InitSha256(wc_Sha256* sha256) return 0; } -#endif +#endif /* SHA256_MANY_REGISTERS */ #endif /* End wc_ software implementation */