1 /* SPDX-License-Identifier: GPL-2.0-only */ 2 /* 3 * Accelerated GHASH implementation with ARMv8 PMULL instructions. 4 * 5 * Copyright (C) 2014 - 2018 Linaro Ltd. <ard.biesheuvel@linaro.org> 6 */ 7 8 #include <linux/linkage.h> 9 #include <linux/cfi_types.h> 10 #include <asm/assembler.h> 11 12 SHASH .req v0 13 SHASH2 .req v1 14 T1 .req v2 15 T2 .req v3 16 MASK .req v4 17 XM .req v5 18 XL .req v6 19 XH .req v7 20 IN1 .req v7 21 22 k00_16 .req v8 23 k32_48 .req v9 24 25 t3 .req v10 26 t4 .req v11 27 t5 .req v12 28 t6 .req v13 29 t7 .req v14 30 t8 .req v15 31 t9 .req v16 32 33 perm1 .req v17 34 perm2 .req v18 35 perm3 .req v19 36 37 sh1 .req v20 38 sh2 .req v21 39 sh3 .req v22 40 sh4 .req v23 41 42 ss1 .req v24 43 ss2 .req v25 44 ss3 .req v26 45 ss4 .req v27 46 47 XL2 .req v8 48 XM2 .req v9 49 XH2 .req v10 50 XL3 .req v11 51 XM3 .req v12 52 XH3 .req v13 53 TT3 .req v14 54 TT4 .req v15 55 HH .req v16 56 HH3 .req v17 57 HH4 .req v18 58 HH34 .req v19 59 60 .text 61 .arch armv8-a+crypto 62 63 .macro __pmull_p64, rd, rn, rm 64 pmull \rd\().1q, \rn\().1d, \rm\().1d 65 .endm 66 67 .macro __pmull2_p64, rd, rn, rm 68 pmull2 \rd\().1q, \rn\().2d, \rm\().2d 69 .endm 70 71 .macro __pmull_p8, rq, ad, bd 72 ext t3.8b, \ad\().8b, \ad\().8b, #1 // A1 73 ext t5.8b, \ad\().8b, \ad\().8b, #2 // A2 74 ext t7.8b, \ad\().8b, \ad\().8b, #3 // A3 75 76 __pmull_p8_\bd \rq, \ad 77 .endm 78 79 .macro __pmull2_p8, rq, ad, bd 80 tbl t3.16b, {\ad\().16b}, perm1.16b // A1 81 tbl t5.16b, {\ad\().16b}, perm2.16b // A2 82 tbl t7.16b, {\ad\().16b}, perm3.16b // A3 83 84 __pmull2_p8_\bd \rq, \ad 85 .endm 86 87 .macro __pmull_p8_SHASH, rq, ad 88 __pmull_p8_tail \rq, \ad\().8b, SHASH.8b, 8b,, sh1, sh2, sh3, sh4 89 .endm 90 91 .macro __pmull_p8_SHASH2, rq, ad 92 __pmull_p8_tail \rq, \ad\().8b, SHASH2.8b, 8b,, ss1, ss2, ss3, ss4 93 .endm 94 95 .macro __pmull2_p8_SHASH, rq, ad 96 __pmull_p8_tail \rq, \ad\().16b, SHASH.16b, 16b, 2, sh1, sh2, sh3, sh4 97 .endm 98 99 .macro __pmull_p8_tail, rq, ad, bd, nb, t, b1, b2, b3, b4 100 pmull\t t3.8h, t3.\nb, \bd // F = A1*B 101 pmull\t t4.8h, \ad, \b1\().\nb // E = A*B1 102 pmull\t t5.8h, t5.\nb, \bd // H = A2*B 103 pmull\t t6.8h, \ad, \b2\().\nb // G = A*B2 104 pmull\t t7.8h, t7.\nb, \bd // J = A3*B 105 pmull\t t8.8h, \ad, \b3\().\nb // I = A*B3 106 pmull\t t9.8h, \ad, \b4\().\nb // K = A*B4 107 pmull\t \rq\().8h, \ad, \bd // D = A*B 108 109 eor t3.16b, t3.16b, t4.16b // L = E + F 110 eor t5.16b, t5.16b, t6.16b // M = G + H 111 eor t7.16b, t7.16b, t8.16b // N = I + J 112 113 uzp1 t4.2d, t3.2d, t5.2d 114 uzp2 t3.2d, t3.2d, t5.2d 115 uzp1 t6.2d, t7.2d, t9.2d 116 uzp2 t7.2d, t7.2d, t9.2d 117 118 // t3 = (L) (P0 + P1) << 8 119 // t5 = (M) (P2 + P3) << 16 120 eor t4.16b, t4.16b, t3.16b 121 and t3.16b, t3.16b, k32_48.16b 122 123 // t7 = (N) (P4 + P5) << 24 124 // t9 = (K) (P6 + P7) << 32 125 eor t6.16b, t6.16b, t7.16b 126 and t7.16b, t7.16b, k00_16.16b 127 128 eor t4.16b, t4.16b, t3.16b 129 eor t6.16b, t6.16b, t7.16b 130 131 zip2 t5.2d, t4.2d, t3.2d 132 zip1 t3.2d, t4.2d, t3.2d 133 zip2 t9.2d, t6.2d, t7.2d 134 zip1 t7.2d, t6.2d, t7.2d 135 136 ext t3.16b, t3.16b, t3.16b, #15 137 ext t5.16b, t5.16b, t5.16b, #14 138 ext t7.16b, t7.16b, t7.16b, #13 139 ext t9.16b, t9.16b, t9.16b, #12 140 141 eor t3.16b, t3.16b, t5.16b 142 eor t7.16b, t7.16b, t9.16b 143 eor \rq\().16b, \rq\().16b, t3.16b 144 eor \rq\().16b, \rq\().16b, t7.16b 145 .endm 146 147 .macro __pmull_pre_p64 148 add x8, x3, #16 149 ld1 {HH.2d-HH4.2d}, [x8] 150 151 trn1 SHASH2.2d, SHASH.2d, HH.2d 152 trn2 T1.2d, SHASH.2d, HH.2d 153 eor SHASH2.16b, SHASH2.16b, T1.16b 154 155 trn1 HH34.2d, HH3.2d, HH4.2d 156 trn2 T1.2d, HH3.2d, HH4.2d 157 eor HH34.16b, HH34.16b, T1.16b 158 159 movi MASK.16b, #0xe1 160 shl MASK.2d, MASK.2d, #57 161 .endm 162 163 .macro __pmull_pre_p8 164 ext SHASH2.16b, SHASH.16b, SHASH.16b, #8 165 eor SHASH2.16b, SHASH2.16b, SHASH.16b 166 167 // k00_16 := 0x0000000000000000_000000000000ffff 168 // k32_48 := 0x00000000ffffffff_0000ffffffffffff 169 movi k32_48.2d, #0xffffffff 170 mov k32_48.h[2], k32_48.h[0] 171 ushr k00_16.2d, k32_48.2d, #32 172 173 // prepare the permutation vectors 174 mov_q x5, 0x080f0e0d0c0b0a09 175 movi T1.8b, #8 176 dup perm1.2d, x5 177 eor perm1.16b, perm1.16b, T1.16b 178 ushr perm2.2d, perm1.2d, #8 179 ushr perm3.2d, perm1.2d, #16 180 ushr T1.2d, perm1.2d, #24 181 sli perm2.2d, perm1.2d, #56 182 sli perm3.2d, perm1.2d, #48 183 sli T1.2d, perm1.2d, #40 184 185 // precompute loop invariants 186 tbl sh1.16b, {SHASH.16b}, perm1.16b 187 tbl sh2.16b, {SHASH.16b}, perm2.16b 188 tbl sh3.16b, {SHASH.16b}, perm3.16b 189 tbl sh4.16b, {SHASH.16b}, T1.16b 190 ext ss1.8b, SHASH2.8b, SHASH2.8b, #1 191 ext ss2.8b, SHASH2.8b, SHASH2.8b, #2 192 ext ss3.8b, SHASH2.8b, SHASH2.8b, #3 193 ext ss4.8b, SHASH2.8b, SHASH2.8b, #4 194 .endm 195 196 // 197 // PMULL (64x64->128) based reduction for CPUs that can do 198 // it in a single instruction. 199 // 200 .macro __pmull_reduce_p64 201 pmull T2.1q, XL.1d, MASK.1d 202 eor XM.16b, XM.16b, T1.16b 203 204 mov XH.d[0], XM.d[1] 205 mov XM.d[1], XL.d[0] 206 207 eor XL.16b, XM.16b, T2.16b 208 ext T2.16b, XL.16b, XL.16b, #8 209 pmull XL.1q, XL.1d, MASK.1d 210 .endm 211 212 // 213 // Alternative reduction for CPUs that lack support for the 214 // 64x64->128 PMULL instruction 215 // 216 .macro __pmull_reduce_p8 217 eor XM.16b, XM.16b, T1.16b 218 219 mov XL.d[1], XM.d[0] 220 mov XH.d[0], XM.d[1] 221 222 shl T1.2d, XL.2d, #57 223 shl T2.2d, XL.2d, #62 224 eor T2.16b, T2.16b, T1.16b 225 shl T1.2d, XL.2d, #63 226 eor T2.16b, T2.16b, T1.16b 227 ext T1.16b, XL.16b, XH.16b, #8 228 eor T2.16b, T2.16b, T1.16b 229 230 mov XL.d[1], T2.d[0] 231 mov XH.d[0], T2.d[1] 232 233 ushr T2.2d, XL.2d, #1 234 eor XH.16b, XH.16b, XL.16b 235 eor XL.16b, XL.16b, T2.16b 236 ushr T2.2d, T2.2d, #6 237 ushr XL.2d, XL.2d, #1 238 .endm 239 240 .macro __pmull_ghash, pn 241 ld1 {SHASH.2d}, [x3] 242 ld1 {XL.2d}, [x1] 243 244 __pmull_pre_\pn 245 246 /* do the head block first, if supplied */ 247 cbz x4, 0f 248 ld1 {T1.2d}, [x4] 249 mov x4, xzr 250 b 3f 251 252 0: .ifc \pn, p64 253 tbnz w0, #0, 2f // skip until #blocks is a 254 tbnz w0, #1, 2f // round multiple of 4 255 256 1: ld1 {XM3.16b-TT4.16b}, [x2], #64 257 258 sub w0, w0, #4 259 260 rev64 T1.16b, XM3.16b 261 rev64 T2.16b, XH3.16b 262 rev64 TT4.16b, TT4.16b 263 rev64 TT3.16b, TT3.16b 264 265 ext IN1.16b, TT4.16b, TT4.16b, #8 266 ext XL3.16b, TT3.16b, TT3.16b, #8 267 268 eor TT4.16b, TT4.16b, IN1.16b 269 pmull2 XH2.1q, SHASH.2d, IN1.2d // a1 * b1 270 pmull XL2.1q, SHASH.1d, IN1.1d // a0 * b0 271 pmull XM2.1q, SHASH2.1d, TT4.1d // (a1 + a0)(b1 + b0) 272 273 eor TT3.16b, TT3.16b, XL3.16b 274 pmull2 XH3.1q, HH.2d, XL3.2d // a1 * b1 275 pmull XL3.1q, HH.1d, XL3.1d // a0 * b0 276 pmull2 XM3.1q, SHASH2.2d, TT3.2d // (a1 + a0)(b1 + b0) 277 278 ext IN1.16b, T2.16b, T2.16b, #8 279 eor XL2.16b, XL2.16b, XL3.16b 280 eor XH2.16b, XH2.16b, XH3.16b 281 eor XM2.16b, XM2.16b, XM3.16b 282 283 eor T2.16b, T2.16b, IN1.16b 284 pmull2 XH3.1q, HH3.2d, IN1.2d // a1 * b1 285 pmull XL3.1q, HH3.1d, IN1.1d // a0 * b0 286 pmull XM3.1q, HH34.1d, T2.1d // (a1 + a0)(b1 + b0) 287 288 eor XL2.16b, XL2.16b, XL3.16b 289 eor XH2.16b, XH2.16b, XH3.16b 290 eor XM2.16b, XM2.16b, XM3.16b 291 292 ext IN1.16b, T1.16b, T1.16b, #8 293 ext TT3.16b, XL.16b, XL.16b, #8 294 eor XL.16b, XL.16b, IN1.16b 295 eor T1.16b, T1.16b, TT3.16b 296 297 pmull2 XH.1q, HH4.2d, XL.2d // a1 * b1 298 eor T1.16b, T1.16b, XL.16b 299 pmull XL.1q, HH4.1d, XL.1d // a0 * b0 300 pmull2 XM.1q, HH34.2d, T1.2d // (a1 + a0)(b1 + b0) 301 302 eor XL.16b, XL.16b, XL2.16b 303 eor XH.16b, XH.16b, XH2.16b 304 eor XM.16b, XM.16b, XM2.16b 305 306 eor T2.16b, XL.16b, XH.16b 307 ext T1.16b, XL.16b, XH.16b, #8 308 eor XM.16b, XM.16b, T2.16b 309 310 __pmull_reduce_p64 311 312 eor T2.16b, T2.16b, XH.16b 313 eor XL.16b, XL.16b, T2.16b 314 315 cbz w0, 5f 316 b 1b 317 .endif 318 319 2: ld1 {T1.2d}, [x2], #16 320 sub w0, w0, #1 321 322 3: /* multiply XL by SHASH in GF(2^128) */ 323 CPU_LE( rev64 T1.16b, T1.16b ) 324 325 ext T2.16b, XL.16b, XL.16b, #8 326 ext IN1.16b, T1.16b, T1.16b, #8 327 eor T1.16b, T1.16b, T2.16b 328 eor XL.16b, XL.16b, IN1.16b 329 330 __pmull2_\pn XH, XL, SHASH // a1 * b1 331 eor T1.16b, T1.16b, XL.16b 332 __pmull_\pn XL, XL, SHASH // a0 * b0 333 __pmull_\pn XM, T1, SHASH2 // (a1 + a0)(b1 + b0) 334 335 4: eor T2.16b, XL.16b, XH.16b 336 ext T1.16b, XL.16b, XH.16b, #8 337 eor XM.16b, XM.16b, T2.16b 338 339 __pmull_reduce_\pn 340 341 eor T2.16b, T2.16b, XH.16b 342 eor XL.16b, XL.16b, T2.16b 343 344 cbnz w0, 0b 345 346 5: st1 {XL.2d}, [x1] 347 ret 348 .endm 349 350 /* 351 * void pmull_ghash_update(int blocks, u64 dg[], const char *src, 352 * struct ghash_key const *k, const char *head) 353 */ 354 SYM_TYPED_FUNC_START(pmull_ghash_update_p64) 355 __pmull_ghash p64 356 SYM_FUNC_END(pmull_ghash_update_p64) 357 358 SYM_TYPED_FUNC_START(pmull_ghash_update_p8) 359 __pmull_ghash p8 360 SYM_FUNC_END(pmull_ghash_update_p8) 361 362 KS0 .req v8 363 KS1 .req v9 364 KS2 .req v10 365 KS3 .req v11 366 367 INP0 .req v21 368 INP1 .req v22 369 INP2 .req v23 370 INP3 .req v24 371 372 K0 .req v25 373 K1 .req v26 374 K2 .req v27 375 K3 .req v28 376 K4 .req v12 377 K5 .req v13 378 K6 .req v4 379 K7 .req v5 380 K8 .req v14 381 K9 .req v15 382 KK .req v29 383 KL .req v30 384 KM .req v31 385 386 .macro load_round_keys, rounds, rk, tmp 387 add \tmp, \rk, #64 388 ld1 {K0.4s-K3.4s}, [\rk] 389 ld1 {K4.4s-K5.4s}, [\tmp] 390 add \tmp, \rk, \rounds, lsl #4 391 sub \tmp, \tmp, #32 392 ld1 {KK.4s-KM.4s}, [\tmp] 393 .endm 394 395 .macro enc_round, state, key 396 aese \state\().16b, \key\().16b 397 aesmc \state\().16b, \state\().16b 398 .endm 399 400 .macro enc_qround, s0, s1, s2, s3, key 401 enc_round \s0, \key 402 enc_round \s1, \key 403 enc_round \s2, \key 404 enc_round \s3, \key 405 .endm 406 407 .macro enc_block, state, rounds, rk, tmp 408 add \tmp, \rk, #96 409 ld1 {K6.4s-K7.4s}, [\tmp], #32 410 .irp key, K0, K1, K2, K3, K4 K5 411 enc_round \state, \key 412 .endr 413 414 tbnz \rounds, #2, .Lnot128_\@ 415 .Lout256_\@: 416 enc_round \state, K6 417 enc_round \state, K7 418 419 .Lout192_\@: 420 enc_round \state, KK 421 aese \state\().16b, KL.16b 422 eor \state\().16b, \state\().16b, KM.16b 423 424 .subsection 1 425 .Lnot128_\@: 426 ld1 {K8.4s-K9.4s}, [\tmp], #32 427 enc_round \state, K6 428 enc_round \state, K7 429 ld1 {K6.4s-K7.4s}, [\tmp] 430 enc_round \state, K8 431 enc_round \state, K9 432 tbz \rounds, #1, .Lout192_\@ 433 b .Lout256_\@ 434 .previous 435 .endm 436 437 .align 6 438 .macro pmull_gcm_do_crypt, enc 439 frame_push 1 440 441 load_round_keys x7, x6, x8 442 443 ld1 {SHASH.2d}, [x3], #16 444 ld1 {HH.2d-HH4.2d}, [x3] 445 446 trn1 SHASH2.2d, SHASH.2d, HH.2d 447 trn2 T1.2d, SHASH.2d, HH.2d 448 eor SHASH2.16b, SHASH2.16b, T1.16b 449 450 trn1 HH34.2d, HH3.2d, HH4.2d 451 trn2 T1.2d, HH3.2d, HH4.2d 452 eor HH34.16b, HH34.16b, T1.16b 453 454 ld1 {XL.2d}, [x4] 455 456 cbz x0, 3f // tag only? 457 458 ldr w8, [x5, #12] // load lower counter 459 CPU_LE( rev w8, w8 ) 460 461 0: mov w9, #4 // max blocks per round 462 add x10, x0, #0xf 463 lsr x10, x10, #4 // remaining blocks 464 465 subs x0, x0, #64 466 csel w9, w10, w9, mi 467 add w8, w8, w9 468 469 bmi 1f 470 ld1 {INP0.16b-INP3.16b}, [x2], #64 471 .subsection 1 472 /* 473 * Populate the four input registers right to left with up to 63 bytes 474 * of data, using overlapping loads to avoid branches. 475 * 476 * INP0 INP1 INP2 INP3 477 * 1 byte | | | |x | 478 * 16 bytes | | | |xxxxxxxx| 479 * 17 bytes | | |xxxxxxxx|x | 480 * 47 bytes | |xxxxxxxx|xxxxxxxx|xxxxxxx | 481 * etc etc 482 * 483 * Note that this code may read up to 15 bytes before the start of 484 * the input. It is up to the calling code to ensure this is safe if 485 * this happens in the first iteration of the loop (i.e., when the 486 * input size is < 16 bytes) 487 */ 488 1: mov x15, #16 489 ands x19, x0, #0xf 490 csel x19, x19, x15, ne 491 adr_l x17, .Lpermute_table + 16 492 493 sub x11, x15, x19 494 add x12, x17, x11 495 sub x17, x17, x11 496 ld1 {T1.16b}, [x12] 497 sub x10, x1, x11 498 sub x11, x2, x11 499 500 cmp x0, #-16 501 csel x14, x15, xzr, gt 502 cmp x0, #-32 503 csel x15, x15, xzr, gt 504 cmp x0, #-48 505 csel x16, x19, xzr, gt 506 csel x1, x1, x10, gt 507 csel x2, x2, x11, gt 508 509 ld1 {INP0.16b}, [x2], x14 510 ld1 {INP1.16b}, [x2], x15 511 ld1 {INP2.16b}, [x2], x16 512 ld1 {INP3.16b}, [x2] 513 tbl INP3.16b, {INP3.16b}, T1.16b 514 b 2f 515 .previous 516 517 2: .if \enc == 0 518 bl pmull_gcm_ghash_4x 519 .endif 520 521 bl pmull_gcm_enc_4x 522 523 tbnz x0, #63, 6f 524 st1 {INP0.16b-INP3.16b}, [x1], #64 525 .if \enc == 1 526 bl pmull_gcm_ghash_4x 527 .endif 528 bne 0b 529 530 3: ldr x10, [sp, #.Lframe_local_offset] 531 cbz x10, 5f // output tag? 532 533 ld1 {INP3.16b}, [x10] // load lengths[] 534 mov w9, #1 535 bl pmull_gcm_ghash_4x 536 537 mov w11, #(0x1 << 24) // BE '1U' 538 ld1 {KS0.16b}, [x5] 539 mov KS0.s[3], w11 540 541 enc_block KS0, x7, x6, x12 542 543 ext XL.16b, XL.16b, XL.16b, #8 544 rev64 XL.16b, XL.16b 545 eor XL.16b, XL.16b, KS0.16b 546 547 .if \enc == 1 548 st1 {XL.16b}, [x10] // store tag 549 .else 550 ldp x11, x12, [sp, #40] // load tag pointer and authsize 551 adr_l x17, .Lpermute_table 552 ld1 {KS0.16b}, [x11] // load supplied tag 553 add x17, x17, x12 554 ld1 {KS1.16b}, [x17] // load permute vector 555 556 cmeq XL.16b, XL.16b, KS0.16b // compare tags 557 mvn XL.16b, XL.16b // -1 for fail, 0 for pass 558 tbl XL.16b, {XL.16b}, KS1.16b // keep authsize bytes only 559 sminv b0, XL.16b // signed minimum across XL 560 smov w0, v0.b[0] // return b0 561 .endif 562 563 4: frame_pop 564 ret 565 566 5: 567 CPU_LE( rev w8, w8 ) 568 str w8, [x5, #12] // store lower counter 569 st1 {XL.2d}, [x4] 570 b 4b 571 572 6: ld1 {T1.16b-T2.16b}, [x17], #32 // permute vectors 573 sub x17, x17, x19, lsl #1 574 575 cmp w9, #1 576 beq 7f 577 .subsection 1 578 7: ld1 {INP2.16b}, [x1] 579 tbx INP2.16b, {INP3.16b}, T1.16b 580 mov INP3.16b, INP2.16b 581 b 8f 582 .previous 583 584 st1 {INP0.16b}, [x1], x14 585 st1 {INP1.16b}, [x1], x15 586 st1 {INP2.16b}, [x1], x16 587 tbl INP3.16b, {INP3.16b}, T1.16b 588 tbx INP3.16b, {INP2.16b}, T2.16b 589 8: st1 {INP3.16b}, [x1] 590 591 .if \enc == 1 592 ld1 {T1.16b}, [x17] 593 tbl INP3.16b, {INP3.16b}, T1.16b // clear non-data bits 594 bl pmull_gcm_ghash_4x 595 .endif 596 b 3b 597 .endm 598 599 /* 600 * void pmull_gcm_encrypt(int blocks, u8 dst[], const u8 src[], 601 * struct ghash_key const *k, u64 dg[], u8 ctr[], 602 * int rounds, u8 tag) 603 */ 604 SYM_FUNC_START(pmull_gcm_encrypt) 605 pmull_gcm_do_crypt 1 606 SYM_FUNC_END(pmull_gcm_encrypt) 607 608 /* 609 * void pmull_gcm_decrypt(int blocks, u8 dst[], const u8 src[], 610 * struct ghash_key const *k, u64 dg[], u8 ctr[], 611 * int rounds, u8 tag) 612 */ 613 SYM_FUNC_START(pmull_gcm_decrypt) 614 pmull_gcm_do_crypt 0 615 SYM_FUNC_END(pmull_gcm_decrypt) 616 617 SYM_FUNC_START_LOCAL(pmull_gcm_ghash_4x) 618 movi MASK.16b, #0xe1 619 shl MASK.2d, MASK.2d, #57 620 621 rev64 T1.16b, INP0.16b 622 rev64 T2.16b, INP1.16b 623 rev64 TT3.16b, INP2.16b 624 rev64 TT4.16b, INP3.16b 625 626 ext XL.16b, XL.16b, XL.16b, #8 627 628 tbz w9, #2, 0f // <4 blocks? 629 .subsection 1 630 0: movi XH2.16b, #0 631 movi XM2.16b, #0 632 movi XL2.16b, #0 633 634 tbz w9, #0, 1f // 2 blocks? 635 tbz w9, #1, 2f // 1 block? 636 637 eor T2.16b, T2.16b, XL.16b 638 ext T1.16b, T2.16b, T2.16b, #8 639 b .Lgh3 640 641 1: eor TT3.16b, TT3.16b, XL.16b 642 ext T2.16b, TT3.16b, TT3.16b, #8 643 b .Lgh2 644 645 2: eor TT4.16b, TT4.16b, XL.16b 646 ext IN1.16b, TT4.16b, TT4.16b, #8 647 b .Lgh1 648 .previous 649 650 eor T1.16b, T1.16b, XL.16b 651 ext IN1.16b, T1.16b, T1.16b, #8 652 653 pmull2 XH2.1q, HH4.2d, IN1.2d // a1 * b1 654 eor T1.16b, T1.16b, IN1.16b 655 pmull XL2.1q, HH4.1d, IN1.1d // a0 * b0 656 pmull2 XM2.1q, HH34.2d, T1.2d // (a1 + a0)(b1 + b0) 657 658 ext T1.16b, T2.16b, T2.16b, #8 659 .Lgh3: eor T2.16b, T2.16b, T1.16b 660 pmull2 XH.1q, HH3.2d, T1.2d // a1 * b1 661 pmull XL.1q, HH3.1d, T1.1d // a0 * b0 662 pmull XM.1q, HH34.1d, T2.1d // (a1 + a0)(b1 + b0) 663 664 eor XH2.16b, XH2.16b, XH.16b 665 eor XL2.16b, XL2.16b, XL.16b 666 eor XM2.16b, XM2.16b, XM.16b 667 668 ext T2.16b, TT3.16b, TT3.16b, #8 669 .Lgh2: eor TT3.16b, TT3.16b, T2.16b 670 pmull2 XH.1q, HH.2d, T2.2d // a1 * b1 671 pmull XL.1q, HH.1d, T2.1d // a0 * b0 672 pmull2 XM.1q, SHASH2.2d, TT3.2d // (a1 + a0)(b1 + b0) 673 674 eor XH2.16b, XH2.16b, XH.16b 675 eor XL2.16b, XL2.16b, XL.16b 676 eor XM2.16b, XM2.16b, XM.16b 677 678 ext IN1.16b, TT4.16b, TT4.16b, #8 679 .Lgh1: eor TT4.16b, TT4.16b, IN1.16b 680 pmull XL.1q, SHASH.1d, IN1.1d // a0 * b0 681 pmull2 XH.1q, SHASH.2d, IN1.2d // a1 * b1 682 pmull XM.1q, SHASH2.1d, TT4.1d // (a1 + a0)(b1 + b0) 683 684 eor XH.16b, XH.16b, XH2.16b 685 eor XL.16b, XL.16b, XL2.16b 686 eor XM.16b, XM.16b, XM2.16b 687 688 eor T2.16b, XL.16b, XH.16b 689 ext T1.16b, XL.16b, XH.16b, #8 690 eor XM.16b, XM.16b, T2.16b 691 692 __pmull_reduce_p64 693 694 eor T2.16b, T2.16b, XH.16b 695 eor XL.16b, XL.16b, T2.16b 696 697 ret 698 SYM_FUNC_END(pmull_gcm_ghash_4x) 699 700 SYM_FUNC_START_LOCAL(pmull_gcm_enc_4x) 701 ld1 {KS0.16b}, [x5] // load upper counter 702 sub w10, w8, #4 703 sub w11, w8, #3 704 sub w12, w8, #2 705 sub w13, w8, #1 706 rev w10, w10 707 rev w11, w11 708 rev w12, w12 709 rev w13, w13 710 mov KS1.16b, KS0.16b 711 mov KS2.16b, KS0.16b 712 mov KS3.16b, KS0.16b 713 ins KS0.s[3], w10 // set lower counter 714 ins KS1.s[3], w11 715 ins KS2.s[3], w12 716 ins KS3.s[3], w13 717 718 add x10, x6, #96 // round key pointer 719 ld1 {K6.4s-K7.4s}, [x10], #32 720 .irp key, K0, K1, K2, K3, K4, K5 721 enc_qround KS0, KS1, KS2, KS3, \key 722 .endr 723 724 tbnz x7, #2, .Lnot128 725 .subsection 1 726 .Lnot128: 727 ld1 {K8.4s-K9.4s}, [x10], #32 728 .irp key, K6, K7 729 enc_qround KS0, KS1, KS2, KS3, \key 730 .endr 731 ld1 {K6.4s-K7.4s}, [x10] 732 .irp key, K8, K9 733 enc_qround KS0, KS1, KS2, KS3, \key 734 .endr 735 tbz x7, #1, .Lout192 736 b .Lout256 737 .previous 738 739 .Lout256: 740 .irp key, K6, K7 741 enc_qround KS0, KS1, KS2, KS3, \key 742 .endr 743 744 .Lout192: 745 enc_qround KS0, KS1, KS2, KS3, KK 746 747 aese KS0.16b, KL.16b 748 aese KS1.16b, KL.16b 749 aese KS2.16b, KL.16b 750 aese KS3.16b, KL.16b 751 752 eor KS0.16b, KS0.16b, KM.16b 753 eor KS1.16b, KS1.16b, KM.16b 754 eor KS2.16b, KS2.16b, KM.16b 755 eor KS3.16b, KS3.16b, KM.16b 756 757 eor INP0.16b, INP0.16b, KS0.16b 758 eor INP1.16b, INP1.16b, KS1.16b 759 eor INP2.16b, INP2.16b, KS2.16b 760 eor INP3.16b, INP3.16b, KS3.16b 761 762 ret 763 SYM_FUNC_END(pmull_gcm_enc_4x) 764 765 .section ".rodata", "a" 766 .align 6 767 .Lpermute_table: 768 .byte 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff 769 .byte 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff 770 .byte 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7 771 .byte 0x8, 0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf 772 .byte 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff 773 .byte 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff 774 .byte 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7 775 .byte 0x8, 0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf 776 .previous
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.