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 }