| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612 |
- #define __ARM_ARCH__ __LINUX_ARM_ARCH__
- #include <linux/linkage.h>
- #if __ARM_ARCH__>=7
- .fpu crypto-neon-fp-armv8
- .text
- # AES assembly implementation for ARMv8 AArch32
- # - aes_v8_cbc_encrypt
- # - aes_v8_cbc_decrypt
- .align 5
- rcon:
- .long 0x00000001,0x00000001,0x00000001,0x00000001
- .long 0x0c0f0e0d,0x0c0f0e0d,0x0c0f0e0d,0x0c0f0e0d
- .long 0x0000001b,0x0000001b,0x0000001b,0x0000001b
- # void aes_v8_cbc_encrypt(u8 out[], u8 const in[], u8 const rk[],
- # int rounds, int blocks, u8 iv[], int first);
- .align 5
- ENTRY(aes_v8_cbc_encrypt)
- push {r4, r5, r6}
- vpush {q4, q5, q6, q7}
- ldr r4, [sp, #76] // blocks
- ldr r5, [sp, #80] // iv
- ldr r6, [sp, #84] // first
- cmp r6, #0
- beq .LcbcencDispatch
- vld1.8 {d2-d3}, [r5]
- .LcbcencDispatch:
- cmp r3, #12
- bhi .Lcbcenc256
- beq .Lcbcenc192
- .Lcbcenc128:
- // Load round keys
- vld1.8 {d4-d5}, [r2]!
- vld1.8 {d6-d7}, [r2]!
- vld1.8 {d8-d9}, [r2]!
- vld1.8 {d10-d11}, [r2]!
- vld1.8 {d12-d13}, [r2]!
- vld1.8 {d14-d15}, [r2]!
- vld1.8 {d16-d17}, [r2]!
- vld1.8 {d18-d19}, [r2]!
- vld1.8 {d20-d21}, [r2]!
- vld1.8 {d22-d23}, [r2]!
- vld1.8 {d24-d25}, [r2]
- .Lcbcenc128Loop:
- // load input 16 bytes, and eor with iv
- vld1.8 {d0-d1}, [r1]!
- veor.8 q0, q0, q1
- pld [r1, #16]
- // aes kernel
- aese.8 q0, q2
- aesmc.8 q0, q0
- aese.8 q0, q3
- aesmc.8 q0, q0
- aese.8 q0, q4
- aesmc.8 q0, q0
- aese.8 q0, q5
- aesmc.8 q0, q0
- aese.8 q0, q6
- aesmc.8 q0, q0
- aese.8 q0, q7
- aesmc.8 q0, q0
- aese.8 q0, q8
- aesmc.8 q0, q0
- aese.8 q0, q9
- aesmc.8 q0, q0
- aese.8 q0, q10
- aesmc.8 q0, q0
- aese.8 q0, q11
- veor.8 q1, q0, q12
- // store output 16 bytes, and continue next round
- vst1.8 {d2-d3}, [r0]!
- subs r4, r4, #1
- bne .Lcbcenc128Loop
- .Lcbcenc128Done:
- vpop {q4, q5, q6, q7}
- pop {r4, r5, r6}
- bx lr
- .Lcbcenc192:
- // Load round keys
- vld1.8 {d4-d5}, [r2]!
- vld1.8 {d6-d7}, [r2]!
- vld1.8 {d8-d9}, [r2]!
- vld1.8 {d10-d11}, [r2]!
- vld1.8 {d12-d13}, [r2]!
- vld1.8 {d14-d15}, [r2]!
- vld1.8 {d16-d17}, [r2]!
- vld1.8 {d18-d19}, [r2]!
- vld1.8 {d20-d21}, [r2]!
- vld1.8 {d22-d23}, [r2]!
- vld1.8 {d24-d25}, [r2]!
- vld1.8 {d26-d27}, [r2]!
- vld1.8 {d28-d29}, [r2]
- .Lcbcenc192Loop:
- // load input 16 bytes, and eor with iv
- vld1.8 {d0-d1}, [r1]!
- veor.8 q0, q0, q1
- pld [r1, #16]
- // aes kernel
- aese.8 q0, q2
- aesmc.8 q0, q0
- aese.8 q0, q3
- aesmc.8 q0, q0
- aese.8 q0, q4
- aesmc.8 q0, q0
- aese.8 q0, q5
- aesmc.8 q0, q0
- aese.8 q0, q6
- aesmc.8 q0, q0
- aese.8 q0, q7
- aesmc.8 q0, q0
- aese.8 q0, q8
- aesmc.8 q0, q0
- aese.8 q0, q9
- aesmc.8 q0, q0
- aese.8 q0, q10
- aesmc.8 q0, q0
- aese.8 q0, q11
- aesmc.8 q0, q0
- aese.8 q0, q12
- aesmc.8 q0, q0
- aese.8 q0, q13
- veor.8 q1, q0, q14
- // store output 16 bytes, and continue next round
- vst1.8 {d2-d3}, [r0]!
- subs r4, r4, #1
- bne .Lcbcenc192Loop
- .Lcbcenc192Done:
- vpop {q4, q5, q6, q7}
- pop {r4, r5, r6}
- bx lr
- .Lcbcenc256:
- // Load round keys
- vld1.8 {d4-d5}, [r2]!
- vld1.8 {d6-d7}, [r2]!
- vld1.8 {d8-d9}, [r2]!
- vld1.8 {d10-d11}, [r2]!
- vld1.8 {d12-d13}, [r2]!
- vld1.8 {d14-d15}, [r2]!
- vld1.8 {d16-d17}, [r2]!
- vld1.8 {d18-d19}, [r2]!
- vld1.8 {d20-d21}, [r2]!
- vld1.8 {d22-d23}, [r2]!
- vld1.8 {d24-d25}, [r2]!
- vld1.8 {d26-d27}, [r2]!
- vld1.8 {d28-d29}, [r2]!
- mov r3, r2
- .Lcbcenc256Loop:
- // load input 16 bytes, and eor with iv
- vld1.8 {d0-d1}, [r1]!
- veor.8 q0, q0, q1
- pld [r1, #16]
- // aes kernel
- aese.8 q0, q2
- aesmc.8 q0, q0
- aese.8 q0, q3
- aesmc.8 q0, q0
- vld1.8 {d30}, [r2]!
- aese.8 q0, q4
- aesmc.8 q0, q0
- aese.8 q0, q5
- aesmc.8 q0, q0
- vld1.8 {d31}, [r2]!
- aese.8 q0, q6
- aesmc.8 q0, q0
- aese.8 q0, q7
- aesmc.8 q0, q0
- aese.8 q0, q8
- aesmc.8 q0, q0
- aese.8 q0, q9
- aesmc.8 q0, q0
- aese.8 q0, q10
- aesmc.8 q0, q0
- aese.8 q0, q11
- aesmc.8 q0, q0
- aese.8 q0, q12
- aesmc.8 q0, q0
- aese.8 q0, q13
- aesmc.8 q0, q0
- aese.8 q0, q14
- aesmc.8 q0, q0
- aese.8 q0, q15
- vld1.8 {d30-d31}, [r2]
- veor.8 q1, q0, q15
- mov r2, r3
- // store output 16 bytes, and continue next round
- vst1.8 {d2-d3}, [r0]!
- subs r4, r4, #1
- bne .Lcbcenc256Loop
- .Lcbcenc256Done:
- vpop {q4, q5, q6, q7}
- pop {r4, r5, r6}
- bx lr
- ENDPROC(aes_v8_cbc_encrypt)
- # void aes_v8_cbc_decrypt(u8 out[], u8 const in[], u8 const rk[],
- # int rounds, int blocks, u8 iv[], int first);
- .align 5
- ENTRY(aes_v8_cbc_decrypt)
- push {r4, r5, r6}
- vpush {q4, q5, q6, q7}
- ldr r4, [sp, #76] // blocks
- ldr r5, [sp, #80] // iv
- ldr r6, [sp, #84] // first
- cmp r6, #0
- beq .LcbcdecDispatch
- vld1.8 {d4-d5}, [r5]
- .LcbcdecDispatch:
- cmp r3, #12
- bhi .Lcbcdec256
- beq .Lcbcdec192
- .Lcbcdec128:
- // Load round keys
- vld1.8 {d10-d11}, [r2]!
- vld1.8 {d12-d13}, [r2]!
- vld1.8 {d14-d15}, [r2]!
- vld1.8 {d16-d17}, [r2]!
- vld1.8 {d18-d19}, [r2]!
- vld1.8 {d20-d21}, [r2]!
- vld1.8 {d22-d23}, [r2]!
- vld1.8 {d24-d25}, [r2]!
- vld1.8 {d26-d27}, [r2]!
- vld1.8 {d28-d29}, [r2]!
- vld1.8 {d30-d31}, [r2]!
- // Sub by 2
- subs r4, r4, #2
- bmi .Lcbcdec128_1X
- .Lcbcdec128_2XLoop:
- // Load input 32 bytes
- vld1.8 {d0-d3}, [r1]!
- pld [r1, #32]
- vmov q3, q0
- vmov q4, q1
- // aes kernel
- aesd.8 q0, q5
- aesimc.8 q0, q0
- aesd.8 q1, q5
- aesimc.8 q1, q1
- aesd.8 q0, q6
- aesimc.8 q0, q0
- aesd.8 q1, q6
- aesimc.8 q1, q1
- aesd.8 q0, q7
- aesimc.8 q0, q0
- aesd.8 q1, q7
- aesimc.8 q1, q1
- aesd.8 q0, q8
- aesimc.8 q0, q0
- aesd.8 q1, q8
- aesimc.8 q1, q1
- aesd.8 q0, q9
- aesimc.8 q0, q0
- aesd.8 q1, q9
- aesimc.8 q1, q1
- aesd.8 q0, q10
- aesimc.8 q0, q0
- aesd.8 q1, q10
- aesimc.8 q1, q1
- aesd.8 q0, q11
- aesimc.8 q0, q0
- aesd.8 q1, q11
- aesimc.8 q1, q1
- aesd.8 q0, q12
- aesimc.8 q0, q0
- aesd.8 q1, q12
- aesimc.8 q1, q1
- aesd.8 q0, q13
- aesimc.8 q0, q0
- aesd.8 q1, q13
- aesimc.8 q1, q1
- aesd.8 q0, q14
- aesd.8 q1, q14
- veor.8 q0, q0, q15
- veor.8 q1, q1, q15
- veor.8 q0, q0, q2
- veor.8 q1, q1, q3
- vmov q2, q4
- vst1.8 {d0-d1}, [r0]!
- vst1.8 {d2-d3}, [r0]!
- vst1.8 {d4-d5}, [r5]
- subs r4, r4, #2
- bpl .Lcbcdec128_2XLoop
- .Lcbcdec128_1X:
- adds r4, r4, #2
- bne .Lcbcdec128_FinalRound
- vpop {q4, q5, q6, q7}
- pop {r4, r5, r6}
- bx lr
- .Lcbcdec128_FinalRound:
- // load input 16 bytes
- vld1.8 {d0-d1}, [r1]!
- vmov q3, q0
- vst1.8 {d0-d1}, [r5]
- // aes kernel
- aesd.8 q0, q5
- aesimc.8 q0, q0
- aesd.8 q0, q6
- aesimc.8 q0, q0
- aesd.8 q0, q7
- aesimc.8 q0, q0
- aesd.8 q0, q8
- aesimc.8 q0, q0
- aesd.8 q0, q9
- aesimc.8 q0, q0
- aesd.8 q0, q10
- aesimc.8 q0, q0
- aesd.8 q0, q11
- aesimc.8 q0, q0
- aesd.8 q0, q12
- aesimc.8 q0, q0
- aesd.8 q0, q13
- aesimc.8 q0, q0
- aesd.8 q0, q14
- veor.8 q0, q0, q15
- veor.8 q0, q0, q2
- vmov q2, q3
- vst1.8 {d0-d1}, [r0]!
- vpop {q4, q5, q6, q7}
- pop {r4, r5, r6}
- bx lr
- .Lcbcdec192:
- // Load round keys
- vld1.8 {d10-d11}, [r2]!
- vld1.8 {d12-d13}, [r2]!
- vld1.8 {d14-d15}, [r2]!
- vld1.8 {d16-d17}, [r2]!
- vld1.8 {d18-d19}, [r2]!
- vld1.8 {d20-d21}, [r2]!
- vld1.8 {d22-d23}, [r2]!
- vld1.8 {d24-d25}, [r2]!
- vld1.8 {d26-d27}, [r2]!
- vld1.8 {d28-d29}, [r2]!
- mov r3, r2
- // Sub by 2
- subs r4, r4, #2
- bmi .Lcbcdec192_1X
- .Lcbcdec192_2XLoop:
- // Load input 32 bytes
- vld1.8 {d0-d3}, [r1]!
- pld [r1, #32]
- vmov q3, q0
- vmov q4, q1
- // aes kernel
- aesd.8 q0, q5
- aesimc.8 q0, q0
- aesd.8 q1, q5
- aesimc.8 q1, q1
- aesd.8 q0, q6
- aesimc.8 q0, q0
- aesd.8 q1, q6
- aesimc.8 q1, q1
- aesd.8 q0, q7
- aesimc.8 q0, q0
- aesd.8 q1, q7
- aesimc.8 q1, q1
- aesd.8 q0, q8
- aesimc.8 q0, q0
- aesd.8 q1, q8
- aesimc.8 q1, q1
- aesd.8 q0, q9
- aesimc.8 q0, q0
- aesd.8 q1, q9
- aesimc.8 q1, q1
- aesd.8 q0, q10
- aesimc.8 q0, q0
- aesd.8 q1, q10
- aesimc.8 q1, q1
- aesd.8 q0, q11
- aesimc.8 q0, q0
- aesd.8 q1, q11
- aesimc.8 q1, q1
- aesd.8 q0, q12
- aesimc.8 q0, q0
- aesd.8 q1, q12
- aesimc.8 q1, q1
- aesd.8 q0, q13
- aesimc.8 q0, q0
- aesd.8 q1, q13
- aesimc.8 q1, q1
- aesd.8 q0, q14
- aesimc.8 q0, q0
- aesd.8 q1, q14
- aesimc.8 q1, q1
- vld1.8 {d30-d31}, [r2]!
- aesd.8 q0, q15
- aesimc.8 q0, q0
- aesd.8 q1, q15
- aesimc.8 q1, q1
- vld1.8 {d30-d31}, [r2]!
- aesd.8 q0, q15
- aesd.8 q1, q15
- vld1.8 {d30-d31}, [r2]!
- veor.8 q0, q0, q15
- veor.8 q1, q1, q15
- mov r2, r3
- veor.8 q0, q0, q2
- veor.8 q1, q1, q3
- vmov q2, q4
- vst1.8 {d0-d1}, [r0]!
- vst1.8 {d2-d3}, [r0]!
- vst1.8 {d4-d5}, [r5]
- subs r4, r4, #2
- bpl .Lcbcdec192_2XLoop
- .Lcbcdec192_1X:
- adds r4, r4, #2
- bne .Lcbcdec192_FinalRound
- vpop {q4, q5, q6, q7}
- pop {r4, r5, r6}
- bx lr
- .Lcbcdec192_FinalRound:
- // load input 16 bytes
- vld1.8 {d0-d1}, [r1]!
- vmov q3, q0
- vst1.8 {d0-d1}, [r5]
- // aes kernel
- aesd.8 q0, q5
- aesimc.8 q0, q0
- vld1.8 {d30}, [r2]!
- aesd.8 q0, q6
- aesimc.8 q0, q0
- vld1.8 {d31}, [r2]!
- aesd.8 q0, q7
- aesimc.8 q0, q0
- aesd.8 q0, q8
- aesimc.8 q0, q0
- aesd.8 q0, q9
- aesimc.8 q0, q0
- aesd.8 q0, q10
- aesimc.8 q0, q0
- aesd.8 q0, q11
- aesimc.8 q0, q0
- aesd.8 q0, q12
- aesimc.8 q0, q0
- aesd.8 q0, q13
- aesimc.8 q0, q0
- aesd.8 q0, q14
- aesimc.8 q0, q0
- aesd.8 q0, q15
- aesimc.8 q0, q0
- vld1.8 {d30-d31}, [r2]!
- aesd.8 q0, q15
- vld1.8 {d30-d31}, [r2]!
- veor.8 q0, q0, q15
- veor.8 q0, q0, q2
- vmov q2, q3
- vst1.8 {d0-d1}, [r0]!
- vpop {q4, q5, q6, q7}
- pop {r4, r5, r6}
- bx lr
- .Lcbcdec256:
- // Load round keys
- vld1.8 {d10-d11}, [r2]!
- vld1.8 {d12-d13}, [r2]!
- vld1.8 {d14-d15}, [r2]!
- vld1.8 {d16-d17}, [r2]!
- vld1.8 {d18-d19}, [r2]!
- vld1.8 {d20-d21}, [r2]!
- vld1.8 {d22-d23}, [r2]!
- vld1.8 {d24-d25}, [r2]!
- vld1.8 {d26-d27}, [r2]!
- vld1.8 {d28-d29}, [r2]!
- mov r3, r2
- // Sub by 2
- subs r4, r4, #2
- bmi .Lcbcdec256_1X
- .Lcbcdec256_2XLoop:
- // Load input 32 bytes
- vld1.8 {d0-d3}, [r1]!
- pld [r1, #32]
- vmov q3, q0
- vmov q4, q1
- // aes kernel
- aesd.8 q0, q5
- aesimc.8 q0, q0
- aesd.8 q1, q5
- aesimc.8 q1, q1
- aesd.8 q0, q6
- aesimc.8 q0, q0
- aesd.8 q1, q6
- aesimc.8 q1, q1
- aesd.8 q0, q7
- aesimc.8 q0, q0
- aesd.8 q1, q7
- aesimc.8 q1, q1
- aesd.8 q0, q8
- aesimc.8 q0, q0
- aesd.8 q1, q8
- aesimc.8 q1, q1
- aesd.8 q0, q9
- aesimc.8 q0, q0
- aesd.8 q1, q9
- aesimc.8 q1, q1
- aesd.8 q0, q10
- aesimc.8 q0, q0
- aesd.8 q1, q10
- aesimc.8 q1, q1
- aesd.8 q0, q11
- aesimc.8 q0, q0
- aesd.8 q1, q11
- aesimc.8 q1, q1
- aesd.8 q0, q12
- aesimc.8 q0, q0
- aesd.8 q1, q12
- aesimc.8 q1, q1
- aesd.8 q0, q13
- aesimc.8 q0, q0
- aesd.8 q1, q13
- aesimc.8 q1, q1
- aesd.8 q0, q14
- aesimc.8 q0, q0
- aesd.8 q1, q14
- aesimc.8 q1, q1
- vld1.8 {d30-d31}, [r2]!
- aesd.8 q0, q15
- aesimc.8 q0, q0
- aesd.8 q1, q15
- aesimc.8 q1, q1
- vld1.8 {d30-d31}, [r2]!
- aesd.8 q0, q15
- aesimc.8 q0, q0
- aesd.8 q1, q15
- aesimc.8 q1, q1
- vld1.8 {d30-d31}, [r2]!
- aesd.8 q0, q15
- aesimc.8 q0, q0
- aesd.8 q1, q15
- aesimc.8 q1, q1
- vld1.8 {d30-d31}, [r2]!
- aesd.8 q0, q15
- aesd.8 q1, q15
- vld1.8 {d30-d31}, [r2]!
- veor.8 q0, q0, q15
- veor.8 q1, q1, q15
- mov r2, r3
- veor.8 q0, q0, q2
- veor.8 q1, q1, q3
- vmov q2, q4
- vst1.8 {d0-d1}, [r0]!
- vst1.8 {d2-d3}, [r0]!
- vst1.8 {d4-d5}, [r5]
- subs r4, r4, #2
- bpl .Lcbcdec256_2XLoop
- .Lcbcdec256_1X:
- adds r4, r4, #2
- bne .Lcbcdec256_FinalRound
- vpop {q4, q5, q6, q7}
- pop {r4, r5, r6}
- bx lr
- .Lcbcdec256_FinalRound:
- // load input 16 bytes
- vld1.8 {d0-d1}, [r1]!
- vmov q3, q0
- vst1.8 {d0-d1}, [r5]
- // aes kernel
- aesd.8 q0, q5
- aesimc.8 q0, q0
- vld1.8 {d30}, [r2]!
- aesd.8 q0, q6
- aesimc.8 q0, q0
- vld1.8 {d31}, [r2]!
- aesd.8 q0, q7
- aesimc.8 q0, q0
- aesd.8 q0, q8
- aesimc.8 q0, q0
- aesd.8 q0, q9
- aesimc.8 q0, q0
- aesd.8 q0, q10
- aesimc.8 q0, q0
- aesd.8 q0, q11
- aesimc.8 q0, q0
- aesd.8 q0, q12
- aesimc.8 q0, q0
- aesd.8 q0, q13
- aesimc.8 q0, q0
- aesd.8 q0, q14
- aesimc.8 q0, q0
- aesd.8 q0, q15
- aesimc.8 q0, q0
- vld1.8 {d30-d31}, [r2]!
- aesd.8 q0, q15
- aesimc.8 q0, q0
- vld1.8 {d30-d31}, [r2]!
- aesd.8 q0, q15
- aesimc.8 q0, q0
- vld1.8 {d30-d31}, [r2]!
- aesd.8 q0, q15
- vld1.8 {d30-d31}, [r2]!
- veor.8 q0, q0, q15
- veor.8 q0, q0, q2
- vmov q2, q3
- vst1.8 {d0-d1}, [r0]!
- vpop {q4, q5, q6, q7}
- pop {r4, r5, r6}
- bx lr
- ENDPROC(aes_v8_cbc_decrypt)
- #endif
|