@@ -22,6 +22,70 @@ const struct ltc_hash_descriptor sha1_desc =
2222 NULL
2323};
2424
25+ #if defined LTC_SHA1_X86
26+ #if !defined _MSC_VER
27+ static LTC_INLINE void s_sha1_cpuid (int * regs , int leaf )
28+ {
29+ int a , b , c , d ;
30+
31+ a = leaf ;
32+ b = 0 ;
33+ c = 0 ;
34+ d = 0 ;
35+ asm volatile ("cpuid"
36+ :"=a" (a ), "=b" (b ), "=c" (c ), "=d" (d )
37+ :"a" (a ), "c" (c )
38+ );
39+ regs [0 ] = a ;
40+ regs [1 ] = b ;
41+ regs [2 ] = c ;
42+ regs [3 ] = d ;
43+ }
44+ #endif
45+ static LTC_INLINE int s_sha1_is_supported (void )
46+ {
47+ static int initialized = 0 ;
48+ static int is_supported = 0 ;
49+
50+ if (initialized == 0 ) {
51+ #if defined _MSC_VER
52+ int regs [4 ];
53+ int leafs ;
54+ 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 */
64+ }
65+ is_supported = sse2 && ssse3 && sse41 && sha ;
66+ 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
84+ }
85+ return is_supported ;
86+ }
87+ #endif
88+
2589/**
2690 Initialize the hash state
2791 @param md The hash state you wish to initialize
@@ -32,7 +96,11 @@ int sha1_init(hash_state * md)
3296 int err ;
3397
3498 #if defined LTC_SHA1_X86
35- ~~~todo ~~~
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 ; }
103+ }
36104 #else
37105 err = sha1_c_init (md ); if (err != CRYPT_OK ){ return err ; }
38106 #endif
@@ -51,7 +119,11 @@ int sha1_process(hash_state * md, const unsigned char *in, unsigned long inlen)
51119 int err ;
52120
53121 #if defined LTC_SHA1_X86
54- ~~~todo ~~~
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 ; }
126+ }
55127 #else
56128 err = sha1_c_process (md , in , inlen ); if (err != CRYPT_OK ){ return err ; }
57129 #endif
@@ -69,7 +141,11 @@ int sha1_done(hash_state * md, unsigned char *out)
69141 int err ;
70142
71143 #if defined LTC_SHA1_X86
72- ~~~todo ~~~
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 ; }
148+ }
73149 #else
74150 err = sha1_c_done (md , out ); if (err != CRYPT_OK ){ return err ; }
75151 #endif
0 commit comments