diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index b53f8706..de52333c 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -47,10 +47,12 @@ jobs: - { BUILDNAME: 'STOCK', BUILDOPTIONS: '', BUILDSCRIPT: '.ci/run.sh' } - { BUILDNAME: 'STOCK-MPI', BUILDOPTIONS: '-ULTM_DESC -UTFM_DESC -UUSE_LTM -UUSE_TFM', BUILDSCRIPT: '.ci/run.sh' } - { BUILDNAME: 'EASY', BUILDOPTIONS: '-DLTC_EASY', BUILDSCRIPT: '.ci/run.sh' } - - { BUILDNAME: 'SMALL', BUILDOPTIONS: '-DLTC_SMALL_CODE', BUILDSCRIPT: '.ci/run.sh' } + - { BUILDNAME: 'SMALL_CODE', BUILDOPTIONS: '-DLTC_SMALL_CODE', BUILDSCRIPT: '.ci/run.sh' } + - { BUILDNAME: 'SMALL_STACK', BUILDOPTIONS: '-DLTC_SMALL_STACK', BUILDSCRIPT: '.ci/run.sh' } + - { BUILDNAME: 'SMALL', BUILDOPTIONS: '-DLTC_SMALL_CODE -DLTC_SMALL_STACK', BUILDSCRIPT: '.ci/run.sh' } - { BUILDNAME: 'NO_TABLES', BUILDOPTIONS: '-DLTC_NO_TABLES', BUILDSCRIPT: '.ci/run.sh' } - { BUILDNAME: 'NO_FAST', BUILDOPTIONS: '-DLTC_NO_FAST', BUILDSCRIPT: '.ci/run.sh' } - - { BUILDNAME: 'NO_FAST+SMALL+NO_TABLES', BUILDOPTIONS: '-DLTC_NO_FAST -DLTC_SMALL_CODE -DLTC_NO_TABLES', BUILDSCRIPT: '.ci/run.sh' } + - { BUILDNAME: 'NO_FAST+SMALL+NO_TABLES', BUILDOPTIONS: '-DLTC_NO_FAST -DLTC_SMALL_CODE -DLTC_SMALL_STACK -DLTC_NO_TABLES', BUILDSCRIPT: '.ci/run.sh' } - { BUILDNAME: 'NO_ASM', BUILDOPTIONS: '-DLTC_NO_ASM', BUILDSCRIPT: '.ci/run.sh' } - { BUILDNAME: 'NO_DEPRECATED_APIS', BUILDOPTIONS: '-DLTC_NO_DEPRECATED_APIS', BUILDSCRIPT: '.ci/run.sh' } - { BUILDNAME: 'NO_TIMING_RESISTANCE', BUILDOPTIONS: '-DLTC_NO_ECC_TIMING_RESISTANT -DLTC_NO_RSA_BLINDING', BUILDSCRIPT: '.ci/run.sh' } diff --git a/src/hashes/sha1.c b/src/hashes/sha1.c index 52b35a2b..38920965 100644 --- a/src/hashes/sha1.c +++ b/src/hashes/sha1.c @@ -4,12 +4,20 @@ /** @file sha1.c - LTC_SHA1 code by Tom St Denis + SHA1 code by Tom St Denis */ #ifdef LTC_SHA1 +/* While implementing the SMALL STACK option in https://github.com/libtom/libtomcrypt/pull/709 + * we came to the conclusion that SHA1 profits from the SMALL STACK option when the SMALL CODE + * option is enabled, so let's do that. + */ +#if defined(LTC_SMALL_STACK) || defined(LTC_SMALL_CODE) +#define LTC_SMALL_STACK_SHA1 +#endif + const struct ltc_hash_descriptor sha1_desc = { "sha1", @@ -39,7 +47,12 @@ static int ss_sha1_compress(hash_state *md, const unsigned char *buf) static int s_sha1_compress(hash_state *md, const unsigned char *buf) #endif { - ulong32 a,b,c,d,e,W[16],i; + ulong32 a,b,c,d,e,i; +#ifdef LTC_SMALL_STACK_SHA1 + ulong32 W[16]; +#else + ulong32 W[80]; +#endif #ifdef LTC_SMALL_CODE ulong32 t; #endif @@ -48,7 +61,6 @@ static int s_sha1_compress(hash_state *md, const unsigned char *buf) for (i = 0; i < 16; i++) { LOAD32H(W[i], buf + (4*i)); } - #define Wi(i) W[(i) % 16] = ROL(W[((i) - 3) % 16] ^ W[((i) - 8) % 16] ^ W[((i) - 14) % 16] ^ W[((i) - 16) % 16], 1); /* copy state */ a = md->sha1.state[0]; @@ -57,12 +69,24 @@ static int s_sha1_compress(hash_state *md, const unsigned char *buf) d = md->sha1.state[3]; e = md->sha1.state[4]; +#ifdef LTC_SMALL_STACK_SHA1 + #define Wi(i) do { W[(i) % 16] = ROL(W[((i) - 3) % 16] ^ W[((i) - 8) % 16] ^ W[((i) - 14) % 16] ^ W[((i) - 16) % 16], 1); } while(0) + #define Windex(i) ((i) % 16) +#else + #define Wi(i) do { } while(0) + #define Windex(i) (i) + /* expand it */ + for (i = 16; i < 80; i++) { + W[i] = ROL(W[i-3] ^ W[i-8] ^ W[i-14] ^ W[i-16], 1); + } +#endif + /* compress */ /* round one */ - #define FF0(a,b,c,d,e,i) e = (ROLc(a, 5) + F0(b,c,d) + e + W[(i) % 16] + 0x5a827999UL); b = ROLc(b, 30); - #define FF1(a,b,c,d,e,i) e = (ROLc(a, 5) + F1(b,c,d) + e + W[(i) % 16] + 0x6ed9eba1UL); b = ROLc(b, 30); - #define FF2(a,b,c,d,e,i) e = (ROLc(a, 5) + F2(b,c,d) + e + W[(i) % 16] + 0x8f1bbcdcUL); b = ROLc(b, 30); - #define FF3(a,b,c,d,e,i) e = (ROLc(a, 5) + F3(b,c,d) + e + W[(i) % 16] + 0xca62c1d6UL); b = ROLc(b, 30); + #define FF0(a,b,c,d,e,i) e = (ROLc(a, 5) + F0(b,c,d) + e + W[Windex(i)] + 0x5a827999UL); b = ROLc(b, 30); + #define FF1(a,b,c,d,e,i) e = (ROLc(a, 5) + F1(b,c,d) + e + W[Windex(i)] + 0x6ed9eba1UL); b = ROLc(b, 30); + #define FF2(a,b,c,d,e,i) e = (ROLc(a, 5) + F2(b,c,d) + e + W[Windex(i)] + 0x8f1bbcdcUL); b = ROLc(b, 30); + #define FF3(a,b,c,d,e,i) e = (ROLc(a, 5) + F3(b,c,d) + e + W[Windex(i)] + 0xca62c1d6UL); b = ROLc(b, 30); #ifdef LTC_SMALL_CODE @@ -133,6 +157,7 @@ static int s_sha1_compress(hash_state *md, const unsigned char *buf) #undef FF2 #undef FF3 #undef Wi + #undef Windex /* store */ md->sha1.state[0] = md->sha1.state[0] + a; diff --git a/src/hashes/sha2/sha256.c b/src/hashes/sha2/sha256.c index f8f0825b..ffd8d6f8 100644 --- a/src/hashes/sha2/sha256.c +++ b/src/hashes/sha2/sha256.c @@ -4,7 +4,7 @@ /** @file sha256.c - LTC_SHA256 by Tom St Denis + SHA256 by Tom St Denis */ #ifdef LTC_SHA256 @@ -27,6 +27,15 @@ const struct ltc_hash_descriptor sha256_desc = NULL }; +/* While implementing the SMALL STACK option in https://github.com/libtom/libtomcrypt/pull/709 + * we came to the conclusion that SHA256 profits from the SMALL STACK option when the SMALL CODE + * option is disabled. + * So enable it either when it's enabled explicitly, or when SMALL CODE is disabled. + */ +#if !defined(LTC_SMALL_CODE) || defined(LTC_SMALL_STACK) +#define LTC_SMALL_STACK_SHA256 +#endif + #ifdef LTC_SMALL_CODE /* the K array */ static const ulong32 K[64] = { @@ -63,7 +72,12 @@ static int ss_sha256_compress(hash_state * md, const unsigned char *buf) static int s_sha256_compress(hash_state * md, const unsigned char *buf) #endif { - ulong32 S[8], W[16], t0, t1; + ulong32 S[8], t0, t1; +#ifdef LTC_SMALL_STACK_SHA256 + ulong32 W[16]; +#else + ulong32 W[64]; +#endif #ifdef LTC_SMALL_CODE ulong32 t; #endif @@ -78,16 +92,29 @@ static int s_sha256_compress(hash_state * md, const unsigned char *buf) for (i = 0; i < 16; i++) { LOAD32H(W[i], buf + (4*i)); } + +#ifdef LTC_SMALL_STACK_SHA256 #define Wi(i) W[(i) % 16] = Gamma1(W[((i) - 2) % 16]) + W[((i) - 7) % 16] + Gamma0(W[((i) - 15) % 16]) + W[((i) - 16) % 16] + #define Windex(i) ((i) % 16) +#else + #define Wi(i) do { } while(0) + #define Windex(i) (i) + + /* fill W[16..63] */ + for (i = 16; i < 64; i++) { + W[i] = Gamma1(W[i - 2]) + W[i - 7] + Gamma0(W[i - 15]) + W[i - 16]; + } +#endif /* Compress */ #ifdef LTC_SMALL_CODE -#define RND(a,b,c,d,e,f,g,h,i) \ - t0 = h + Sigma1(e) + Ch(e, f, g) + K[i] + W[(i) % 16]; \ - t1 = Sigma0(a) + Maj(a, b, c); \ - d += t0; \ +#define RND(a,b,c,d,e,f,g,h,i) \ + t0 = h + Sigma1(e) + Ch(e, f, g) + K[i] + W[Windex(i)]; \ + t1 = Sigma0(a) + Maj(a, b, c); \ + d += t0; \ h = t0 + t1; +#ifdef LTC_SMALL_STACK_SHA256 for (i = 0; i < 16; ++i) { RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],i); t = S[7]; S[7] = S[6]; S[6] = S[5]; S[5] = S[4]; @@ -100,10 +127,17 @@ static int s_sha256_compress(hash_state * md, const unsigned char *buf) S[4] = S[3]; S[3] = S[2]; S[2] = S[1]; S[1] = S[0]; S[0] = t; } #else -#define RND(a,b,c,d,e,f,g,h,i,ki) \ - t0 = h + Sigma1(e) + Ch(e, f, g) + ki + W[(i) % 16]; \ - t1 = Sigma0(a) + Maj(a, b, c); \ - d += t0; \ + for (i = 0; i < 64; ++i) { + RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],i); + t = S[7]; S[7] = S[6]; S[6] = S[5]; S[5] = S[4]; + S[4] = S[3]; S[3] = S[2]; S[2] = S[1]; S[1] = S[0]; S[0] = t; + } +#endif /* LTC_SMALL_STACK_SHA256 */ +#else +#define RND(a,b,c,d,e,f,g,h,i,ki) \ + t0 = h + Sigma1(e) + Ch(e, f, g) + ki + W[Windex(i)]; \ + t1 = Sigma0(a) + Maj(a, b, c); \ + d += t0; \ h = t0 + t1; RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],0,0x428a2f98); @@ -173,6 +207,7 @@ static int s_sha256_compress(hash_state * md, const unsigned char *buf) #endif #undef RND #undef Wi +#undef Windex /* feedback */ for (i = 0; i < 8; i++) { diff --git a/src/hashes/sha2/sha512.c b/src/hashes/sha2/sha512.c index 326ee90b..d4a16a36 100644 --- a/src/hashes/sha2/sha512.c +++ b/src/hashes/sha2/sha512.c @@ -4,7 +4,7 @@ /** @param sha512.c - LTC_SHA512 by Tom St Denis + SHA512 by Tom St Denis */ #ifdef LTC_SHA512 @@ -88,7 +88,12 @@ static int ss_sha512_compress(hash_state * md, const unsigned char *buf) static int s_sha512_compress(hash_state * md, const unsigned char *buf) #endif { - ulong64 S[8], W[16], t0, t1; + ulong64 S[8], t0, t1; +#ifdef LTC_SMALL_STACK + ulong64 W[16]; +#else + ulong64 W[80]; +#endif int i; /* copy state into S */ @@ -100,12 +105,24 @@ static int s_sha512_compress(hash_state * md, const unsigned char *buf) for (i = 0; i < 16; i++) { LOAD64H(W[i], buf + (8*i)); } + +#ifdef LTC_SMALL_STACK #define Wi(i) W[(i) % 16] = Gamma1(W[((i) - 2) % 16]) + W[((i) - 7) % 16] + Gamma0(W[((i) - 15) % 16]) + W[((i) - 16) % 16]; + #define Windex(i) ((i) % 16) +#else + #define Wi(i) do { } while(0) + #define Windex(i) (i) + + /* fill W[16..79] */ + for (i = 16; i < 80; i++) { + W[i] = Gamma1(W[i - 2]) + W[i - 7] + Gamma0(W[i - 15]) + W[i - 16]; + } +#endif /* Compress */ #ifdef LTC_SMALL_CODE for (i = 0; i < 16; i++) { - t0 = S[7] + Sigma1(S[4]) + Ch(S[4], S[5], S[6]) + K[i] + W[i % 16]; + t0 = S[7] + Sigma1(S[4]) + Ch(S[4], S[5], S[6]) + K[i] + W[Windex(i)]; t1 = Sigma0(S[0]) + Maj(S[0], S[1], S[2]); S[7] = S[6]; S[6] = S[5]; @@ -118,7 +135,7 @@ static int s_sha512_compress(hash_state * md, const unsigned char *buf) } for (; i < 80; i++) { Wi(i); - t0 = S[7] + Sigma1(S[4]) + Ch(S[4], S[5], S[6]) + K[i] + W[i % 16]; + t0 = S[7] + Sigma1(S[4]) + Ch(S[4], S[5], S[6]) + K[i] + W[Windex(i)]; t1 = Sigma0(S[0]) + Maj(S[0], S[1], S[2]); S[7] = S[6]; S[6] = S[5]; @@ -130,10 +147,10 @@ static int s_sha512_compress(hash_state * md, const unsigned char *buf) S[0] = t0 + t1; } #else -#define RND(a,b,c,d,e,f,g,h,i) \ - t0 = h + Sigma1(e) + Ch(e, f, g) + K[i] + W[(i) % 16]; \ - t1 = Sigma0(a) + Maj(a, b, c); \ - d += t0; \ +#define RND(a,b,c,d,e,f,g,h,i) \ + t0 = h + Sigma1(e) + Ch(e, f, g) + K[i] + W[Windex(i)]; \ + t1 = Sigma0(a) + Maj(a, b, c); \ + d += t0; \ h = t0 + t1; for (i = 0; i < 16; i += 8) { @@ -156,8 +173,10 @@ static int s_sha512_compress(hash_state * md, const unsigned char *buf) Wi(i+6); RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],i+6); Wi(i+7); RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],i+7); } +#undef RND #endif #undef Wi +#undef Windex /* feedback */ diff --git a/src/misc/crypt/crypt.c b/src/misc/crypt/crypt.c index 90120bff..42fe2e30 100644 --- a/src/misc/crypt/crypt.c +++ b/src/misc/crypt/crypt.c @@ -528,6 +528,9 @@ const char *crypt_build_settings = #if defined(LTC_SMALL_CODE) " LTC_SMALL_CODE " #endif +#if defined(LTC_SMALL_STACK) + " LTC_SMALL_STACK " +#endif #if defined(LTC_NO_FILE) " LTC_NO_FILE " #endif