123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713 |
- /* SPDX-License-Identifier: GPL-2.0-only */
- /*
- * aes-ce-core.S - AES in CBC/CTR/XTS mode using ARMv8 Crypto Extensions
- *
- * Copyright (C) 2015 Linaro Ltd <ard.biesheuvel@linaro.org>
- */
- #include <linux/linkage.h>
- #include <asm/assembler.h>
- .text
- .arch armv8-a
- .fpu crypto-neon-fp-armv8
- .align 3
- .macro enc_round, state, key
- aese.8 \state, \key
- aesmc.8 \state, \state
- .endm
- .macro dec_round, state, key
- aesd.8 \state, \key
- aesimc.8 \state, \state
- .endm
- .macro enc_dround, key1, key2
- enc_round q0, \key1
- enc_round q0, \key2
- .endm
- .macro dec_dround, key1, key2
- dec_round q0, \key1
- dec_round q0, \key2
- .endm
- .macro enc_fround, key1, key2, key3
- enc_round q0, \key1
- aese.8 q0, \key2
- veor q0, q0, \key3
- .endm
- .macro dec_fround, key1, key2, key3
- dec_round q0, \key1
- aesd.8 q0, \key2
- veor q0, q0, \key3
- .endm
- .macro enc_dround_4x, key1, key2
- enc_round q0, \key1
- enc_round q1, \key1
- enc_round q2, \key1
- enc_round q3, \key1
- enc_round q0, \key2
- enc_round q1, \key2
- enc_round q2, \key2
- enc_round q3, \key2
- .endm
- .macro dec_dround_4x, key1, key2
- dec_round q0, \key1
- dec_round q1, \key1
- dec_round q2, \key1
- dec_round q3, \key1
- dec_round q0, \key2
- dec_round q1, \key2
- dec_round q2, \key2
- dec_round q3, \key2
- .endm
- .macro enc_fround_4x, key1, key2, key3
- enc_round q0, \key1
- enc_round q1, \key1
- enc_round q2, \key1
- enc_round q3, \key1
- aese.8 q0, \key2
- aese.8 q1, \key2
- aese.8 q2, \key2
- aese.8 q3, \key2
- veor q0, q0, \key3
- veor q1, q1, \key3
- veor q2, q2, \key3
- veor q3, q3, \key3
- .endm
- .macro dec_fround_4x, key1, key2, key3
- dec_round q0, \key1
- dec_round q1, \key1
- dec_round q2, \key1
- dec_round q3, \key1
- aesd.8 q0, \key2
- aesd.8 q1, \key2
- aesd.8 q2, \key2
- aesd.8 q3, \key2
- veor q0, q0, \key3
- veor q1, q1, \key3
- veor q2, q2, \key3
- veor q3, q3, \key3
- .endm
- .macro do_block, dround, fround
- cmp r3, #12 @ which key size?
- vld1.32 {q10-q11}, [ip]!
- \dround q8, q9
- vld1.32 {q12-q13}, [ip]!
- \dround q10, q11
- vld1.32 {q10-q11}, [ip]!
- \dround q12, q13
- vld1.32 {q12-q13}, [ip]!
- \dround q10, q11
- blo 0f @ AES-128: 10 rounds
- vld1.32 {q10-q11}, [ip]!
- \dround q12, q13
- beq 1f @ AES-192: 12 rounds
- vld1.32 {q12-q13}, [ip]
- \dround q10, q11
- 0: \fround q12, q13, q14
- bx lr
- 1: \fround q10, q11, q14
- bx lr
- .endm
- /*
- * Internal, non-AAPCS compliant functions that implement the core AES
- * transforms. These should preserve all registers except q0 - q2 and ip
- * Arguments:
- * q0 : first in/output block
- * q1 : second in/output block (_4x version only)
- * q2 : third in/output block (_4x version only)
- * q3 : fourth in/output block (_4x version only)
- * q8 : first round key
- * q9 : secound round key
- * q14 : final round key
- * r2 : address of round key array
- * r3 : number of rounds
- */
- .align 6
- aes_encrypt:
- add ip, r2, #32 @ 3rd round key
- .Laes_encrypt_tweak:
- do_block enc_dround, enc_fround
- ENDPROC(aes_encrypt)
- .align 6
- aes_decrypt:
- add ip, r2, #32 @ 3rd round key
- do_block dec_dround, dec_fround
- ENDPROC(aes_decrypt)
- .align 6
- aes_encrypt_4x:
- add ip, r2, #32 @ 3rd round key
- do_block enc_dround_4x, enc_fround_4x
- ENDPROC(aes_encrypt_4x)
- .align 6
- aes_decrypt_4x:
- add ip, r2, #32 @ 3rd round key
- do_block dec_dround_4x, dec_fround_4x
- ENDPROC(aes_decrypt_4x)
- .macro prepare_key, rk, rounds
- add ip, \rk, \rounds, lsl #4
- vld1.32 {q8-q9}, [\rk] @ load first 2 round keys
- vld1.32 {q14}, [ip] @ load last round key
- .endm
- /*
- * aes_ecb_encrypt(u8 out[], u8 const in[], u32 const rk[], int rounds,
- * int blocks)
- * aes_ecb_decrypt(u8 out[], u8 const in[], u32 const rk[], int rounds,
- * int blocks)
- */
- ENTRY(ce_aes_ecb_encrypt)
- push {r4, lr}
- ldr r4, [sp, #8]
- prepare_key r2, r3
- .Lecbencloop4x:
- subs r4, r4, #4
- bmi .Lecbenc1x
- vld1.8 {q0-q1}, [r1]!
- vld1.8 {q2-q3}, [r1]!
- bl aes_encrypt_4x
- vst1.8 {q0-q1}, [r0]!
- vst1.8 {q2-q3}, [r0]!
- b .Lecbencloop4x
- .Lecbenc1x:
- adds r4, r4, #4
- beq .Lecbencout
- .Lecbencloop:
- vld1.8 {q0}, [r1]!
- bl aes_encrypt
- vst1.8 {q0}, [r0]!
- subs r4, r4, #1
- bne .Lecbencloop
- .Lecbencout:
- pop {r4, pc}
- ENDPROC(ce_aes_ecb_encrypt)
- ENTRY(ce_aes_ecb_decrypt)
- push {r4, lr}
- ldr r4, [sp, #8]
- prepare_key r2, r3
- .Lecbdecloop4x:
- subs r4, r4, #4
- bmi .Lecbdec1x
- vld1.8 {q0-q1}, [r1]!
- vld1.8 {q2-q3}, [r1]!
- bl aes_decrypt_4x
- vst1.8 {q0-q1}, [r0]!
- vst1.8 {q2-q3}, [r0]!
- b .Lecbdecloop4x
- .Lecbdec1x:
- adds r4, r4, #4
- beq .Lecbdecout
- .Lecbdecloop:
- vld1.8 {q0}, [r1]!
- bl aes_decrypt
- vst1.8 {q0}, [r0]!
- subs r4, r4, #1
- bne .Lecbdecloop
- .Lecbdecout:
- pop {r4, pc}
- ENDPROC(ce_aes_ecb_decrypt)
- /*
- * aes_cbc_encrypt(u8 out[], u8 const in[], u32 const rk[], int rounds,
- * int blocks, u8 iv[])
- * aes_cbc_decrypt(u8 out[], u8 const in[], u32 const rk[], int rounds,
- * int blocks, u8 iv[])
- */
- ENTRY(ce_aes_cbc_encrypt)
- push {r4-r6, lr}
- ldrd r4, r5, [sp, #16]
- vld1.8 {q0}, [r5]
- prepare_key r2, r3
- .Lcbcencloop:
- vld1.8 {q1}, [r1]! @ get next pt block
- veor q0, q0, q1 @ ..and xor with iv
- bl aes_encrypt
- vst1.8 {q0}, [r0]!
- subs r4, r4, #1
- bne .Lcbcencloop
- vst1.8 {q0}, [r5]
- pop {r4-r6, pc}
- ENDPROC(ce_aes_cbc_encrypt)
- ENTRY(ce_aes_cbc_decrypt)
- push {r4-r6, lr}
- ldrd r4, r5, [sp, #16]
- vld1.8 {q15}, [r5] @ keep iv in q15
- prepare_key r2, r3
- .Lcbcdecloop4x:
- subs r4, r4, #4
- bmi .Lcbcdec1x
- vld1.8 {q0-q1}, [r1]!
- vld1.8 {q2-q3}, [r1]!
- vmov q4, q0
- vmov q5, q1
- vmov q6, q2
- vmov q7, q3
- bl aes_decrypt_4x
- veor q0, q0, q15
- veor q1, q1, q4
- veor q2, q2, q5
- veor q3, q3, q6
- vmov q15, q7
- vst1.8 {q0-q1}, [r0]!
- vst1.8 {q2-q3}, [r0]!
- b .Lcbcdecloop4x
- .Lcbcdec1x:
- adds r4, r4, #4
- beq .Lcbcdecout
- vmov q6, q14 @ preserve last round key
- .Lcbcdecloop:
- vld1.8 {q0}, [r1]! @ get next ct block
- veor q14, q15, q6 @ combine prev ct with last key
- vmov q15, q0
- bl aes_decrypt
- vst1.8 {q0}, [r0]!
- subs r4, r4, #1
- bne .Lcbcdecloop
- .Lcbcdecout:
- vst1.8 {q15}, [r5] @ keep iv in q15
- pop {r4-r6, pc}
- ENDPROC(ce_aes_cbc_decrypt)
- /*
- * ce_aes_cbc_cts_encrypt(u8 out[], u8 const in[], u32 const rk[],
- * int rounds, int bytes, u8 const iv[])
- * ce_aes_cbc_cts_decrypt(u8 out[], u8 const in[], u32 const rk[],
- * int rounds, int bytes, u8 const iv[])
- */
- ENTRY(ce_aes_cbc_cts_encrypt)
- push {r4-r6, lr}
- ldrd r4, r5, [sp, #16]
- movw ip, :lower16:.Lcts_permute_table
- movt ip, :upper16:.Lcts_permute_table
- sub r4, r4, #16
- add lr, ip, #32
- add ip, ip, r4
- sub lr, lr, r4
- vld1.8 {q5}, [ip]
- vld1.8 {q6}, [lr]
- add ip, r1, r4
- vld1.8 {q0}, [r1] @ overlapping loads
- vld1.8 {q3}, [ip]
- vld1.8 {q1}, [r5] @ get iv
- prepare_key r2, r3
- veor q0, q0, q1 @ xor with iv
- bl aes_encrypt
- vtbl.8 d4, {d0-d1}, d10
- vtbl.8 d5, {d0-d1}, d11
- vtbl.8 d2, {d6-d7}, d12
- vtbl.8 d3, {d6-d7}, d13
- veor q0, q0, q1
- bl aes_encrypt
- add r4, r0, r4
- vst1.8 {q2}, [r4] @ overlapping stores
- vst1.8 {q0}, [r0]
- pop {r4-r6, pc}
- ENDPROC(ce_aes_cbc_cts_encrypt)
- ENTRY(ce_aes_cbc_cts_decrypt)
- push {r4-r6, lr}
- ldrd r4, r5, [sp, #16]
- movw ip, :lower16:.Lcts_permute_table
- movt ip, :upper16:.Lcts_permute_table
- sub r4, r4, #16
- add lr, ip, #32
- add ip, ip, r4
- sub lr, lr, r4
- vld1.8 {q5}, [ip]
- vld1.8 {q6}, [lr]
- add ip, r1, r4
- vld1.8 {q0}, [r1] @ overlapping loads
- vld1.8 {q1}, [ip]
- vld1.8 {q3}, [r5] @ get iv
- prepare_key r2, r3
- bl aes_decrypt
- vtbl.8 d4, {d0-d1}, d10
- vtbl.8 d5, {d0-d1}, d11
- vtbx.8 d0, {d2-d3}, d12
- vtbx.8 d1, {d2-d3}, d13
- veor q1, q1, q2
- bl aes_decrypt
- veor q0, q0, q3 @ xor with iv
- add r4, r0, r4
- vst1.8 {q1}, [r4] @ overlapping stores
- vst1.8 {q0}, [r0]
- pop {r4-r6, pc}
- ENDPROC(ce_aes_cbc_cts_decrypt)
- /*
- * aes_ctr_encrypt(u8 out[], u8 const in[], u32 const rk[], int rounds,
- * int blocks, u8 ctr[])
- */
- ENTRY(ce_aes_ctr_encrypt)
- push {r4-r6, lr}
- ldrd r4, r5, [sp, #16]
- vld1.8 {q7}, [r5] @ load ctr
- prepare_key r2, r3
- vmov r6, s31 @ keep swabbed ctr in r6
- rev r6, r6
- cmn r6, r4 @ 32 bit overflow?
- bcs .Lctrloop
- .Lctrloop4x:
- subs r4, r4, #4
- bmi .Lctr1x
- /*
- * NOTE: the sequence below has been carefully tweaked to avoid
- * a silicon erratum that exists in Cortex-A57 (#1742098) and
- * Cortex-A72 (#1655431) cores, where AESE/AESMC instruction pairs
- * may produce an incorrect result if they take their input from a
- * register of which a single 32-bit lane has been updated the last
- * time it was modified. To work around this, the lanes of registers
- * q0-q3 below are not manipulated individually, and the different
- * counter values are prepared by successive manipulations of q7.
- */
- add ip, r6, #1
- vmov q0, q7
- rev ip, ip
- add lr, r6, #2
- vmov s31, ip @ set lane 3 of q1 via q7
- add ip, r6, #3
- rev lr, lr
- vmov q1, q7
- vmov s31, lr @ set lane 3 of q2 via q7
- rev ip, ip
- vmov q2, q7
- vmov s31, ip @ set lane 3 of q3 via q7
- add r6, r6, #4
- vmov q3, q7
- vld1.8 {q4-q5}, [r1]!
- vld1.8 {q6}, [r1]!
- vld1.8 {q15}, [r1]!
- bl aes_encrypt_4x
- veor q0, q0, q4
- veor q1, q1, q5
- veor q2, q2, q6
- veor q3, q3, q15
- rev ip, r6
- vst1.8 {q0-q1}, [r0]!
- vst1.8 {q2-q3}, [r0]!
- vmov s31, ip
- b .Lctrloop4x
- .Lctr1x:
- adds r4, r4, #4
- beq .Lctrout
- .Lctrloop:
- vmov q0, q7
- bl aes_encrypt
- adds r6, r6, #1 @ increment BE ctr
- rev ip, r6
- vmov s31, ip
- bcs .Lctrcarry
- .Lctrcarrydone:
- subs r4, r4, #1
- bmi .Lctrtailblock @ blocks < 0 means tail block
- vld1.8 {q3}, [r1]!
- veor q3, q0, q3
- vst1.8 {q3}, [r0]!
- bne .Lctrloop
- .Lctrout:
- vst1.8 {q7}, [r5] @ return next CTR value
- pop {r4-r6, pc}
- .Lctrtailblock:
- vst1.8 {q0}, [r0, :64] @ return the key stream
- b .Lctrout
- .Lctrcarry:
- .irp sreg, s30, s29, s28
- vmov ip, \sreg @ load next word of ctr
- rev ip, ip @ ... to handle the carry
- adds ip, ip, #1
- rev ip, ip
- vmov \sreg, ip
- bcc .Lctrcarrydone
- .endr
- b .Lctrcarrydone
- ENDPROC(ce_aes_ctr_encrypt)
- /*
- * aes_xts_encrypt(u8 out[], u8 const in[], u32 const rk1[], int rounds,
- * int bytes, u8 iv[], u32 const rk2[], int first)
- * aes_xts_decrypt(u8 out[], u8 const in[], u32 const rk1[], int rounds,
- * int bytes, u8 iv[], u32 const rk2[], int first)
- */
- .macro next_tweak, out, in, const, tmp
- vshr.s64 \tmp, \in, #63
- vand \tmp, \tmp, \const
- vadd.u64 \out, \in, \in
- vext.8 \tmp, \tmp, \tmp, #8
- veor \out, \out, \tmp
- .endm
- ce_aes_xts_init:
- vmov.i32 d30, #0x87 @ compose tweak mask vector
- vmovl.u32 q15, d30
- vshr.u64 d30, d31, #7
- ldrd r4, r5, [sp, #16] @ load args
- ldr r6, [sp, #28]
- vld1.8 {q0}, [r5] @ load iv
- teq r6, #1 @ start of a block?
- bxne lr
- @ Encrypt the IV in q0 with the second AES key. This should only
- @ be done at the start of a block.
- ldr r6, [sp, #24] @ load AES key 2
- prepare_key r6, r3
- add ip, r6, #32 @ 3rd round key of key 2
- b .Laes_encrypt_tweak @ tail call
- ENDPROC(ce_aes_xts_init)
- ENTRY(ce_aes_xts_encrypt)
- push {r4-r6, lr}
- bl ce_aes_xts_init @ run shared prologue
- prepare_key r2, r3
- vmov q4, q0
- teq r6, #0 @ start of a block?
- bne .Lxtsenc4x
- .Lxtsencloop4x:
- next_tweak q4, q4, q15, q10
- .Lxtsenc4x:
- subs r4, r4, #64
- bmi .Lxtsenc1x
- vld1.8 {q0-q1}, [r1]! @ get 4 pt blocks
- vld1.8 {q2-q3}, [r1]!
- next_tweak q5, q4, q15, q10
- veor q0, q0, q4
- next_tweak q6, q5, q15, q10
- veor q1, q1, q5
- next_tweak q7, q6, q15, q10
- veor q2, q2, q6
- veor q3, q3, q7
- bl aes_encrypt_4x
- veor q0, q0, q4
- veor q1, q1, q5
- veor q2, q2, q6
- veor q3, q3, q7
- vst1.8 {q0-q1}, [r0]! @ write 4 ct blocks
- vst1.8 {q2-q3}, [r0]!
- vmov q4, q7
- teq r4, #0
- beq .Lxtsencret
- b .Lxtsencloop4x
- .Lxtsenc1x:
- adds r4, r4, #64
- beq .Lxtsencout
- subs r4, r4, #16
- bmi .LxtsencctsNx
- .Lxtsencloop:
- vld1.8 {q0}, [r1]!
- .Lxtsencctsout:
- veor q0, q0, q4
- bl aes_encrypt
- veor q0, q0, q4
- teq r4, #0
- beq .Lxtsencout
- subs r4, r4, #16
- next_tweak q4, q4, q15, q6
- bmi .Lxtsenccts
- vst1.8 {q0}, [r0]!
- b .Lxtsencloop
- .Lxtsencout:
- vst1.8 {q0}, [r0]
- .Lxtsencret:
- vst1.8 {q4}, [r5]
- pop {r4-r6, pc}
- .LxtsencctsNx:
- vmov q0, q3
- sub r0, r0, #16
- .Lxtsenccts:
- movw ip, :lower16:.Lcts_permute_table
- movt ip, :upper16:.Lcts_permute_table
- add r1, r1, r4 @ rewind input pointer
- add r4, r4, #16 @ # bytes in final block
- add lr, ip, #32
- add ip, ip, r4
- sub lr, lr, r4
- add r4, r0, r4 @ output address of final block
- vld1.8 {q1}, [r1] @ load final partial block
- vld1.8 {q2}, [ip]
- vld1.8 {q3}, [lr]
- vtbl.8 d4, {d0-d1}, d4
- vtbl.8 d5, {d0-d1}, d5
- vtbx.8 d0, {d2-d3}, d6
- vtbx.8 d1, {d2-d3}, d7
- vst1.8 {q2}, [r4] @ overlapping stores
- mov r4, #0
- b .Lxtsencctsout
- ENDPROC(ce_aes_xts_encrypt)
- ENTRY(ce_aes_xts_decrypt)
- push {r4-r6, lr}
- bl ce_aes_xts_init @ run shared prologue
- prepare_key r2, r3
- vmov q4, q0
- /* subtract 16 bytes if we are doing CTS */
- tst r4, #0xf
- subne r4, r4, #0x10
- teq r6, #0 @ start of a block?
- bne .Lxtsdec4x
- .Lxtsdecloop4x:
- next_tweak q4, q4, q15, q10
- .Lxtsdec4x:
- subs r4, r4, #64
- bmi .Lxtsdec1x
- vld1.8 {q0-q1}, [r1]! @ get 4 ct blocks
- vld1.8 {q2-q3}, [r1]!
- next_tweak q5, q4, q15, q10
- veor q0, q0, q4
- next_tweak q6, q5, q15, q10
- veor q1, q1, q5
- next_tweak q7, q6, q15, q10
- veor q2, q2, q6
- veor q3, q3, q7
- bl aes_decrypt_4x
- veor q0, q0, q4
- veor q1, q1, q5
- veor q2, q2, q6
- veor q3, q3, q7
- vst1.8 {q0-q1}, [r0]! @ write 4 pt blocks
- vst1.8 {q2-q3}, [r0]!
- vmov q4, q7
- teq r4, #0
- beq .Lxtsdecout
- b .Lxtsdecloop4x
- .Lxtsdec1x:
- adds r4, r4, #64
- beq .Lxtsdecout
- subs r4, r4, #16
- .Lxtsdecloop:
- vld1.8 {q0}, [r1]!
- bmi .Lxtsdeccts
- .Lxtsdecctsout:
- veor q0, q0, q4
- bl aes_decrypt
- veor q0, q0, q4
- vst1.8 {q0}, [r0]!
- teq r4, #0
- beq .Lxtsdecout
- subs r4, r4, #16
- next_tweak q4, q4, q15, q6
- b .Lxtsdecloop
- .Lxtsdecout:
- vst1.8 {q4}, [r5]
- pop {r4-r6, pc}
- .Lxtsdeccts:
- movw ip, :lower16:.Lcts_permute_table
- movt ip, :upper16:.Lcts_permute_table
- add r1, r1, r4 @ rewind input pointer
- add r4, r4, #16 @ # bytes in final block
- add lr, ip, #32
- add ip, ip, r4
- sub lr, lr, r4
- add r4, r0, r4 @ output address of final block
- next_tweak q5, q4, q15, q6
- vld1.8 {q1}, [r1] @ load final partial block
- vld1.8 {q2}, [ip]
- vld1.8 {q3}, [lr]
- veor q0, q0, q5
- bl aes_decrypt
- veor q0, q0, q5
- vtbl.8 d4, {d0-d1}, d4
- vtbl.8 d5, {d0-d1}, d5
- vtbx.8 d0, {d2-d3}, d6
- vtbx.8 d1, {d2-d3}, d7
- vst1.8 {q2}, [r4] @ overlapping stores
- mov r4, #0
- b .Lxtsdecctsout
- ENDPROC(ce_aes_xts_decrypt)
- /*
- * u32 ce_aes_sub(u32 input) - use the aese instruction to perform the
- * AES sbox substitution on each byte in
- * 'input'
- */
- ENTRY(ce_aes_sub)
- vdup.32 q1, r0
- veor q0, q0, q0
- aese.8 q0, q1
- vmov r0, s0
- bx lr
- ENDPROC(ce_aes_sub)
- /*
- * void ce_aes_invert(u8 *dst, u8 *src) - perform the Inverse MixColumns
- * operation on round key *src
- */
- ENTRY(ce_aes_invert)
- vld1.32 {q0}, [r1]
- aesimc.8 q0, q0
- vst1.32 {q0}, [r0]
- bx lr
- ENDPROC(ce_aes_invert)
- .section ".rodata", "a"
- .align 6
- .Lcts_permute_table:
- .byte 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
- .byte 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
- .byte 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7
- .byte 0x8, 0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf
- .byte 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
- .byte 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
|