1 /** 2 * SHA-160 (x86-64) 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_64; 12 13 import botan.constants; 14 static if (BOTAN_HAS_SHA1 && BOTAN_HAS_SHA1_X86_64): 15 16 import botan.utils.asm_x86_64.asm_x86_64; 17 import botan.hash.sha160; 18 import botan.hash.hash; 19 20 /** 21 * SHA-160 in x86-64 assembly 22 */ 23 class SHA160_X86_64 : SHA160 24 { 25 public: 26 override HashFunction clone() const { return new SHA160_X86_64; } 27 28 protected: 29 /* 30 * SHA-160 Compression Function 31 */ 32 override void compressN(const(ubyte)* input, size_t blocks) 33 { 34 foreach (size_t i; 0 .. blocks) 35 { 36 botan_sha160_x86_64_compress(m_digest.ptr, input, m_W.ptr); 37 input += hashBlockSize; 38 } 39 } 40 } 41 42 private: 43 pure: 44 45 enum DIGEST_ARR = "RDI"; 46 enum INPUT = "RSI"; 47 enum W = "RDX"; 48 enum LOOP_CTR = "EAX"; 49 50 enum A = "R8D"; 51 enum B = "R9D"; 52 enum C = "R10D"; 53 enum D = "R11D"; 54 enum E = "ECX"; 55 56 /* 57 * Using negative values for SHA-1 constants > 2^31 to work around 58 * a bug in binutils not accepting large lea displacements. 59 * -0x70E44324 == 0x8F1BBCDC 60 * -0x359D3E2A == 0xCA62C1D6 61 */ 62 enum MAGIC1 = 0x5A827999; 63 enum MAGIC2 = 0x6ED9EBA1; 64 enum MAGIC3 = -0x70E44324; 65 enum MAGIC4 = -0x359D3E2A; 66 67 enum T = "ESI"; 68 enum T2 = "EAX"; 69 70 extern(C) 71 void botan_sha160_x86_64_compress(uint* arg1, const(ubyte)* arg2, uint* arg3) 72 { 73 /* defined later 74 enum A = "R8D"; 75 enum B = "R9D"; 76 enum C = "R10D"; 77 enum D = "R11D"; 78 enum E = "ECX"; 79 */ 80 enum ASM = 81 START_ASM ~ 82 "mov " ~ DIGEST_ARR ~ ", arg1;" ~ 83 "mov " ~ INPUT ~ ", arg2;" ~ 84 "mov " ~ W ~ ", arg3;" ~ 85 ZEROIZE(LOOP_CTR) ~ 86 ALIGN ~ `; 87 LOOP_LOAD_INPUT: 88 add EAX, 8; 89 90 mov ` ~ R8 ~ `, ` ~ ARRAY8(INPUT, 0) ~ `; 91 mov ` ~ R9 ~ `, ` ~ ARRAY8(INPUT, 1) ~ `; 92 mov ` ~ R10 ~ `, ` ~ ARRAY8(INPUT, 2) ~ `; 93 mov ` ~ R11 ~ `, ` ~ ARRAY8(INPUT, 3) ~ `; 94 95 bswap ` ~ R8 ~ `; 96 bswap ` ~ R9 ~ `; 97 bswap ` ~ R10 ~ `; 98 bswap ` ~ R11 ~ `; 99 100 rol ` ~ R8 ~ `, 32; 101 rol ` ~ R9 ~ `, 32; 102 rol ` ~ R10 ~ `, 32; 103 rol ` ~ R11 ~ `, 32; 104 105 mov ` ~ ARRAY8(W, 0) ~ `, ` ~ R8 ~ `; 106 mov ` ~ ARRAY8(W, 1) ~ `, ` ~ R9 ~ `; 107 mov ` ~ ARRAY8(W, 2) ~ `, ` ~ R10 ~ `; 108 mov ` ~ ARRAY8(W, 3) ~ `, ` ~ R11 ~ `; 109 110 add ` ~ W ~ `, 32; 111 add ` ~ INPUT ~ `, 32; 112 113 cmp ` ~ LOOP_CTR ~ `, ` ~ IMM(16) ~ `; 114 jne LOOP_LOAD_INPUT;` ~ 115 116 ALIGN ~ `; 117 LOOP_EXPANSION: 118 add ` ~ LOOP_CTR ~ `, 4; 119 ` ~ 120 121 ZEROIZE(A) ~ 122 ASSIGN(B, ARRAY4(W, -1)) ~ 123 ASSIGN(C, ARRAY4(W, -2)) ~ 124 ASSIGN(D, ARRAY4(W, -3)) ~ 125 126 XOR(A, ARRAY4(W, -5)) ~ 127 XOR(B, ARRAY4(W, -6)) ~ 128 XOR(C, ARRAY4(W, -7)) ~ 129 XOR(D, ARRAY4(W, -8)) ~ 130 131 XOR(A, ARRAY4(W, -11)) ~ 132 XOR(B, ARRAY4(W, -12)) ~ 133 XOR(C, ARRAY4(W, -13)) ~ 134 XOR(D, ARRAY4(W, -14)) ~ 135 136 XOR(A, ARRAY4(W, -13)) ~ 137 XOR(B, ARRAY4(W, -14)) ~ 138 XOR(C, ARRAY4(W, -15)) ~ 139 XOR(D, ARRAY4(W, -16)) ~ 140 141 ROTL_IMM(D, 1) ~ 142 ROTL_IMM(C, 1) ~ 143 ROTL_IMM(B, 1) ~ 144 XOR(A, D) ~ 145 ROTL_IMM(A, 1) ~ 146 147 ASSIGN(ARRAY4(W, 0), D) ~ 148 ASSIGN(ARRAY4(W, 1), C) ~ 149 ASSIGN(ARRAY4(W, 2), B) ~ 150 ASSIGN(ARRAY4(W, 3), A) ~ 151 152 `add ` ~ W ~ `, 16; 153 cmp ` ~ LOOP_CTR ~ `, ` ~ IMM(80) ~ `; 154 jne LOOP_EXPANSION; 155 156 sub ` ~ W ~ `, 320;` ~ 157 158 159 160 ASSIGN(T, ARRAY4(DIGEST_ARR, 0)) ~ 161 ASSIGN(B, ARRAY4(DIGEST_ARR, 1)) ~ 162 ASSIGN(C, ARRAY4(DIGEST_ARR, 2)) ~ 163 ASSIGN(D, ARRAY4(DIGEST_ARR, 3)) ~ 164 ASSIGN(E, ARRAY4(DIGEST_ARR, 4)) ~ 165 166 /* First Round */ 167 F1(A, B, C, D, E, T, 0) ~ 168 F1(T, A, B, C, D, E, 1) ~ 169 F1(E, T, A, B, C, D, 2) ~ 170 F1(D, E, T, A, B, C, 3) ~ 171 F1(C, D, E, T, A, B, 4) ~ 172 F1(B, C, D, E, T, A, 5) ~ 173 F1(A, B, C, D, E, T, 6) ~ 174 F1(T, A, B, C, D, E, 7) ~ 175 F1(E, T, A, B, C, D, 8) ~ 176 F1(D, E, T, A, B, C, 9) ~ 177 F1(C, D, E, T, A, B, 10) ~ 178 F1(B, C, D, E, T, A, 11) ~ 179 F1(A, B, C, D, E, T, 12) ~ 180 F1(T, A, B, C, D, E, 13) ~ 181 F1(E, T, A, B, C, D, 14) ~ 182 F1(D, E, T, A, B, C, 15) ~ 183 F1(C, D, E, T, A, B, 16) ~ 184 F1(B, C, D, E, T, A, 17) ~ 185 F1(A, B, C, D, E, T, 18) ~ 186 F1(T, A, B, C, D, E, 19) ~ 187 188 /* Second Round */ 189 F2(E, T, A, B, C, D, 20) ~ 190 F2(D, E, T, A, B, C, 21) ~ 191 F2(C, D, E, T, A, B, 22) ~ 192 F2(B, C, D, E, T, A, 23) ~ 193 F2(A, B, C, D, E, T, 24) ~ 194 F2(T, A, B, C, D, E, 25) ~ 195 F2(E, T, A, B, C, D, 26) ~ 196 F2(D, E, T, A, B, C, 27) ~ 197 F2(C, D, E, T, A, B, 28) ~ 198 F2(B, C, D, E, T, A, 29 ) ~ 199 F2(A, B, C, D, E, T, 30 ) ~ 200 F2(T, A, B, C, D, E, 31 ) ~ 201 F2(E, T, A, B, C, D, 32 ) ~ 202 F2(D, E, T, A, B, C, 33 ) ~ 203 F2(C, D, E, T, A, B, 34 ) ~ 204 F2(B, C, D, E, T, A, 35 ) ~ 205 F2(A, B, C, D, E, T, 36 ) ~ 206 F2(T, A, B, C, D, E, 37 ) ~ 207 F2(E, T, A, B, C, D, 38 ) ~ 208 F2(D, E, T, A, B, C, 39 ) ~ 209 210 /* Third Round */ 211 F3(C, D, E, T, A, B, 40 ) ~ 212 F3(B, C, D, E, T, A, 41 ) ~ 213 F3(A, B, C, D, E, T, 42 ) ~ 214 F3(T, A, B, C, D, E, 43 ) ~ 215 F3(E, T, A, B, C, D, 44 ) ~ 216 F3(D, E, T, A, B, C, 45 ) ~ 217 F3(C, D, E, T, A, B, 46 ) ~ 218 F3(B, C, D, E, T, A, 47 ) ~ 219 F3(A, B, C, D, E, T, 48 ) ~ 220 F3(T, A, B, C, D, E, 49 ) ~ 221 F3(E, T, A, B, C, D, 50 ) ~ 222 F3(D, E, T, A, B, C, 51 ) ~ 223 F3(C, D, E, T, A, B, 52 ) ~ 224 F3(B, C, D, E, T, A, 53 ) ~ 225 F3(A, B, C, D, E, T, 54 ) ~ 226 F3(T, A, B, C, D, E, 55 ) ~ 227 F3(E, T, A, B, C, D, 56 ) ~ 228 F3(D, E, T, A, B, C, 57 ) ~ 229 F3(C, D, E, T, A, B, 58 ) ~ 230 F3(B, C, D, E, T, A, 59 ) ~ 231 232 /* Fourth Round */ 233 F4(A, B, C, D, E, T, 60 ) ~ 234 F4(T, A, B, C, D, E, 61 ) ~ 235 F4(E, T, A, B, C, D, 62 ) ~ 236 F4(D, E, T, A, B, C, 63 ) ~ 237 F4(C, D, E, T, A, B, 64 ) ~ 238 F4(B, C, D, E, T, A, 65 ) ~ 239 F4(A, B, C, D, E, T, 66 ) ~ 240 F4(T, A, B, C, D, E, 67 ) ~ 241 F4(E, T, A, B, C, D, 68 ) ~ 242 F4(D, E, T, A, B, C, 69 ) ~ 243 F4(C, D, E, T, A, B, 70 ) ~ 244 F4(B, C, D, E, T, A, 71 ) ~ 245 F4(A, B, C, D, E, T, 72 ) ~ 246 F4(T, A, B, C, D, E, 73 ) ~ 247 F4(E, T, A, B, C, D, 74 ) ~ 248 F4(D, E, T, A, B, C, 75 ) ~ 249 F4(C, D, E, T, A, B, 76 ) ~ 250 F4(B, C, D, E, T, A, 77 ) ~ 251 F4(A, B, C, D, E, T, 78 ) ~ 252 F4(T, A, B, C, D, E, 79 ) ~ 253 254 ADD(ARRAY4(DIGEST_ARR, 0), D) ~ 255 ADD(ARRAY4(DIGEST_ARR, 1), T) ~ 256 ADD(ARRAY4(DIGEST_ARR, 2), A) ~ 257 ADD(ARRAY4(DIGEST_ARR, 3), B) ~ 258 ADD(ARRAY4(DIGEST_ARR, 4), C) ~ 259 END_ASM; 260 261 262 mixin(ASM); 263 264 265 } 266 267 268 string F1(string A, string B, string C, string D, string E, string F, ubyte N) 269 { 270 return ASSIGN(T2, ARRAY4(W, N)) ~ 271 ASSIGN(A, F) ~ 272 ROTL_IMM(F, 5) ~ 273 ADD(F, E) ~ 274 ASSIGN(E, C) ~ 275 XOR(E, D) ~ 276 ADD3_IMM(F, T2, MAGIC1) ~ 277 AND(E, B) ~ 278 XOR(E, D) ~ 279 ROTR_IMM(B, 2) ~ 280 ADD(E, F); 281 } 282 283 string F2_4(string A, string B, string C, string D, string E, string F, ubyte N, int MAGIC) 284 { 285 return ASSIGN(T2, ARRAY4(W, N)) ~ 286 ASSIGN(A, F) ~ 287 ROTL_IMM(F, 5) ~ 288 ADD(F, E) ~ 289 ASSIGN(E, B) ~ 290 XOR(E, C) ~ 291 ADD3_IMM(F, T2, MAGIC) ~ 292 XOR(E, D) ~ 293 ROTR_IMM(B, 2) ~ 294 ADD(E, F); 295 } 296 297 string F3(string A, string B, string C, string D, string E, string F, ubyte N) 298 { 299 return ASSIGN(T2, ARRAY4(W, N)) ~ 300 ASSIGN(A, F) ~ 301 ROTL_IMM(F, 5) ~ 302 ADD(F, E) ~ 303 ASSIGN(E, B) ~ 304 OR(E, C) ~ 305 AND(E, D) ~ 306 ADD3_IMM(F, T2, MAGIC3) ~ 307 ASSIGN(T2, B) ~ 308 AND(T2, C) ~ 309 OR(E, T2) ~ 310 ROTR_IMM(B, 2) ~ 311 ADD(E, F); 312 } 313 314 string F2(string A, string B, string C, string D, string E, string F, ubyte W2) 315 { 316 return F2_4(A, B, C, D, E, F, W2, MAGIC2); 317 } 318 319 string F4(string A, string B, string C, string D, string E, string F, ubyte W2) 320 { 321 return F2_4(A, B, C, D, E, F, W2, MAGIC4); 322 }