Skip to content

Commit 4a8ec46

Browse files
committed
Minor changes of SHA1 x86 integration.
* Unify tests into one implementation. * Re-factor `s_sha1_is_supported()` which simplifies this quite a bit. * Improve the pattern where choosing which implementation to run in `sha1_desc.c`. * Only register the common descriptor in `register_all_hashes()`. * Some other minor fixes/improvements. Signed-off-by: Steffen Jaeckel <s@jaeckel.eu>
1 parent 8148711 commit 4a8ec46

5 files changed

Lines changed: 102 additions & 150 deletions

File tree

src/hashes/sha1.c

Lines changed: 2 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020

2121
const struct ltc_hash_descriptor sha1_portable_desc =
2222
{
23-
"sha1_portable",
23+
"sha1",
2424
2,
2525
20,
2626
64,
@@ -266,39 +266,7 @@ int sha1_c_done(hash_state * md, unsigned char *out)
266266
*/
267267
int sha1_c_test(void)
268268
{
269-
#ifndef LTC_TEST
270-
return CRYPT_NOP;
271-
#else
272-
static const struct {
273-
const char *msg;
274-
unsigned char hash[20];
275-
} tests[] = {
276-
{ "abc",
277-
{ 0xa9, 0x99, 0x3e, 0x36, 0x47, 0x06, 0x81, 0x6a,
278-
0xba, 0x3e, 0x25, 0x71, 0x78, 0x50, 0xc2, 0x6c,
279-
0x9c, 0xd0, 0xd8, 0x9d }
280-
},
281-
{ "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
282-
{ 0x84, 0x98, 0x3E, 0x44, 0x1C, 0x3B, 0xD2, 0x6E,
283-
0xBA, 0xAE, 0x4A, 0xA1, 0xF9, 0x51, 0x29, 0xE5,
284-
0xE5, 0x46, 0x70, 0xF1 }
285-
}
286-
};
287-
288-
int i;
289-
unsigned char tmp[20];
290-
hash_state md;
291-
292-
for (i = 0; i < (int)(sizeof(tests) / sizeof(tests[0])); i++) {
293-
sha1_c_init(&md);
294-
sha1_c_process(&md, (unsigned char*)tests[i].msg, (unsigned long)XSTRLEN(tests[i].msg));
295-
sha1_c_done(&md, tmp);
296-
if (ltc_compare_testvector(tmp, sizeof(tmp), tests[i].hash, sizeof(tests[i].hash), "SHA1", i)) {
297-
return CRYPT_FAIL_TESTVECTOR;
298-
}
299-
}
300-
return CRYPT_OK;
301-
#endif
269+
return sha1_test_desc(&sha1_portable_desc, "SHA1 portable");
302270
}
303271

304272
#undef F0

src/hashes/sha1_desc.c

Lines changed: 87 additions & 101 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,17 @@ const struct ltc_hash_descriptor sha1_desc =
2323
};
2424

