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