1 /** 2 * MD5 (x86-32) 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.md5_x86_32; 12 13 import botan.constants; 14 static if (BOTAN_HAS_MD5_X86_32): 15 16 import botan.hash.md5; 17 import botan.hash.hash; 18 import botan.utils.asm_x86_32.asm_x86_32; 19 20 /** 21 * MD5 in x86 assembly 22 */ 23 final class MD5_X86_32 : MD5 24 { 25 public: 26 override HashFunction clone() const { return new MD5_X86_32; } 27 28 protected: 29 override void compressN(const(ubyte)* input, size_t blocks) 30 { 31 foreach (size_t i; 0 .. blocks) 32 { 33 botan_md5_x86_32_compress(m_digest.ptr, input, m_M.ptr); 34 input += hashBlockSize; 35 } 36 } 37 38 } 39 40 extern(C) 41 void botan_md5_x86_32_compress(uint* digest, const(ubyte)* input, uint* M) pure 42 { 43 enum PUSHED = 4; 44 mixin(START_ASM ~ 45 "naked;\n" ~ 46 SPILL_REGS() ~ 47 ASSIGN(EBP, ARG(PUSHED, 2)) ~ /* input block */ 48 ASSIGN(EDI, ARG(PUSHED, 3)) ~ /* expanded words */ 49 50 ZEROIZE(ESI) ~ 51 52 START_LOOP("LOAD_INPUT") ~ 53 ADD_IMM(ESI, 4) ~ 54 55 ASSIGN(EAX, ARRAY4(EBP, 0)) ~ 56 ASSIGN(EBX, ARRAY4(EBP, 1)) ~ 57 ASSIGN(ECX, ARRAY4(EBP, 2)) ~ 58 ASSIGN(EDX, ARRAY4(EBP, 3)) ~ 59 60 ADD_IMM(EBP, 16) ~ 61 62 ASSIGN(ARRAY4_INDIRECT(EDI,ESI,-4), EAX) ~ 63 ASSIGN(ARRAY4_INDIRECT(EDI,ESI,-3), EBX) ~ 64 ASSIGN(ARRAY4_INDIRECT(EDI,ESI,-2), ECX) ~ 65 ASSIGN(ARRAY4_INDIRECT(EDI,ESI,-1), EDX) ~ 66 LOOP_UNTIL_EQ(ESI, 16, "LOAD_INPUT") ~ 67 68 ASSIGN(EBP, ARG(PUSHED, 1)) ~ 69 ASSIGN(EAX, ARRAY4(EBP, 0)) ~ 70 ASSIGN(EBX, ARRAY4(EBP, 1)) ~ 71 ASSIGN(ECX, ARRAY4(EBP, 2)) ~ 72 ASSIGN(EDX, ARRAY4(EBP, 3)) ~ 73 74 FF(EAX,EBX,ECX,EDX, 0, 7,0xD76AA478) ~ 75 FF(EDX,EAX,EBX,ECX, 1,12,0xE8C7B756) ~ 76 FF(ECX,EDX,EAX,EBX, 2,17,0x242070DB) ~ 77 FF(EBX,ECX,EDX,EAX, 3,22,0xC1BDCEEE) ~ 78 FF(EAX,EBX,ECX,EDX, 4, 7,0xF57C0FAF) ~ 79 FF(EDX,EAX,EBX,ECX, 5,12,0x4787C62A) ~ 80 FF(ECX,EDX,EAX,EBX, 6,17,0xA8304613) ~ 81 FF(EBX,ECX,EDX,EAX, 7,22,0xFD469501) ~ 82 FF(EAX,EBX,ECX,EDX, 8, 7,0x698098D8) ~ 83 FF(EDX,EAX,EBX,ECX, 9,12,0x8B44F7AF) ~ 84 FF(ECX,EDX,EAX,EBX,10,17,0xFFFF5BB1) ~ 85 FF(EBX,ECX,EDX,EAX,11,22,0x895CD7BE) ~ 86 FF(EAX,EBX,ECX,EDX,12, 7,0x6B901122) ~ 87 FF(EDX,EAX,EBX,ECX,13,12,0xFD987193) ~ 88 FF(ECX,EDX,EAX,EBX,14,17,0xA679438E) ~ 89 FF(EBX,ECX,EDX,EAX,15,22,0x49B40821) ~ 90 91 GG(EAX,EBX,ECX,EDX, 1, 5,0xF61E2562) ~ 92 GG(EDX,EAX,EBX,ECX, 6, 9,0xC040B340) ~ 93 GG(ECX,EDX,EAX,EBX,11,14,0x265E5A51) ~ 94 GG(EBX,ECX,EDX,EAX, 0,20,0xE9B6C7AA) ~ 95 GG(EAX,EBX,ECX,EDX, 5, 5,0xD62F105D) ~ 96 GG(EDX,EAX,EBX,ECX,10, 9,0x02441453) ~ 97 GG(ECX,EDX,EAX,EBX,15,14,0xD8A1E681) ~ 98 GG(EBX,ECX,EDX,EAX, 4,20,0xE7D3FBC8) ~ 99 GG(EAX,EBX,ECX,EDX, 9, 5,0x21E1CDE6) ~ 100 GG(EDX,EAX,EBX,ECX,14, 9,0xC33707D6) ~ 101 GG(ECX,EDX,EAX,EBX, 3,14,0xF4D50D87) ~ 102 GG(EBX,ECX,EDX,EAX, 8,20,0x455A14ED) ~ 103 GG(EAX,EBX,ECX,EDX,13, 5,0xA9E3E905) ~ 104 GG(EDX,EAX,EBX,ECX, 2, 9,0xFCEFA3F8) ~ 105 GG(ECX,EDX,EAX,EBX, 7,14,0x676F02D9) ~ 106 GG(EBX,ECX,EDX,EAX,12,20,0x8D2A4C8A) ~ 107 108 HH(EAX,EBX,ECX,EDX, 5, 4,0xFFFA3942) ~ 109 HH(EDX,EAX,EBX,ECX, 8,11,0x8771F681) ~ 110 HH(ECX,EDX,EAX,EBX,11,16,0x6D9D6122) ~ 111 HH(EBX,ECX,EDX,EAX,14,23,0xFDE5380C) ~ 112 HH(EAX,EBX,ECX,EDX, 1, 4,0xA4BEEA44) ~ 113 HH(EDX,EAX,EBX,ECX, 4,11,0x4BDECFA9) ~ 114 HH(ECX,EDX,EAX,EBX, 7,16,0xF6BB4B60) ~ 115 HH(EBX,ECX,EDX,EAX,10,23,0xBEBFBC70) ~ 116 HH(EAX,EBX,ECX,EDX,13, 4,0x289B7EC6) ~ 117 HH(EDX,EAX,EBX,ECX, 0,11,0xEAA127FA) ~ 118 HH(ECX,EDX,EAX,EBX, 3,16,0xD4EF3085) ~ 119 HH(EBX,ECX,EDX,EAX, 6,23,0x04881D05) ~ 120 HH(EAX,EBX,ECX,EDX, 9, 4,0xD9D4D039) ~ 121 HH(EDX,EAX,EBX,ECX,12,11,0xE6DB99E5) ~ 122 HH(ECX,EDX,EAX,EBX,15,16,0x1FA27CF8) ~ 123 HH(EBX,ECX,EDX,EAX, 2,23,0xC4AC5665) ~ 124 125 II(EAX,EBX,ECX,EDX, 0, 6,0xF4292244) ~ 126 II(EDX,EAX,EBX,ECX, 7,10,0x432AFF97) ~ 127 II(ECX,EDX,EAX,EBX,14,15,0xAB9423A7) ~ 128 II(EBX,ECX,EDX,EAX, 5,21,0xFC93A039) ~ 129 II(EAX,EBX,ECX,EDX,12, 6,0x655B59C3) ~ 130 II(EDX,EAX,EBX,ECX, 3,10,0x8F0CCC92) ~ 131 II(ECX,EDX,EAX,EBX,10,15,0xFFEFF47D) ~ 132 II(EBX,ECX,EDX,EAX, 1,21,0x85845DD1) ~ 133 II(EAX,EBX,ECX,EDX, 8, 6,0x6FA87E4F) ~ 134 II(EDX,EAX,EBX,ECX,15,10,0xFE2CE6E0) ~ 135 II(ECX,EDX,EAX,EBX, 6,15,0xA3014314) ~ 136 II(EBX,ECX,EDX,EAX,13,21,0x4E0811A1) ~ 137 II(EAX,EBX,ECX,EDX, 4, 6,0xF7537E82) ~ 138 II(EDX,EAX,EBX,ECX,11,10,0xBD3AF235) ~ 139 II(ECX,EDX,EAX,EBX, 2,15,0x2AD7D2BB) ~ 140 II(EBX,ECX,EDX,EAX, 9,21,0xEB86D391) ~ 141 142 ASSIGN(EBP, ARG(PUSHED, 1)) ~ 143 ADD(ARRAY4(EBP, 0), EAX) ~ 144 ADD(ARRAY4(EBP, 1), EBX) ~ 145 ADD(ARRAY4(EBP, 2), ECX) ~ 146 ADD(ARRAY4(EBP, 3), EDX) ~ 147 148 RESTORE_REGS() ~ 149 "ret;\n" ~ 150 END_ASM); 151 152 } 153 154 enum MSG = EDI; 155 enum T1 = ESI; 156 enum T2 = EBP; 157 158 string FF(string A, string B, string C, string D, ubyte N, ubyte S, int MAGIC) { 159 return ASSIGN(T1, ARRAY4(MSG, N)) ~ 160 ASSIGN(T2, C) ~ 161 XOR(T2, D) ~ 162 AND(T2, B) ~ 163 XOR(T2, D) ~ 164 ADD3_IMM(A, T1, MAGIC) ~ 165 ADD(A, T2) ~ 166 ROTL_IMM(A, S) ~ 167 ADD(A, B); 168 } 169 170 string GG(string A, string B, string C, string D, ubyte N, ubyte S, int MAGIC) 171 { 172 return ASSIGN(T1, ARRAY4(MSG, N)) ~ 173 ASSIGN(T2, B) ~ 174 XOR(T2, C) ~ 175 AND(T2, D) ~ 176 XOR(T2, C) ~ 177 ADD3_IMM(A, T1, MAGIC) ~ 178 ADD(A, T2) ~ 179 ROTL_IMM(A, S) ~ 180 ADD(A, B); 181 } 182 183 string HH(string A, string B, string C, string D, ubyte N, ubyte S, int MAGIC) 184 { 185 return ASSIGN(T1, ARRAY4(MSG, N)) ~ 186 ASSIGN(T2, B) ~ 187 XOR(T2, C) ~ 188 XOR(T2, D) ~ 189 ADD3_IMM(A, T1, MAGIC) ~ 190 ADD(A, T2) ~ 191 ROTL_IMM(A, S) ~ 192 ADD(A, B); 193 } 194 195 string II(string A, string B, string C, string D, ubyte N, ubyte S, int MAGIC) 196 { 197 return ASSIGN(T1, ARRAY4(MSG, N)) ~ 198 ASSIGN(T2, D) ~ 199 NOT(T2) ~ 200 OR(T2, B) ~ 201 XOR(T2, C) ~ 202 ADD3_IMM(A, T1, MAGIC) ~ 203 ADD(A, T2) ~ 204 ROTL_IMM(A, S) ~ 205 ADD(A, B); 206 }