18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-or-later */
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci * AES modes (ECB/CBC/CTR/XTS) for PPC AES implementation
48c2ecf20Sopenharmony_ci *
58c2ecf20Sopenharmony_ci * Copyright (c) 2015 Markus Stockhausen <stockhausen@collogia.de>
68c2ecf20Sopenharmony_ci */
78c2ecf20Sopenharmony_ci
88c2ecf20Sopenharmony_ci#include <asm/ppc_asm.h>
98c2ecf20Sopenharmony_ci#include "aes-spe-regs.h"
108c2ecf20Sopenharmony_ci
118c2ecf20Sopenharmony_ci#ifdef __BIG_ENDIAN__			/* Macros for big endian builds	*/
128c2ecf20Sopenharmony_ci
138c2ecf20Sopenharmony_ci#define LOAD_DATA(reg, off) \
148c2ecf20Sopenharmony_ci	lwz		reg,off(rSP);	/* load with offset		*/
158c2ecf20Sopenharmony_ci#define SAVE_DATA(reg, off) \
168c2ecf20Sopenharmony_ci	stw		reg,off(rDP);	/* save with offset		*/
178c2ecf20Sopenharmony_ci#define NEXT_BLOCK \
188c2ecf20Sopenharmony_ci	addi		rSP,rSP,16;	/* increment pointers per bloc	*/ \
198c2ecf20Sopenharmony_ci	addi		rDP,rDP,16;
208c2ecf20Sopenharmony_ci#define LOAD_IV(reg, off) \
218c2ecf20Sopenharmony_ci	lwz		reg,off(rIP);	/* IV loading with offset	*/
228c2ecf20Sopenharmony_ci#define SAVE_IV(reg, off) \
238c2ecf20Sopenharmony_ci	stw		reg,off(rIP);	/* IV saving with offset	*/
248c2ecf20Sopenharmony_ci#define START_IV			/* nothing to reset		*/
258c2ecf20Sopenharmony_ci#define CBC_DEC 16			/* CBC decrement per block	*/
268c2ecf20Sopenharmony_ci#define CTR_DEC 1			/* CTR decrement one byte	*/
278c2ecf20Sopenharmony_ci
288c2ecf20Sopenharmony_ci#else					/* Macros for little endian	*/
298c2ecf20Sopenharmony_ci
308c2ecf20Sopenharmony_ci#define LOAD_DATA(reg, off) \
318c2ecf20Sopenharmony_ci	lwbrx		reg,0,rSP;	/* load reversed		*/ \
328c2ecf20Sopenharmony_ci	addi		rSP,rSP,4;	/* and increment pointer	*/
338c2ecf20Sopenharmony_ci#define SAVE_DATA(reg, off) \
348c2ecf20Sopenharmony_ci	stwbrx		reg,0,rDP;	/* save reversed		*/ \
358c2ecf20Sopenharmony_ci	addi		rDP,rDP,4;	/* and increment pointer	*/
368c2ecf20Sopenharmony_ci#define NEXT_BLOCK			/* nothing todo			*/
378c2ecf20Sopenharmony_ci#define LOAD_IV(reg, off) \
388c2ecf20Sopenharmony_ci	lwbrx		reg,0,rIP;	/* load reversed		*/ \
398c2ecf20Sopenharmony_ci	addi		rIP,rIP,4;	/* and increment pointer	*/
408c2ecf20Sopenharmony_ci#define SAVE_IV(reg, off) \
418c2ecf20Sopenharmony_ci	stwbrx		reg,0,rIP;	/* load reversed		*/ \
428c2ecf20Sopenharmony_ci	addi		rIP,rIP,4;	/* and increment pointer	*/
438c2ecf20Sopenharmony_ci#define START_IV \
448c2ecf20Sopenharmony_ci	subi		rIP,rIP,16;	/* must reset pointer		*/
458c2ecf20Sopenharmony_ci#define CBC_DEC 32			/* 2 blocks because of incs	*/
468c2ecf20Sopenharmony_ci#define CTR_DEC 17			/* 1 block because of incs	*/
478c2ecf20Sopenharmony_ci
488c2ecf20Sopenharmony_ci#endif
498c2ecf20Sopenharmony_ci
508c2ecf20Sopenharmony_ci#define SAVE_0_REGS
518c2ecf20Sopenharmony_ci#define LOAD_0_REGS
528c2ecf20Sopenharmony_ci
538c2ecf20Sopenharmony_ci#define SAVE_4_REGS \
548c2ecf20Sopenharmony_ci	stw		rI0,96(r1);	/* save 32 bit registers	*/ \
558c2ecf20Sopenharmony_ci	stw		rI1,100(r1);					   \
568c2ecf20Sopenharmony_ci	stw		rI2,104(r1);					   \
578c2ecf20Sopenharmony_ci	stw		rI3,108(r1);
588c2ecf20Sopenharmony_ci
598c2ecf20Sopenharmony_ci#define LOAD_4_REGS \
608c2ecf20Sopenharmony_ci	lwz		rI0,96(r1);	/* restore 32 bit registers	*/ \
618c2ecf20Sopenharmony_ci	lwz		rI1,100(r1);					   \
628c2ecf20Sopenharmony_ci	lwz		rI2,104(r1);					   \
638c2ecf20Sopenharmony_ci	lwz		rI3,108(r1);
648c2ecf20Sopenharmony_ci
658c2ecf20Sopenharmony_ci#define SAVE_8_REGS \
668c2ecf20Sopenharmony_ci	SAVE_4_REGS							   \
678c2ecf20Sopenharmony_ci	stw		rG0,112(r1);	/* save 32 bit registers	*/ \
688c2ecf20Sopenharmony_ci	stw		rG1,116(r1);					   \
698c2ecf20Sopenharmony_ci	stw		rG2,120(r1);					   \
708c2ecf20Sopenharmony_ci	stw		rG3,124(r1);
718c2ecf20Sopenharmony_ci
728c2ecf20Sopenharmony_ci#define LOAD_8_REGS \
738c2ecf20Sopenharmony_ci	LOAD_4_REGS							   \
748c2ecf20Sopenharmony_ci	lwz		rG0,112(r1);	/* restore 32 bit registers	*/ \
758c2ecf20Sopenharmony_ci	lwz		rG1,116(r1);					   \
768c2ecf20Sopenharmony_ci	lwz		rG2,120(r1);					   \
778c2ecf20Sopenharmony_ci	lwz		rG3,124(r1);
788c2ecf20Sopenharmony_ci
798c2ecf20Sopenharmony_ci#define INITIALIZE_CRYPT(tab,nr32bitregs) \
808c2ecf20Sopenharmony_ci	mflr		r0;						   \
818c2ecf20Sopenharmony_ci	stwu		r1,-160(r1);	/* create stack frame		*/ \
828c2ecf20Sopenharmony_ci	lis		rT0,tab@h;	/* en-/decryption table pointer	*/ \
838c2ecf20Sopenharmony_ci	stw		r0,8(r1);	/* save link register		*/ \
848c2ecf20Sopenharmony_ci	ori		rT0,rT0,tab@l;					   \
858c2ecf20Sopenharmony_ci	evstdw		r14,16(r1);					   \
868c2ecf20Sopenharmony_ci	mr		rKS,rKP;					   \
878c2ecf20Sopenharmony_ci	evstdw		r15,24(r1);	/* We must save non volatile	*/ \
888c2ecf20Sopenharmony_ci	evstdw		r16,32(r1);	/* registers. Take the chance	*/ \
898c2ecf20Sopenharmony_ci	evstdw		r17,40(r1);	/* and save the SPE part too	*/ \
908c2ecf20Sopenharmony_ci	evstdw		r18,48(r1);					   \
918c2ecf20Sopenharmony_ci	evstdw		r19,56(r1);					   \
928c2ecf20Sopenharmony_ci	evstdw		r20,64(r1);					   \
938c2ecf20Sopenharmony_ci	evstdw		r21,72(r1);					   \
948c2ecf20Sopenharmony_ci	evstdw		r22,80(r1);					   \
958c2ecf20Sopenharmony_ci	evstdw		r23,88(r1);					   \
968c2ecf20Sopenharmony_ci	SAVE_##nr32bitregs##_REGS
978c2ecf20Sopenharmony_ci
988c2ecf20Sopenharmony_ci#define FINALIZE_CRYPT(nr32bitregs) \
998c2ecf20Sopenharmony_ci	lwz		r0,8(r1);					   \
1008c2ecf20Sopenharmony_ci	evldw		r14,16(r1);	/* restore SPE registers	*/ \
1018c2ecf20Sopenharmony_ci	evldw		r15,24(r1);					   \
1028c2ecf20Sopenharmony_ci	evldw		r16,32(r1);					   \
1038c2ecf20Sopenharmony_ci	evldw		r17,40(r1);					   \
1048c2ecf20Sopenharmony_ci	evldw		r18,48(r1);					   \
1058c2ecf20Sopenharmony_ci	evldw		r19,56(r1);					   \
1068c2ecf20Sopenharmony_ci	evldw		r20,64(r1);					   \
1078c2ecf20Sopenharmony_ci	evldw		r21,72(r1);					   \
1088c2ecf20Sopenharmony_ci	evldw		r22,80(r1);					   \
1098c2ecf20Sopenharmony_ci	evldw		r23,88(r1);					   \
1108c2ecf20Sopenharmony_ci	LOAD_##nr32bitregs##_REGS					   \
1118c2ecf20Sopenharmony_ci	mtlr		r0;		/* restore link register	*/ \
1128c2ecf20Sopenharmony_ci	xor		r0,r0,r0;					   \
1138c2ecf20Sopenharmony_ci	stw		r0,16(r1);	/* delete sensitive data	*/ \
1148c2ecf20Sopenharmony_ci	stw		r0,24(r1);	/* that we might have pushed	*/ \
1158c2ecf20Sopenharmony_ci	stw		r0,32(r1);	/* from other context that runs	*/ \
1168c2ecf20Sopenharmony_ci	stw		r0,40(r1);	/* the same code		*/ \
1178c2ecf20Sopenharmony_ci	stw		r0,48(r1);					   \
1188c2ecf20Sopenharmony_ci	stw		r0,56(r1);					   \
1198c2ecf20Sopenharmony_ci	stw		r0,64(r1);					   \
1208c2ecf20Sopenharmony_ci	stw		r0,72(r1);					   \
1218c2ecf20Sopenharmony_ci	stw		r0,80(r1);					   \
1228c2ecf20Sopenharmony_ci	stw		r0,88(r1);					   \
1238c2ecf20Sopenharmony_ci	addi		r1,r1,160;	/* cleanup stack frame		*/
1248c2ecf20Sopenharmony_ci
1258c2ecf20Sopenharmony_ci#define ENDIAN_SWAP(t0, t1, s0, s1) \
1268c2ecf20Sopenharmony_ci	rotrwi		t0,s0,8;	/* swap endianness for 2 GPRs	*/ \
1278c2ecf20Sopenharmony_ci	rotrwi		t1,s1,8;					   \
1288c2ecf20Sopenharmony_ci	rlwimi		t0,s0,8,8,15;					   \
1298c2ecf20Sopenharmony_ci	rlwimi		t1,s1,8,8,15;					   \
1308c2ecf20Sopenharmony_ci	rlwimi		t0,s0,8,24,31;					   \
1318c2ecf20Sopenharmony_ci	rlwimi		t1,s1,8,24,31;
1328c2ecf20Sopenharmony_ci
1338c2ecf20Sopenharmony_ci#define GF128_MUL(d0, d1, d2, d3, t0) \
1348c2ecf20Sopenharmony_ci	li		t0,0x87;	/* multiplication in GF128	*/ \
1358c2ecf20Sopenharmony_ci	cmpwi		d3,-1;						   \
1368c2ecf20Sopenharmony_ci	iselgt		t0,0,t0;					   \
1378c2ecf20Sopenharmony_ci	rlwimi		d3,d2,0,0,0;	/* propagate "carry" bits	*/ \
1388c2ecf20Sopenharmony_ci	rotlwi		d3,d3,1;					   \
1398c2ecf20Sopenharmony_ci	rlwimi		d2,d1,0,0,0;					   \
1408c2ecf20Sopenharmony_ci	rotlwi		d2,d2,1;					   \
1418c2ecf20Sopenharmony_ci	rlwimi		d1,d0,0,0,0;					   \
1428c2ecf20Sopenharmony_ci	slwi		d0,d0,1;	/* shift left 128 bit		*/ \
1438c2ecf20Sopenharmony_ci	rotlwi		d1,d1,1;					   \
1448c2ecf20Sopenharmony_ci	xor		d0,d0,t0;
1458c2ecf20Sopenharmony_ci
1468c2ecf20Sopenharmony_ci#define START_KEY(d0, d1, d2, d3) \
1478c2ecf20Sopenharmony_ci	lwz		rW0,0(rKP);					   \
1488c2ecf20Sopenharmony_ci	mtctr		rRR;						   \
1498c2ecf20Sopenharmony_ci	lwz		rW1,4(rKP);					   \
1508c2ecf20Sopenharmony_ci	lwz		rW2,8(rKP);					   \
1518c2ecf20Sopenharmony_ci	lwz		rW3,12(rKP);					   \
1528c2ecf20Sopenharmony_ci	xor		rD0,d0,rW0;					   \
1538c2ecf20Sopenharmony_ci	xor		rD1,d1,rW1;					   \
1548c2ecf20Sopenharmony_ci	xor		rD2,d2,rW2;					   \
1558c2ecf20Sopenharmony_ci	xor		rD3,d3,rW3;
1568c2ecf20Sopenharmony_ci
1578c2ecf20Sopenharmony_ci/*
1588c2ecf20Sopenharmony_ci * ppc_encrypt_aes(u8 *out, const u8 *in, u32 *key_enc,
1598c2ecf20Sopenharmony_ci *		   u32 rounds)
1608c2ecf20Sopenharmony_ci *
1618c2ecf20Sopenharmony_ci * called from glue layer to encrypt a single 16 byte block
1628c2ecf20Sopenharmony_ci * round values are AES128 = 4, AES192 = 5, AES256 = 6
1638c2ecf20Sopenharmony_ci *
1648c2ecf20Sopenharmony_ci */
1658c2ecf20Sopenharmony_ci_GLOBAL(ppc_encrypt_aes)
1668c2ecf20Sopenharmony_ci	INITIALIZE_CRYPT(PPC_AES_4K_ENCTAB, 0)
1678c2ecf20Sopenharmony_ci	LOAD_DATA(rD0, 0)
1688c2ecf20Sopenharmony_ci	LOAD_DATA(rD1, 4)
1698c2ecf20Sopenharmony_ci	LOAD_DATA(rD2, 8)
1708c2ecf20Sopenharmony_ci	LOAD_DATA(rD3, 12)
1718c2ecf20Sopenharmony_ci	START_KEY(rD0, rD1, rD2, rD3)
1728c2ecf20Sopenharmony_ci	bl		ppc_encrypt_block
1738c2ecf20Sopenharmony_ci	xor		rD0,rD0,rW0
1748c2ecf20Sopenharmony_ci	SAVE_DATA(rD0, 0)
1758c2ecf20Sopenharmony_ci	xor		rD1,rD1,rW1
1768c2ecf20Sopenharmony_ci	SAVE_DATA(rD1, 4)
1778c2ecf20Sopenharmony_ci	xor		rD2,rD2,rW2
1788c2ecf20Sopenharmony_ci	SAVE_DATA(rD2, 8)
1798c2ecf20Sopenharmony_ci	xor		rD3,rD3,rW3
1808c2ecf20Sopenharmony_ci	SAVE_DATA(rD3, 12)
1818c2ecf20Sopenharmony_ci	FINALIZE_CRYPT(0)
1828c2ecf20Sopenharmony_ci	blr
1838c2ecf20Sopenharmony_ci
1848c2ecf20Sopenharmony_ci/*
1858c2ecf20Sopenharmony_ci * ppc_decrypt_aes(u8 *out, const u8 *in, u32 *key_dec,
1868c2ecf20Sopenharmony_ci *		   u32 rounds)
1878c2ecf20Sopenharmony_ci *
1888c2ecf20Sopenharmony_ci * called from glue layer to decrypt a single 16 byte block
1898c2ecf20Sopenharmony_ci * round values are AES128 = 4, AES192 = 5, AES256 = 6
1908c2ecf20Sopenharmony_ci *
1918c2ecf20Sopenharmony_ci */
1928c2ecf20Sopenharmony_ci_GLOBAL(ppc_decrypt_aes)
1938c2ecf20Sopenharmony_ci	INITIALIZE_CRYPT(PPC_AES_4K_DECTAB,0)
1948c2ecf20Sopenharmony_ci	LOAD_DATA(rD0, 0)
1958c2ecf20Sopenharmony_ci	addi		rT1,rT0,4096
1968c2ecf20Sopenharmony_ci	LOAD_DATA(rD1, 4)
1978c2ecf20Sopenharmony_ci	LOAD_DATA(rD2, 8)
1988c2ecf20Sopenharmony_ci	LOAD_DATA(rD3, 12)
1998c2ecf20Sopenharmony_ci	START_KEY(rD0, rD1, rD2, rD3)
2008c2ecf20Sopenharmony_ci	bl		ppc_decrypt_block
2018c2ecf20Sopenharmony_ci	xor		rD0,rD0,rW0
2028c2ecf20Sopenharmony_ci	SAVE_DATA(rD0, 0)
2038c2ecf20Sopenharmony_ci	xor		rD1,rD1,rW1
2048c2ecf20Sopenharmony_ci	SAVE_DATA(rD1, 4)
2058c2ecf20Sopenharmony_ci	xor		rD2,rD2,rW2
2068c2ecf20Sopenharmony_ci	SAVE_DATA(rD2, 8)
2078c2ecf20Sopenharmony_ci	xor		rD3,rD3,rW3
2088c2ecf20Sopenharmony_ci	SAVE_DATA(rD3, 12)
2098c2ecf20Sopenharmony_ci	FINALIZE_CRYPT(0)
2108c2ecf20Sopenharmony_ci	blr
2118c2ecf20Sopenharmony_ci
2128c2ecf20Sopenharmony_ci/*
2138c2ecf20Sopenharmony_ci * ppc_encrypt_ecb(u8 *out, const u8 *in, u32 *key_enc,
2148c2ecf20Sopenharmony_ci *		   u32 rounds, u32 bytes);
2158c2ecf20Sopenharmony_ci *
2168c2ecf20Sopenharmony_ci * called from glue layer to encrypt multiple blocks via ECB
2178c2ecf20Sopenharmony_ci * Bytes must be larger or equal 16 and only whole blocks are
2188c2ecf20Sopenharmony_ci * processed. round values are AES128 = 4, AES192 = 5 and
2198c2ecf20Sopenharmony_ci * AES256 = 6
2208c2ecf20Sopenharmony_ci *
2218c2ecf20Sopenharmony_ci */
2228c2ecf20Sopenharmony_ci_GLOBAL(ppc_encrypt_ecb)
2238c2ecf20Sopenharmony_ci	INITIALIZE_CRYPT(PPC_AES_4K_ENCTAB, 0)
2248c2ecf20Sopenharmony_cippc_encrypt_ecb_loop:
2258c2ecf20Sopenharmony_ci	LOAD_DATA(rD0, 0)
2268c2ecf20Sopenharmony_ci	mr		rKP,rKS
2278c2ecf20Sopenharmony_ci	LOAD_DATA(rD1, 4)
2288c2ecf20Sopenharmony_ci	subi		rLN,rLN,16
2298c2ecf20Sopenharmony_ci	LOAD_DATA(rD2, 8)
2308c2ecf20Sopenharmony_ci	cmpwi		rLN,15
2318c2ecf20Sopenharmony_ci	LOAD_DATA(rD3, 12)
2328c2ecf20Sopenharmony_ci	START_KEY(rD0, rD1, rD2, rD3)
2338c2ecf20Sopenharmony_ci	bl		ppc_encrypt_block
2348c2ecf20Sopenharmony_ci	xor		rD0,rD0,rW0
2358c2ecf20Sopenharmony_ci	SAVE_DATA(rD0, 0)
2368c2ecf20Sopenharmony_ci	xor		rD1,rD1,rW1
2378c2ecf20Sopenharmony_ci	SAVE_DATA(rD1, 4)
2388c2ecf20Sopenharmony_ci	xor		rD2,rD2,rW2
2398c2ecf20Sopenharmony_ci	SAVE_DATA(rD2, 8)
2408c2ecf20Sopenharmony_ci	xor		rD3,rD3,rW3
2418c2ecf20Sopenharmony_ci	SAVE_DATA(rD3, 12)
2428c2ecf20Sopenharmony_ci	NEXT_BLOCK
2438c2ecf20Sopenharmony_ci	bt		gt,ppc_encrypt_ecb_loop
2448c2ecf20Sopenharmony_ci	FINALIZE_CRYPT(0)
2458c2ecf20Sopenharmony_ci	blr
2468c2ecf20Sopenharmony_ci
2478c2ecf20Sopenharmony_ci/*
2488c2ecf20Sopenharmony_ci * ppc_decrypt_ecb(u8 *out, const u8 *in, u32 *key_dec,
2498c2ecf20Sopenharmony_ci *		   u32 rounds, u32 bytes);
2508c2ecf20Sopenharmony_ci *
2518c2ecf20Sopenharmony_ci * called from glue layer to decrypt multiple blocks via ECB
2528c2ecf20Sopenharmony_ci * Bytes must be larger or equal 16 and only whole blocks are
2538c2ecf20Sopenharmony_ci * processed. round values are AES128 = 4, AES192 = 5 and
2548c2ecf20Sopenharmony_ci * AES256 = 6
2558c2ecf20Sopenharmony_ci *
2568c2ecf20Sopenharmony_ci */
2578c2ecf20Sopenharmony_ci_GLOBAL(ppc_decrypt_ecb)
2588c2ecf20Sopenharmony_ci	INITIALIZE_CRYPT(PPC_AES_4K_DECTAB, 0)
2598c2ecf20Sopenharmony_ci	addi		rT1,rT0,4096
2608c2ecf20Sopenharmony_cippc_decrypt_ecb_loop:
2618c2ecf20Sopenharmony_ci	LOAD_DATA(rD0, 0)
2628c2ecf20Sopenharmony_ci	mr		rKP,rKS
2638c2ecf20Sopenharmony_ci	LOAD_DATA(rD1, 4)
2648c2ecf20Sopenharmony_ci	subi		rLN,rLN,16
2658c2ecf20Sopenharmony_ci	LOAD_DATA(rD2, 8)
2668c2ecf20Sopenharmony_ci	cmpwi		rLN,15
2678c2ecf20Sopenharmony_ci	LOAD_DATA(rD3, 12)
2688c2ecf20Sopenharmony_ci	START_KEY(rD0, rD1, rD2, rD3)
2698c2ecf20Sopenharmony_ci	bl		ppc_decrypt_block
2708c2ecf20Sopenharmony_ci	xor		rD0,rD0,rW0
2718c2ecf20Sopenharmony_ci	SAVE_DATA(rD0, 0)
2728c2ecf20Sopenharmony_ci	xor		rD1,rD1,rW1
2738c2ecf20Sopenharmony_ci	SAVE_DATA(rD1, 4)
2748c2ecf20Sopenharmony_ci	xor		rD2,rD2,rW2
2758c2ecf20Sopenharmony_ci	SAVE_DATA(rD2, 8)
2768c2ecf20Sopenharmony_ci	xor		rD3,rD3,rW3
2778c2ecf20Sopenharmony_ci	SAVE_DATA(rD3, 12)
2788c2ecf20Sopenharmony_ci	NEXT_BLOCK
2798c2ecf20Sopenharmony_ci	bt		gt,ppc_decrypt_ecb_loop
2808c2ecf20Sopenharmony_ci	FINALIZE_CRYPT(0)
2818c2ecf20Sopenharmony_ci	blr
2828c2ecf20Sopenharmony_ci
2838c2ecf20Sopenharmony_ci/*
2848c2ecf20Sopenharmony_ci * ppc_encrypt_cbc(u8 *out, const u8 *in, u32 *key_enc,
2858c2ecf20Sopenharmony_ci *		   32 rounds, u32 bytes, u8 *iv);
2868c2ecf20Sopenharmony_ci *
2878c2ecf20Sopenharmony_ci * called from glue layer to encrypt multiple blocks via CBC
2888c2ecf20Sopenharmony_ci * Bytes must be larger or equal 16 and only whole blocks are
2898c2ecf20Sopenharmony_ci * processed. round values are AES128 = 4, AES192 = 5 and
2908c2ecf20Sopenharmony_ci * AES256 = 6
2918c2ecf20Sopenharmony_ci *
2928c2ecf20Sopenharmony_ci */
2938c2ecf20Sopenharmony_ci_GLOBAL(ppc_encrypt_cbc)
2948c2ecf20Sopenharmony_ci	INITIALIZE_CRYPT(PPC_AES_4K_ENCTAB, 4)
2958c2ecf20Sopenharmony_ci	LOAD_IV(rI0, 0)
2968c2ecf20Sopenharmony_ci	LOAD_IV(rI1, 4)
2978c2ecf20Sopenharmony_ci	LOAD_IV(rI2, 8)
2988c2ecf20Sopenharmony_ci	LOAD_IV(rI3, 12)
2998c2ecf20Sopenharmony_cippc_encrypt_cbc_loop:
3008c2ecf20Sopenharmony_ci	LOAD_DATA(rD0, 0)
3018c2ecf20Sopenharmony_ci	mr		rKP,rKS
3028c2ecf20Sopenharmony_ci	LOAD_DATA(rD1, 4)
3038c2ecf20Sopenharmony_ci	subi		rLN,rLN,16
3048c2ecf20Sopenharmony_ci	LOAD_DATA(rD2, 8)
3058c2ecf20Sopenharmony_ci	cmpwi		rLN,15
3068c2ecf20Sopenharmony_ci	LOAD_DATA(rD3, 12)
3078c2ecf20Sopenharmony_ci	xor		rD0,rD0,rI0
3088c2ecf20Sopenharmony_ci	xor		rD1,rD1,rI1
3098c2ecf20Sopenharmony_ci	xor		rD2,rD2,rI2
3108c2ecf20Sopenharmony_ci	xor		rD3,rD3,rI3
3118c2ecf20Sopenharmony_ci	START_KEY(rD0, rD1, rD2, rD3)
3128c2ecf20Sopenharmony_ci	bl		ppc_encrypt_block
3138c2ecf20Sopenharmony_ci	xor		rI0,rD0,rW0
3148c2ecf20Sopenharmony_ci	SAVE_DATA(rI0, 0)
3158c2ecf20Sopenharmony_ci	xor		rI1,rD1,rW1
3168c2ecf20Sopenharmony_ci	SAVE_DATA(rI1, 4)
3178c2ecf20Sopenharmony_ci	xor		rI2,rD2,rW2
3188c2ecf20Sopenharmony_ci	SAVE_DATA(rI2, 8)
3198c2ecf20Sopenharmony_ci	xor		rI3,rD3,rW3
3208c2ecf20Sopenharmony_ci	SAVE_DATA(rI3, 12)
3218c2ecf20Sopenharmony_ci	NEXT_BLOCK
3228c2ecf20Sopenharmony_ci	bt		gt,ppc_encrypt_cbc_loop
3238c2ecf20Sopenharmony_ci	START_IV
3248c2ecf20Sopenharmony_ci	SAVE_IV(rI0, 0)
3258c2ecf20Sopenharmony_ci	SAVE_IV(rI1, 4)
3268c2ecf20Sopenharmony_ci	SAVE_IV(rI2, 8)
3278c2ecf20Sopenharmony_ci	SAVE_IV(rI3, 12)
3288c2ecf20Sopenharmony_ci	FINALIZE_CRYPT(4)
3298c2ecf20Sopenharmony_ci	blr
3308c2ecf20Sopenharmony_ci
3318c2ecf20Sopenharmony_ci/*
3328c2ecf20Sopenharmony_ci * ppc_decrypt_cbc(u8 *out, const u8 *in, u32 *key_dec,
3338c2ecf20Sopenharmony_ci *		   u32 rounds, u32 bytes, u8 *iv);
3348c2ecf20Sopenharmony_ci *
3358c2ecf20Sopenharmony_ci * called from glue layer to decrypt multiple blocks via CBC
3368c2ecf20Sopenharmony_ci * round values are AES128 = 4, AES192 = 5, AES256 = 6
3378c2ecf20Sopenharmony_ci *
3388c2ecf20Sopenharmony_ci */
3398c2ecf20Sopenharmony_ci_GLOBAL(ppc_decrypt_cbc)
3408c2ecf20Sopenharmony_ci	INITIALIZE_CRYPT(PPC_AES_4K_DECTAB, 4)
3418c2ecf20Sopenharmony_ci	li		rT1,15
3428c2ecf20Sopenharmony_ci	LOAD_IV(rI0, 0)
3438c2ecf20Sopenharmony_ci	andc		rLN,rLN,rT1
3448c2ecf20Sopenharmony_ci	LOAD_IV(rI1, 4)
3458c2ecf20Sopenharmony_ci	subi		rLN,rLN,16
3468c2ecf20Sopenharmony_ci	LOAD_IV(rI2, 8)
3478c2ecf20Sopenharmony_ci	add		rSP,rSP,rLN	/* reverse processing		*/
3488c2ecf20Sopenharmony_ci	LOAD_IV(rI3, 12)
3498c2ecf20Sopenharmony_ci	add		rDP,rDP,rLN
3508c2ecf20Sopenharmony_ci	LOAD_DATA(rD0, 0)
3518c2ecf20Sopenharmony_ci	addi		rT1,rT0,4096
3528c2ecf20Sopenharmony_ci	LOAD_DATA(rD1, 4)
3538c2ecf20Sopenharmony_ci	LOAD_DATA(rD2, 8)
3548c2ecf20Sopenharmony_ci	LOAD_DATA(rD3, 12)
3558c2ecf20Sopenharmony_ci	START_IV
3568c2ecf20Sopenharmony_ci	SAVE_IV(rD0, 0)
3578c2ecf20Sopenharmony_ci	SAVE_IV(rD1, 4)
3588c2ecf20Sopenharmony_ci	SAVE_IV(rD2, 8)
3598c2ecf20Sopenharmony_ci	cmpwi		rLN,16
3608c2ecf20Sopenharmony_ci	SAVE_IV(rD3, 12)
3618c2ecf20Sopenharmony_ci	bt		lt,ppc_decrypt_cbc_end
3628c2ecf20Sopenharmony_cippc_decrypt_cbc_loop:
3638c2ecf20Sopenharmony_ci	mr		rKP,rKS
3648c2ecf20Sopenharmony_ci	START_KEY(rD0, rD1, rD2, rD3)
3658c2ecf20Sopenharmony_ci	bl		ppc_decrypt_block
3668c2ecf20Sopenharmony_ci	subi		rLN,rLN,16
3678c2ecf20Sopenharmony_ci	subi		rSP,rSP,CBC_DEC
3688c2ecf20Sopenharmony_ci	xor		rW0,rD0,rW0
3698c2ecf20Sopenharmony_ci	LOAD_DATA(rD0, 0)
3708c2ecf20Sopenharmony_ci	xor		rW1,rD1,rW1
3718c2ecf20Sopenharmony_ci	LOAD_DATA(rD1, 4)
3728c2ecf20Sopenharmony_ci	xor		rW2,rD2,rW2
3738c2ecf20Sopenharmony_ci	LOAD_DATA(rD2, 8)
3748c2ecf20Sopenharmony_ci	xor		rW3,rD3,rW3
3758c2ecf20Sopenharmony_ci	LOAD_DATA(rD3, 12)
3768c2ecf20Sopenharmony_ci	xor		rW0,rW0,rD0
3778c2ecf20Sopenharmony_ci	SAVE_DATA(rW0, 0)
3788c2ecf20Sopenharmony_ci	xor		rW1,rW1,rD1
3798c2ecf20Sopenharmony_ci	SAVE_DATA(rW1, 4)
3808c2ecf20Sopenharmony_ci	xor		rW2,rW2,rD2
3818c2ecf20Sopenharmony_ci	SAVE_DATA(rW2, 8)
3828c2ecf20Sopenharmony_ci	xor		rW3,rW3,rD3
3838c2ecf20Sopenharmony_ci	SAVE_DATA(rW3, 12)
3848c2ecf20Sopenharmony_ci	cmpwi		rLN,15
3858c2ecf20Sopenharmony_ci	subi		rDP,rDP,CBC_DEC
3868c2ecf20Sopenharmony_ci	bt		gt,ppc_decrypt_cbc_loop
3878c2ecf20Sopenharmony_cippc_decrypt_cbc_end:
3888c2ecf20Sopenharmony_ci	mr		rKP,rKS
3898c2ecf20Sopenharmony_ci	START_KEY(rD0, rD1, rD2, rD3)
3908c2ecf20Sopenharmony_ci	bl		ppc_decrypt_block
3918c2ecf20Sopenharmony_ci	xor		rW0,rW0,rD0
3928c2ecf20Sopenharmony_ci	xor		rW1,rW1,rD1
3938c2ecf20Sopenharmony_ci	xor		rW2,rW2,rD2
3948c2ecf20Sopenharmony_ci	xor		rW3,rW3,rD3
3958c2ecf20Sopenharmony_ci	xor		rW0,rW0,rI0	/* decrypt with initial IV	*/
3968c2ecf20Sopenharmony_ci	SAVE_DATA(rW0, 0)
3978c2ecf20Sopenharmony_ci	xor		rW1,rW1,rI1
3988c2ecf20Sopenharmony_ci	SAVE_DATA(rW1, 4)
3998c2ecf20Sopenharmony_ci	xor		rW2,rW2,rI2
4008c2ecf20Sopenharmony_ci	SAVE_DATA(rW2, 8)
4018c2ecf20Sopenharmony_ci	xor		rW3,rW3,rI3
4028c2ecf20Sopenharmony_ci	SAVE_DATA(rW3, 12)
4038c2ecf20Sopenharmony_ci	FINALIZE_CRYPT(4)
4048c2ecf20Sopenharmony_ci	blr
4058c2ecf20Sopenharmony_ci
4068c2ecf20Sopenharmony_ci/*
4078c2ecf20Sopenharmony_ci * ppc_crypt_ctr(u8 *out, const u8 *in, u32 *key_enc,
4088c2ecf20Sopenharmony_ci *		 u32 rounds, u32 bytes, u8 *iv);
4098c2ecf20Sopenharmony_ci *
4108c2ecf20Sopenharmony_ci * called from glue layer to encrypt/decrypt multiple blocks
4118c2ecf20Sopenharmony_ci * via CTR. Number of bytes does not need to be a multiple of
4128c2ecf20Sopenharmony_ci * 16. Round values are AES128 = 4, AES192 = 5, AES256 = 6
4138c2ecf20Sopenharmony_ci *
4148c2ecf20Sopenharmony_ci */
4158c2ecf20Sopenharmony_ci_GLOBAL(ppc_crypt_ctr)
4168c2ecf20Sopenharmony_ci	INITIALIZE_CRYPT(PPC_AES_4K_ENCTAB, 4)
4178c2ecf20Sopenharmony_ci	LOAD_IV(rI0, 0)
4188c2ecf20Sopenharmony_ci	LOAD_IV(rI1, 4)
4198c2ecf20Sopenharmony_ci	LOAD_IV(rI2, 8)
4208c2ecf20Sopenharmony_ci	cmpwi		rLN,16
4218c2ecf20Sopenharmony_ci	LOAD_IV(rI3, 12)
4228c2ecf20Sopenharmony_ci	START_IV
4238c2ecf20Sopenharmony_ci	bt		lt,ppc_crypt_ctr_partial
4248c2ecf20Sopenharmony_cippc_crypt_ctr_loop:
4258c2ecf20Sopenharmony_ci	mr		rKP,rKS
4268c2ecf20Sopenharmony_ci	START_KEY(rI0, rI1, rI2, rI3)
4278c2ecf20Sopenharmony_ci	bl		ppc_encrypt_block
4288c2ecf20Sopenharmony_ci	xor		rW0,rD0,rW0
4298c2ecf20Sopenharmony_ci	xor		rW1,rD1,rW1
4308c2ecf20Sopenharmony_ci	xor		rW2,rD2,rW2
4318c2ecf20Sopenharmony_ci	xor		rW3,rD3,rW3
4328c2ecf20Sopenharmony_ci	LOAD_DATA(rD0, 0)
4338c2ecf20Sopenharmony_ci	subi		rLN,rLN,16
4348c2ecf20Sopenharmony_ci	LOAD_DATA(rD1, 4)
4358c2ecf20Sopenharmony_ci	LOAD_DATA(rD2, 8)
4368c2ecf20Sopenharmony_ci	LOAD_DATA(rD3, 12)
4378c2ecf20Sopenharmony_ci	xor		rD0,rD0,rW0
4388c2ecf20Sopenharmony_ci	SAVE_DATA(rD0, 0)
4398c2ecf20Sopenharmony_ci	xor		rD1,rD1,rW1
4408c2ecf20Sopenharmony_ci	SAVE_DATA(rD1, 4)
4418c2ecf20Sopenharmony_ci	xor		rD2,rD2,rW2
4428c2ecf20Sopenharmony_ci	SAVE_DATA(rD2, 8)
4438c2ecf20Sopenharmony_ci	xor		rD3,rD3,rW3
4448c2ecf20Sopenharmony_ci	SAVE_DATA(rD3, 12)
4458c2ecf20Sopenharmony_ci	addic		rI3,rI3,1	/* increase counter			*/
4468c2ecf20Sopenharmony_ci	addze		rI2,rI2
4478c2ecf20Sopenharmony_ci	addze		rI1,rI1
4488c2ecf20Sopenharmony_ci	addze		rI0,rI0
4498c2ecf20Sopenharmony_ci	NEXT_BLOCK
4508c2ecf20Sopenharmony_ci	cmpwi		rLN,15
4518c2ecf20Sopenharmony_ci	bt		gt,ppc_crypt_ctr_loop
4528c2ecf20Sopenharmony_cippc_crypt_ctr_partial:
4538c2ecf20Sopenharmony_ci	cmpwi		rLN,0
4548c2ecf20Sopenharmony_ci	bt		eq,ppc_crypt_ctr_end
4558c2ecf20Sopenharmony_ci	mr		rKP,rKS
4568c2ecf20Sopenharmony_ci	START_KEY(rI0, rI1, rI2, rI3)
4578c2ecf20Sopenharmony_ci	bl		ppc_encrypt_block
4588c2ecf20Sopenharmony_ci	xor		rW0,rD0,rW0
4598c2ecf20Sopenharmony_ci	SAVE_IV(rW0, 0)
4608c2ecf20Sopenharmony_ci	xor		rW1,rD1,rW1
4618c2ecf20Sopenharmony_ci	SAVE_IV(rW1, 4)
4628c2ecf20Sopenharmony_ci	xor		rW2,rD2,rW2
4638c2ecf20Sopenharmony_ci	SAVE_IV(rW2, 8)
4648c2ecf20Sopenharmony_ci	xor		rW3,rD3,rW3
4658c2ecf20Sopenharmony_ci	SAVE_IV(rW3, 12)
4668c2ecf20Sopenharmony_ci	mtctr		rLN
4678c2ecf20Sopenharmony_ci	subi		rIP,rIP,CTR_DEC
4688c2ecf20Sopenharmony_ci	subi		rSP,rSP,1
4698c2ecf20Sopenharmony_ci	subi		rDP,rDP,1
4708c2ecf20Sopenharmony_cippc_crypt_ctr_xorbyte:
4718c2ecf20Sopenharmony_ci	lbzu		rW4,1(rIP)	/* bytewise xor for partial block	*/
4728c2ecf20Sopenharmony_ci	lbzu		rW5,1(rSP)
4738c2ecf20Sopenharmony_ci	xor		rW4,rW4,rW5
4748c2ecf20Sopenharmony_ci	stbu		rW4,1(rDP)
4758c2ecf20Sopenharmony_ci	bdnz		ppc_crypt_ctr_xorbyte
4768c2ecf20Sopenharmony_ci	subf		rIP,rLN,rIP
4778c2ecf20Sopenharmony_ci	addi		rIP,rIP,1
4788c2ecf20Sopenharmony_ci	addic		rI3,rI3,1
4798c2ecf20Sopenharmony_ci	addze		rI2,rI2
4808c2ecf20Sopenharmony_ci	addze		rI1,rI1
4818c2ecf20Sopenharmony_ci	addze		rI0,rI0
4828c2ecf20Sopenharmony_cippc_crypt_ctr_end:
4838c2ecf20Sopenharmony_ci	SAVE_IV(rI0, 0)
4848c2ecf20Sopenharmony_ci	SAVE_IV(rI1, 4)
4858c2ecf20Sopenharmony_ci	SAVE_IV(rI2, 8)
4868c2ecf20Sopenharmony_ci	SAVE_IV(rI3, 12)
4878c2ecf20Sopenharmony_ci	FINALIZE_CRYPT(4)
4888c2ecf20Sopenharmony_ci	blr
4898c2ecf20Sopenharmony_ci
4908c2ecf20Sopenharmony_ci/*
4918c2ecf20Sopenharmony_ci * ppc_encrypt_xts(u8 *out, const u8 *in, u32 *key_enc,
4928c2ecf20Sopenharmony_ci *		   u32 rounds, u32 bytes, u8 *iv, u32 *key_twk);
4938c2ecf20Sopenharmony_ci *
4948c2ecf20Sopenharmony_ci * called from glue layer to encrypt multiple blocks via XTS
4958c2ecf20Sopenharmony_ci * If key_twk is given, the initial IV encryption will be
4968c2ecf20Sopenharmony_ci * processed too. Round values are AES128 = 4, AES192 = 5,
4978c2ecf20Sopenharmony_ci * AES256 = 6
4988c2ecf20Sopenharmony_ci *
4998c2ecf20Sopenharmony_ci */
5008c2ecf20Sopenharmony_ci_GLOBAL(ppc_encrypt_xts)
5018c2ecf20Sopenharmony_ci	INITIALIZE_CRYPT(PPC_AES_4K_ENCTAB, 8)
5028c2ecf20Sopenharmony_ci	LOAD_IV(rI0, 0)
5038c2ecf20Sopenharmony_ci	LOAD_IV(rI1, 4)
5048c2ecf20Sopenharmony_ci	LOAD_IV(rI2, 8)
5058c2ecf20Sopenharmony_ci	cmpwi		rKT,0
5068c2ecf20Sopenharmony_ci	LOAD_IV(rI3, 12)
5078c2ecf20Sopenharmony_ci	bt		eq,ppc_encrypt_xts_notweak
5088c2ecf20Sopenharmony_ci	mr		rKP,rKT
5098c2ecf20Sopenharmony_ci	START_KEY(rI0, rI1, rI2, rI3)
5108c2ecf20Sopenharmony_ci	bl		ppc_encrypt_block
5118c2ecf20Sopenharmony_ci	xor		rI0,rD0,rW0
5128c2ecf20Sopenharmony_ci	xor		rI1,rD1,rW1
5138c2ecf20Sopenharmony_ci	xor		rI2,rD2,rW2
5148c2ecf20Sopenharmony_ci	xor		rI3,rD3,rW3
5158c2ecf20Sopenharmony_cippc_encrypt_xts_notweak:
5168c2ecf20Sopenharmony_ci	ENDIAN_SWAP(rG0, rG1, rI0, rI1)
5178c2ecf20Sopenharmony_ci	ENDIAN_SWAP(rG2, rG3, rI2, rI3)
5188c2ecf20Sopenharmony_cippc_encrypt_xts_loop:
5198c2ecf20Sopenharmony_ci	LOAD_DATA(rD0, 0)
5208c2ecf20Sopenharmony_ci	mr		rKP,rKS
5218c2ecf20Sopenharmony_ci	LOAD_DATA(rD1, 4)
5228c2ecf20Sopenharmony_ci	subi		rLN,rLN,16
5238c2ecf20Sopenharmony_ci	LOAD_DATA(rD2, 8)
5248c2ecf20Sopenharmony_ci	LOAD_DATA(rD3, 12)
5258c2ecf20Sopenharmony_ci	xor		rD0,rD0,rI0
5268c2ecf20Sopenharmony_ci	xor		rD1,rD1,rI1
5278c2ecf20Sopenharmony_ci	xor		rD2,rD2,rI2
5288c2ecf20Sopenharmony_ci	xor		rD3,rD3,rI3
5298c2ecf20Sopenharmony_ci	START_KEY(rD0, rD1, rD2, rD3)
5308c2ecf20Sopenharmony_ci	bl		ppc_encrypt_block
5318c2ecf20Sopenharmony_ci	xor		rD0,rD0,rW0
5328c2ecf20Sopenharmony_ci	xor		rD1,rD1,rW1
5338c2ecf20Sopenharmony_ci	xor		rD2,rD2,rW2
5348c2ecf20Sopenharmony_ci	xor		rD3,rD3,rW3
5358c2ecf20Sopenharmony_ci	xor		rD0,rD0,rI0
5368c2ecf20Sopenharmony_ci	SAVE_DATA(rD0, 0)
5378c2ecf20Sopenharmony_ci	xor		rD1,rD1,rI1
5388c2ecf20Sopenharmony_ci	SAVE_DATA(rD1, 4)
5398c2ecf20Sopenharmony_ci	xor		rD2,rD2,rI2
5408c2ecf20Sopenharmony_ci	SAVE_DATA(rD2, 8)
5418c2ecf20Sopenharmony_ci	xor		rD3,rD3,rI3
5428c2ecf20Sopenharmony_ci	SAVE_DATA(rD3, 12)
5438c2ecf20Sopenharmony_ci	GF128_MUL(rG0, rG1, rG2, rG3, rW0)
5448c2ecf20Sopenharmony_ci	ENDIAN_SWAP(rI0, rI1, rG0, rG1)
5458c2ecf20Sopenharmony_ci	ENDIAN_SWAP(rI2, rI3, rG2, rG3)
5468c2ecf20Sopenharmony_ci	cmpwi		rLN,0
5478c2ecf20Sopenharmony_ci	NEXT_BLOCK
5488c2ecf20Sopenharmony_ci	bt		gt,ppc_encrypt_xts_loop
5498c2ecf20Sopenharmony_ci	START_IV
5508c2ecf20Sopenharmony_ci	SAVE_IV(rI0, 0)
5518c2ecf20Sopenharmony_ci	SAVE_IV(rI1, 4)
5528c2ecf20Sopenharmony_ci	SAVE_IV(rI2, 8)
5538c2ecf20Sopenharmony_ci	SAVE_IV(rI3, 12)
5548c2ecf20Sopenharmony_ci	FINALIZE_CRYPT(8)
5558c2ecf20Sopenharmony_ci	blr
5568c2ecf20Sopenharmony_ci
5578c2ecf20Sopenharmony_ci/*
5588c2ecf20Sopenharmony_ci * ppc_decrypt_xts(u8 *out, const u8 *in, u32 *key_dec,
5598c2ecf20Sopenharmony_ci *		   u32 rounds, u32 blocks, u8 *iv, u32 *key_twk);
5608c2ecf20Sopenharmony_ci *
5618c2ecf20Sopenharmony_ci * called from glue layer to decrypt multiple blocks via XTS
5628c2ecf20Sopenharmony_ci * If key_twk is given, the initial IV encryption will be
5638c2ecf20Sopenharmony_ci * processed too. Round values are AES128 = 4, AES192 = 5,
5648c2ecf20Sopenharmony_ci * AES256 = 6
5658c2ecf20Sopenharmony_ci *
5668c2ecf20Sopenharmony_ci */
5678c2ecf20Sopenharmony_ci_GLOBAL(ppc_decrypt_xts)
5688c2ecf20Sopenharmony_ci	INITIALIZE_CRYPT(PPC_AES_4K_DECTAB, 8)
5698c2ecf20Sopenharmony_ci	LOAD_IV(rI0, 0)
5708c2ecf20Sopenharmony_ci	addi		rT1,rT0,4096
5718c2ecf20Sopenharmony_ci	LOAD_IV(rI1, 4)
5728c2ecf20Sopenharmony_ci	LOAD_IV(rI2, 8)
5738c2ecf20Sopenharmony_ci	cmpwi		rKT,0
5748c2ecf20Sopenharmony_ci	LOAD_IV(rI3, 12)
5758c2ecf20Sopenharmony_ci	bt		eq,ppc_decrypt_xts_notweak
5768c2ecf20Sopenharmony_ci	subi		rT0,rT0,4096
5778c2ecf20Sopenharmony_ci	mr		rKP,rKT
5788c2ecf20Sopenharmony_ci	START_KEY(rI0, rI1, rI2, rI3)
5798c2ecf20Sopenharmony_ci	bl		ppc_encrypt_block
5808c2ecf20Sopenharmony_ci	xor		rI0,rD0,rW0
5818c2ecf20Sopenharmony_ci	xor		rI1,rD1,rW1
5828c2ecf20Sopenharmony_ci	xor		rI2,rD2,rW2
5838c2ecf20Sopenharmony_ci	xor		rI3,rD3,rW3
5848c2ecf20Sopenharmony_ci	addi		rT0,rT0,4096
5858c2ecf20Sopenharmony_cippc_decrypt_xts_notweak:
5868c2ecf20Sopenharmony_ci	ENDIAN_SWAP(rG0, rG1, rI0, rI1)
5878c2ecf20Sopenharmony_ci	ENDIAN_SWAP(rG2, rG3, rI2, rI3)
5888c2ecf20Sopenharmony_cippc_decrypt_xts_loop:
5898c2ecf20Sopenharmony_ci	LOAD_DATA(rD0, 0)
5908c2ecf20Sopenharmony_ci	mr		rKP,rKS
5918c2ecf20Sopenharmony_ci	LOAD_DATA(rD1, 4)
5928c2ecf20Sopenharmony_ci	subi		rLN,rLN,16
5938c2ecf20Sopenharmony_ci	LOAD_DATA(rD2, 8)
5948c2ecf20Sopenharmony_ci	LOAD_DATA(rD3, 12)
5958c2ecf20Sopenharmony_ci	xor		rD0,rD0,rI0
5968c2ecf20Sopenharmony_ci	xor		rD1,rD1,rI1
5978c2ecf20Sopenharmony_ci	xor		rD2,rD2,rI2
5988c2ecf20Sopenharmony_ci	xor		rD3,rD3,rI3
5998c2ecf20Sopenharmony_ci	START_KEY(rD0, rD1, rD2, rD3)
6008c2ecf20Sopenharmony_ci	bl		ppc_decrypt_block
6018c2ecf20Sopenharmony_ci	xor		rD0,rD0,rW0
6028c2ecf20Sopenharmony_ci	xor		rD1,rD1,rW1
6038c2ecf20Sopenharmony_ci	xor		rD2,rD2,rW2
6048c2ecf20Sopenharmony_ci	xor		rD3,rD3,rW3
6058c2ecf20Sopenharmony_ci	xor		rD0,rD0,rI0
6068c2ecf20Sopenharmony_ci	SAVE_DATA(rD0, 0)
6078c2ecf20Sopenharmony_ci	xor		rD1,rD1,rI1
6088c2ecf20Sopenharmony_ci	SAVE_DATA(rD1, 4)
6098c2ecf20Sopenharmony_ci	xor		rD2,rD2,rI2
6108c2ecf20Sopenharmony_ci	SAVE_DATA(rD2, 8)
6118c2ecf20Sopenharmony_ci	xor		rD3,rD3,rI3
6128c2ecf20Sopenharmony_ci	SAVE_DATA(rD3, 12)
6138c2ecf20Sopenharmony_ci	GF128_MUL(rG0, rG1, rG2, rG3, rW0)
6148c2ecf20Sopenharmony_ci	ENDIAN_SWAP(rI0, rI1, rG0, rG1)
6158c2ecf20Sopenharmony_ci	ENDIAN_SWAP(rI2, rI3, rG2, rG3)
6168c2ecf20Sopenharmony_ci	cmpwi		rLN,0
6178c2ecf20Sopenharmony_ci	NEXT_BLOCK
6188c2ecf20Sopenharmony_ci	bt		gt,ppc_decrypt_xts_loop
6198c2ecf20Sopenharmony_ci	START_IV
6208c2ecf20Sopenharmony_ci	SAVE_IV(rI0, 0)
6218c2ecf20Sopenharmony_ci	SAVE_IV(rI1, 4)
6228c2ecf20Sopenharmony_ci	SAVE_IV(rI2, 8)
6238c2ecf20Sopenharmony_ci	SAVE_IV(rI3, 12)
6248c2ecf20Sopenharmony_ci	FINALIZE_CRYPT(8)
6258c2ecf20Sopenharmony_ci	blr
626