1 /* 2 * Copyright (c) 2017 Thomas Pornin <pornin@bolet.org> 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining 5 * a copy of this software and associated documentation files (the 6 * "Software"), to deal in the Software without restriction, including 7 * without limitation the rights to use, copy, modify, merge, publish, 8 * distribute, sublicense, and/or sell copies of the Software, and to 9 * permit persons to whom the Software is furnished to do so, subject to 10 * the following conditions: 11 * 12 * The above copyright notice and this permission notice shall be 13 * included in all copies or substantial portions of the Software. 14 * 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 19 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 20 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 * SOFTWARE. 23 */ 24 25 #define BR_POWER_ASM_MACROS 1 26 #include "inner.h" 27 28 #if BR_POWER8 29 30 /* see bearssl_block.h */ 31 void 32 br_aes_pwr8_ctr_init(br_aes_pwr8_ctr_keys *ctx, 33 const void *key, size_t len) 34 { 35 ctx->vtable = &br_aes_pwr8_ctr_vtable; 36 ctx->num_rounds = br_aes_pwr8_keysched(ctx->skey.skni, key, len); 37 } 38 39 static void 40 ctr_128(const unsigned char *sk, const unsigned char *ivbuf, 41 unsigned char *buf, size_t num_blocks) 42 { 43 long cc0, cc1, cc2, cc3; 44 45 #if BR_POWER8_LE 46 static const uint32_t idx2be[] = { 47 0x03020100, 0x07060504, 0x0B0A0908, 0x0F0E0D0C 48 }; 49 #endif 50 static const uint32_t ctrinc[] = { 51 0, 0, 0, 4 52 }; 53 54 cc0 = 0; 55 cc1 = 16; 56 cc2 = 32; 57 cc3 = 48; 58 asm volatile ( 59 60 /* 61 * Load subkeys into v0..v10 62 */ 63 lxvw4x(32, %[cc0], %[sk]) 64 addi(%[cc0], %[cc0], 16) 65 lxvw4x(33, %[cc0], %[sk]) 66 addi(%[cc0], %[cc0], 16) 67 lxvw4x(34, %[cc0], %[sk]) 68 addi(%[cc0], %[cc0], 16) 69 lxvw4x(35, %[cc0], %[sk]) 70 addi(%[cc0], %[cc0], 16) 71 lxvw4x(36, %[cc0], %[sk]) 72 addi(%[cc0], %[cc0], 16) 73 lxvw4x(37, %[cc0], %[sk]) 74 addi(%[cc0], %[cc0], 16) 75 lxvw4x(38, %[cc0], %[sk]) 76 addi(%[cc0], %[cc0], 16) 77 lxvw4x(39, %[cc0], %[sk]) 78 addi(%[cc0], %[cc0], 16) 79 lxvw4x(40, %[cc0], %[sk]) 80 addi(%[cc0], %[cc0], 16) 81 lxvw4x(41, %[cc0], %[sk]) 82 addi(%[cc0], %[cc0], 16) 83 lxvw4x(42, %[cc0], %[sk]) 84 li(%[cc0], 0) 85 86 #if BR_POWER8_LE 87 /* 88 * v15 = constant for byteswapping words 89 */ 90 lxvw4x(47, 0, %[idx2be]) 91 #endif 92 /* 93 * v28 = increment for IV counter. 94 */ 95 lxvw4x(60, 0, %[ctrinc]) 96 97 /* 98 * Load IV into v16..v19 99 */ 100 lxvw4x(48, %[cc0], %[ivbuf]) 101 lxvw4x(49, %[cc1], %[ivbuf]) 102 lxvw4x(50, %[cc2], %[ivbuf]) 103 lxvw4x(51, %[cc3], %[ivbuf]) 104 #if BR_POWER8_LE 105 vperm(16, 16, 16, 15) 106 vperm(17, 17, 17, 15) 107 vperm(18, 18, 18, 15) 108 vperm(19, 19, 19, 15) 109 #endif 110 111 mtctr(%[num_blocks]) 112 label(loop) 113 /* 114 * Compute next IV into v24..v27 115 */ 116 vadduwm(24, 16, 28) 117 vadduwm(25, 17, 28) 118 vadduwm(26, 18, 28) 119 vadduwm(27, 19, 28) 120 121 /* 122 * Load next data blocks. We do this early on but we 123 * won't need them until IV encryption is done. 124 */ 125 lxvw4x(52, %[cc0], %[buf]) 126 lxvw4x(53, %[cc1], %[buf]) 127 lxvw4x(54, %[cc2], %[buf]) 128 lxvw4x(55, %[cc3], %[buf]) 129 130 /* 131 * Encrypt the current IV. 132 */ 133 vxor(16, 16, 0) 134 vxor(17, 17, 0) 135 vxor(18, 18, 0) 136 vxor(19, 19, 0) 137 vcipher(16, 16, 1) 138 vcipher(17, 17, 1) 139 vcipher(18, 18, 1) 140 vcipher(19, 19, 1) 141 vcipher(16, 16, 2) 142 vcipher(17, 17, 2) 143 vcipher(18, 18, 2) 144 vcipher(19, 19, 2) 145 vcipher(16, 16, 3) 146 vcipher(17, 17, 3) 147 vcipher(18, 18, 3) 148 vcipher(19, 19, 3) 149 vcipher(16, 16, 4) 150 vcipher(17, 17, 4) 151 vcipher(18, 18, 4) 152 vcipher(19, 19, 4) 153 vcipher(16, 16, 5) 154 vcipher(17, 17, 5) 155 vcipher(18, 18, 5) 156 vcipher(19, 19, 5) 157 vcipher(16, 16, 6) 158 vcipher(17, 17, 6) 159 vcipher(18, 18, 6) 160 vcipher(19, 19, 6) 161 vcipher(16, 16, 7) 162 vcipher(17, 17, 7) 163 vcipher(18, 18, 7) 164 vcipher(19, 19, 7) 165 vcipher(16, 16, 8) 166 vcipher(17, 17, 8) 167 vcipher(18, 18, 8) 168 vcipher(19, 19, 8) 169 vcipher(16, 16, 9) 170 vcipher(17, 17, 9) 171 vcipher(18, 18, 9) 172 vcipher(19, 19, 9) 173 vcipherlast(16, 16, 10) 174 vcipherlast(17, 17, 10) 175 vcipherlast(18, 18, 10) 176 vcipherlast(19, 19, 10) 177 178 #if BR_POWER8_LE 179 vperm(16, 16, 16, 15) 180 vperm(17, 17, 17, 15) 181 vperm(18, 18, 18, 15) 182 vperm(19, 19, 19, 15) 183 #endif 184 185 /* 186 * Load next plaintext word and XOR with encrypted IV. 187 */ 188 vxor(16, 20, 16) 189 vxor(17, 21, 17) 190 vxor(18, 22, 18) 191 vxor(19, 23, 19) 192 stxvw4x(48, %[cc0], %[buf]) 193 stxvw4x(49, %[cc1], %[buf]) 194 stxvw4x(50, %[cc2], %[buf]) 195 stxvw4x(51, %[cc3], %[buf]) 196 197 addi(%[buf], %[buf], 64) 198 199 /* 200 * Update IV. 201 */ 202 vand(16, 24, 24) 203 vand(17, 25, 25) 204 vand(18, 26, 26) 205 vand(19, 27, 27) 206 207 bdnz(loop) 208 209 : [cc0] "+b" (cc0), [cc1] "+b" (cc1), [cc2] "+b" (cc2), [cc3] "+b" (cc3), 210 [buf] "+b" (buf) 211 : [sk] "b" (sk), [ivbuf] "b" (ivbuf), [num_blocks] "b" (num_blocks >> 2), 212 [ctrinc] "b" (ctrinc) 213 #if BR_POWER8_LE 214 , [idx2be] "b" (idx2be) 215 #endif 216 : "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", "v9", 217 "v10", "v11", "v12", "v13", "v14", "v15", "v16", "v17", "v18", "v19", 218 "v20", "v21", "v22", "v23", "v24", "v25", "v26", "v27", "v28", "v29", 219 "ctr", "memory" 220 ); 221 } 222 223 static void 224 ctr_192(const unsigned char *sk, const unsigned char *ivbuf, 225 unsigned char *buf, size_t num_blocks) 226 { 227 long cc0, cc1, cc2, cc3; 228 229 #if BR_POWER8_LE 230 static const uint32_t idx2be[] = { 231 0x03020100, 0x07060504, 0x0B0A0908, 0x0F0E0D0C 232 }; 233 #endif 234 static const uint32_t ctrinc[] = { 235 0, 0, 0, 4 236 }; 237 238 cc0 = 0; 239 cc1 = 16; 240 cc2 = 32; 241 cc3 = 48; 242 asm volatile ( 243 244 /* 245 * Load subkeys into v0..v12 246 */ 247 lxvw4x(32, %[cc0], %[sk]) 248 addi(%[cc0], %[cc0], 16) 249 lxvw4x(33, %[cc0], %[sk]) 250 addi(%[cc0], %[cc0], 16) 251 lxvw4x(34, %[cc0], %[sk]) 252 addi(%[cc0], %[cc0], 16) 253 lxvw4x(35, %[cc0], %[sk]) 254 addi(%[cc0], %[cc0], 16) 255 lxvw4x(36, %[cc0], %[sk]) 256 addi(%[cc0], %[cc0], 16) 257 lxvw4x(37, %[cc0], %[sk]) 258 addi(%[cc0], %[cc0], 16) 259 lxvw4x(38, %[cc0], %[sk]) 260 addi(%[cc0], %[cc0], 16) 261 lxvw4x(39, %[cc0], %[sk]) 262 addi(%[cc0], %[cc0], 16) 263 lxvw4x(40, %[cc0], %[sk]) 264 addi(%[cc0], %[cc0], 16) 265 lxvw4x(41, %[cc0], %[sk]) 266 addi(%[cc0], %[cc0], 16) 267 lxvw4x(42, %[cc0], %[sk]) 268 addi(%[cc0], %[cc0], 16) 269 lxvw4x(43, %[cc0], %[sk]) 270 addi(%[cc0], %[cc0], 16) 271 lxvw4x(44, %[cc0], %[sk]) 272 li(%[cc0], 0) 273 274 #if BR_POWER8_LE 275 /* 276 * v15 = constant for byteswapping words 277 */ 278 lxvw4x(47, 0, %[idx2be]) 279 #endif 280 /* 281 * v28 = increment for IV counter. 282 */ 283 lxvw4x(60, 0, %[ctrinc]) 284 285 /* 286 * Load IV into v16..v19 287 */ 288 lxvw4x(48, %[cc0], %[ivbuf]) 289 lxvw4x(49, %[cc1], %[ivbuf]) 290 lxvw4x(50, %[cc2], %[ivbuf]) 291 lxvw4x(51, %[cc3], %[ivbuf]) 292 #if BR_POWER8_LE 293 vperm(16, 16, 16, 15) 294 vperm(17, 17, 17, 15) 295 vperm(18, 18, 18, 15) 296 vperm(19, 19, 19, 15) 297 #endif 298 299 mtctr(%[num_blocks]) 300 label(loop) 301 /* 302 * Compute next IV into v24..v27 303 */ 304 vadduwm(24, 16, 28) 305 vadduwm(25, 17, 28) 306 vadduwm(26, 18, 28) 307 vadduwm(27, 19, 28) 308 309 /* 310 * Load next data blocks. We do this early on but we 311 * won't need them until IV encryption is done. 312 */ 313 lxvw4x(52, %[cc0], %[buf]) 314 lxvw4x(53, %[cc1], %[buf]) 315 lxvw4x(54, %[cc2], %[buf]) 316 lxvw4x(55, %[cc3], %[buf]) 317 318 /* 319 * Encrypt the current IV. 320 */ 321 vxor(16, 16, 0) 322 vxor(17, 17, 0) 323 vxor(18, 18, 0) 324 vxor(19, 19, 0) 325 vcipher(16, 16, 1) 326 vcipher(17, 17, 1) 327 vcipher(18, 18, 1) 328 vcipher(19, 19, 1) 329 vcipher(16, 16, 2) 330 vcipher(17, 17, 2) 331 vcipher(18, 18, 2) 332 vcipher(19, 19, 2) 333 vcipher(16, 16, 3) 334 vcipher(17, 17, 3) 335 vcipher(18, 18, 3) 336 vcipher(19, 19, 3) 337 vcipher(16, 16, 4) 338 vcipher(17, 17, 4) 339 vcipher(18, 18, 4) 340 vcipher(19, 19, 4) 341 vcipher(16, 16, 5) 342 vcipher(17, 17, 5) 343 vcipher(18, 18, 5) 344 vcipher(19, 19, 5) 345 vcipher(16, 16, 6) 346 vcipher(17, 17, 6) 347 vcipher(18, 18, 6) 348 vcipher(19, 19, 6) 349 vcipher(16, 16, 7) 350 vcipher(17, 17, 7) 351 vcipher(18, 18, 7) 352 vcipher(19, 19, 7) 353 vcipher(16, 16, 8) 354 vcipher(17, 17, 8) 355 vcipher(18, 18, 8) 356 vcipher(19, 19, 8) 357 vcipher(16, 16, 9) 358 vcipher(17, 17, 9) 359 vcipher(18, 18, 9) 360 vcipher(19, 19, 9) 361 vcipher(16, 16, 10) 362 vcipher(17, 17, 10) 363 vcipher(18, 18, 10) 364 vcipher(19, 19, 10) 365 vcipher(16, 16, 11) 366 vcipher(17, 17, 11) 367 vcipher(18, 18, 11) 368 vcipher(19, 19, 11) 369 vcipherlast(16, 16, 12) 370 vcipherlast(17, 17, 12) 371 vcipherlast(18, 18, 12) 372 vcipherlast(19, 19, 12) 373 374 #if BR_POWER8_LE 375 vperm(16, 16, 16, 15) 376 vperm(17, 17, 17, 15) 377 vperm(18, 18, 18, 15) 378 vperm(19, 19, 19, 15) 379 #endif 380 381 /* 382 * Load next plaintext word and XOR with encrypted IV. 383 */ 384 vxor(16, 20, 16) 385 vxor(17, 21, 17) 386 vxor(18, 22, 18) 387 vxor(19, 23, 19) 388 stxvw4x(48, %[cc0], %[buf]) 389 stxvw4x(49, %[cc1], %[buf]) 390 stxvw4x(50, %[cc2], %[buf]) 391 stxvw4x(51, %[cc3], %[buf]) 392 393 addi(%[buf], %[buf], 64) 394 395 /* 396 * Update IV. 397 */ 398 vand(16, 24, 24) 399 vand(17, 25, 25) 400 vand(18, 26, 26) 401 vand(19, 27, 27) 402 403 bdnz(loop) 404 405 : [cc0] "+b" (cc0), [cc1] "+b" (cc1), [cc2] "+b" (cc2), [cc3] "+b" (cc3), 406 [buf] "+b" (buf) 407 : [sk] "b" (sk), [ivbuf] "b" (ivbuf), [num_blocks] "b" (num_blocks >> 2), 408 [ctrinc] "b" (ctrinc) 409 #if BR_POWER8_LE 410 , [idx2be] "b" (idx2be) 411 #endif 412 : "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", "v9", 413 "v10", "v11", "v12", "v13", "v14", "v15", "v16", "v17", "v18", "v19", 414 "v20", "v21", "v22", "v23", "v24", "v25", "v26", "v27", "v28", "v29", 415 "ctr", "memory" 416 ); 417 } 418 419 static void 420 ctr_256(const unsigned char *sk, const unsigned char *ivbuf, 421 unsigned char *buf, size_t num_blocks) 422 { 423 long cc0, cc1, cc2, cc3; 424 425 #if BR_POWER8_LE 426 static const uint32_t idx2be[] = { 427 0x03020100, 0x07060504, 0x0B0A0908, 0x0F0E0D0C 428 }; 429 #endif 430 static const uint32_t ctrinc[] = { 431 0, 0, 0, 4 432 }; 433 434 cc0 = 0; 435 cc1 = 16; 436 cc2 = 32; 437 cc3 = 48; 438 asm volatile ( 439 440 /* 441 * Load subkeys into v0..v14 442 */ 443 lxvw4x(32, %[cc0], %[sk]) 444 addi(%[cc0], %[cc0], 16) 445 lxvw4x(33, %[cc0], %[sk]) 446 addi(%[cc0], %[cc0], 16) 447 lxvw4x(34, %[cc0], %[sk]) 448 addi(%[cc0], %[cc0], 16) 449 lxvw4x(35, %[cc0], %[sk]) 450 addi(%[cc0], %[cc0], 16) 451 lxvw4x(36, %[cc0], %[sk]) 452 addi(%[cc0], %[cc0], 16) 453 lxvw4x(37, %[cc0], %[sk]) 454 addi(%[cc0], %[cc0], 16) 455 lxvw4x(38, %[cc0], %[sk]) 456 addi(%[cc0], %[cc0], 16) 457 lxvw4x(39, %[cc0], %[sk]) 458 addi(%[cc0], %[cc0], 16) 459 lxvw4x(40, %[cc0], %[sk]) 460 addi(%[cc0], %[cc0], 16) 461 lxvw4x(41, %[cc0], %[sk]) 462 addi(%[cc0], %[cc0], 16) 463 lxvw4x(42, %[cc0], %[sk]) 464 addi(%[cc0], %[cc0], 16) 465 lxvw4x(43, %[cc0], %[sk]) 466 addi(%[cc0], %[cc0], 16) 467 lxvw4x(44, %[cc0], %[sk]) 468 addi(%[cc0], %[cc0], 16) 469 lxvw4x(45, %[cc0], %[sk]) 470 addi(%[cc0], %[cc0], 16) 471 lxvw4x(46, %[cc0], %[sk]) 472 li(%[cc0], 0) 473 474 #if BR_POWER8_LE 475 /* 476 * v15 = constant for byteswapping words 477 */ 478 lxvw4x(47, 0, %[idx2be]) 479 #endif 480 /* 481 * v28 = increment for IV counter. 482 */ 483 lxvw4x(60, 0, %[ctrinc]) 484 485 /* 486 * Load IV into v16..v19 487 */ 488 lxvw4x(48, %[cc0], %[ivbuf]) 489 lxvw4x(49, %[cc1], %[ivbuf]) 490 lxvw4x(50, %[cc2], %[ivbuf]) 491 lxvw4x(51, %[cc3], %[ivbuf]) 492 #if BR_POWER8_LE 493 vperm(16, 16, 16, 15) 494 vperm(17, 17, 17, 15) 495 vperm(18, 18, 18, 15) 496 vperm(19, 19, 19, 15) 497 #endif 498 499 mtctr(%[num_blocks]) 500 label(loop) 501 /* 502 * Compute next IV into v24..v27 503 */ 504 vadduwm(24, 16, 28) 505 vadduwm(25, 17, 28) 506 vadduwm(26, 18, 28) 507 vadduwm(27, 19, 28) 508 509 /* 510 * Load next data blocks. We do this early on but we 511 * won't need them until IV encryption is done. 512 */ 513 lxvw4x(52, %[cc0], %[buf]) 514 lxvw4x(53, %[cc1], %[buf]) 515 lxvw4x(54, %[cc2], %[buf]) 516 lxvw4x(55, %[cc3], %[buf]) 517 518 /* 519 * Encrypt the current IV. 520 */ 521 vxor(16, 16, 0) 522 vxor(17, 17, 0) 523 vxor(18, 18, 0) 524 vxor(19, 19, 0) 525 vcipher(16, 16, 1) 526 vcipher(17, 17, 1) 527 vcipher(18, 18, 1) 528 vcipher(19, 19, 1) 529 vcipher(16, 16, 2) 530 vcipher(17, 17, 2) 531 vcipher(18, 18, 2) 532 vcipher(19, 19, 2) 533 vcipher(16, 16, 3) 534 vcipher(17, 17, 3) 535 vcipher(18, 18, 3) 536 vcipher(19, 19, 3) 537 vcipher(16, 16, 4) 538 vcipher(17, 17, 4) 539 vcipher(18, 18, 4) 540 vcipher(19, 19, 4) 541 vcipher(16, 16, 5) 542 vcipher(17, 17, 5) 543 vcipher(18, 18, 5) 544 vcipher(19, 19, 5) 545 vcipher(16, 16, 6) 546 vcipher(17, 17, 6) 547 vcipher(18, 18, 6) 548 vcipher(19, 19, 6) 549 vcipher(16, 16, 7) 550 vcipher(17, 17, 7) 551 vcipher(18, 18, 7) 552 vcipher(19, 19, 7) 553 vcipher(16, 16, 8) 554 vcipher(17, 17, 8) 555 vcipher(18, 18, 8) 556 vcipher(19, 19, 8) 557 vcipher(16, 16, 9) 558 vcipher(17, 17, 9) 559 vcipher(18, 18, 9) 560 vcipher(19, 19, 9) 561 vcipher(16, 16, 10) 562 vcipher(17, 17, 10) 563 vcipher(18, 18, 10) 564 vcipher(19, 19, 10) 565 vcipher(16, 16, 11) 566 vcipher(17, 17, 11) 567 vcipher(18, 18, 11) 568 vcipher(19, 19, 11) 569 vcipher(16, 16, 12) 570 vcipher(17, 17, 12) 571 vcipher(18, 18, 12) 572 vcipher(19, 19, 12) 573 vcipher(16, 16, 13) 574 vcipher(17, 17, 13) 575 vcipher(18, 18, 13) 576 vcipher(19, 19, 13) 577 vcipherlast(16, 16, 14) 578 vcipherlast(17, 17, 14) 579 vcipherlast(18, 18, 14) 580 vcipherlast(19, 19, 14) 581 582 #if BR_POWER8_LE 583 vperm(16, 16, 16, 15) 584 vperm(17, 17, 17, 15) 585 vperm(18, 18, 18, 15) 586 vperm(19, 19, 19, 15) 587 #endif 588 589 /* 590 * Load next plaintext word and XOR with encrypted IV. 591 */ 592 vxor(16, 20, 16) 593 vxor(17, 21, 17) 594 vxor(18, 22, 18) 595 vxor(19, 23, 19) 596 stxvw4x(48, %[cc0], %[buf]) 597 stxvw4x(49, %[cc1], %[buf]) 598 stxvw4x(50, %[cc2], %[buf]) 599 stxvw4x(51, %[cc3], %[buf]) 600 601 addi(%[buf], %[buf], 64) 602 603 /* 604 * Update IV. 605 */ 606 vand(16, 24, 24) 607 vand(17, 25, 25) 608 vand(18, 26, 26) 609 vand(19, 27, 27) 610 611 bdnz(loop) 612 613 : [cc0] "+b" (cc0), [cc1] "+b" (cc1), [cc2] "+b" (cc2), [cc3] "+b" (cc3), 614 [buf] "+b" (buf) 615 : [sk] "b" (sk), [ivbuf] "b" (ivbuf), [num_blocks] "b" (num_blocks >> 2), 616 [ctrinc] "b" (ctrinc) 617 #if BR_POWER8_LE 618 , [idx2be] "b" (idx2be) 619 #endif 620 : "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", "v9", 621 "v10", "v11", "v12", "v13", "v14", "v15", "v16", "v17", "v18", "v19", 622 "v20", "v21", "v22", "v23", "v24", "v25", "v26", "v27", "v28", "v29", 623 "ctr", "memory" 624 ); 625 } 626 627 /* see bearssl_block.h */ 628 uint32_t 629 br_aes_pwr8_ctr_run(const br_aes_pwr8_ctr_keys *ctx, 630 const void *iv, uint32_t cc, void *data, size_t len) 631 { 632 unsigned char *buf; 633 unsigned char ivbuf[64]; 634 635 buf = data; 636 memcpy(ivbuf + 0, iv, 12); 637 memcpy(ivbuf + 16, iv, 12); 638 memcpy(ivbuf + 32, iv, 12); 639 memcpy(ivbuf + 48, iv, 12); 640 if (len >= 64) { 641 br_enc32be(ivbuf + 12, cc + 0); 642 br_enc32be(ivbuf + 28, cc + 1); 643 br_enc32be(ivbuf + 44, cc + 2); 644 br_enc32be(ivbuf + 60, cc + 3); 645 switch (ctx->num_rounds) { 646 case 10: 647 ctr_128(ctx->skey.skni, ivbuf, buf, 648 (len >> 4) & ~(size_t)3); 649 break; 650 case 12: 651 ctr_192(ctx->skey.skni, ivbuf, buf, 652 (len >> 4) & ~(size_t)3); 653 break; 654 default: 655 ctr_256(ctx->skey.skni, ivbuf, buf, 656 (len >> 4) & ~(size_t)3); 657 break; 658 } 659 cc += (len >> 4) & ~(size_t)3; 660 buf += len & ~(size_t)63; 661 len &= 63; 662 } 663 if (len > 0) { 664 unsigned char tmp[64]; 665 666 memcpy(tmp, buf, len); 667 memset(tmp + len, 0, (sizeof tmp) - len); 668 br_enc32be(ivbuf + 12, cc + 0); 669 br_enc32be(ivbuf + 28, cc + 1); 670 br_enc32be(ivbuf + 44, cc + 2); 671 br_enc32be(ivbuf + 60, cc + 3); 672 switch (ctx->num_rounds) { 673 case 10: 674 ctr_128(ctx->skey.skni, ivbuf, tmp, 4); 675 break; 676 case 12: 677 ctr_192(ctx->skey.skni, ivbuf, tmp, 4); 678 break; 679 default: 680 ctr_256(ctx->skey.skni, ivbuf, tmp, 4); 681 break; 682 } 683 memcpy(buf, tmp, len); 684 cc += (len + 15) >> 4; 685 } 686 return cc; 687 } 688 689 /* see bearssl_block.h */ 690 const br_block_ctr_class br_aes_pwr8_ctr_vtable = { 691 sizeof(br_aes_pwr8_ctr_keys), 692 16, 693 4, 694 (void (*)(const br_block_ctr_class **, const void *, size_t)) 695 &br_aes_pwr8_ctr_init, 696 (uint32_t (*)(const br_block_ctr_class *const *, 697 const void *, uint32_t, void *, size_t)) 698 &br_aes_pwr8_ctr_run 699 }; 700 701 /* see bearssl_block.h */ 702 const br_block_ctr_class * 703 br_aes_pwr8_ctr_get_vtable(void) 704 { 705 return br_aes_pwr8_supported() ? &br_aes_pwr8_ctr_vtable : NULL; 706 } 707 708 #else 709 710 /* see bearssl_block.h */ 711 const br_block_ctr_class * 712 br_aes_pwr8_ctr_get_vtable(void) 713 { 714 return NULL; 715 } 716 717 #endif 718