123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631 |
- /*
- * AES modes (ECB/CBC/CTR/XTS) 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>
- #include "aes-spe-regs.h"
- #ifdef __BIG_ENDIAN__ /* Macros for big endian builds */
- #define LOAD_DATA(reg, off) \
- lwz reg,off(rSP); /* load with offset */
- #define SAVE_DATA(reg, off) \
- stw reg,off(rDP); /* save with offset */
- #define NEXT_BLOCK \
- addi rSP,rSP,16; /* increment pointers per bloc */ \
- addi rDP,rDP,16;
- #define LOAD_IV(reg, off) \
- lwz reg,off(rIP); /* IV loading with offset */
- #define SAVE_IV(reg, off) \
- stw reg,off(rIP); /* IV saving with offset */
- #define START_IV /* nothing to reset */
- #define CBC_DEC 16 /* CBC decrement per block */
- #define CTR_DEC 1 /* CTR decrement one byte */
- #else /* Macros for little endian */
- #define LOAD_DATA(reg, off) \
- lwbrx reg,0,rSP; /* load reversed */ \
- addi rSP,rSP,4; /* and increment pointer */
- #define SAVE_DATA(reg, off) \
- stwbrx reg,0,rDP; /* save reversed */ \
- addi rDP,rDP,4; /* and increment pointer */
- #define NEXT_BLOCK /* nothing todo */
- #define LOAD_IV(reg, off) \
- lwbrx reg,0,rIP; /* load reversed */ \
- addi rIP,rIP,4; /* and increment pointer */
- #define SAVE_IV(reg, off) \
- stwbrx reg,0,rIP; /* load reversed */ \
- addi rIP,rIP,4; /* and increment pointer */
- #define START_IV \
- subi rIP,rIP,16; /* must reset pointer */
- #define CBC_DEC 32 /* 2 blocks because of incs */
- #define CTR_DEC 17 /* 1 block because of incs */
- #endif
- #define SAVE_0_REGS
- #define LOAD_0_REGS
- #define SAVE_4_REGS \
- stw rI0,96(r1); /* save 32 bit registers */ \
- stw rI1,100(r1); \
- stw rI2,104(r1); \
- stw rI3,108(r1);
- #define LOAD_4_REGS \
- lwz rI0,96(r1); /* restore 32 bit registers */ \
- lwz rI1,100(r1); \
- lwz rI2,104(r1); \
- lwz rI3,108(r1);
- #define SAVE_8_REGS \
- SAVE_4_REGS \
- stw rG0,112(r1); /* save 32 bit registers */ \
- stw rG1,116(r1); \
- stw rG2,120(r1); \
- stw rG3,124(r1);
- #define LOAD_8_REGS \
- LOAD_4_REGS \
- lwz rG0,112(r1); /* restore 32 bit registers */ \
- lwz rG1,116(r1); \
- lwz rG2,120(r1); \
- lwz rG3,124(r1);
- #define INITIALIZE_CRYPT(tab,nr32bitregs) \
- mflr r0; \
- stwu r1,-160(r1); /* create stack frame */ \
- lis rT0,tab@h; /* en-/decryption table pointer */ \
- stw r0,8(r1); /* save link register */ \
- ori rT0,rT0,tab@l; \
- evstdw r14,16(r1); \
- mr rKS,rKP; \
- evstdw r15,24(r1); /* We must save non volatile */ \
- evstdw r16,32(r1); /* registers. Take the chance */ \
- evstdw r17,40(r1); /* and save the SPE part too */ \
- evstdw r18,48(r1); \
- evstdw r19,56(r1); \
- evstdw r20,64(r1); \
- evstdw r21,72(r1); \
- evstdw r22,80(r1); \
- evstdw r23,88(r1); \
- SAVE_##nr32bitregs##_REGS
- #define FINALIZE_CRYPT(nr32bitregs) \
- lwz r0,8(r1); \
- evldw r14,16(r1); /* restore SPE registers */ \
- evldw r15,24(r1); \
- evldw r16,32(r1); \
- evldw r17,40(r1); \
- evldw r18,48(r1); \
- evldw r19,56(r1); \
- evldw r20,64(r1); \
- evldw r21,72(r1); \
- evldw r22,80(r1); \
- evldw r23,88(r1); \
- LOAD_##nr32bitregs##_REGS \
- mtlr r0; /* restore link register */ \
- xor r0,r0,r0; \
- stw r0,16(r1); /* delete sensitive data */ \
- stw r0,24(r1); /* that we might have pushed */ \
- stw r0,32(r1); /* from other context that runs */ \
- stw r0,40(r1); /* the same code */ \
- stw r0,48(r1); \
- stw r0,56(r1); \
- stw r0,64(r1); \
- stw r0,72(r1); \
- stw r0,80(r1); \
- stw r0,88(r1); \
- addi r1,r1,160; /* cleanup stack frame */
- #define ENDIAN_SWAP(t0, t1, s0, s1) \
- rotrwi t0,s0,8; /* swap endianness for 2 GPRs */ \
- rotrwi t1,s1,8; \
- rlwimi t0,s0,8,8,15; \
- rlwimi t1,s1,8,8,15; \
- rlwimi t0,s0,8,24,31; \
- rlwimi t1,s1,8,24,31;
- #define GF128_MUL(d0, d1, d2, d3, t0) \
- li t0,0x87; /* multiplication in GF128 */ \
- cmpwi d3,-1; \
- iselgt t0,0,t0; \
- rlwimi d3,d2,0,0,0; /* propagate "carry" bits */ \
- rotlwi d3,d3,1; \
- rlwimi d2,d1,0,0,0; \
- rotlwi d2,d2,1; \
- rlwimi d1,d0,0,0,0; \
- slwi d0,d0,1; /* shift left 128 bit */ \
- rotlwi d1,d1,1; \
- xor d0,d0,t0;
- #define START_KEY(d0, d1, d2, d3) \
- lwz rW0,0(rKP); \
- mtctr rRR; \
- lwz rW1,4(rKP); \
- lwz rW2,8(rKP); \
- lwz rW3,12(rKP); \
- xor rD0,d0,rW0; \
- xor rD1,d1,rW1; \
- xor rD2,d2,rW2; \
- xor rD3,d3,rW3;
- /*
- * ppc_encrypt_aes(u8 *out, const u8 *in, u32 *key_enc,
- * u32 rounds)
- *
- * called from glue layer to encrypt a single 16 byte block
- * round values are AES128 = 4, AES192 = 5, AES256 = 6
- *
- */
- _GLOBAL(ppc_encrypt_aes)
- INITIALIZE_CRYPT(PPC_AES_4K_ENCTAB, 0)
- LOAD_DATA(rD0, 0)
- LOAD_DATA(rD1, 4)
- LOAD_DATA(rD2, 8)
- LOAD_DATA(rD3, 12)
- START_KEY(rD0, rD1, rD2, rD3)
- bl ppc_encrypt_block
- xor rD0,rD0,rW0
- SAVE_DATA(rD0, 0)
- xor rD1,rD1,rW1
- SAVE_DATA(rD1, 4)
- xor rD2,rD2,rW2
- SAVE_DATA(rD2, 8)
- xor rD3,rD3,rW3
- SAVE_DATA(rD3, 12)
- FINALIZE_CRYPT(0)
- blr
- /*
- * ppc_decrypt_aes(u8 *out, const u8 *in, u32 *key_dec,
- * u32 rounds)
- *
- * called from glue layer to decrypt a single 16 byte block
- * round values are AES128 = 4, AES192 = 5, AES256 = 6
- *
- */
- _GLOBAL(ppc_decrypt_aes)
- INITIALIZE_CRYPT(PPC_AES_4K_DECTAB,0)
- LOAD_DATA(rD0, 0)
- addi rT1,rT0,4096
- LOAD_DATA(rD1, 4)
- LOAD_DATA(rD2, 8)
- LOAD_DATA(rD3, 12)
- START_KEY(rD0, rD1, rD2, rD3)
- bl ppc_decrypt_block
- xor rD0,rD0,rW0
- SAVE_DATA(rD0, 0)
- xor rD1,rD1,rW1
- SAVE_DATA(rD1, 4)
- xor rD2,rD2,rW2
- SAVE_DATA(rD2, 8)
- xor rD3,rD3,rW3
- SAVE_DATA(rD3, 12)
- FINALIZE_CRYPT(0)
- blr
- /*
- * ppc_encrypt_ecb(u8 *out, const u8 *in, u32 *key_enc,
- * u32 rounds, u32 bytes);
- *
- * called from glue layer to encrypt multiple blocks via ECB
- * Bytes must be larger or equal 16 and only whole blocks are
- * processed. round values are AES128 = 4, AES192 = 5 and
- * AES256 = 6
- *
- */
- _GLOBAL(ppc_encrypt_ecb)
- INITIALIZE_CRYPT(PPC_AES_4K_ENCTAB, 0)
- ppc_encrypt_ecb_loop:
- LOAD_DATA(rD0, 0)
- mr rKP,rKS
- LOAD_DATA(rD1, 4)
- subi rLN,rLN,16
- LOAD_DATA(rD2, 8)
- cmpwi rLN,15
- LOAD_DATA(rD3, 12)
- START_KEY(rD0, rD1, rD2, rD3)
- bl ppc_encrypt_block
- xor rD0,rD0,rW0
- SAVE_DATA(rD0, 0)
- xor rD1,rD1,rW1
- SAVE_DATA(rD1, 4)
- xor rD2,rD2,rW2
- SAVE_DATA(rD2, 8)
- xor rD3,rD3,rW3
- SAVE_DATA(rD3, 12)
- NEXT_BLOCK
- bt gt,ppc_encrypt_ecb_loop
- FINALIZE_CRYPT(0)
- blr
- /*
- * ppc_decrypt_ecb(u8 *out, const u8 *in, u32 *key_dec,
- * u32 rounds, u32 bytes);
- *
- * called from glue layer to decrypt multiple blocks via ECB
- * Bytes must be larger or equal 16 and only whole blocks are
- * processed. round values are AES128 = 4, AES192 = 5 and
- * AES256 = 6
- *
- */
- _GLOBAL(ppc_decrypt_ecb)
- INITIALIZE_CRYPT(PPC_AES_4K_DECTAB, 0)
- addi rT1,rT0,4096
- ppc_decrypt_ecb_loop:
- LOAD_DATA(rD0, 0)
- mr rKP,rKS
- LOAD_DATA(rD1, 4)
- subi rLN,rLN,16
- LOAD_DATA(rD2, 8)
- cmpwi rLN,15
- LOAD_DATA(rD3, 12)
- START_KEY(rD0, rD1, rD2, rD3)
- bl ppc_decrypt_block
- xor rD0,rD0,rW0
- SAVE_DATA(rD0, 0)
- xor rD1,rD1,rW1
- SAVE_DATA(rD1, 4)
- xor rD2,rD2,rW2
- SAVE_DATA(rD2, 8)
- xor rD3,rD3,rW3
- SAVE_DATA(rD3, 12)
- NEXT_BLOCK
- bt gt,ppc_decrypt_ecb_loop
- FINALIZE_CRYPT(0)
- blr
- /*
- * ppc_encrypt_cbc(u8 *out, const u8 *in, u32 *key_enc,
- * 32 rounds, u32 bytes, u8 *iv);
- *
- * called from glue layer to encrypt multiple blocks via CBC
- * Bytes must be larger or equal 16 and only whole blocks are
- * processed. round values are AES128 = 4, AES192 = 5 and
- * AES256 = 6
- *
- */
- _GLOBAL(ppc_encrypt_cbc)
- INITIALIZE_CRYPT(PPC_AES_4K_ENCTAB, 4)
- LOAD_IV(rI0, 0)
- LOAD_IV(rI1, 4)
- LOAD_IV(rI2, 8)
- LOAD_IV(rI3, 12)
- ppc_encrypt_cbc_loop:
- LOAD_DATA(rD0, 0)
- mr rKP,rKS
- LOAD_DATA(rD1, 4)
- subi rLN,rLN,16
- LOAD_DATA(rD2, 8)
- cmpwi rLN,15
- LOAD_DATA(rD3, 12)
- xor rD0,rD0,rI0
- xor rD1,rD1,rI1
- xor rD2,rD2,rI2
- xor rD3,rD3,rI3
- START_KEY(rD0, rD1, rD2, rD3)
- bl ppc_encrypt_block
- xor rI0,rD0,rW0
- SAVE_DATA(rI0, 0)
- xor rI1,rD1,rW1
- SAVE_DATA(rI1, 4)
- xor rI2,rD2,rW2
- SAVE_DATA(rI2, 8)
- xor rI3,rD3,rW3
- SAVE_DATA(rI3, 12)
- NEXT_BLOCK
- bt gt,ppc_encrypt_cbc_loop
- START_IV
- SAVE_IV(rI0, 0)
- SAVE_IV(rI1, 4)
- SAVE_IV(rI2, 8)
- SAVE_IV(rI3, 12)
- FINALIZE_CRYPT(4)
- blr
- /*
- * ppc_decrypt_cbc(u8 *out, const u8 *in, u32 *key_dec,
- * u32 rounds, u32 bytes, u8 *iv);
- *
- * called from glue layer to decrypt multiple blocks via CBC
- * round values are AES128 = 4, AES192 = 5, AES256 = 6
- *
- */
- _GLOBAL(ppc_decrypt_cbc)
- INITIALIZE_CRYPT(PPC_AES_4K_DECTAB, 4)
- li rT1,15
- LOAD_IV(rI0, 0)
- andc rLN,rLN,rT1
- LOAD_IV(rI1, 4)
- subi rLN,rLN,16
- LOAD_IV(rI2, 8)
- add rSP,rSP,rLN /* reverse processing */
- LOAD_IV(rI3, 12)
- add rDP,rDP,rLN
- LOAD_DATA(rD0, 0)
- addi rT1,rT0,4096
- LOAD_DATA(rD1, 4)
- LOAD_DATA(rD2, 8)
- LOAD_DATA(rD3, 12)
- START_IV
- SAVE_IV(rD0, 0)
- SAVE_IV(rD1, 4)
- SAVE_IV(rD2, 8)
- cmpwi rLN,16
- SAVE_IV(rD3, 12)
- bt lt,ppc_decrypt_cbc_end
- ppc_decrypt_cbc_loop:
- mr rKP,rKS
- START_KEY(rD0, rD1, rD2, rD3)
- bl ppc_decrypt_block
- subi rLN,rLN,16
- subi rSP,rSP,CBC_DEC
- xor rW0,rD0,rW0
- LOAD_DATA(rD0, 0)
- xor rW1,rD1,rW1
- LOAD_DATA(rD1, 4)
- xor rW2,rD2,rW2
- LOAD_DATA(rD2, 8)
- xor rW3,rD3,rW3
- LOAD_DATA(rD3, 12)
- xor rW0,rW0,rD0
- SAVE_DATA(rW0, 0)
- xor rW1,rW1,rD1
- SAVE_DATA(rW1, 4)
- xor rW2,rW2,rD2
- SAVE_DATA(rW2, 8)
- xor rW3,rW3,rD3
- SAVE_DATA(rW3, 12)
- cmpwi rLN,15
- subi rDP,rDP,CBC_DEC
- bt gt,ppc_decrypt_cbc_loop
- ppc_decrypt_cbc_end:
- mr rKP,rKS
- START_KEY(rD0, rD1, rD2, rD3)
- bl ppc_decrypt_block
- xor rW0,rW0,rD0
- xor rW1,rW1,rD1
- xor rW2,rW2,rD2
- xor rW3,rW3,rD3
- xor rW0,rW0,rI0 /* decrypt with initial IV */
- SAVE_DATA(rW0, 0)
- xor rW1,rW1,rI1
- SAVE_DATA(rW1, 4)
- xor rW2,rW2,rI2
- SAVE_DATA(rW2, 8)
- xor rW3,rW3,rI3
- SAVE_DATA(rW3, 12)
- FINALIZE_CRYPT(4)
- blr
- /*
- * ppc_crypt_ctr(u8 *out, const u8 *in, u32 *key_enc,
- * u32 rounds, u32 bytes, u8 *iv);
- *
- * called from glue layer to encrypt/decrypt multiple blocks
- * via CTR. Number of bytes does not need to be a multiple of
- * 16. Round values are AES128 = 4, AES192 = 5, AES256 = 6
- *
- */
- _GLOBAL(ppc_crypt_ctr)
- INITIALIZE_CRYPT(PPC_AES_4K_ENCTAB, 4)
- LOAD_IV(rI0, 0)
- LOAD_IV(rI1, 4)
- LOAD_IV(rI2, 8)
- cmpwi rLN,16
- LOAD_IV(rI3, 12)
- START_IV
- bt lt,ppc_crypt_ctr_partial
- ppc_crypt_ctr_loop:
- mr rKP,rKS
- START_KEY(rI0, rI1, rI2, rI3)
- bl ppc_encrypt_block
- xor rW0,rD0,rW0
- xor rW1,rD1,rW1
- xor rW2,rD2,rW2
- xor rW3,rD3,rW3
- LOAD_DATA(rD0, 0)
- subi rLN,rLN,16
- LOAD_DATA(rD1, 4)
- LOAD_DATA(rD2, 8)
- LOAD_DATA(rD3, 12)
- xor rD0,rD0,rW0
- SAVE_DATA(rD0, 0)
- xor rD1,rD1,rW1
- SAVE_DATA(rD1, 4)
- xor rD2,rD2,rW2
- SAVE_DATA(rD2, 8)
- xor rD3,rD3,rW3
- SAVE_DATA(rD3, 12)
- addic rI3,rI3,1 /* increase counter */
- addze rI2,rI2
- addze rI1,rI1
- addze rI0,rI0
- NEXT_BLOCK
- cmpwi rLN,15
- bt gt,ppc_crypt_ctr_loop
- ppc_crypt_ctr_partial:
- cmpwi rLN,0
- bt eq,ppc_crypt_ctr_end
- mr rKP,rKS
- START_KEY(rI0, rI1, rI2, rI3)
- bl ppc_encrypt_block
- xor rW0,rD0,rW0
- SAVE_IV(rW0, 0)
- xor rW1,rD1,rW1
- SAVE_IV(rW1, 4)
- xor rW2,rD2,rW2
- SAVE_IV(rW2, 8)
- xor rW3,rD3,rW3
- SAVE_IV(rW3, 12)
- mtctr rLN
- subi rIP,rIP,CTR_DEC
- subi rSP,rSP,1
- subi rDP,rDP,1
- ppc_crypt_ctr_xorbyte:
- lbzu rW4,1(rIP) /* bytewise xor for partial block */
- lbzu rW5,1(rSP)
- xor rW4,rW4,rW5
- stbu rW4,1(rDP)
- bdnz ppc_crypt_ctr_xorbyte
- subf rIP,rLN,rIP
- addi rIP,rIP,1
- addic rI3,rI3,1
- addze rI2,rI2
- addze rI1,rI1
- addze rI0,rI0
- ppc_crypt_ctr_end:
- SAVE_IV(rI0, 0)
- SAVE_IV(rI1, 4)
- SAVE_IV(rI2, 8)
- SAVE_IV(rI3, 12)
- FINALIZE_CRYPT(4)
- blr
- /*
- * ppc_encrypt_xts(u8 *out, const u8 *in, u32 *key_enc,
- * u32 rounds, u32 bytes, u8 *iv, u32 *key_twk);
- *
- * called from glue layer to encrypt multiple blocks via XTS
- * If key_twk is given, the initial IV encryption will be
- * processed too. Round values are AES128 = 4, AES192 = 5,
- * AES256 = 6
- *
- */
- _GLOBAL(ppc_encrypt_xts)
- INITIALIZE_CRYPT(PPC_AES_4K_ENCTAB, 8)
- LOAD_IV(rI0, 0)
- LOAD_IV(rI1, 4)
- LOAD_IV(rI2, 8)
- cmpwi rKT,0
- LOAD_IV(rI3, 12)
- bt eq,ppc_encrypt_xts_notweak
- mr rKP,rKT
- START_KEY(rI0, rI1, rI2, rI3)
- bl ppc_encrypt_block
- xor rI0,rD0,rW0
- xor rI1,rD1,rW1
- xor rI2,rD2,rW2
- xor rI3,rD3,rW3
- ppc_encrypt_xts_notweak:
- ENDIAN_SWAP(rG0, rG1, rI0, rI1)
- ENDIAN_SWAP(rG2, rG3, rI2, rI3)
- ppc_encrypt_xts_loop:
- LOAD_DATA(rD0, 0)
- mr rKP,rKS
- LOAD_DATA(rD1, 4)
- subi rLN,rLN,16
- LOAD_DATA(rD2, 8)
- LOAD_DATA(rD3, 12)
- xor rD0,rD0,rI0
- xor rD1,rD1,rI1
- xor rD2,rD2,rI2
- xor rD3,rD3,rI3
- START_KEY(rD0, rD1, rD2, rD3)
- bl ppc_encrypt_block
- xor rD0,rD0,rW0
- xor rD1,rD1,rW1
- xor rD2,rD2,rW2
- xor rD3,rD3,rW3
- xor rD0,rD0,rI0
- SAVE_DATA(rD0, 0)
- xor rD1,rD1,rI1
- SAVE_DATA(rD1, 4)
- xor rD2,rD2,rI2
- SAVE_DATA(rD2, 8)
- xor rD3,rD3,rI3
- SAVE_DATA(rD3, 12)
- GF128_MUL(rG0, rG1, rG2, rG3, rW0)
- ENDIAN_SWAP(rI0, rI1, rG0, rG1)
- ENDIAN_SWAP(rI2, rI3, rG2, rG3)
- cmpwi rLN,0
- NEXT_BLOCK
- bt gt,ppc_encrypt_xts_loop
- START_IV
- SAVE_IV(rI0, 0)
- SAVE_IV(rI1, 4)
- SAVE_IV(rI2, 8)
- SAVE_IV(rI3, 12)
- FINALIZE_CRYPT(8)
- blr
- /*
- * ppc_decrypt_xts(u8 *out, const u8 *in, u32 *key_dec,
- * u32 rounds, u32 blocks, u8 *iv, u32 *key_twk);
- *
- * called from glue layer to decrypt multiple blocks via XTS
- * If key_twk is given, the initial IV encryption will be
- * processed too. Round values are AES128 = 4, AES192 = 5,
- * AES256 = 6
- *
- */
- _GLOBAL(ppc_decrypt_xts)
- INITIALIZE_CRYPT(PPC_AES_4K_DECTAB, 8)
- LOAD_IV(rI0, 0)
- addi rT1,rT0,4096
- LOAD_IV(rI1, 4)
- LOAD_IV(rI2, 8)
- cmpwi rKT,0
- LOAD_IV(rI3, 12)
- bt eq,ppc_decrypt_xts_notweak
- subi rT0,rT0,4096
- mr rKP,rKT
- START_KEY(rI0, rI1, rI2, rI3)
- bl ppc_encrypt_block
- xor rI0,rD0,rW0
- xor rI1,rD1,rW1
- xor rI2,rD2,rW2
- xor rI3,rD3,rW3
- addi rT0,rT0,4096
- ppc_decrypt_xts_notweak:
- ENDIAN_SWAP(rG0, rG1, rI0, rI1)
- ENDIAN_SWAP(rG2, rG3, rI2, rI3)
- ppc_decrypt_xts_loop:
- LOAD_DATA(rD0, 0)
- mr rKP,rKS
- LOAD_DATA(rD1, 4)
- subi rLN,rLN,16
- LOAD_DATA(rD2, 8)
- LOAD_DATA(rD3, 12)
- xor rD0,rD0,rI0
- xor rD1,rD1,rI1
- xor rD2,rD2,rI2
- xor rD3,rD3,rI3
- START_KEY(rD0, rD1, rD2, rD3)
- bl ppc_decrypt_block
- xor rD0,rD0,rW0
- xor rD1,rD1,rW1
- xor rD2,rD2,rW2
- xor rD3,rD3,rW3
- xor rD0,rD0,rI0
- SAVE_DATA(rD0, 0)
- xor rD1,rD1,rI1
- SAVE_DATA(rD1, 4)
- xor rD2,rD2,rI2
- SAVE_DATA(rD2, 8)
- xor rD3,rD3,rI3
- SAVE_DATA(rD3, 12)
- GF128_MUL(rG0, rG1, rG2, rG3, rW0)
- ENDIAN_SWAP(rI0, rI1, rG0, rG1)
- ENDIAN_SWAP(rI2, rI3, rG2, rG3)
- cmpwi rLN,0
- NEXT_BLOCK
- bt gt,ppc_decrypt_xts_loop
- START_IV
- SAVE_IV(rI0, 0)
- SAVE_IV(rI1, 4)
- SAVE_IV(rI2, 8)
- SAVE_IV(rI3, 12)
- FINALIZE_CRYPT(8)
- blr
|