Mercurial > dropbear
annotate sha1-asm-ltc.c @ 910:89555751c489 asm
merge up to 2013.63, improve ASM makefile rules a bit
author | Matt Johnston <matt@ucc.asn.au> |
---|---|
date | Thu, 27 Feb 2014 21:35:58 +0800 |
parents | e4b75744acab |
children |
rev | line source |
---|---|
908 | 1 /* LibTomCrypt, modular cryptographic library -- Tom St Denis |
2 * | |
3 * LibTomCrypt is a library that provides various cryptographic | |
4 * algorithms in a highly modular and flexible manner. | |
5 * | |
6 * The library is free for all purposes without any express | |
7 * guarantee it works. | |
8 * | |
9 * Tom St Denis, [email protected], http://libtomcrypt.com | |
10 */ | |
11 #include "tomcrypt.h" | |
12 | |
13 /** | |
14 @file sha1.c | |
15 SHA1 code by Tom St Denis | |
16 */ | |
17 | |
18 | |
19 #ifdef DROPBEAR_SHA1_ASM | |
20 | |
21 /** | |
22 Initialize the hash state | |
23 @param md The hash state you wish to initialize | |
24 @return CRYPT_OK if successful | |
25 */ | |
909
e4b75744acab
- Call the asm with multiple blocks
Matt Johnston <matt@ucc.asn.au>
parents:
908
diff
changeset
|
26 static int sha1_asm_init(hash_state * md) |
908 | 27 { |
28 LTC_ARGCHK(md != NULL); | |
29 md->sha1.state[0] = 0x67452301UL; | |
30 md->sha1.state[1] = 0xefcdab89UL; | |
31 md->sha1.state[2] = 0x98badcfeUL; | |
32 md->sha1.state[3] = 0x10325476UL; | |
33 md->sha1.state[4] = 0xc3d2e1f0UL; | |
34 md->sha1.curlen = 0; | |
35 md->sha1.length = 0; | |
36 return CRYPT_OK; | |
37 } | |
38 | |
909
e4b75744acab
- Call the asm with multiple blocks
Matt Johnston <matt@ucc.asn.au>
parents:
908
diff
changeset
|
39 void sha1_block_data_order(void* sha1s, const unsigned char *buf, size_t num); |
908 | 40 |
909
e4b75744acab
- Call the asm with multiple blocks
Matt Johnston <matt@ucc.asn.au>
parents:
908
diff
changeset
|
41 static int sha1_asm_compress(hash_state *md, unsigned char *buf, size_t num) |
908 | 42 { |
909
e4b75744acab
- Call the asm with multiple blocks
Matt Johnston <matt@ucc.asn.au>
parents:
908
diff
changeset
|
43 sha1_block_data_order(&md->sha1.state, buf, num); |
908 | 44 return CRYPT_OK; |
45 } | |
46 | |
47 /** | |
48 Process a block of memory though the hash | |
49 @param md The hash state | |
50 @param in The data to hash | |
51 @param inlen The length of the data (octets) | |
52 @return CRYPT_OK if successful | |
53 */ | |
909
e4b75744acab
- Call the asm with multiple blocks
Matt Johnston <matt@ucc.asn.au>
parents:
908
diff
changeset
|
54 int sha1_asm_process (hash_state * md, const unsigned char *in, unsigned long inlen) \ |
e4b75744acab
- Call the asm with multiple blocks
Matt Johnston <matt@ucc.asn.au>
parents:
908
diff
changeset
|
55 { \ |
e4b75744acab
- Call the asm with multiple blocks
Matt Johnston <matt@ucc.asn.au>
parents:
908
diff
changeset
|
56 unsigned long n; \ |
e4b75744acab
- Call the asm with multiple blocks
Matt Johnston <matt@ucc.asn.au>
parents:
908
diff
changeset
|
57 int err; \ |
e4b75744acab
- Call the asm with multiple blocks
Matt Johnston <matt@ucc.asn.au>
parents:
908
diff
changeset
|
58 LTC_ARGCHK(md != NULL); \ |
e4b75744acab
- Call the asm with multiple blocks
Matt Johnston <matt@ucc.asn.au>
parents:
908
diff
changeset
|
59 LTC_ARGCHK(in != NULL); \ |
e4b75744acab
- Call the asm with multiple blocks
Matt Johnston <matt@ucc.asn.au>
parents:
908
diff
changeset
|
60 if (md-> sha1 .curlen > sizeof(md-> sha1 .buf)) { \ |
e4b75744acab
- Call the asm with multiple blocks
Matt Johnston <matt@ucc.asn.au>
parents:
908
diff
changeset
|
61 return CRYPT_INVALID_ARG; \ |
e4b75744acab
- Call the asm with multiple blocks
Matt Johnston <matt@ucc.asn.au>
parents:
908
diff
changeset
|
62 } \ |
e4b75744acab
- Call the asm with multiple blocks
Matt Johnston <matt@ucc.asn.au>
parents:
908
diff
changeset
|
63 while (inlen > 0) { \ |
e4b75744acab
- Call the asm with multiple blocks
Matt Johnston <matt@ucc.asn.au>
parents:
908
diff
changeset
|
64 if (md-> sha1 .curlen == 0 && inlen >= 64) { \ |
e4b75744acab
- Call the asm with multiple blocks
Matt Johnston <matt@ucc.asn.au>
parents:
908
diff
changeset
|
65 //const size_t num = inlen / 64; |
e4b75744acab
- Call the asm with multiple blocks
Matt Johnston <matt@ucc.asn.au>
parents:
908
diff
changeset
|
66 const size_t num = 1; |
e4b75744acab
- Call the asm with multiple blocks
Matt Johnston <matt@ucc.asn.au>
parents:
908
diff
changeset
|
67 if ((err = sha1_asm_compress (md, (unsigned char *)in, num)) != CRYPT_OK) { \ |
e4b75744acab
- Call the asm with multiple blocks
Matt Johnston <matt@ucc.asn.au>
parents:
908
diff
changeset
|
68 return err; \ |
e4b75744acab
- Call the asm with multiple blocks
Matt Johnston <matt@ucc.asn.au>
parents:
908
diff
changeset
|
69 } \ |
e4b75744acab
- Call the asm with multiple blocks
Matt Johnston <matt@ucc.asn.au>
parents:
908
diff
changeset
|
70 md-> sha1 .length += 64 * 8 * num; \ |
e4b75744acab
- Call the asm with multiple blocks
Matt Johnston <matt@ucc.asn.au>
parents:
908
diff
changeset
|
71 in += 64 * num; \ |
e4b75744acab
- Call the asm with multiple blocks
Matt Johnston <matt@ucc.asn.au>
parents:
908
diff
changeset
|
72 inlen -= 64 * num; \ |
e4b75744acab
- Call the asm with multiple blocks
Matt Johnston <matt@ucc.asn.au>
parents:
908
diff
changeset
|
73 } else { \ |
e4b75744acab
- Call the asm with multiple blocks
Matt Johnston <matt@ucc.asn.au>
parents:
908
diff
changeset
|
74 n = MIN(inlen, (64 - md-> sha1 .curlen)); \ |
e4b75744acab
- Call the asm with multiple blocks
Matt Johnston <matt@ucc.asn.au>
parents:
908
diff
changeset
|
75 memcpy(md-> sha1 .buf + md-> sha1.curlen, in, (size_t)n); \ |
e4b75744acab
- Call the asm with multiple blocks
Matt Johnston <matt@ucc.asn.au>
parents:
908
diff
changeset
|
76 md-> sha1 .curlen += n; \ |
e4b75744acab
- Call the asm with multiple blocks
Matt Johnston <matt@ucc.asn.au>
parents:
908
diff
changeset
|
77 in += n; \ |
e4b75744acab
- Call the asm with multiple blocks
Matt Johnston <matt@ucc.asn.au>
parents:
908
diff
changeset
|
78 inlen -= n; \ |
e4b75744acab
- Call the asm with multiple blocks
Matt Johnston <matt@ucc.asn.au>
parents:
908
diff
changeset
|
79 if (md-> sha1 .curlen == 64) { \ |
e4b75744acab
- Call the asm with multiple blocks
Matt Johnston <matt@ucc.asn.au>
parents:
908
diff
changeset
|
80 if ((err = sha1_asm_compress (md, md-> sha1 .buf, 1)) != CRYPT_OK) { \ |
e4b75744acab
- Call the asm with multiple blocks
Matt Johnston <matt@ucc.asn.au>
parents:
908
diff
changeset
|
81 return err; \ |
e4b75744acab
- Call the asm with multiple blocks
Matt Johnston <matt@ucc.asn.au>
parents:
908
diff
changeset
|
82 } \ |
e4b75744acab
- Call the asm with multiple blocks
Matt Johnston <matt@ucc.asn.au>
parents:
908
diff
changeset
|
83 md-> sha1 .length += 8*64; \ |
e4b75744acab
- Call the asm with multiple blocks
Matt Johnston <matt@ucc.asn.au>
parents:
908
diff
changeset
|
84 md-> sha1 .curlen = 0; \ |
e4b75744acab
- Call the asm with multiple blocks
Matt Johnston <matt@ucc.asn.au>
parents:
908
diff
changeset
|
85 } \ |
e4b75744acab
- Call the asm with multiple blocks
Matt Johnston <matt@ucc.asn.au>
parents:
908
diff
changeset
|
86 } \ |
e4b75744acab
- Call the asm with multiple blocks
Matt Johnston <matt@ucc.asn.au>
parents:
908
diff
changeset
|
87 } \ |
e4b75744acab
- Call the asm with multiple blocks
Matt Johnston <matt@ucc.asn.au>
parents:
908
diff
changeset
|
88 return CRYPT_OK; \ |
e4b75744acab
- Call the asm with multiple blocks
Matt Johnston <matt@ucc.asn.au>
parents:
908
diff
changeset
|
89 } |
908 | 90 |
91 /** | |
92 Terminate the hash to get the digest | |
93 @param md The hash state | |
94 @param out [out] The destination of the hash (20 bytes) | |
95 @return CRYPT_OK if successful | |
96 */ | |
909
e4b75744acab
- Call the asm with multiple blocks
Matt Johnston <matt@ucc.asn.au>
parents:
908
diff
changeset
|
97 int sha1_asm_done(hash_state * md, unsigned char *out) |
908 | 98 { |
99 int i; | |
100 | |
101 LTC_ARGCHK(md != NULL); | |
102 LTC_ARGCHK(out != NULL); | |
103 | |
104 if (md->sha1.curlen >= sizeof(md->sha1.buf)) { | |
105 return CRYPT_INVALID_ARG; | |
106 } | |
107 | |
108 /* increase the length of the message */ | |
109 md->sha1.length += md->sha1.curlen * 8; | |
110 | |
111 /* append the '1' bit */ | |
112 md->sha1.buf[md->sha1.curlen++] = (unsigned char)0x80; | |
113 | |
114 /* if the length is currently above 56 bytes we append zeros | |
115 * then compress. Then we can fall back to padding zeros and length | |
116 * encoding like normal. | |
117 */ | |
118 if (md->sha1.curlen > 56) { | |
119 while (md->sha1.curlen < 64) { | |
120 md->sha1.buf[md->sha1.curlen++] = (unsigned char)0; | |
121 } | |
909
e4b75744acab
- Call the asm with multiple blocks
Matt Johnston <matt@ucc.asn.au>
parents:
908
diff
changeset
|
122 sha1_asm_compress(md, md->sha1.buf, 1); |
908 | 123 md->sha1.curlen = 0; |
124 } | |
125 | |
126 /* pad upto 56 bytes of zeroes */ | |
127 while (md->sha1.curlen < 56) { | |
128 md->sha1.buf[md->sha1.curlen++] = (unsigned char)0; | |
129 } | |
130 | |
131 /* store length */ | |
132 STORE64H(md->sha1.length, md->sha1.buf+56); | |
909
e4b75744acab
- Call the asm with multiple blocks
Matt Johnston <matt@ucc.asn.au>
parents:
908
diff
changeset
|
133 sha1_asm_compress(md, md->sha1.buf, 1); |
908 | 134 |
135 /* copy output */ | |
136 for (i = 0; i < 5; i++) { | |
137 STORE32H(md->sha1.state[i], out+(4*i)); | |
138 } | |
139 #ifdef LTC_CLEAN_STACK | |
140 zeromem(md, sizeof(hash_state)); | |
141 #endif | |
142 return CRYPT_OK; | |
143 } | |
144 | |
145 /** | |
146 Self-test the hash | |
147 @return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled | |
148 */ | |
909
e4b75744acab
- Call the asm with multiple blocks
Matt Johnston <matt@ucc.asn.au>
parents:
908
diff
changeset
|
149 int sha1_asm_test(void) |
908 | 150 { |
151 #ifndef LTC_TEST | |
152 return CRYPT_NOP; | |
153 #else | |
154 static const struct { | |
155 char *msg; | |
156 unsigned char hash[20]; | |
157 } tests[] = { | |
158 { "abc", | |
159 { 0xa9, 0x99, 0x3e, 0x36, 0x47, 0x06, 0x81, 0x6a, | |
160 0xba, 0x3e, 0x25, 0x71, 0x78, 0x50, 0xc2, 0x6c, | |
161 0x9c, 0xd0, 0xd8, 0x9d } | |
162 }, | |
163 { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", | |
164 { 0x84, 0x98, 0x3E, 0x44, 0x1C, 0x3B, 0xD2, 0x6E, | |
165 0xBA, 0xAE, 0x4A, 0xA1, 0xF9, 0x51, 0x29, 0xE5, | |
166 0xE5, 0x46, 0x70, 0xF1 } | |
167 } | |
168 }; | |
169 | |
170 int i; | |
171 unsigned char tmp[20]; | |
172 hash_state md; | |
173 | |
174 for (i = 0; i < (int)(sizeof(tests) / sizeof(tests[0])); i++) { | |
175 sha1_init(&md); | |
176 sha1_process(&md, (unsigned char*)tests[i].msg, (unsigned long)strlen(tests[i].msg)); | |
177 sha1_done(&md, tmp); | |
178 if (XMEMCMP(tmp, tests[i].hash, 20) != 0) { | |
179 return CRYPT_FAIL_TESTVECTOR; | |
180 } | |
181 } | |
182 return CRYPT_OK; | |
183 #endif | |
184 } | |
185 | |
909
e4b75744acab
- Call the asm with multiple blocks
Matt Johnston <matt@ucc.asn.au>
parents:
908
diff
changeset
|
186 const struct ltc_hash_descriptor sha1_asm_desc = |
e4b75744acab
- Call the asm with multiple blocks
Matt Johnston <matt@ucc.asn.au>
parents:
908
diff
changeset
|
187 { |
e4b75744acab
- Call the asm with multiple blocks
Matt Johnston <matt@ucc.asn.au>
parents:
908
diff
changeset
|
188 "sha1_asm", |
e4b75744acab
- Call the asm with multiple blocks
Matt Johnston <matt@ucc.asn.au>
parents:
908
diff
changeset
|
189 102, |
e4b75744acab
- Call the asm with multiple blocks
Matt Johnston <matt@ucc.asn.au>
parents:
908
diff
changeset
|
190 20, |
e4b75744acab
- Call the asm with multiple blocks
Matt Johnston <matt@ucc.asn.au>
parents:
908
diff
changeset
|
191 64, |
e4b75744acab
- Call the asm with multiple blocks
Matt Johnston <matt@ucc.asn.au>
parents:
908
diff
changeset
|
192 |
e4b75744acab
- Call the asm with multiple blocks
Matt Johnston <matt@ucc.asn.au>
parents:
908
diff
changeset
|
193 /* OID */ |
e4b75744acab
- Call the asm with multiple blocks
Matt Johnston <matt@ucc.asn.au>
parents:
908
diff
changeset
|
194 { 1, 3, 14, 3, 2, 26, }, |
e4b75744acab
- Call the asm with multiple blocks
Matt Johnston <matt@ucc.asn.au>
parents:
908
diff
changeset
|
195 6, |
e4b75744acab
- Call the asm with multiple blocks
Matt Johnston <matt@ucc.asn.au>
parents:
908
diff
changeset
|
196 |
e4b75744acab
- Call the asm with multiple blocks
Matt Johnston <matt@ucc.asn.au>
parents:
908
diff
changeset
|
197 &sha1_asm_init, |
e4b75744acab
- Call the asm with multiple blocks
Matt Johnston <matt@ucc.asn.au>
parents:
908
diff
changeset
|
198 &sha1_asm_process, |
e4b75744acab
- Call the asm with multiple blocks
Matt Johnston <matt@ucc.asn.au>
parents:
908
diff
changeset
|
199 &sha1_asm_done, |
e4b75744acab
- Call the asm with multiple blocks
Matt Johnston <matt@ucc.asn.au>
parents:
908
diff
changeset
|
200 &sha1_asm_test, |
e4b75744acab
- Call the asm with multiple blocks
Matt Johnston <matt@ucc.asn.au>
parents:
908
diff
changeset
|
201 NULL |
e4b75744acab
- Call the asm with multiple blocks
Matt Johnston <matt@ucc.asn.au>
parents:
908
diff
changeset
|
202 }; |
e4b75744acab
- Call the asm with multiple blocks
Matt Johnston <matt@ucc.asn.au>
parents:
908
diff
changeset
|
203 |
e4b75744acab
- Call the asm with multiple blocks
Matt Johnston <matt@ucc.asn.au>
parents:
908
diff
changeset
|
204 |
908 | 205 #endif |
206 | |
207 | |
208 | |
209 /* $Source: /cvs/libtom/libtomcrypt/src/hashes/sha1.c,v $ */ | |
210 /* $Revision: 1.8 $ */ | |
211 /* $Date: 2006/11/01 09:28:17 $ */ |