162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * SHA-1 implementation for PowerPC.
462306a36Sopenharmony_ci *
562306a36Sopenharmony_ci * Copyright (C) 2005 Paul Mackerras <paulus@samba.org>
662306a36Sopenharmony_ci */
762306a36Sopenharmony_ci
862306a36Sopenharmony_ci#include <asm/ppc_asm.h>
962306a36Sopenharmony_ci#include <asm/asm-offsets.h>
1062306a36Sopenharmony_ci#include <asm/asm-compat.h>
1162306a36Sopenharmony_ci
1262306a36Sopenharmony_ci#ifdef __BIG_ENDIAN__
1362306a36Sopenharmony_ci#define LWZ(rt, d, ra)	\
1462306a36Sopenharmony_ci	lwz	rt,d(ra)
1562306a36Sopenharmony_ci#else
1662306a36Sopenharmony_ci#define LWZ(rt, d, ra)	\
1762306a36Sopenharmony_ci	li	rt,d;	\
1862306a36Sopenharmony_ci	lwbrx	rt,rt,ra
1962306a36Sopenharmony_ci#endif
2062306a36Sopenharmony_ci
2162306a36Sopenharmony_ci/*
2262306a36Sopenharmony_ci * We roll the registers for T, A, B, C, D, E around on each
2362306a36Sopenharmony_ci * iteration; T on iteration t is A on iteration t+1, and so on.
2462306a36Sopenharmony_ci * We use registers 7 - 12 for this.
2562306a36Sopenharmony_ci */
2662306a36Sopenharmony_ci#define RT(t)	((((t)+5)%6)+7)
2762306a36Sopenharmony_ci#define RA(t)	((((t)+4)%6)+7)
2862306a36Sopenharmony_ci#define RB(t)	((((t)+3)%6)+7)
2962306a36Sopenharmony_ci#define RC(t)	((((t)+2)%6)+7)
3062306a36Sopenharmony_ci#define RD(t)	((((t)+1)%6)+7)
3162306a36Sopenharmony_ci#define RE(t)	((((t)+0)%6)+7)
3262306a36Sopenharmony_ci
3362306a36Sopenharmony_ci/* We use registers 16 - 31 for the W values */
3462306a36Sopenharmony_ci#define W(t)	(((t)%16)+16)
3562306a36Sopenharmony_ci
3662306a36Sopenharmony_ci#define LOADW(t)				\
3762306a36Sopenharmony_ci	LWZ(W(t),(t)*4,r4)
3862306a36Sopenharmony_ci
3962306a36Sopenharmony_ci#define STEPD0_LOAD(t)				\
4062306a36Sopenharmony_ci	andc	r0,RD(t),RB(t);		\
4162306a36Sopenharmony_ci	and	r6,RB(t),RC(t);		\
4262306a36Sopenharmony_ci	rotlwi	RT(t),RA(t),5;			\
4362306a36Sopenharmony_ci	or	r6,r6,r0;			\
4462306a36Sopenharmony_ci	add	r0,RE(t),r15;			\
4562306a36Sopenharmony_ci	add	RT(t),RT(t),r6;		\
4662306a36Sopenharmony_ci	add	r14,r0,W(t);			\
4762306a36Sopenharmony_ci	LWZ(W((t)+4),((t)+4)*4,r4);	\
4862306a36Sopenharmony_ci	rotlwi	RB(t),RB(t),30;			\
4962306a36Sopenharmony_ci	add	RT(t),RT(t),r14
5062306a36Sopenharmony_ci
5162306a36Sopenharmony_ci#define STEPD0_UPDATE(t)			\
5262306a36Sopenharmony_ci	and	r6,RB(t),RC(t);		\
5362306a36Sopenharmony_ci	andc	r0,RD(t),RB(t);		\
5462306a36Sopenharmony_ci	rotlwi	RT(t),RA(t),5;			\
5562306a36Sopenharmony_ci	rotlwi	RB(t),RB(t),30;			\
5662306a36Sopenharmony_ci	or	r6,r6,r0;			\
5762306a36Sopenharmony_ci	add	r0,RE(t),r15;			\
5862306a36Sopenharmony_ci	xor	r5,W((t)+4-3),W((t)+4-8);		\
5962306a36Sopenharmony_ci	add	RT(t),RT(t),r6;		\
6062306a36Sopenharmony_ci	xor	W((t)+4),W((t)+4-16),W((t)+4-14);	\
6162306a36Sopenharmony_ci	add	r0,r0,W(t);			\
6262306a36Sopenharmony_ci	xor	W((t)+4),W((t)+4),r5;			\
6362306a36Sopenharmony_ci	add	RT(t),RT(t),r0;		\
6462306a36Sopenharmony_ci	rotlwi	W((t)+4),W((t)+4),1
6562306a36Sopenharmony_ci
6662306a36Sopenharmony_ci#define STEPD1(t)				\
6762306a36Sopenharmony_ci	xor	r6,RB(t),RC(t);		\
6862306a36Sopenharmony_ci	rotlwi	RT(t),RA(t),5;			\
6962306a36Sopenharmony_ci	rotlwi	RB(t),RB(t),30;			\
7062306a36Sopenharmony_ci	xor	r6,r6,RD(t);			\
7162306a36Sopenharmony_ci	add	r0,RE(t),r15;			\
7262306a36Sopenharmony_ci	add	RT(t),RT(t),r6;		\
7362306a36Sopenharmony_ci	add	r0,r0,W(t);			\
7462306a36Sopenharmony_ci	add	RT(t),RT(t),r0
7562306a36Sopenharmony_ci
7662306a36Sopenharmony_ci#define STEPD1_UPDATE(t)				\
7762306a36Sopenharmony_ci	xor	r6,RB(t),RC(t);		\
7862306a36Sopenharmony_ci	rotlwi	RT(t),RA(t),5;			\
7962306a36Sopenharmony_ci	rotlwi	RB(t),RB(t),30;			\
8062306a36Sopenharmony_ci	xor	r6,r6,RD(t);			\
8162306a36Sopenharmony_ci	add	r0,RE(t),r15;			\
8262306a36Sopenharmony_ci	xor	r5,W((t)+4-3),W((t)+4-8);		\
8362306a36Sopenharmony_ci	add	RT(t),RT(t),r6;		\
8462306a36Sopenharmony_ci	xor	W((t)+4),W((t)+4-16),W((t)+4-14);	\
8562306a36Sopenharmony_ci	add	r0,r0,W(t);			\
8662306a36Sopenharmony_ci	xor	W((t)+4),W((t)+4),r5;			\
8762306a36Sopenharmony_ci	add	RT(t),RT(t),r0;		\
8862306a36Sopenharmony_ci	rotlwi	W((t)+4),W((t)+4),1
8962306a36Sopenharmony_ci
9062306a36Sopenharmony_ci#define STEPD2_UPDATE(t)			\
9162306a36Sopenharmony_ci	and	r6,RB(t),RC(t);		\
9262306a36Sopenharmony_ci	and	r0,RB(t),RD(t);		\
9362306a36Sopenharmony_ci	rotlwi	RT(t),RA(t),5;			\
9462306a36Sopenharmony_ci	or	r6,r6,r0;			\
9562306a36Sopenharmony_ci	rotlwi	RB(t),RB(t),30;			\
9662306a36Sopenharmony_ci	and	r0,RC(t),RD(t);		\
9762306a36Sopenharmony_ci	xor	r5,W((t)+4-3),W((t)+4-8);	\
9862306a36Sopenharmony_ci	or	r6,r6,r0;			\
9962306a36Sopenharmony_ci	xor	W((t)+4),W((t)+4-16),W((t)+4-14);	\
10062306a36Sopenharmony_ci	add	r0,RE(t),r15;			\
10162306a36Sopenharmony_ci	add	RT(t),RT(t),r6;		\
10262306a36Sopenharmony_ci	add	r0,r0,W(t);			\
10362306a36Sopenharmony_ci	xor	W((t)+4),W((t)+4),r5;		\
10462306a36Sopenharmony_ci	add	RT(t),RT(t),r0;		\
10562306a36Sopenharmony_ci	rotlwi	W((t)+4),W((t)+4),1
10662306a36Sopenharmony_ci
10762306a36Sopenharmony_ci#define STEP0LD4(t)				\
10862306a36Sopenharmony_ci	STEPD0_LOAD(t);				\
10962306a36Sopenharmony_ci	STEPD0_LOAD((t)+1);			\
11062306a36Sopenharmony_ci	STEPD0_LOAD((t)+2);			\
11162306a36Sopenharmony_ci	STEPD0_LOAD((t)+3)
11262306a36Sopenharmony_ci
11362306a36Sopenharmony_ci#define STEPUP4(t, fn)				\
11462306a36Sopenharmony_ci	STEP##fn##_UPDATE(t);			\
11562306a36Sopenharmony_ci	STEP##fn##_UPDATE((t)+1);		\
11662306a36Sopenharmony_ci	STEP##fn##_UPDATE((t)+2);		\
11762306a36Sopenharmony_ci	STEP##fn##_UPDATE((t)+3)
11862306a36Sopenharmony_ci
11962306a36Sopenharmony_ci#define STEPUP20(t, fn)				\
12062306a36Sopenharmony_ci	STEPUP4(t, fn);				\
12162306a36Sopenharmony_ci	STEPUP4((t)+4, fn);			\
12262306a36Sopenharmony_ci	STEPUP4((t)+8, fn);			\
12362306a36Sopenharmony_ci	STEPUP4((t)+12, fn);			\
12462306a36Sopenharmony_ci	STEPUP4((t)+16, fn)
12562306a36Sopenharmony_ci
12662306a36Sopenharmony_ci_GLOBAL(powerpc_sha_transform)
12762306a36Sopenharmony_ci	PPC_STLU r1,-INT_FRAME_SIZE(r1)
12862306a36Sopenharmony_ci	SAVE_GPRS(14, 31, r1)
12962306a36Sopenharmony_ci
13062306a36Sopenharmony_ci	/* Load up A - E */
13162306a36Sopenharmony_ci	lwz	RA(0),0(r3)	/* A */
13262306a36Sopenharmony_ci	lwz	RB(0),4(r3)	/* B */
13362306a36Sopenharmony_ci	lwz	RC(0),8(r3)	/* C */
13462306a36Sopenharmony_ci	lwz	RD(0),12(r3)	/* D */
13562306a36Sopenharmony_ci	lwz	RE(0),16(r3)	/* E */
13662306a36Sopenharmony_ci
13762306a36Sopenharmony_ci	LOADW(0)
13862306a36Sopenharmony_ci	LOADW(1)
13962306a36Sopenharmony_ci	LOADW(2)
14062306a36Sopenharmony_ci	LOADW(3)
14162306a36Sopenharmony_ci
14262306a36Sopenharmony_ci	lis	r15,0x5a82	/* K0-19 */
14362306a36Sopenharmony_ci	ori	r15,r15,0x7999
14462306a36Sopenharmony_ci	STEP0LD4(0)
14562306a36Sopenharmony_ci	STEP0LD4(4)
14662306a36Sopenharmony_ci	STEP0LD4(8)
14762306a36Sopenharmony_ci	STEPUP4(12, D0)
14862306a36Sopenharmony_ci	STEPUP4(16, D0)
14962306a36Sopenharmony_ci
15062306a36Sopenharmony_ci	lis	r15,0x6ed9	/* K20-39 */
15162306a36Sopenharmony_ci	ori	r15,r15,0xeba1
15262306a36Sopenharmony_ci	STEPUP20(20, D1)
15362306a36Sopenharmony_ci
15462306a36Sopenharmony_ci	lis	r15,0x8f1b	/* K40-59 */
15562306a36Sopenharmony_ci	ori	r15,r15,0xbcdc
15662306a36Sopenharmony_ci	STEPUP20(40, D2)
15762306a36Sopenharmony_ci
15862306a36Sopenharmony_ci	lis	r15,0xca62	/* K60-79 */
15962306a36Sopenharmony_ci	ori	r15,r15,0xc1d6
16062306a36Sopenharmony_ci	STEPUP4(60, D1)
16162306a36Sopenharmony_ci	STEPUP4(64, D1)
16262306a36Sopenharmony_ci	STEPUP4(68, D1)
16362306a36Sopenharmony_ci	STEPUP4(72, D1)
16462306a36Sopenharmony_ci	lwz	r20,16(r3)
16562306a36Sopenharmony_ci	STEPD1(76)
16662306a36Sopenharmony_ci	lwz	r19,12(r3)
16762306a36Sopenharmony_ci	STEPD1(77)
16862306a36Sopenharmony_ci	lwz	r18,8(r3)
16962306a36Sopenharmony_ci	STEPD1(78)
17062306a36Sopenharmony_ci	lwz	r17,4(r3)
17162306a36Sopenharmony_ci	STEPD1(79)
17262306a36Sopenharmony_ci
17362306a36Sopenharmony_ci	lwz	r16,0(r3)
17462306a36Sopenharmony_ci	add	r20,RE(80),r20
17562306a36Sopenharmony_ci	add	RD(0),RD(80),r19
17662306a36Sopenharmony_ci	add	RC(0),RC(80),r18
17762306a36Sopenharmony_ci	add	RB(0),RB(80),r17
17862306a36Sopenharmony_ci	add	RA(0),RA(80),r16
17962306a36Sopenharmony_ci	mr	RE(0),r20
18062306a36Sopenharmony_ci	stw	RA(0),0(r3)
18162306a36Sopenharmony_ci	stw	RB(0),4(r3)
18262306a36Sopenharmony_ci	stw	RC(0),8(r3)
18362306a36Sopenharmony_ci	stw	RD(0),12(r3)
18462306a36Sopenharmony_ci	stw	RE(0),16(r3)
18562306a36Sopenharmony_ci
18662306a36Sopenharmony_ci	REST_GPRS(14, 31, r1)
18762306a36Sopenharmony_ci	addi	r1,r1,INT_FRAME_SIZE
18862306a36Sopenharmony_ci	blr
189