162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-or-later */ 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * AES modes (ECB/CBC/CTR/XTS) for PPC AES implementation 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci * Copyright (c) 2015 Markus Stockhausen <stockhausen@collogia.de> 662306a36Sopenharmony_ci */ 762306a36Sopenharmony_ci 862306a36Sopenharmony_ci#include <asm/ppc_asm.h> 962306a36Sopenharmony_ci#include "aes-spe-regs.h" 1062306a36Sopenharmony_ci 1162306a36Sopenharmony_ci#ifdef __BIG_ENDIAN__ /* Macros for big endian builds */ 1262306a36Sopenharmony_ci 1362306a36Sopenharmony_ci#define LOAD_DATA(reg, off) \ 1462306a36Sopenharmony_ci lwz reg,off(rSP); /* load with offset */ 1562306a36Sopenharmony_ci#define SAVE_DATA(reg, off) \ 1662306a36Sopenharmony_ci stw reg,off(rDP); /* save with offset */ 1762306a36Sopenharmony_ci#define NEXT_BLOCK \ 1862306a36Sopenharmony_ci addi rSP,rSP,16; /* increment pointers per bloc */ \ 1962306a36Sopenharmony_ci addi rDP,rDP,16; 2062306a36Sopenharmony_ci#define LOAD_IV(reg, off) \ 2162306a36Sopenharmony_ci lwz reg,off(rIP); /* IV loading with offset */ 2262306a36Sopenharmony_ci#define SAVE_IV(reg, off) \ 2362306a36Sopenharmony_ci stw reg,off(rIP); /* IV saving with offset */ 2462306a36Sopenharmony_ci#define START_IV /* nothing to reset */ 2562306a36Sopenharmony_ci#define CBC_DEC 16 /* CBC decrement per block */ 2662306a36Sopenharmony_ci#define CTR_DEC 1 /* CTR decrement one byte */ 2762306a36Sopenharmony_ci 2862306a36Sopenharmony_ci#else /* Macros for little endian */ 2962306a36Sopenharmony_ci 3062306a36Sopenharmony_ci#define LOAD_DATA(reg, off) \ 3162306a36Sopenharmony_ci lwbrx reg,0,rSP; /* load reversed */ \ 3262306a36Sopenharmony_ci addi rSP,rSP,4; /* and increment pointer */ 3362306a36Sopenharmony_ci#define SAVE_DATA(reg, off) \ 3462306a36Sopenharmony_ci stwbrx reg,0,rDP; /* save reversed */ \ 3562306a36Sopenharmony_ci addi rDP,rDP,4; /* and increment pointer */ 3662306a36Sopenharmony_ci#define NEXT_BLOCK /* nothing todo */ 3762306a36Sopenharmony_ci#define LOAD_IV(reg, off) \ 3862306a36Sopenharmony_ci lwbrx reg,0,rIP; /* load reversed */ \ 3962306a36Sopenharmony_ci addi rIP,rIP,4; /* and increment pointer */ 4062306a36Sopenharmony_ci#define SAVE_IV(reg, off) \ 4162306a36Sopenharmony_ci stwbrx reg,0,rIP; /* load reversed */ \ 4262306a36Sopenharmony_ci addi rIP,rIP,4; /* and increment pointer */ 4362306a36Sopenharmony_ci#define START_IV \ 4462306a36Sopenharmony_ci subi rIP,rIP,16; /* must reset pointer */ 4562306a36Sopenharmony_ci#define CBC_DEC 32 /* 2 blocks because of incs */ 4662306a36Sopenharmony_ci#define CTR_DEC 17 /* 1 block because of incs */ 4762306a36Sopenharmony_ci 4862306a36Sopenharmony_ci#endif 4962306a36Sopenharmony_ci 5062306a36Sopenharmony_ci#define SAVE_0_REGS 5162306a36Sopenharmony_ci#define LOAD_0_REGS 5262306a36Sopenharmony_ci 5362306a36Sopenharmony_ci#define SAVE_4_REGS \ 5462306a36Sopenharmony_ci stw rI0,96(r1); /* save 32 bit registers */ \ 5562306a36Sopenharmony_ci stw rI1,100(r1); \ 5662306a36Sopenharmony_ci stw rI2,104(r1); \ 5762306a36Sopenharmony_ci stw rI3,108(r1); 5862306a36Sopenharmony_ci 5962306a36Sopenharmony_ci#define LOAD_4_REGS \ 6062306a36Sopenharmony_ci lwz rI0,96(r1); /* restore 32 bit registers */ \ 6162306a36Sopenharmony_ci lwz rI1,100(r1); \ 6262306a36Sopenharmony_ci lwz rI2,104(r1); \ 6362306a36Sopenharmony_ci lwz rI3,108(r1); 6462306a36Sopenharmony_ci 6562306a36Sopenharmony_ci#define SAVE_8_REGS \ 6662306a36Sopenharmony_ci SAVE_4_REGS \ 6762306a36Sopenharmony_ci stw rG0,112(r1); /* save 32 bit registers */ \ 6862306a36Sopenharmony_ci stw rG1,116(r1); \ 6962306a36Sopenharmony_ci stw rG2,120(r1); \ 7062306a36Sopenharmony_ci stw rG3,124(r1); 7162306a36Sopenharmony_ci 7262306a36Sopenharmony_ci#define LOAD_8_REGS \ 7362306a36Sopenharmony_ci LOAD_4_REGS \ 7462306a36Sopenharmony_ci lwz rG0,112(r1); /* restore 32 bit registers */ \ 7562306a36Sopenharmony_ci lwz rG1,116(r1); \ 7662306a36Sopenharmony_ci lwz rG2,120(r1); \ 7762306a36Sopenharmony_ci lwz rG3,124(r1); 7862306a36Sopenharmony_ci 7962306a36Sopenharmony_ci#define INITIALIZE_CRYPT(tab,nr32bitregs) \ 8062306a36Sopenharmony_ci mflr r0; \ 8162306a36Sopenharmony_ci stwu r1,-160(r1); /* create stack frame */ \ 8262306a36Sopenharmony_ci lis rT0,tab@h; /* en-/decryption table pointer */ \ 8362306a36Sopenharmony_ci stw r0,8(r1); /* save link register */ \ 8462306a36Sopenharmony_ci ori rT0,rT0,tab@l; \ 8562306a36Sopenharmony_ci evstdw r14,16(r1); \ 8662306a36Sopenharmony_ci mr rKS,rKP; \ 8762306a36Sopenharmony_ci evstdw r15,24(r1); /* We must save non volatile */ \ 8862306a36Sopenharmony_ci evstdw r16,32(r1); /* registers. Take the chance */ \ 8962306a36Sopenharmony_ci evstdw r17,40(r1); /* and save the SPE part too */ \ 9062306a36Sopenharmony_ci evstdw r18,48(r1); \ 9162306a36Sopenharmony_ci evstdw r19,56(r1); \ 9262306a36Sopenharmony_ci evstdw r20,64(r1); \ 9362306a36Sopenharmony_ci evstdw r21,72(r1); \ 9462306a36Sopenharmony_ci evstdw r22,80(r1); \ 9562306a36Sopenharmony_ci evstdw r23,88(r1); \ 9662306a36Sopenharmony_ci SAVE_##nr32bitregs##_REGS 9762306a36Sopenharmony_ci 9862306a36Sopenharmony_ci#define FINALIZE_CRYPT(nr32bitregs) \ 9962306a36Sopenharmony_ci lwz r0,8(r1); \ 10062306a36Sopenharmony_ci evldw r14,16(r1); /* restore SPE registers */ \ 10162306a36Sopenharmony_ci evldw r15,24(r1); \ 10262306a36Sopenharmony_ci evldw r16,32(r1); \ 10362306a36Sopenharmony_ci evldw r17,40(r1); \ 10462306a36Sopenharmony_ci evldw r18,48(r1); \ 10562306a36Sopenharmony_ci evldw r19,56(r1); \ 10662306a36Sopenharmony_ci evldw r20,64(r1); \ 10762306a36Sopenharmony_ci evldw r21,72(r1); \ 10862306a36Sopenharmony_ci evldw r22,80(r1); \ 10962306a36Sopenharmony_ci evldw r23,88(r1); \ 11062306a36Sopenharmony_ci LOAD_##nr32bitregs##_REGS \ 11162306a36Sopenharmony_ci mtlr r0; /* restore link register */ \ 11262306a36Sopenharmony_ci xor r0,r0,r0; \ 11362306a36Sopenharmony_ci stw r0,16(r1); /* delete sensitive data */ \ 11462306a36Sopenharmony_ci stw r0,24(r1); /* that we might have pushed */ \ 11562306a36Sopenharmony_ci stw r0,32(r1); /* from other context that runs */ \ 11662306a36Sopenharmony_ci stw r0,40(r1); /* the same code */ \ 11762306a36Sopenharmony_ci stw r0,48(r1); \ 11862306a36Sopenharmony_ci stw r0,56(r1); \ 11962306a36Sopenharmony_ci stw r0,64(r1); \ 12062306a36Sopenharmony_ci stw r0,72(r1); \ 12162306a36Sopenharmony_ci stw r0,80(r1); \ 12262306a36Sopenharmony_ci stw r0,88(r1); \ 12362306a36Sopenharmony_ci addi r1,r1,160; /* cleanup stack frame */ 12462306a36Sopenharmony_ci 12562306a36Sopenharmony_ci#define ENDIAN_SWAP(t0, t1, s0, s1) \ 12662306a36Sopenharmony_ci rotrwi t0,s0,8; /* swap endianness for 2 GPRs */ \ 12762306a36Sopenharmony_ci rotrwi t1,s1,8; \ 12862306a36Sopenharmony_ci rlwimi t0,s0,8,8,15; \ 12962306a36Sopenharmony_ci rlwimi t1,s1,8,8,15; \ 13062306a36Sopenharmony_ci rlwimi t0,s0,8,24,31; \ 13162306a36Sopenharmony_ci rlwimi t1,s1,8,24,31; 13262306a36Sopenharmony_ci 13362306a36Sopenharmony_ci#define GF128_MUL(d0, d1, d2, d3, t0) \ 13462306a36Sopenharmony_ci li t0,0x87; /* multiplication in GF128 */ \ 13562306a36Sopenharmony_ci cmpwi d3,-1; \ 13662306a36Sopenharmony_ci iselgt t0,0,t0; \ 13762306a36Sopenharmony_ci rlwimi d3,d2,0,0,0; /* propagate "carry" bits */ \ 13862306a36Sopenharmony_ci rotlwi d3,d3,1; \ 13962306a36Sopenharmony_ci rlwimi d2,d1,0,0,0; \ 14062306a36Sopenharmony_ci rotlwi d2,d2,1; \ 14162306a36Sopenharmony_ci rlwimi d1,d0,0,0,0; \ 14262306a36Sopenharmony_ci slwi d0,d0,1; /* shift left 128 bit */ \ 14362306a36Sopenharmony_ci rotlwi d1,d1,1; \ 14462306a36Sopenharmony_ci xor d0,d0,t0; 14562306a36Sopenharmony_ci 14662306a36Sopenharmony_ci#define START_KEY(d0, d1, d2, d3) \ 14762306a36Sopenharmony_ci lwz rW0,0(rKP); \ 14862306a36Sopenharmony_ci mtctr rRR; \ 14962306a36Sopenharmony_ci lwz rW1,4(rKP); \ 15062306a36Sopenharmony_ci lwz rW2,8(rKP); \ 15162306a36Sopenharmony_ci lwz rW3,12(rKP); \ 15262306a36Sopenharmony_ci xor rD0,d0,rW0; \ 15362306a36Sopenharmony_ci xor rD1,d1,rW1; \ 15462306a36Sopenharmony_ci xor rD2,d2,rW2; \ 15562306a36Sopenharmony_ci xor rD3,d3,rW3; 15662306a36Sopenharmony_ci 15762306a36Sopenharmony_ci/* 15862306a36Sopenharmony_ci * ppc_encrypt_aes(u8 *out, const u8 *in, u32 *key_enc, 15962306a36Sopenharmony_ci * u32 rounds) 16062306a36Sopenharmony_ci * 16162306a36Sopenharmony_ci * called from glue layer to encrypt a single 16 byte block 16262306a36Sopenharmony_ci * round values are AES128 = 4, AES192 = 5, AES256 = 6 16362306a36Sopenharmony_ci * 16462306a36Sopenharmony_ci */ 16562306a36Sopenharmony_ci_GLOBAL(ppc_encrypt_aes) 16662306a36Sopenharmony_ci INITIALIZE_CRYPT(PPC_AES_4K_ENCTAB, 0) 16762306a36Sopenharmony_ci LOAD_DATA(rD0, 0) 16862306a36Sopenharmony_ci LOAD_DATA(rD1, 4) 16962306a36Sopenharmony_ci LOAD_DATA(rD2, 8) 17062306a36Sopenharmony_ci LOAD_DATA(rD3, 12) 17162306a36Sopenharmony_ci START_KEY(rD0, rD1, rD2, rD3) 17262306a36Sopenharmony_ci bl ppc_encrypt_block 17362306a36Sopenharmony_ci xor rD0,rD0,rW0 17462306a36Sopenharmony_ci SAVE_DATA(rD0, 0) 17562306a36Sopenharmony_ci xor rD1,rD1,rW1 17662306a36Sopenharmony_ci SAVE_DATA(rD1, 4) 17762306a36Sopenharmony_ci xor rD2,rD2,rW2 17862306a36Sopenharmony_ci SAVE_DATA(rD2, 8) 17962306a36Sopenharmony_ci xor rD3,rD3,rW3 18062306a36Sopenharmony_ci SAVE_DATA(rD3, 12) 18162306a36Sopenharmony_ci FINALIZE_CRYPT(0) 18262306a36Sopenharmony_ci blr 18362306a36Sopenharmony_ci 18462306a36Sopenharmony_ci/* 18562306a36Sopenharmony_ci * ppc_decrypt_aes(u8 *out, const u8 *in, u32 *key_dec, 18662306a36Sopenharmony_ci * u32 rounds) 18762306a36Sopenharmony_ci * 18862306a36Sopenharmony_ci * called from glue layer to decrypt a single 16 byte block 18962306a36Sopenharmony_ci * round values are AES128 = 4, AES192 = 5, AES256 = 6 19062306a36Sopenharmony_ci * 19162306a36Sopenharmony_ci */ 19262306a36Sopenharmony_ci_GLOBAL(ppc_decrypt_aes) 19362306a36Sopenharmony_ci INITIALIZE_CRYPT(PPC_AES_4K_DECTAB,0) 19462306a36Sopenharmony_ci LOAD_DATA(rD0, 0) 19562306a36Sopenharmony_ci addi rT1,rT0,4096 19662306a36Sopenharmony_ci LOAD_DATA(rD1, 4) 19762306a36Sopenharmony_ci LOAD_DATA(rD2, 8) 19862306a36Sopenharmony_ci LOAD_DATA(rD3, 12) 19962306a36Sopenharmony_ci START_KEY(rD0, rD1, rD2, rD3) 20062306a36Sopenharmony_ci bl ppc_decrypt_block 20162306a36Sopenharmony_ci xor rD0,rD0,rW0 20262306a36Sopenharmony_ci SAVE_DATA(rD0, 0) 20362306a36Sopenharmony_ci xor rD1,rD1,rW1 20462306a36Sopenharmony_ci SAVE_DATA(rD1, 4) 20562306a36Sopenharmony_ci xor rD2,rD2,rW2 20662306a36Sopenharmony_ci SAVE_DATA(rD2, 8) 20762306a36Sopenharmony_ci xor rD3,rD3,rW3 20862306a36Sopenharmony_ci SAVE_DATA(rD3, 12) 20962306a36Sopenharmony_ci FINALIZE_CRYPT(0) 21062306a36Sopenharmony_ci blr 21162306a36Sopenharmony_ci 21262306a36Sopenharmony_ci/* 21362306a36Sopenharmony_ci * ppc_encrypt_ecb(u8 *out, const u8 *in, u32 *key_enc, 21462306a36Sopenharmony_ci * u32 rounds, u32 bytes); 21562306a36Sopenharmony_ci * 21662306a36Sopenharmony_ci * called from glue layer to encrypt multiple blocks via ECB 21762306a36Sopenharmony_ci * Bytes must be larger or equal 16 and only whole blocks are 21862306a36Sopenharmony_ci * processed. round values are AES128 = 4, AES192 = 5 and 21962306a36Sopenharmony_ci * AES256 = 6 22062306a36Sopenharmony_ci * 22162306a36Sopenharmony_ci */ 22262306a36Sopenharmony_ci_GLOBAL(ppc_encrypt_ecb) 22362306a36Sopenharmony_ci INITIALIZE_CRYPT(PPC_AES_4K_ENCTAB, 0) 22462306a36Sopenharmony_cippc_encrypt_ecb_loop: 22562306a36Sopenharmony_ci LOAD_DATA(rD0, 0) 22662306a36Sopenharmony_ci mr rKP,rKS 22762306a36Sopenharmony_ci LOAD_DATA(rD1, 4) 22862306a36Sopenharmony_ci subi rLN,rLN,16 22962306a36Sopenharmony_ci LOAD_DATA(rD2, 8) 23062306a36Sopenharmony_ci cmpwi rLN,15 23162306a36Sopenharmony_ci LOAD_DATA(rD3, 12) 23262306a36Sopenharmony_ci START_KEY(rD0, rD1, rD2, rD3) 23362306a36Sopenharmony_ci bl ppc_encrypt_block 23462306a36Sopenharmony_ci xor rD0,rD0,rW0 23562306a36Sopenharmony_ci SAVE_DATA(rD0, 0) 23662306a36Sopenharmony_ci xor rD1,rD1,rW1 23762306a36Sopenharmony_ci SAVE_DATA(rD1, 4) 23862306a36Sopenharmony_ci xor rD2,rD2,rW2 23962306a36Sopenharmony_ci SAVE_DATA(rD2, 8) 24062306a36Sopenharmony_ci xor rD3,rD3,rW3 24162306a36Sopenharmony_ci SAVE_DATA(rD3, 12) 24262306a36Sopenharmony_ci NEXT_BLOCK 24362306a36Sopenharmony_ci bt gt,ppc_encrypt_ecb_loop 24462306a36Sopenharmony_ci FINALIZE_CRYPT(0) 24562306a36Sopenharmony_ci blr 24662306a36Sopenharmony_ci 24762306a36Sopenharmony_ci/* 24862306a36Sopenharmony_ci * ppc_decrypt_ecb(u8 *out, const u8 *in, u32 *key_dec, 24962306a36Sopenharmony_ci * u32 rounds, u32 bytes); 25062306a36Sopenharmony_ci * 25162306a36Sopenharmony_ci * called from glue layer to decrypt multiple blocks via ECB 25262306a36Sopenharmony_ci * Bytes must be larger or equal 16 and only whole blocks are 25362306a36Sopenharmony_ci * processed. round values are AES128 = 4, AES192 = 5 and 25462306a36Sopenharmony_ci * AES256 = 6 25562306a36Sopenharmony_ci * 25662306a36Sopenharmony_ci */ 25762306a36Sopenharmony_ci_GLOBAL(ppc_decrypt_ecb) 25862306a36Sopenharmony_ci INITIALIZE_CRYPT(PPC_AES_4K_DECTAB, 0) 25962306a36Sopenharmony_ci addi rT1,rT0,4096 26062306a36Sopenharmony_cippc_decrypt_ecb_loop: 26162306a36Sopenharmony_ci LOAD_DATA(rD0, 0) 26262306a36Sopenharmony_ci mr rKP,rKS 26362306a36Sopenharmony_ci LOAD_DATA(rD1, 4) 26462306a36Sopenharmony_ci subi rLN,rLN,16 26562306a36Sopenharmony_ci LOAD_DATA(rD2, 8) 26662306a36Sopenharmony_ci cmpwi rLN,15 26762306a36Sopenharmony_ci LOAD_DATA(rD3, 12) 26862306a36Sopenharmony_ci START_KEY(rD0, rD1, rD2, rD3) 26962306a36Sopenharmony_ci bl ppc_decrypt_block 27062306a36Sopenharmony_ci xor rD0,rD0,rW0 27162306a36Sopenharmony_ci SAVE_DATA(rD0, 0) 27262306a36Sopenharmony_ci xor rD1,rD1,rW1 27362306a36Sopenharmony_ci SAVE_DATA(rD1, 4) 27462306a36Sopenharmony_ci xor rD2,rD2,rW2 27562306a36Sopenharmony_ci SAVE_DATA(rD2, 8) 27662306a36Sopenharmony_ci xor rD3,rD3,rW3 27762306a36Sopenharmony_ci SAVE_DATA(rD3, 12) 27862306a36Sopenharmony_ci NEXT_BLOCK 27962306a36Sopenharmony_ci bt gt,ppc_decrypt_ecb_loop 28062306a36Sopenharmony_ci FINALIZE_CRYPT(0) 28162306a36Sopenharmony_ci blr 28262306a36Sopenharmony_ci 28362306a36Sopenharmony_ci/* 28462306a36Sopenharmony_ci * ppc_encrypt_cbc(u8 *out, const u8 *in, u32 *key_enc, 28562306a36Sopenharmony_ci * 32 rounds, u32 bytes, u8 *iv); 28662306a36Sopenharmony_ci * 28762306a36Sopenharmony_ci * called from glue layer to encrypt multiple blocks via CBC 28862306a36Sopenharmony_ci * Bytes must be larger or equal 16 and only whole blocks are 28962306a36Sopenharmony_ci * processed. round values are AES128 = 4, AES192 = 5 and 29062306a36Sopenharmony_ci * AES256 = 6 29162306a36Sopenharmony_ci * 29262306a36Sopenharmony_ci */ 29362306a36Sopenharmony_ci_GLOBAL(ppc_encrypt_cbc) 29462306a36Sopenharmony_ci INITIALIZE_CRYPT(PPC_AES_4K_ENCTAB, 4) 29562306a36Sopenharmony_ci LOAD_IV(rI0, 0) 29662306a36Sopenharmony_ci LOAD_IV(rI1, 4) 29762306a36Sopenharmony_ci LOAD_IV(rI2, 8) 29862306a36Sopenharmony_ci LOAD_IV(rI3, 12) 29962306a36Sopenharmony_cippc_encrypt_cbc_loop: 30062306a36Sopenharmony_ci LOAD_DATA(rD0, 0) 30162306a36Sopenharmony_ci mr rKP,rKS 30262306a36Sopenharmony_ci LOAD_DATA(rD1, 4) 30362306a36Sopenharmony_ci subi rLN,rLN,16 30462306a36Sopenharmony_ci LOAD_DATA(rD2, 8) 30562306a36Sopenharmony_ci cmpwi rLN,15 30662306a36Sopenharmony_ci LOAD_DATA(rD3, 12) 30762306a36Sopenharmony_ci xor rD0,rD0,rI0 30862306a36Sopenharmony_ci xor rD1,rD1,rI1 30962306a36Sopenharmony_ci xor rD2,rD2,rI2 31062306a36Sopenharmony_ci xor rD3,rD3,rI3 31162306a36Sopenharmony_ci START_KEY(rD0, rD1, rD2, rD3) 31262306a36Sopenharmony_ci bl ppc_encrypt_block 31362306a36Sopenharmony_ci xor rI0,rD0,rW0 31462306a36Sopenharmony_ci SAVE_DATA(rI0, 0) 31562306a36Sopenharmony_ci xor rI1,rD1,rW1 31662306a36Sopenharmony_ci SAVE_DATA(rI1, 4) 31762306a36Sopenharmony_ci xor rI2,rD2,rW2 31862306a36Sopenharmony_ci SAVE_DATA(rI2, 8) 31962306a36Sopenharmony_ci xor rI3,rD3,rW3 32062306a36Sopenharmony_ci SAVE_DATA(rI3, 12) 32162306a36Sopenharmony_ci NEXT_BLOCK 32262306a36Sopenharmony_ci bt gt,ppc_encrypt_cbc_loop 32362306a36Sopenharmony_ci START_IV 32462306a36Sopenharmony_ci SAVE_IV(rI0, 0) 32562306a36Sopenharmony_ci SAVE_IV(rI1, 4) 32662306a36Sopenharmony_ci SAVE_IV(rI2, 8) 32762306a36Sopenharmony_ci SAVE_IV(rI3, 12) 32862306a36Sopenharmony_ci FINALIZE_CRYPT(4) 32962306a36Sopenharmony_ci blr 33062306a36Sopenharmony_ci 33162306a36Sopenharmony_ci/* 33262306a36Sopenharmony_ci * ppc_decrypt_cbc(u8 *out, const u8 *in, u32 *key_dec, 33362306a36Sopenharmony_ci * u32 rounds, u32 bytes, u8 *iv); 33462306a36Sopenharmony_ci * 33562306a36Sopenharmony_ci * called from glue layer to decrypt multiple blocks via CBC 33662306a36Sopenharmony_ci * round values are AES128 = 4, AES192 = 5, AES256 = 6 33762306a36Sopenharmony_ci * 33862306a36Sopenharmony_ci */ 33962306a36Sopenharmony_ci_GLOBAL(ppc_decrypt_cbc) 34062306a36Sopenharmony_ci INITIALIZE_CRYPT(PPC_AES_4K_DECTAB, 4) 34162306a36Sopenharmony_ci li rT1,15 34262306a36Sopenharmony_ci LOAD_IV(rI0, 0) 34362306a36Sopenharmony_ci andc rLN,rLN,rT1 34462306a36Sopenharmony_ci LOAD_IV(rI1, 4) 34562306a36Sopenharmony_ci subi rLN,rLN,16 34662306a36Sopenharmony_ci LOAD_IV(rI2, 8) 34762306a36Sopenharmony_ci add rSP,rSP,rLN /* reverse processing */ 34862306a36Sopenharmony_ci LOAD_IV(rI3, 12) 34962306a36Sopenharmony_ci add rDP,rDP,rLN 35062306a36Sopenharmony_ci LOAD_DATA(rD0, 0) 35162306a36Sopenharmony_ci addi rT1,rT0,4096 35262306a36Sopenharmony_ci LOAD_DATA(rD1, 4) 35362306a36Sopenharmony_ci LOAD_DATA(rD2, 8) 35462306a36Sopenharmony_ci LOAD_DATA(rD3, 12) 35562306a36Sopenharmony_ci START_IV 35662306a36Sopenharmony_ci SAVE_IV(rD0, 0) 35762306a36Sopenharmony_ci SAVE_IV(rD1, 4) 35862306a36Sopenharmony_ci SAVE_IV(rD2, 8) 35962306a36Sopenharmony_ci cmpwi rLN,16 36062306a36Sopenharmony_ci SAVE_IV(rD3, 12) 36162306a36Sopenharmony_ci bt lt,ppc_decrypt_cbc_end 36262306a36Sopenharmony_cippc_decrypt_cbc_loop: 36362306a36Sopenharmony_ci mr rKP,rKS 36462306a36Sopenharmony_ci START_KEY(rD0, rD1, rD2, rD3) 36562306a36Sopenharmony_ci bl ppc_decrypt_block 36662306a36Sopenharmony_ci subi rLN,rLN,16 36762306a36Sopenharmony_ci subi rSP,rSP,CBC_DEC 36862306a36Sopenharmony_ci xor rW0,rD0,rW0 36962306a36Sopenharmony_ci LOAD_DATA(rD0, 0) 37062306a36Sopenharmony_ci xor rW1,rD1,rW1 37162306a36Sopenharmony_ci LOAD_DATA(rD1, 4) 37262306a36Sopenharmony_ci xor rW2,rD2,rW2 37362306a36Sopenharmony_ci LOAD_DATA(rD2, 8) 37462306a36Sopenharmony_ci xor rW3,rD3,rW3 37562306a36Sopenharmony_ci LOAD_DATA(rD3, 12) 37662306a36Sopenharmony_ci xor rW0,rW0,rD0 37762306a36Sopenharmony_ci SAVE_DATA(rW0, 0) 37862306a36Sopenharmony_ci xor rW1,rW1,rD1 37962306a36Sopenharmony_ci SAVE_DATA(rW1, 4) 38062306a36Sopenharmony_ci xor rW2,rW2,rD2 38162306a36Sopenharmony_ci SAVE_DATA(rW2, 8) 38262306a36Sopenharmony_ci xor rW3,rW3,rD3 38362306a36Sopenharmony_ci SAVE_DATA(rW3, 12) 38462306a36Sopenharmony_ci cmpwi rLN,15 38562306a36Sopenharmony_ci subi rDP,rDP,CBC_DEC 38662306a36Sopenharmony_ci bt gt,ppc_decrypt_cbc_loop 38762306a36Sopenharmony_cippc_decrypt_cbc_end: 38862306a36Sopenharmony_ci mr rKP,rKS 38962306a36Sopenharmony_ci START_KEY(rD0, rD1, rD2, rD3) 39062306a36Sopenharmony_ci bl ppc_decrypt_block 39162306a36Sopenharmony_ci xor rW0,rW0,rD0 39262306a36Sopenharmony_ci xor rW1,rW1,rD1 39362306a36Sopenharmony_ci xor rW2,rW2,rD2 39462306a36Sopenharmony_ci xor rW3,rW3,rD3 39562306a36Sopenharmony_ci xor rW0,rW0,rI0 /* decrypt with initial IV */ 39662306a36Sopenharmony_ci SAVE_DATA(rW0, 0) 39762306a36Sopenharmony_ci xor rW1,rW1,rI1 39862306a36Sopenharmony_ci SAVE_DATA(rW1, 4) 39962306a36Sopenharmony_ci xor rW2,rW2,rI2 40062306a36Sopenharmony_ci SAVE_DATA(rW2, 8) 40162306a36Sopenharmony_ci xor rW3,rW3,rI3 40262306a36Sopenharmony_ci SAVE_DATA(rW3, 12) 40362306a36Sopenharmony_ci FINALIZE_CRYPT(4) 40462306a36Sopenharmony_ci blr 40562306a36Sopenharmony_ci 40662306a36Sopenharmony_ci/* 40762306a36Sopenharmony_ci * ppc_crypt_ctr(u8 *out, const u8 *in, u32 *key_enc, 40862306a36Sopenharmony_ci * u32 rounds, u32 bytes, u8 *iv); 40962306a36Sopenharmony_ci * 41062306a36Sopenharmony_ci * called from glue layer to encrypt/decrypt multiple blocks 41162306a36Sopenharmony_ci * via CTR. Number of bytes does not need to be a multiple of 41262306a36Sopenharmony_ci * 16. Round values are AES128 = 4, AES192 = 5, AES256 = 6 41362306a36Sopenharmony_ci * 41462306a36Sopenharmony_ci */ 41562306a36Sopenharmony_ci_GLOBAL(ppc_crypt_ctr) 41662306a36Sopenharmony_ci INITIALIZE_CRYPT(PPC_AES_4K_ENCTAB, 4) 41762306a36Sopenharmony_ci LOAD_IV(rI0, 0) 41862306a36Sopenharmony_ci LOAD_IV(rI1, 4) 41962306a36Sopenharmony_ci LOAD_IV(rI2, 8) 42062306a36Sopenharmony_ci cmpwi rLN,16 42162306a36Sopenharmony_ci LOAD_IV(rI3, 12) 42262306a36Sopenharmony_ci START_IV 42362306a36Sopenharmony_ci bt lt,ppc_crypt_ctr_partial 42462306a36Sopenharmony_cippc_crypt_ctr_loop: 42562306a36Sopenharmony_ci mr rKP,rKS 42662306a36Sopenharmony_ci START_KEY(rI0, rI1, rI2, rI3) 42762306a36Sopenharmony_ci bl ppc_encrypt_block 42862306a36Sopenharmony_ci xor rW0,rD0,rW0 42962306a36Sopenharmony_ci xor rW1,rD1,rW1 43062306a36Sopenharmony_ci xor rW2,rD2,rW2 43162306a36Sopenharmony_ci xor rW3,rD3,rW3 43262306a36Sopenharmony_ci LOAD_DATA(rD0, 0) 43362306a36Sopenharmony_ci subi rLN,rLN,16 43462306a36Sopenharmony_ci LOAD_DATA(rD1, 4) 43562306a36Sopenharmony_ci LOAD_DATA(rD2, 8) 43662306a36Sopenharmony_ci LOAD_DATA(rD3, 12) 43762306a36Sopenharmony_ci xor rD0,rD0,rW0 43862306a36Sopenharmony_ci SAVE_DATA(rD0, 0) 43962306a36Sopenharmony_ci xor rD1,rD1,rW1 44062306a36Sopenharmony_ci SAVE_DATA(rD1, 4) 44162306a36Sopenharmony_ci xor rD2,rD2,rW2 44262306a36Sopenharmony_ci SAVE_DATA(rD2, 8) 44362306a36Sopenharmony_ci xor rD3,rD3,rW3 44462306a36Sopenharmony_ci SAVE_DATA(rD3, 12) 44562306a36Sopenharmony_ci addic rI3,rI3,1 /* increase counter */ 44662306a36Sopenharmony_ci addze rI2,rI2 44762306a36Sopenharmony_ci addze rI1,rI1 44862306a36Sopenharmony_ci addze rI0,rI0 44962306a36Sopenharmony_ci NEXT_BLOCK 45062306a36Sopenharmony_ci cmpwi rLN,15 45162306a36Sopenharmony_ci bt gt,ppc_crypt_ctr_loop 45262306a36Sopenharmony_cippc_crypt_ctr_partial: 45362306a36Sopenharmony_ci cmpwi rLN,0 45462306a36Sopenharmony_ci bt eq,ppc_crypt_ctr_end 45562306a36Sopenharmony_ci mr rKP,rKS 45662306a36Sopenharmony_ci START_KEY(rI0, rI1, rI2, rI3) 45762306a36Sopenharmony_ci bl ppc_encrypt_block 45862306a36Sopenharmony_ci xor rW0,rD0,rW0 45962306a36Sopenharmony_ci SAVE_IV(rW0, 0) 46062306a36Sopenharmony_ci xor rW1,rD1,rW1 46162306a36Sopenharmony_ci SAVE_IV(rW1, 4) 46262306a36Sopenharmony_ci xor rW2,rD2,rW2 46362306a36Sopenharmony_ci SAVE_IV(rW2, 8) 46462306a36Sopenharmony_ci xor rW3,rD3,rW3 46562306a36Sopenharmony_ci SAVE_IV(rW3, 12) 46662306a36Sopenharmony_ci mtctr rLN 46762306a36Sopenharmony_ci subi rIP,rIP,CTR_DEC 46862306a36Sopenharmony_ci subi rSP,rSP,1 46962306a36Sopenharmony_ci subi rDP,rDP,1 47062306a36Sopenharmony_cippc_crypt_ctr_xorbyte: 47162306a36Sopenharmony_ci lbzu rW4,1(rIP) /* bytewise xor for partial block */ 47262306a36Sopenharmony_ci lbzu rW5,1(rSP) 47362306a36Sopenharmony_ci xor rW4,rW4,rW5 47462306a36Sopenharmony_ci stbu rW4,1(rDP) 47562306a36Sopenharmony_ci bdnz ppc_crypt_ctr_xorbyte 47662306a36Sopenharmony_ci subf rIP,rLN,rIP 47762306a36Sopenharmony_ci addi rIP,rIP,1 47862306a36Sopenharmony_ci addic rI3,rI3,1 47962306a36Sopenharmony_ci addze rI2,rI2 48062306a36Sopenharmony_ci addze rI1,rI1 48162306a36Sopenharmony_ci addze rI0,rI0 48262306a36Sopenharmony_cippc_crypt_ctr_end: 48362306a36Sopenharmony_ci SAVE_IV(rI0, 0) 48462306a36Sopenharmony_ci SAVE_IV(rI1, 4) 48562306a36Sopenharmony_ci SAVE_IV(rI2, 8) 48662306a36Sopenharmony_ci SAVE_IV(rI3, 12) 48762306a36Sopenharmony_ci FINALIZE_CRYPT(4) 48862306a36Sopenharmony_ci blr 48962306a36Sopenharmony_ci 49062306a36Sopenharmony_ci/* 49162306a36Sopenharmony_ci * ppc_encrypt_xts(u8 *out, const u8 *in, u32 *key_enc, 49262306a36Sopenharmony_ci * u32 rounds, u32 bytes, u8 *iv, u32 *key_twk); 49362306a36Sopenharmony_ci * 49462306a36Sopenharmony_ci * called from glue layer to encrypt multiple blocks via XTS 49562306a36Sopenharmony_ci * If key_twk is given, the initial IV encryption will be 49662306a36Sopenharmony_ci * processed too. Round values are AES128 = 4, AES192 = 5, 49762306a36Sopenharmony_ci * AES256 = 6 49862306a36Sopenharmony_ci * 49962306a36Sopenharmony_ci */ 50062306a36Sopenharmony_ci_GLOBAL(ppc_encrypt_xts) 50162306a36Sopenharmony_ci INITIALIZE_CRYPT(PPC_AES_4K_ENCTAB, 8) 50262306a36Sopenharmony_ci LOAD_IV(rI0, 0) 50362306a36Sopenharmony_ci LOAD_IV(rI1, 4) 50462306a36Sopenharmony_ci LOAD_IV(rI2, 8) 50562306a36Sopenharmony_ci cmpwi rKT,0 50662306a36Sopenharmony_ci LOAD_IV(rI3, 12) 50762306a36Sopenharmony_ci bt eq,ppc_encrypt_xts_notweak 50862306a36Sopenharmony_ci mr rKP,rKT 50962306a36Sopenharmony_ci START_KEY(rI0, rI1, rI2, rI3) 51062306a36Sopenharmony_ci bl ppc_encrypt_block 51162306a36Sopenharmony_ci xor rI0,rD0,rW0 51262306a36Sopenharmony_ci xor rI1,rD1,rW1 51362306a36Sopenharmony_ci xor rI2,rD2,rW2 51462306a36Sopenharmony_ci xor rI3,rD3,rW3 51562306a36Sopenharmony_cippc_encrypt_xts_notweak: 51662306a36Sopenharmony_ci ENDIAN_SWAP(rG0, rG1, rI0, rI1) 51762306a36Sopenharmony_ci ENDIAN_SWAP(rG2, rG3, rI2, rI3) 51862306a36Sopenharmony_cippc_encrypt_xts_loop: 51962306a36Sopenharmony_ci LOAD_DATA(rD0, 0) 52062306a36Sopenharmony_ci mr rKP,rKS 52162306a36Sopenharmony_ci LOAD_DATA(rD1, 4) 52262306a36Sopenharmony_ci subi rLN,rLN,16 52362306a36Sopenharmony_ci LOAD_DATA(rD2, 8) 52462306a36Sopenharmony_ci LOAD_DATA(rD3, 12) 52562306a36Sopenharmony_ci xor rD0,rD0,rI0 52662306a36Sopenharmony_ci xor rD1,rD1,rI1 52762306a36Sopenharmony_ci xor rD2,rD2,rI2 52862306a36Sopenharmony_ci xor rD3,rD3,rI3 52962306a36Sopenharmony_ci START_KEY(rD0, rD1, rD2, rD3) 53062306a36Sopenharmony_ci bl ppc_encrypt_block 53162306a36Sopenharmony_ci xor rD0,rD0,rW0 53262306a36Sopenharmony_ci xor rD1,rD1,rW1 53362306a36Sopenharmony_ci xor rD2,rD2,rW2 53462306a36Sopenharmony_ci xor rD3,rD3,rW3 53562306a36Sopenharmony_ci xor rD0,rD0,rI0 53662306a36Sopenharmony_ci SAVE_DATA(rD0, 0) 53762306a36Sopenharmony_ci xor rD1,rD1,rI1 53862306a36Sopenharmony_ci SAVE_DATA(rD1, 4) 53962306a36Sopenharmony_ci xor rD2,rD2,rI2 54062306a36Sopenharmony_ci SAVE_DATA(rD2, 8) 54162306a36Sopenharmony_ci xor rD3,rD3,rI3 54262306a36Sopenharmony_ci SAVE_DATA(rD3, 12) 54362306a36Sopenharmony_ci GF128_MUL(rG0, rG1, rG2, rG3, rW0) 54462306a36Sopenharmony_ci ENDIAN_SWAP(rI0, rI1, rG0, rG1) 54562306a36Sopenharmony_ci ENDIAN_SWAP(rI2, rI3, rG2, rG3) 54662306a36Sopenharmony_ci cmpwi rLN,0 54762306a36Sopenharmony_ci NEXT_BLOCK 54862306a36Sopenharmony_ci bt gt,ppc_encrypt_xts_loop 54962306a36Sopenharmony_ci START_IV 55062306a36Sopenharmony_ci SAVE_IV(rI0, 0) 55162306a36Sopenharmony_ci SAVE_IV(rI1, 4) 55262306a36Sopenharmony_ci SAVE_IV(rI2, 8) 55362306a36Sopenharmony_ci SAVE_IV(rI3, 12) 55462306a36Sopenharmony_ci FINALIZE_CRYPT(8) 55562306a36Sopenharmony_ci blr 55662306a36Sopenharmony_ci 55762306a36Sopenharmony_ci/* 55862306a36Sopenharmony_ci * ppc_decrypt_xts(u8 *out, const u8 *in, u32 *key_dec, 55962306a36Sopenharmony_ci * u32 rounds, u32 blocks, u8 *iv, u32 *key_twk); 56062306a36Sopenharmony_ci * 56162306a36Sopenharmony_ci * called from glue layer to decrypt multiple blocks via XTS 56262306a36Sopenharmony_ci * If key_twk is given, the initial IV encryption will be 56362306a36Sopenharmony_ci * processed too. Round values are AES128 = 4, AES192 = 5, 56462306a36Sopenharmony_ci * AES256 = 6 56562306a36Sopenharmony_ci * 56662306a36Sopenharmony_ci */ 56762306a36Sopenharmony_ci_GLOBAL(ppc_decrypt_xts) 56862306a36Sopenharmony_ci INITIALIZE_CRYPT(PPC_AES_4K_DECTAB, 8) 56962306a36Sopenharmony_ci LOAD_IV(rI0, 0) 57062306a36Sopenharmony_ci addi rT1,rT0,4096 57162306a36Sopenharmony_ci LOAD_IV(rI1, 4) 57262306a36Sopenharmony_ci LOAD_IV(rI2, 8) 57362306a36Sopenharmony_ci cmpwi rKT,0 57462306a36Sopenharmony_ci LOAD_IV(rI3, 12) 57562306a36Sopenharmony_ci bt eq,ppc_decrypt_xts_notweak 57662306a36Sopenharmony_ci subi rT0,rT0,4096 57762306a36Sopenharmony_ci mr rKP,rKT 57862306a36Sopenharmony_ci START_KEY(rI0, rI1, rI2, rI3) 57962306a36Sopenharmony_ci bl ppc_encrypt_block 58062306a36Sopenharmony_ci xor rI0,rD0,rW0 58162306a36Sopenharmony_ci xor rI1,rD1,rW1 58262306a36Sopenharmony_ci xor rI2,rD2,rW2 58362306a36Sopenharmony_ci xor rI3,rD3,rW3 58462306a36Sopenharmony_ci addi rT0,rT0,4096 58562306a36Sopenharmony_cippc_decrypt_xts_notweak: 58662306a36Sopenharmony_ci ENDIAN_SWAP(rG0, rG1, rI0, rI1) 58762306a36Sopenharmony_ci ENDIAN_SWAP(rG2, rG3, rI2, rI3) 58862306a36Sopenharmony_cippc_decrypt_xts_loop: 58962306a36Sopenharmony_ci LOAD_DATA(rD0, 0) 59062306a36Sopenharmony_ci mr rKP,rKS 59162306a36Sopenharmony_ci LOAD_DATA(rD1, 4) 59262306a36Sopenharmony_ci subi rLN,rLN,16 59362306a36Sopenharmony_ci LOAD_DATA(rD2, 8) 59462306a36Sopenharmony_ci LOAD_DATA(rD3, 12) 59562306a36Sopenharmony_ci xor rD0,rD0,rI0 59662306a36Sopenharmony_ci xor rD1,rD1,rI1 59762306a36Sopenharmony_ci xor rD2,rD2,rI2 59862306a36Sopenharmony_ci xor rD3,rD3,rI3 59962306a36Sopenharmony_ci START_KEY(rD0, rD1, rD2, rD3) 60062306a36Sopenharmony_ci bl ppc_decrypt_block 60162306a36Sopenharmony_ci xor rD0,rD0,rW0 60262306a36Sopenharmony_ci xor rD1,rD1,rW1 60362306a36Sopenharmony_ci xor rD2,rD2,rW2 60462306a36Sopenharmony_ci xor rD3,rD3,rW3 60562306a36Sopenharmony_ci xor rD0,rD0,rI0 60662306a36Sopenharmony_ci SAVE_DATA(rD0, 0) 60762306a36Sopenharmony_ci xor rD1,rD1,rI1 60862306a36Sopenharmony_ci SAVE_DATA(rD1, 4) 60962306a36Sopenharmony_ci xor rD2,rD2,rI2 61062306a36Sopenharmony_ci SAVE_DATA(rD2, 8) 61162306a36Sopenharmony_ci xor rD3,rD3,rI3 61262306a36Sopenharmony_ci SAVE_DATA(rD3, 12) 61362306a36Sopenharmony_ci GF128_MUL(rG0, rG1, rG2, rG3, rW0) 61462306a36Sopenharmony_ci ENDIAN_SWAP(rI0, rI1, rG0, rG1) 61562306a36Sopenharmony_ci ENDIAN_SWAP(rI2, rI3, rG2, rG3) 61662306a36Sopenharmony_ci cmpwi rLN,0 61762306a36Sopenharmony_ci NEXT_BLOCK 61862306a36Sopenharmony_ci bt gt,ppc_decrypt_xts_loop 61962306a36Sopenharmony_ci START_IV 62062306a36Sopenharmony_ci SAVE_IV(rI0, 0) 62162306a36Sopenharmony_ci SAVE_IV(rI1, 4) 62262306a36Sopenharmony_ci SAVE_IV(rI2, 8) 62362306a36Sopenharmony_ci SAVE_IV(rI3, 12) 62462306a36Sopenharmony_ci FINALIZE_CRYPT(8) 62562306a36Sopenharmony_ci blr 626