1/* SPDX-License-Identifier: GPL-2.0-only */ 2/* 3 * Bit sliced AES using NEON instructions 4 * 5 * Copyright (C) 2017 Linaro Ltd. 6 * Author: Ard Biesheuvel <ard.biesheuvel@linaro.org> 7 */ 8 9/* 10 * The algorithm implemented here is described in detail by the paper 11 * 'Faster and Timing-Attack Resistant AES-GCM' by Emilia Kaesper and 12 * Peter Schwabe (https://eprint.iacr.org/2009/129.pdf) 13 * 14 * This implementation is based primarily on the OpenSSL implementation 15 * for 32-bit ARM written by Andy Polyakov <appro@openssl.org> 16 */ 17 18#include <linux/linkage.h> 19#include <asm/assembler.h> 20 21 .text 22 .fpu neon 23 24 rounds .req ip 25 bskey .req r4 26 27 q0l .req d0 28 q0h .req d1 29 q1l .req d2 30 q1h .req d3 31 q2l .req d4 32 q2h .req d5 33 q3l .req d6 34 q3h .req d7 35 q4l .req d8 36 q4h .req d9 37 q5l .req d10 38 q5h .req d11 39 q6l .req d12 40 q6h .req d13 41 q7l .req d14 42 q7h .req d15 43 q8l .req d16 44 q8h .req d17 45 q9l .req d18 46 q9h .req d19 47 q10l .req d20 48 q10h .req d21 49 q11l .req d22 50 q11h .req d23 51 q12l .req d24 52 q12h .req d25 53 q13l .req d26 54 q13h .req d27 55 q14l .req d28 56 q14h .req d29 57 q15l .req d30 58 q15h .req d31 59 60 .macro __tbl, out, tbl, in, tmp 61 .ifc \out, \tbl 62 .ifb \tmp 63 .error __tbl needs temp register if out == tbl 64 .endif 65 vmov \tmp, \out 66 .endif 67 vtbl.8 \out\()l, {\tbl}, \in\()l 68 .ifc \out, \tbl 69 vtbl.8 \out\()h, {\tmp}, \in\()h 70 .else 71 vtbl.8 \out\()h, {\tbl}, \in\()h 72 .endif 73 .endm 74 75 .macro __ldr, out, sym 76 vldr \out\()l, \sym 77 vldr \out\()h, \sym + 8 78 .endm 79 80 .macro in_bs_ch, b0, b1, b2, b3, b4, b5, b6, b7 81 veor \b2, \b2, \b1 82 veor \b5, \b5, \b6 83 veor \b3, \b3, \b0 84 veor \b6, \b6, \b2 85 veor \b5, \b5, \b0 86 veor \b6, \b6, \b3 87 veor \b3, \b3, \b7 88 veor \b7, \b7, \b5 89 veor \b3, \b3, \b4 90 veor \b4, \b4, \b5 91 veor \b2, \b2, \b7 92 veor \b3, \b3, \b1 93 veor \b1, \b1, \b5 94 .endm 95 96 .macro out_bs_ch, b0, b1, b2, b3, b4, b5, b6, b7 97 veor \b0, \b0, \b6 98 veor \b1, \b1, \b4 99 veor \b4, \b4, \b6 100 veor \b2, \b2, \b0 101 veor \b6, \b6, \b1 102 veor \b1, \b1, \b5 103 veor \b5, \b5, \b3 104 veor \b3, \b3, \b7 105 veor \b7, \b7, \b5 106 veor \b2, \b2, \b5 107 veor \b4, \b4, \b7 108 .endm 109 110 .macro inv_in_bs_ch, b6, b1, b2, b4, b7, b0, b3, b5 111 veor \b1, \b1, \b7 112 veor \b4, \b4, \b7 113 veor \b7, \b7, \b5 114 veor \b1, \b1, \b3 115 veor \b2, \b2, \b5 116 veor \b3, \b3, \b7 117 veor \b6, \b6, \b1 118 veor \b2, \b2, \b0 119 veor \b5, \b5, \b3 120 veor \b4, \b4, \b6 121 veor \b0, \b0, \b6 122 veor \b1, \b1, \b4 123 .endm 124 125 .macro inv_out_bs_ch, b6, b5, b0, b3, b7, b1, b4, b2 126 veor \b1, \b1, \b5 127 veor \b2, \b2, \b7 128 veor \b3, \b3, \b1 129 veor \b4, \b4, \b5 130 veor \b7, \b7, \b5 131 veor \b3, \b3, \b4 132 veor \b5, \b5, \b0 133 veor \b3, \b3, \b7 134 veor \b6, \b6, \b2 135 veor \b2, \b2, \b1 136 veor \b6, \b6, \b3 137 veor \b3, \b3, \b0 138 veor \b5, \b5, \b6 139 .endm 140 141 .macro mul_gf4, x0, x1, y0, y1, t0, t1 142 veor \t0, \y0, \y1 143 vand \t0, \t0, \x0 144 veor \x0, \x0, \x1 145 vand \t1, \x1, \y0 146 vand \x0, \x0, \y1 147 veor \x1, \t1, \t0 148 veor \x0, \x0, \t1 149 .endm 150 151 .macro mul_gf4_n_gf4, x0, x1, y0, y1, t0, x2, x3, y2, y3, t1 152 veor \t0, \y0, \y1 153 veor \t1, \y2, \y3 154 vand \t0, \t0, \x0 155 vand \t1, \t1, \x2 156 veor \x0, \x0, \x1 157 veor \x2, \x2, \x3 158 vand \x1, \x1, \y0 159 vand \x3, \x3, \y2 160 vand \x0, \x0, \y1 161 vand \x2, \x2, \y3 162 veor \x1, \x1, \x0 163 veor \x2, \x2, \x3 164 veor \x0, \x0, \t0 165 veor \x3, \x3, \t1 166 .endm 167 168 .macro mul_gf16_2, x0, x1, x2, x3, x4, x5, x6, x7, \ 169 y0, y1, y2, y3, t0, t1, t2, t3 170 veor \t0, \x0, \x2 171 veor \t1, \x1, \x3 172 mul_gf4 \x0, \x1, \y0, \y1, \t2, \t3 173 veor \y0, \y0, \y2 174 veor \y1, \y1, \y3 175 mul_gf4_n_gf4 \t0, \t1, \y0, \y1, \t3, \x2, \x3, \y2, \y3, \t2 176 veor \x0, \x0, \t0 177 veor \x2, \x2, \t0 178 veor \x1, \x1, \t1 179 veor \x3, \x3, \t1 180 veor \t0, \x4, \x6 181 veor \t1, \x5, \x7 182 mul_gf4_n_gf4 \t0, \t1, \y0, \y1, \t3, \x6, \x7, \y2, \y3, \t2 183 veor \y0, \y0, \y2 184 veor \y1, \y1, \y3 185 mul_gf4 \x4, \x5, \y0, \y1, \t2, \t3 186 veor \x4, \x4, \t0 187 veor \x6, \x6, \t0 188 veor \x5, \x5, \t1 189 veor \x7, \x7, \t1 190 .endm 191 192 .macro inv_gf256, x0, x1, x2, x3, x4, x5, x6, x7, \ 193 t0, t1, t2, t3, s0, s1, s2, s3 194 veor \t3, \x4, \x6 195 veor \t0, \x5, \x7 196 veor \t1, \x1, \x3 197 veor \s1, \x7, \x6 198 veor \s0, \x0, \x2 199 veor \s3, \t3, \t0 200 vorr \t2, \t0, \t1 201 vand \s2, \t3, \s0 202 vorr \t3, \t3, \s0 203 veor \s0, \s0, \t1 204 vand \t0, \t0, \t1 205 veor \t1, \x3, \x2 206 vand \s3, \s3, \s0 207 vand \s1, \s1, \t1 208 veor \t1, \x4, \x5 209 veor \s0, \x1, \x0 210 veor \t3, \t3, \s1 211 veor \t2, \t2, \s1 212 vand \s1, \t1, \s0 213 vorr \t1, \t1, \s0 214 veor \t3, \t3, \s3 215 veor \t0, \t0, \s1 216 veor \t2, \t2, \s2 217 veor \t1, \t1, \s3 218 veor \t0, \t0, \s2 219 vand \s0, \x7, \x3 220 veor \t1, \t1, \s2 221 vand \s1, \x6, \x2 222 vand \s2, \x5, \x1 223 vorr \s3, \x4, \x0 224 veor \t3, \t3, \s0 225 veor \t1, \t1, \s2 226 veor \s0, \t0, \s3 227 veor \t2, \t2, \s1 228 vand \s2, \t3, \t1 229 veor \s1, \t2, \s2 230 veor \s3, \s0, \s2 231 vbsl \s1, \t1, \s0 232 vmvn \t0, \s0 233 vbsl \s0, \s1, \s3 234 vbsl \t0, \s1, \s3 235 vbsl \s3, \t3, \t2 236 veor \t3, \t3, \t2 237 vand \s2, \s0, \s3 238 veor \t1, \t1, \t0 239 veor \s2, \s2, \t3 240 mul_gf16_2 \x0, \x1, \x2, \x3, \x4, \x5, \x6, \x7, \ 241 \s3, \s2, \s1, \t1, \s0, \t0, \t2, \t3 242 .endm 243 244 .macro sbox, b0, b1, b2, b3, b4, b5, b6, b7, \ 245 t0, t1, t2, t3, s0, s1, s2, s3 246 in_bs_ch \b0, \b1, \b2, \b3, \b4, \b5, \b6, \b7 247 inv_gf256 \b6, \b5, \b0, \b3, \b7, \b1, \b4, \b2, \ 248 \t0, \t1, \t2, \t3, \s0, \s1, \s2, \s3 249 out_bs_ch \b7, \b1, \b4, \b2, \b6, \b5, \b0, \b3 250 .endm 251 252 .macro inv_sbox, b0, b1, b2, b3, b4, b5, b6, b7, \ 253 t0, t1, t2, t3, s0, s1, s2, s3 254 inv_in_bs_ch \b0, \b1, \b2, \b3, \b4, \b5, \b6, \b7 255 inv_gf256 \b5, \b1, \b2, \b6, \b3, \b7, \b0, \b4, \ 256 \t0, \t1, \t2, \t3, \s0, \s1, \s2, \s3 257 inv_out_bs_ch \b3, \b7, \b0, \b4, \b5, \b1, \b2, \b6 258 .endm 259 260 .macro shift_rows, x0, x1, x2, x3, x4, x5, x6, x7, \ 261 t0, t1, t2, t3, mask 262 vld1.8 {\t0-\t1}, [bskey, :256]! 263 veor \t0, \t0, \x0 264 vld1.8 {\t2-\t3}, [bskey, :256]! 265 veor \t1, \t1, \x1 266 __tbl \x0, \t0, \mask 267 veor \t2, \t2, \x2 268 __tbl \x1, \t1, \mask 269 vld1.8 {\t0-\t1}, [bskey, :256]! 270 veor \t3, \t3, \x3 271 __tbl \x2, \t2, \mask 272 __tbl \x3, \t3, \mask 273 vld1.8 {\t2-\t3}, [bskey, :256]! 274 veor \t0, \t0, \x4 275 veor \t1, \t1, \x5 276 __tbl \x4, \t0, \mask 277 veor \t2, \t2, \x6 278 __tbl \x5, \t1, \mask 279 veor \t3, \t3, \x7 280 __tbl \x6, \t2, \mask 281 __tbl \x7, \t3, \mask 282 .endm 283 284 .macro inv_shift_rows, x0, x1, x2, x3, x4, x5, x6, x7, \ 285 t0, t1, t2, t3, mask 286 __tbl \x0, \x0, \mask, \t0 287 __tbl \x1, \x1, \mask, \t1 288 __tbl \x2, \x2, \mask, \t2 289 __tbl \x3, \x3, \mask, \t3 290 __tbl \x4, \x4, \mask, \t0 291 __tbl \x5, \x5, \mask, \t1 292 __tbl \x6, \x6, \mask, \t2 293 __tbl \x7, \x7, \mask, \t3 294 .endm 295 296 .macro mix_cols, x0, x1, x2, x3, x4, x5, x6, x7, \ 297 t0, t1, t2, t3, t4, t5, t6, t7, inv 298 vext.8 \t0, \x0, \x0, #12 299 vext.8 \t1, \x1, \x1, #12 300 veor \x0, \x0, \t0 301 vext.8 \t2, \x2, \x2, #12 302 veor \x1, \x1, \t1 303 vext.8 \t3, \x3, \x3, #12 304 veor \x2, \x2, \t2 305 vext.8 \t4, \x4, \x4, #12 306 veor \x3, \x3, \t3 307 vext.8 \t5, \x5, \x5, #12 308 veor \x4, \x4, \t4 309 vext.8 \t6, \x6, \x6, #12 310 veor \x5, \x5, \t5 311 vext.8 \t7, \x7, \x7, #12 312 veor \x6, \x6, \t6 313 veor \t1, \t1, \x0 314 veor.8 \x7, \x7, \t7 315 vext.8 \x0, \x0, \x0, #8 316 veor \t2, \t2, \x1 317 veor \t0, \t0, \x7 318 veor \t1, \t1, \x7 319 vext.8 \x1, \x1, \x1, #8 320 veor \t5, \t5, \x4 321 veor \x0, \x0, \t0 322 veor \t6, \t6, \x5 323 veor \x1, \x1, \t1 324 vext.8 \t0, \x4, \x4, #8 325 veor \t4, \t4, \x3 326 vext.8 \t1, \x5, \x5, #8 327 veor \t7, \t7, \x6 328 vext.8 \x4, \x3, \x3, #8 329 veor \t3, \t3, \x2 330 vext.8 \x5, \x7, \x7, #8 331 veor \t4, \t4, \x7 332 vext.8 \x3, \x6, \x6, #8 333 veor \t3, \t3, \x7 334 vext.8 \x6, \x2, \x2, #8 335 veor \x7, \t1, \t5 336 .ifb \inv 337 veor \x2, \t0, \t4 338 veor \x4, \x4, \t3 339 veor \x5, \x5, \t7 340 veor \x3, \x3, \t6 341 veor \x6, \x6, \t2 342 .else 343 veor \t3, \t3, \x4 344 veor \x5, \x5, \t7 345 veor \x2, \x3, \t6 346 veor \x3, \t0, \t4 347 veor \x4, \x6, \t2 348 vmov \x6, \t3 349 .endif 350 .endm 351 352 .macro inv_mix_cols, x0, x1, x2, x3, x4, x5, x6, x7, \ 353 t0, t1, t2, t3, t4, t5, t6, t7 354 vld1.8 {\t0-\t1}, [bskey, :256]! 355 veor \x0, \x0, \t0 356 vld1.8 {\t2-\t3}, [bskey, :256]! 357 veor \x1, \x1, \t1 358 vld1.8 {\t4-\t5}, [bskey, :256]! 359 veor \x2, \x2, \t2 360 vld1.8 {\t6-\t7}, [bskey, :256] 361 sub bskey, bskey, #224 362 veor \x3, \x3, \t3 363 veor \x4, \x4, \t4 364 veor \x5, \x5, \t5 365 veor \x6, \x6, \t6 366 veor \x7, \x7, \t7 367 vext.8 \t0, \x0, \x0, #8 368 vext.8 \t6, \x6, \x6, #8 369 vext.8 \t7, \x7, \x7, #8 370 veor \t0, \t0, \x0 371 vext.8 \t1, \x1, \x1, #8 372 veor \t6, \t6, \x6 373 vext.8 \t2, \x2, \x2, #8 374 veor \t7, \t7, \x7 375 vext.8 \t3, \x3, \x3, #8 376 veor \t1, \t1, \x1 377 vext.8 \t4, \x4, \x4, #8 378 veor \t2, \t2, \x2 379 vext.8 \t5, \x5, \x5, #8 380 veor \t3, \t3, \x3 381 veor \t4, \t4, \x4 382 veor \t5, \t5, \x5 383 veor \x0, \x0, \t6 384 veor \x1, \x1, \t6 385 veor \x2, \x2, \t0 386 veor \x4, \x4, \t2 387 veor \x3, \x3, \t1 388 veor \x1, \x1, \t7 389 veor \x2, \x2, \t7 390 veor \x4, \x4, \t6 391 veor \x5, \x5, \t3 392 veor \x3, \x3, \t6 393 veor \x6, \x6, \t4 394 veor \x4, \x4, \t7 395 veor \x5, \x5, \t7 396 veor \x7, \x7, \t5 397 mix_cols \x0, \x1, \x2, \x3, \x4, \x5, \x6, \x7, \ 398 \t0, \t1, \t2, \t3, \t4, \t5, \t6, \t7, 1 399 .endm 400 401 .macro swapmove_2x, a0, b0, a1, b1, n, mask, t0, t1 402 vshr.u64 \t0, \b0, #\n 403 vshr.u64 \t1, \b1, #\n 404 veor \t0, \t0, \a0 405 veor \t1, \t1, \a1 406 vand \t0, \t0, \mask 407 vand \t1, \t1, \mask 408 veor \a0, \a0, \t0 409 vshl.s64 \t0, \t0, #\n 410 veor \a1, \a1, \t1 411 vshl.s64 \t1, \t1, #\n 412 veor \b0, \b0, \t0 413 veor \b1, \b1, \t1 414 .endm 415 416 .macro bitslice, x7, x6, x5, x4, x3, x2, x1, x0, t0, t1, t2, t3 417 vmov.i8 \t0, #0x55 418 vmov.i8 \t1, #0x33 419 swapmove_2x \x0, \x1, \x2, \x3, 1, \t0, \t2, \t3 420 swapmove_2x \x4, \x5, \x6, \x7, 1, \t0, \t2, \t3 421 vmov.i8 \t0, #0x0f 422 swapmove_2x \x0, \x2, \x1, \x3, 2, \t1, \t2, \t3 423 swapmove_2x \x4, \x6, \x5, \x7, 2, \t1, \t2, \t3 424 swapmove_2x \x0, \x4, \x1, \x5, 4, \t0, \t2, \t3 425 swapmove_2x \x2, \x6, \x3, \x7, 4, \t0, \t2, \t3 426 .endm 427 428 .align 4 429M0: .quad 0x02060a0e03070b0f, 0x0004080c0105090d 430 431 /* 432 * void aesbs_convert_key(u8 out[], u32 const rk[], int rounds) 433 */ 434ENTRY(aesbs_convert_key) 435 vld1.32 {q7}, [r1]! // load round 0 key 436 vld1.32 {q15}, [r1]! // load round 1 key 437 438 vmov.i8 q8, #0x01 // bit masks 439 vmov.i8 q9, #0x02 440 vmov.i8 q10, #0x04 441 vmov.i8 q11, #0x08 442 vmov.i8 q12, #0x10 443 vmov.i8 q13, #0x20 444 __ldr q14, M0 445 446 sub r2, r2, #1 447 vst1.8 {q7}, [r0, :128]! // save round 0 key 448 449.Lkey_loop: 450 __tbl q7, q15, q14 451 vmov.i8 q6, #0x40 452 vmov.i8 q15, #0x80 453 454 vtst.8 q0, q7, q8 455 vtst.8 q1, q7, q9 456 vtst.8 q2, q7, q10 457 vtst.8 q3, q7, q11 458 vtst.8 q4, q7, q12 459 vtst.8 q5, q7, q13 460 vtst.8 q6, q7, q6 461 vtst.8 q7, q7, q15 462 vld1.32 {q15}, [r1]! // load next round key 463 vmvn q0, q0 464 vmvn q1, q1 465 vmvn q5, q5 466 vmvn q6, q6 467 468 subs r2, r2, #1 469 vst1.8 {q0-q1}, [r0, :256]! 470 vst1.8 {q2-q3}, [r0, :256]! 471 vst1.8 {q4-q5}, [r0, :256]! 472 vst1.8 {q6-q7}, [r0, :256]! 473 bne .Lkey_loop 474 475 vmov.i8 q7, #0x63 // compose .L63 476 veor q15, q15, q7 477 vst1.8 {q15}, [r0, :128] 478 bx lr 479ENDPROC(aesbs_convert_key) 480 481 .align 4 482M0SR: .quad 0x0a0e02060f03070b, 0x0004080c05090d01 483 484aesbs_encrypt8: 485 vld1.8 {q9}, [bskey, :128]! // round 0 key 486 __ldr q8, M0SR 487 488 veor q10, q0, q9 // xor with round0 key 489 veor q11, q1, q9 490 __tbl q0, q10, q8 491 veor q12, q2, q9 492 __tbl q1, q11, q8 493 veor q13, q3, q9 494 __tbl q2, q12, q8 495 veor q14, q4, q9 496 __tbl q3, q13, q8 497 veor q15, q5, q9 498 __tbl q4, q14, q8 499 veor q10, q6, q9 500 __tbl q5, q15, q8 501 veor q11, q7, q9 502 __tbl q6, q10, q8 503 __tbl q7, q11, q8 504 505 bitslice q0, q1, q2, q3, q4, q5, q6, q7, q8, q9, q10, q11 506 507 sub rounds, rounds, #1 508 b .Lenc_sbox 509 510 .align 5 511SR: .quad 0x0504070600030201, 0x0f0e0d0c0a09080b 512SRM0: .quad 0x0304090e00050a0f, 0x01060b0c0207080d 513 514.Lenc_last: 515 __ldr q12, SRM0 516.Lenc_loop: 517 shift_rows q0, q1, q2, q3, q4, q5, q6, q7, q8, q9, q10, q11, q12 518.Lenc_sbox: 519 sbox q0, q1, q2, q3, q4, q5, q6, q7, q8, q9, q10, q11, q12, \ 520 q13, q14, q15 521 subs rounds, rounds, #1 522 bcc .Lenc_done 523 524 mix_cols q0, q1, q4, q6, q3, q7, q2, q5, q8, q9, q10, q11, q12, \ 525 q13, q14, q15 526 527 beq .Lenc_last 528 __ldr q12, SR 529 b .Lenc_loop 530 531.Lenc_done: 532 vld1.8 {q12}, [bskey, :128] // last round key 533 534 bitslice q0, q1, q4, q6, q3, q7, q2, q5, q8, q9, q10, q11 535 536 veor q0, q0, q12 537 veor q1, q1, q12 538 veor q4, q4, q12 539 veor q6, q6, q12 540 veor q3, q3, q12 541 veor q7, q7, q12 542 veor q2, q2, q12 543 veor q5, q5, q12 544 bx lr 545ENDPROC(aesbs_encrypt8) 546 547 .align 4 548M0ISR: .quad 0x0a0e0206070b0f03, 0x0004080c0d010509 549 550aesbs_decrypt8: 551 add bskey, bskey, rounds, lsl #7 552 sub bskey, bskey, #112 553 vld1.8 {q9}, [bskey, :128] // round 0 key 554 sub bskey, bskey, #128 555 __ldr q8, M0ISR 556 557 veor q10, q0, q9 // xor with round0 key 558 veor q11, q1, q9 559 __tbl q0, q10, q8 560 veor q12, q2, q9 561 __tbl q1, q11, q8 562 veor q13, q3, q9 563 __tbl q2, q12, q8 564 veor q14, q4, q9 565 __tbl q3, q13, q8 566 veor q15, q5, q9 567 __tbl q4, q14, q8 568 veor q10, q6, q9 569 __tbl q5, q15, q8 570 veor q11, q7, q9 571 __tbl q6, q10, q8 572 __tbl q7, q11, q8 573 574 bitslice q0, q1, q2, q3, q4, q5, q6, q7, q8, q9, q10, q11 575 576 sub rounds, rounds, #1 577 b .Ldec_sbox 578 579 .align 5 580ISR: .quad 0x0504070602010003, 0x0f0e0d0c080b0a09 581ISRM0: .quad 0x01040b0e0205080f, 0x0306090c00070a0d 582 583.Ldec_last: 584 __ldr q12, ISRM0 585.Ldec_loop: 586 inv_shift_rows q0, q1, q2, q3, q4, q5, q6, q7, q8, q9, q10, q11, q12 587.Ldec_sbox: 588 inv_sbox q0, q1, q2, q3, q4, q5, q6, q7, q8, q9, q10, q11, q12, \ 589 q13, q14, q15 590 subs rounds, rounds, #1 591 bcc .Ldec_done 592 593 inv_mix_cols q0, q1, q6, q4, q2, q7, q3, q5, q8, q9, q10, q11, q12, \ 594 q13, q14, q15 595 596 beq .Ldec_last 597 __ldr q12, ISR 598 b .Ldec_loop 599 600.Ldec_done: 601 add bskey, bskey, #112 602 vld1.8 {q12}, [bskey, :128] // last round key 603 604 bitslice q0, q1, q6, q4, q2, q7, q3, q5, q8, q9, q10, q11 605 606 veor q0, q0, q12 607 veor q1, q1, q12 608 veor q6, q6, q12 609 veor q4, q4, q12 610 veor q2, q2, q12 611 veor q7, q7, q12 612 veor q3, q3, q12 613 veor q5, q5, q12 614 bx lr 615ENDPROC(aesbs_decrypt8) 616 617 /* 618 * aesbs_ecb_encrypt(u8 out[], u8 const in[], u8 const rk[], int rounds, 619 * int blocks) 620 * aesbs_ecb_decrypt(u8 out[], u8 const in[], u8 const rk[], int rounds, 621 * int blocks) 622 */ 623 .macro __ecb_crypt, do8, o0, o1, o2, o3, o4, o5, o6, o7 624 push {r4-r6, lr} 625 ldr r5, [sp, #16] // number of blocks 626 62799: adr ip, 0f 628 and lr, r5, #7 629 cmp r5, #8 630 sub ip, ip, lr, lsl #2 631 movlt pc, ip // computed goto if blocks < 8 632 633 vld1.8 {q0}, [r1]! 634 vld1.8 {q1}, [r1]! 635 vld1.8 {q2}, [r1]! 636 vld1.8 {q3}, [r1]! 637 vld1.8 {q4}, [r1]! 638 vld1.8 {q5}, [r1]! 639 vld1.8 {q6}, [r1]! 640 vld1.8 {q7}, [r1]! 641 6420: mov bskey, r2 643 mov rounds, r3 644 bl \do8 645 646 adr ip, 1f 647 and lr, r5, #7 648 cmp r5, #8 649 sub ip, ip, lr, lsl #2 650 movlt pc, ip // computed goto if blocks < 8 651 652 vst1.8 {\o0}, [r0]! 653 vst1.8 {\o1}, [r0]! 654 vst1.8 {\o2}, [r0]! 655 vst1.8 {\o3}, [r0]! 656 vst1.8 {\o4}, [r0]! 657 vst1.8 {\o5}, [r0]! 658 vst1.8 {\o6}, [r0]! 659 vst1.8 {\o7}, [r0]! 660 6611: subs r5, r5, #8 662 bgt 99b 663 664 pop {r4-r6, pc} 665 .endm 666 667 .align 4 668ENTRY(aesbs_ecb_encrypt) 669 __ecb_crypt aesbs_encrypt8, q0, q1, q4, q6, q3, q7, q2, q5 670ENDPROC(aesbs_ecb_encrypt) 671 672 .align 4 673ENTRY(aesbs_ecb_decrypt) 674 __ecb_crypt aesbs_decrypt8, q0, q1, q6, q4, q2, q7, q3, q5 675ENDPROC(aesbs_ecb_decrypt) 676 677 /* 678 * aesbs_cbc_decrypt(u8 out[], u8 const in[], u8 const rk[], 679 * int rounds, int blocks, u8 iv[]) 680 */ 681 .align 4 682ENTRY(aesbs_cbc_decrypt) 683 mov ip, sp 684 push {r4-r6, lr} 685 ldm ip, {r5-r6} // load args 4-5 686 68799: adr ip, 0f 688 and lr, r5, #7 689 cmp r5, #8 690 sub ip, ip, lr, lsl #2 691 mov lr, r1 692 movlt pc, ip // computed goto if blocks < 8 693 694 vld1.8 {q0}, [lr]! 695 vld1.8 {q1}, [lr]! 696 vld1.8 {q2}, [lr]! 697 vld1.8 {q3}, [lr]! 698 vld1.8 {q4}, [lr]! 699 vld1.8 {q5}, [lr]! 700 vld1.8 {q6}, [lr]! 701 vld1.8 {q7}, [lr] 702 7030: mov bskey, r2 704 mov rounds, r3 705 bl aesbs_decrypt8 706 707 vld1.8 {q8}, [r6] 708 vmov q9, q8 709 vmov q10, q8 710 vmov q11, q8 711 vmov q12, q8 712 vmov q13, q8 713 vmov q14, q8 714 vmov q15, q8 715 716 adr ip, 1f 717 and lr, r5, #7 718 cmp r5, #8 719 sub ip, ip, lr, lsl #2 720 movlt pc, ip // computed goto if blocks < 8 721 722 vld1.8 {q9}, [r1]! 723 vld1.8 {q10}, [r1]! 724 vld1.8 {q11}, [r1]! 725 vld1.8 {q12}, [r1]! 726 vld1.8 {q13}, [r1]! 727 vld1.8 {q14}, [r1]! 728 vld1.8 {q15}, [r1]! 729 W(nop) 730 7311: adr ip, 2f 732 sub ip, ip, lr, lsl #3 733 movlt pc, ip // computed goto if blocks < 8 734 735 veor q0, q0, q8 736 vst1.8 {q0}, [r0]! 737 veor q1, q1, q9 738 vst1.8 {q1}, [r0]! 739 veor q6, q6, q10 740 vst1.8 {q6}, [r0]! 741 veor q4, q4, q11 742 vst1.8 {q4}, [r0]! 743 veor q2, q2, q12 744 vst1.8 {q2}, [r0]! 745 veor q7, q7, q13 746 vst1.8 {q7}, [r0]! 747 veor q3, q3, q14 748 vst1.8 {q3}, [r0]! 749 veor q5, q5, q15 750 vld1.8 {q8}, [r1]! // load next round's iv 7512: vst1.8 {q5}, [r0]! 752 753 subs r5, r5, #8 754 vst1.8 {q8}, [r6] // store next round's iv 755 bgt 99b 756 757 pop {r4-r6, pc} 758ENDPROC(aesbs_cbc_decrypt) 759 760 .macro next_ctr, q 761 vmov.32 \q\()h[1], r10 762 adds r10, r10, #1 763 vmov.32 \q\()h[0], r9 764 adcs r9, r9, #0 765 vmov.32 \q\()l[1], r8 766 adcs r8, r8, #0 767 vmov.32 \q\()l[0], r7 768 adc r7, r7, #0 769 vrev32.8 \q, \q 770 .endm 771 772 /* 773 * aesbs_ctr_encrypt(u8 out[], u8 const in[], u8 const rk[], 774 * int rounds, int blocks, u8 ctr[], u8 final[]) 775 */ 776ENTRY(aesbs_ctr_encrypt) 777 mov ip, sp 778 push {r4-r10, lr} 779 780 ldm ip, {r5-r7} // load args 4-6 781 teq r7, #0 782 addne r5, r5, #1 // one extra block if final != 0 783 784 vld1.8 {q0}, [r6] // load counter 785 vrev32.8 q1, q0 786 vmov r9, r10, d3 787 vmov r7, r8, d2 788 789 adds r10, r10, #1 790 adcs r9, r9, #0 791 adcs r8, r8, #0 792 adc r7, r7, #0 793 79499: vmov q1, q0 795 vmov q2, q0 796 vmov q3, q0 797 vmov q4, q0 798 vmov q5, q0 799 vmov q6, q0 800 vmov q7, q0 801 802 adr ip, 0f 803 sub lr, r5, #1 804 and lr, lr, #7 805 cmp r5, #8 806 sub ip, ip, lr, lsl #5 807 sub ip, ip, lr, lsl #2 808 movlt pc, ip // computed goto if blocks < 8 809 810 next_ctr q1 811 next_ctr q2 812 next_ctr q3 813 next_ctr q4 814 next_ctr q5 815 next_ctr q6 816 next_ctr q7 817 8180: mov bskey, r2 819 mov rounds, r3 820 bl aesbs_encrypt8 821 822 adr ip, 1f 823 and lr, r5, #7 824 cmp r5, #8 825 movgt r4, #0 826 ldrle r4, [sp, #40] // load final in the last round 827 sub ip, ip, lr, lsl #2 828 movlt pc, ip // computed goto if blocks < 8 829 830 vld1.8 {q8}, [r1]! 831 vld1.8 {q9}, [r1]! 832 vld1.8 {q10}, [r1]! 833 vld1.8 {q11}, [r1]! 834 vld1.8 {q12}, [r1]! 835 vld1.8 {q13}, [r1]! 836 vld1.8 {q14}, [r1]! 837 teq r4, #0 // skip last block if 'final' 8381: bne 2f 839 vld1.8 {q15}, [r1]! 840 8412: adr ip, 3f 842 cmp r5, #8 843 sub ip, ip, lr, lsl #3 844 movlt pc, ip // computed goto if blocks < 8 845 846 veor q0, q0, q8 847 vst1.8 {q0}, [r0]! 848 veor q1, q1, q9 849 vst1.8 {q1}, [r0]! 850 veor q4, q4, q10 851 vst1.8 {q4}, [r0]! 852 veor q6, q6, q11 853 vst1.8 {q6}, [r0]! 854 veor q3, q3, q12 855 vst1.8 {q3}, [r0]! 856 veor q7, q7, q13 857 vst1.8 {q7}, [r0]! 858 veor q2, q2, q14 859 vst1.8 {q2}, [r0]! 860 teq r4, #0 // skip last block if 'final' 861 W(bne) 5f 8623: veor q5, q5, q15 863 vst1.8 {q5}, [r0]! 864 8654: next_ctr q0 866 867 subs r5, r5, #8 868 bgt 99b 869 870 vst1.8 {q0}, [r6] 871 pop {r4-r10, pc} 872 8735: vst1.8 {q5}, [r4] 874 b 4b 875ENDPROC(aesbs_ctr_encrypt) 876 877 .macro next_tweak, out, in, const, tmp 878 vshr.s64 \tmp, \in, #63 879 vand \tmp, \tmp, \const 880 vadd.u64 \out, \in, \in 881 vext.8 \tmp, \tmp, \tmp, #8 882 veor \out, \out, \tmp 883 .endm 884 885 /* 886 * aesbs_xts_encrypt(u8 out[], u8 const in[], u8 const rk[], int rounds, 887 * int blocks, u8 iv[], int reorder_last_tweak) 888 * aesbs_xts_decrypt(u8 out[], u8 const in[], u8 const rk[], int rounds, 889 * int blocks, u8 iv[], int reorder_last_tweak) 890 */ 891__xts_prepare8: 892 vld1.8 {q14}, [r7] // load iv 893 vmov.i32 d30, #0x87 // compose tweak mask vector 894 vmovl.u32 q15, d30 895 vshr.u64 d30, d31, #7 896 vmov q12, q14 897 898 adr ip, 0f 899 and r4, r6, #7 900 cmp r6, #8 901 sub ip, ip, r4, lsl #5 902 mov r4, sp 903 movlt pc, ip // computed goto if blocks < 8 904 905 vld1.8 {q0}, [r1]! 906 next_tweak q12, q14, q15, q13 907 veor q0, q0, q14 908 vst1.8 {q14}, [r4, :128]! 909 910 vld1.8 {q1}, [r1]! 911 next_tweak q14, q12, q15, q13 912 veor q1, q1, q12 913 vst1.8 {q12}, [r4, :128]! 914 915 vld1.8 {q2}, [r1]! 916 next_tweak q12, q14, q15, q13 917 veor q2, q2, q14 918 vst1.8 {q14}, [r4, :128]! 919 920 vld1.8 {q3}, [r1]! 921 next_tweak q14, q12, q15, q13 922 veor q3, q3, q12 923 vst1.8 {q12}, [r4, :128]! 924 925 vld1.8 {q4}, [r1]! 926 next_tweak q12, q14, q15, q13 927 veor q4, q4, q14 928 vst1.8 {q14}, [r4, :128]! 929 930 vld1.8 {q5}, [r1]! 931 next_tweak q14, q12, q15, q13 932 veor q5, q5, q12 933 vst1.8 {q12}, [r4, :128]! 934 935 vld1.8 {q6}, [r1]! 936 next_tweak q12, q14, q15, q13 937 veor q6, q6, q14 938 vst1.8 {q14}, [r4, :128]! 939 940 vld1.8 {q7}, [r1]! 941 next_tweak q14, q12, q15, q13 942THUMB( itt le ) 943 W(cmple) r8, #0 944 ble 1f 9450: veor q7, q7, q12 946 vst1.8 {q12}, [r4, :128] 947 948 vst1.8 {q14}, [r7] // store next iv 949 bx lr 950 9511: vswp q12, q14 952 b 0b 953ENDPROC(__xts_prepare8) 954 955 .macro __xts_crypt, do8, o0, o1, o2, o3, o4, o5, o6, o7 956 push {r4-r8, lr} 957 mov r5, sp // preserve sp 958 ldrd r6, r7, [sp, #24] // get blocks and iv args 959 rsb r8, ip, #1 960 sub ip, sp, #128 // make room for 8x tweak 961 bic ip, ip, #0xf // align sp to 16 bytes 962 mov sp, ip 963 96499: bl __xts_prepare8 965 966 mov bskey, r2 967 mov rounds, r3 968 bl \do8 969 970 adr ip, 0f 971 and lr, r6, #7 972 cmp r6, #8 973 sub ip, ip, lr, lsl #2 974 mov r4, sp 975 movlt pc, ip // computed goto if blocks < 8 976 977 vld1.8 {q8}, [r4, :128]! 978 vld1.8 {q9}, [r4, :128]! 979 vld1.8 {q10}, [r4, :128]! 980 vld1.8 {q11}, [r4, :128]! 981 vld1.8 {q12}, [r4, :128]! 982 vld1.8 {q13}, [r4, :128]! 983 vld1.8 {q14}, [r4, :128]! 984 vld1.8 {q15}, [r4, :128] 985 9860: adr ip, 1f 987 sub ip, ip, lr, lsl #3 988 movlt pc, ip // computed goto if blocks < 8 989 990 veor \o0, \o0, q8 991 vst1.8 {\o0}, [r0]! 992 veor \o1, \o1, q9 993 vst1.8 {\o1}, [r0]! 994 veor \o2, \o2, q10 995 vst1.8 {\o2}, [r0]! 996 veor \o3, \o3, q11 997 vst1.8 {\o3}, [r0]! 998 veor \o4, \o4, q12 999 vst1.8 {\o4}, [r0]! 1000 veor \o5, \o5, q13 1001 vst1.8 {\o5}, [r0]! 1002 veor \o6, \o6, q14 1003 vst1.8 {\o6}, [r0]! 1004 veor \o7, \o7, q15 1005 vst1.8 {\o7}, [r0]! 1006 10071: subs r6, r6, #8 1008 bgt 99b 1009 1010 mov sp, r5 1011 pop {r4-r8, pc} 1012 .endm 1013 1014ENTRY(aesbs_xts_encrypt) 1015 mov ip, #0 // never reorder final tweak 1016 __xts_crypt aesbs_encrypt8, q0, q1, q4, q6, q3, q7, q2, q5 1017ENDPROC(aesbs_xts_encrypt) 1018 1019ENTRY(aesbs_xts_decrypt) 1020 ldr ip, [sp, #8] // reorder final tweak? 1021 __xts_crypt aesbs_decrypt8, q0, q1, q6, q4, q2, q7, q3, q5 1022ENDPROC(aesbs_xts_decrypt) 1023