mirror of
https://github.com/libtom/libtomcrypt
synced 2026-08-25 20:26:07 -04:00
Add x86-optimized SHA1.
This commit is contained in:
parent
68aae28a9d
commit
7ac05df902
9 changed files with 521 additions and 53 deletions
|
|
@ -18,7 +18,7 @@
|
|||
#define LTC_SMALL_STACK_SHA1
|
||||
#endif
|
||||
|
||||
const struct ltc_hash_descriptor sha1_desc =
|
||||
const struct ltc_hash_descriptor sha1_portable_desc =
|
||||
{
|
||||
"sha1",
|
||||
2,
|
||||
|
|
@ -29,10 +29,10 @@ const struct ltc_hash_descriptor sha1_desc =
|
|||
{ 1, 3, 14, 3, 2, 26, },
|
||||
6,
|
||||
|
||||
&sha1_init,
|
||||
&sha1_process,
|
||||
&sha1_done,
|
||||
&sha1_test,
|
||||
&sha1_c_init,
|
||||
&sha1_c_process,
|
||||
&sha1_c_done,
|
||||
&sha1_c_test,
|
||||
NULL
|
||||
};
|
||||
|
||||
|
|
@ -42,9 +42,9 @@ const struct ltc_hash_descriptor sha1_desc =
|
|||
#define F3(x,y,z) (x ^ y ^ z)
|
||||
|
||||
#ifdef LTC_CLEAN_STACK
|
||||
static int ss_sha1_compress(hash_state *md, const unsigned char *buf)
|
||||
static int ss_sha1_c_compress(hash_state *md, const unsigned char *buf)
|
||||
#else
|
||||
static int s_sha1_compress(hash_state *md, const unsigned char *buf)
|
||||
static int s_sha1_c_compress(hash_state *md, const unsigned char *buf)
|
||||
#endif
|
||||
{
|
||||
ulong32 a,b,c,d,e,i;
|
||||
|
|
@ -170,10 +170,10 @@ static int s_sha1_compress(hash_state *md, const unsigned char *buf)
|
|||
}
|
||||
|
||||
#ifdef LTC_CLEAN_STACK
|
||||
static int s_sha1_compress(hash_state *md, const unsigned char *buf)
|
||||
static int s_sha1_c_compress(hash_state *md, const unsigned char *buf)
|
||||
{
|
||||
int err;
|
||||
err = ss_sha1_compress(md, buf);
|
||||
err = ss_sha1_c_compress(md, buf);
|
||||
burn_stack(sizeof(ulong32) * 87);
|
||||
return err;
|
||||
}
|
||||
|
|
@ -184,9 +184,12 @@ static int s_sha1_compress(hash_state *md, const unsigned char *buf)
|
|||
@param md The hash state you wish to initialize
|
||||
@return CRYPT_OK if successful
|
||||
*/
|
||||
int sha1_init(hash_state * md)
|
||||
int sha1_c_init(hash_state * md)
|
||||
{
|
||||
LTC_ARGCHK(md != NULL);
|
||||
|
||||
md->sha1.state = LTC_ALIGN_BUF(md->sha1.state_buf, 16);
|
||||
|
||||
md->sha1.state[0] = 0x67452301UL;
|
||||
md->sha1.state[1] = 0xefcdab89UL;
|
||||
md->sha1.state[2] = 0x98badcfeUL;
|
||||
|
|
@ -204,7 +207,7 @@ int sha1_init(hash_state * md)
|
|||
@param inlen The length of the data (octets)
|
||||
@return CRYPT_OK if successful
|
||||
*/
|
||||
HASH_PROCESS(sha1_process, s_sha1_compress, sha1, 64)
|
||||
HASH_PROCESS(sha1_c_process, s_sha1_c_compress, sha1, 64)
|
||||
|
||||
/**
|
||||
Terminate the hash to get the digest
|
||||
|
|
@ -212,7 +215,7 @@ HASH_PROCESS(sha1_process, s_sha1_compress, sha1, 64)
|
|||
@param out [out] The destination of the hash (20 bytes)
|
||||
@return CRYPT_OK if successful
|
||||
*/
|
||||
int sha1_done(hash_state * md, unsigned char *out)
|
||||
int sha1_c_done(hash_state * md, unsigned char *out)
|
||||
{
|
||||
int i;
|
||||
|
||||
|
|
@ -237,7 +240,7 @@ int sha1_done(hash_state * md, unsigned char *out)
|
|||
while (md->sha1.curlen < 64) {
|
||||
md->sha1.buf[md->sha1.curlen++] = (unsigned char)0;
|
||||
}
|
||||
s_sha1_compress(md, md->sha1.buf);
|
||||
s_sha1_c_compress(md, md->sha1.buf);
|
||||
md->sha1.curlen = 0;
|
||||
}
|
||||
|
||||
|
|
@ -248,7 +251,7 @@ int sha1_done(hash_state * md, unsigned char *out)
|
|||
|
||||
/* store length */
|
||||
STORE64H(md->sha1.length, md->sha1.buf+56);
|
||||
s_sha1_compress(md, md->sha1.buf);
|
||||
s_sha1_c_compress(md, md->sha1.buf);
|
||||
|
||||
/* copy output */
|
||||
for (i = 0; i < 5; i++) {
|
||||
|
|
@ -264,41 +267,9 @@ int sha1_done(hash_state * md, unsigned char *out)
|
|||
Self-test the hash
|
||||
@return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled
|
||||
*/
|
||||
int sha1_test(void)
|
||||
int sha1_c_test(void)
|
||||
{
|
||||
#ifndef LTC_TEST
|
||||
return CRYPT_NOP;
|
||||
#else
|
||||
static const struct {
|
||||
const char *msg;
|
||||
unsigned char hash[20];
|
||||
} tests[] = {
|
||||
{ "abc",
|
||||
{ 0xa9, 0x99, 0x3e, 0x36, 0x47, 0x06, 0x81, 0x6a,
|
||||
0xba, 0x3e, 0x25, 0x71, 0x78, 0x50, 0xc2, 0x6c,
|
||||
0x9c, 0xd0, 0xd8, 0x9d }
|
||||
},
|
||||
{ "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
|
||||
{ 0x84, 0x98, 0x3E, 0x44, 0x1C, 0x3B, 0xD2, 0x6E,
|
||||
0xBA, 0xAE, 0x4A, 0xA1, 0xF9, 0x51, 0x29, 0xE5,
|
||||
0xE5, 0x46, 0x70, 0xF1 }
|
||||
}
|
||||
};
|
||||
|
||||
int i;
|
||||
unsigned char tmp[20];
|
||||
hash_state md;
|
||||
|
||||
for (i = 0; i < (int)(sizeof(tests) / sizeof(tests[0])); i++) {
|
||||
sha1_init(&md);
|
||||
sha1_process(&md, (unsigned char*)tests[i].msg, (unsigned long)XSTRLEN(tests[i].msg));
|
||||
sha1_done(&md, tmp);
|
||||
if (ltc_compare_testvector(tmp, sizeof(tmp), tests[i].hash, sizeof(tests[i].hash), "SHA1", i)) {
|
||||
return CRYPT_FAIL_TESTVECTOR;
|
||||
}
|
||||
}
|
||||
return CRYPT_OK;
|
||||
#endif
|
||||
return sha1_test_desc(&sha1_portable_desc, "SHA1 portable");
|
||||
}
|
||||
|
||||
#undef F0
|
||||
|
|
|
|||
175
src/hashes/sha1_desc.c
Normal file
175
src/hashes/sha1_desc.c
Normal file
|
|
@ -0,0 +1,175 @@
|
|||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
#include "tomcrypt_private.h"
|
||||
|
||||
#ifdef LTC_SHA1
|
||||
|
||||
const struct ltc_hash_descriptor sha1_desc =
|
||||
{
|
||||
"sha1",
|
||||
2,
|
||||
20,
|
||||
64,
|
||||
|
||||
/* OID */
|
||||
{ 1, 3, 14, 3, 2, 26, },
|
||||
6,
|
||||
|
||||
&sha1_init,
|
||||
&sha1_process,
|
||||
&sha1_done,
|
||||
&sha1_test,
|
||||
NULL
|
||||
};
|
||||
|
||||
#if defined LTC_SHA1_X86
|
||||
|
||||
#if !defined (LTC_S_X86_CPUID)
|
||||
#define LTC_S_X86_CPUID
|
||||
static LTC_INLINE void s_x86_cpuid(int* regs, int leaf)
|
||||
{
|
||||
#if defined _MSC_VER
|
||||
__cpuid(regs, leaf);
|
||||
#else
|
||||
int a, b, c, d;
|
||||
|
||||
a = leaf;
|
||||
b = c = d = 0;
|
||||
asm volatile ("cpuid"
|
||||
:"=a"(a), "=b"(b), "=c"(c), "=d"(d)
|
||||
:"a"(a), "c"(c)
|
||||
);
|
||||
regs[0] = a;
|
||||
regs[1] = b;
|
||||
regs[2] = c;
|
||||
regs[3] = d;
|
||||
#endif
|
||||
}
|
||||
#endif /* LTC_S_X86_CPUID */
|
||||
|
||||
static LTC_INLINE int s_sha1_x86_is_supported(void)
|
||||
{
|
||||
static int initialized = 0;
|
||||
static int is_supported = 0;
|
||||
|
||||
if (initialized == 0) {
|
||||
int regs[4];
|
||||
int sse2, ssse3, sse41, sha;
|
||||
/* Leaf 0, Reg 0 contains the number of leafs available */
|
||||
s_x86_cpuid(regs, 0);
|
||||
if(regs[0] >= 7) {
|
||||
s_x86_cpuid(regs, 1);
|
||||
sse2 = ((((unsigned int)(regs[3])) >> 26) & 1u) != 0; /* SSE2, leaf 1, edx, bit 26 */
|
||||
ssse3 = ((((unsigned int)(regs[2])) >> 9) & 1u) != 0; /* SSSE3, leaf 1, ecx, bit 9 */
|
||||
sse41 = ((((unsigned int)(regs[2])) >> 19) & 1u) != 0; /* SSE4.1, leaf 1, ecx, bit 19 */
|
||||
s_x86_cpuid(regs, 7);
|
||||
sha = ((((unsigned int)(regs[1])) >> 29) & 1u) != 0; /* SHA, leaf 7, ebx, bit 29 */
|
||||
is_supported = sse2 && ssse3 && sse41 && sha;
|
||||
}
|
||||
initialized = 1;
|
||||
}
|
||||
return is_supported;
|
||||
}
|
||||
#endif /* LTC_SHA1_X86 */
|
||||
|
||||
/**
|
||||
Initialize the hash state
|
||||
@param md The hash state you wish to initialize
|
||||
@return CRYPT_OK if successful
|
||||
*/
|
||||
int sha1_init(hash_state * md)
|
||||
{
|
||||
#if defined LTC_SHA1_X86
|
||||
if(s_sha1_x86_is_supported()) {
|
||||
return sha1_x86_init(md);
|
||||
}
|
||||
#endif
|
||||
return sha1_c_init(md);
|
||||
}
|
||||
|
||||
/**
|
||||
Process a block of memory though the hash
|
||||
@param md The hash state
|
||||
@param in The data to hash
|
||||
@param inlen The length of the data (octets)
|
||||
@return CRYPT_OK if successful
|
||||
*/
|
||||
int sha1_process(hash_state * md, const unsigned char *in, unsigned long inlen)
|
||||
{
|
||||
#if defined LTC_SHA1_X86
|
||||
if(s_sha1_x86_is_supported()) {
|
||||
return sha1_x86_process(md, in, inlen);
|
||||
}
|
||||
#endif
|
||||
return sha1_c_process(md, in, inlen);
|
||||
}
|
||||
|
||||
/**
|
||||
Terminate the hash to get the digest
|
||||
@param md The hash state
|
||||
@param out [out] The destination of the hash (20 bytes)
|
||||
@return CRYPT_OK if successful
|
||||
*/
|
||||
int sha1_done(hash_state * md, unsigned char *out)
|
||||
{
|
||||
#if defined LTC_SHA1_X86
|
||||
if(s_sha1_x86_is_supported()) {
|
||||
return sha1_x86_done(md, out);
|
||||
}
|
||||
#endif
|
||||
return sha1_c_done(md, out);
|
||||
}
|
||||
|
||||
/**
|
||||
Self-test the hash
|
||||
@return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled
|
||||
*/
|
||||
int sha1_test(void)
|
||||
{
|
||||
return sha1_test_desc(&sha1_desc, "SHA1");
|
||||
}
|
||||
|
||||
int sha1_test_desc(const struct ltc_hash_descriptor *desc, const char *name)
|
||||
{
|
||||
#ifndef LTC_TEST
|
||||
return CRYPT_NOP;
|
||||
#else
|
||||
static const struct {
|
||||
const char *msg;
|
||||
unsigned char hash[20];
|
||||
} tests[] = {
|
||||
{ "abc",
|
||||
{ 0xa9, 0x99, 0x3e, 0x36, 0x47, 0x06, 0x81, 0x6a,
|
||||
0xba, 0x3e, 0x25, 0x71, 0x78, 0x50, 0xc2, 0x6c,
|
||||
0x9c, 0xd0, 0xd8, 0x9d }
|
||||
},
|
||||
{ "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
|
||||
{ 0x84, 0x98, 0x3E, 0x44, 0x1C, 0x3B, 0xD2, 0x6E,
|
||||
0xBA, 0xAE, 0x4A, 0xA1, 0xF9, 0x51, 0x29, 0xE5,
|
||||
0xE5, 0x46, 0x70, 0xF1 }
|
||||
}
|
||||
};
|
||||
|
||||
int i;
|
||||
unsigned char tmp[20];
|
||||
hash_state md;
|
||||
|
||||
LTC_ARGCHK(desc != NULL);
|
||||
LTC_ARGCHK(desc->init != NULL);
|
||||
LTC_ARGCHK(desc->process != NULL);
|
||||
LTC_ARGCHK(desc->done != NULL);
|
||||
LTC_ARGCHK(name != NULL);
|
||||
|
||||
for (i = 0; i < (int)(sizeof(tests) / sizeof(tests[0])); i++) {
|
||||
desc->init(&md);
|
||||
desc->process(&md, (unsigned char*)tests[i].msg, (unsigned long)XSTRLEN(tests[i].msg));
|
||||
desc->done(&md, tmp);
|
||||
if (ltc_compare_testvector(tmp, sizeof(tmp), tests[i].hash, sizeof(tests[i].hash), name, i)) {
|
||||
return CRYPT_FAIL_TESTVECTOR;
|
||||
}
|
||||
}
|
||||
return CRYPT_OK;
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
287
src/hashes/sha1_x86.c
Normal file
287
src/hashes/sha1_x86.c
Normal file
|
|
@ -0,0 +1,287 @@
|
|||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
#include "tomcrypt_private.h"
|
||||
|
||||
/**
|
||||
@file sha1_x86.c
|
||||
SHA1 code by Marek Knapek
|
||||
*/
|
||||
|
||||
|
||||
#ifdef LTC_SHA1_X86
|
||||
|
||||
#if defined(__GNUC__)
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wdeclaration-after-statement"
|
||||
#pragma GCC diagnostic ignored "-Wuninitialized"
|
||||
#pragma GCC diagnostic ignored "-Wunused-function"
|
||||
#elif defined(_MSC_VER)
|
||||
#include <intrin.h>
|
||||
#endif
|
||||
#include <emmintrin.h> /* SSE2 _mm_load_si128 _mm_loadu_si128 _mm_store_si128 _mm_set_epi32 _mm_set_epi64x _mm_setzero_si128 _mm_xor_si128 _mm_add_epi32 _mm_shuffle_epi32 */
|
||||
#include <tmmintrin.h> /* SSSE3 _mm_shuffle_epi8 */
|
||||
#include <smmintrin.h> /* SSE4.1 _mm_extract_epi32 */
|
||||
#include <immintrin.h> /* SHA _mm_sha1msg1_epu32 _mm_sha1msg2_epu32 _mm_sha1rnds4_epu32 _mm_sha1nexte_epu32 */
|
||||
|
||||
#if defined(__GNUC__)
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
||||
const struct ltc_hash_descriptor sha1_x86_desc =
|
||||
{
|
||||
"sha1",
|
||||
2,
|
||||
20,
|
||||
64,
|
||||
|
||||
/* OID */
|
||||
{ 1, 3, 14, 3, 2, 26, },
|
||||
6,
|
||||
|
||||
&sha1_x86_init,
|
||||
&sha1_x86_process,
|
||||
&sha1_x86_done,
|
||||
&sha1_x86_test,
|
||||
NULL
|
||||
};
|
||||
|
||||
#ifdef LTC_CLEAN_STACK
|
||||
static int LTC_SHA_TARGET ss_sha1_x86_compress(hash_state *md, const unsigned char *buf)
|
||||
#else
|
||||
static int LTC_SHA_TARGET s_sha1_x86_compress(hash_state *md, const unsigned char *buf)
|
||||
#endif
|
||||
{
|
||||
#define k_reverse_32 ((0x0 << (3 * 2)) | (0x1 << (2 * 2)) | (0x2 << (1 * 2)) | (0x3 << (0 * 2)))
|
||||
|
||||
__m128i reverse_8;
|
||||
__m128i abcdx;
|
||||
__m128i e;
|
||||
__m128i old_abcd;
|
||||
__m128i old_e;
|
||||
__m128i msg_0;
|
||||
__m128i abcdy;
|
||||
__m128i msg_1;
|
||||
__m128i msg_2;
|
||||
__m128i msg_3;
|
||||
|
||||
reverse_8 = _mm_set_epi64x(0x0001020304050607ull, 0x08090a0b0c0d0e0full);
|
||||
abcdx = _mm_load_si128(((__m128i const*)(&md->sha1.state[0])));
|
||||
abcdx = _mm_shuffle_epi32(abcdx, k_reverse_32);
|
||||
e = _mm_set_epi32(*((int const*)(&md->sha1.state[4])), 0, 0, 0);
|
||||
|
||||
old_abcd = abcdx;
|
||||
old_e = e;
|
||||
msg_0 = _mm_loadu_si128(((__m128i const*)(&buf[0 * 16])));
|
||||
msg_0 = _mm_shuffle_epi8(msg_0, reverse_8);
|
||||
e = _mm_add_epi32(e, msg_0);
|
||||
abcdy = _mm_sha1rnds4_epu32(abcdx, e, 0);
|
||||
msg_1 = _mm_loadu_si128(((__m128i const*)(&buf[1 * 16])));
|
||||
msg_1 = _mm_shuffle_epi8(msg_1, reverse_8);
|
||||
e = _mm_sha1nexte_epu32(abcdx, msg_1);
|
||||
abcdx = _mm_sha1rnds4_epu32(abcdy, e, 0);
|
||||
msg_2 = _mm_loadu_si128(((__m128i const*)(&buf[2 * 16])));
|
||||
msg_2 = _mm_shuffle_epi8(msg_2, reverse_8);
|
||||
e = _mm_sha1nexte_epu32(abcdy, msg_2);
|
||||
abcdy = _mm_sha1rnds4_epu32(abcdx, e, 0);
|
||||
msg_3 = _mm_loadu_si128(((__m128i const*)(&buf[3 * 16])));
|
||||
msg_3 = _mm_shuffle_epi8(msg_3, reverse_8);
|
||||
e = _mm_sha1nexte_epu32(abcdx, msg_3);
|
||||
abcdx = _mm_sha1rnds4_epu32(abcdy, e, 0);
|
||||
msg_0 = _mm_sha1msg1_epu32(msg_0, msg_1);
|
||||
msg_0 = _mm_xor_si128(msg_0, msg_2);
|
||||
msg_0 = _mm_sha1msg2_epu32(msg_0, msg_3);
|
||||
e = _mm_sha1nexte_epu32(abcdy, msg_0);
|
||||
abcdy = _mm_sha1rnds4_epu32(abcdx, e, 0);
|
||||
msg_1 = _mm_sha1msg1_epu32(msg_1, msg_2);
|
||||
msg_1 = _mm_xor_si128(msg_1, msg_3);
|
||||
msg_1 = _mm_sha1msg2_epu32(msg_1, msg_0);
|
||||
e = _mm_sha1nexte_epu32(abcdx, msg_1);
|
||||
abcdx = _mm_sha1rnds4_epu32(abcdy, e, 1);
|
||||
msg_2 = _mm_sha1msg1_epu32(msg_2, msg_3);
|
||||
msg_2 = _mm_xor_si128(msg_2, msg_0);
|
||||
msg_2 = _mm_sha1msg2_epu32(msg_2, msg_1);
|
||||
e = _mm_sha1nexte_epu32(abcdy, msg_2);
|
||||
abcdy = _mm_sha1rnds4_epu32(abcdx, e, 1);
|
||||
msg_3 = _mm_sha1msg1_epu32(msg_3, msg_0);
|
||||
msg_3 = _mm_xor_si128(msg_3, msg_1);
|
||||
msg_3 = _mm_sha1msg2_epu32(msg_3, msg_2);
|
||||
e = _mm_sha1nexte_epu32(abcdx, msg_3);
|
||||
abcdx = _mm_sha1rnds4_epu32(abcdy, e, 1);
|
||||
msg_0 = _mm_sha1msg1_epu32(msg_0, msg_1);
|
||||
msg_0 = _mm_xor_si128(msg_0, msg_2);
|
||||
msg_0 = _mm_sha1msg2_epu32(msg_0, msg_3);
|
||||
e = _mm_sha1nexte_epu32(abcdy, msg_0);
|
||||
abcdy = _mm_sha1rnds4_epu32(abcdx, e, 1);
|
||||
msg_1 = _mm_sha1msg1_epu32(msg_1, msg_2);
|
||||
msg_1 = _mm_xor_si128(msg_1, msg_3);
|
||||
msg_1 = _mm_sha1msg2_epu32(msg_1, msg_0);
|
||||
e = _mm_sha1nexte_epu32(abcdx, msg_1);
|
||||
abcdx = _mm_sha1rnds4_epu32(abcdy, e, 1);
|
||||
msg_2 = _mm_sha1msg1_epu32(msg_2, msg_3);
|
||||
msg_2 = _mm_xor_si128(msg_2, msg_0);
|
||||
msg_2 = _mm_sha1msg2_epu32(msg_2, msg_1);
|
||||
e = _mm_sha1nexte_epu32(abcdy, msg_2);
|
||||
abcdy = _mm_sha1rnds4_epu32(abcdx, e, 2);
|
||||
msg_3 = _mm_sha1msg1_epu32(msg_3, msg_0);
|
||||
msg_3 = _mm_xor_si128(msg_3, msg_1);
|
||||
msg_3 = _mm_sha1msg2_epu32(msg_3, msg_2);
|
||||
e = _mm_sha1nexte_epu32(abcdx, msg_3);
|
||||
abcdx = _mm_sha1rnds4_epu32(abcdy, e, 2);
|
||||
msg_0 = _mm_sha1msg1_epu32(msg_0, msg_1);
|
||||
msg_0 = _mm_xor_si128(msg_0, msg_2);
|
||||
msg_0 = _mm_sha1msg2_epu32(msg_0, msg_3);
|
||||
e = _mm_sha1nexte_epu32(abcdy, msg_0);
|
||||
abcdy = _mm_sha1rnds4_epu32(abcdx, e, 2);
|
||||
msg_1 = _mm_sha1msg1_epu32(msg_1, msg_2);
|
||||
msg_1 = _mm_xor_si128(msg_1, msg_3);
|
||||
msg_1 = _mm_sha1msg2_epu32(msg_1, msg_0);
|
||||
e = _mm_sha1nexte_epu32(abcdx, msg_1);
|
||||
abcdx = _mm_sha1rnds4_epu32(abcdy, e, 2);
|
||||
msg_2 = _mm_sha1msg1_epu32(msg_2, msg_3);
|
||||
msg_2 = _mm_xor_si128(msg_2, msg_0);
|
||||
msg_2 = _mm_sha1msg2_epu32(msg_2, msg_1);
|
||||
e = _mm_sha1nexte_epu32(abcdy, msg_2);
|
||||
abcdy = _mm_sha1rnds4_epu32(abcdx, e, 2);
|
||||
msg_3 = _mm_sha1msg1_epu32(msg_3, msg_0);
|
||||
msg_3 = _mm_xor_si128(msg_3, msg_1);
|
||||
msg_3 = _mm_sha1msg2_epu32(msg_3, msg_2);
|
||||
e = _mm_sha1nexte_epu32(abcdx, msg_3);
|
||||
abcdx = _mm_sha1rnds4_epu32(abcdy, e, 3);
|
||||
msg_0 = _mm_sha1msg1_epu32(msg_0, msg_1);
|
||||
msg_0 = _mm_xor_si128(msg_0, msg_2);
|
||||
msg_0 = _mm_sha1msg2_epu32(msg_0, msg_3);
|
||||
e = _mm_sha1nexte_epu32(abcdy, msg_0);
|
||||
abcdy = _mm_sha1rnds4_epu32(abcdx, e, 3);
|
||||
msg_1 = _mm_sha1msg1_epu32(msg_1, msg_2);
|
||||
msg_1 = _mm_xor_si128(msg_1, msg_3);
|
||||
msg_1 = _mm_sha1msg2_epu32(msg_1, msg_0);
|
||||
e = _mm_sha1nexte_epu32(abcdx, msg_1);
|
||||
abcdx = _mm_sha1rnds4_epu32(abcdy, e, 3);
|
||||
msg_2 = _mm_sha1msg1_epu32(msg_2, msg_3);
|
||||
msg_2 = _mm_xor_si128(msg_2, msg_0);
|
||||
msg_2 = _mm_sha1msg2_epu32(msg_2, msg_1);
|
||||
e = _mm_sha1nexte_epu32(abcdy, msg_2);
|
||||
abcdy = _mm_sha1rnds4_epu32(abcdx, e, 3);
|
||||
msg_3 = _mm_sha1msg1_epu32(msg_3, msg_0);
|
||||
msg_3 = _mm_xor_si128(msg_3, msg_1);
|
||||
msg_3 = _mm_sha1msg2_epu32(msg_3, msg_2);
|
||||
e = _mm_sha1nexte_epu32(abcdx, msg_3);
|
||||
abcdx = _mm_sha1rnds4_epu32(abcdy, e, 3);
|
||||
msg_0 = _mm_setzero_si128();
|
||||
e = _mm_sha1nexte_epu32(abcdy, msg_0);
|
||||
abcdx = _mm_add_epi32(abcdx, old_abcd);
|
||||
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);
|
||||
|
||||
return CRYPT_OK;
|
||||
|
||||
#undef k_reverse_32
|
||||
}
|
||||
|
||||
#ifdef LTC_CLEAN_STACK
|
||||
static int s_sha1_x86_compress(hash_state *md, const unsigned char *buf)
|
||||
{
|
||||
int err;
|
||||
err = ss_sha1_x86_compress(md, buf);
|
||||
burn_stack(sizeof(ulong32) * 87);
|
||||
return err;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
Initialize the hash state
|
||||
@param md The hash state you wish to initialize
|
||||
@return CRYPT_OK if successful
|
||||
*/
|
||||
int sha1_x86_init(hash_state * md)
|
||||
{
|
||||
LTC_ARGCHK(md != NULL);
|
||||
|
||||
md->sha1.state = LTC_ALIGN_BUF(md->sha1.state_buf, 16);
|
||||
|
||||
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;
|
||||
md->sha1.curlen = 0;
|
||||
md->sha1.length = 0;
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
Process a block of memory though the hash
|
||||
@param md The hash state
|
||||
@param in The data to hash
|
||||
@param inlen The length of the data (octets)
|
||||
@return CRYPT_OK if successful
|
||||
*/
|
||||
HASH_PROCESS(sha1_x86_process, s_sha1_x86_compress, sha1, 64)
|
||||
|
||||
/**
|
||||
Terminate the hash to get the digest
|
||||
@param md The hash state
|
||||
@param out [out] The destination of the hash (20 bytes)
|
||||
@return CRYPT_OK if successful
|
||||
*/
|
||||
int sha1_x86_done(hash_state * md, unsigned char *out)
|
||||
{
|
||||
int i;
|
||||
|
||||
LTC_ARGCHK(md != NULL);
|
||||
LTC_ARGCHK(out != NULL);
|
||||
|
||||
if (md->sha1.curlen >= ((int)(sizeof(md->sha1.buf)))) {
|
||||
return CRYPT_INVALID_ARG;
|
||||
}
|
||||
|
||||
/* increase the length of the message */
|
||||
md->sha1.length += md->sha1.curlen * 8;
|
||||
|
||||
/* append the '1' bit */
|
||||
md->sha1.buf[md->sha1.curlen++] = (unsigned char)0x80;
|
||||
|
||||
/* if the length is currently above 56 bytes we append zeros
|
||||
* then compress. Then we can fall back to padding zeros and length
|
||||
* encoding like normal.
|
||||
*/
|
||||
if (md->sha1.curlen > 56) {
|
||||
while (md->sha1.curlen < 64) {
|
||||
md->sha1.buf[md->sha1.curlen++] = (unsigned char)0;
|
||||
}
|
||||
s_sha1_x86_compress(md, md->sha1.buf);
|
||||
md->sha1.curlen = 0;
|
||||
}
|
||||
|
||||
/* pad upto 56 bytes of zeroes */
|
||||
while (md->sha1.curlen < 56) {
|
||||
md->sha1.buf[md->sha1.curlen++] = (unsigned char)0;
|
||||
}
|
||||
|
||||
/* store length */
|
||||
STORE64H(md->sha1.length, md->sha1.buf+56);
|
||||
s_sha1_x86_compress(md, md->sha1.buf);
|
||||
|
||||
/* copy output */
|
||||
for (i = 0; i < 5; i++) {
|
||||
STORE32H(md->sha1.state[i], out+(4*i));
|
||||
}
|
||||
#ifdef LTC_CLEAN_STACK
|
||||
zeromem(md, sizeof(hash_state));
|
||||
#endif
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
Self-test the hash
|
||||
@return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled
|
||||
*/
|
||||
int sha1_x86_test(void)
|
||||
{
|
||||
return sha1_test_desc(&sha1_x86_desc, "SHA1 x86");
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -307,8 +307,13 @@ typedef unsigned long ltc_mp_digit;
|
|||
#define LTC_HAVE_CTZL_BUILTIN
|
||||
#endif
|
||||
|
||||
#if !defined(LTC_NO_AES_NI) && (defined(__x86_64__) || defined(_M_X64))
|
||||
#define LTC_AES_NI
|
||||
#if (defined(__x86_64__) || defined(_M_X64))
|
||||
#if !defined(LTC_NO_AES_NI)
|
||||
#define LTC_AES_NI
|
||||
#endif
|
||||
#if !defined(LTC_NO_SHA1_X86)
|
||||
#define LTC_SHA1_X86
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(__GNUC__)
|
||||
|
|
@ -375,8 +380,10 @@ typedef unsigned long ltc_mp_digit;
|
|||
|
||||
#if defined(__clang__) || defined(__GNUC__)
|
||||
#define LTC_GCM_PCLMUL_TARGET __attribute__((target("pclmul,ssse3")))
|
||||
#define LTC_SHA_TARGET __attribute__((__target__("sse2,ssse3,sse4.1,sha")))
|
||||
#else
|
||||
#define LTC_GCM_PCLMUL_TARGET
|
||||
#define LTC_SHA_TARGET
|
||||
#endif
|
||||
|
||||
#if !defined(LTC_NO_GCM_PMULL) && (defined(__aarch64__) || defined(_M_ARM64))
|
||||
|
|
|
|||
|
|
@ -45,8 +45,9 @@ struct sha256_state {
|
|||
#ifdef LTC_SHA1
|
||||
struct sha1_state {
|
||||
ulong64 length;
|
||||
ulong32 state[5], curlen;
|
||||
ulong32 *state, curlen;
|
||||
unsigned char buf[64];
|
||||
unsigned char state_buf[LTC_ALIGNED_BUF_SIZE(ulong32, 5, 16)];
|
||||
};
|
||||
#endif
|
||||
|
||||
|
|
@ -174,7 +175,7 @@ typedef union Hash_state {
|
|||
struct sha256_state sha256;
|
||||
#endif
|
||||
#ifdef LTC_SHA1
|
||||
struct sha1_state sha1;
|
||||
struct sha1_state sha1;
|
||||
#endif
|
||||
#ifdef LTC_MD5
|
||||
struct md5_state md5;
|
||||
|
|
@ -398,7 +399,21 @@ int sha1_process(hash_state * md, const unsigned char *in, unsigned long inlen);
|
|||
int sha1_done(hash_state * md, unsigned char *out);
|
||||
int sha1_test(void);
|
||||
extern const struct ltc_hash_descriptor sha1_desc;
|
||||
#endif
|
||||
|
||||
int sha1_c_init(hash_state * md);
|
||||
int sha1_c_process(hash_state * md, const unsigned char *in, unsigned long inlen);
|
||||
int sha1_c_done(hash_state * md, unsigned char *out);
|
||||
int sha1_c_test(void);
|
||||
extern const struct ltc_hash_descriptor sha1_portable_desc;
|
||||
|
||||
#ifdef LTC_SHA1_X86
|
||||
int sha1_x86_init(hash_state * md);
|
||||
int sha1_x86_process(hash_state * md, const unsigned char *in, unsigned long inlen);
|
||||
int sha1_x86_done(hash_state * md, unsigned char *out);
|
||||
int sha1_x86_test(void);
|
||||
extern const struct ltc_hash_descriptor sha1_x86_desc;
|
||||
#endif /* LTC_SHA1_X86 */
|
||||
#endif /* LTC_SHA1 */
|
||||
|
||||
#ifdef LTC_BLAKE2S
|
||||
extern const struct ltc_hash_descriptor blake2s_256_desc;
|
||||
|
|
|
|||
|
|
@ -182,6 +182,9 @@ int func_name (hash_state * md, const unsigned char *in, unsigned long inlen)
|
|||
return CRYPT_OK; \
|
||||
}
|
||||
|
||||
#ifdef LTC_SHA1
|
||||
int sha1_test_desc(const struct ltc_hash_descriptor *desc, const char *name);
|
||||
#endif
|
||||
|
||||
/* tomcrypt_mac.h */
|
||||
|
||||
|
|
|
|||
|
|
@ -502,6 +502,9 @@ const char *crypt_build_settings =
|
|||
#if defined(LTC_PEM_SSH)
|
||||
" OpenSSH-PEM "
|
||||
#endif
|
||||
#if defined(LTC_SHA1_X86)
|
||||
" SHA1-NI "
|
||||
#endif
|
||||
#if defined(LTC_DEVRANDOM)
|
||||
" LTC_DEVRANDOM "
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -40,6 +40,9 @@ int register_all_hashes(void)
|
|||
REGISTER_HASH(&sha384_desc);
|
||||
#endif
|
||||
#ifdef LTC_SHA1
|
||||
/* `sha1_desc` does the multiplexing into `sha1_x86_desc` resp. `sha1_portable_desc`
|
||||
* depending on the capabilities of the CPU.
|
||||
*/
|
||||
REGISTER_HASH(&sha1_desc);
|
||||
#endif
|
||||
#ifdef LTC_MD5
|
||||
|
|
|
|||
|
|
@ -204,6 +204,10 @@ static void s_unregister_all(void)
|
|||
unregister_hash(&md5_desc);
|
||||
#endif
|
||||
#ifdef LTC_SHA1
|
||||
/* `register_all_hashes()` does not register
|
||||
* - `sha1_portable_desc`
|
||||
* - `sha1_x86_desc`
|
||||
* so we don't have to unregister them */
|
||||
unregister_hash(&sha1_desc);
|
||||
#endif
|
||||
#ifdef LTC_SHA224
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue