AnCH Framework 0.1
Another C++ Hack Framework
 
Loading...
Searching...
No Matches
aes.hpp
1/*
2 ANCH Framework: ANother C++ Hack is a C++ framework based on C++11 standard
3 Copyright (C) 2012 Vincent Lachenal
4
5 This file is part of ANCH Framework.
6
7 ANCH Framework is free software: you can redistribute it and/or modify
8 it under the terms of the GNU Lesser General Public License as published by
9 the Free Software Foundation, either version 3 of the License, or
10 (at your option) any later version.
11
12 ANCH Framework is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU Lesser General Public License for more details.
16
17 You should have received a copy of the GNU Lesser General Public License
18 along with ANCH Framework. If not, see <http://www.gnu.org/licenses/>.
19*/
20#pragma once
21
22#include "crypto/cipher/blockCipher.hpp"
23
24#include <bitset>
25#include <cstring>
26
27#ifdef ANCH_CPU_DETECTION
28#include "device/cpu.hpp"
29#endif
30
31#ifdef ANCH_CPU_AES
32#include <wmmintrin.h>
33#include <smmintrin.h>
34#endif
35
36#if !defined (ALIGN16)
37# if defined (__GNUC__)
38# define ALIGN16 __attribute__ ( (aligned (16)))
39# else
40# define ALIGN16 __declspec (align (16))
41# endif
42#endif
43
44
45namespace anch {
46 namespace crypto {
47
48#ifdef ANCH_CPU_AES
49 template<std::size_t S>
50 struct AesniKey {
51 ALIGN16 __m128i cipherKey[S];
52 ALIGN16 __m128i decipherKey[S];
53 };
54#endif
55
66 template<std::size_t K, std::size_t R>
67 class AES: public anch::crypto::BlockCipher<16> {
68 // Attributes +
69 private:
70#if defined ANCH_CPU_DETECTION || !defined(ANCH_CPU_AES)
72 uint8_t _state[4][4];
73#endif
74
76 union ExpKey {
77#ifdef ANCH_CPU_DETECTION
78 uint32_t swKey[4 * (R + 1)];
80#elif ANCH_CPU_AES
82#else
83 uint32_t swKey[4 * (R + 1)];
84#endif
85 };
86 ExpKey _expKey;
87 // Attributes -
88
89
90 // Constructors +
91 public:
97 AES(const uint8_t key[4*K]);
98
105 AES(const AES& other);
106 // Constructors -
107
108
109 // Destructors +
113 virtual ~AES();
114 // Destructors -
115
116
117 // Methods +
118 public:
125 void cipher(const std::array<uint8_t,16>& input, std::array<uint8_t,16>& output);
126
133 void decipher(const std::array<uint8_t,16>& input, std::array<uint8_t,16>& output);
134
135 private:
136#ifdef ANCH_CPU_AES
143 void aesniCipher(const std::array<uint8_t,16>& input, std::array<uint8_t,16>& output);
144
151 void aesniDecipher(const std::array<uint8_t,16>& input, std::array<uint8_t,16>& output);
152
161 __m128i aes128assist(__m128i& temp1, __m128i& temp2);
162
168 void aesni128ExpandKey(uint8_t key[4 * K]);
169
177 void aes192assist(__m128i& temp1, __m128i& temp2, __m128i& temp3);
178
184 void aesni192ExpandKey(uint8_t key[4 * K]);
185
192 void aes256assist1(__m128i& temp1, __m128i& temp2);
193
200 void aes256assist2(__m128i& temp1, __m128i& temp3);
201
207 void aesni256ExpandKey(uint8_t key[4 * K]);
208
214 void aesniExpandKey(uint8_t key[4 * K]);
215#endif // ANCH_CPU_AES
216
217#if defined ANCH_CPU_DETECTION || !defined(ANCH_CPU_AES)
224 void swCipher(const std::array<uint8_t,16>& input, std::array<uint8_t,16>& output);
225
232 void swDecipher(const std::array<uint8_t,16>& input, std::array<uint8_t,16>& output);
233
239 void expandKey(const uint8_t key[4 * K]);
240
249 uint32_t subWord(const uint32_t& word);
250
258 uint32_t rotateWord(const uint32_t& word);
259
264 void cipherSubBytes();
265
270 void decipherSubBytes();
271
275 void cipherShiftRows();
276
280 void decipherShiftRows();
281
285 void cipherMixColumns();
286
290 void decipherMixColumns();
291
297 void addRoundKey(const uint32_t& round);
298#endif // ANCH_CPU_DETECTION || !ANCH_CPU_AES
299 // Methods -
300
301 };
302
303 // Constructors +
304 template<std::size_t K, std::size_t R>
305 AES<K,R>::AES(const uint8_t key[4*K]): _state(), _expKey() {
306#ifdef ANCH_CPU_DETECTION
307 if(anch::device::CPU::getInstance().isAES()) {
308 uint8_t aesKey[4*K];
309 std::memcpy(aesKey, key, 4*K);
310 aesniExpandKey(aesKey);
311 } else {
312 expandKey(key);
313 }
314#elif ANCH_CPU_AES
315 uint8_t aesKey[4*K];
316 std::memcpy(aesKey, key, 4*K);
317 aesniExpandKey(aesKey);
318#else
319 expandKey(key);
320#endif
321 }
322
323 template<std::size_t K, std::size_t R>
324 AES<K,R>::AES(const AES& other): _state(), _expKey() {
325#ifdef ANCH_CPU_DETECTION
326 if(anch::device::CPU::getInstance().isAES()) {
327 std::memcpy(_expKey.hwKey.cipherKey, other._expKey.hwKey.cipherKey, (R + 1) * sizeof(__m128i));
328 std::memcpy(_expKey.hwKey.decipherKey, other._expKey.hwKey.decipherKey, (R + 1) * sizeof(__m128i));
329 } else {
330 std::memcpy(_expKey.swKey, other._expKey.swKey, 4 * (R + 1) * sizeof(uint32_t));
331 }
332#elif ANCH_CPU_AES
333 std::memcpy(_expKey.hwKey.cipherKey, other._expKey.hwKey.cipherKey, (R + 1) * sizeof(__m128i));
334 std::memcpy(_expKey.hwKey.decipherKey, other._expKey.hwKey.decipherKey, (R + 1) * sizeof(__m128i));
335#else
336 std::memcpy(_expKey.swKey, other._expKey.swKey, 4 * (R + 1) * sizeof(uint32_t));
337#endif
338 }
339 // Constructors -
340
341
342 // Destructors +
343 template<std::size_t K, std::size_t R>
345 // Nothing to do
346 }
347 // Destructors -
348
349
350 // Methods +
351 template<std::size_t K, std::size_t R>
352 void
353 AES<K,R>::cipher(const std::array<uint8_t,16>& input, std::array<uint8_t,16>& output) {
354#ifdef ANCH_CPU_DETECTION
355 if(anch::device::CPU::getInstance().isAES()) {
356 aesniCipher(input, output);
357 } else {
358 swCipher(input, output);
359 }
360#elif ANCH_CPU_AES
361 aesniCipher(input, output);
362#else
363 swCipher(input, output);
364#endif
365 }
366
367 template<std::size_t K, std::size_t R>
368 void
369 AES<K,R>::decipher(const std::array<uint8_t,16>& input, std::array<uint8_t,16>& output) {
370#ifdef ANCH_CPU_DETECTION
371 if(anch::device::CPU::getInstance().isAES()) {
372 aesniDecipher(input, output);
373 } else {
374 swDecipher(input, output);
375 }
376#elif ANCH_CPU_AES
377 aesniDecipher(input, output);
378#else
379 swDecipher(input, output);
380#endif
381 }
382
383#ifdef ANCH_CPU_AES
384 template<std::size_t K, std::size_t R>
385 void
386 AES<K,R>::aesniCipher(const std::array<uint8_t,16>& input, std::array<uint8_t,16>& output) {
387 __m128i tmp;
388 std::size_t j;
389 ALIGN16 uint8_t in[16];
390 std::memcpy(in, input.data(), 16);
391 ALIGN16 __m128i out/*[2]*/;
392 /*for(std::size_t i = 0 ; i < 2 ; ++i) {
393 tmp = _mm_loadu_si128(&(reinterpret_cast<__m128i*>(in)[i]));
394 tmp = _mm_xor_si128(tmp, _expKey.hwKey.cipherKey[0]);
395 for(j = 1 ; j < R ; ++j) {
396 tmp = _mm_aesenc_si128(tmp, _expKey.hwKey.cipherKey[j]);
397 }
398 tmp = _mm_aesenclast_si128(tmp, _expKey.hwKey.cipherKey[j]);
399 _mm_storeu_si128(&(out[i]), tmp);
400 }*/
401 tmp = _mm_loadu_si128(reinterpret_cast<__m128i*>(in));
402 tmp = _mm_xor_si128(tmp, _expKey.hwKey.cipherKey[0]);
403 for(j = 1 ; j < R ; ++j) {
404 tmp = _mm_aesenc_si128(tmp, _expKey.hwKey.cipherKey[j]);
405 }
406 tmp = _mm_aesenclast_si128(tmp, _expKey.hwKey.cipherKey[j]);
407 _mm_storeu_si128(&out, tmp);
408 std::memcpy(output.data(), reinterpret_cast<uint8_t*>(&out), 16);
409 }
410
411 template<std::size_t K, std::size_t R>
412 void
413 AES<K,R>::aesniDecipher(const std::array<uint8_t,16>& input, std::array<uint8_t,16>& output) {
414 __m128i tmp;
415 std::size_t j;
416 ALIGN16 uint8_t in[16];
417 std::memcpy(in, input.data(), 16);
418 ALIGN16 __m128i out/*[2]*/;
419 /*for(std::size_t i = 0 ; i < 2 ; ++i) {
420 tmp = _mm_loadu_si128(&(reinterpret_cast<__m128i*>(in)[i]));
421 tmp = _mm_xor_si128(tmp, _expKey.hwKey.decipherKey[0]);
422 for(j = 1 ; j < R ; ++j) {
423 tmp = _mm_aesdec_si128(tmp, _expKey.hwKey.decipherKey[j]);
424 }
425 tmp = _mm_aesdeclast_si128(tmp, _expKey.hwKey.decipherKey[j]);
426 _mm_storeu_si128(&(out[i]), tmp);
427 }*/
428 tmp = _mm_loadu_si128(reinterpret_cast<__m128i*>(in));
429 tmp = _mm_xor_si128(tmp, _expKey.hwKey.decipherKey[0]);
430 for(j = 1 ; j < R ; ++j) {
431 tmp = _mm_aesdec_si128(tmp, _expKey.hwKey.decipherKey[j]);
432 }
433 tmp = _mm_aesdeclast_si128(tmp, _expKey.hwKey.decipherKey[j]);
434 _mm_storeu_si128(&out, tmp);
435 std::memcpy(output.data(), reinterpret_cast<uint8_t*>(&out), 16);
436 }
437
438 template<std::size_t K, std::size_t R>
439 inline __m128i
440 AES<K,R>::aes128assist(__m128i& temp1, __m128i& temp2) {
441 __m128i temp3;
442 temp2 = _mm_shuffle_epi32(temp2 ,0xff);
443 temp3 = _mm_slli_si128(temp1, 0x4);
444 temp1 = _mm_xor_si128(temp1, temp3);
445 temp3 = _mm_slli_si128(temp3, 0x4);
446 temp1 = _mm_xor_si128(temp1, temp3);
447 temp3 = _mm_slli_si128(temp3, 0x4);
448 temp1 = _mm_xor_si128(temp1, temp3);
449 temp1 = _mm_xor_si128(temp1, temp2);
450 return temp1;
451 }
452
453 template<std::size_t K, std::size_t R>
454 inline void
455 AES<K,R>::aesni128ExpandKey([[maybe_unused]] uint8_t key[4 * K]) {
456 if constexpr (K == 4) {
457 __m128i temp1, temp2;
458 temp1 = _mm_loadu_si128(reinterpret_cast<__m128i*>(key));
459 _expKey.hwKey.cipherKey[0] = temp1;
460 temp2 = _mm_aeskeygenassist_si128(temp1, 0x1);
461 temp1 = aes128assist(temp1, temp2);
462 _expKey.hwKey.cipherKey[1] = temp1;
463 temp2 = _mm_aeskeygenassist_si128(temp1, 0x2);
464 temp1 = aes128assist(temp1, temp2);
465 _expKey.hwKey.cipherKey[2] = temp1;
466 temp2 = _mm_aeskeygenassist_si128(temp1, 0x4);
467 temp1 = aes128assist(temp1, temp2);
468 _expKey.hwKey.cipherKey[3] = temp1;
469 temp2 = _mm_aeskeygenassist_si128(temp1, 0x8);
470 temp1 = aes128assist(temp1, temp2);
471 _expKey.hwKey.cipherKey[4] = temp1;
472 temp2 = _mm_aeskeygenassist_si128(temp1, 0x10);
473 temp1 = aes128assist(temp1, temp2);
474 _expKey.hwKey.cipherKey[5] = temp1;
475 temp2 = _mm_aeskeygenassist_si128(temp1, 0x20);
476 temp1 = aes128assist(temp1, temp2);
477 _expKey.hwKey.cipherKey[6] = temp1;
478 temp2 = _mm_aeskeygenassist_si128(temp1, 0x40);
479 temp1 = aes128assist(temp1, temp2);
480 _expKey.hwKey.cipherKey[7] = temp1;
481 temp2 = _mm_aeskeygenassist_si128(temp1, 0x80);
482 temp1 = aes128assist(temp1, temp2);
483 _expKey.hwKey.cipherKey[8] = temp1;
484 temp2 = _mm_aeskeygenassist_si128(temp1, 0x1b);
485 temp1 = aes128assist(temp1, temp2);
486 _expKey.hwKey.cipherKey[9] = temp1;
487 temp2 = _mm_aeskeygenassist_si128(temp1, 0x36);
488 temp1 = aes128assist(temp1, temp2);
489 _expKey.hwKey.cipherKey[10] = temp1;
490 }
491 }
492
493 template<std::size_t K, std::size_t R>
494 inline void
495 AES<K,R>::aes192assist(__m128i& temp1, __m128i& temp2, __m128i& temp3) {
496 __m128i temp4;
497 temp2 = _mm_shuffle_epi32(temp2, 0x55);
498 temp4 = _mm_slli_si128(temp1, 0x4);
499 temp1 = _mm_xor_si128(temp1, temp4);
500 temp4 = _mm_slli_si128(temp4, 0x4);
501 temp1 = _mm_xor_si128(temp1, temp4);
502 temp4 = _mm_slli_si128(temp4, 0x4);
503 temp1 = _mm_xor_si128(temp1, temp4);
504 temp1 = _mm_xor_si128(temp1, temp2);
505 temp2 = _mm_shuffle_epi32(temp1, 0xff);
506 temp4 = _mm_slli_si128(temp3, 0x4);
507 temp3 = _mm_xor_si128(temp3, temp4);
508 temp3 = _mm_xor_si128(temp3, temp2);
509 }
510
511 template<std::size_t K, std::size_t R>
512 inline void
513 AES<K,R>::aesni192ExpandKey([[maybe_unused]] uint8_t key[4 * K]) {
514 if constexpr (K == 6) {
515 __m128i temp1, temp2, temp3;
516 temp1 = _mm_loadu_si128(reinterpret_cast<__m128i*>(key));
517 temp3 = _mm_loadu_si128(reinterpret_cast<__m128i*>((key + 16)));
518 _expKey.hwKey.cipherKey[0] = temp1;
519 _expKey.hwKey.cipherKey[1] = temp3;
520 temp2 = _mm_aeskeygenassist_si128(temp3, 0x1);
521 aes192assist(temp1, temp2, temp3);
522 _expKey.hwKey.cipherKey[1] = reinterpret_cast<__m128i>(_mm_shuffle_pd(reinterpret_cast<__m128d>(_expKey.hwKey.cipherKey[1]),
523 reinterpret_cast<__m128d>(temp1), 0));
524 _expKey.hwKey.cipherKey[2] = reinterpret_cast<__m128i>(_mm_shuffle_pd(reinterpret_cast<__m128d>(temp1),
525 reinterpret_cast<__m128d>(temp3), 1));
526 temp2 = _mm_aeskeygenassist_si128(temp3, 0x2);
527 aes192assist(temp1, temp2, temp3);
528 _expKey.hwKey.cipherKey[3] = temp1;
529 _expKey.hwKey.cipherKey[4] = temp3;
530 temp2 = _mm_aeskeygenassist_si128(temp3, 0x4);
531 aes192assist(temp1, temp2, temp3);
532 _expKey.hwKey.cipherKey[4] = reinterpret_cast<__m128i>(_mm_shuffle_pd(reinterpret_cast<__m128d>(_expKey.hwKey.cipherKey[4]),
533 reinterpret_cast<__m128d>(temp1), 0));
534 _expKey.hwKey.cipherKey[5] = reinterpret_cast<__m128i>(_mm_shuffle_pd(reinterpret_cast<__m128d>(temp1),
535 reinterpret_cast<__m128d>(temp3), 1));
536 temp2 = _mm_aeskeygenassist_si128(temp3, 0x8);
537 aes192assist(temp1, temp2, temp3);
538 _expKey.hwKey.cipherKey[6] = temp1;
539 _expKey.hwKey.cipherKey[7] = temp3;
540 temp2 = _mm_aeskeygenassist_si128(temp3, 0x10);
541 aes192assist(temp1, temp2, temp3);
542 _expKey.hwKey.cipherKey[7] = reinterpret_cast<__m128i>(_mm_shuffle_pd(reinterpret_cast<__m128d>(_expKey.hwKey.cipherKey[7]),
543 reinterpret_cast<__m128d>(temp1), 0));
544 _expKey.hwKey.cipherKey[8] = reinterpret_cast<__m128i>(_mm_shuffle_pd(reinterpret_cast<__m128d>(temp1),
545 reinterpret_cast<__m128d>(temp3), 1));
546 temp2 = _mm_aeskeygenassist_si128 (temp3, 0x20);
547 aes192assist(temp1, temp2, temp3);
548 _expKey.hwKey.cipherKey[9] = temp1;
549 _expKey.hwKey.cipherKey[10] = temp3;
550 temp2 = _mm_aeskeygenassist_si128(temp3, 0x40);
551 aes192assist(temp1, temp2, temp3);
552 _expKey.hwKey.cipherKey[10] = reinterpret_cast<__m128i>(_mm_shuffle_pd(reinterpret_cast<__m128d>(_expKey.hwKey.cipherKey[10]),
553 reinterpret_cast<__m128d>(temp1), 0));
554 _expKey.hwKey.cipherKey[11] = reinterpret_cast<__m128i>(_mm_shuffle_pd(reinterpret_cast<__m128d>(temp1),
555 reinterpret_cast<__m128d>(temp3), 1));
556 temp2 = _mm_aeskeygenassist_si128(temp3, 0x80);
557 aes192assist(temp1, temp2, temp3);
558 _expKey.hwKey.cipherKey[12] = temp1;
559 }
560 }
561
562 template<std::size_t K, std::size_t R>
563 inline void
564 AES<K,R>::aes256assist1(__m128i& temp1, __m128i& temp2) {
565 __m128i temp4;
566 temp2 = _mm_shuffle_epi32(temp2, 0xff);
567 temp4 = _mm_slli_si128(temp1, 0x4);
568 temp1 = _mm_xor_si128(temp1, temp4);
569 temp4 = _mm_slli_si128(temp4, 0x4);
570 temp1 = _mm_xor_si128(temp1, temp4);
571 temp4 = _mm_slli_si128(temp4, 0x4);
572 temp1 = _mm_xor_si128(temp1, temp4);
573 temp1 = _mm_xor_si128(temp1, temp2);
574 }
575
576 template<std::size_t K, std::size_t R>
577 inline void
578 AES<K,R>::aes256assist2(__m128i& temp1, __m128i& temp3) {
579 __m128i temp2,temp4;
580 temp4 = _mm_aeskeygenassist_si128(temp1, 0x0);
581 temp2 = _mm_shuffle_epi32(temp4, 0xaa);
582 temp4 = _mm_slli_si128(temp3, 0x4);
583 temp3 = _mm_xor_si128(temp3, temp4);
584 temp4 = _mm_slli_si128(temp4, 0x4);
585 temp3 = _mm_xor_si128(temp3, temp4);
586 temp4 = _mm_slli_si128(temp4, 0x4);
587 temp3 = _mm_xor_si128(temp3, temp4);
588 temp3 = _mm_xor_si128(temp3, temp2);
589 }
590
591 template<std::size_t K, std::size_t R>
592 inline void
593 AES<K,R>::aesni256ExpandKey([[maybe_unused]] uint8_t key[4 * K]) {
594 if constexpr (K == 8) {
595 __m128i temp1, temp2, temp3;
596 temp1 = _mm_loadu_si128(reinterpret_cast<__m128i*>(key));
597 temp3 = _mm_loadu_si128(reinterpret_cast<__m128i*>(key + 16));
598 _expKey.hwKey.cipherKey[0] = temp1;
599 _expKey.hwKey.cipherKey[1] = temp3;
600 temp2 = _mm_aeskeygenassist_si128(temp3, 0x01);
601 aes256assist1(temp1, temp2);
602 _expKey.hwKey.cipherKey[2] = temp1;
603 aes256assist2(temp1, temp3);
604 _expKey.hwKey.cipherKey[3] = temp3;
605 temp2 = _mm_aeskeygenassist_si128(temp3, 0x02);
606 aes256assist1(temp1, temp2);
607 _expKey.hwKey.cipherKey[4] = temp1;
608 aes256assist2(temp1, temp3);
609 _expKey.hwKey.cipherKey[5] = temp3;
610 temp2 = _mm_aeskeygenassist_si128(temp3, 0x04);
611 aes256assist1(temp1, temp2);
612 _expKey.hwKey.cipherKey[6] = temp1;
613 aes256assist2(temp1, temp3);
614 _expKey.hwKey.cipherKey[7] = temp3;
615 temp2 = _mm_aeskeygenassist_si128(temp3, 0x08);
616 aes256assist1(temp1, temp2);
617 _expKey.hwKey.cipherKey[8] = temp1;
618 aes256assist2(temp1, temp3);
619 _expKey.hwKey.cipherKey[9] = temp3;
620 temp2 = _mm_aeskeygenassist_si128(temp3, 0x10);
621 aes256assist1(temp1, temp2);
622 _expKey.hwKey.cipherKey[10] = temp1;
623 aes256assist2(temp1, temp3);
624 _expKey.hwKey.cipherKey[11] = temp3;
625 temp2 = _mm_aeskeygenassist_si128(temp3, 0x20);
626 aes256assist1(temp1, temp2);
627 _expKey.hwKey.cipherKey[12] = temp1;
628 aes256assist2(temp1, temp3);
629 _expKey.hwKey.cipherKey[13] = temp3;
630 temp2 = _mm_aeskeygenassist_si128(temp3, 0x40);
631 aes256assist1(temp1, temp2);
632 _expKey.hwKey.cipherKey[14] = temp1;
633 }
634 }
635
636 template<std::size_t K, std::size_t R>
637 void
638 AES<K,R>::aesniExpandKey(uint8_t key[4 * K]) {
639 // Compute cipher key +
640 aesni128ExpandKey(key);
641 aesni192ExpandKey(key);
642 aesni256ExpandKey(key);
643 // Compute cipher key -
644
645 // Compute decipher key +
646 _expKey.hwKey.decipherKey[R] = _expKey.hwKey.cipherKey[0];
647 _expKey.hwKey.decipherKey[R - 1] = _mm_aesimc_si128(_expKey.hwKey.cipherKey[1]);
648 _expKey.hwKey.decipherKey[R - 2] = _mm_aesimc_si128(_expKey.hwKey.cipherKey[2]);
649 _expKey.hwKey.decipherKey[R - 3] = _mm_aesimc_si128(_expKey.hwKey.cipherKey[3]);
650 _expKey.hwKey.decipherKey[R - 4] = _mm_aesimc_si128(_expKey.hwKey.cipherKey[4]);
651 _expKey.hwKey.decipherKey[R - 5] = _mm_aesimc_si128(_expKey.hwKey.cipherKey[5]);
652 _expKey.hwKey.decipherKey[R - 6] = _mm_aesimc_si128(_expKey.hwKey.cipherKey[6]);
653 _expKey.hwKey.decipherKey[R - 7] = _mm_aesimc_si128(_expKey.hwKey.cipherKey[7]);
654 _expKey.hwKey.decipherKey[R - 8] = _mm_aesimc_si128(_expKey.hwKey.cipherKey[8]);
655 _expKey.hwKey.decipherKey[R - 9] = _mm_aesimc_si128(_expKey.hwKey.cipherKey[9]);
656 if constexpr (R > 10) {
657 _expKey.hwKey.decipherKey[R - 10] = _mm_aesimc_si128(_expKey.hwKey.cipherKey[10]);
658 _expKey.hwKey.decipherKey[R - 11] = _mm_aesimc_si128(_expKey.hwKey.cipherKey[11]);
659 }
660 if constexpr (R > 12) {
661 _expKey.hwKey.decipherKey[R - 12] = _mm_aesimc_si128(_expKey.hwKey.cipherKey[12]);
662 _expKey.hwKey.decipherKey[R - 13] = _mm_aesimc_si128(_expKey.hwKey.cipherKey[13]);
663 }
664 _expKey.hwKey.decipherKey[0] = _expKey.hwKey.cipherKey[R];
665 // Compute decipher key -
666 }
667#endif // ANCH_CPU_AES
668
669#if defined ANCH_CPU_DETECTION || !defined(ANCH_CPU_AES)
671 extern const uint8_t ANCH_AES_CIPHER_SBOX[256];
672
674 extern const uint8_t ANCH_AES_DECIPHER_SBOX[256];
675
677 extern const uint32_t ANCH_AES_RCON[11];
678
679 template<std::size_t K, std::size_t R>
680 void
681 AES<K,R>::swCipher(const std::array<uint8_t,16>& input, std::array<uint8_t,16>& output) {
682 std::memcpy(&_state, input.data(), 16);
683 unsigned int round = 0;
684
685 // Initial round +
686 addRoundKey(round);
687 // Initial round -
688
689 // Rounds +
690 for(round = 1 ; round < R ; ++round) {
691 cipherSubBytes();
692 cipherShiftRows();
693 cipherMixColumns();
694 addRoundKey(round);
695 }
696 // Rounds -
697
698 // Final round +
699 cipherSubBytes();
700 cipherShiftRows();
701 addRoundKey(round);
702 // Final round -
703
704 std::memcpy(output.data(), &_state, 16);
705 }
706
707 template<std::size_t K, std::size_t R>
708 void
709 AES<K,R>::swDecipher(const std::array<uint8_t,16>& input, std::array<uint8_t,16>& output) {
710 std::memcpy(&_state, input.data(), 16);
711 unsigned int round = R;
712
713 // Initial round +
714 addRoundKey(round);
715 decipherShiftRows();
716 decipherSubBytes();
717 // Initial round -
718
719 // Rounds +
720 for(round = R - 1 ; round > 0 ; --round) {
721 addRoundKey(round);
722 decipherMixColumns();
723 decipherShiftRows();
724 decipherSubBytes();
725 }
726 // Rounds -
727
728 // Final round +
729 addRoundKey(round);
730 // Final round -
731
732 std::memcpy(output.data(), &_state, 16);
733 }
734
735 template<std::size_t K, std::size_t R>
736 void
737 AES<K,R>::expandKey(const uint8_t key[4 * K]) {
738 std::memcpy(_expKey.swKey, key, 4 * K);
739 for(std::size_t i = K ; i < 4 * (R + 1) ; ++i) {
740 uint32_t mod = static_cast<uint32_t>(i % K);
741 if(mod == 0) {
742 _expKey.swKey[i] = _expKey.swKey[i - K] ^ (subWord(rotateWord(_expKey.swKey[i - 1])) ^ ANCH_AES_RCON[i / K]);
743 } else if(K > 6 && mod == 4) {
744 _expKey.swKey[i] = _expKey.swKey[i - K] ^ subWord(_expKey.swKey[i - 1]);
745 } else {
746 _expKey.swKey[i] = _expKey.swKey[i - K] ^ _expKey.swKey[i - 1];
747 }
748 }
749 }
750
751 template<std::size_t K, std::size_t R>
752 inline uint32_t
753 AES<K,R>::subWord(const uint32_t& word) {
754 uint32_t res;
755 uint8_t* resBytes = reinterpret_cast<uint8_t*>(&res);
756 const uint8_t* const bytes = reinterpret_cast<const uint8_t* const>(&word);
757 resBytes[0] = ANCH_AES_CIPHER_SBOX[bytes[0]];
758 resBytes[1] = ANCH_AES_CIPHER_SBOX[bytes[1]];
759 resBytes[2] = ANCH_AES_CIPHER_SBOX[bytes[2]];
760 resBytes[3] = ANCH_AES_CIPHER_SBOX[bytes[3]];
761 return res;
762 }
763
764 template<std::size_t K, std::size_t R>
765 inline uint32_t
766 AES<K,R>::rotateWord(const uint32_t& word) {
767 return ((word << 24) | (word >> 8));
768 }
769
770 template<std::size_t K, std::size_t R>
771 inline void
772 AES<K,R>::cipherSubBytes() {
773 _state[0][0] = ANCH_AES_CIPHER_SBOX[_state[0][0]];
774 _state[0][1] = ANCH_AES_CIPHER_SBOX[_state[0][1]];
775 _state[0][2] = ANCH_AES_CIPHER_SBOX[_state[0][2]];
776 _state[0][3] = ANCH_AES_CIPHER_SBOX[_state[0][3]];
777 _state[1][0] = ANCH_AES_CIPHER_SBOX[_state[1][0]];
778 _state[1][1] = ANCH_AES_CIPHER_SBOX[_state[1][1]];
779 _state[1][2] = ANCH_AES_CIPHER_SBOX[_state[1][2]];
780 _state[1][3] = ANCH_AES_CIPHER_SBOX[_state[1][3]];
781 _state[2][0] = ANCH_AES_CIPHER_SBOX[_state[2][0]];
782 _state[2][1] = ANCH_AES_CIPHER_SBOX[_state[2][1]];
783 _state[2][2] = ANCH_AES_CIPHER_SBOX[_state[2][2]];
784 _state[2][3] = ANCH_AES_CIPHER_SBOX[_state[2][3]];
785 _state[3][0] = ANCH_AES_CIPHER_SBOX[_state[3][0]];
786 _state[3][1] = ANCH_AES_CIPHER_SBOX[_state[3][1]];
787 _state[3][2] = ANCH_AES_CIPHER_SBOX[_state[3][2]];
788 _state[3][3] = ANCH_AES_CIPHER_SBOX[_state[3][3]];
789 }
790
791 template<std::size_t K, std::size_t R>
792 inline void
793 AES<K,R>::decipherSubBytes() {
794 _state[0][0] = ANCH_AES_DECIPHER_SBOX[_state[0][0]];
795 _state[0][1] = ANCH_AES_DECIPHER_SBOX[_state[0][1]];
796 _state[0][2] = ANCH_AES_DECIPHER_SBOX[_state[0][2]];
797 _state[0][3] = ANCH_AES_DECIPHER_SBOX[_state[0][3]];
798 _state[1][0] = ANCH_AES_DECIPHER_SBOX[_state[1][0]];
799 _state[1][1] = ANCH_AES_DECIPHER_SBOX[_state[1][1]];
800 _state[1][2] = ANCH_AES_DECIPHER_SBOX[_state[1][2]];
801 _state[1][3] = ANCH_AES_DECIPHER_SBOX[_state[1][3]];
802 _state[2][0] = ANCH_AES_DECIPHER_SBOX[_state[2][0]];
803 _state[2][1] = ANCH_AES_DECIPHER_SBOX[_state[2][1]];
804 _state[2][2] = ANCH_AES_DECIPHER_SBOX[_state[2][2]];
805 _state[2][3] = ANCH_AES_DECIPHER_SBOX[_state[2][3]];
806 _state[3][0] = ANCH_AES_DECIPHER_SBOX[_state[3][0]];
807 _state[3][1] = ANCH_AES_DECIPHER_SBOX[_state[3][1]];
808 _state[3][2] = ANCH_AES_DECIPHER_SBOX[_state[3][2]];
809 _state[3][3] = ANCH_AES_DECIPHER_SBOX[_state[3][3]];
810 }
811
812 template<std::size_t K, std::size_t R>
813 inline void
814 AES<K,R>::cipherShiftRows() {
815 uint8_t tmp = _state[0][1];
816 _state[0][1] = _state[1][1];
817 _state[1][1] = _state[2][1];
818 _state[2][1] = _state[3][1];
819 _state[3][1] = tmp;
820 tmp = _state[1][2];
821 _state[1][2] = _state[3][2];
822 _state[3][2] = tmp;
823 tmp = _state[2][2];
824 _state[2][2] = _state[0][2];
825 _state[0][2] = tmp;
826 tmp = _state[3][3];
827 _state[3][3] = _state[2][3];
828 _state[2][3] = _state[1][3];
829 _state[1][3] = _state[0][3];
830 _state[0][3] = tmp;
831 }
832
833 template<std::size_t K, std::size_t R>
834 inline void
835 AES<K,R>::decipherShiftRows() {
836 uint8_t tmp = _state[3][1];
837 _state[3][1] = _state[2][1];
838 _state[2][1] = _state[1][1];
839 _state[1][1] = _state[0][1];
840 _state[0][1] = tmp;
841 tmp = _state[1][2];
842 _state[1][2] = _state[3][2];
843 _state[3][2] = tmp;
844 tmp = _state[2][2];
845 _state[2][2] = _state[0][2];
846 _state[0][2] = tmp;
847 tmp = _state[0][3];
848 _state[0][3] = _state[1][3];
849 _state[1][3] = _state[2][3];
850 _state[2][3] = _state[3][3];
851 _state[3][3] = tmp;
852 }
853
854 template<std::size_t K, std::size_t R>
855 inline void
856 AES<K,R>::cipherMixColumns() {
857 uint8_t state[4];
858
859 state[0] = _state[0][0];
860 state[1] = _state[0][1];
861 state[2] = _state[0][2];
862 state[3] = _state[0][3];
863 _state[0][0] = ANCH_GALOIS_MULT2[state[0]] ^ ANCH_GALOIS_MULT3[state[1]] ^ state[2] ^ state[3];
864 _state[0][1] = state[0] ^ ANCH_GALOIS_MULT2[state[1]] ^ ANCH_GALOIS_MULT3[state[2]] ^ state[3];
865 _state[0][2] = state[0] ^ state[1] ^ ANCH_GALOIS_MULT2[state[2]] ^ ANCH_GALOIS_MULT3[state[3]];
866 _state[0][3] = ANCH_GALOIS_MULT3[state[0]] ^ state[1] ^ state[2] ^ ANCH_GALOIS_MULT2[state[3]];
867
868 state[0] = _state[1][0];
869 state[1] = _state[1][1];
870 state[2] = _state[1][2];
871 state[3] = _state[1][3];
872 _state[1][0] = ANCH_GALOIS_MULT2[state[0]] ^ ANCH_GALOIS_MULT3[state[1]] ^ state[2] ^ state[3];
873 _state[1][1] = state[0] ^ ANCH_GALOIS_MULT2[state[1]] ^ ANCH_GALOIS_MULT3[state[2]] ^ state[3];
874 _state[1][2] = state[0] ^ state[1] ^ ANCH_GALOIS_MULT2[state[2]] ^ ANCH_GALOIS_MULT3[state[3]];
875 _state[1][3] = ANCH_GALOIS_MULT3[state[0]] ^ state[1] ^ state[2] ^ ANCH_GALOIS_MULT2[state[3]];
876
877 state[0] = _state[2][0];
878 state[1] = _state[2][1];
879 state[2] = _state[2][2];
880 state[3] = _state[2][3];
881 _state[2][0] = ANCH_GALOIS_MULT2[state[0]] ^ ANCH_GALOIS_MULT3[state[1]] ^ state[2] ^ state[3];
882 _state[2][1] = state[0] ^ ANCH_GALOIS_MULT2[state[1]] ^ ANCH_GALOIS_MULT3[state[2]] ^ state[3];
883 _state[2][2] = state[0] ^ state[1] ^ ANCH_GALOIS_MULT2[state[2]] ^ ANCH_GALOIS_MULT3[state[3]];
884 _state[2][3] = ANCH_GALOIS_MULT3[state[0]] ^ state[1] ^ state[2] ^ ANCH_GALOIS_MULT2[state[3]];
885
886 state[0] = _state[3][0];
887 state[1] = _state[3][1];
888 state[2] = _state[3][2];
889 state[3] = _state[3][3];
890 _state[3][0] = ANCH_GALOIS_MULT2[state[0]] ^ ANCH_GALOIS_MULT3[state[1]] ^ state[2] ^ state[3];
891 _state[3][1] = state[0] ^ ANCH_GALOIS_MULT2[state[1]] ^ ANCH_GALOIS_MULT3[state[2]] ^ state[3];
892 _state[3][2] = state[0] ^ state[1] ^ ANCH_GALOIS_MULT2[state[2]] ^ ANCH_GALOIS_MULT3[state[3]];
893 _state[3][3] = ANCH_GALOIS_MULT3[state[0]] ^ state[1] ^ state[2] ^ ANCH_GALOIS_MULT2[state[3]];
894 }
895
896 template<std::size_t K, std::size_t R>
897 inline void
898 AES<K,R>::decipherMixColumns() {
899 uint8_t state[4];
900
901 state[0] = _state[0][0];
902 state[1] = _state[0][1];
903 state[2] = _state[0][2];
904 state[3] = _state[0][3];
905 _state[0][0] = ANCH_GALOIS_MULT14[state[0]] ^ ANCH_GALOIS_MULT11[state[1]] ^ ANCH_GALOIS_MULT13[state[2]] ^ ANCH_GALOIS_MULT9[state[3]];
906 _state[0][1] = ANCH_GALOIS_MULT9[state[0]] ^ ANCH_GALOIS_MULT14[state[1]] ^ ANCH_GALOIS_MULT11[state[2]] ^ ANCH_GALOIS_MULT13[state[3]];
907 _state[0][2] = ANCH_GALOIS_MULT13[state[0]] ^ ANCH_GALOIS_MULT9[state[1]] ^ ANCH_GALOIS_MULT14[state[2]] ^ ANCH_GALOIS_MULT11[state[3]];
908 _state[0][3] = ANCH_GALOIS_MULT11[state[0]] ^ ANCH_GALOIS_MULT13[state[1]] ^ ANCH_GALOIS_MULT9[state[2]] ^ ANCH_GALOIS_MULT14[state[3]];
909
910 state[0] = _state[1][0];
911 state[1] = _state[1][1];
912 state[2] = _state[1][2];
913 state[3] = _state[1][3];
914 _state[1][0] = ANCH_GALOIS_MULT14[state[0]] ^ ANCH_GALOIS_MULT11[state[1]] ^ ANCH_GALOIS_MULT13[state[2]] ^ ANCH_GALOIS_MULT9[state[3]];
915 _state[1][1] = ANCH_GALOIS_MULT9[state[0]] ^ ANCH_GALOIS_MULT14[state[1]] ^ ANCH_GALOIS_MULT11[state[2]] ^ ANCH_GALOIS_MULT13[state[3]];
916 _state[1][2] = ANCH_GALOIS_MULT13[state[0]] ^ ANCH_GALOIS_MULT9[state[1]] ^ ANCH_GALOIS_MULT14[state[2]] ^ ANCH_GALOIS_MULT11[state[3]];
917 _state[1][3] = ANCH_GALOIS_MULT11[state[0]] ^ ANCH_GALOIS_MULT13[state[1]] ^ ANCH_GALOIS_MULT9[state[2]] ^ ANCH_GALOIS_MULT14[state[3]];
918
919 state[0] = _state[2][0];
920 state[1] = _state[2][1];
921 state[2] = _state[2][2];
922 state[3] = _state[2][3];
923 _state[2][0] = ANCH_GALOIS_MULT14[state[0]] ^ ANCH_GALOIS_MULT11[state[1]] ^ ANCH_GALOIS_MULT13[state[2]] ^ ANCH_GALOIS_MULT9[state[3]];
924 _state[2][1] = ANCH_GALOIS_MULT9[state[0]] ^ ANCH_GALOIS_MULT14[state[1]] ^ ANCH_GALOIS_MULT11[state[2]] ^ ANCH_GALOIS_MULT13[state[3]];
925 _state[2][2] = ANCH_GALOIS_MULT13[state[0]] ^ ANCH_GALOIS_MULT9[state[1]] ^ ANCH_GALOIS_MULT14[state[2]] ^ ANCH_GALOIS_MULT11[state[3]];
926 _state[2][3] = ANCH_GALOIS_MULT11[state[0]] ^ ANCH_GALOIS_MULT13[state[1]] ^ ANCH_GALOIS_MULT9[state[2]] ^ ANCH_GALOIS_MULT14[state[3]];
927
928 state[0] = _state[3][0];
929 state[1] = _state[3][1];
930 state[2] = _state[3][2];
931 state[3] = _state[3][3];
932 _state[3][0] = ANCH_GALOIS_MULT14[state[0]] ^ ANCH_GALOIS_MULT11[state[1]] ^ ANCH_GALOIS_MULT13[state[2]] ^ ANCH_GALOIS_MULT9[state[3]];
933 _state[3][1] = ANCH_GALOIS_MULT9[state[0]] ^ ANCH_GALOIS_MULT14[state[1]] ^ ANCH_GALOIS_MULT11[state[2]] ^ ANCH_GALOIS_MULT13[state[3]];
934 _state[3][2] = ANCH_GALOIS_MULT13[state[0]] ^ ANCH_GALOIS_MULT9[state[1]] ^ ANCH_GALOIS_MULT14[state[2]] ^ ANCH_GALOIS_MULT11[state[3]];
935 _state[3][3] = ANCH_GALOIS_MULT11[state[0]] ^ ANCH_GALOIS_MULT13[state[1]] ^ ANCH_GALOIS_MULT9[state[2]] ^ ANCH_GALOIS_MULT14[state[3]];
936 }
937
938 template<std::size_t K, std::size_t R>
939 inline void
940 AES<K,R>::addRoundKey(const uint32_t& round) {
941 uint32_t* key = _expKey.swKey + 4 * round;
942 uint32_t* state = reinterpret_cast<uint32_t*>(_state);
943 state[0] ^= key[0];
944 state[1] ^= key[1];
945 state[2] ^= key[2];
946 state[3] ^= key[3];
947 }
948#endif // ANCH_CPU_DETECTION || !ANCH_CPU_AES
949 // Methods -
950
951 }
952}
static CPU & getInstance()
AES(const AES &other)
Definition aes.hpp:324
void cipher(const std::array< uint8_t, 16 > &input, std::array< uint8_t, 16 > &output)
Definition aes.hpp:353
virtual ~AES()
Definition aes.hpp:344
void decipher(const std::array< uint8_t, 16 > &input, std::array< uint8_t, 16 > &output)
Definition aes.hpp:369
AES(const uint8_t key[4 *K])
Definition aes.hpp:305
Block cipher interface.
Definition blockCipher.hpp:58
Cryptography namespace.
Definition base64.hpp:28
const uint8_t ANCH_AES_CIPHER_SBOX[256]
const uint8_t ANCH_GALOIS_MULT11[256]
const uint8_t ANCH_GALOIS_MULT9[256]
const uint32_t ANCH_AES_RCON[11]
const uint8_t ANCH_AES_DECIPHER_SBOX[256]
const uint8_t ANCH_GALOIS_MULT3[256]
const uint8_t ANCH_GALOIS_MULT14[256]
const uint8_t ANCH_GALOIS_MULT13[256]
const uint8_t ANCH_GALOIS_MULT2[256]
AnCH framework base namespace.
Definition app.hpp:28
Definition aes.hpp:50