1 /* SPDX-License-Identifier: GPL-2.0-only */
3 * Scalar AES core transform
5 * Copyright (C) 2017 Linaro Ltd.
6 * Author: Ard Biesheuvel <ard.biesheuvel@linaro.org>
9 #include <linux/linkage.h>
10 #include <asm/assembler.h>
11 #include <asm/cache.h>
26 .macro __select, out, in, idx
27 .if __LINUX_ARM_ARCH__ < 7
28 and \out, \in, #0xff << (8 * \idx)
30 ubfx \out, \in, #(8 * \idx), #8
34 .macro __load, out, in, idx, sz, op
35 .if __LINUX_ARM_ARCH__ < 7 && \idx > 0
36 ldr\op \out, [ttab, \in, lsr #(8 * \idx) - \sz]
38 ldr\op \out, [ttab, \in, lsl #\sz]
42 .macro __hround, out0, out1, in0, in1, in2, in3, t3, t4, enc, sz, op, oldcpsr
43 __select \out0, \in0, 0
45 __load \out0, \out0, 0, \sz, \op
46 __load t0, t0, 1, \sz, \op
49 __select \out1, \in1, 0
52 __select \out1, \in3, 0
55 __load \out1, \out1, 0, \sz, \op
57 __load t1, t1, 1, \sz, \op
58 __load t2, t2, 2, \sz, \op
60 eor \out0, \out0, t0, ror #24
70 __load \t3, \t3, 2, \sz, \op
71 __load t0, t0, 3, \sz, \op
72 __load \t4, \t4, 3, \sz, \op
76 * This is the final round and we're done with all data-dependent table
77 * lookups, so we can safely re-enable interrupts.
82 eor \out1, \out1, t1, ror #24
83 eor \out0, \out0, t2, ror #16
85 eor \out1, \out1, \t3, ror #16
86 eor \out0, \out0, t0, ror #8
87 eor \out1, \out1, \t4, ror #8
92 .macro fround, out0, out1, out2, out3, in0, in1, in2, in3, sz=2, op, oldcpsr
93 __hround \out0, \out1, \in0, \in1, \in2, \in3, \out2, \out3, 1, \sz, \op
94 __hround \out2, \out3, \in2, \in3, \in0, \in1, \in1, \in2, 1, \sz, \op, \oldcpsr
97 .macro iround, out0, out1, out2, out3, in0, in1, in2, in3, sz=2, op, oldcpsr
98 __hround \out0, \out1, \in0, \in3, \in2, \in1, \out2, \out3, 0, \sz, \op
99 __hround \out2, \out3, \in2, \in1, \in0, \in3, \in1, \in0, 0, \sz, \op, \oldcpsr
102 .macro __rev, out, in
103 .if __LINUX_ARM_ARCH__ < 6
106 and t2, \in, #0xff0000
107 orr \out, t0, \in, lsr #24
108 orr \out, \out, t1, lsl #8
109 orr \out, \out, t2, lsr #8
115 .macro __adrl, out, sym, c
116 .if __LINUX_ARM_ARCH__ < 7
119 movw\c \out, #:lower16:\sym
120 movt\c \out, #:upper16:\sym
124 .macro do_crypt, round, ttab, ltab, bsz
127 // Load keys first, to reduce latency in case they're not cached yet.
135 #ifdef CONFIG_CPU_BIG_ENDIAN
149 * Disable interrupts and prefetch the 1024-byte 'ft' or 'it' table into
150 * L1 cache, assuming cacheline size >= 32. This is a hardening measure
151 * intended to make cache-timing attacks more difficult. They may not
152 * be fully prevented, however; see the paper
153 * https://cr.yp.to/antiforgery/cachetiming-20050414.pdf
154 * ("Cache-timing attacks on AES") for a discussion of the many
155 * difficulties involved in writing truly constant-time AES software.
157 save_and_disable_irqs t0
160 ldr r8, [ttab, #i + 0]
161 ldr r9, [ttab, #i + 32]
162 ldr r10, [ttab, #i + 64]
163 ldr r11, [ttab, #i + 96]
171 0: \round r8, r9, r10, r11, r4, r5, r6, r7
172 \round r4, r5, r6, r7, r8, r9, r10, r11
174 1: subs rounds, rounds, #4
175 \round r8, r9, r10, r11, r4, r5, r6, r7
177 \round r4, r5, r6, r7, r8, r9, r10, r11
184 // Prefetch inverse S-box for final round; see explanation above
187 ldr t0, [ttab, #i + 0]
188 ldr t1, [ttab, #i + 32]
193 pop {rounds} // oldcpsr
194 \round r4, r5, r6, r7, r8, r9, r10, r11, \bsz, b, rounds
196 #ifdef CONFIG_CPU_BIG_ENDIAN
216 ENTRY(__aes_arm_encrypt)
217 do_crypt fround, crypto_ft_tab,, 2
218 ENDPROC(__aes_arm_encrypt)
221 ENTRY(__aes_arm_decrypt)
222 do_crypt iround, crypto_it_tab, crypto_aes_inv_sbox, 0
223 ENDPROC(__aes_arm_decrypt)