18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci * SHA-1 implementation for PowerPC.
48c2ecf20Sopenharmony_ci *
58c2ecf20Sopenharmony_ci * Copyright (C) 2005 Paul Mackerras <paulus@samba.org>
68c2ecf20Sopenharmony_ci */
78c2ecf20Sopenharmony_ci
88c2ecf20Sopenharmony_ci#include <asm/ppc_asm.h>
98c2ecf20Sopenharmony_ci#include <asm/asm-offsets.h>
108c2ecf20Sopenharmony_ci#include <asm/asm-compat.h>
118c2ecf20Sopenharmony_ci
128c2ecf20Sopenharmony_ci#ifdef __BIG_ENDIAN__
138c2ecf20Sopenharmony_ci#define LWZ(rt, d, ra)	\
148c2ecf20Sopenharmony_ci	lwz	rt,d(ra)
158c2ecf20Sopenharmony_ci#else
168c2ecf20Sopenharmony_ci#define LWZ(rt, d, ra)	\
178c2ecf20Sopenharmony_ci	li	rt,d;	\
188c2ecf20Sopenharmony_ci	lwbrx	rt,rt,ra
198c2ecf20Sopenharmony_ci#endif
208c2ecf20Sopenharmony_ci
218c2ecf20Sopenharmony_ci/*
228c2ecf20Sopenharmony_ci * We roll the registers for T, A, B, C, D, E around on each
238c2ecf20Sopenharmony_ci * iteration; T on iteration t is A on iteration t+1, and so on.
248c2ecf20Sopenharmony_ci * We use registers 7 - 12 for this.
258c2ecf20Sopenharmony_ci */
268c2ecf20Sopenharmony_ci#define RT(t)	((((t)+5)%6)+7)
278c2ecf20Sopenharmony_ci#define RA(t)	((((t)+4)%6)+7)
288c2ecf20Sopenharmony_ci#define RB(t)	((((t)+3)%6)+7)
298c2ecf20Sopenharmony_ci#define RC(t)	((((t)+2)%6)+7)
308c2ecf20Sopenharmony_ci#define RD(t)	((((t)+1)%6)+7)
318c2ecf20Sopenharmony_ci#define RE(t)	((((t)+0)%6)+7)
328c2ecf20Sopenharmony_ci
338c2ecf20Sopenharmony_ci/* We use registers 16 - 31 for the W values */
348c2ecf20Sopenharmony_ci#define W(t)	(((t)%16)+16)
358c2ecf20Sopenharmony_ci
368c2ecf20Sopenharmony_ci#define LOADW(t)				\
378c2ecf20Sopenharmony_ci	LWZ(W(t),(t)*4,r4)
388c2ecf20Sopenharmony_ci
398c2ecf20Sopenharmony_ci#define STEPD0_LOAD(t)				\
408c2ecf20Sopenharmony_ci	andc	r0,RD(t),RB(t);		\
418c2ecf20Sopenharmony_ci	and	r6,RB(t),RC(t);		\
428c2ecf20Sopenharmony_ci	rotlwi	RT(t),RA(t),5;			\
438c2ecf20Sopenharmony_ci	or	r6,r6,r0;			\
448c2ecf20Sopenharmony_ci	add	r0,RE(t),r15;			\
458c2ecf20Sopenharmony_ci	add	RT(t),RT(t),r6;		\
468c2ecf20Sopenharmony_ci	add	r14,r0,W(t);			\
478c2ecf20Sopenharmony_ci	LWZ(W((t)+4),((t)+4)*4,r4);	\
488c2ecf20Sopenharmony_ci	rotlwi	RB(t),RB(t),30;			\
498c2ecf20Sopenharmony_ci	add	RT(t),RT(t),r14
508c2ecf20Sopenharmony_ci
518c2ecf20Sopenharmony_ci#define STEPD0_UPDATE(t)			\
528c2ecf20Sopenharmony_ci	and	r6,RB(t),RC(t);		\
538c2ecf20Sopenharmony_ci	andc	r0,RD(t),RB(t);		\
548c2ecf20Sopenharmony_ci	rotlwi	RT(t),RA(t),5;			\
558c2ecf20Sopenharmony_ci	rotlwi	RB(t),RB(t),30;			\
568c2ecf20Sopenharmony_ci	or	r6,r6,r0;			\
578c2ecf20Sopenharmony_ci	add	r0,RE(t),r15;			\
588c2ecf20Sopenharmony_ci	xor	r5,W((t)+4-3),W((t)+4-8);		\
598c2ecf20Sopenharmony_ci	add	RT(t),RT(t),r6;		\
608c2ecf20Sopenharmony_ci	xor	W((t)+4),W((t)+4-16),W((t)+4-14);	\
618c2ecf20Sopenharmony_ci	add	r0,r0,W(t);			\
628c2ecf20Sopenharmony_ci	xor	W((t)+4),W((t)+4),r5;			\
638c2ecf20Sopenharmony_ci	add	RT(t),RT(t),r0;		\
648c2ecf20Sopenharmony_ci	rotlwi	W((t)+4),W((t)+4),1
658c2ecf20Sopenharmony_ci
668c2ecf20Sopenharmony_ci#define STEPD1(t)				\
678c2ecf20Sopenharmony_ci	xor	r6,RB(t),RC(t);		\
688c2ecf20Sopenharmony_ci	rotlwi	RT(t),RA(t),5;			\
698c2ecf20Sopenharmony_ci	rotlwi	RB(t),RB(t),30;			\
708c2ecf20Sopenharmony_ci	xor	r6,r6,RD(t);			\
718c2ecf20Sopenharmony_ci	add	r0,RE(t),r15;			\
728c2ecf20Sopenharmony_ci	add	RT(t),RT(t),r6;		\
738c2ecf20Sopenharmony_ci	add	r0,r0,W(t);			\
748c2ecf20Sopenharmony_ci	add	RT(t),RT(t),r0
758c2ecf20Sopenharmony_ci
768c2ecf20Sopenharmony_ci#define STEPD1_UPDATE(t)				\
778c2ecf20Sopenharmony_ci	xor	r6,RB(t),RC(t);		\
788c2ecf20Sopenharmony_ci	rotlwi	RT(t),RA(t),5;			\
798c2ecf20Sopenharmony_ci	rotlwi	RB(t),RB(t),30;			\
808c2ecf20Sopenharmony_ci	xor	r6,r6,RD(t);			\
818c2ecf20Sopenharmony_ci	add	r0,RE(t),r15;			\
828c2ecf20Sopenharmony_ci	xor	r5,W((t)+4-3),W((t)+4-8);		\
838c2ecf20Sopenharmony_ci	add	RT(t),RT(t),r6;		\
848c2ecf20Sopenharmony_ci	xor	W((t)+4),W((t)+4-16),W((t)+4-14);	\
858c2ecf20Sopenharmony_ci	add	r0,r0,W(t);			\
868c2ecf20Sopenharmony_ci	xor	W((t)+4),W((t)+4),r5;			\
878c2ecf20Sopenharmony_ci	add	RT(t),RT(t),r0;		\
888c2ecf20Sopenharmony_ci	rotlwi	W((t)+4),W((t)+4),1
898c2ecf20Sopenharmony_ci
908c2ecf20Sopenharmony_ci#define STEPD2_UPDATE(t)			\
918c2ecf20Sopenharmony_ci	and	r6,RB(t),RC(t);		\
928c2ecf20Sopenharmony_ci	and	r0,RB(t),RD(t);		\
938c2ecf20Sopenharmony_ci	rotlwi	RT(t),RA(t),5;			\
948c2ecf20Sopenharmony_ci	or	r6,r6,r0;			\
958c2ecf20Sopenharmony_ci	rotlwi	RB(t),RB(t),30;			\
968c2ecf20Sopenharmony_ci	and	r0,RC(t),RD(t);		\
978c2ecf20Sopenharmony_ci	xor	r5,W((t)+4-3),W((t)+4-8);	\
988c2ecf20Sopenharmony_ci	or	r6,r6,r0;			\
998c2ecf20Sopenharmony_ci	xor	W((t)+4),W((t)+4-16),W((t)+4-14);	\
1008c2ecf20Sopenharmony_ci	add	r0,RE(t),r15;			\
1018c2ecf20Sopenharmony_ci	add	RT(t),RT(t),r6;		\
1028c2ecf20Sopenharmony_ci	add	r0,r0,W(t);			\
1038c2ecf20Sopenharmony_ci	xor	W((t)+4),W((t)+4),r5;		\
1048c2ecf20Sopenharmony_ci	add	RT(t),RT(t),r0;		\
1058c2ecf20Sopenharmony_ci	rotlwi	W((t)+4),W((t)+4),1
1068c2ecf20Sopenharmony_ci
1078c2ecf20Sopenharmony_ci#define STEP0LD4(t)				\
1088c2ecf20Sopenharmony_ci	STEPD0_LOAD(t);				\
1098c2ecf20Sopenharmony_ci	STEPD0_LOAD((t)+1);			\
1108c2ecf20Sopenharmony_ci	STEPD0_LOAD((t)+2);			\
1118c2ecf20Sopenharmony_ci	STEPD0_LOAD((t)+3)
1128c2ecf20Sopenharmony_ci
1138c2ecf20Sopenharmony_ci#define STEPUP4(t, fn)				\
1148c2ecf20Sopenharmony_ci	STEP##fn##_UPDATE(t);			\
1158c2ecf20Sopenharmony_ci	STEP##fn##_UPDATE((t)+1);		\
1168c2ecf20Sopenharmony_ci	STEP##fn##_UPDATE((t)+2);		\
1178c2ecf20Sopenharmony_ci	STEP##fn##_UPDATE((t)+3)
1188c2ecf20Sopenharmony_ci
1198c2ecf20Sopenharmony_ci#define STEPUP20(t, fn)				\
1208c2ecf20Sopenharmony_ci	STEPUP4(t, fn);				\
1218c2ecf20Sopenharmony_ci	STEPUP4((t)+4, fn);			\
1228c2ecf20Sopenharmony_ci	STEPUP4((t)+8, fn);			\
1238c2ecf20Sopenharmony_ci	STEPUP4((t)+12, fn);			\
1248c2ecf20Sopenharmony_ci	STEPUP4((t)+16, fn)
1258c2ecf20Sopenharmony_ci
1268c2ecf20Sopenharmony_ci_GLOBAL(powerpc_sha_transform)
1278c2ecf20Sopenharmony_ci	PPC_STLU r1,-INT_FRAME_SIZE(r1)
1288c2ecf20Sopenharmony_ci	SAVE_8GPRS(14, r1)
1298c2ecf20Sopenharmony_ci	SAVE_10GPRS(22, r1)
1308c2ecf20Sopenharmony_ci
1318c2ecf20Sopenharmony_ci	/* Load up A - E */
1328c2ecf20Sopenharmony_ci	lwz	RA(0),0(r3)	/* A */
1338c2ecf20Sopenharmony_ci	lwz	RB(0),4(r3)	/* B */
1348c2ecf20Sopenharmony_ci	lwz	RC(0),8(r3)	/* C */
1358c2ecf20Sopenharmony_ci	lwz	RD(0),12(r3)	/* D */
1368c2ecf20Sopenharmony_ci	lwz	RE(0),16(r3)	/* E */
1378c2ecf20Sopenharmony_ci
1388c2ecf20Sopenharmony_ci	LOADW(0)
1398c2ecf20Sopenharmony_ci	LOADW(1)
1408c2ecf20Sopenharmony_ci	LOADW(2)
1418c2ecf20Sopenharmony_ci	LOADW(3)
1428c2ecf20Sopenharmony_ci
1438c2ecf20Sopenharmony_ci	lis	r15,0x5a82	/* K0-19 */
1448c2ecf20Sopenharmony_ci	ori	r15,r15,0x7999
1458c2ecf20Sopenharmony_ci	STEP0LD4(0)
1468c2ecf20Sopenharmony_ci	STEP0LD4(4)
1478c2ecf20Sopenharmony_ci	STEP0LD4(8)
1488c2ecf20Sopenharmony_ci	STEPUP4(12, D0)
1498c2ecf20Sopenharmony_ci	STEPUP4(16, D0)
1508c2ecf20Sopenharmony_ci
1518c2ecf20Sopenharmony_ci	lis	r15,0x6ed9	/* K20-39 */
1528c2ecf20Sopenharmony_ci	ori	r15,r15,0xeba1
1538c2ecf20Sopenharmony_ci	STEPUP20(20, D1)
1548c2ecf20Sopenharmony_ci
1558c2ecf20Sopenharmony_ci	lis	r15,0x8f1b	/* K40-59 */
1568c2ecf20Sopenharmony_ci	ori	r15,r15,0xbcdc
1578c2ecf20Sopenharmony_ci	STEPUP20(40, D2)
1588c2ecf20Sopenharmony_ci
1598c2ecf20Sopenharmony_ci	lis	r15,0xca62	/* K60-79 */
1608c2ecf20Sopenharmony_ci	ori	r15,r15,0xc1d6
1618c2ecf20Sopenharmony_ci	STEPUP4(60, D1)
1628c2ecf20Sopenharmony_ci	STEPUP4(64, D1)
1638c2ecf20Sopenharmony_ci	STEPUP4(68, D1)
1648c2ecf20Sopenharmony_ci	STEPUP4(72, D1)
1658c2ecf20Sopenharmony_ci	lwz	r20,16(r3)
1668c2ecf20Sopenharmony_ci	STEPD1(76)
1678c2ecf20Sopenharmony_ci	lwz	r19,12(r3)
1688c2ecf20Sopenharmony_ci	STEPD1(77)
1698c2ecf20Sopenharmony_ci	lwz	r18,8(r3)
1708c2ecf20Sopenharmony_ci	STEPD1(78)
1718c2ecf20Sopenharmony_ci	lwz	r17,4(r3)
1728c2ecf20Sopenharmony_ci	STEPD1(79)
1738c2ecf20Sopenharmony_ci
1748c2ecf20Sopenharmony_ci	lwz	r16,0(r3)
1758c2ecf20Sopenharmony_ci	add	r20,RE(80),r20
1768c2ecf20Sopenharmony_ci	add	RD(0),RD(80),r19
1778c2ecf20Sopenharmony_ci	add	RC(0),RC(80),r18
1788c2ecf20Sopenharmony_ci	add	RB(0),RB(80),r17
1798c2ecf20Sopenharmony_ci	add	RA(0),RA(80),r16
1808c2ecf20Sopenharmony_ci	mr	RE(0),r20
1818c2ecf20Sopenharmony_ci	stw	RA(0),0(r3)
1828c2ecf20Sopenharmony_ci	stw	RB(0),4(r3)
1838c2ecf20Sopenharmony_ci	stw	RC(0),8(r3)
1848c2ecf20Sopenharmony_ci	stw	RD(0),12(r3)
1858c2ecf20Sopenharmony_ci	stw	RE(0),16(r3)
1868c2ecf20Sopenharmony_ci
1878c2ecf20Sopenharmony_ci	REST_8GPRS(14, r1)
1888c2ecf20Sopenharmony_ci	REST_10GPRS(22, r1)
1898c2ecf20Sopenharmony_ci	addi	r1,r1,INT_FRAME_SIZE
1908c2ecf20Sopenharmony_ci	blr
191