| /* | 
 |  * Key handling functions for PPC AES implementation | 
 |  * | 
 |  * Copyright (c) 2015 Markus Stockhausen <stockhausen@collogia.de> | 
 |  * | 
 |  * This program is free software; you can redistribute it and/or modify it | 
 |  * under the terms of the GNU General Public License as published by the Free | 
 |  * Software Foundation; either version 2 of the License, or (at your option) | 
 |  * any later version. | 
 |  * | 
 |  */ | 
 |  | 
 | #include <asm/ppc_asm.h> | 
 |  | 
 | #ifdef __BIG_ENDIAN__ | 
 | #define LOAD_KEY(d, s, off) \ | 
 | 	lwz		d,off(s); | 
 | #else | 
 | #define LOAD_KEY(d, s, off) \ | 
 | 	li		r0,off; \ | 
 | 	lwbrx		d,s,r0; | 
 | #endif | 
 |  | 
 | #define INITIALIZE_KEY \ | 
 | 	stwu		r1,-32(r1);	/* create stack frame		*/ \ | 
 | 	stw		r14,8(r1);	/* save registers		*/ \ | 
 | 	stw		r15,12(r1);					   \ | 
 | 	stw		r16,16(r1); | 
 |  | 
 | #define FINALIZE_KEY \ | 
 | 	lwz		r14,8(r1);	/* restore registers		*/ \ | 
 | 	lwz		r15,12(r1);					   \ | 
 | 	lwz		r16,16(r1);					   \ | 
 | 	xor		r5,r5,r5;	/* clear sensitive data		*/ \ | 
 | 	xor		r6,r6,r6;					   \ | 
 | 	xor		r7,r7,r7;					   \ | 
 | 	xor		r8,r8,r8;					   \ | 
 | 	xor		r9,r9,r9;					   \ | 
 | 	xor		r10,r10,r10;					   \ | 
 | 	xor		r11,r11,r11;					   \ | 
 | 	xor		r12,r12,r12;					   \ | 
 | 	addi		r1,r1,32;	/* cleanup stack		*/ | 
 |  | 
 | #define LS_BOX(r, t1, t2) \ | 
 | 	lis		t2,PPC_AES_4K_ENCTAB@h;				   \ | 
 | 	ori		t2,t2,PPC_AES_4K_ENCTAB@l;			   \ | 
 | 	rlwimi		t2,r,4,20,27;					   \ | 
 | 	lbz		t1,8(t2);					   \ | 
 | 	rlwimi		r,t1,0,24,31;					   \ | 
 | 	rlwimi		t2,r,28,20,27;					   \ | 
 | 	lbz		t1,8(t2);					   \ | 
 | 	rlwimi		r,t1,8,16,23;					   \ | 
 | 	rlwimi		t2,r,20,20,27;					   \ | 
 | 	lbz		t1,8(t2);					   \ | 
 | 	rlwimi		r,t1,16,8,15;					   \ | 
 | 	rlwimi		t2,r,12,20,27;					   \ | 
 | 	lbz		t1,8(t2);					   \ | 
 | 	rlwimi		r,t1,24,0,7; | 
 |  | 
 | #define GF8_MUL(out, in, t1, t2) \ | 
 | 	lis t1,0x8080;			/* multiplication in GF8	*/ \ | 
 | 	ori t1,t1,0x8080; 						   \ | 
 | 	and t1,t1,in; 							   \ | 
 | 	srwi t1,t1,7; 							   \ | 
 | 	mulli t1,t1,0x1b; 						   \ | 
 | 	lis t2,0x7f7f; 							   \ | 
 | 	ori t2,t2,0x7f7f; 						   \ | 
 | 	and t2,t2,in; 							   \ | 
 | 	slwi t2,t2,1; 							   \ | 
 | 	xor out,t1,t2; | 
 |  | 
 | /* | 
 |  * ppc_expand_key_128(u32 *key_enc, const u8 *key) | 
 |  * | 
 |  * Expand 128 bit key into 176 bytes encryption key. It consists of | 
 |  * key itself plus 10 rounds with 16 bytes each | 
 |  * | 
 |  */ | 
 | _GLOBAL(ppc_expand_key_128) | 
 | 	INITIALIZE_KEY | 
 | 	LOAD_KEY(r5,r4,0) | 
 | 	LOAD_KEY(r6,r4,4) | 
 | 	LOAD_KEY(r7,r4,8) | 
 | 	LOAD_KEY(r8,r4,12) | 
 | 	stw		r5,0(r3)	/* key[0..3] = input data	*/ | 
 | 	stw		r6,4(r3) | 
 | 	stw		r7,8(r3) | 
 | 	stw		r8,12(r3) | 
 | 	li		r16,10		/* 10 expansion rounds		*/ | 
 | 	lis		r0,0x0100	/* RCO(1)			*/ | 
 | ppc_expand_128_loop: | 
 | 	addi		r3,r3,16 | 
 | 	mr		r14,r8		/* apply LS_BOX to 4th temp	*/ | 
 | 	rotlwi		r14,r14,8 | 
 | 	LS_BOX(r14, r15, r4) | 
 | 	xor		r14,r14,r0 | 
 | 	xor		r5,r5,r14	/* xor next 4 keys		*/ | 
 | 	xor		r6,r6,r5 | 
 | 	xor		r7,r7,r6 | 
 | 	xor		r8,r8,r7 | 
 | 	stw		r5,0(r3)	/* store next 4 keys		*/ | 
 | 	stw		r6,4(r3) | 
 | 	stw		r7,8(r3) | 
 | 	stw		r8,12(r3) | 
 | 	GF8_MUL(r0, r0, r4, r14)	/* multiply RCO by 2 in GF	*/ | 
 | 	subi		r16,r16,1 | 
 | 	cmpwi		r16,0 | 
 | 	bt		eq,ppc_expand_128_end | 
 | 	b		ppc_expand_128_loop | 
 | ppc_expand_128_end: | 
 | 	FINALIZE_KEY | 
 | 	blr | 
 |  | 
 | /* | 
 |  * ppc_expand_key_192(u32 *key_enc, const u8 *key) | 
 |  * | 
 |  * Expand 192 bit key into 208 bytes encryption key. It consists of key | 
 |  * itself plus 12 rounds with 16 bytes each | 
 |  * | 
 |  */ | 
 | _GLOBAL(ppc_expand_key_192) | 
 | 	INITIALIZE_KEY | 
 | 	LOAD_KEY(r5,r4,0) | 
 | 	LOAD_KEY(r6,r4,4) | 
 | 	LOAD_KEY(r7,r4,8) | 
 | 	LOAD_KEY(r8,r4,12) | 
 | 	LOAD_KEY(r9,r4,16) | 
 | 	LOAD_KEY(r10,r4,20) | 
 | 	stw		r5,0(r3) | 
 | 	stw		r6,4(r3) | 
 | 	stw		r7,8(r3) | 
 | 	stw		r8,12(r3) | 
 | 	stw		r9,16(r3) | 
 | 	stw		r10,20(r3) | 
 | 	li		r16,8		/* 8 expansion rounds		*/ | 
 | 	lis		r0,0x0100	/* RCO(1)			*/ | 
 | ppc_expand_192_loop: | 
 | 	addi		r3,r3,24 | 
 | 	mr		r14,r10		/* apply LS_BOX to 6th temp	*/ | 
 | 	rotlwi		r14,r14,8 | 
 | 	LS_BOX(r14, r15, r4) | 
 | 	xor		r14,r14,r0 | 
 | 	xor		r5,r5,r14	/* xor next 6 keys		*/ | 
 | 	xor		r6,r6,r5 | 
 | 	xor		r7,r7,r6 | 
 | 	xor		r8,r8,r7 | 
 | 	xor		r9,r9,r8 | 
 | 	xor		r10,r10,r9 | 
 | 	stw		r5,0(r3) | 
 | 	stw		r6,4(r3) | 
 | 	stw		r7,8(r3) | 
 | 	stw		r8,12(r3) | 
 | 	subi		r16,r16,1 | 
 | 	cmpwi		r16,0		/* last round early kick out	*/ | 
 | 	bt		eq,ppc_expand_192_end | 
 | 	stw		r9,16(r3) | 
 | 	stw		r10,20(r3) | 
 | 	GF8_MUL(r0, r0, r4, r14)	/* multiply RCO GF8		*/ | 
 | 	b		ppc_expand_192_loop | 
 | ppc_expand_192_end: | 
 | 	FINALIZE_KEY | 
 | 	blr | 
 |  | 
 | /* | 
 |  * ppc_expand_key_256(u32 *key_enc, const u8 *key) | 
 |  * | 
 |  * Expand 256 bit key into 240 bytes encryption key. It consists of key | 
 |  * itself plus 14 rounds with 16 bytes each | 
 |  * | 
 |  */ | 
 | _GLOBAL(ppc_expand_key_256) | 
 | 	INITIALIZE_KEY | 
 | 	LOAD_KEY(r5,r4,0) | 
 | 	LOAD_KEY(r6,r4,4) | 
 | 	LOAD_KEY(r7,r4,8) | 
 | 	LOAD_KEY(r8,r4,12) | 
 | 	LOAD_KEY(r9,r4,16) | 
 | 	LOAD_KEY(r10,r4,20) | 
 | 	LOAD_KEY(r11,r4,24) | 
 | 	LOAD_KEY(r12,r4,28) | 
 | 	stw		r5,0(r3) | 
 | 	stw		r6,4(r3) | 
 | 	stw		r7,8(r3) | 
 | 	stw		r8,12(r3) | 
 | 	stw		r9,16(r3) | 
 | 	stw		r10,20(r3) | 
 | 	stw		r11,24(r3) | 
 | 	stw		r12,28(r3) | 
 | 	li		r16,7		/* 7 expansion rounds		*/ | 
 | 	lis		r0,0x0100	/* RCO(1)			*/ | 
 | ppc_expand_256_loop: | 
 | 	addi		r3,r3,32 | 
 | 	mr		r14,r12		/* apply LS_BOX to 8th temp	*/ | 
 | 	rotlwi		r14,r14,8 | 
 | 	LS_BOX(r14, r15, r4) | 
 | 	xor		r14,r14,r0 | 
 | 	xor		r5,r5,r14	/* xor 4 keys			*/ | 
 | 	xor		r6,r6,r5 | 
 | 	xor		r7,r7,r6 | 
 | 	xor		r8,r8,r7 | 
 | 	mr		r14,r8 | 
 | 	LS_BOX(r14, r15, r4)		/* apply LS_BOX to 4th temp	*/ | 
 | 	xor		r9,r9,r14	/* xor 4 keys			*/ | 
 | 	xor		r10,r10,r9 | 
 | 	xor		r11,r11,r10 | 
 | 	xor		r12,r12,r11 | 
 | 	stw		r5,0(r3) | 
 | 	stw		r6,4(r3) | 
 | 	stw		r7,8(r3) | 
 | 	stw		r8,12(r3) | 
 | 	subi		r16,r16,1 | 
 | 	cmpwi		r16,0		/* last round early kick out	*/ | 
 | 	bt		eq,ppc_expand_256_end | 
 | 	stw		r9,16(r3) | 
 | 	stw		r10,20(r3) | 
 | 	stw		r11,24(r3) | 
 | 	stw		r12,28(r3) | 
 | 	GF8_MUL(r0, r0, r4, r14) | 
 | 	b		ppc_expand_256_loop | 
 | ppc_expand_256_end: | 
 | 	FINALIZE_KEY | 
 | 	blr | 
 |  | 
 | /* | 
 |  * ppc_generate_decrypt_key: derive decryption key from encryption key | 
 |  * number of bytes to handle are calculated from length of key (16/24/32) | 
 |  * | 
 |  */ | 
 | _GLOBAL(ppc_generate_decrypt_key) | 
 | 	addi		r6,r5,24 | 
 | 	slwi		r6,r6,2 | 
 | 	lwzx		r7,r4,r6	/* first/last 4 words are same	*/ | 
 | 	stw		r7,0(r3) | 
 | 	lwz		r7,0(r4) | 
 | 	stwx		r7,r3,r6 | 
 | 	addi		r6,r6,4 | 
 | 	lwzx		r7,r4,r6 | 
 | 	stw		r7,4(r3) | 
 | 	lwz		r7,4(r4) | 
 | 	stwx		r7,r3,r6 | 
 | 	addi		r6,r6,4 | 
 | 	lwzx		r7,r4,r6 | 
 | 	stw		r7,8(r3) | 
 | 	lwz		r7,8(r4) | 
 | 	stwx		r7,r3,r6 | 
 | 	addi		r6,r6,4 | 
 | 	lwzx		r7,r4,r6 | 
 | 	stw		r7,12(r3) | 
 | 	lwz		r7,12(r4) | 
 | 	stwx		r7,r3,r6 | 
 | 	addi		r3,r3,16 | 
 | 	add		r4,r4,r6 | 
 | 	subi		r4,r4,28 | 
 | 	addi		r5,r5,20 | 
 | 	srwi		r5,r5,2 | 
 | ppc_generate_decrypt_block: | 
 | 	li	r6,4 | 
 | 	mtctr	r6 | 
 | ppc_generate_decrypt_word: | 
 | 	lwz		r6,0(r4) | 
 | 	GF8_MUL(r7, r6, r0, r7) | 
 | 	GF8_MUL(r8, r7, r0, r8) | 
 | 	GF8_MUL(r9, r8, r0, r9) | 
 | 	xor		r10,r9,r6 | 
 | 	xor		r11,r7,r8 | 
 | 	xor		r11,r11,r9 | 
 | 	xor		r12,r7,r10 | 
 | 	rotrwi		r12,r12,24 | 
 | 	xor		r11,r11,r12 | 
 | 	xor		r12,r8,r10 | 
 | 	rotrwi		r12,r12,16 | 
 | 	xor		r11,r11,r12 | 
 | 	rotrwi		r12,r10,8 | 
 | 	xor		r11,r11,r12 | 
 | 	stw		r11,0(r3) | 
 | 	addi		r3,r3,4 | 
 | 	addi		r4,r4,4 | 
 | 	bdnz		ppc_generate_decrypt_word | 
 | 	subi		r4,r4,32 | 
 | 	subi		r5,r5,1 | 
 | 	cmpwi		r5,0 | 
 | 	bt		gt,ppc_generate_decrypt_block | 
 | 	blr |