1 /* 2 * Copyright (c) 2020 Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 * 23 */ 24 25 /* 26 * Copyright (c) 2017 Project Nayuki. (MIT License) 27 * https://www.nayuki.io/page/fast-md5-hash-implementation-in-x86-assembly 28 * 29 * Permission is hereby granted, free of charge, to any person obtaining a copy of 30 * this software and associated documentation files (the "Software"), to deal in 31 * the Software without restriction, including without limitation the rights to 32 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 33 * the Software, and to permit persons to whom the Software is furnished to do so, 34 * subject to the following conditions: 35 * - The above copyright notice and this permission notice shall be included in 36 * all copies or substantial portions of the Software. 37 * - The Software is provided "as is", without warranty of any kind, express or 38 * implied, including but not limited to the warranties of merchantability, 39 * fitness for a particular purpose and noninfringement. In no event shall the 40 * authors or copyright holders be liable for any claim, damages or other 41 * liability, whether in an action of contract, tort or otherwise, arising from, 42 * out of or in connection with the Software or the use or other dealings in the 43 * Software. 44 */ 45 46 #include "precompiled.hpp" 47 #include "asm/assembler.hpp" 48 #include "asm/assembler.inline.hpp" 49 #include "runtime/stubRoutines.hpp" 50 #include "macroAssembler_x86.hpp" 51 52 // int com.sun.security.provider.MD5.implCompress0(byte[] b, int ofs) 53 void MacroAssembler::fast_md5(Register buf, Address state, Address ofs, Address limit, bool multi_block) { 54 55 Label start, done_hash, loop0; 56 57 bind(start); 58 59 bind(loop0); 60 61 // Save hash values for addition after rounds 62 movptr(rdi, state); 63 movl(rax, Address(rdi, 0)); 64 movl(rbx, Address(rdi, 4)); 65 movl(rcx, Address(rdi, 8)); 66 movl(rdx, Address(rdi, 12)); 67 68 #define FF(r1, r2, r3, r4, k, s, t) \ 69 movl(rsi, r3); \ 70 addl(r1, Address(buf, k*4)); \ 71 xorl(rsi, r4); \ 72 andl(rsi, r2); \ 73 xorl(rsi, r4); \ 74 leal(r1, Address(r1, rsi, Address::times_1, t)); \ 75 roll(r1, s); \ 76 addl(r1, r2); 77 78 #define GG(r1, r2, r3, r4, k, s, t) \ 79 movl(rsi, r4); \ 80 movl(rdi, r4); \ 81 addl(r1, Address(buf, k*4)); \ 82 notl(rsi); \ 83 andl(rdi, r2); \ 84 andl(rsi, r3); \ 85 orl(rsi, rdi); \ 86 leal(r1, Address(r1, rsi, Address::times_1, t)); \ 87 roll(r1, s); \ 88 addl(r1, r2); 89 90 #define HH(r1, r2, r3, r4, k, s, t) \ 91 movl(rsi, r3); \ 92 addl(r1, Address(buf, k*4)); \ 93 xorl(rsi, r4); \ 94 xorl(rsi, r2); \ 95 leal(r1, Address(r1, rsi, Address::times_1, t)); \ 96 roll(r1, s); \ 97 addl(r1, r2); 98 99 #define II(r1, r2, r3, r4, k, s, t) \ 100 movl(rsi, r4); \ 101 notl(rsi); \ 102 addl(r1, Address(buf, k*4)); \ 103 orl(rsi, r2); \ 104 xorl(rsi, r3); \ 105 leal(r1, Address(r1, rsi, Address::times_1, t)); \ 106 roll(r1, s); \ 107 addl(r1, r2); 108 109 // Round 1 110 FF(rax, rbx, rcx, rdx, 0, 7, 0xd76aa478) 111 FF(rdx, rax, rbx, rcx, 1, 12, 0xe8c7b756) 112 FF(rcx, rdx, rax, rbx, 2, 17, 0x242070db) 113 FF(rbx, rcx, rdx, rax, 3, 22, 0xc1bdceee) 114 FF(rax, rbx, rcx, rdx, 4, 7, 0xf57c0faf) 115 FF(rdx, rax, rbx, rcx, 5, 12, 0x4787c62a) 116 FF(rcx, rdx, rax, rbx, 6, 17, 0xa8304613) 117 FF(rbx, rcx, rdx, rax, 7, 22, 0xfd469501) 118 FF(rax, rbx, rcx, rdx, 8, 7, 0x698098d8) 119 FF(rdx, rax, rbx, rcx, 9, 12, 0x8b44f7af) 120 FF(rcx, rdx, rax, rbx, 10, 17, 0xffff5bb1) 121 FF(rbx, rcx, rdx, rax, 11, 22, 0x895cd7be) 122 FF(rax, rbx, rcx, rdx, 12, 7, 0x6b901122) 123 FF(rdx, rax, rbx, rcx, 13, 12, 0xfd987193) 124 FF(rcx, rdx, rax, rbx, 14, 17, 0xa679438e) 125 FF(rbx, rcx, rdx, rax, 15, 22, 0x49b40821) 126 127 // Round 2 128 GG(rax, rbx, rcx, rdx, 1, 5, 0xf61e2562) 129 GG(rdx, rax, rbx, rcx, 6, 9, 0xc040b340) 130 GG(rcx, rdx, rax, rbx, 11, 14, 0x265e5a51) 131 GG(rbx, rcx, rdx, rax, 0, 20, 0xe9b6c7aa) 132 GG(rax, rbx, rcx, rdx, 5, 5, 0xd62f105d) 133 GG(rdx, rax, rbx, rcx, 10, 9, 0x02441453) 134 GG(rcx, rdx, rax, rbx, 15, 14, 0xd8a1e681) 135 GG(rbx, rcx, rdx, rax, 4, 20, 0xe7d3fbc8) 136 GG(rax, rbx, rcx, rdx, 9, 5, 0x21e1cde6) 137 GG(rdx, rax, rbx, rcx, 14, 9, 0xc33707d6) 138 GG(rcx, rdx, rax, rbx, 3, 14, 0xf4d50d87) 139 GG(rbx, rcx, rdx, rax, 8, 20, 0x455a14ed) 140 GG(rax, rbx, rcx, rdx, 13, 5, 0xa9e3e905) 141 GG(rdx, rax, rbx, rcx, 2, 9, 0xfcefa3f8) 142 GG(rcx, rdx, rax, rbx, 7, 14, 0x676f02d9) 143 GG(rbx, rcx, rdx, rax, 12, 20, 0x8d2a4c8a) 144 145 // Round 3 146 HH(rax, rbx, rcx, rdx, 5, 4, 0xfffa3942) 147 HH(rdx, rax, rbx, rcx, 8, 11, 0x8771f681) 148 HH(rcx, rdx, rax, rbx, 11, 16, 0x6d9d6122) 149 HH(rbx, rcx, rdx, rax, 14, 23, 0xfde5380c) 150 HH(rax, rbx, rcx, rdx, 1, 4, 0xa4beea44) 151 HH(rdx, rax, rbx, rcx, 4, 11, 0x4bdecfa9) 152 HH(rcx, rdx, rax, rbx, 7, 16, 0xf6bb4b60) 153 HH(rbx, rcx, rdx, rax, 10, 23, 0xbebfbc70) 154 HH(rax, rbx, rcx, rdx, 13, 4, 0x289b7ec6) 155 HH(rdx, rax, rbx, rcx, 0, 11, 0xeaa127fa) 156 HH(rcx, rdx, rax, rbx, 3, 16, 0xd4ef3085) 157 HH(rbx, rcx, rdx, rax, 6, 23, 0x04881d05) 158 HH(rax, rbx, rcx, rdx, 9, 4, 0xd9d4d039) 159 HH(rdx, rax, rbx, rcx, 12, 11, 0xe6db99e5) 160 HH(rcx, rdx, rax, rbx, 15, 16, 0x1fa27cf8) 161 HH(rbx, rcx, rdx, rax, 2, 23, 0xc4ac5665) 162 163 // Round 4 164 II(rax, rbx, rcx, rdx, 0, 6, 0xf4292244) 165 II(rdx, rax, rbx, rcx, 7, 10, 0x432aff97) 166 II(rcx, rdx, rax, rbx, 14, 15, 0xab9423a7) 167 II(rbx, rcx, rdx, rax, 5, 21, 0xfc93a039) 168 II(rax, rbx, rcx, rdx, 12, 6, 0x655b59c3) 169 II(rdx, rax, rbx, rcx, 3, 10, 0x8f0ccc92) 170 II(rcx, rdx, rax, rbx, 10, 15, 0xffeff47d) 171 II(rbx, rcx, rdx, rax, 1, 21, 0x85845dd1) 172 II(rax, rbx, rcx, rdx, 8, 6, 0x6fa87e4f) 173 II(rdx, rax, rbx, rcx, 15, 10, 0xfe2ce6e0) 174 II(rcx, rdx, rax, rbx, 6, 15, 0xa3014314) 175 II(rbx, rcx, rdx, rax, 13, 21, 0x4e0811a1) 176 II(rax, rbx, rcx, rdx, 4, 6, 0xf7537e82) 177 II(rdx, rax, rbx, rcx, 11, 10, 0xbd3af235) 178 II(rcx, rdx, rax, rbx, 2, 15, 0x2ad7d2bb) 179 II(rbx, rcx, rdx, rax, 9, 21, 0xeb86d391) 180 181 #undef FF 182 #undef GG 183 #undef HH 184 #undef II 185 186 // write hash values back in the correct order 187 movptr(rdi, state); 188 addl(Address(rdi, 0), rax); 189 addl(Address(rdi, 4), rbx); 190 addl(Address(rdi, 8), rcx); 191 addl(Address(rdi, 12), rdx); 192 193 if (multi_block) { 194 // increment data pointer and loop if more to process 195 addptr(buf, 64); 196 addl(ofs, 64); 197 movl(rsi, ofs); 198 cmpl(rsi, limit); 199 jcc(Assembler::belowEqual, loop0); 200 movptr(rax, rsi); //return ofs 201 } 202 203 bind(done_hash); 204 }