18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-or-later */ 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * Key handling functions 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 108c2ecf20Sopenharmony_ci#ifdef __BIG_ENDIAN__ 118c2ecf20Sopenharmony_ci#define LOAD_KEY(d, s, off) \ 128c2ecf20Sopenharmony_ci lwz d,off(s); 138c2ecf20Sopenharmony_ci#else 148c2ecf20Sopenharmony_ci#define LOAD_KEY(d, s, off) \ 158c2ecf20Sopenharmony_ci li r0,off; \ 168c2ecf20Sopenharmony_ci lwbrx d,s,r0; 178c2ecf20Sopenharmony_ci#endif 188c2ecf20Sopenharmony_ci 198c2ecf20Sopenharmony_ci#define INITIALIZE_KEY \ 208c2ecf20Sopenharmony_ci stwu r1,-32(r1); /* create stack frame */ \ 218c2ecf20Sopenharmony_ci stw r14,8(r1); /* save registers */ \ 228c2ecf20Sopenharmony_ci stw r15,12(r1); \ 238c2ecf20Sopenharmony_ci stw r16,16(r1); 248c2ecf20Sopenharmony_ci 258c2ecf20Sopenharmony_ci#define FINALIZE_KEY \ 268c2ecf20Sopenharmony_ci lwz r14,8(r1); /* restore registers */ \ 278c2ecf20Sopenharmony_ci lwz r15,12(r1); \ 288c2ecf20Sopenharmony_ci lwz r16,16(r1); \ 298c2ecf20Sopenharmony_ci xor r5,r5,r5; /* clear sensitive data */ \ 308c2ecf20Sopenharmony_ci xor r6,r6,r6; \ 318c2ecf20Sopenharmony_ci xor r7,r7,r7; \ 328c2ecf20Sopenharmony_ci xor r8,r8,r8; \ 338c2ecf20Sopenharmony_ci xor r9,r9,r9; \ 348c2ecf20Sopenharmony_ci xor r10,r10,r10; \ 358c2ecf20Sopenharmony_ci xor r11,r11,r11; \ 368c2ecf20Sopenharmony_ci xor r12,r12,r12; \ 378c2ecf20Sopenharmony_ci addi r1,r1,32; /* cleanup stack */ 388c2ecf20Sopenharmony_ci 398c2ecf20Sopenharmony_ci#define LS_BOX(r, t1, t2) \ 408c2ecf20Sopenharmony_ci lis t2,PPC_AES_4K_ENCTAB@h; \ 418c2ecf20Sopenharmony_ci ori t2,t2,PPC_AES_4K_ENCTAB@l; \ 428c2ecf20Sopenharmony_ci rlwimi t2,r,4,20,27; \ 438c2ecf20Sopenharmony_ci lbz t1,8(t2); \ 448c2ecf20Sopenharmony_ci rlwimi r,t1,0,24,31; \ 458c2ecf20Sopenharmony_ci rlwimi t2,r,28,20,27; \ 468c2ecf20Sopenharmony_ci lbz t1,8(t2); \ 478c2ecf20Sopenharmony_ci rlwimi r,t1,8,16,23; \ 488c2ecf20Sopenharmony_ci rlwimi t2,r,20,20,27; \ 498c2ecf20Sopenharmony_ci lbz t1,8(t2); \ 508c2ecf20Sopenharmony_ci rlwimi r,t1,16,8,15; \ 518c2ecf20Sopenharmony_ci rlwimi t2,r,12,20,27; \ 528c2ecf20Sopenharmony_ci lbz t1,8(t2); \ 538c2ecf20Sopenharmony_ci rlwimi r,t1,24,0,7; 548c2ecf20Sopenharmony_ci 558c2ecf20Sopenharmony_ci#define GF8_MUL(out, in, t1, t2) \ 568c2ecf20Sopenharmony_ci lis t1,0x8080; /* multiplication in GF8 */ \ 578c2ecf20Sopenharmony_ci ori t1,t1,0x8080; \ 588c2ecf20Sopenharmony_ci and t1,t1,in; \ 598c2ecf20Sopenharmony_ci srwi t1,t1,7; \ 608c2ecf20Sopenharmony_ci mulli t1,t1,0x1b; \ 618c2ecf20Sopenharmony_ci lis t2,0x7f7f; \ 628c2ecf20Sopenharmony_ci ori t2,t2,0x7f7f; \ 638c2ecf20Sopenharmony_ci and t2,t2,in; \ 648c2ecf20Sopenharmony_ci slwi t2,t2,1; \ 658c2ecf20Sopenharmony_ci xor out,t1,t2; 668c2ecf20Sopenharmony_ci 678c2ecf20Sopenharmony_ci/* 688c2ecf20Sopenharmony_ci * ppc_expand_key_128(u32 *key_enc, const u8 *key) 698c2ecf20Sopenharmony_ci * 708c2ecf20Sopenharmony_ci * Expand 128 bit key into 176 bytes encryption key. It consists of 718c2ecf20Sopenharmony_ci * key itself plus 10 rounds with 16 bytes each 728c2ecf20Sopenharmony_ci * 738c2ecf20Sopenharmony_ci */ 748c2ecf20Sopenharmony_ci_GLOBAL(ppc_expand_key_128) 758c2ecf20Sopenharmony_ci INITIALIZE_KEY 768c2ecf20Sopenharmony_ci LOAD_KEY(r5,r4,0) 778c2ecf20Sopenharmony_ci LOAD_KEY(r6,r4,4) 788c2ecf20Sopenharmony_ci LOAD_KEY(r7,r4,8) 798c2ecf20Sopenharmony_ci LOAD_KEY(r8,r4,12) 808c2ecf20Sopenharmony_ci stw r5,0(r3) /* key[0..3] = input data */ 818c2ecf20Sopenharmony_ci stw r6,4(r3) 828c2ecf20Sopenharmony_ci stw r7,8(r3) 838c2ecf20Sopenharmony_ci stw r8,12(r3) 848c2ecf20Sopenharmony_ci li r16,10 /* 10 expansion rounds */ 858c2ecf20Sopenharmony_ci lis r0,0x0100 /* RCO(1) */ 868c2ecf20Sopenharmony_cippc_expand_128_loop: 878c2ecf20Sopenharmony_ci addi r3,r3,16 888c2ecf20Sopenharmony_ci mr r14,r8 /* apply LS_BOX to 4th temp */ 898c2ecf20Sopenharmony_ci rotlwi r14,r14,8 908c2ecf20Sopenharmony_ci LS_BOX(r14, r15, r4) 918c2ecf20Sopenharmony_ci xor r14,r14,r0 928c2ecf20Sopenharmony_ci xor r5,r5,r14 /* xor next 4 keys */ 938c2ecf20Sopenharmony_ci xor r6,r6,r5 948c2ecf20Sopenharmony_ci xor r7,r7,r6 958c2ecf20Sopenharmony_ci xor r8,r8,r7 968c2ecf20Sopenharmony_ci stw r5,0(r3) /* store next 4 keys */ 978c2ecf20Sopenharmony_ci stw r6,4(r3) 988c2ecf20Sopenharmony_ci stw r7,8(r3) 998c2ecf20Sopenharmony_ci stw r8,12(r3) 1008c2ecf20Sopenharmony_ci GF8_MUL(r0, r0, r4, r14) /* multiply RCO by 2 in GF */ 1018c2ecf20Sopenharmony_ci subi r16,r16,1 1028c2ecf20Sopenharmony_ci cmpwi r16,0 1038c2ecf20Sopenharmony_ci bt eq,ppc_expand_128_end 1048c2ecf20Sopenharmony_ci b ppc_expand_128_loop 1058c2ecf20Sopenharmony_cippc_expand_128_end: 1068c2ecf20Sopenharmony_ci FINALIZE_KEY 1078c2ecf20Sopenharmony_ci blr 1088c2ecf20Sopenharmony_ci 1098c2ecf20Sopenharmony_ci/* 1108c2ecf20Sopenharmony_ci * ppc_expand_key_192(u32 *key_enc, const u8 *key) 1118c2ecf20Sopenharmony_ci * 1128c2ecf20Sopenharmony_ci * Expand 192 bit key into 208 bytes encryption key. It consists of key 1138c2ecf20Sopenharmony_ci * itself plus 12 rounds with 16 bytes each 1148c2ecf20Sopenharmony_ci * 1158c2ecf20Sopenharmony_ci */ 1168c2ecf20Sopenharmony_ci_GLOBAL(ppc_expand_key_192) 1178c2ecf20Sopenharmony_ci INITIALIZE_KEY 1188c2ecf20Sopenharmony_ci LOAD_KEY(r5,r4,0) 1198c2ecf20Sopenharmony_ci LOAD_KEY(r6,r4,4) 1208c2ecf20Sopenharmony_ci LOAD_KEY(r7,r4,8) 1218c2ecf20Sopenharmony_ci LOAD_KEY(r8,r4,12) 1228c2ecf20Sopenharmony_ci LOAD_KEY(r9,r4,16) 1238c2ecf20Sopenharmony_ci LOAD_KEY(r10,r4,20) 1248c2ecf20Sopenharmony_ci stw r5,0(r3) 1258c2ecf20Sopenharmony_ci stw r6,4(r3) 1268c2ecf20Sopenharmony_ci stw r7,8(r3) 1278c2ecf20Sopenharmony_ci stw r8,12(r3) 1288c2ecf20Sopenharmony_ci stw r9,16(r3) 1298c2ecf20Sopenharmony_ci stw r10,20(r3) 1308c2ecf20Sopenharmony_ci li r16,8 /* 8 expansion rounds */ 1318c2ecf20Sopenharmony_ci lis r0,0x0100 /* RCO(1) */ 1328c2ecf20Sopenharmony_cippc_expand_192_loop: 1338c2ecf20Sopenharmony_ci addi r3,r3,24 1348c2ecf20Sopenharmony_ci mr r14,r10 /* apply LS_BOX to 6th temp */ 1358c2ecf20Sopenharmony_ci rotlwi r14,r14,8 1368c2ecf20Sopenharmony_ci LS_BOX(r14, r15, r4) 1378c2ecf20Sopenharmony_ci xor r14,r14,r0 1388c2ecf20Sopenharmony_ci xor r5,r5,r14 /* xor next 6 keys */ 1398c2ecf20Sopenharmony_ci xor r6,r6,r5 1408c2ecf20Sopenharmony_ci xor r7,r7,r6 1418c2ecf20Sopenharmony_ci xor r8,r8,r7 1428c2ecf20Sopenharmony_ci xor r9,r9,r8 1438c2ecf20Sopenharmony_ci xor r10,r10,r9 1448c2ecf20Sopenharmony_ci stw r5,0(r3) 1458c2ecf20Sopenharmony_ci stw r6,4(r3) 1468c2ecf20Sopenharmony_ci stw r7,8(r3) 1478c2ecf20Sopenharmony_ci stw r8,12(r3) 1488c2ecf20Sopenharmony_ci subi r16,r16,1 1498c2ecf20Sopenharmony_ci cmpwi r16,0 /* last round early kick out */ 1508c2ecf20Sopenharmony_ci bt eq,ppc_expand_192_end 1518c2ecf20Sopenharmony_ci stw r9,16(r3) 1528c2ecf20Sopenharmony_ci stw r10,20(r3) 1538c2ecf20Sopenharmony_ci GF8_MUL(r0, r0, r4, r14) /* multiply RCO GF8 */ 1548c2ecf20Sopenharmony_ci b ppc_expand_192_loop 1558c2ecf20Sopenharmony_cippc_expand_192_end: 1568c2ecf20Sopenharmony_ci FINALIZE_KEY 1578c2ecf20Sopenharmony_ci blr 1588c2ecf20Sopenharmony_ci 1598c2ecf20Sopenharmony_ci/* 1608c2ecf20Sopenharmony_ci * ppc_expand_key_256(u32 *key_enc, const u8 *key) 1618c2ecf20Sopenharmony_ci * 1628c2ecf20Sopenharmony_ci * Expand 256 bit key into 240 bytes encryption key. It consists of key 1638c2ecf20Sopenharmony_ci * itself plus 14 rounds with 16 bytes each 1648c2ecf20Sopenharmony_ci * 1658c2ecf20Sopenharmony_ci */ 1668c2ecf20Sopenharmony_ci_GLOBAL(ppc_expand_key_256) 1678c2ecf20Sopenharmony_ci INITIALIZE_KEY 1688c2ecf20Sopenharmony_ci LOAD_KEY(r5,r4,0) 1698c2ecf20Sopenharmony_ci LOAD_KEY(r6,r4,4) 1708c2ecf20Sopenharmony_ci LOAD_KEY(r7,r4,8) 1718c2ecf20Sopenharmony_ci LOAD_KEY(r8,r4,12) 1728c2ecf20Sopenharmony_ci LOAD_KEY(r9,r4,16) 1738c2ecf20Sopenharmony_ci LOAD_KEY(r10,r4,20) 1748c2ecf20Sopenharmony_ci LOAD_KEY(r11,r4,24) 1758c2ecf20Sopenharmony_ci LOAD_KEY(r12,r4,28) 1768c2ecf20Sopenharmony_ci stw r5,0(r3) 1778c2ecf20Sopenharmony_ci stw r6,4(r3) 1788c2ecf20Sopenharmony_ci stw r7,8(r3) 1798c2ecf20Sopenharmony_ci stw r8,12(r3) 1808c2ecf20Sopenharmony_ci stw r9,16(r3) 1818c2ecf20Sopenharmony_ci stw r10,20(r3) 1828c2ecf20Sopenharmony_ci stw r11,24(r3) 1838c2ecf20Sopenharmony_ci stw r12,28(r3) 1848c2ecf20Sopenharmony_ci li r16,7 /* 7 expansion rounds */ 1858c2ecf20Sopenharmony_ci lis r0,0x0100 /* RCO(1) */ 1868c2ecf20Sopenharmony_cippc_expand_256_loop: 1878c2ecf20Sopenharmony_ci addi r3,r3,32 1888c2ecf20Sopenharmony_ci mr r14,r12 /* apply LS_BOX to 8th temp */ 1898c2ecf20Sopenharmony_ci rotlwi r14,r14,8 1908c2ecf20Sopenharmony_ci LS_BOX(r14, r15, r4) 1918c2ecf20Sopenharmony_ci xor r14,r14,r0 1928c2ecf20Sopenharmony_ci xor r5,r5,r14 /* xor 4 keys */ 1938c2ecf20Sopenharmony_ci xor r6,r6,r5 1948c2ecf20Sopenharmony_ci xor r7,r7,r6 1958c2ecf20Sopenharmony_ci xor r8,r8,r7 1968c2ecf20Sopenharmony_ci mr r14,r8 1978c2ecf20Sopenharmony_ci LS_BOX(r14, r15, r4) /* apply LS_BOX to 4th temp */ 1988c2ecf20Sopenharmony_ci xor r9,r9,r14 /* xor 4 keys */ 1998c2ecf20Sopenharmony_ci xor r10,r10,r9 2008c2ecf20Sopenharmony_ci xor r11,r11,r10 2018c2ecf20Sopenharmony_ci xor r12,r12,r11 2028c2ecf20Sopenharmony_ci stw r5,0(r3) 2038c2ecf20Sopenharmony_ci stw r6,4(r3) 2048c2ecf20Sopenharmony_ci stw r7,8(r3) 2058c2ecf20Sopenharmony_ci stw r8,12(r3) 2068c2ecf20Sopenharmony_ci subi r16,r16,1 2078c2ecf20Sopenharmony_ci cmpwi r16,0 /* last round early kick out */ 2088c2ecf20Sopenharmony_ci bt eq,ppc_expand_256_end 2098c2ecf20Sopenharmony_ci stw r9,16(r3) 2108c2ecf20Sopenharmony_ci stw r10,20(r3) 2118c2ecf20Sopenharmony_ci stw r11,24(r3) 2128c2ecf20Sopenharmony_ci stw r12,28(r3) 2138c2ecf20Sopenharmony_ci GF8_MUL(r0, r0, r4, r14) 2148c2ecf20Sopenharmony_ci b ppc_expand_256_loop 2158c2ecf20Sopenharmony_cippc_expand_256_end: 2168c2ecf20Sopenharmony_ci FINALIZE_KEY 2178c2ecf20Sopenharmony_ci blr 2188c2ecf20Sopenharmony_ci 2198c2ecf20Sopenharmony_ci/* 2208c2ecf20Sopenharmony_ci * ppc_generate_decrypt_key: derive decryption key from encryption key 2218c2ecf20Sopenharmony_ci * number of bytes to handle are calculated from length of key (16/24/32) 2228c2ecf20Sopenharmony_ci * 2238c2ecf20Sopenharmony_ci */ 2248c2ecf20Sopenharmony_ci_GLOBAL(ppc_generate_decrypt_key) 2258c2ecf20Sopenharmony_ci addi r6,r5,24 2268c2ecf20Sopenharmony_ci slwi r6,r6,2 2278c2ecf20Sopenharmony_ci lwzx r7,r4,r6 /* first/last 4 words are same */ 2288c2ecf20Sopenharmony_ci stw r7,0(r3) 2298c2ecf20Sopenharmony_ci lwz r7,0(r4) 2308c2ecf20Sopenharmony_ci stwx r7,r3,r6 2318c2ecf20Sopenharmony_ci addi r6,r6,4 2328c2ecf20Sopenharmony_ci lwzx r7,r4,r6 2338c2ecf20Sopenharmony_ci stw r7,4(r3) 2348c2ecf20Sopenharmony_ci lwz r7,4(r4) 2358c2ecf20Sopenharmony_ci stwx r7,r3,r6 2368c2ecf20Sopenharmony_ci addi r6,r6,4 2378c2ecf20Sopenharmony_ci lwzx r7,r4,r6 2388c2ecf20Sopenharmony_ci stw r7,8(r3) 2398c2ecf20Sopenharmony_ci lwz r7,8(r4) 2408c2ecf20Sopenharmony_ci stwx r7,r3,r6 2418c2ecf20Sopenharmony_ci addi r6,r6,4 2428c2ecf20Sopenharmony_ci lwzx r7,r4,r6 2438c2ecf20Sopenharmony_ci stw r7,12(r3) 2448c2ecf20Sopenharmony_ci lwz r7,12(r4) 2458c2ecf20Sopenharmony_ci stwx r7,r3,r6 2468c2ecf20Sopenharmony_ci addi r3,r3,16 2478c2ecf20Sopenharmony_ci add r4,r4,r6 2488c2ecf20Sopenharmony_ci subi r4,r4,28 2498c2ecf20Sopenharmony_ci addi r5,r5,20 2508c2ecf20Sopenharmony_ci srwi r5,r5,2 2518c2ecf20Sopenharmony_cippc_generate_decrypt_block: 2528c2ecf20Sopenharmony_ci li r6,4 2538c2ecf20Sopenharmony_ci mtctr r6 2548c2ecf20Sopenharmony_cippc_generate_decrypt_word: 2558c2ecf20Sopenharmony_ci lwz r6,0(r4) 2568c2ecf20Sopenharmony_ci GF8_MUL(r7, r6, r0, r7) 2578c2ecf20Sopenharmony_ci GF8_MUL(r8, r7, r0, r8) 2588c2ecf20Sopenharmony_ci GF8_MUL(r9, r8, r0, r9) 2598c2ecf20Sopenharmony_ci xor r10,r9,r6 2608c2ecf20Sopenharmony_ci xor r11,r7,r8 2618c2ecf20Sopenharmony_ci xor r11,r11,r9 2628c2ecf20Sopenharmony_ci xor r12,r7,r10 2638c2ecf20Sopenharmony_ci rotrwi r12,r12,24 2648c2ecf20Sopenharmony_ci xor r11,r11,r12 2658c2ecf20Sopenharmony_ci xor r12,r8,r10 2668c2ecf20Sopenharmony_ci rotrwi r12,r12,16 2678c2ecf20Sopenharmony_ci xor r11,r11,r12 2688c2ecf20Sopenharmony_ci rotrwi r12,r10,8 2698c2ecf20Sopenharmony_ci xor r11,r11,r12 2708c2ecf20Sopenharmony_ci stw r11,0(r3) 2718c2ecf20Sopenharmony_ci addi r3,r3,4 2728c2ecf20Sopenharmony_ci addi r4,r4,4 2738c2ecf20Sopenharmony_ci bdnz ppc_generate_decrypt_word 2748c2ecf20Sopenharmony_ci subi r4,r4,32 2758c2ecf20Sopenharmony_ci subi r5,r5,1 2768c2ecf20Sopenharmony_ci cmpwi r5,0 2778c2ecf20Sopenharmony_ci bt gt,ppc_generate_decrypt_block 2788c2ecf20Sopenharmony_ci blr 279