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, __aes_arm_inverse_sbox, 0
223 ENDPROC(__aes_arm_decrypt)
225 .section ".rodata", "a"
226 .align L1_CACHE_SHIFT
227 .type __aes_arm_inverse_sbox, %object
228 __aes_arm_inverse_sbox:
229 .byte 0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38
230 .byte 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb
231 .byte 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87
232 .byte 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb
233 .byte 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d
234 .byte 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e
235 .byte 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2
236 .byte 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25
237 .byte 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16
238 .byte 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92
239 .byte 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda
240 .byte 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84
241 .byte 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a
242 .byte 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06
243 .byte 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02
244 .byte 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b
245 .byte 0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea
246 .byte 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73
247 .byte 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85
248 .byte 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e
249 .byte 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89
250 .byte 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b
251 .byte 0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20
252 .byte 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4
253 .byte 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31
254 .byte 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f
255 .byte 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d
256 .byte 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef
257 .byte 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0
258 .byte 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61
259 .byte 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26
260 .byte 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d
261 .size __aes_arm_inverse_sbox, . - __aes_arm_inverse_sbox