1/* SPDX-License-Identifier: GPL-2.0-or-later */ 2/* 3 * Fast MD5 implementation for PPC 4 * 5 * Copyright (c) 2015 Markus Stockhausen <stockhausen@collogia.de> 6 */ 7#include <asm/ppc_asm.h> 8#include <asm/asm-offsets.h> 9#include <asm/asm-compat.h> 10 11#define rHP r3 12#define rWP r4 13 14#define rH0 r0 15#define rH1 r6 16#define rH2 r7 17#define rH3 r5 18 19#define rW00 r8 20#define rW01 r9 21#define rW02 r10 22#define rW03 r11 23#define rW04 r12 24#define rW05 r14 25#define rW06 r15 26#define rW07 r16 27#define rW08 r17 28#define rW09 r18 29#define rW10 r19 30#define rW11 r20 31#define rW12 r21 32#define rW13 r22 33#define rW14 r23 34#define rW15 r24 35 36#define rT0 r25 37#define rT1 r26 38 39#define INITIALIZE \ 40 PPC_STLU r1,-INT_FRAME_SIZE(r1); \ 41 SAVE_8GPRS(14, r1); /* push registers onto stack */ \ 42 SAVE_4GPRS(22, r1); \ 43 SAVE_GPR(26, r1) 44 45#define FINALIZE \ 46 REST_8GPRS(14, r1); /* pop registers from stack */ \ 47 REST_4GPRS(22, r1); \ 48 REST_GPR(26, r1); \ 49 addi r1,r1,INT_FRAME_SIZE; 50 51#ifdef __BIG_ENDIAN__ 52#define LOAD_DATA(reg, off) \ 53 lwbrx reg,0,rWP; /* load data */ 54#define INC_PTR \ 55 addi rWP,rWP,4; /* increment per word */ 56#define NEXT_BLOCK /* nothing to do */ 57#else 58#define LOAD_DATA(reg, off) \ 59 lwz reg,off(rWP); /* load data */ 60#define INC_PTR /* nothing to do */ 61#define NEXT_BLOCK \ 62 addi rWP,rWP,64; /* increment per block */ 63#endif 64 65#define R_00_15(a, b, c, d, w0, w1, p, q, off, k0h, k0l, k1h, k1l) \ 66 LOAD_DATA(w0, off) /* W */ \ 67 and rT0,b,c; /* 1: f = b and c */ \ 68 INC_PTR /* ptr++ */ \ 69 andc rT1,d,b; /* 1: f' = ~b and d */ \ 70 LOAD_DATA(w1, off+4) /* W */ \ 71 or rT0,rT0,rT1; /* 1: f = f or f' */ \ 72 addi w0,w0,k0l; /* 1: wk = w + k */ \ 73 add a,a,rT0; /* 1: a = a + f */ \ 74 addis w0,w0,k0h; /* 1: wk = w + k' */ \ 75 addis w1,w1,k1h; /* 2: wk = w + k */ \ 76 add a,a,w0; /* 1: a = a + wk */ \ 77 addi w1,w1,k1l; /* 2: wk = w + k' */ \ 78 rotrwi a,a,p; /* 1: a = a rotl x */ \ 79 add d,d,w1; /* 2: a = a + wk */ \ 80 add a,a,b; /* 1: a = a + b */ \ 81 and rT0,a,b; /* 2: f = b and c */ \ 82 andc rT1,c,a; /* 2: f' = ~b and d */ \ 83 or rT0,rT0,rT1; /* 2: f = f or f' */ \ 84 add d,d,rT0; /* 2: a = a + f */ \ 85 INC_PTR /* ptr++ */ \ 86 rotrwi d,d,q; /* 2: a = a rotl x */ \ 87 add d,d,a; /* 2: a = a + b */ 88 89#define R_16_31(a, b, c, d, w0, w1, p, q, k0h, k0l, k1h, k1l) \ 90 andc rT0,c,d; /* 1: f = c and ~d */ \ 91 and rT1,b,d; /* 1: f' = b and d */ \ 92 addi w0,w0,k0l; /* 1: wk = w + k */ \ 93 or rT0,rT0,rT1; /* 1: f = f or f' */ \ 94 addis w0,w0,k0h; /* 1: wk = w + k' */ \ 95 add a,a,rT0; /* 1: a = a + f */ \ 96 addi w1,w1,k1l; /* 2: wk = w + k */ \ 97 add a,a,w0; /* 1: a = a + wk */ \ 98 addis w1,w1,k1h; /* 2: wk = w + k' */ \ 99 andc rT0,b,c; /* 2: f = c and ~d */ \ 100 rotrwi a,a,p; /* 1: a = a rotl x */ \ 101 add a,a,b; /* 1: a = a + b */ \ 102 add d,d,w1; /* 2: a = a + wk */ \ 103 and rT1,a,c; /* 2: f' = b and d */ \ 104 or rT0,rT0,rT1; /* 2: f = f or f' */ \ 105 add d,d,rT0; /* 2: a = a + f */ \ 106 rotrwi d,d,q; /* 2: a = a rotl x */ \ 107 add d,d,a; /* 2: a = a +b */ 108 109#define R_32_47(a, b, c, d, w0, w1, p, q, k0h, k0l, k1h, k1l) \ 110 xor rT0,b,c; /* 1: f' = b xor c */ \ 111 addi w0,w0,k0l; /* 1: wk = w + k */ \ 112 xor rT1,rT0,d; /* 1: f = f xor f' */ \ 113 addis w0,w0,k0h; /* 1: wk = w + k' */ \ 114 add a,a,rT1; /* 1: a = a + f */ \ 115 addi w1,w1,k1l; /* 2: wk = w + k */ \ 116 add a,a,w0; /* 1: a = a + wk */ \ 117 addis w1,w1,k1h; /* 2: wk = w + k' */ \ 118 rotrwi a,a,p; /* 1: a = a rotl x */ \ 119 add d,d,w1; /* 2: a = a + wk */ \ 120 add a,a,b; /* 1: a = a + b */ \ 121 xor rT1,rT0,a; /* 2: f = b xor f' */ \ 122 add d,d,rT1; /* 2: a = a + f */ \ 123 rotrwi d,d,q; /* 2: a = a rotl x */ \ 124 add d,d,a; /* 2: a = a + b */ 125 126#define R_48_63(a, b, c, d, w0, w1, p, q, k0h, k0l, k1h, k1l) \ 127 addi w0,w0,k0l; /* 1: w = w + k */ \ 128 orc rT0,b,d; /* 1: f = b or ~d */ \ 129 addis w0,w0,k0h; /* 1: w = w + k' */ \ 130 xor rT0,rT0,c; /* 1: f = f xor c */ \ 131 add a,a,w0; /* 1: a = a + wk */ \ 132 addi w1,w1,k1l; /* 2: w = w + k */ \ 133 add a,a,rT0; /* 1: a = a + f */ \ 134 addis w1,w1,k1h; /* 2: w = w + k' */ \ 135 rotrwi a,a,p; /* 1: a = a rotl x */ \ 136 add a,a,b; /* 1: a = a + b */ \ 137 orc rT0,a,c; /* 2: f = b or ~d */ \ 138 add d,d,w1; /* 2: a = a + wk */ \ 139 xor rT0,rT0,b; /* 2: f = f xor c */ \ 140 add d,d,rT0; /* 2: a = a + f */ \ 141 rotrwi d,d,q; /* 2: a = a rotl x */ \ 142 add d,d,a; /* 2: a = a + b */ 143 144_GLOBAL(ppc_md5_transform) 145 INITIALIZE 146 147 mtctr r5 148 lwz rH0,0(rHP) 149 lwz rH1,4(rHP) 150 lwz rH2,8(rHP) 151 lwz rH3,12(rHP) 152 153ppc_md5_main: 154 R_00_15(rH0, rH1, rH2, rH3, rW00, rW01, 25, 20, 0, 155 0xd76b, -23432, 0xe8c8, -18602) 156 R_00_15(rH2, rH3, rH0, rH1, rW02, rW03, 15, 10, 8, 157 0x2420, 0x70db, 0xc1be, -12562) 158 R_00_15(rH0, rH1, rH2, rH3, rW04, rW05, 25, 20, 16, 159 0xf57c, 0x0faf, 0x4788, -14806) 160 R_00_15(rH2, rH3, rH0, rH1, rW06, rW07, 15, 10, 24, 161 0xa830, 0x4613, 0xfd47, -27391) 162 R_00_15(rH0, rH1, rH2, rH3, rW08, rW09, 25, 20, 32, 163 0x6981, -26408, 0x8b45, -2129) 164 R_00_15(rH2, rH3, rH0, rH1, rW10, rW11, 15, 10, 40, 165 0xffff, 0x5bb1, 0x895d, -10306) 166 R_00_15(rH0, rH1, rH2, rH3, rW12, rW13, 25, 20, 48, 167 0x6b90, 0x1122, 0xfd98, 0x7193) 168 R_00_15(rH2, rH3, rH0, rH1, rW14, rW15, 15, 10, 56, 169 0xa679, 0x438e, 0x49b4, 0x0821) 170 171 R_16_31(rH0, rH1, rH2, rH3, rW01, rW06, 27, 23, 172 0x0d56, 0x6e0c, 0x1810, 0x6d2d) 173 R_16_31(rH2, rH3, rH0, rH1, rW11, rW00, 18, 12, 174 0x9d02, -32109, 0x124c, 0x2332) 175 R_16_31(rH0, rH1, rH2, rH3, rW05, rW10, 27, 23, 176 0x8ea7, 0x4a33, 0x0245, -18270) 177 R_16_31(rH2, rH3, rH0, rH1, rW15, rW04, 18, 12, 178 0x8eee, -8608, 0xf258, -5095) 179 R_16_31(rH0, rH1, rH2, rH3, rW09, rW14, 27, 23, 180 0x969d, -10697, 0x1cbe, -15288) 181 R_16_31(rH2, rH3, rH0, rH1, rW03, rW08, 18, 12, 182 0x3317, 0x3e99, 0xdbd9, 0x7c15) 183 R_16_31(rH0, rH1, rH2, rH3, rW13, rW02, 27, 23, 184 0xac4b, 0x7772, 0xd8cf, 0x331d) 185 R_16_31(rH2, rH3, rH0, rH1, rW07, rW12, 18, 12, 186 0x6a28, 0x6dd8, 0x219a, 0x3b68) 187 188 R_32_47(rH0, rH1, rH2, rH3, rW05, rW08, 28, 21, 189 0x29cb, 0x28e5, 0x4218, -7788) 190 R_32_47(rH2, rH3, rH0, rH1, rW11, rW14, 16, 9, 191 0x473f, 0x06d1, 0x3aae, 0x3036) 192 R_32_47(rH0, rH1, rH2, rH3, rW01, rW04, 28, 21, 193 0xaea1, -15134, 0x640b, -11295) 194 R_32_47(rH2, rH3, rH0, rH1, rW07, rW10, 16, 9, 195 0x8f4c, 0x4887, 0xbc7c, -22499) 196 R_32_47(rH0, rH1, rH2, rH3, rW13, rW00, 28, 21, 197 0x7eb8, -27199, 0x00ea, 0x6050) 198 R_32_47(rH2, rH3, rH0, rH1, rW03, rW06, 16, 9, 199 0xe01a, 0x22fe, 0x4447, 0x69c5) 200 R_32_47(rH0, rH1, rH2, rH3, rW09, rW12, 28, 21, 201 0xb7f3, 0x0253, 0x59b1, 0x4d5b) 202 R_32_47(rH2, rH3, rH0, rH1, rW15, rW02, 16, 9, 203 0x4701, -27017, 0xc7bd, -19859) 204 205 R_48_63(rH0, rH1, rH2, rH3, rW00, rW07, 26, 22, 206 0x0988, -1462, 0x4c70, -19401) 207 R_48_63(rH2, rH3, rH0, rH1, rW14, rW05, 17, 11, 208 0xadaf, -5221, 0xfc99, 0x66f7) 209 R_48_63(rH0, rH1, rH2, rH3, rW12, rW03, 26, 22, 210 0x7e80, -16418, 0xba1e, -25587) 211 R_48_63(rH2, rH3, rH0, rH1, rW10, rW01, 17, 11, 212 0x4130, 0x380d, 0xe0c5, 0x738d) 213 lwz rW00,0(rHP) 214 R_48_63(rH0, rH1, rH2, rH3, rW08, rW15, 26, 22, 215 0xe837, -30770, 0xde8a, 0x69e8) 216 lwz rW14,4(rHP) 217 R_48_63(rH2, rH3, rH0, rH1, rW06, rW13, 17, 11, 218 0x9e79, 0x260f, 0x256d, -27941) 219 lwz rW12,8(rHP) 220 R_48_63(rH0, rH1, rH2, rH3, rW04, rW11, 26, 22, 221 0xab75, -20775, 0x4f9e, -28397) 222 lwz rW10,12(rHP) 223 R_48_63(rH2, rH3, rH0, rH1, rW02, rW09, 17, 11, 224 0x662b, 0x7c56, 0x11b2, 0x0358) 225 226 add rH0,rH0,rW00 227 stw rH0,0(rHP) 228 add rH1,rH1,rW14 229 stw rH1,4(rHP) 230 add rH2,rH2,rW12 231 stw rH2,8(rHP) 232 add rH3,rH3,rW10 233 stw rH3,12(rHP) 234 NEXT_BLOCK 235 236 bdnz ppc_md5_main 237 238 FINALIZE 239 blr 240