Skip to content

Commit 874e095

Browse files
MarekKnapeksjaeckel
authored andcommitted
SHA-256 & SHA-224 x86
1 parent 7ac05df commit 874e095

13 files changed

Lines changed: 883 additions & 91 deletions

File tree

src/hashes/sha2/sha224.c

Lines changed: 10 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010
#if defined(LTC_SHA224) && defined(LTC_SHA256)
1111

12-
const struct ltc_hash_descriptor sha224_desc =
12+
const struct ltc_hash_descriptor sha224_portable_desc =
1313
{
1414
"sha224",
1515
10,
@@ -20,9 +20,9 @@ const struct ltc_hash_descriptor sha224_desc =
2020
{ 2, 16, 840, 1, 101, 3, 4, 2, 4, },
2121
9,
2222

23-
&sha224_init,
24-
&sha256_process,
25-
&sha224_done,
23+
&sha224_c_init,
24+
&sha256_c_process,
25+
&sha224_c_done,
2626
&sha224_test,
2727
NULL
2828
};
@@ -33,10 +33,12 @@ const struct ltc_hash_descriptor sha224_desc =
3333
@param md The hash state you wish to initialize
3434
@return CRYPT_OK if successful
3535
*/
36-
int sha224_init(hash_state * md)
36+
int sha224_c_init(hash_state * md)
3737
{
3838
LTC_ARGCHK(md != NULL);
3939

40+
md->sha256.state = LTC_ALIGN_BUF(md->sha256.state_buf, 16);
41+
4042
md->sha256.curlen = 0;
4143
md->sha256.length = 0;
4244
md->sha256.state[0] = 0xc1059ed8UL;
@@ -56,7 +58,7 @@ int sha224_init(hash_state * md)
5658
@param out [out] The destination of the hash (28 bytes)
5759
@return CRYPT_OK if successful
5860
*/
59-
int sha224_done(hash_state * md, unsigned char *out)
61+
int sha224_c_done(hash_state * md, unsigned char *out)
6062
{
6163
unsigned char buf[32];
6264
int err;
@@ -76,43 +78,9 @@ int sha224_done(hash_state * md, unsigned char *out)
7678
Self-test the hash
7779
@return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled
7880
*/
79-
int sha224_test(void)
81+
int sha224_c_test(void)
8082
{
81-
#ifndef LTC_TEST
82-
return CRYPT_NOP;
83-
#else
84-
static const struct {
85-
const char *msg;
86-
unsigned char hash[28];
87-
} tests[] = {
88-
{ "abc",
89-
{ 0x23, 0x09, 0x7d, 0x22, 0x34, 0x05, 0xd8,
90-
0x22, 0x86, 0x42, 0xa4, 0x77, 0xbd, 0xa2,
91-
0x55, 0xb3, 0x2a, 0xad, 0xbc, 0xe4, 0xbd,
92-
0xa0, 0xb3, 0xf7, 0xe3, 0x6c, 0x9d, 0xa7 }
93-
},
94-
{ "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
95-
{ 0x75, 0x38, 0x8b, 0x16, 0x51, 0x27, 0x76,
96-
0xcc, 0x5d, 0xba, 0x5d, 0xa1, 0xfd, 0x89,
97-
0x01, 0x50, 0xb0, 0xc6, 0x45, 0x5c, 0xb4,
98-
0xf5, 0x8b, 0x19, 0x52, 0x52, 0x25, 0x25 }
99-
},
100-
};
101-
102-
int i;
103-
unsigned char tmp[28];
104-
hash_state md;
105-
106-
for (i = 0; i < (int)(sizeof(tests) / sizeof(tests[0])); i++) {
107-
sha224_init(&md);
108-
sha224_process(&md, (unsigned char*)tests[i].msg, (unsigned long)XSTRLEN(tests[i].msg));
109-
sha224_done(&md, tmp);
110-
if (ltc_compare_testvector(tmp, sizeof(tmp), tests[i].hash, sizeof(tests[i].hash), "SHA224", i)) {
111-
return CRYPT_FAIL_TESTVECTOR;
112-
}
113-
}
114-
return CRYPT_OK;
115-
#endif
83+
return sha224_test_desc(&sha224_portable_desc, "SHA224 portable");
11684
}
11785

11886
#endif /* defined(LTC_SHA224) && defined(LTC_SHA256) */

src/hashes/sha2/sha224_desc.c

Lines changed: 167 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,167 @@
1+
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
2+
/* SPDX-License-Identifier: Unlicense */
3+
/**
4+
@param sha224.c
5+
LTC_SHA-224 new NIST standard based off of LTC_SHA-256 truncated to 224 bits (Tom St Denis)
6+
*/
7+
8+
#include "tomcrypt_private.h"
9+
10+
#if defined(LTC_SHA224) && defined(LTC_SHA256)
11+
12+
const struct ltc_hash_descriptor sha224_desc =
13+
{
14+
"sha224",
15+
10,
16+
28,
17+
64,
18+
19+
/* OID */
20+
{ 2, 16, 840, 1, 101, 3, 4, 2, 4, },
21+
9,
22+
23+
&sha224_init,
24+
&sha256_process,
25+
&sha224_done,
26+
&sha224_test,
27+
NULL
28+
};
29+
30+
#if defined LTC_SHA256_X86
31+
32+
#if !defined (LTC_S_X86_CPUID)
33+
#define LTC_S_X86_CPUID
34+
static LTC_INLINE void s_x86_cpuid(int* regs, int leaf)
35+
{
36+
#if defined _MSC_VER
37+
__cpuid(regs, leaf);
38+
#else
39+
int a, b, c, d;
40+
41+
a = leaf;
42+
b = c = d = 0;
43+
asm volatile ("cpuid"
44+
:"=a"(a), "=b"(b), "=c"(c), "=d"(d)
45+
:"a"(a), "c"(c)
46+
);
47+
regs[0] = a;
48+
regs[1] = b;
49+
regs[2] = c;
50+
regs[3] = d;
51+
#endif
52+
}
53+
#endif /* LTC_S_X86_CPUID */
54+
55+
static LTC_INLINE int s_sha224_x86_is_supported(void)
56+
{
57+
static int initialized = 0;
58+
static int is_supported = 0;
59+
60+
if (initialized == 0) {
61+
int regs[4];
62+
int sse2, ssse3, sse41, sha;
63+
/* Leaf 0, Reg 0 contains the number of leafs available */
64+
s_x86_cpuid(regs, 0);
65+
if(regs[0] >= 7) {
66+
s_x86_cpuid(regs, 1);
67+
sse2 = ((((unsigned int)(regs[3])) >> 26) & 1u) != 0; /* SSE2, leaf 1, edx, bit 26 */
68+
ssse3 = ((((unsigned int)(regs[2])) >> 9) & 1u) != 0; /* SSSE3, leaf 1, ecx, bit 9 */
69+
sse41 = ((((unsigned int)(regs[2])) >> 19) & 1u) != 0; /* SSE4.1, leaf 1, ecx, bit 19 */
70+
s_x86_cpuid(regs, 7);
71+
sha = ((((unsigned int)(regs[1])) >> 29) & 1u) != 0; /* SHA, leaf 7, ebx, bit 29 */
72+
is_supported = sse2 && ssse3 && sse41 && sha;
73+
}
74+
initialized = 1;
75+
}
76+
return is_supported;
77+
}
78+
#endif /* LTC_SHA224_X86 */
79+
80+
/* init the sha256 er... sha224 state ;-) */
81+
/**
82+
Initialize the hash state
83+
@param md The hash state you wish to initialize
84+
@return CRYPT_OK if successful
85+
*/
86+
int sha224_init(hash_state * md)
87+
{
88+
#if defined LTC_SHA224_X86
89+
if(s_sha224_x86_is_supported()) {
90+
return sha224_x86_init(md);
91+
}
92+
#endif
93+
return sha224_c_init(md);
94+
}
95+
96+
/**
97+
Terminate the hash to get the digest
98+
@param md The hash state
99+
@param out [out] The destination of the hash (28 bytes)
100+
@return CRYPT_OK if successful
101+
*/
102+
int sha224_done(hash_state * md, unsigned char *out)
103+
{
104+
#if defined LTC_SHA224_X86
105+
if(s_sha224_x86_is_supported()) {
106+
return sha224_x86_done(md, out);
107+
}
108+
#endif
109+
return sha224_c_done(md, out);
110+
}
111+
112+
/**
113+
Self-test the hash
114+
@return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled
115+
*/
116+
int sha224_test(void)
117+
{
118+
return sha224_test_desc(&sha224_desc, "SHA224");
119+
}
120+
121+
int sha224_test_desc(const struct ltc_hash_descriptor *desc, const char *name)
122+
{
123+
#ifndef LTC_TEST
124+
return CRYPT_NOP;
125+
#else
126+
static const struct {
127+
const char *msg;
128+
unsigned char hash[28];
129+
} tests[] = {
130+
{ "abc",
131+
{ 0x23, 0x09, 0x7d, 0x22, 0x34, 0x05, 0xd8,
132+
0x22, 0x86, 0x42, 0xa4, 0x77, 0xbd, 0xa2,
133+
0x55, 0xb3, 0x2a, 0xad, 0xbc, 0xe4, 0xbd,
134+
0xa0, 0xb3, 0xf7, 0xe3, 0x6c, 0x9d, 0xa7 }
135+
},
136+
{ "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
137+
{ 0x75, 0x38, 0x8b, 0x16, 0x51, 0x27, 0x76,
138+
0xcc, 0x5d, 0xba, 0x5d, 0xa1, 0xfd, 0x89,
139+
0x01, 0x50, 0xb0, 0xc6, 0x45, 0x5c, 0xb4,
140+
0xf5, 0x8b, 0x19, 0x52, 0x52, 0x25, 0x25 }
141+
},
142+
};
143+
144+
int i;
145+
unsigned char tmp[32];
146+
hash_state md;
147+
148+
LTC_ARGCHK(desc != NULL);
149+
LTC_ARGCHK(desc->init != NULL);
150+
LTC_ARGCHK(desc->process != NULL);
151+
LTC_ARGCHK(desc->done != NULL);
152+
LTC_ARGCHK(name != NULL);
153+
154+
for (i = 0; i < (int)(sizeof(tests) / sizeof(tests[0])); i++) {
155+
desc->init(&md);
156+
desc->process(&md, (unsigned char*)tests[i].msg, (unsigned long)XSTRLEN(tests[i].msg));
157+
desc->done(&md, tmp);
158+
if (ltc_compare_testvector(tmp, 28, tests[i].hash, sizeof(tests[i].hash), name, i)) {
159+
return CRYPT_FAIL_TESTVECTOR;
160+
}
161+
}
162+
return CRYPT_OK;
163+
#endif
164+
}
165+
166+
#endif /* defined(LTC_SHA224) && defined(LTC_SHA256) */
167+

src/hashes/sha2/sha224_x86.c

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
2+
/* SPDX-License-Identifier: Unlicense */
3+
/**
4+
@param sha224.c
5+
LTC_SHA-224 new NIST standard based off of LTC_SHA-256 truncated to 224 bits (Tom St Denis)
6+
*/
7+
8+
#include "tomcrypt_private.h"
9+
10+
#if defined(LTC_SHA224) && defined(LTC_SHA256) && defined(LTC_SHA224_X86)
11+
12+
const struct ltc_hash_descriptor sha224_x86_desc =
13+
{
14+
"sha224",
15+
10,
16+
28,
17+
64,
18+
19+
/* OID */
20+
{ 2, 16, 840, 1, 101, 3, 4, 2, 4, },
21+
9,
22+
23+
&sha224_x86_init,
24+
&sha256_x86_process,
25+
&sha224_x86_done,
26+
&sha224_x86_test,
27+
NULL
28+
};
29+
30+
/* init the sha256 er... sha224 state ;-) */
31+
/**
32+
Initialize the hash state
33+
@param md The hash state you wish to initialize
34+
@return CRYPT_OK if successful
35+
*/
36+
int sha224_x86_init(hash_state * md)
37+
{
38+
LTC_ARGCHK(md != NULL);
39+
40+
md->sha256.state = LTC_ALIGN_BUF(md->sha256.state_buf, 16);
41+
42+
md->sha256.curlen = 0;
43+
md->sha256.length = 0;
44+
md->sha256.state[0] = 0xc1059ed8UL;
45+
md->sha256.state[1] = 0x367cd507UL;
46+
md->sha256.state[2] = 0x3070dd17UL;
47+
md->sha256.state[3] = 0xf70e5939UL;
48+
md->sha256.state[4] = 0xffc00b31UL;
49+
md->sha256.state[5] = 0x68581511UL;
50+
md->sha256.state[6] = 0x64f98fa7UL;
51+
md->sha256.state[7] = 0xbefa4fa4UL;
52+
return CRYPT_OK;
53+
}
54+
55+
/**
56+
Terminate the hash to get the digest
57+
@param md The hash state
58+
@param out [out] The destination of the hash (28 bytes)
59+
@return CRYPT_OK if successful
60+
*/
61+
int sha224_x86_done(hash_state * md, unsigned char *out)
62+
{
63+
unsigned char buf[32];
64+
int err;
65+
66+
LTC_ARGCHK(md != NULL);
67+
LTC_ARGCHK(out != NULL);
68+
69+
err = sha256_done(md, buf);
70+
XMEMCPY(out, buf, 28);
71+
#ifdef LTC_CLEAN_STACK
72+
zeromem(buf, sizeof(buf));
73+
#endif
74+
return err;
75+
}
76+
77+
/**
78+
Self-test the hash
79+
@return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled
80+
*/
81+
int sha224_x86_test(void)
82+
{
83+
return sha224_test_desc(&sha224_x86_desc, "SHA224 x86");
84+
}
85+
86+
#endif /* defined(LTC_SHA224) && defined(LTC_SHA256) */
87+

0 commit comments

Comments
 (0)