2525
#if defined LTC_SHA1_X86
26-
#if !defined _MSC_VER
27-
static LTC_INLINE void s_sha1_cpuid(int* regs, int leaf)
26+
27+
#if !defined (LTC_S_X86_CPUID)
28+
#define LTC_S_X86_CPUID
29+
30+
#if defined _MSC_VER
31+
static LTC_INLINE void s_x86_cpuid(int* regs, int leaf)
32+
{
33+
__cpuid(regs, leaf);
34+
}
35+
#else
36+
static LTC_INLINE void s_x86_cpuid(int* regs, int leaf)
2837
{
2938
int a, b, c, d;
3039

@@ -42,49 +51,33 @@ static LTC_INLINE void s_sha1_cpuid(int* regs, int leaf)
4251
regs[3] = d;
4352
}
4453
#endif
45-
static LTC_INLINE int s_sha1_is_supported(void)
54+
55+
#endif /* LTC_S_X86_CPUID */
56+
57+
static LTC_INLINE int s_sha1_x86_is_supported(void)
4658
{
4759
static int initialized = 0;
4860
static int is_supported = 0;
4961

5062
if (initialized == 0) {
51-
#if defined _MSC_VER
5263
int regs[4];
53-
int leafs;
5464
int sse2, ssse3, sse41, sha;
55-
__cpuid(&regs[0], 0); leafs = regs[0];
56-
__cpuid(&regs[0], 1);
57-
sse2 = ((((unsigned int)(regs[3])) >> 26) & 1u) != 0; /* SSE2, leaf 1, edx, bit 26 */
58-
ssse3 = ((((unsigned int)(regs[2])) >> 9) & 1u) != 0; /* SSES3, leaf 1, ecx, bit 9 */
59-
sse41 = ((((unsigned int)(regs[2])) >> 19) & 1u) != 0; /* SSE4.1, leaf 1, ecx, bit 19 */
60-
sha = 0;
61-
if(leafs >= 7) {
62-
__cpuid(&regs[0], 7);
63-
sha = ((((unsigned int)(regs[1])) >> 29) & 1u) != 0; /* SHA, leaf 7, ebx, bit 29 */
65+
/* Leaf 0, Reg 0 contains the number of leafs available */
66+
s_x86_cpuid(regs, 0);
67+
if(regs[0] >= 7) {
68+
s_x86_cpuid(regs, 1);
69+
sse2 = ((((unsigned int)(regs[3])) >> 26) & 1u) != 0; /* SSE2, leaf 1, edx, bit 26 */
70+
ssse3 = ((((unsigned int)(regs[2])) >> 9) & 1u) != 0; /* SSES3, leaf 1, ecx, bit 9 */
71+
sse41 = ((((unsigned int)(regs[2])) >> 19) & 1u) != 0; /* SSE4.1, leaf 1, ecx, bit 19 */
72+
s_x86_cpuid(regs, 7);
73+
sha = ((((unsigned int)(regs[1])) >> 29) & 1u) != 0; /* SHA, leaf 7, ebx, bit 29 */
74+
is_supported = sse2 && ssse3 && sse41 && sha;
6475
}
65-
is_supported = sse2 && ssse3 && sse41 && sha;
6676
initialized = 1;
67-
#else
68-
int regs[4];
69-
int leafs;
70-
int sse2, ssse3, sse41, sha;
71-
s_sha1_cpuid(&regs[0], 0); leafs = regs[0];
72-
s_sha1_cpuid(&regs[0], 1);
73-
sse2 = ((((unsigned int)(regs[3])) >> 26) & 1u) != 0; /* SSE2, leaf 1, edx, bit 26 */
74-
ssse3 = ((((unsigned int)(regs[2])) >> 9) & 1u) != 0; /* SSES3, leaf 1, ecx, bit 9 */
75-
sse41 = ((((unsigned int)(regs[2])) >> 19) & 1u) != 0; /* SSE4.1, leaf 1, ecx, bit 19 */
76-
sha = 0;
77-
if(leafs >= 7) {
78-
s_sha1_cpuid(&regs[0], 7);
79-
sha = ((((unsigned int)(regs[1])) >> 29) & 1u) != 0; /* SHA, leaf 7, ebx, bit 29 */
80-
}
81-
is_supported = sse2 && ssse3 && sse41 && sha;
82-
initialized = 1;
83-
#endif
8477
}
8578
return is_supported;
86-
}
87-
#endif
79+
}
80+
#endif /* LTC_SHA1_X86 */
8881

