blob: 4460ed05d6ff3c8bf12e2cd17de25b54252a8e03 [file] [log] [blame]
Thomas Gleixnerd2912cb2019-06-04 10:11:33 +02001/* SPDX-License-Identifier: GPL-2.0-only */
Ard Biesheuvel81edb422017-01-11 16:41:53 +00002/*
3 * Scalar AES core transform
4 *
5 * Copyright (C) 2017 Linaro Ltd.
6 * Author: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Ard Biesheuvel81edb422017-01-11 16:41:53 +00007 */
8
9#include <linux/linkage.h>
Eric Biggers913a3aa2018-10-17 21:37:59 -070010#include <asm/assembler.h>
Ard Biesheuvel0d149ce2017-07-24 11:28:19 +010011#include <asm/cache.h>
Ard Biesheuvel81edb422017-01-11 16:41:53 +000012
13 .text
14 .align 5
15
16 rk .req r0
17 rounds .req r1
18 in .req r2
19 out .req r3
Ard Biesheuvel658fa752017-01-13 08:33:26 +000020 ttab .req ip
Ard Biesheuvel81edb422017-01-11 16:41:53 +000021
22 t0 .req lr
23 t1 .req r2
24 t2 .req r3
25
26 .macro __select, out, in, idx
27 .if __LINUX_ARM_ARCH__ < 7
28 and \out, \in, #0xff << (8 * \idx)
29 .else
30 ubfx \out, \in, #(8 * \idx), #8
31 .endif
32 .endm
33
Ard Biesheuvel0d149ce2017-07-24 11:28:19 +010034 .macro __load, out, in, idx, sz, op
Ard Biesheuvel81edb422017-01-11 16:41:53 +000035 .if __LINUX_ARM_ARCH__ < 7 && \idx > 0
Ard Biesheuvel0d149ce2017-07-24 11:28:19 +010036 ldr\op \out, [ttab, \in, lsr #(8 * \idx) - \sz]
Ard Biesheuvel81edb422017-01-11 16:41:53 +000037 .else
Ard Biesheuvel0d149ce2017-07-24 11:28:19 +010038 ldr\op \out, [ttab, \in, lsl #\sz]
Ard Biesheuvel81edb422017-01-11 16:41:53 +000039 .endif
40 .endm
41
Eric Biggers913a3aa2018-10-17 21:37:59 -070042 .macro __hround, out0, out1, in0, in1, in2, in3, t3, t4, enc, sz, op, oldcpsr
Ard Biesheuvel81edb422017-01-11 16:41:53 +000043 __select \out0, \in0, 0
44 __select t0, \in1, 1
Ard Biesheuvel0d149ce2017-07-24 11:28:19 +010045 __load \out0, \out0, 0, \sz, \op
46 __load t0, t0, 1, \sz, \op
Ard Biesheuvel81edb422017-01-11 16:41:53 +000047
48 .if \enc
49 __select \out1, \in1, 0
50 __select t1, \in2, 1
51 .else
52 __select \out1, \in3, 0
53 __select t1, \in0, 1
54 .endif
Ard Biesheuvel0d149ce2017-07-24 11:28:19 +010055 __load \out1, \out1, 0, \sz, \op
Ard Biesheuvel81edb422017-01-11 16:41:53 +000056 __select t2, \in2, 2
Ard Biesheuvel0d149ce2017-07-24 11:28:19 +010057 __load t1, t1, 1, \sz, \op
58 __load t2, t2, 2, \sz, \op
Ard Biesheuvel81edb422017-01-11 16:41:53 +000059
60 eor \out0, \out0, t0, ror #24
61
62 __select t0, \in3, 3
63 .if \enc
64 __select \t3, \in3, 2
65 __select \t4, \in0, 3
66 .else
67 __select \t3, \in1, 2
68 __select \t4, \in2, 3
69 .endif
Ard Biesheuvel0d149ce2017-07-24 11:28:19 +010070 __load \t3, \t3, 2, \sz, \op
71 __load t0, t0, 3, \sz, \op
72 __load \t4, \t4, 3, \sz, \op
Ard Biesheuvel81edb422017-01-11 16:41:53 +000073
Eric Biggers913a3aa2018-10-17 21:37:59 -070074 .ifnb \oldcpsr
75 /*
76 * This is the final round and we're done with all data-dependent table
77 * lookups, so we can safely re-enable interrupts.
78 */
79 restore_irqs \oldcpsr
80 .endif
81
Ard Biesheuvel81edb422017-01-11 16:41:53 +000082 eor \out1, \out1, t1, ror #24
83 eor \out0, \out0, t2, ror #16
84 ldm rk!, {t1, t2}
85 eor \out1, \out1, \t3, ror #16
86 eor \out0, \out0, t0, ror #8
87 eor \out1, \out1, \t4, ror #8
88 eor \out0, \out0, t1
89 eor \out1, \out1, t2
90 .endm
91
Eric Biggers913a3aa2018-10-17 21:37:59 -070092 .macro fround, out0, out1, out2, out3, in0, in1, in2, in3, sz=2, op, oldcpsr
Ard Biesheuvel0d149ce2017-07-24 11:28:19 +010093 __hround \out0, \out1, \in0, \in1, \in2, \in3, \out2, \out3, 1, \sz, \op
Eric Biggers913a3aa2018-10-17 21:37:59 -070094 __hround \out2, \out3, \in2, \in3, \in0, \in1, \in1, \in2, 1, \sz, \op, \oldcpsr
Ard Biesheuvel81edb422017-01-11 16:41:53 +000095 .endm
96
Eric Biggers913a3aa2018-10-17 21:37:59 -070097 .macro iround, out0, out1, out2, out3, in0, in1, in2, in3, sz=2, op, oldcpsr
Ard Biesheuvel0d149ce2017-07-24 11:28:19 +010098 __hround \out0, \out1, \in0, \in3, \in2, \in1, \out2, \out3, 0, \sz, \op
Eric Biggers913a3aa2018-10-17 21:37:59 -070099 __hround \out2, \out3, \in2, \in1, \in0, \in3, \in1, \in0, 0, \sz, \op, \oldcpsr
Ard Biesheuvel81edb422017-01-11 16:41:53 +0000100 .endm
101
102 .macro __rev, out, in
103 .if __LINUX_ARM_ARCH__ < 6
104 lsl t0, \in, #24
105 and t1, \in, #0xff00
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
110 .else
111 rev \out, \in
112 .endif
113 .endm
114
115 .macro __adrl, out, sym, c
116 .if __LINUX_ARM_ARCH__ < 7
117 ldr\c \out, =\sym
118 .else
119 movw\c \out, #:lower16:\sym
120 movt\c \out, #:upper16:\sym
121 .endif
122 .endm
123
Ard Biesheuvel0d149ce2017-07-24 11:28:19 +0100124 .macro do_crypt, round, ttab, ltab, bsz
Ard Biesheuvel81edb422017-01-11 16:41:53 +0000125 push {r3-r11, lr}
126
Eric Biggers913a3aa2018-10-17 21:37:59 -0700127 // Load keys first, to reduce latency in case they're not cached yet.
128 ldm rk!, {r8-r11}
129
Ard Biesheuvel81edb422017-01-11 16:41:53 +0000130 ldr r4, [in]
131 ldr r5, [in, #4]
132 ldr r6, [in, #8]
133 ldr r7, [in, #12]
134
Ard Biesheuvel81edb422017-01-11 16:41:53 +0000135#ifdef CONFIG_CPU_BIG_ENDIAN
136 __rev r4, r4
137 __rev r5, r5
138 __rev r6, r6
139 __rev r7, r7
140#endif
141
142 eor r4, r4, r8
143 eor r5, r5, r9
144 eor r6, r6, r10
145 eor r7, r7, r11
146
Ard Biesheuvel658fa752017-01-13 08:33:26 +0000147 __adrl ttab, \ttab
Eric Biggers913a3aa2018-10-17 21:37:59 -0700148 /*
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.
156 */
157 save_and_disable_irqs t0
158 .set i, 0
159 .rept 1024 / 128
160 ldr r8, [ttab, #i + 0]
161 ldr r9, [ttab, #i + 32]
162 ldr r10, [ttab, #i + 64]
163 ldr r11, [ttab, #i + 96]
164 .set i, i + 128
165 .endr
166 push {t0} // oldcpsr
Ard Biesheuvel81edb422017-01-11 16:41:53 +0000167
168 tst rounds, #2
169 bne 1f
170
1710: \round r8, r9, r10, r11, r4, r5, r6, r7
172 \round r4, r5, r6, r7, r8, r9, r10, r11
173
1741: subs rounds, rounds, #4
175 \round r8, r9, r10, r11, r4, r5, r6, r7
Ard Biesheuvel0d149ce2017-07-24 11:28:19 +0100176 bls 2f
Ard Biesheuvel81edb422017-01-11 16:41:53 +0000177 \round r4, r5, r6, r7, r8, r9, r10, r11
Ard Biesheuvel0d149ce2017-07-24 11:28:19 +0100178 b 0b
179
Eric Biggers913a3aa2018-10-17 21:37:59 -07001802: .ifb \ltab
181 add ttab, ttab, #1
182 .else
183 __adrl ttab, \ltab
184 // Prefetch inverse S-box for final round; see explanation above
185 .set i, 0
186 .rept 256 / 64
187 ldr t0, [ttab, #i + 0]
188 ldr t1, [ttab, #i + 32]
189 .set i, i + 64
190 .endr
191 .endif
192
193 pop {rounds} // oldcpsr
194 \round r4, r5, r6, r7, r8, r9, r10, r11, \bsz, b, rounds
Ard Biesheuvel81edb422017-01-11 16:41:53 +0000195
196#ifdef CONFIG_CPU_BIG_ENDIAN
197 __rev r4, r4
198 __rev r5, r5
199 __rev r6, r6
200 __rev r7, r7
201#endif
202
203 ldr out, [sp]
204
205 str r4, [out]
206 str r5, [out, #4]
207 str r6, [out, #8]
208 str r7, [out, #12]
209
210 pop {r3-r11, pc}
211
212 .align 3
213 .ltorg
214 .endm
215
Jinbum Park4ff8b1d2018-02-12 22:52:37 +0900216ENTRY(__aes_arm_encrypt)
Eric Biggers913a3aa2018-10-17 21:37:59 -0700217 do_crypt fround, crypto_ft_tab,, 2
Jinbum Park4ff8b1d2018-02-12 22:52:37 +0900218ENDPROC(__aes_arm_encrypt)
219
220 .align 5
221ENTRY(__aes_arm_decrypt)
222 do_crypt iround, crypto_it_tab, __aes_arm_inverse_sbox, 0
223ENDPROC(__aes_arm_decrypt)
224
225 .section ".rodata", "a"
Ard Biesheuvel0d149ce2017-07-24 11:28:19 +0100226 .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