1/*
2 * SHA-1 implementation for PowerPC.
3 *
4 * Copyright (C) 2005 Paul Mackerras <paulus@samba.org>
5 */
6
7#include <asm/ppc_asm.h>
8#include <asm/asm-offsets.h>
9
10/*
11 * We roll the registers for T, A, B, C, D, E around on each
12 * iteration; T on iteration t is A on iteration t+1, and so on.
13 * We use registers 7 - 12 for this.
14 */
15#define RT(t)	((((t)+5)%6)+7)
16#define RA(t)	((((t)+4)%6)+7)
17#define RB(t)	((((t)+3)%6)+7)
18#define RC(t)	((((t)+2)%6)+7)
19#define RD(t)	((((t)+1)%6)+7)
20#define RE(t)	((((t)+0)%6)+7)
21
22/* We use registers 16 - 31 for the W values */
23#define W(t)	(((t)%16)+16)
24
25#define LOADW(t)				\
26	lwz	W(t),(t)*4(r4)
27
28#define STEPD0_LOAD(t)				\
29	andc	r0,RD(t),RB(t);		\
30	and	r6,RB(t),RC(t);		\
31	rotlwi	RT(t),RA(t),5;			\
32	or	r6,r6,r0;			\
33	add	r0,RE(t),r15;			\
34	add	RT(t),RT(t),r6;		\
35	add	r14,r0,W(t);			\
36	lwz	W((t)+4),((t)+4)*4(r4);	\
37	rotlwi	RB(t),RB(t),30;			\
38	add	RT(t),RT(t),r14
39
40#define STEPD0_UPDATE(t)			\
41	and	r6,RB(t),RC(t);		\
42	andc	r0,RD(t),RB(t);		\
43	rotlwi	RT(t),RA(t),5;			\
44	rotlwi	RB(t),RB(t),30;			\
45	or	r6,r6,r0;			\
46	add	r0,RE(t),r15;			\
47	xor	r5,W((t)+4-3),W((t)+4-8);		\
48	add	RT(t),RT(t),r6;		\
49	xor	W((t)+4),W((t)+4-16),W((t)+4-14);	\
50	add	r0,r0,W(t);			\
51	xor	W((t)+4),W((t)+4),r5;			\
52	add	RT(t),RT(t),r0;		\
53	rotlwi	W((t)+4),W((t)+4),1
54
55#define STEPD1(t)				\
56	xor	r6,RB(t),RC(t);		\
57	rotlwi	RT(t),RA(t),5;			\
58	rotlwi	RB(t),RB(t),30;			\
59	xor	r6,r6,RD(t);			\
60	add	r0,RE(t),r15;			\
61	add	RT(t),RT(t),r6;		\
62	add	r0,r0,W(t);			\
63	add	RT(t),RT(t),r0
64
65#define STEPD1_UPDATE(t)				\
66	xor	r6,RB(t),RC(t);		\
67	rotlwi	RT(t),RA(t),5;			\
68	rotlwi	RB(t),RB(t),30;			\
69	xor	r6,r6,RD(t);			\
70	add	r0,RE(t),r15;			\
71	xor	r5,W((t)+4-3),W((t)+4-8);		\
72	add	RT(t),RT(t),r6;		\
73	xor	W((t)+4),W((t)+4-16),W((t)+4-14);	\
74	add	r0,r0,W(t);			\
75	xor	W((t)+4),W((t)+4),r5;			\
76	add	RT(t),RT(t),r0;		\
77	rotlwi	W((t)+4),W((t)+4),1
78
79#define STEPD2_UPDATE(t)			\
80	and	r6,RB(t),RC(t);		\
81	and	r0,RB(t),RD(t);		\
82	rotlwi	RT(t),RA(t),5;			\
83	or	r6,r6,r0;			\
84	rotlwi	RB(t),RB(t),30;			\
85	and	r0,RC(t),RD(t);		\
86	xor	r5,W((t)+4-3),W((t)+4-8);	\
87	or	r6,r6,r0;			\
88	xor	W((t)+4),W((t)+4-16),W((t)+4-14);	\
89	add	r0,RE(t),r15;			\
90	add	RT(t),RT(t),r6;		\
91	add	r0,r0,W(t);			\
92	xor	W((t)+4),W((t)+4),r5;		\
93	add	RT(t),RT(t),r0;		\
94	rotlwi	W((t)+4),W((t)+4),1
95
96#define STEP0LD4(t)				\
97	STEPD0_LOAD(t);				\
98	STEPD0_LOAD((t)+1);			\
99	STEPD0_LOAD((t)+2);			\
100	STEPD0_LOAD((t)+3)
101
102#define STEPUP4(t, fn)				\
103	STEP##fn##_UPDATE(t);			\
104	STEP##fn##_UPDATE((t)+1);		\
105	STEP##fn##_UPDATE((t)+2);		\
106	STEP##fn##_UPDATE((t)+3)
107
108#define STEPUP20(t, fn)				\
109	STEPUP4(t, fn);				\
110	STEPUP4((t)+4, fn);			\
111	STEPUP4((t)+8, fn);			\
112	STEPUP4((t)+12, fn);			\
113	STEPUP4((t)+16, fn)
114
115_GLOBAL(powerpc_sha_transform)
116	PPC_STLU r1,-INT_FRAME_SIZE(r1)
117	SAVE_8GPRS(14, r1)
118	SAVE_10GPRS(22, r1)
119
120	/* Load up A - E */
121	lwz	RA(0),0(r3)	/* A */
122	lwz	RB(0),4(r3)	/* B */
123	lwz	RC(0),8(r3)	/* C */
124	lwz	RD(0),12(r3)	/* D */
125	lwz	RE(0),16(r3)	/* E */
126
127	LOADW(0)
128	LOADW(1)
129	LOADW(2)
130	LOADW(3)
131
132	lis	r15,0x5a82	/* K0-19 */
133	ori	r15,r15,0x7999
134	STEP0LD4(0)
135	STEP0LD4(4)
136	STEP0LD4(8)
137	STEPUP4(12, D0)
138	STEPUP4(16, D0)
139
140	lis	r15,0x6ed9	/* K20-39 */
141	ori	r15,r15,0xeba1
142	STEPUP20(20, D1)
143
144	lis	r15,0x8f1b	/* K40-59 */
145	ori	r15,r15,0xbcdc
146	STEPUP20(40, D2)
147
148	lis	r15,0xca62	/* K60-79 */
149	ori	r15,r15,0xc1d6
150	STEPUP4(60, D1)
151	STEPUP4(64, D1)
152	STEPUP4(68, D1)
153	STEPUP4(72, D1)
154	lwz	r20,16(r3)
155	STEPD1(76)
156	lwz	r19,12(r3)
157	STEPD1(77)
158	lwz	r18,8(r3)
159	STEPD1(78)
160	lwz	r17,4(r3)
161	STEPD1(79)
162
163	lwz	r16,0(r3)
164	add	r20,RE(80),r20
165	add	RD(0),RD(80),r19
166	add	RC(0),RC(80),r18
167	add	RB(0),RB(80),r17
168	add	RA(0),RA(80),r16
169	mr	RE(0),r20
170	stw	RA(0),0(r3)
171	stw	RB(0),4(r3)
172	stw	RC(0),8(r3)
173	stw	RD(0),12(r3)
174	stw	RE(0),16(r3)
175
176	REST_8GPRS(14, r1)
177	REST_10GPRS(22, r1)
178	addi	r1,r1,INT_FRAME_SIZE
179	blr
180