1 From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
2 From: "Jason A. Donenfeld" <Jason@zx2c4.com>
3 Date: Fri, 8 Nov 2019 13:22:38 +0100
4 Subject: [PATCH] crypto: arm/curve25519 - wire up NEON implementation
6 commit d8f1308a025fc7e00414194ed742d5f05a21e13c upstream.
8 This ports the SUPERCOP implementation for usage in kernel space. In
9 addition to the usual header, macro, and style changes required for
10 kernel space, it makes a few small changes to the code:
12 - The stack alignment is relaxed to 16 bytes.
13 - Superfluous mov statements have been removed.
14 - ldr for constants has been replaced with movw.
15 - ldreq has been replaced with moveq.
16 - The str epilogue has been made more idiomatic.
17 - SIMD registers are not pushed and popped at the beginning and end.
18 - The prologue and epilogue have been made idiomatic.
19 - A hole has been removed from the stack, saving 32 bytes.
20 - We write-back the base register whenever possible for vld1.8.
21 - Some multiplications have been reordered for better A7 performance.
23 There are more opportunities for cleanup, since this code is from qhasm,
24 which doesn't always do the most opportune thing. But even prior to
25 extensive hand optimizations, this code delivers significant performance
26 improvements (given in get_cycles() per call):
28 ----------- -------------
29 | generic C | this commit |
30 ------------ ----------- -------------
31 | Cortex-A7 | 49136 | 22395 |
32 ------------ ----------- -------------
33 | Cortex-A17 | 17326 | 4983 |
34 ------------ ----------- -------------
36 Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
37 [ardb: - move to arch/arm/crypto
38 - wire into lib/crypto framework
39 - implement crypto API KPP hooks ]
40 Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
41 Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
42 Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
44 arch/arm/crypto/Kconfig | 6 +
45 arch/arm/crypto/Makefile | 2 +
46 arch/arm/crypto/curve25519-core.S | 347 +++++++++++++-----------------
47 arch/arm/crypto/curve25519-glue.c | 127 +++++++++++
48 4 files changed, 287 insertions(+), 195 deletions(-)
49 create mode 100644 arch/arm/crypto/curve25519-glue.c
51 --- a/arch/arm/crypto/Kconfig
52 +++ b/arch/arm/crypto/Kconfig
53 @@ -141,4 +141,10 @@ config CRYPTO_NHPOLY1305_NEON
54 depends on KERNEL_MODE_NEON
55 select CRYPTO_NHPOLY1305
57 +config CRYPTO_CURVE25519_NEON
58 + tristate "NEON accelerated Curve25519 scalar multiplication library"
59 + depends on KERNEL_MODE_NEON
60 + select CRYPTO_LIB_CURVE25519_GENERIC
61 + select CRYPTO_ARCH_HAVE_LIB_CURVE25519
64 --- a/arch/arm/crypto/Makefile
65 +++ b/arch/arm/crypto/Makefile
66 @@ -12,6 +12,7 @@ obj-$(CONFIG_CRYPTO_SHA512_ARM) += sha51
67 obj-$(CONFIG_CRYPTO_CHACHA20_NEON) += chacha-neon.o
68 obj-$(CONFIG_CRYPTO_POLY1305_ARM) += poly1305-arm.o
69 obj-$(CONFIG_CRYPTO_NHPOLY1305_NEON) += nhpoly1305-neon.o
70 +obj-$(CONFIG_CRYPTO_CURVE25519_NEON) += curve25519-neon.o
72 ce-obj-$(CONFIG_CRYPTO_AES_ARM_CE) += aes-arm-ce.o
73 ce-obj-$(CONFIG_CRYPTO_SHA1_ARM_CE) += sha1-arm-ce.o
74 @@ -58,6 +59,7 @@ chacha-neon-y := chacha-scalar-core.o ch
75 chacha-neon-$(CONFIG_KERNEL_MODE_NEON) += chacha-neon-core.o
76 poly1305-arm-y := poly1305-core.o poly1305-glue.o
77 nhpoly1305-neon-y := nh-neon-core.o nhpoly1305-neon-glue.o
78 +curve25519-neon-y := curve25519-core.o curve25519-glue.o
80 ifdef REGENERATE_ARM_CRYPTO
81 quiet_cmd_perl = PERL $@
82 --- a/arch/arm/crypto/curve25519-core.S
83 +++ b/arch/arm/crypto/curve25519-core.S
85 +/* SPDX-License-Identifier: GPL-2.0 OR MIT */
87 - * Public domain code from Daniel J. Bernstein and Peter Schwabe, from
88 - * SUPERCOP's curve25519/neon2/scalarmult.s.
89 + * Copyright (C) 2015-2019 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
91 + * Based on public domain code from Daniel J. Bernstein and Peter Schwabe. This
92 + * began from SUPERCOP's curve25519/neon2/scalarmult.s, but has subsequently been
93 + * manually reworked for use in kernel space.
97 +#include <linux/linkage.h>
103 -.global _crypto_scalarmult_curve25519_neon2
104 -.global crypto_scalarmult_curve25519_neon2
105 -.type _crypto_scalarmult_curve25519_neon2 STT_FUNC
106 -.type crypto_scalarmult_curve25519_neon2 STT_FUNC
107 - _crypto_scalarmult_curve25519_neon2:
108 - crypto_scalarmult_curve25519_neon2:
109 - vpush {q4, q5, q6, q7}
112 - and sp, sp, #0xffffffe0
116 - strd r10, [sp, #24]
117 - str r12, [sp, #480]
118 - str r14, [sp, #484]
126 +ENTRY(curve25519_neon)
130 + and r3, r3, #0xfffffff0
140 - vst1.8 {d2-d3}, [r6, : 128]
142 - vst1.8 {d0-d1}, [r6, : 128]
145 + vst1.8 {d2-d3}, [r6, : 128]!
146 + vst1.8 {d0-d1}, [r6, : 128]!
147 vst1.8 {d4-d5}, [r6, : 128]
151 vst1.8 {d4-d5}, [r6, : 128]!
152 vst1.8 d4, [r6, : 64]
158 sub r7, r7, r7, LSL #7
162 vld1.8 {d4-d5}, [r1]!
164 vst1.8 {d4-d5}, [r6, : 128]!
165 @@ -212,15 +204,15 @@
166 vst1.8 {d0-d1}, [r6, : 128]!
167 vst1.8 {d2-d3}, [r6, : 128]!
168 vst1.8 d4, [r6, : 64]
186 vst1.8 d4, [r4, : 64]
187 vst1.8 d0, [r6, : 64]
192 vld1.8 {d0-d1}, [r2, : 128]
193 @@ -361,14 +353,13 @@
194 vmlal.s32 q0, d12, d8
195 vmlal.s32 q0, d13, d17
198 - vld1.8 {d18-d19}, [r2, : 128]
200 + vld1.8 {d18-d19}, [r2, : 128]!
201 vmull.s32 q3, d16, d7
202 vmlal.s32 q3, d10, d15
203 vmlal.s32 q3, d11, d14
204 vmlal.s32 q3, d12, d9
205 vmlal.s32 q3, d13, d8
207 vld1.8 {d8-d9}, [r2, : 128]
210 @@ -502,22 +493,19 @@
216 vadd.i32 q10, q10, q2
218 - vst1.8 {d12-d13}, [r2, : 128]
219 + vst1.8 {d12-d13}, [r2, : 128]!
222 - vst1.8 {d20-d21}, [r2, : 128]
223 + vst1.8 {d20-d21}, [r2, : 128]!
224 vshl.i32 q10, q14, #1
226 - vst1.8 {d12-d13}, [r2, : 128]
227 + vst1.8 {d12-d13}, [r2, : 128]!
228 vshl.i32 q15, q12, #1
230 vext.32 d10, d31, d30, #0
233 - vst1.8 {d16-d17}, [r2, : 128]
234 + vst1.8 {d16-d17}, [r2, : 128]!
235 vmull.s32 q8, d18, d5
236 vmlal.s32 q8, d26, d4
237 vmlal.s32 q8, d19, d9
239 vmlal.s32 q8, d29, d1
240 vmlal.s32 q8, d24, d6
241 vmlal.s32 q8, d25, d0
243 - vst1.8 {d14-d15}, [r2, : 128]
244 + vst1.8 {d14-d15}, [r2, : 128]!
245 vmull.s32 q2, d18, d4
246 vmlal.s32 q2, d12, d9
247 vmlal.s32 q2, d13, d8
249 vmlal.s32 q2, d22, d2
250 vmlal.s32 q2, d23, d1
251 vmlal.s32 q2, d24, d0
253 - vst1.8 {d20-d21}, [r2, : 128]
254 + vst1.8 {d20-d21}, [r2, : 128]!
255 vmull.s32 q7, d18, d9
256 vmlal.s32 q7, d26, d3
257 vmlal.s32 q7, d19, d8
258 @@ -547,14 +533,12 @@
259 vmlal.s32 q7, d28, d1
260 vmlal.s32 q7, d23, d6
261 vmlal.s32 q7, d29, d0
263 - vst1.8 {d10-d11}, [r2, : 128]
264 + vst1.8 {d10-d11}, [r2, : 128]!
265 vmull.s32 q5, d18, d3
266 vmlal.s32 q5, d19, d2
267 vmlal.s32 q5, d22, d1
268 vmlal.s32 q5, d23, d0
269 vmlal.s32 q5, d12, d8
271 vst1.8 {d16-d17}, [r2, : 128]
272 vmull.s32 q4, d18, d8
273 vmlal.s32 q4, d26, d2
275 vmlal.s32 q8, d26, d1
276 vmlal.s32 q8, d19, d6
277 vmlal.s32 q8, d27, d0
280 vld1.8 {d20-d21}, [r2, : 128]
281 vmlal.s32 q7, d24, d21
282 vmlal.s32 q7, d25, d20
283 @@ -575,32 +559,30 @@
284 vmlal.s32 q8, d22, d21
285 vmlal.s32 q8, d28, d20
286 vmlal.s32 q5, d24, d20
288 vst1.8 {d14-d15}, [r2, : 128]
289 vmull.s32 q7, d18, d6
290 vmlal.s32 q7, d26, d0
293 vld1.8 {d30-d31}, [r2, : 128]
294 vmlal.s32 q2, d30, d21
295 vmlal.s32 q7, d19, d21
296 vmlal.s32 q7, d27, d20
299 vld1.8 {d26-d27}, [r2, : 128]
300 vmlal.s32 q4, d25, d27
301 vmlal.s32 q8, d29, d27
302 vmlal.s32 q8, d25, d26
303 vmlal.s32 q7, d28, d27
304 vmlal.s32 q7, d29, d26
307 vld1.8 {d28-d29}, [r2, : 128]
308 vmlal.s32 q4, d24, d29
309 vmlal.s32 q8, d23, d29
310 vmlal.s32 q8, d24, d28
311 vmlal.s32 q7, d22, d29
312 vmlal.s32 q7, d23, d28
314 vst1.8 {d8-d9}, [r2, : 128]
317 vld1.8 {d8-d9}, [r2, : 128]
318 vmlal.s32 q7, d24, d9
319 vmlal.s32 q7, d25, d31
320 @@ -621,36 +603,36 @@
321 vmlal.s32 q0, d23, d26
322 vmlal.s32 q0, d24, d31
323 vmlal.s32 q0, d19, d20
326 vld1.8 {d18-d19}, [r2, : 128]
327 vmlal.s32 q2, d18, d7
328 - vmlal.s32 q2, d19, d6
329 vmlal.s32 q5, d18, d6
330 - vmlal.s32 q5, d19, d21
331 vmlal.s32 q1, d18, d21
332 - vmlal.s32 q1, d19, d29
333 vmlal.s32 q0, d18, d28
334 - vmlal.s32 q0, d19, d9
335 vmlal.s32 q6, d18, d29
336 + vmlal.s32 q2, d19, d6
337 + vmlal.s32 q5, d19, d21
338 + vmlal.s32 q1, d19, d29
339 + vmlal.s32 q0, d19, d9
340 vmlal.s32 q6, d19, d28
343 vld1.8 {d18-d19}, [r2, : 128]
346 vld1.8 {d22-d23}, [r2, : 128]
347 vmlal.s32 q5, d19, d7
348 vmlal.s32 q0, d18, d21
349 vmlal.s32 q0, d19, d29
350 vmlal.s32 q6, d18, d6
353 vld1.8 {d6-d7}, [r2, : 128]
354 vmlal.s32 q6, d19, d21
357 vld1.8 {d18-d19}, [r2, : 128]
358 vmlal.s32 q0, d30, d8
361 vld1.8 {d20-d21}, [r2, : 128]
362 vmlal.s32 q5, d30, d29
365 vld1.8 {d24-d25}, [r2, : 128]
366 vmlal.s32 q1, d30, d28
367 vadd.i64 q13, q0, q11
368 @@ -823,22 +805,19 @@
374 vadd.i32 q10, q10, q2
376 - vst1.8 {d12-d13}, [r2, : 128]
377 + vst1.8 {d12-d13}, [r2, : 128]!
380 - vst1.8 {d20-d21}, [r2, : 128]
381 + vst1.8 {d20-d21}, [r2, : 128]!
382 vshl.i32 q10, q14, #1
384 - vst1.8 {d12-d13}, [r2, : 128]
385 + vst1.8 {d12-d13}, [r2, : 128]!
386 vshl.i32 q15, q12, #1
388 vext.32 d10, d31, d30, #0
391 - vst1.8 {d16-d17}, [r2, : 128]
392 + vst1.8 {d16-d17}, [r2, : 128]!
393 vmull.s32 q8, d18, d5
394 vmlal.s32 q8, d26, d4
395 vmlal.s32 q8, d19, d9
397 vmlal.s32 q8, d29, d1
398 vmlal.s32 q8, d24, d6
399 vmlal.s32 q8, d25, d0
401 - vst1.8 {d14-d15}, [r2, : 128]
402 + vst1.8 {d14-d15}, [r2, : 128]!
403 vmull.s32 q2, d18, d4
404 vmlal.s32 q2, d12, d9
405 vmlal.s32 q2, d13, d8
407 vmlal.s32 q2, d22, d2
408 vmlal.s32 q2, d23, d1
409 vmlal.s32 q2, d24, d0
411 - vst1.8 {d20-d21}, [r2, : 128]
412 + vst1.8 {d20-d21}, [r2, : 128]!
413 vmull.s32 q7, d18, d9
414 vmlal.s32 q7, d26, d3
415 vmlal.s32 q7, d19, d8
416 @@ -868,15 +845,13 @@
417 vmlal.s32 q7, d28, d1
418 vmlal.s32 q7, d23, d6
419 vmlal.s32 q7, d29, d0
421 - vst1.8 {d10-d11}, [r2, : 128]
422 + vst1.8 {d10-d11}, [r2, : 128]!
423 vmull.s32 q5, d18, d3
424 vmlal.s32 q5, d19, d2
425 vmlal.s32 q5, d22, d1
426 vmlal.s32 q5, d23, d0
427 vmlal.s32 q5, d12, d8
429 - vst1.8 {d16-d17}, [r2, : 128]
430 + vst1.8 {d16-d17}, [r2, : 128]!
431 vmull.s32 q4, d18, d8
432 vmlal.s32 q4, d26, d2
433 vmlal.s32 q4, d19, d7
435 vmlal.s32 q8, d26, d1
436 vmlal.s32 q8, d19, d6
437 vmlal.s32 q8, d27, d0
440 vld1.8 {d20-d21}, [r2, : 128]
441 vmlal.s32 q7, d24, d21
442 vmlal.s32 q7, d25, d20
443 @@ -896,32 +871,30 @@
444 vmlal.s32 q8, d22, d21
445 vmlal.s32 q8, d28, d20
446 vmlal.s32 q5, d24, d20
448 vst1.8 {d14-d15}, [r2, : 128]
449 vmull.s32 q7, d18, d6
450 vmlal.s32 q7, d26, d0
453 vld1.8 {d30-d31}, [r2, : 128]
454 vmlal.s32 q2, d30, d21
455 vmlal.s32 q7, d19, d21
456 vmlal.s32 q7, d27, d20
459 vld1.8 {d26-d27}, [r2, : 128]
460 vmlal.s32 q4, d25, d27
461 vmlal.s32 q8, d29, d27
462 vmlal.s32 q8, d25, d26
463 vmlal.s32 q7, d28, d27
464 vmlal.s32 q7, d29, d26
467 vld1.8 {d28-d29}, [r2, : 128]
468 vmlal.s32 q4, d24, d29
469 vmlal.s32 q8, d23, d29
470 vmlal.s32 q8, d24, d28
471 vmlal.s32 q7, d22, d29
472 vmlal.s32 q7, d23, d28
474 vst1.8 {d8-d9}, [r2, : 128]
477 vld1.8 {d8-d9}, [r2, : 128]
478 vmlal.s32 q7, d24, d9
479 vmlal.s32 q7, d25, d31
480 @@ -942,36 +915,36 @@
481 vmlal.s32 q0, d23, d26
482 vmlal.s32 q0, d24, d31
483 vmlal.s32 q0, d19, d20
486 vld1.8 {d18-d19}, [r2, : 128]
487 vmlal.s32 q2, d18, d7
488 - vmlal.s32 q2, d19, d6
489 vmlal.s32 q5, d18, d6
490 - vmlal.s32 q5, d19, d21
491 vmlal.s32 q1, d18, d21
492 - vmlal.s32 q1, d19, d29
493 vmlal.s32 q0, d18, d28
494 - vmlal.s32 q0, d19, d9
495 vmlal.s32 q6, d18, d29
496 + vmlal.s32 q2, d19, d6
497 + vmlal.s32 q5, d19, d21
498 + vmlal.s32 q1, d19, d29
499 + vmlal.s32 q0, d19, d9
500 vmlal.s32 q6, d19, d28
503 vld1.8 {d18-d19}, [r2, : 128]
506 vld1.8 {d22-d23}, [r2, : 128]
507 vmlal.s32 q5, d19, d7
508 vmlal.s32 q0, d18, d21
509 vmlal.s32 q0, d19, d29
510 vmlal.s32 q6, d18, d6
513 vld1.8 {d6-d7}, [r2, : 128]
514 vmlal.s32 q6, d19, d21
517 vld1.8 {d18-d19}, [r2, : 128]
518 vmlal.s32 q0, d30, d8
521 vld1.8 {d20-d21}, [r2, : 128]
522 vmlal.s32 q5, d30, d29
525 vld1.8 {d24-d25}, [r2, : 128]
526 vmlal.s32 q1, d30, d28
527 vadd.i64 q13, q0, q11
528 @@ -1069,7 +1042,7 @@
530 vst1.8 d0, [r2, : 64]
531 vst1.8 d1, [r4, : 64]
536 vld1.8 {d0-d1}, [r2, : 128]
537 @@ -1139,14 +1112,13 @@
538 vmlal.s32 q0, d12, d8
539 vmlal.s32 q0, d13, d17
542 - vld1.8 {d18-d19}, [r2, : 128]
544 + vld1.8 {d18-d19}, [r2, : 128]!
545 vmull.s32 q3, d16, d7
546 vmlal.s32 q3, d10, d15
547 vmlal.s32 q3, d11, d14
548 vmlal.s32 q3, d12, d9
549 vmlal.s32 q3, d13, d8
551 vld1.8 {d8-d9}, [r2, : 128]
554 @@ -1295,22 +1267,19 @@
560 vadd.i32 q10, q10, q2
562 - vst1.8 {d12-d13}, [r2, : 128]
563 + vst1.8 {d12-d13}, [r2, : 128]!
566 - vst1.8 {d20-d21}, [r2, : 128]
567 + vst1.8 {d20-d21}, [r2, : 128]!
568 vshl.i32 q10, q14, #1
570 - vst1.8 {d12-d13}, [r2, : 128]
571 + vst1.8 {d12-d13}, [r2, : 128]!
572 vshl.i32 q15, q12, #1
574 vext.32 d10, d31, d30, #0
577 - vst1.8 {d16-d17}, [r2, : 128]
578 + vst1.8 {d16-d17}, [r2, : 128]!
579 vmull.s32 q8, d18, d5
580 vmlal.s32 q8, d26, d4
581 vmlal.s32 q8, d19, d9
582 @@ -1321,8 +1290,7 @@
583 vmlal.s32 q8, d29, d1
584 vmlal.s32 q8, d24, d6
585 vmlal.s32 q8, d25, d0
587 - vst1.8 {d14-d15}, [r2, : 128]
588 + vst1.8 {d14-d15}, [r2, : 128]!
589 vmull.s32 q2, d18, d4
590 vmlal.s32 q2, d12, d9
591 vmlal.s32 q2, d13, d8
592 @@ -1330,8 +1298,7 @@
593 vmlal.s32 q2, d22, d2
594 vmlal.s32 q2, d23, d1
595 vmlal.s32 q2, d24, d0
597 - vst1.8 {d20-d21}, [r2, : 128]
598 + vst1.8 {d20-d21}, [r2, : 128]!
599 vmull.s32 q7, d18, d9
600 vmlal.s32 q7, d26, d3
601 vmlal.s32 q7, d19, d8
602 @@ -1340,15 +1307,13 @@
603 vmlal.s32 q7, d28, d1
604 vmlal.s32 q7, d23, d6
605 vmlal.s32 q7, d29, d0
607 - vst1.8 {d10-d11}, [r2, : 128]
608 + vst1.8 {d10-d11}, [r2, : 128]!
609 vmull.s32 q5, d18, d3
610 vmlal.s32 q5, d19, d2
611 vmlal.s32 q5, d22, d1
612 vmlal.s32 q5, d23, d0
613 vmlal.s32 q5, d12, d8
615 - vst1.8 {d16-d17}, [r2, : 128]
616 + vst1.8 {d16-d17}, [r2, : 128]!
617 vmull.s32 q4, d18, d8
618 vmlal.s32 q4, d26, d2
619 vmlal.s32 q4, d19, d7
620 @@ -1359,7 +1324,7 @@
621 vmlal.s32 q8, d26, d1
622 vmlal.s32 q8, d19, d6
623 vmlal.s32 q8, d27, d0
626 vld1.8 {d20-d21}, [r2, : 128]
627 vmlal.s32 q7, d24, d21
628 vmlal.s32 q7, d25, d20
629 @@ -1368,32 +1333,30 @@
630 vmlal.s32 q8, d22, d21
631 vmlal.s32 q8, d28, d20
632 vmlal.s32 q5, d24, d20
634 vst1.8 {d14-d15}, [r2, : 128]
635 vmull.s32 q7, d18, d6
636 vmlal.s32 q7, d26, d0
639 vld1.8 {d30-d31}, [r2, : 128]
640 vmlal.s32 q2, d30, d21
641 vmlal.s32 q7, d19, d21
642 vmlal.s32 q7, d27, d20
645 vld1.8 {d26-d27}, [r2, : 128]
646 vmlal.s32 q4, d25, d27
647 vmlal.s32 q8, d29, d27
648 vmlal.s32 q8, d25, d26
649 vmlal.s32 q7, d28, d27
650 vmlal.s32 q7, d29, d26
653 vld1.8 {d28-d29}, [r2, : 128]
654 vmlal.s32 q4, d24, d29
655 vmlal.s32 q8, d23, d29
656 vmlal.s32 q8, d24, d28
657 vmlal.s32 q7, d22, d29
658 vmlal.s32 q7, d23, d28
660 vst1.8 {d8-d9}, [r2, : 128]
663 vld1.8 {d8-d9}, [r2, : 128]
664 vmlal.s32 q7, d24, d9
665 vmlal.s32 q7, d25, d31
666 @@ -1414,36 +1377,36 @@
667 vmlal.s32 q0, d23, d26
668 vmlal.s32 q0, d24, d31
669 vmlal.s32 q0, d19, d20
672 vld1.8 {d18-d19}, [r2, : 128]
673 vmlal.s32 q2, d18, d7
674 - vmlal.s32 q2, d19, d6
675 vmlal.s32 q5, d18, d6
676 - vmlal.s32 q5, d19, d21
677 vmlal.s32 q1, d18, d21
678 - vmlal.s32 q1, d19, d29
679 vmlal.s32 q0, d18, d28
680 - vmlal.s32 q0, d19, d9
681 vmlal.s32 q6, d18, d29
682 + vmlal.s32 q2, d19, d6
683 + vmlal.s32 q5, d19, d21
684 + vmlal.s32 q1, d19, d29
685 + vmlal.s32 q0, d19, d9
686 vmlal.s32 q6, d19, d28
689 vld1.8 {d18-d19}, [r2, : 128]
692 vld1.8 {d22-d23}, [r2, : 128]
693 vmlal.s32 q5, d19, d7
694 vmlal.s32 q0, d18, d21
695 vmlal.s32 q0, d19, d29
696 vmlal.s32 q6, d18, d6
699 vld1.8 {d6-d7}, [r2, : 128]
700 vmlal.s32 q6, d19, d21
703 vld1.8 {d18-d19}, [r2, : 128]
704 vmlal.s32 q0, d30, d8
707 vld1.8 {d20-d21}, [r2, : 128]
708 vmlal.s32 q5, d30, d29
711 vld1.8 {d24-d25}, [r2, : 128]
712 vmlal.s32 q1, d30, d28
713 vadd.i64 q13, q0, q11
714 @@ -1541,10 +1504,10 @@
716 vst1.8 d0, [r2, : 64]
717 vst1.8 d1, [r4, : 64]
727 vld1.8 {d0-d1}, [r1, : 128]!
728 @@ -1553,41 +1516,41 @@
729 vst1.8 {d0-d1}, [r2, : 128]!
730 vst1.8 {d2-d3}, [r2, : 128]!
731 vst1.8 d4, [r2, : 64]
785 @@ -1598,8 +1561,8 @@
786 vst1.8 {d2-d3}, [r7, : 128]!
787 vst1.8 d4, [r7, : 64]
789 - beq ._skipsquaringloop
791 + beq .Lskipsquaringloop
796 @@ -1611,7 +1574,7 @@
797 vld1.8 {d6-d7}, [r7, : 128]!
798 vld1.8 {d9}, [r7, : 64]
799 vld1.8 {d10-d11}, [r6, : 128]!
802 vld1.8 {d12-d13}, [r6, : 128]!
804 vld1.8 {d8}, [r6, : 64]
805 @@ -1726,7 +1689,7 @@
806 vext.32 d10, d6, d6, #0
807 vmov.i32 q1, #0xffffffff
811 vld1.8 {d14-d15}, [r7, : 128]
814 @@ -1735,7 +1698,7 @@
817 vld1.8 {d16}, [r6, : 64]!
820 vld1.8 {d20-d21}, [r6, : 128]
821 vadd.i64 q11, q5, q10
823 @@ -1789,8 +1752,8 @@
825 vst1.8 d4, [r6, : 64]
834 @@ -1802,7 +1765,7 @@
835 vld1.8 {d6-d7}, [r5, : 128]!
836 vld1.8 {d9}, [r5, : 64]
837 vld1.8 {d10-d11}, [r2, : 128]!
840 vld1.8 {d12-d13}, [r2, : 128]!
842 vld1.8 {d8}, [r2, : 64]
843 @@ -1917,7 +1880,7 @@
844 vext.32 d10, d6, d6, #0
845 vmov.i32 q1, #0xffffffff
849 vld1.8 {d14-d15}, [r5, : 128]
852 @@ -1926,7 +1889,7 @@
855 vld1.8 {d16}, [r2, : 64]!
858 vld1.8 {d20-d21}, [r2, : 128]
859 vadd.i64 q11, q5, q10
861 @@ -1980,7 +1943,7 @@
863 vst1.8 d4, [r2, : 64]
869 vld1.8 {d0-d1}, [r2, : 128]!
870 @@ -1989,9 +1952,9 @@
871 vst1.8 {d0-d1}, [r4, : 128]!
872 vst1.8 {d2-d3}, [r4, : 128]!
873 vst1.8 d4, [r4, : 64]
877 - bne ._skipfinalcopy
878 + bne .Lskipfinalcopy
881 vld1.8 {d0-d1}, [r2, : 128]!
882 @@ -2000,10 +1963,10 @@
883 vst1.8 {d0-d1}, [r4, : 128]!
884 vst1.8 {d2-d3}, [r4, : 128]!
885 vst1.8 d4, [r4, : 64]
895 @@ -2085,21 +2048,15 @@
896 add r8, r8, r10, LSL #12
898 add r1, r9, r1, LSL #6
910 - ldrd r10, [sp, #24]
911 - ldr r12, [sp, #480]
912 - ldr r14, [sp, #484]
915 - vpop {q4, q5, q6, q7}
928 +ENDPROC(curve25519_neon)
930 +++ b/arch/arm/crypto/curve25519-glue.c
932 +// SPDX-License-Identifier: GPL-2.0 OR MIT
934 + * Copyright (C) 2015-2019 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
936 + * Based on public domain code from Daniel J. Bernstein and Peter Schwabe. This
937 + * began from SUPERCOP's curve25519/neon2/scalarmult.s, but has subsequently been
938 + * manually reworked for use in kernel space.
941 +#include <asm/hwcap.h>
942 +#include <asm/neon.h>
943 +#include <asm/simd.h>
944 +#include <crypto/internal/kpp.h>
945 +#include <crypto/internal/simd.h>
946 +#include <linux/types.h>
947 +#include <linux/module.h>
948 +#include <linux/init.h>
949 +#include <linux/jump_label.h>
950 +#include <crypto/curve25519.h>
952 +asmlinkage void curve25519_neon(u8 mypublic[CURVE25519_KEY_SIZE],
953 + const u8 secret[CURVE25519_KEY_SIZE],
954 + const u8 basepoint[CURVE25519_KEY_SIZE]);
956 +static __ro_after_init DEFINE_STATIC_KEY_FALSE(have_neon);
958 +void curve25519_arch(u8 out[CURVE25519_KEY_SIZE],
959 + const u8 scalar[CURVE25519_KEY_SIZE],
960 + const u8 point[CURVE25519_KEY_SIZE])
962 + if (static_branch_likely(&have_neon) && crypto_simd_usable()) {
963 + kernel_neon_begin();
964 + curve25519_neon(out, scalar, point);
967 + curve25519_generic(out, scalar, point);
970 +EXPORT_SYMBOL(curve25519_arch);
972 +static int curve25519_set_secret(struct crypto_kpp *tfm, const void *buf,
975 + u8 *secret = kpp_tfm_ctx(tfm);
978 + curve25519_generate_secret(secret);
979 + else if (len == CURVE25519_KEY_SIZE &&
980 + crypto_memneq(buf, curve25519_null_point, CURVE25519_KEY_SIZE))
981 + memcpy(secret, buf, CURVE25519_KEY_SIZE);
987 +static int curve25519_compute_value(struct kpp_request *req)
989 + struct crypto_kpp *tfm = crypto_kpp_reqtfm(req);
990 + const u8 *secret = kpp_tfm_ctx(tfm);
991 + u8 public_key[CURVE25519_KEY_SIZE];
992 + u8 buf[CURVE25519_KEY_SIZE];
993 + int copied, nbytes;
997 + copied = sg_copy_to_buffer(req->src,
998 + sg_nents_for_len(req->src,
999 + CURVE25519_KEY_SIZE),
1000 + public_key, CURVE25519_KEY_SIZE);
1001 + if (copied != CURVE25519_KEY_SIZE)
1005 + bp = curve25519_base_point;
1008 + curve25519_arch(buf, secret, bp);
1010 + /* might want less than we've got */
1011 + nbytes = min_t(size_t, CURVE25519_KEY_SIZE, req->dst_len);
1012 + copied = sg_copy_from_buffer(req->dst, sg_nents_for_len(req->dst,
1015 + if (copied != nbytes)
1020 +static unsigned int curve25519_max_size(struct crypto_kpp *tfm)
1022 + return CURVE25519_KEY_SIZE;
1025 +static struct kpp_alg curve25519_alg = {
1026 + .base.cra_name = "curve25519",
1027 + .base.cra_driver_name = "curve25519-neon",
1028 + .base.cra_priority = 200,
1029 + .base.cra_module = THIS_MODULE,
1030 + .base.cra_ctxsize = CURVE25519_KEY_SIZE,
1032 + .set_secret = curve25519_set_secret,
1033 + .generate_public_key = curve25519_compute_value,
1034 + .compute_shared_secret = curve25519_compute_value,
1035 + .max_size = curve25519_max_size,
1038 +static int __init mod_init(void)
1040 + if (elf_hwcap & HWCAP_NEON) {
1041 + static_branch_enable(&have_neon);
1042 + return crypto_register_kpp(&curve25519_alg);
1047 +static void __exit mod_exit(void)
1049 + if (elf_hwcap & HWCAP_NEON)
1050 + crypto_unregister_kpp(&curve25519_alg);
1053 +module_init(mod_init);
1054 +module_exit(mod_exit);
1056 +MODULE_ALIAS_CRYPTO("curve25519");
1057 +MODULE_ALIAS_CRYPTO("curve25519-neon");
1058 +MODULE_LICENSE("GPL v2");