8982
/**
9083
Initialize the hash state
@@ -93,18 +86,12 @@ static LTC_INLINE int s_sha1_is_supported(void)
9386
*/
9487
int sha1_init(hash_state * md)
9588
{
96-
int err;
97-
98-
#if defined LTC_SHA1_X86
99-
if(s_sha1_is_supported()) {
100-
err = sha1_x86_init(md); if(err != CRYPT_OK){ return err; }
101-
} else {
102-
err = sha1_c_init(md); if(err != CRYPT_OK){ return err; }
89+
#if defined LTC_SHA1_X86
90+
if(s_sha1_x86_is_supported()) {
91+
return sha1_x86_init(md);
10392
}
104-
#else
105-
err = sha1_c_init(md); if(err != CRYPT_OK){ return err; }
106-
#endif
107-
return CRYPT_OK;
93+
#endif
94+
return sha1_c_init(md);
10895
}
10996

11097
/**
@@ -116,18 +103,12 @@ int sha1_init(hash_state * md)
116103
*/
117104
int sha1_process(hash_state * md, const unsigned char *in, unsigned long inlen)
118105
{
119-
int err;
120-
121-
#if defined LTC_SHA1_X86
122-
if(s_sha1_is_supported()) {
123-
err = sha1_x86_process(md, in, inlen); if(err != CRYPT_OK){ return err; }
124-
} else {
125-
err = sha1_c_process(md, in, inlen); if(err != CRYPT_OK){ return err; }
106+
#if defined LTC_SHA1_X86
107+
if(s_sha1_x86_is_supported()) {
108+
return sha1_x86_process(md, in, inlen);
126109
}
127-
#else
128-
err = sha1_c_process(md, in, inlen); if(err != CRYPT_OK){ return err; }
129-
#endif
130-
return CRYPT_OK;
110+
#endif
111+
return sha1_c_process(md, in, inlen);
131112
}
132113

133114
/**
@@ -138,59 +119,64 @@ int sha1_process(hash_state * md, const unsigned char *in, unsigned long inlen)
138119
*/
139120
int sha1_done(hash_state * md, unsigned char *out)
140121
{
141-
int err;
142-
143-
#if defined LTC_SHA1_X86
144-
if(s_sha1_is_supported()) {
145-
err = sha1_x86_done(md, out); if(err != CRYPT_OK){ return err; }
146-
} else {
147-
err = sha1_c_done(md, out); if(err != CRYPT_OK){ return err; }
122+
#if defined LTC_SHA1_X86
123+
if(s_sha1_x86_is_supported()) {
124+
return sha1_x86_done(md, out);
148125
}
149-
#else
150-
err = sha1_c_done(md, out); if(err != CRYPT_OK){ return err; }
151-
#endif
152-
return CRYPT_OK;
126+
#endif
127+
return sha1_c_done(md, out);
153128
}
154129

155130
/**
156131
Self-test the hash
157132
@return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled
158133
*/
159-
int sha1_test(void)
134+
int sha1_test(void)
160135
{
161-
#ifndef LTC_TEST
162-
return CRYPT_NOP;
163-
#else
164-
static const struct {
165-
const char *msg;
166-
unsigned char hash[20];
167-
} tests[] = {
168-
{ "abc",
169-
{ 0xa9, 0x99, 0x3e, 0x36, 0x47, 0x06, 0x81, 0x6a,
170-
0xba, 0x3e, 0x25, 0x71, 0x78, 0x50, 0xc2, 0x6c,
171-
0x9c, 0xd0, 0xd8, 0x9d }
172-
},
173-
{ "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
174-
{ 0x84, 0x98, 0x3E, 0x44, 0x1C, 0x3B, 0xD2, 0x6E,
175-
0xBA, 0xAE, 0x4A, 0xA1, 0xF9, 0x51, 0x29, 0xE5,
176-
0xE5, 0x46, 0x70, 0xF1 }
177-
}
178-
};
179-
180-
int i;
181-
unsigned char tmp[20];
182-
hash_state md;
183-
184-
for (i = 0; i < (int)(sizeof(tests) / sizeof(tests[0])); i++) {
185-
sha1_init(&md);
186-
sha1_process(&md, (unsigned char*)tests[i].msg, (unsigned long)XSTRLEN(tests[i].msg));
187-
sha1_done(&md, tmp);
188-
if (ltc_compare_testvector(tmp, sizeof(tmp), tests[i].hash, sizeof(tests[i].hash), "SHA1", i)) {
189-
return CRYPT_FAIL_TESTVECTOR;
190-
}
191-
}
192-
return CRYPT_OK;
193-
#endif
136+
return sha1_test_desc(&sha1_desc, "SHA1");
137+
}
138+
139+
int sha1_test_desc(const struct ltc_hash_descriptor *desc, const char *name)
140+
{
141+
#ifndef LTC_TEST
142+
return CRYPT_NOP;
143+
#else
144+
static const struct {
145+
const char *msg;
146+
unsigned char hash[20];
147+
} tests[] = {
148+
{ "abc",
149+
{ 0xa9, 0x99, 0x3e, 0x36, 0x47, 0x06, 0x81, 0x6a,
150+
0xba, 0x3e, 0x25, 0x71, 0x78, 0x50, 0xc2, 0x6c,
151+
0x9c, 0xd0, 0xd8, 0x9d }
152+
},
153+
{ "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
154+
{ 0x84, 0x98, 0x3E, 0x44, 0x1C, 0x3B, 0xD2, 0x6E,
155+
0xBA, 0xAE, 0x4A, 0xA1, 0xF9, 0x51, 0x29, 0xE5,
156+
0xE5, 0x46, 0x70, 0xF1 }
157+
}
158+
};
159+
160+
int i;
161+
unsigned char tmp[20];
162+
hash_state md;
163+
164+
LTC_ARGCHK(desc != NULL);
165+
LTC_ARGCHK(desc->init != NULL);
166+
LTC_ARGCHK(desc->process != NULL);
167+
LTC_ARGCHK(desc->done != NULL);
168+
LTC_ARGCHK(name != NULL);
169+
170+
for (i = 0; i < (int)(sizeof(tests) / sizeof(tests[0])); i++) {
171+
desc->init(&md);
172+
desc->process(&md, (unsigned char*)tests[i].msg, (unsigned long)XSTRLEN(tests[i].msg));
173+
desc->done(&md, tmp);
174+
if (ltc_compare_testvector(tmp, sizeof(tmp), tests[i].hash, sizeof(tests[i].hash), name, i)) {
175+
return CRYPT_FAIL_TESTVECTOR;
176+
}
177+
}
178+
return CRYPT_OK;
179+
#endif
194180
}
195181

196182
#endif

src/hashes/sha1_x86.c

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#if defined __GNUC__
1414
#pragma GCC diagnostic push
1515
#pragma GCC diagnostic ignored "-Wdeclaration-after-statement"
16+
#pragma GCC diagnostic ignored "-Wunused-function"
1617
#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 */
1718
#include <tmmintrin.h> /* SSSE3 _mm_shuffle_epi8 */
1819
#include <smmintrin.h> /* SSE4.1 _mm_extract_epi32 */
@@ -26,14 +27,14 @@
2627

2728
const struct ltc_hash_descriptor sha1_x86_desc =
2829
{
29-
"sha1_x86",
30+
"sha1",
3031
2,
3132
20,
3233
64,
3334

3435
/* OID */
35-
{ 1, 3, 14, 3, 2, 26, },
36-
6,
36+
{ 1, 3, 14, 3, 2, 26, },
37+
6,
3738

3839
&sha1_x86_init,
3940
&sha1_x86_process,
@@ -48,7 +49,7 @@ static int ltc_attribute_sha1 ss_sha1_x86_compress(hash_state *md, const unsigne
4849
static int ltc_attribute_sha1 s_sha1_x86_compress(hash_state *md, const unsigned char *buf)
4950
#endif
5051
{
51-
#define k_reverse_32 ((0x0 << (3 * 2)) | (0x1 << (2 * 2)) | (0x2 << (1 * 2)) | (0x3 << (0 * 2)))
52+
#define k_reverse_32 ((0x0 << (3 * 2)) | (0x1 << (2 * 2)) | (0x2 << (1 * 2)) | (0x3 << (0 * 2)))
5253

5354
__m128i reverse_8;
5455
__m128i abcdx;
@@ -180,7 +181,7 @@ static int ltc_attribute_sha1 s_sha1_x86_compress(hash_state *md, const unsigned
180181

181182
return CRYPT_OK;
182183

183-
#undef k_reverse_32
184+
#undef k_reverse_32
184185
}
185186

186187
#ifdef LTC_CLEAN_STACK
@@ -280,12 +281,7 @@ int sha1_x86_done(hash_state * md, unsigned char *out)
280281
*/
281282
int sha1_x86_test(void)
282283
{
283-
#ifndef LTC_TEST
284-
return CRYPT_NOP;
285-
#else
286-
return CRYPT_OK;
287-
#endif
284+
return sha1_test_desc(&sha1_x86_desc, "SHA1 x86");
288285
}
289286

290-
291287
#endif

src/headers/tomcrypt_private.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,9 @@ int func_name (hash_state * md, const unsigned char *in, unsigned long inlen)
179179
return CRYPT_OK; \
180180
}
181181

182+
#ifdef LTC_SHA1
183+
int sha1_test_desc(const struct ltc_hash_descriptor *desc, const char *name);
184+
#endif
182185

183186
/* tomcrypt_mac.h */
184187

src/misc/crypt/crypt_register_all_hashes.c

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,11 +40,10 @@ int register_all_hashes(void)
4040
REGISTER_HASH(&sha384_desc);
4141
#endif
4242
#ifdef LTC_SHA1
43+
/* `sha1_desc` does the multiplexing into `sha1_x86_desc` resp. `sha1_portable_desc`
44+
* depending on the capabilities of the CPU.
45+
*/
4346
REGISTER_HASH(&sha1_desc);
44-
REGISTER_HASH(&sha1_portable_desc);
45-
#endif
46-
#ifdef LTC_SHA1_X86
47-
REGISTER_HASH(&sha1_x86_desc);
4847
#endif
4948
#ifdef LTC_MD5
5049
REGISTER_HASH(&md5_desc);

0 commit comments

Comments
 (0)