2019-05-27 14:55:01 +08:00
|
|
|
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
2015-02-22 16:59:54 +08:00
|
|
|
/*
|
|
|
|
* Key handling functions for PPC AES implementation
|
|
|
|
*
|
|
|
|
* Copyright (c) 2015 Markus Stockhausen <stockhausen@collogia.de>
|
|
|
|
*/
|
|
|
|
|
|
|
|
#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
|