diff --git a/makefile.mingw b/makefile.mingw index df39d6fbc..ab1874c40 100644 --- a/makefile.mingw +++ b/makefile.mingw @@ -244,12 +244,12 @@ src/stream/sosemanuk/sosemanuk_memory.o src/stream/sosemanuk/sosemanuk_test.o TOBJECTS=tests/argon2_test.o tests/base16_test.o tests/base32_test.o tests/base64_test.o \ tests/bcrypt_test.o tests/cipher_hash_test.o tests/common.o tests/deprecated_test.o tests/der_test.o \ tests/dh_test.o tests/dsa_test.o tests/ecc_test.o tests/ed25519_test.o tests/ed448_test.o \ -tests/file_test.o tests/mac_test.o tests/misc_test.o tests/modes_test.o tests/mpi_test.o \ -tests/multi_test.o tests/no_null_termination_check_test.o tests/no_prng.o tests/padding_test.o \ -tests/pem_test.o tests/pk_oid_test.o tests/pkcs_1_eme_test.o tests/pkcs_1_emsa_test.o \ -tests/pkcs_1_oaep_test.o tests/pkcs_1_pss_test.o tests/pkcs_1_test.o tests/prng_test.o \ -tests/rotate_test.o tests/rsa_test.o tests/scrypt_test.o tests/siv_wycheproof_test.o tests/ssh_test.o \ -tests/store_test.o tests/test.o tests/x25519_test.o tests/x448_test.o +tests/file_test.o tests/hash_state_test.o tests/mac_test.o tests/misc_test.o tests/modes_test.o \ +tests/mpi_test.o tests/multi_test.o tests/no_null_termination_check_test.o tests/no_prng.o \ +tests/padding_test.o tests/pem_test.o tests/pk_oid_test.o tests/pkcs_1_eme_test.o \ +tests/pkcs_1_emsa_test.o tests/pkcs_1_oaep_test.o tests/pkcs_1_pss_test.o tests/pkcs_1_test.o \ +tests/prng_test.o tests/rotate_test.o tests/rsa_test.o tests/scrypt_test.o tests/siv_wycheproof_test.o \ +tests/ssh_test.o tests/store_test.o tests/test.o tests/x25519_test.o tests/x448_test.o #The following headers will be installed by "make install" HEADERS_PUB=src/headers/tomcrypt.h src/headers/tomcrypt_argchk.h src/headers/tomcrypt_cfg.h \ diff --git a/makefile.msvc b/makefile.msvc index e9028e8ab..7d4f8dae5 100644 --- a/makefile.msvc +++ b/makefile.msvc @@ -237,12 +237,12 @@ src/stream/sosemanuk/sosemanuk_memory.obj src/stream/sosemanuk/sosemanuk_test.ob TOBJECTS=tests/argon2_test.obj tests/base16_test.obj tests/base32_test.obj tests/base64_test.obj \ tests/bcrypt_test.obj tests/cipher_hash_test.obj tests/common.obj tests/deprecated_test.obj tests/der_test.obj \ tests/dh_test.obj tests/dsa_test.obj tests/ecc_test.obj tests/ed25519_test.obj tests/ed448_test.obj \ -tests/file_test.obj tests/mac_test.obj tests/misc_test.obj tests/modes_test.obj tests/mpi_test.obj \ -tests/multi_test.obj tests/no_null_termination_check_test.obj tests/no_prng.obj tests/padding_test.obj \ -tests/pem_test.obj tests/pk_oid_test.obj tests/pkcs_1_eme_test.obj tests/pkcs_1_emsa_test.obj \ -tests/pkcs_1_oaep_test.obj tests/pkcs_1_pss_test.obj tests/pkcs_1_test.obj tests/prng_test.obj \ -tests/rotate_test.obj tests/rsa_test.obj tests/scrypt_test.obj tests/siv_wycheproof_test.obj tests/ssh_test.obj \ -tests/store_test.obj tests/test.obj tests/x25519_test.obj tests/x448_test.obj +tests/file_test.obj tests/hash_state_test.obj tests/mac_test.obj tests/misc_test.obj tests/modes_test.obj \ +tests/mpi_test.obj tests/multi_test.obj tests/no_null_termination_check_test.obj tests/no_prng.obj \ +tests/padding_test.obj tests/pem_test.obj tests/pk_oid_test.obj tests/pkcs_1_eme_test.obj \ +tests/pkcs_1_emsa_test.obj tests/pkcs_1_oaep_test.obj tests/pkcs_1_pss_test.obj tests/pkcs_1_test.obj \ +tests/prng_test.obj tests/rotate_test.obj tests/rsa_test.obj tests/scrypt_test.obj tests/siv_wycheproof_test.obj \ +tests/ssh_test.obj tests/store_test.obj tests/test.obj tests/x25519_test.obj tests/x448_test.obj #The following headers will be installed by "make install" HEADERS_PUB=src/headers/tomcrypt.h src/headers/tomcrypt_argchk.h src/headers/tomcrypt_cfg.h \ diff --git a/makefile.unix b/makefile.unix index b07b43b8c..2d8db2d98 100644 --- a/makefile.unix +++ b/makefile.unix @@ -258,12 +258,12 @@ src/stream/sosemanuk/sosemanuk_memory.o src/stream/sosemanuk/sosemanuk_test.o TOBJECTS=tests/argon2_test.o tests/base16_test.o tests/base32_test.o tests/base64_test.o \ tests/bcrypt_test.o tests/cipher_hash_test.o tests/common.o tests/deprecated_test.o tests/der_test.o \ tests/dh_test.o tests/dsa_test.o tests/ecc_test.o tests/ed25519_test.o tests/ed448_test.o \ -tests/file_test.o tests/mac_test.o tests/misc_test.o tests/modes_test.o tests/mpi_test.o \ -tests/multi_test.o tests/no_null_termination_check_test.o tests/no_prng.o tests/padding_test.o \ -tests/pem_test.o tests/pk_oid_test.o tests/pkcs_1_eme_test.o tests/pkcs_1_emsa_test.o \ -tests/pkcs_1_oaep_test.o tests/pkcs_1_pss_test.o tests/pkcs_1_test.o tests/prng_test.o \ -tests/rotate_test.o tests/rsa_test.o tests/scrypt_test.o tests/siv_wycheproof_test.o tests/ssh_test.o \ -tests/store_test.o tests/test.o tests/x25519_test.o tests/x448_test.o +tests/file_test.o tests/hash_state_test.o tests/mac_test.o tests/misc_test.o tests/modes_test.o \ +tests/mpi_test.o tests/multi_test.o tests/no_null_termination_check_test.o tests/no_prng.o \ +tests/padding_test.o tests/pem_test.o tests/pk_oid_test.o tests/pkcs_1_eme_test.o \ +tests/pkcs_1_emsa_test.o tests/pkcs_1_oaep_test.o tests/pkcs_1_pss_test.o tests/pkcs_1_test.o \ +tests/prng_test.o tests/rotate_test.o tests/rsa_test.o tests/scrypt_test.o tests/siv_wycheproof_test.o \ +tests/ssh_test.o tests/store_test.o tests/test.o tests/x25519_test.o tests/x448_test.o #The following headers will be installed by "make install" HEADERS_PUB=src/headers/tomcrypt.h src/headers/tomcrypt_argchk.h src/headers/tomcrypt_cfg.h \ diff --git a/makefile_include.mk b/makefile_include.mk index 0577b5bda..b37973155 100644 --- a/makefile_include.mk +++ b/makefile_include.mk @@ -434,12 +434,12 @@ endif TOBJECTS=tests/argon2_test.o tests/base16_test.o tests/base32_test.o tests/base64_test.o \ tests/bcrypt_test.o tests/cipher_hash_test.o tests/common.o tests/deprecated_test.o tests/der_test.o \ tests/dh_test.o tests/dsa_test.o tests/ecc_test.o tests/ed25519_test.o tests/ed448_test.o \ -tests/file_test.o tests/mac_test.o tests/misc_test.o tests/modes_test.o tests/mpi_test.o \ -tests/multi_test.o tests/no_null_termination_check_test.o tests/no_prng.o tests/padding_test.o \ -tests/pem_test.o tests/pk_oid_test.o tests/pkcs_1_eme_test.o tests/pkcs_1_emsa_test.o \ -tests/pkcs_1_oaep_test.o tests/pkcs_1_pss_test.o tests/pkcs_1_test.o tests/prng_test.o \ -tests/rotate_test.o tests/rsa_test.o tests/scrypt_test.o tests/siv_wycheproof_test.o tests/ssh_test.o \ -tests/store_test.o tests/test.o tests/x25519_test.o tests/x448_test.o +tests/file_test.o tests/hash_state_test.o tests/mac_test.o tests/misc_test.o tests/modes_test.o \ +tests/mpi_test.o tests/multi_test.o tests/no_null_termination_check_test.o tests/no_prng.o \ +tests/padding_test.o tests/pem_test.o tests/pk_oid_test.o tests/pkcs_1_eme_test.o \ +tests/pkcs_1_emsa_test.o tests/pkcs_1_oaep_test.o tests/pkcs_1_pss_test.o tests/pkcs_1_test.o \ +tests/prng_test.o tests/rotate_test.o tests/rsa_test.o tests/scrypt_test.o tests/siv_wycheproof_test.o \ +tests/ssh_test.o tests/store_test.o tests/test.o tests/x25519_test.o tests/x448_test.o # The following headers will be installed by "make install" HEADERS_PUB=src/headers/tomcrypt.h src/headers/tomcrypt_argchk.h src/headers/tomcrypt_cfg.h \ diff --git a/src/hashes/sha1.c b/src/hashes/sha1.c index 72ef692d1..494be9bf5 100644 --- a/src/hashes/sha1.c +++ b/src/hashes/sha1.c @@ -47,6 +47,8 @@ static int ss_sha1_c_compress(hash_state *md, const unsigned char *buf) static int s_sha1_c_compress(hash_state *md, const unsigned char *buf) #endif { + ulong32* state; + int align; ulong32 a,b,c,d,e,i; #ifdef LTC_SMALL_STACK_SHA1 ulong32 W[16]; @@ -57,17 +59,24 @@ static int s_sha1_c_compress(hash_state *md, const unsigned char *buf) ulong32 t; #endif + state = LTC_ALIGN_BUF(md->sha1.state_buf, 16); + align = (int)((char*)state - (char*)md->sha1.state_buf); + if (align != md->sha1.align) { + XMEMMOVE(state, &md->sha1.state_buf[align], 5 * sizeof(ulong32)); + md->sha1.align = align; + } + /* copy the state into 512-bits into W[0..15] */ for (i = 0; i < 16; i++) { LOAD32H(W[i], buf + (4*i)); } /* copy state */ - a = md->sha1.state[0]; - b = md->sha1.state[1]; - c = md->sha1.state[2]; - d = md->sha1.state[3]; - e = md->sha1.state[4]; + a = state[0]; + b = state[1]; + c = state[2]; + d = state[3]; + e = 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) @@ -160,11 +169,11 @@ static int s_sha1_c_compress(hash_state *md, const unsigned char *buf) #undef Windex /* store */ - md->sha1.state[0] = md->sha1.state[0] + a; - md->sha1.state[1] = md->sha1.state[1] + b; - md->sha1.state[2] = md->sha1.state[2] + c; - md->sha1.state[3] = md->sha1.state[3] + d; - md->sha1.state[4] = md->sha1.state[4] + e; + state[0] = state[0] + a; + state[1] = state[1] + b; + state[2] = state[2] + c; + state[3] = state[3] + d; + state[4] = state[4] + e; return CRYPT_OK; } @@ -186,15 +195,18 @@ static int s_sha1_c_compress(hash_state *md, const unsigned char *buf) */ int sha1_c_init(hash_state * md) { + ulong32* state; + LTC_ARGCHK(md != NULL); - md->sha1.state = LTC_ALIGN_BUF(md->sha1.state_buf, 16); + state = LTC_ALIGN_BUF(md->sha1.state_buf, 16); + md->sha1.align = (int)((char*)state - (char*)md->sha1.state_buf); - md->sha1.state[0] = 0x67452301UL; - md->sha1.state[1] = 0xefcdab89UL; - md->sha1.state[2] = 0x98badcfeUL; - md->sha1.state[3] = 0x10325476UL; - md->sha1.state[4] = 0xc3d2e1f0UL; + state[0] = 0x67452301UL; + state[1] = 0xefcdab89UL; + state[2] = 0x98badcfeUL; + state[3] = 0x10325476UL; + state[4] = 0xc3d2e1f0UL; md->sha1.curlen = 0; md->sha1.length = 0; return CRYPT_OK; @@ -217,6 +229,8 @@ HASH_PROCESS(sha1_c_process, s_sha1_c_compress, sha1, 64) */ int sha1_c_done(hash_state * md, unsigned char *out) { + ulong32* state; + int align; int i; LTC_ARGCHK(md != NULL); @@ -226,6 +240,13 @@ int sha1_c_done(hash_state * md, unsigned char *out) return CRYPT_INVALID_ARG; } + state = LTC_ALIGN_BUF(md->sha1.state_buf, 16); + align = (int)((char*)state - (char*)md->sha1.state_buf); + if (align != md->sha1.align) { + XMEMMOVE(state, &md->sha1.state_buf[align], 5 * sizeof(ulong32)); + md->sha1.align = align; + } + /* increase the length of the message */ md->sha1.length += md->sha1.curlen * 8; @@ -255,7 +276,7 @@ int sha1_c_done(hash_state * md, unsigned char *out) /* copy output */ for (i = 0; i < 5; i++) { - STORE32H(md->sha1.state[i], out+(4*i)); + STORE32H(state[i], out+(4*i)); } #ifdef LTC_CLEAN_STACK zeromem(md, sizeof(hash_state)); diff --git a/src/hashes/sha1_x86.c b/src/hashes/sha1_x86.c index c1c5408be..3d9d10bcc 100644 --- a/src/hashes/sha1_x86.c +++ b/src/hashes/sha1_x86.c @@ -53,6 +53,8 @@ static int LTC_SHA_TARGET s_sha1_x86_compress(hash_state *md, const unsigned cha { #define k_reverse_32 ((0x0 << (3 * 2)) | (0x1 << (2 * 2)) | (0x2 << (1 * 2)) | (0x3 << (0 * 2))) + ulong32* state; + int align; __m128i reverse_8; __m128i abcdx; __m128i e; @@ -64,10 +66,17 @@ static int LTC_SHA_TARGET s_sha1_x86_compress(hash_state *md, const unsigned cha __m128i msg_2; __m128i msg_3; + state = LTC_ALIGN_BUF(md->sha1.state_buf, 16); + align = (int)((char*)state - (char*)md->sha1.state_buf); + if (align != md->sha1.align) { + XMEMMOVE(state, &md->sha1.state_buf[align], 5 * sizeof(ulong32)); + md->sha1.align = align; + } + reverse_8 = _mm_set_epi64x(0x0001020304050607ull, 0x08090a0b0c0d0e0full); - abcdx = _mm_load_si128(((__m128i const*)(&md->sha1.state[0]))); + abcdx = _mm_load_si128(((__m128i const*)(&state[0]))); abcdx = _mm_shuffle_epi32(abcdx, k_reverse_32); - e = _mm_set_epi32(*((int const*)(&md->sha1.state[4])), 0, 0, 0); + e = _mm_set_epi32(*((int const*)(&state[4])), 0, 0, 0); old_abcd = abcdx; old_e = e; @@ -173,8 +182,8 @@ static int LTC_SHA_TARGET s_sha1_x86_compress(hash_state *md, const unsigned cha e = _mm_add_epi32(e, old_e); abcdx = _mm_shuffle_epi32(abcdx, k_reverse_32); - _mm_store_si128(((__m128i*)(&md->sha1.state[0])), abcdx); - *((int*)(&md->sha1.state[4])) = _mm_extract_epi32(e, 3); + _mm_store_si128(((__m128i*)(&state[0])), abcdx); + *((int*)(&state[4])) = _mm_extract_epi32(e, 3); return CRYPT_OK; @@ -198,15 +207,18 @@ static int s_sha1_x86_compress(hash_state *md, const unsigned char *buf) */ int sha1_x86_init(hash_state * md) { + ulong32* state; + LTC_ARGCHK(md != NULL); - md->sha1.state = LTC_ALIGN_BUF(md->sha1.state_buf, 16); + state = LTC_ALIGN_BUF(md->sha1.state_buf, 16); + md->sha1.align = (int)((char*)state - (char*)md->sha1.state_buf); - md->sha1.state[0] = 0x67452301UL; - md->sha1.state[1] = 0xefcdab89UL; - md->sha1.state[2] = 0x98badcfeUL; - md->sha1.state[3] = 0x10325476UL; - md->sha1.state[4] = 0xc3d2e1f0UL; + state[0] = 0x67452301UL; + state[1] = 0xefcdab89UL; + state[2] = 0x98badcfeUL; + state[3] = 0x10325476UL; + state[4] = 0xc3d2e1f0UL; md->sha1.curlen = 0; md->sha1.length = 0; return CRYPT_OK; @@ -229,6 +241,8 @@ HASH_PROCESS(sha1_x86_process, s_sha1_x86_compress, sha1, 64) */ int sha1_x86_done(hash_state * md, unsigned char *out) { + ulong32* state; + int align; int i; LTC_ARGCHK(md != NULL); @@ -238,6 +252,13 @@ int sha1_x86_done(hash_state * md, unsigned char *out) return CRYPT_INVALID_ARG; } + state = LTC_ALIGN_BUF(md->sha1.state_buf, 16); + align = (int)((char*)state - (char*)md->sha1.state_buf); + if (align != md->sha1.align) { + XMEMMOVE(state, &md->sha1.state_buf[align], 5 * sizeof(ulong32)); + md->sha1.align = align; + } + /* increase the length of the message */ md->sha1.length += md->sha1.curlen * 8; @@ -267,7 +288,7 @@ int sha1_x86_done(hash_state * md, unsigned char *out) /* copy output */ for (i = 0; i < 5; i++) { - STORE32H(md->sha1.state[i], out+(4*i)); + STORE32H(state[i], out+(4*i)); } #ifdef LTC_CLEAN_STACK zeromem(md, sizeof(hash_state)); diff --git a/src/hashes/sha2/sha224.c b/src/hashes/sha2/sha224.c index 15fc36767..c78a0d0a6 100644 --- a/src/hashes/sha2/sha224.c +++ b/src/hashes/sha2/sha224.c @@ -35,20 +35,23 @@ const struct ltc_hash_descriptor sha224_portable_desc = */ int sha224_c_init(hash_state * md) { + ulong32* state; + LTC_ARGCHK(md != NULL); - md->sha256.state = LTC_ALIGN_BUF(md->sha256.state_buf, 16); + state = LTC_ALIGN_BUF(md->sha256.state_buf, 16); + md->sha256.align = (int)((char*)state - (char*)md->sha256.state_buf); md->sha256.curlen = 0; md->sha256.length = 0; - md->sha256.state[0] = 0xc1059ed8UL; - md->sha256.state[1] = 0x367cd507UL; - md->sha256.state[2] = 0x3070dd17UL; - md->sha256.state[3] = 0xf70e5939UL; - md->sha256.state[4] = 0xffc00b31UL; - md->sha256.state[5] = 0x68581511UL; - md->sha256.state[6] = 0x64f98fa7UL; - md->sha256.state[7] = 0xbefa4fa4UL; + state[0] = 0xc1059ed8UL; + state[1] = 0x367cd507UL; + state[2] = 0x3070dd17UL; + state[3] = 0xf70e5939UL; + state[4] = 0xffc00b31UL; + state[5] = 0x68581511UL; + state[6] = 0x64f98fa7UL; + state[7] = 0xbefa4fa4UL; return CRYPT_OK; } diff --git a/src/hashes/sha2/sha224_x86.c b/src/hashes/sha2/sha224_x86.c index f562b34a0..7c2dc52e5 100644 --- a/src/hashes/sha2/sha224_x86.c +++ b/src/hashes/sha2/sha224_x86.c @@ -35,20 +35,23 @@ const struct ltc_hash_descriptor sha224_x86_desc = */ int sha224_x86_init(hash_state * md) { + ulong32* state; + LTC_ARGCHK(md != NULL); - md->sha256.state = LTC_ALIGN_BUF(md->sha256.state_buf, 16); + state = LTC_ALIGN_BUF(md->sha256.state_buf, 16); + md->sha256.align = (int)((char*)state - (char*)md->sha256.state_buf); md->sha256.curlen = 0; md->sha256.length = 0; - md->sha256.state[0] = 0xc1059ed8UL; - md->sha256.state[1] = 0x367cd507UL; - md->sha256.state[2] = 0x3070dd17UL; - md->sha256.state[3] = 0xf70e5939UL; - md->sha256.state[4] = 0xffc00b31UL; - md->sha256.state[5] = 0x68581511UL; - md->sha256.state[6] = 0x64f98fa7UL; - md->sha256.state[7] = 0xbefa4fa4UL; + state[0] = 0xc1059ed8UL; + state[1] = 0x367cd507UL; + state[2] = 0x3070dd17UL; + state[3] = 0xf70e5939UL; + state[4] = 0xffc00b31UL; + state[5] = 0x68581511UL; + state[6] = 0x64f98fa7UL; + state[7] = 0xbefa4fa4UL; return CRYPT_OK; } diff --git a/src/hashes/sha2/sha256.c b/src/hashes/sha2/sha256.c index a37028d64..f5b3ad1d7 100644 --- a/src/hashes/sha2/sha256.c +++ b/src/hashes/sha2/sha256.c @@ -72,6 +72,8 @@ 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* state; + int align; ulong32 S[8], t0, t1; #ifdef LTC_SMALL_STACK_SHA256 ulong32 W[16]; @@ -83,9 +85,16 @@ static int s_sha256_compress(hash_state * md, const unsigned char *buf) #endif int i; + state = LTC_ALIGN_BUF(md->sha256.state_buf, 16); + align = (int)((char*)state - (char*)md->sha256.state_buf); + if (align != md->sha256.align) { + XMEMMOVE(state, &md->sha256.state_buf[align], 8 * sizeof(ulong32)); + md->sha256.align = align; + } + /* copy state into S */ for (i = 0; i < 8; i++) { - S[i] = md->sha256.state[i]; + S[i] = state[i]; } /* copy the state into 512-bits into W[0..15] */ @@ -211,7 +220,7 @@ static int s_sha256_compress(hash_state * md, const unsigned char *buf) /* feedback */ for (i = 0; i < 8; i++) { - md->sha256.state[i] = md->sha256.state[i] + S[i]; + state[i] = state[i] + S[i]; } return CRYPT_OK; } @@ -233,20 +242,23 @@ static int s_sha256_compress(hash_state * md, const unsigned char *buf) */ int sha256_c_init(hash_state * md) { + ulong32* state; + LTC_ARGCHK(md != NULL); - md->sha256.state = LTC_ALIGN_BUF(md->sha256.state_buf, 16); + state = LTC_ALIGN_BUF(md->sha256.state_buf, 16); + md->sha256.align = (int)((char*)state - (char*)md->sha256.state_buf); md->sha256.curlen = 0; md->sha256.length = 0; - md->sha256.state[0] = 0x6A09E667UL; - md->sha256.state[1] = 0xBB67AE85UL; - md->sha256.state[2] = 0x3C6EF372UL; - md->sha256.state[3] = 0xA54FF53AUL; - md->sha256.state[4] = 0x510E527FUL; - md->sha256.state[5] = 0x9B05688CUL; - md->sha256.state[6] = 0x1F83D9ABUL; - md->sha256.state[7] = 0x5BE0CD19UL; + state[0] = 0x6A09E667UL; + state[1] = 0xBB67AE85UL; + state[2] = 0x3C6EF372UL; + state[3] = 0xA54FF53AUL; + state[4] = 0x510E527FUL; + state[5] = 0x9B05688CUL; + state[6] = 0x1F83D9ABUL; + state[7] = 0x5BE0CD19UL; return CRYPT_OK; } @@ -267,6 +279,8 @@ HASH_PROCESS(sha256_c_process,s_sha256_compress, sha256, 64) */ int sha256_c_done(hash_state * md, unsigned char *out) { + ulong32* state; + int align; int i; LTC_ARGCHK(md != NULL); @@ -276,6 +290,12 @@ int sha256_c_done(hash_state * md, unsigned char *out) return CRYPT_INVALID_ARG; } + state = LTC_ALIGN_BUF(md->sha256.state_buf, 16); + align = (int)((char*)state - (char*)md->sha256.state_buf); + if (align != md->sha256.align) { + XMEMMOVE(state, &md->sha256.state_buf[align], 8 * sizeof(ulong32)); + md->sha256.align = align; + } /* increase the length of the message */ md->sha256.length += md->sha256.curlen * 8; @@ -306,7 +326,7 @@ int sha256_c_done(hash_state * md, unsigned char *out) /* copy output */ for (i = 0; i < 8; i++) { - STORE32H(md->sha256.state[i], out+(4*i)); + STORE32H(state[i], out+(4*i)); } #ifdef LTC_CLEAN_STACK zeromem(md, sizeof(hash_state)); diff --git a/src/hashes/sha2/sha256_x86.c b/src/hashes/sha2/sha256_x86.c index 43a23c913..a56cc8a54 100644 --- a/src/hashes/sha2/sha256_x86.c +++ b/src/hashes/sha2/sha256_x86.c @@ -77,6 +77,8 @@ static int LTC_SHA_TARGET s_sha256_x86_compress(hash_state * md, const unsigned #define k_alignr_epi8(a) (((a) & 0x3) * 4) #define k_any 0x0 + ulong32* state; + int align; __m128i reverse; __m128i state_0; __m128i state_1; @@ -89,9 +91,16 @@ static int LTC_SHA_TARGET s_sha256_x86_compress(hash_state * md, const unsigned __m128i msg_2; __m128i msg_3; + state = LTC_ALIGN_BUF(md->sha256.state_buf, 16); + align = (int)((char*)state - (char*)md->sha256.state_buf); + if (align != md->sha256.align) { + XMEMMOVE(state, &md->sha256.state_buf[align], 8 * sizeof(ulong32)); + md->sha256.align = align; + } + reverse = _mm_set_epi64x(0x0c0d0e0f08090a0bull, 0x0405060700010203ull); - state_0 = _mm_load_si128(((__m128i const*)(&md->sha256.state[0]))); - state_1 = _mm_load_si128(((__m128i const*)(&md->sha256.state[4]))); + state_0 = _mm_load_si128(((__m128i const*)(&state[0]))); + state_1 = _mm_load_si128(((__m128i const*)(&state[4]))); tmp = _mm_shuffle_epi32(state_0, k_shuffle_epi32(0x2, 0x3, 0x0, 0x1)); state_1 = _mm_shuffle_epi32(state_1, k_shuffle_epi32(0x0, 0x1, 0x2, 0x3)); state_0 = _mm_alignr_epi8(tmp, state_1, k_alignr_epi8(2)); @@ -242,8 +251,8 @@ static int LTC_SHA_TARGET s_sha256_x86_compress(hash_state * md, const unsigned state_1 = _mm_shuffle_epi32(state_1, k_shuffle_epi32(0x2, 0x3, 0x0, 0x1)); state_0 = ltc_mm_blend_epi32(tmp, state_1, k_blend_epi32(0x1, 0x1, 0x0, 0x0)); state_1 = _mm_alignr_epi8(state_1, tmp, k_alignr_epi8(2)); - _mm_store_si128(((__m128i*)(&md->sha256.state[0])), state_0); - _mm_store_si128(((__m128i*)(&md->sha256.state[4])), state_1); + _mm_store_si128(((__m128i*)(&state[0])), state_0); + _mm_store_si128(((__m128i*)(&state[4])), state_1); return CRYPT_OK; } #undef K @@ -265,20 +274,23 @@ static int s_sha256_compress(hash_state * md, const unsigned char *buf) */ int sha256_x86_init(hash_state * md) { + ulong32* state; + LTC_ARGCHK(md != NULL); - md->sha256.state = LTC_ALIGN_BUF(md->sha256.state_buf, 16); + state = LTC_ALIGN_BUF(md->sha256.state_buf, 16); + md->sha256.align = (int)((char*)state - (char*)md->sha256.state_buf); md->sha256.curlen = 0; md->sha256.length = 0; - md->sha256.state[0] = 0x6A09E667UL; - md->sha256.state[1] = 0xBB67AE85UL; - md->sha256.state[2] = 0x3C6EF372UL; - md->sha256.state[3] = 0xA54FF53AUL; - md->sha256.state[4] = 0x510E527FUL; - md->sha256.state[5] = 0x9B05688CUL; - md->sha256.state[6] = 0x1F83D9ABUL; - md->sha256.state[7] = 0x5BE0CD19UL; + state[0] = 0x6A09E667UL; + state[1] = 0xBB67AE85UL; + state[2] = 0x3C6EF372UL; + state[3] = 0xA54FF53AUL; + state[4] = 0x510E527FUL; + state[5] = 0x9B05688CUL; + state[6] = 0x1F83D9ABUL; + state[7] = 0x5BE0CD19UL; return CRYPT_OK; } @@ -299,6 +311,8 @@ HASH_PROCESS(sha256_x86_process,s_sha256_x86_compress, sha256, 64) */ int sha256_x86_done(hash_state * md, unsigned char *out) { + ulong32* state; + int align; int i; LTC_ARGCHK(md != NULL); @@ -308,6 +322,12 @@ int sha256_x86_done(hash_state * md, unsigned char *out) return CRYPT_INVALID_ARG; } + state = LTC_ALIGN_BUF(md->sha256.state_buf, 16); + align = (int)((char*)state - (char*)md->sha256.state_buf); + if (align != md->sha256.align) { + XMEMMOVE(state, &md->sha256.state_buf[align], 8 * sizeof(ulong32)); + md->sha256.align = align; + } /* increase the length of the message */ md->sha256.length += md->sha256.curlen * 8; diff --git a/src/headers/tomcrypt_hash.h b/src/headers/tomcrypt_hash.h index 3f619e4a2..2bd7a5917 100644 --- a/src/headers/tomcrypt_hash.h +++ b/src/headers/tomcrypt_hash.h @@ -37,7 +37,8 @@ struct sha512_state { #ifdef LTC_SHA256 struct sha256_state { ulong64 length; - ulong32 *state, curlen; + ulong32 curlen; + int align; unsigned char buf[64]; unsigned char state_buf[LTC_ALIGNED_BUF_SIZE(ulong32, 8, 16)]; }; @@ -46,7 +47,8 @@ struct sha256_state { #ifdef LTC_SHA1 struct sha1_state { ulong64 length; - ulong32 *state, curlen; + ulong32 curlen; + int align; unsigned char buf[64]; unsigned char state_buf[LTC_ALIGNED_BUF_SIZE(ulong32, 5, 16)]; }; diff --git a/tests/hash_state_test.c b/tests/hash_state_test.c new file mode 100644 index 000000000..ac39e1209 --- /dev/null +++ b/tests/hash_state_test.c @@ -0,0 +1,126 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ + +#include + +#include + + +static int s_hash_state_test_sha1(void) +{ +#ifdef LTC_SHA1 + struct ugly_struct + { + unsigned char uchar; + struct sha1_state state; + }; + typedef struct ugly_struct ugly_struct; + + const unsigned char digest_baseline[] = { 0xa4, 0x9b, 0x24, 0x46, 0xa0, 0x2c, 0x64, 0x5b, 0xf4, 0x19, 0xf9, 0x95, 0xb6, 0x70, 0x91, 0x25, 0x3a, 0x04, 0xa2, 0x59 }; + + ugly_struct* md_a; + int err; + ugly_struct* md_b; + unsigned char digest_computed[sizeof(digest_baseline)]; + int cmp; + + md_a = (ugly_struct*)malloc(sizeof(*md_a)); + err = sha1_init((hash_state*)&md_a->state); if(err != CRYPT_OK){ return err; } + err = sha1_process((hash_state*)&md_a->state, (const unsigned char*)"abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu", 112); if(err != CRYPT_OK){ return err; } + md_b = (ugly_struct*)malloc(sizeof(*md_b)); + *md_b = *md_a; + XMEMSET(md_a, 0xff, sizeof(*md_a)); + free(md_a); + err = sha1_done((hash_state*)&md_b->state, &digest_computed[0]); if(err != CRYPT_OK){ return err; } + free(md_b); + cmp = ltc_compare_testvector(&digest_computed[0], sizeof(digest_computed), &digest_baseline[0], sizeof(digest_baseline), "SHA-1", 0); + if(cmp != 0) + { + return CRYPT_FAIL_TESTVECTOR; + } +#endif + return CRYPT_OK; +} + +static int s_hash_state_test_sha224(void) +{ +#ifdef LTC_SHA224 + struct ugly_struct + { + unsigned char uchar; + struct sha256_state state; + }; + typedef struct ugly_struct ugly_struct; + + const unsigned char digest_baseline[] = { 0xc9, 0x7c, 0xa9, 0xa5, 0x59, 0x85, 0x0c, 0xe9, 0x7a, 0x04, 0xa9, 0x6d, 0xef, 0x6d, 0x99, 0xa9, 0xe0, 0xe0, 0xe2, 0xab, 0x14, 0xe6, 0xb8, 0xdf, 0x26, 0x5f, 0xc0, 0xb3 }; + + ugly_struct* md_a; + int err; + ugly_struct* md_b; + unsigned char digest_computed[sizeof(digest_baseline)]; + int cmp; + + md_a = (ugly_struct*)malloc(sizeof(*md_a)); + err = sha224_init((hash_state*)&md_a->state); if(err != CRYPT_OK){ return err; } + err = sha224_process((hash_state*)&md_a->state, (const unsigned char*)"abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu", 112); if(err != CRYPT_OK){ return err; } + md_b = (ugly_struct*)malloc(sizeof(*md_b)); + *md_b = *md_a; + XMEMSET(md_a, 0xff, sizeof(*md_a)); + free(md_a); + err = sha224_done((hash_state*)&md_b->state, &digest_computed[0]); if(err != CRYPT_OK){ return err; } + free(md_b); + cmp = ltc_compare_testvector(&digest_computed[0], sizeof(digest_computed), &digest_baseline[0], sizeof(digest_baseline), "SHA-224", 0); + if(cmp != 0) + { + return CRYPT_FAIL_TESTVECTOR; + } +#endif + return CRYPT_OK; +} + +static int s_hash_state_test_sha256(void) +{ +#ifdef LTC_SHA256 + struct ugly_struct + { + unsigned char uchar; + struct sha256_state state; + }; + typedef struct ugly_struct ugly_struct; + + const unsigned char digest_baseline[] = { 0xcf, 0x5b, 0x16, 0xa7, 0x78, 0xaf, 0x83, 0x80, 0x03, 0x6c, 0xe5, 0x9e, 0x7b, 0x04, 0x92, 0x37, 0x0b, 0x24, 0x9b, 0x11, 0xe8, 0xf0, 0x7a, 0x51, 0xaf, 0xac, 0x45, 0x03, 0x7a, 0xfe, 0xe9, 0xd1 }; + + ugly_struct* md_a; + int err; + ugly_struct* md_b; + unsigned char digest_computed[sizeof(digest_baseline)]; + int cmp; + + md_a = (ugly_struct*)malloc(sizeof(*md_a)); + err = sha256_init((hash_state*)&md_a->state); if(err != CRYPT_OK){ return err; } + err = sha256_process((hash_state*)&md_a->state, (const unsigned char*)"abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu", 112); if(err != CRYPT_OK){ return err; } + md_b = (ugly_struct*)malloc(sizeof(*md_b)); + *md_b = *md_a; + XMEMSET(md_a, 0xff, sizeof(*md_a)); + free(md_a); + err = sha256_done((hash_state*)&md_b->state, &digest_computed[0]); if(err != CRYPT_OK){ return err; } + free(md_b); + cmp = ltc_compare_testvector(&digest_computed[0], sizeof(digest_computed), &digest_baseline[0], sizeof(digest_baseline), "SHA-256", 0); + if(cmp != 0) + { + return CRYPT_FAIL_TESTVECTOR; + } +#endif + return CRYPT_OK; +} + + +int hash_state_test(void) +{ + int err; + + err = s_hash_state_test_sha1(); if(err != CRYPT_OK){ return err; } + err = s_hash_state_test_sha224(); if(err != CRYPT_OK){ return err; } + err = s_hash_state_test_sha256(); if(err != CRYPT_OK){ return err; } + return CRYPT_OK; +} diff --git a/tests/misc_test.c b/tests/misc_test.c index d3d2945dc..5a0c105e0 100644 --- a/tests/misc_test.c +++ b/tests/misc_test.c @@ -40,6 +40,7 @@ int misc_test(void) #ifdef LTC_SSH ssh_test(); #endif + DO(hash_state_test()); pk_oid_test(); no_null_termination_check_test(); return 0; diff --git a/tests/sources.cmake b/tests/sources.cmake index a24ae5d6c..66c7fa2f4 100644 --- a/tests/sources.cmake +++ b/tests/sources.cmake @@ -14,6 +14,7 @@ ecc_test.c ed25519_test.c ed448_test.c file_test.c +hash_state_test.c mac_test.c misc_test.c modes_test.c diff --git a/tests/tomcrypt_test.h b/tests/tomcrypt_test.h index 86d39af77..029cf409c 100644 --- a/tests/tomcrypt_test.h +++ b/tests/tomcrypt_test.h @@ -56,6 +56,7 @@ int no_null_termination_check_test(void); int pk_oid_test(void); int deprecated_test(void); int nop_test(void); +int hash_state_test(void); #ifdef LTC_PKCS_1 struct ltc_prng_descriptor* no_prng_desc_get(void);