~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/arch/arm64/crypto/aes-modes.S

Version: ~ [ linux-6.12-rc7 ] ~ [ linux-6.11.7 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.60 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.116 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.171 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.229 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.285 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.323 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.12 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /* SPDX-License-Identifier: GPL-2.0-only */
  2 /*
  3  * linux/arch/arm64/crypto/aes-modes.S - chaining mode wrappers for AES
  4  *
  5  * Copyright (C) 2013 - 2017 Linaro Ltd <ard.biesheuvel@linaro.org>
  6  */
  7 
  8 /* included by aes-ce.S and aes-neon.S */
  9 
 10         .text
 11         .align          4
 12 
 13 #ifndef MAX_STRIDE
 14 #define MAX_STRIDE      4
 15 #endif
 16 
 17 #if MAX_STRIDE == 4
 18 #define ST4(x...) x
 19 #define ST5(x...)
 20 #else
 21 #define ST4(x...)
 22 #define ST5(x...) x
 23 #endif
 24 
 25 SYM_FUNC_START_LOCAL(aes_encrypt_block4x)
 26         encrypt_block4x v0, v1, v2, v3, w3, x2, x8, w7
 27         ret
 28 SYM_FUNC_END(aes_encrypt_block4x)
 29 
 30 SYM_FUNC_START_LOCAL(aes_decrypt_block4x)
 31         decrypt_block4x v0, v1, v2, v3, w3, x2, x8, w7
 32         ret
 33 SYM_FUNC_END(aes_decrypt_block4x)
 34 
 35 #if MAX_STRIDE == 5
 36 SYM_FUNC_START_LOCAL(aes_encrypt_block5x)
 37         encrypt_block5x v0, v1, v2, v3, v4, w3, x2, x8, w7
 38         ret
 39 SYM_FUNC_END(aes_encrypt_block5x)
 40 
 41 SYM_FUNC_START_LOCAL(aes_decrypt_block5x)
 42         decrypt_block5x v0, v1, v2, v3, v4, w3, x2, x8, w7
 43         ret
 44 SYM_FUNC_END(aes_decrypt_block5x)
 45 #endif
 46 
 47         /*
 48          * aes_ecb_encrypt(u8 out[], u8 const in[], u8 const rk[], int rounds,
 49          *                 int blocks)
 50          * aes_ecb_decrypt(u8 out[], u8 const in[], u8 const rk[], int rounds,
 51          *                 int blocks)
 52          */
 53 
 54 AES_FUNC_START(aes_ecb_encrypt)
 55         frame_push      0
 56 
 57         enc_prepare     w3, x2, x5
 58 
 59 .LecbencloopNx:
 60         subs            w4, w4, #MAX_STRIDE
 61         bmi             .Lecbenc1x
 62         ld1             {v0.16b-v3.16b}, [x1], #64      /* get 4 pt blocks */
 63 ST4(    bl              aes_encrypt_block4x             )
 64 ST5(    ld1             {v4.16b}, [x1], #16             )
 65 ST5(    bl              aes_encrypt_block5x             )
 66         st1             {v0.16b-v3.16b}, [x0], #64
 67 ST5(    st1             {v4.16b}, [x0], #16             )
 68         b               .LecbencloopNx
 69 .Lecbenc1x:
 70         adds            w4, w4, #MAX_STRIDE
 71         beq             .Lecbencout
 72 .Lecbencloop:
 73         ld1             {v0.16b}, [x1], #16             /* get next pt block */
 74         encrypt_block   v0, w3, x2, x5, w6
 75         st1             {v0.16b}, [x0], #16
 76         subs            w4, w4, #1
 77         bne             .Lecbencloop
 78 .Lecbencout:
 79         frame_pop
 80         ret
 81 AES_FUNC_END(aes_ecb_encrypt)
 82 
 83 
 84 AES_FUNC_START(aes_ecb_decrypt)
 85         frame_push      0
 86 
 87         dec_prepare     w3, x2, x5
 88 
 89 .LecbdecloopNx:
 90         subs            w4, w4, #MAX_STRIDE
 91         bmi             .Lecbdec1x
 92         ld1             {v0.16b-v3.16b}, [x1], #64      /* get 4 ct blocks */
 93 ST4(    bl              aes_decrypt_block4x             )
 94 ST5(    ld1             {v4.16b}, [x1], #16             )
 95 ST5(    bl              aes_decrypt_block5x             )
 96         st1             {v0.16b-v3.16b}, [x0], #64
 97 ST5(    st1             {v4.16b}, [x0], #16             )
 98         b               .LecbdecloopNx
 99 .Lecbdec1x:
100         adds            w4, w4, #MAX_STRIDE
101         beq             .Lecbdecout
102 .Lecbdecloop:
103         ld1             {v0.16b}, [x1], #16             /* get next ct block */
104         decrypt_block   v0, w3, x2, x5, w6
105         st1             {v0.16b}, [x0], #16
106         subs            w4, w4, #1
107         bne             .Lecbdecloop
108 .Lecbdecout:
109         frame_pop
110         ret
111 AES_FUNC_END(aes_ecb_decrypt)
112 
113 
114         /*
115          * aes_cbc_encrypt(u8 out[], u8 const in[], u8 const rk[], int rounds,
116          *                 int blocks, u8 iv[])
117          * aes_cbc_decrypt(u8 out[], u8 const in[], u8 const rk[], int rounds,
118          *                 int blocks, u8 iv[])
119          * aes_essiv_cbc_encrypt(u8 out[], u8 const in[], u32 const rk1[],
120          *                       int rounds, int blocks, u8 iv[],
121          *                       u32 const rk2[]);
122          * aes_essiv_cbc_decrypt(u8 out[], u8 const in[], u32 const rk1[],
123          *                       int rounds, int blocks, u8 iv[],
124          *                       u32 const rk2[]);
125          */
126 
127 AES_FUNC_START(aes_essiv_cbc_encrypt)
128         ld1             {v4.16b}, [x5]                  /* get iv */
129 
130         mov             w8, #14                         /* AES-256: 14 rounds */
131         enc_prepare     w8, x6, x7
132         encrypt_block   v4, w8, x6, x7, w9
133         enc_switch_key  w3, x2, x6
134         b               .Lcbcencloop4x
135 
136 AES_FUNC_START(aes_cbc_encrypt)
137         ld1             {v4.16b}, [x5]                  /* get iv */
138         enc_prepare     w3, x2, x6
139 
140 .Lcbcencloop4x:
141         subs            w4, w4, #4
142         bmi             .Lcbcenc1x
143         ld1             {v0.16b-v3.16b}, [x1], #64      /* get 4 pt blocks */
144         eor             v0.16b, v0.16b, v4.16b          /* ..and xor with iv */
145         encrypt_block   v0, w3, x2, x6, w7
146         eor             v1.16b, v1.16b, v0.16b
147         encrypt_block   v1, w3, x2, x6, w7
148         eor             v2.16b, v2.16b, v1.16b
149         encrypt_block   v2, w3, x2, x6, w7
150         eor             v3.16b, v3.16b, v2.16b
151         encrypt_block   v3, w3, x2, x6, w7
152         st1             {v0.16b-v3.16b}, [x0], #64
153         mov             v4.16b, v3.16b
154         b               .Lcbcencloop4x
155 .Lcbcenc1x:
156         adds            w4, w4, #4
157         beq             .Lcbcencout
158 .Lcbcencloop:
159         ld1             {v0.16b}, [x1], #16             /* get next pt block */
160         eor             v4.16b, v4.16b, v0.16b          /* ..and xor with iv */
161         encrypt_block   v4, w3, x2, x6, w7
162         st1             {v4.16b}, [x0], #16
163         subs            w4, w4, #1
164         bne             .Lcbcencloop
165 .Lcbcencout:
166         st1             {v4.16b}, [x5]                  /* return iv */
167         ret
168 AES_FUNC_END(aes_cbc_encrypt)
169 AES_FUNC_END(aes_essiv_cbc_encrypt)
170 
171 AES_FUNC_START(aes_essiv_cbc_decrypt)
172         ld1             {cbciv.16b}, [x5]               /* get iv */
173 
174         mov             w8, #14                         /* AES-256: 14 rounds */
175         enc_prepare     w8, x6, x7
176         encrypt_block   cbciv, w8, x6, x7, w9
177         b               .Lessivcbcdecstart
178 
179 AES_FUNC_START(aes_cbc_decrypt)
180         ld1             {cbciv.16b}, [x5]               /* get iv */
181 .Lessivcbcdecstart:
182         frame_push      0
183         dec_prepare     w3, x2, x6
184 
185 .LcbcdecloopNx:
186         subs            w4, w4, #MAX_STRIDE
187         bmi             .Lcbcdec1x
188         ld1             {v0.16b-v3.16b}, [x1], #64      /* get 4 ct blocks */
189 #if MAX_STRIDE == 5
190         ld1             {v4.16b}, [x1], #16             /* get 1 ct block */
191         mov             v5.16b, v0.16b
192         mov             v6.16b, v1.16b
193         mov             v7.16b, v2.16b
194         bl              aes_decrypt_block5x
195         sub             x1, x1, #32
196         eor             v0.16b, v0.16b, cbciv.16b
197         eor             v1.16b, v1.16b, v5.16b
198         ld1             {v5.16b}, [x1], #16             /* reload 1 ct block */
199         ld1             {cbciv.16b}, [x1], #16          /* reload 1 ct block */
200         eor             v2.16b, v2.16b, v6.16b
201         eor             v3.16b, v3.16b, v7.16b
202         eor             v4.16b, v4.16b, v5.16b
203 #else
204         mov             v4.16b, v0.16b
205         mov             v5.16b, v1.16b
206         mov             v6.16b, v2.16b
207         bl              aes_decrypt_block4x
208         sub             x1, x1, #16
209         eor             v0.16b, v0.16b, cbciv.16b
210         eor             v1.16b, v1.16b, v4.16b
211         ld1             {cbciv.16b}, [x1], #16          /* reload 1 ct block */
212         eor             v2.16b, v2.16b, v5.16b
213         eor             v3.16b, v3.16b, v6.16b
214 #endif
215         st1             {v0.16b-v3.16b}, [x0], #64
216 ST5(    st1             {v4.16b}, [x0], #16             )
217         b               .LcbcdecloopNx
218 .Lcbcdec1x:
219         adds            w4, w4, #MAX_STRIDE
220         beq             .Lcbcdecout
221 .Lcbcdecloop:
222         ld1             {v1.16b}, [x1], #16             /* get next ct block */
223         mov             v0.16b, v1.16b                  /* ...and copy to v0 */
224         decrypt_block   v0, w3, x2, x6, w7
225         eor             v0.16b, v0.16b, cbciv.16b       /* xor with iv => pt */
226         mov             cbciv.16b, v1.16b               /* ct is next iv */
227         st1             {v0.16b}, [x0], #16
228         subs            w4, w4, #1
229         bne             .Lcbcdecloop
230 .Lcbcdecout:
231         st1             {cbciv.16b}, [x5]               /* return iv */
232         frame_pop
233         ret
234 AES_FUNC_END(aes_cbc_decrypt)
235 AES_FUNC_END(aes_essiv_cbc_decrypt)
236 
237 
238         /*
239          * aes_cbc_cts_encrypt(u8 out[], u8 const in[], u32 const rk[],
240          *                     int rounds, int bytes, u8 const iv[])
241          * aes_cbc_cts_decrypt(u8 out[], u8 const in[], u32 const rk[],
242          *                     int rounds, int bytes, u8 const iv[])
243          */
244 
245 AES_FUNC_START(aes_cbc_cts_encrypt)
246         adr_l           x8, .Lcts_permute_table
247         sub             x4, x4, #16
248         add             x9, x8, #32
249         add             x8, x8, x4
250         sub             x9, x9, x4
251         ld1             {v3.16b}, [x8]
252         ld1             {v4.16b}, [x9]
253 
254         ld1             {v0.16b}, [x1], x4              /* overlapping loads */
255         ld1             {v1.16b}, [x1]
256 
257         ld1             {v5.16b}, [x5]                  /* get iv */
258         enc_prepare     w3, x2, x6
259 
260         eor             v0.16b, v0.16b, v5.16b          /* xor with iv */
261         tbl             v1.16b, {v1.16b}, v4.16b
262         encrypt_block   v0, w3, x2, x6, w7
263 
264         eor             v1.16b, v1.16b, v0.16b
265         tbl             v0.16b, {v0.16b}, v3.16b
266         encrypt_block   v1, w3, x2, x6, w7
267 
268         add             x4, x0, x4
269         st1             {v0.16b}, [x4]                  /* overlapping stores */
270         st1             {v1.16b}, [x0]
271         ret
272 AES_FUNC_END(aes_cbc_cts_encrypt)
273 
274 AES_FUNC_START(aes_cbc_cts_decrypt)
275         adr_l           x8, .Lcts_permute_table
276         sub             x4, x4, #16
277         add             x9, x8, #32
278         add             x8, x8, x4
279         sub             x9, x9, x4
280         ld1             {v3.16b}, [x8]
281         ld1             {v4.16b}, [x9]
282 
283         ld1             {v0.16b}, [x1], x4              /* overlapping loads */
284         ld1             {v1.16b}, [x1]
285 
286         ld1             {v5.16b}, [x5]                  /* get iv */
287         dec_prepare     w3, x2, x6
288 
289         decrypt_block   v0, w3, x2, x6, w7
290         tbl             v2.16b, {v0.16b}, v3.16b
291         eor             v2.16b, v2.16b, v1.16b
292 
293         tbx             v0.16b, {v1.16b}, v4.16b
294         decrypt_block   v0, w3, x2, x6, w7
295         eor             v0.16b, v0.16b, v5.16b          /* xor with iv */
296 
297         add             x4, x0, x4
298         st1             {v2.16b}, [x4]                  /* overlapping stores */
299         st1             {v0.16b}, [x0]
300         ret
301 AES_FUNC_END(aes_cbc_cts_decrypt)
302 
303         .section        ".rodata", "a"
304         .align          6
305 .Lcts_permute_table:
306         .byte           0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
307         .byte           0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
308         .byte            0x0,  0x1,  0x2,  0x3,  0x4,  0x5,  0x6,  0x7
309         .byte            0x8,  0x9,  0xa,  0xb,  0xc,  0xd,  0xe,  0xf
310         .byte           0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
311         .byte           0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
312         .previous
313 
314         /*
315          * This macro generates the code for CTR and XCTR mode.
316          */
317 .macro ctr_encrypt xctr
318         // Arguments
319         OUT             .req x0
320         IN              .req x1
321         KEY             .req x2
322         ROUNDS_W        .req w3
323         BYTES_W         .req w4
324         IV              .req x5
325         BYTE_CTR_W      .req w6         // XCTR only
326         // Intermediate values
327         CTR_W           .req w11        // XCTR only
328         CTR             .req x11        // XCTR only
329         IV_PART         .req x12
330         BLOCKS          .req x13
331         BLOCKS_W        .req w13
332 
333         frame_push      0
334 
335         enc_prepare     ROUNDS_W, KEY, IV_PART
336         ld1             {vctr.16b}, [IV]
337 
338         /*
339          * Keep 64 bits of the IV in a register.  For CTR mode this lets us
340          * easily increment the IV.  For XCTR mode this lets us efficiently XOR
341          * the 64-bit counter with the IV.
342          */
343         .if \xctr
344                 umov            IV_PART, vctr.d[0]
345                 lsr             CTR_W, BYTE_CTR_W, #4
346         .else
347                 umov            IV_PART, vctr.d[1]
348                 rev             IV_PART, IV_PART
349         .endif
350 
351 .LctrloopNx\xctr:
352         add             BLOCKS_W, BYTES_W, #15
353         sub             BYTES_W, BYTES_W, #MAX_STRIDE << 4
354         lsr             BLOCKS_W, BLOCKS_W, #4
355         mov             w8, #MAX_STRIDE
356         cmp             BLOCKS_W, w8
357         csel            BLOCKS_W, BLOCKS_W, w8, lt
358 
359         /*
360          * Set up the counter values in v0-v{MAX_STRIDE-1}.
361          *
362          * If we are encrypting less than MAX_STRIDE blocks, the tail block
363          * handling code expects the last keystream block to be in
364          * v{MAX_STRIDE-1}.  For example: if encrypting two blocks with
365          * MAX_STRIDE=5, then v3 and v4 should have the next two counter blocks.
366          */
367         .if \xctr
368                 add             CTR, CTR, BLOCKS
369         .else
370                 adds            IV_PART, IV_PART, BLOCKS
371         .endif
372         mov             v0.16b, vctr.16b
373         mov             v1.16b, vctr.16b
374         mov             v2.16b, vctr.16b
375         mov             v3.16b, vctr.16b
376 ST5(    mov             v4.16b, vctr.16b                )
377         .if \xctr
378                 sub             x6, CTR, #MAX_STRIDE - 1
379                 sub             x7, CTR, #MAX_STRIDE - 2
380                 sub             x8, CTR, #MAX_STRIDE - 3
381                 sub             x9, CTR, #MAX_STRIDE - 4
382 ST5(            sub             x10, CTR, #MAX_STRIDE - 5       )
383                 eor             x6, x6, IV_PART
384                 eor             x7, x7, IV_PART
385                 eor             x8, x8, IV_PART
386                 eor             x9, x9, IV_PART
387 ST5(            eor             x10, x10, IV_PART               )
388                 mov             v0.d[0], x6
389                 mov             v1.d[0], x7
390                 mov             v2.d[0], x8
391                 mov             v3.d[0], x9
392 ST5(            mov             v4.d[0], x10                    )
393         .else
394                 bcs             0f
395                 .subsection     1
396                 /*
397                  * This subsection handles carries.
398                  *
399                  * Conditional branching here is allowed with respect to time
400                  * invariance since the branches are dependent on the IV instead
401                  * of the plaintext or key.  This code is rarely executed in
402                  * practice anyway.
403                  */
404 
405                 /* Apply carry to outgoing counter. */
406 0:              umov            x8, vctr.d[0]
407                 rev             x8, x8
408                 add             x8, x8, #1
409                 rev             x8, x8
410                 ins             vctr.d[0], x8
411 
412                 /*
413                  * Apply carry to counter blocks if needed.
414                  *
415                  * Since the carry flag was set, we know 0 <= IV_PART <
416                  * MAX_STRIDE.  Using the value of IV_PART we can determine how
417                  * many counter blocks need to be updated.
418                  */
419                 cbz             IV_PART, 2f
420                 adr             x16, 1f
421                 sub             x16, x16, IV_PART, lsl #3
422                 br              x16
423                 bti             c
424                 mov             v0.d[0], vctr.d[0]
425                 bti             c
426                 mov             v1.d[0], vctr.d[0]
427                 bti             c
428                 mov             v2.d[0], vctr.d[0]
429                 bti             c
430                 mov             v3.d[0], vctr.d[0]
431 ST5(            bti             c                               )
432 ST5(            mov             v4.d[0], vctr.d[0]              )
433 1:              b               2f
434                 .previous
435 
436 2:              rev             x7, IV_PART
437                 ins             vctr.d[1], x7
438                 sub             x7, IV_PART, #MAX_STRIDE - 1
439                 sub             x8, IV_PART, #MAX_STRIDE - 2
440                 sub             x9, IV_PART, #MAX_STRIDE - 3
441                 rev             x7, x7
442                 rev             x8, x8
443                 mov             v1.d[1], x7
444                 rev             x9, x9
445 ST5(            sub             x10, IV_PART, #MAX_STRIDE - 4   )
446                 mov             v2.d[1], x8
447 ST5(            rev             x10, x10                        )
448                 mov             v3.d[1], x9
449 ST5(            mov             v4.d[1], x10                    )
450         .endif
451 
452         /*
453          * If there are at least MAX_STRIDE blocks left, XOR the data with
454          * keystream and store.  Otherwise jump to tail handling.
455          */
456         tbnz            BYTES_W, #31, .Lctrtail\xctr
457         ld1             {v5.16b-v7.16b}, [IN], #48
458 ST4(    bl              aes_encrypt_block4x             )
459 ST5(    bl              aes_encrypt_block5x             )
460         eor             v0.16b, v5.16b, v0.16b
461 ST4(    ld1             {v5.16b}, [IN], #16             )
462         eor             v1.16b, v6.16b, v1.16b
463 ST5(    ld1             {v5.16b-v6.16b}, [IN], #32      )
464         eor             v2.16b, v7.16b, v2.16b
465         eor             v3.16b, v5.16b, v3.16b
466 ST5(    eor             v4.16b, v6.16b, v4.16b          )
467         st1             {v0.16b-v3.16b}, [OUT], #64
468 ST5(    st1             {v4.16b}, [OUT], #16            )
469         cbz             BYTES_W, .Lctrout\xctr
470         b               .LctrloopNx\xctr
471 
472 .Lctrout\xctr:
473         .if !\xctr
474                 st1             {vctr.16b}, [IV] /* return next CTR value */
475         .endif
476         frame_pop
477         ret
478 
479 .Lctrtail\xctr:
480         /*
481          * Handle up to MAX_STRIDE * 16 - 1 bytes of plaintext
482          *
483          * This code expects the last keystream block to be in v{MAX_STRIDE-1}.
484          * For example: if encrypting two blocks with MAX_STRIDE=5, then v3 and
485          * v4 should have the next two counter blocks.
486          *
487          * This allows us to store the ciphertext by writing to overlapping
488          * regions of memory.  Any invalid ciphertext blocks get overwritten by
489          * correctly computed blocks.  This approach greatly simplifies the
490          * logic for storing the ciphertext.
491          */
492         mov             x16, #16
493         ands            w7, BYTES_W, #0xf
494         csel            x13, x7, x16, ne
495 
496 ST5(    cmp             BYTES_W, #64 - (MAX_STRIDE << 4))
497 ST5(    csel            x14, x16, xzr, gt               )
498         cmp             BYTES_W, #48 - (MAX_STRIDE << 4)
499         csel            x15, x16, xzr, gt
500         cmp             BYTES_W, #32 - (MAX_STRIDE << 4)
501         csel            x16, x16, xzr, gt
502         cmp             BYTES_W, #16 - (MAX_STRIDE << 4)
503 
504         adr_l           x9, .Lcts_permute_table
505         add             x9, x9, x13
506         ble             .Lctrtail1x\xctr
507 
508 ST5(    ld1             {v5.16b}, [IN], x14             )
509         ld1             {v6.16b}, [IN], x15
510         ld1             {v7.16b}, [IN], x16
511 
512 ST4(    bl              aes_encrypt_block4x             )
513 ST5(    bl              aes_encrypt_block5x             )
514 
515         ld1             {v8.16b}, [IN], x13
516         ld1             {v9.16b}, [IN]
517         ld1             {v10.16b}, [x9]
518 
519 ST4(    eor             v6.16b, v6.16b, v0.16b          )
520 ST4(    eor             v7.16b, v7.16b, v1.16b          )
521 ST4(    tbl             v3.16b, {v3.16b}, v10.16b       )
522 ST4(    eor             v8.16b, v8.16b, v2.16b          )
523 ST4(    eor             v9.16b, v9.16b, v3.16b          )
524 
525 ST5(    eor             v5.16b, v5.16b, v0.16b          )
526 ST5(    eor             v6.16b, v6.16b, v1.16b          )
527 ST5(    tbl             v4.16b, {v4.16b}, v10.16b       )
528 ST5(    eor             v7.16b, v7.16b, v2.16b          )
529 ST5(    eor             v8.16b, v8.16b, v3.16b          )
530 ST5(    eor             v9.16b, v9.16b, v4.16b          )
531 
532 ST5(    st1             {v5.16b}, [OUT], x14            )
533         st1             {v6.16b}, [OUT], x15
534         st1             {v7.16b}, [OUT], x16
535         add             x13, x13, OUT
536         st1             {v9.16b}, [x13]         // overlapping stores
537         st1             {v8.16b}, [OUT]
538         b               .Lctrout\xctr
539 
540 .Lctrtail1x\xctr:
541         /*
542          * Handle <= 16 bytes of plaintext
543          *
544          * This code always reads and writes 16 bytes.  To avoid out of bounds
545          * accesses, XCTR and CTR modes must use a temporary buffer when
546          * encrypting/decrypting less than 16 bytes.
547          *
548          * This code is unusual in that it loads the input and stores the output
549          * relative to the end of the buffers rather than relative to the start.
550          * This causes unusual behaviour when encrypting/decrypting less than 16
551          * bytes; the end of the data is expected to be at the end of the
552          * temporary buffer rather than the start of the data being at the start
553          * of the temporary buffer.
554          */
555         sub             x8, x7, #16
556         csel            x7, x7, x8, eq
557         add             IN, IN, x7
558         add             OUT, OUT, x7
559         ld1             {v5.16b}, [IN]
560         ld1             {v6.16b}, [OUT]
561 ST5(    mov             v3.16b, v4.16b                  )
562         encrypt_block   v3, ROUNDS_W, KEY, x8, w7
563         ld1             {v10.16b-v11.16b}, [x9]
564         tbl             v3.16b, {v3.16b}, v10.16b
565         sshr            v11.16b, v11.16b, #7
566         eor             v5.16b, v5.16b, v3.16b
567         bif             v5.16b, v6.16b, v11.16b
568         st1             {v5.16b}, [OUT]
569         b               .Lctrout\xctr
570 
571         // Arguments
572         .unreq OUT
573         .unreq IN
574         .unreq KEY
575         .unreq ROUNDS_W
576         .unreq BYTES_W
577         .unreq IV
578         .unreq BYTE_CTR_W       // XCTR only
579         // Intermediate values
580         .unreq CTR_W            // XCTR only
581         .unreq CTR              // XCTR only
582         .unreq IV_PART
583         .unreq BLOCKS
584         .unreq BLOCKS_W
585 .endm
586 
587         /*
588          * aes_ctr_encrypt(u8 out[], u8 const in[], u8 const rk[], int rounds,
589          *                 int bytes, u8 ctr[])
590          *
591          * The input and output buffers must always be at least 16 bytes even if
592          * encrypting/decrypting less than 16 bytes.  Otherwise out of bounds
593          * accesses will occur.  The data to be encrypted/decrypted is expected
594          * to be at the end of this 16-byte temporary buffer rather than the
595          * start.
596          */
597 
598 AES_FUNC_START(aes_ctr_encrypt)
599         ctr_encrypt 0
600 AES_FUNC_END(aes_ctr_encrypt)
601 
602         /*
603          * aes_xctr_encrypt(u8 out[], u8 const in[], u8 const rk[], int rounds,
604          *                 int bytes, u8 const iv[], int byte_ctr)
605          *
606          * The input and output buffers must always be at least 16 bytes even if
607          * encrypting/decrypting less than 16 bytes.  Otherwise out of bounds
608          * accesses will occur.  The data to be encrypted/decrypted is expected
609          * to be at the end of this 16-byte temporary buffer rather than the
610          * start.
611          */
612 
613 AES_FUNC_START(aes_xctr_encrypt)
614         ctr_encrypt 1
615 AES_FUNC_END(aes_xctr_encrypt)
616 
617 
618         /*
619          * aes_xts_encrypt(u8 out[], u8 const in[], u8 const rk1[], int rounds,
620          *                 int bytes, u8 const rk2[], u8 iv[], int first)
621          * aes_xts_decrypt(u8 out[], u8 const in[], u8 const rk1[], int rounds,
622          *                 int bytes, u8 const rk2[], u8 iv[], int first)
623          */
624 
625         .macro          next_tweak, out, in, tmp
626         sshr            \tmp\().2d,  \in\().2d,   #63
627         and             \tmp\().16b, \tmp\().16b, xtsmask.16b
628         add             \out\().2d,  \in\().2d,   \in\().2d
629         ext             \tmp\().16b, \tmp\().16b, \tmp\().16b, #8
630         eor             \out\().16b, \out\().16b, \tmp\().16b
631         .endm
632 
633         .macro          xts_load_mask, tmp
634         movi            xtsmask.2s, #0x1
635         movi            \tmp\().2s, #0x87
636         uzp1            xtsmask.4s, xtsmask.4s, \tmp\().4s
637         .endm
638 
639 AES_FUNC_START(aes_xts_encrypt)
640         frame_push      0
641 
642         ld1             {v4.16b}, [x6]
643         xts_load_mask   v8
644         cbz             w7, .Lxtsencnotfirst
645 
646         enc_prepare     w3, x5, x8
647         xts_cts_skip_tw w7, .LxtsencNx
648         encrypt_block   v4, w3, x5, x8, w7              /* first tweak */
649         enc_switch_key  w3, x2, x8
650         b               .LxtsencNx
651 
652 .Lxtsencnotfirst:
653         enc_prepare     w3, x2, x8
654 .LxtsencloopNx:
655         next_tweak      v4, v4, v8
656 .LxtsencNx:
657         subs            w4, w4, #64
658         bmi             .Lxtsenc1x
659         ld1             {v0.16b-v3.16b}, [x1], #64      /* get 4 pt blocks */
660         next_tweak      v5, v4, v8
661         eor             v0.16b, v0.16b, v4.16b
662         next_tweak      v6, v5, v8
663         eor             v1.16b, v1.16b, v5.16b
664         eor             v2.16b, v2.16b, v6.16b
665         next_tweak      v7, v6, v8
666         eor             v3.16b, v3.16b, v7.16b
667         bl              aes_encrypt_block4x
668         eor             v3.16b, v3.16b, v7.16b
669         eor             v0.16b, v0.16b, v4.16b
670         eor             v1.16b, v1.16b, v5.16b
671         eor             v2.16b, v2.16b, v6.16b
672         st1             {v0.16b-v3.16b}, [x0], #64
673         mov             v4.16b, v7.16b
674         cbz             w4, .Lxtsencret
675         xts_reload_mask v8
676         b               .LxtsencloopNx
677 .Lxtsenc1x:
678         adds            w4, w4, #64
679         beq             .Lxtsencout
680         subs            w4, w4, #16
681         bmi             .LxtsencctsNx
682 .Lxtsencloop:
683         ld1             {v0.16b}, [x1], #16
684 .Lxtsencctsout:
685         eor             v0.16b, v0.16b, v4.16b
686         encrypt_block   v0, w3, x2, x8, w7
687         eor             v0.16b, v0.16b, v4.16b
688         cbz             w4, .Lxtsencout
689         subs            w4, w4, #16
690         next_tweak      v4, v4, v8
691         bmi             .Lxtsenccts
692         st1             {v0.16b}, [x0], #16
693         b               .Lxtsencloop
694 .Lxtsencout:
695         st1             {v0.16b}, [x0]
696 .Lxtsencret:
697         st1             {v4.16b}, [x6]
698         frame_pop
699         ret
700 
701 .LxtsencctsNx:
702         mov             v0.16b, v3.16b
703         sub             x0, x0, #16
704 .Lxtsenccts:
705         adr_l           x8, .Lcts_permute_table
706 
707         add             x1, x1, w4, sxtw        /* rewind input pointer */
708         add             w4, w4, #16             /* # bytes in final block */
709         add             x9, x8, #32
710         add             x8, x8, x4
711         sub             x9, x9, x4
712         add             x4, x0, x4              /* output address of final block */
713 
714         ld1             {v1.16b}, [x1]          /* load final block */
715         ld1             {v2.16b}, [x8]
716         ld1             {v3.16b}, [x9]
717 
718         tbl             v2.16b, {v0.16b}, v2.16b
719         tbx             v0.16b, {v1.16b}, v3.16b
720         st1             {v2.16b}, [x4]                  /* overlapping stores */
721         mov             w4, wzr
722         b               .Lxtsencctsout
723 AES_FUNC_END(aes_xts_encrypt)
724 
725 AES_FUNC_START(aes_xts_decrypt)
726         frame_push      0
727 
728         /* subtract 16 bytes if we are doing CTS */
729         sub             w8, w4, #0x10
730         tst             w4, #0xf
731         csel            w4, w4, w8, eq
732 
733         ld1             {v4.16b}, [x6]
734         xts_load_mask   v8
735         xts_cts_skip_tw w7, .Lxtsdecskiptw
736         cbz             w7, .Lxtsdecnotfirst
737 
738         enc_prepare     w3, x5, x8
739         encrypt_block   v4, w3, x5, x8, w7              /* first tweak */
740 .Lxtsdecskiptw:
741         dec_prepare     w3, x2, x8
742         b               .LxtsdecNx
743 
744 .Lxtsdecnotfirst:
745         dec_prepare     w3, x2, x8
746 .LxtsdecloopNx:
747         next_tweak      v4, v4, v8
748 .LxtsdecNx:
749         subs            w4, w4, #64
750         bmi             .Lxtsdec1x
751         ld1             {v0.16b-v3.16b}, [x1], #64      /* get 4 ct blocks */
752         next_tweak      v5, v4, v8
753         eor             v0.16b, v0.16b, v4.16b
754         next_tweak      v6, v5, v8
755         eor             v1.16b, v1.16b, v5.16b
756         eor             v2.16b, v2.16b, v6.16b
757         next_tweak      v7, v6, v8
758         eor             v3.16b, v3.16b, v7.16b
759         bl              aes_decrypt_block4x
760         eor             v3.16b, v3.16b, v7.16b
761         eor             v0.16b, v0.16b, v4.16b
762         eor             v1.16b, v1.16b, v5.16b
763         eor             v2.16b, v2.16b, v6.16b
764         st1             {v0.16b-v3.16b}, [x0], #64
765         mov             v4.16b, v7.16b
766         cbz             w4, .Lxtsdecout
767         xts_reload_mask v8
768         b               .LxtsdecloopNx
769 .Lxtsdec1x:
770         adds            w4, w4, #64
771         beq             .Lxtsdecout
772         subs            w4, w4, #16
773 .Lxtsdecloop:
774         ld1             {v0.16b}, [x1], #16
775         bmi             .Lxtsdeccts
776 .Lxtsdecctsout:
777         eor             v0.16b, v0.16b, v4.16b
778         decrypt_block   v0, w3, x2, x8, w7
779         eor             v0.16b, v0.16b, v4.16b
780         st1             {v0.16b}, [x0], #16
781         cbz             w4, .Lxtsdecout
782         subs            w4, w4, #16
783         next_tweak      v4, v4, v8
784         b               .Lxtsdecloop
785 .Lxtsdecout:
786         st1             {v4.16b}, [x6]
787         frame_pop
788         ret
789 
790 .Lxtsdeccts:
791         adr_l           x8, .Lcts_permute_table
792 
793         add             x1, x1, w4, sxtw        /* rewind input pointer */
794         add             w4, w4, #16             /* # bytes in final block */
795         add             x9, x8, #32
796         add             x8, x8, x4
797         sub             x9, x9, x4
798         add             x4, x0, x4              /* output address of final block */
799 
800         next_tweak      v5, v4, v8
801 
802         ld1             {v1.16b}, [x1]          /* load final block */
803         ld1             {v2.16b}, [x8]
804         ld1             {v3.16b}, [x9]
805 
806         eor             v0.16b, v0.16b, v5.16b
807         decrypt_block   v0, w3, x2, x8, w7
808         eor             v0.16b, v0.16b, v5.16b
809 
810         tbl             v2.16b, {v0.16b}, v2.16b
811         tbx             v0.16b, {v1.16b}, v3.16b
812 
813         st1             {v2.16b}, [x4]                  /* overlapping stores */
814         mov             w4, wzr
815         b               .Lxtsdecctsout
816 AES_FUNC_END(aes_xts_decrypt)
817 
818         /*
819          * aes_mac_update(u8 const in[], u32 const rk[], int rounds,
820          *                int blocks, u8 dg[], int enc_before, int enc_after)
821          */
822 AES_FUNC_START(aes_mac_update)
823         ld1             {v0.16b}, [x4]                  /* get dg */
824         enc_prepare     w2, x1, x7
825         cbz             w5, .Lmacloop4x
826 
827         encrypt_block   v0, w2, x1, x7, w8
828 
829 .Lmacloop4x:
830         subs            w3, w3, #4
831         bmi             .Lmac1x
832         ld1             {v1.16b-v4.16b}, [x0], #64      /* get next pt block */
833         eor             v0.16b, v0.16b, v1.16b          /* ..and xor with dg */
834         encrypt_block   v0, w2, x1, x7, w8
835         eor             v0.16b, v0.16b, v2.16b
836         encrypt_block   v0, w2, x1, x7, w8
837         eor             v0.16b, v0.16b, v3.16b
838         encrypt_block   v0, w2, x1, x7, w8
839         eor             v0.16b, v0.16b, v4.16b
840         cmp             w3, wzr
841         csinv           x5, x6, xzr, eq
842         cbz             w5, .Lmacout
843         encrypt_block   v0, w2, x1, x7, w8
844         st1             {v0.16b}, [x4]                  /* return dg */
845         cond_yield      .Lmacout, x7, x8
846         b               .Lmacloop4x
847 .Lmac1x:
848         add             w3, w3, #4
849 .Lmacloop:
850         cbz             w3, .Lmacout
851         ld1             {v1.16b}, [x0], #16             /* get next pt block */
852         eor             v0.16b, v0.16b, v1.16b          /* ..and xor with dg */
853 
854         subs            w3, w3, #1
855         csinv           x5, x6, xzr, eq
856         cbz             w5, .Lmacout
857 
858 .Lmacenc:
859         encrypt_block   v0, w2, x1, x7, w8
860         b               .Lmacloop
861 
862 .Lmacout:
863         st1             {v0.16b}, [x4]                  /* return dg */
864         mov             w0, w3
865         ret
866 AES_FUNC_END(aes_mac_update)

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php