1 /**
2 * SHA-160 in x86-32 asm
3 * 
4 * Copyright:
5 * (C) 1999-2007 Jack Lloyd
6 * (C) 2014-2015 Etienne Cimon
7 *
8 * License:
9 * Botan is released under the Simplified BSD License (see LICENSE.md)
10 */
11 module botan.hash.sha1_x86_32;
12 
13 import botan.constants;
14 static if (BOTAN_HAS_SHA1 && BOTAN_HAS_SHA1_X86_32):
15 
16 import botan.hash.sha160;
17 import botan.utils.asm_x86_32.asm_x86_32;
18 import botan.hash.hash;
19 
20 /**
21 * SHA-160 in x86 assembly
22 */
23 class SHA160_X86_32 : SHA160
24 {
25 public:
26     override HashFunction clone() const { return new SHA160_X86_32; }
27 
28     // Note 81 instead of normal 80: x86-32 asm needs an extra temp
29     this() 
30     {
31         super(81);
32     }
33 
34 protected:
35     /*
36     * SHA-160 Compression Function
37     */
38     override void compressN(const(ubyte)* input, size_t blocks)
39     {
40         foreach (size_t i; 0 .. blocks)
41         {
42             botan_sha160_x86_32_compress(m_digest.ptr, input, m_W.ptr);
43             input += hashBlockSize;
44         }
45     }
46 
47 }
48 
49 private:
50 extern(C)
51 void botan_sha160_x86_32_compress(uint* arg1, const(ubyte)* arg2, uint* arg3) pure
52 {
53     enum PUSHED = 4;
54     enum ASM =
55           START_ASM ~ 
56           "naked;" ~
57           SPILL_REGS() ~ 
58           ASSIGN(EDI, ARG(PUSHED, 2)) ~
59           ASSIGN(EBP, ARG(PUSHED, 3)) ~
60           
61           ZEROIZE(ESI) ~
62           
63           START_LOOP("LOAD_INPUT") ~
64           ADD_IMM(ESI, 4) ~
65           
66           ASSIGN(EAX, ARRAY4(EDI, 0)) ~
67           ASSIGN(EBX, ARRAY4(EDI, 1)) ~
68           ASSIGN(ECX, ARRAY4(EDI, 2)) ~
69           ASSIGN(EDX, ARRAY4(EDI, 3)) ~
70           
71           ADD_IMM(EDI, 16) ~
72           
73           BSWAP(EAX) ~
74           BSWAP(EBX) ~
75           BSWAP(ECX) ~
76           BSWAP(EDX) ~
77           
78           ASSIGN(ARRAY4_INDIRECT(EBP,ESI,-4), EAX) ~
79           ASSIGN(ARRAY4_INDIRECT(EBP,ESI,-3), EBX) ~
80           ASSIGN(ARRAY4_INDIRECT(EBP,ESI,-2), ECX) ~
81           ASSIGN(ARRAY4_INDIRECT(EBP,ESI,-1), EDX) ~
82           LOOP_UNTIL_EQ(ESI, 16, "LOAD_INPUT") ~
83           
84           ADD2_IMM(EDI, EBP, 64) ~
85           
86           START_LOOP("L_SHA_EXPANSION") ~
87           ADD_IMM(ESI, 4) ~
88           
89           ZEROIZE(EAX) ~
90           ASSIGN(EBX, ARRAY4(EDI, -1)) ~
91           ASSIGN(ECX, ARRAY4(EDI, -2)) ~
92           ASSIGN(EDX, ARRAY4(EDI, -3)) ~
93           
94           XOR(EAX, ARRAY4(EDI, -5)) ~
95           XOR(EBX, ARRAY4(EDI, -6)) ~
96           XOR(ECX, ARRAY4(EDI, -7)) ~
97           XOR(EDX, ARRAY4(EDI, -8)) ~
98           
99           XOR(EAX, ARRAY4(EDI, -11)) ~
100           XOR(EBX, ARRAY4(EDI, -12)) ~
101           XOR(ECX, ARRAY4(EDI, -13)) ~
102           XOR(EDX, ARRAY4(EDI, -14)) ~
103           
104           XOR(EAX, ARRAY4(EDI, -13)) ~
105           XOR(EBX, ARRAY4(EDI, -14)) ~
106           XOR(ECX, ARRAY4(EDI, -15)) ~
107           XOR(EDX, ARRAY4(EDI, -16)) ~
108           
109           ROTL_IMM(EDX, 1) ~
110           ROTL_IMM(ECX, 1) ~
111           ROTL_IMM(EBX, 1) ~
112           XOR(EAX, EDX) ~
113           ROTL_IMM(EAX, 1) ~
114           
115           ASSIGN(ARRAY4(EDI, 0), EDX) ~
116           ASSIGN(ARRAY4(EDI, 1), ECX) ~
117           ASSIGN(ARRAY4(EDI, 2), EBX) ~
118           ASSIGN(ARRAY4(EDI, 3), EAX) ~
119           
120           ADD_IMM(EDI, 16) ~
121           LOOP_UNTIL_EQ(ESI, 80, "L_SHA_EXPANSION") ~
122           
123           ASSIGN(EAX, ARG(PUSHED, 1)) ~
124           ASSIGN(EDI, ARRAY4(EAX, 0)) ~
125           ASSIGN(EBX, ARRAY4(EAX, 1)) ~
126           ASSIGN(ECX, ARRAY4(EAX, 2)) ~
127           ASSIGN(EDX, ARRAY4(EAX, 3)) ~
128           ASSIGN(ESI, ARRAY4(EAX, 4)) ~
129           
130           ASSIGN(ARRAY4(EBP, 80), ESP) ~
131           ASSIGN(ESP, EBP) ~
132           
133           /* First Round */
134           F1(EAX, EBX, ECX, EDX, ESI, EDI, 0) ~
135           F1(EDI, EAX, EBX, ECX, EDX, ESI, 1) ~
136           F1(ESI, EDI, EAX, EBX, ECX, EDX, 2) ~
137           F1(EDX, ESI, EDI, EAX, EBX, ECX, 3) ~
138           F1(ECX, EDX, ESI, EDI, EAX, EBX, 4) ~
139           F1(EBX, ECX, EDX, ESI, EDI, EAX, 5) ~
140           F1(EAX, EBX, ECX, EDX, ESI, EDI, 6) ~
141           F1(EDI, EAX, EBX, ECX, EDX, ESI, 7) ~
142           F1(ESI, EDI, EAX, EBX, ECX, EDX, 8) ~
143           F1(EDX, ESI, EDI, EAX, EBX, ECX, 9) ~
144           F1(ECX, EDX, ESI, EDI, EAX, EBX, 10) ~
145           F1(EBX, ECX, EDX, ESI, EDI, EAX, 11) ~
146           F1(EAX, EBX, ECX, EDX, ESI, EDI, 12) ~
147           F1(EDI, EAX, EBX, ECX, EDX, ESI, 13) ~
148           F1(ESI, EDI, EAX, EBX, ECX, EDX, 14) ~
149           F1(EDX, ESI, EDI, EAX, EBX, ECX, 15) ~
150           F1(ECX, EDX, ESI, EDI, EAX, EBX, 16) ~
151           F1(EBX, ECX, EDX, ESI, EDI, EAX, 17) ~
152           F1(EAX, EBX, ECX, EDX, ESI, EDI, 18) ~
153           F1(EDI, EAX, EBX, ECX, EDX, ESI, 19) ~
154           
155           /* Second Round */
156           F2(ESI, EDI, EAX, EBX, ECX, EDX, 20) ~
157           F2(EDX, ESI, EDI, EAX, EBX, ECX, 21) ~
158           F2(ECX, EDX, ESI, EDI, EAX, EBX, 22) ~
159           F2(EBX, ECX, EDX, ESI, EDI, EAX, 23) ~
160           F2(EAX, EBX, ECX, EDX, ESI, EDI, 24) ~
161           F2(EDI, EAX, EBX, ECX, EDX, ESI, 25) ~
162           F2(ESI, EDI, EAX, EBX, ECX, EDX, 26) ~
163           F2(EDX, ESI, EDI, EAX, EBX, ECX, 27) ~
164           F2(ECX, EDX, ESI, EDI, EAX, EBX, 28) ~
165           F2(EBX, ECX, EDX, ESI, EDI, EAX, 29) ~
166           F2(EAX, EBX, ECX, EDX, ESI, EDI, 30) ~
167           F2(EDI, EAX, EBX, ECX, EDX, ESI, 31) ~
168           F2(ESI, EDI, EAX, EBX, ECX, EDX, 32) ~
169           F2(EDX, ESI, EDI, EAX, EBX, ECX, 33) ~
170           F2(ECX, EDX, ESI, EDI, EAX, EBX, 34) ~
171           F2(EBX, ECX, EDX, ESI, EDI, EAX, 35) ~
172           F2(EAX, EBX, ECX, EDX, ESI, EDI, 36) ~
173           F2(EDI, EAX, EBX, ECX, EDX, ESI, 37) ~
174           F2(ESI, EDI, EAX, EBX, ECX, EDX, 38) ~
175           F2(EDX, ESI, EDI, EAX, EBX, ECX, 39) ~
176           
177           /* Third Round */
178           F3(ECX, EDX, ESI, EDI, EAX, EBX, 40) ~
179           F3(EBX, ECX, EDX, ESI, EDI, EAX, 41) ~
180           F3(EAX, EBX, ECX, EDX, ESI, EDI, 42) ~
181           F3(EDI, EAX, EBX, ECX, EDX, ESI, 43) ~
182           F3(ESI, EDI, EAX, EBX, ECX, EDX, 44) ~
183           F3(EDX, ESI, EDI, EAX, EBX, ECX, 45) ~
184           F3(ECX, EDX, ESI, EDI, EAX, EBX, 46) ~
185           F3(EBX, ECX, EDX, ESI, EDI, EAX, 47) ~
186           F3(EAX, EBX, ECX, EDX, ESI, EDI, 48) ~
187           F3(EDI, EAX, EBX, ECX, EDX, ESI, 49) ~
188           F3(ESI, EDI, EAX, EBX, ECX, EDX, 50) ~
189           F3(EDX, ESI, EDI, EAX, EBX, ECX, 51) ~
190           F3(ECX, EDX, ESI, EDI, EAX, EBX, 52) ~
191           F3(EBX, ECX, EDX, ESI, EDI, EAX, 53) ~
192           F3(EAX, EBX, ECX, EDX, ESI, EDI, 54) ~
193           F3(EDI, EAX, EBX, ECX, EDX, ESI, 55) ~
194           F3(ESI, EDI, EAX, EBX, ECX, EDX, 56) ~
195           F3(EDX, ESI, EDI, EAX, EBX, ECX, 57) ~
196           F3(ECX, EDX, ESI, EDI, EAX, EBX, 58) ~
197           F3(EBX, ECX, EDX, ESI, EDI, EAX, 59) ~
198           
199           /* Fourth Round */
200           F4(EAX, EBX, ECX, EDX, ESI, EDI, 60) ~
201           F4(EDI, EAX, EBX, ECX, EDX, ESI, 61) ~
202           F4(ESI, EDI, EAX, EBX, ECX, EDX, 62) ~
203           F4(EDX, ESI, EDI, EAX, EBX, ECX, 63) ~
204           F4(ECX, EDX, ESI, EDI, EAX, EBX, 64) ~
205           F4(EBX, ECX, EDX, ESI, EDI, EAX, 65) ~
206           F4(EAX, EBX, ECX, EDX, ESI, EDI, 66) ~
207           F4(EDI, EAX, EBX, ECX, EDX, ESI, 67) ~
208           F4(ESI, EDI, EAX, EBX, ECX, EDX, 68) ~
209           F4(EDX, ESI, EDI, EAX, EBX, ECX, 69) ~
210           F4(ECX, EDX, ESI, EDI, EAX, EBX, 70) ~
211           F4(EBX, ECX, EDX, ESI, EDI, EAX, 71) ~
212           F4(EAX, EBX, ECX, EDX, ESI, EDI, 72) ~
213           F4(EDI, EAX, EBX, ECX, EDX, ESI, 73) ~
214           F4(ESI, EDI, EAX, EBX, ECX, EDX, 74) ~
215           F4(EDX, ESI, EDI, EAX, EBX, ECX, 75) ~
216           F4(ECX, EDX, ESI, EDI, EAX, EBX, 76) ~
217           F4(EBX, ECX, EDX, ESI, EDI, EAX, 77) ~
218           F4(EAX, EBX, ECX, EDX, ESI, EDI, 78) ~
219           F4(EDI, EAX, EBX, ECX, EDX, ESI, 79) ~
220           
221           ASSIGN(ESP, ARRAY4(ESP, 80)) ~
222           
223           ASSIGN(EBP, ARG(PUSHED, 1)) ~
224           ADD(ARRAY4(EBP, 0), EDX) ~
225           ADD(ARRAY4(EBP, 1), EDI) ~
226           ADD(ARRAY4(EBP, 2), EAX) ~
227           ADD(ARRAY4(EBP, 3), EBX) ~
228           ADD(ARRAY4(EBP, 4), ECX) ~
229 
230           RESTORE_REGS() ~
231           "ret;"~
232           END_ASM;
233     mixin(ASM);
234 }
235 
236 enum MAGIC1 = 0x5A827999;
237 enum MAGIC2 = 0x6ED9EBA1;
238 enum MAGIC3 = 0x8F1BBCDC;
239 enum MAGIC4 = 0xCA62C1D6;
240 
241 enum MSG = ESP;
242 enum T2 = EBP;
243 
244 string F1(string A, string B, string C, string D, string E, string F, ubyte N) 
245 {
246     return  ASSIGN(T2, ARRAY4(MSG, N)) ~
247             ASSIGN(A, F) ~
248             ROTL_IMM(F, 5) ~
249             ADD(F, E) ~
250             ASSIGN(E, C)     ~
251             XOR(E, D) ~
252             ADD3_IMM(F, T2, MAGIC1)     ~
253             AND(E, B) ~
254             XOR(E, D) ~
255             ROTR_IMM(B, 2) ~
256             ADD(E, F);
257 }
258 
259 string F2_4(string A, string B, string C, string D, string E, string F, ubyte N, int MAGIC)
260 {
261     return  ASSIGN(T2, ARRAY4(MSG, N)) ~
262             ASSIGN(A, F)     ~
263             ROTL_IMM(F, 5) ~
264             ADD(F, E) ~
265             ASSIGN(E, B)     ~
266             XOR(E, C) ~
267             ADD3_IMM(F, T2, MAGIC)     ~
268             XOR(E, D) ~
269             ROTR_IMM(B, 2) ~
270             ADD(E, F);
271 }
272 
273 string F3(string A, string B, string C, string D, string E, string F, ubyte N)
274 {
275     return  ASSIGN(T2, ARRAY4(MSG, N)) ~
276             ASSIGN(A, F)     ~
277             ROTL_IMM(F, 5) ~
278             ADD(F, E) ~
279             ASSIGN(E, B)     ~
280             OR(E, C) ~
281             AND(E, D) ~
282             ADD3_IMM(F, T2, MAGIC3)     ~
283             ASSIGN(T2, B) ~
284             AND(T2, C)     ~
285             OR(E, T2) ~
286             ROTR_IMM(B, 2) ~
287             ADD(E, F);
288 }
289 
290 string F2(string A, string B, string C, string D, string E, string F, ubyte MSG2)
291 {
292     return F2_4(A, B, C, D, E, F, MSG2, MAGIC2);
293 }
294 
295 string F4(string A, string B, string C, string D, string E, string F, ubyte MSG2)
296 {
297     return F2_4(A, B, C, D, E, F, MSG2, MAGIC4);
298 }