aes.c
Go to the documentation of this file.
1 /**
2  * @file aes.c
3  * @brief AES (Advanced Encryption Standard)
4  *
5  * @section License
6  *
7  * SPDX-License-Identifier: GPL-2.0-or-later
8  *
9  * Copyright (C) 2010-2019 Oryx Embedded SARL. All rights reserved.
10  *
11  * This file is part of CycloneCrypto Open.
12  *
13  * This program is free software; you can redistribute it and/or
14  * modify it under the terms of the GNU General Public License
15  * as published by the Free Software Foundation; either version 2
16  * of the License, or (at your option) any later version.
17  *
18  * This program is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21  * GNU General Public License for more details.
22  *
23  * You should have received a copy of the GNU General Public License
24  * along with this program; if not, write to the Free Software Foundation,
25  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
26  *
27  * @section Description
28  *
29  * AES is an encryption standard based on Rijndael algorithm, a symmetric block
30  * cipher that can process data blocks of 128 bits, using cipher keys with
31  * lengths of 128, 192, and 256 bits. Refer to FIPS 197 for more details
32  *
33  * @author Oryx Embedded SARL (www.oryx-embedded.com)
34  * @version 1.9.6
35  **/
36 
37 //Switch to the appropriate trace level
38 #define TRACE_LEVEL CRYPTO_TRACE_LEVEL
39 
40 //Dependencies
41 #include "core/crypto.h"
42 #include "cipher/aes.h"
43 
44 //Check crypto library configuration
45 #if (AES_SUPPORT == ENABLED)
46 
47 //Substitution table used by encryption algorithm (S-box)
48 static const uint8_t sbox[256] =
49 {
50  0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5, 0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76,
51  0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0, 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0,
52  0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC, 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15,
53  0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A, 0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75,
54  0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0, 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84,
55  0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B, 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF,
56  0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85, 0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8,
57  0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5, 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2,
58  0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17, 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73,
59  0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88, 0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB,
60  0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C, 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79,
61  0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9, 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08,
62  0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6, 0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A,
63  0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E, 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E,
64  0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94, 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF,
65  0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68, 0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16
66 };
67 
68 //Substitution table used by decryption algorithm (inverse S-box)
69 static const uint8_t isbox[256] =
70 {
71  0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38, 0xBF, 0x40, 0xA3, 0x9E, 0x81, 0xF3, 0xD7, 0xFB,
72  0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87, 0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB,
73  0x54, 0x7B, 0x94, 0x32, 0xA6, 0xC2, 0x23, 0x3D, 0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E,
74  0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2, 0x76, 0x5B, 0xA2, 0x49, 0x6D, 0x8B, 0xD1, 0x25,
75  0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92,
76  0x6C, 0x70, 0x48, 0x50, 0xFD, 0xED, 0xB9, 0xDA, 0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84,
77  0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A, 0xF7, 0xE4, 0x58, 0x05, 0xB8, 0xB3, 0x45, 0x06,
78  0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02, 0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B,
79  0x3A, 0x91, 0x11, 0x41, 0x4F, 0x67, 0xDC, 0xEA, 0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73,
80  0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85, 0xE2, 0xF9, 0x37, 0xE8, 0x1C, 0x75, 0xDF, 0x6E,
81  0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89, 0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B,
82  0xFC, 0x56, 0x3E, 0x4B, 0xC6, 0xD2, 0x79, 0x20, 0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4,
83  0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31, 0xB1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xEC, 0x5F,
84  0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D, 0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF,
85  0xA0, 0xE0, 0x3B, 0x4D, 0xAE, 0x2A, 0xF5, 0xB0, 0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61,
86  0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26, 0xE1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0C, 0x7D
87 };
88 
89 //Precalculated table (encryption)
90 static const uint32_t te[256] =
91 {
92  0xA56363C6, 0x847C7CF8, 0x997777EE, 0x8D7B7BF6, 0x0DF2F2FF, 0xBD6B6BD6, 0xB16F6FDE, 0x54C5C591,
93  0x50303060, 0x03010102, 0xA96767CE, 0x7D2B2B56, 0x19FEFEE7, 0x62D7D7B5, 0xE6ABAB4D, 0x9A7676EC,
94  0x45CACA8F, 0x9D82821F, 0x40C9C989, 0x877D7DFA, 0x15FAFAEF, 0xEB5959B2, 0xC947478E, 0x0BF0F0FB,
95  0xECADAD41, 0x67D4D4B3, 0xFDA2A25F, 0xEAAFAF45, 0xBF9C9C23, 0xF7A4A453, 0x967272E4, 0x5BC0C09B,
96  0xC2B7B775, 0x1CFDFDE1, 0xAE93933D, 0x6A26264C, 0x5A36366C, 0x413F3F7E, 0x02F7F7F5, 0x4FCCCC83,
97  0x5C343468, 0xF4A5A551, 0x34E5E5D1, 0x08F1F1F9, 0x937171E2, 0x73D8D8AB, 0x53313162, 0x3F15152A,
98  0x0C040408, 0x52C7C795, 0x65232346, 0x5EC3C39D, 0x28181830, 0xA1969637, 0x0F05050A, 0xB59A9A2F,
99  0x0907070E, 0x36121224, 0x9B80801B, 0x3DE2E2DF, 0x26EBEBCD, 0x6927274E, 0xCDB2B27F, 0x9F7575EA,
100  0x1B090912, 0x9E83831D, 0x742C2C58, 0x2E1A1A34, 0x2D1B1B36, 0xB26E6EDC, 0xEE5A5AB4, 0xFBA0A05B,
101  0xF65252A4, 0x4D3B3B76, 0x61D6D6B7, 0xCEB3B37D, 0x7B292952, 0x3EE3E3DD, 0x712F2F5E, 0x97848413,
102  0xF55353A6, 0x68D1D1B9, 0x00000000, 0x2CEDEDC1, 0x60202040, 0x1FFCFCE3, 0xC8B1B179, 0xED5B5BB6,
103  0xBE6A6AD4, 0x46CBCB8D, 0xD9BEBE67, 0x4B393972, 0xDE4A4A94, 0xD44C4C98, 0xE85858B0, 0x4ACFCF85,
104  0x6BD0D0BB, 0x2AEFEFC5, 0xE5AAAA4F, 0x16FBFBED, 0xC5434386, 0xD74D4D9A, 0x55333366, 0x94858511,
105  0xCF45458A, 0x10F9F9E9, 0x06020204, 0x817F7FFE, 0xF05050A0, 0x443C3C78, 0xBA9F9F25, 0xE3A8A84B,
106  0xF35151A2, 0xFEA3A35D, 0xC0404080, 0x8A8F8F05, 0xAD92923F, 0xBC9D9D21, 0x48383870, 0x04F5F5F1,
107  0xDFBCBC63, 0xC1B6B677, 0x75DADAAF, 0x63212142, 0x30101020, 0x1AFFFFE5, 0x0EF3F3FD, 0x6DD2D2BF,
108  0x4CCDCD81, 0x140C0C18, 0x35131326, 0x2FECECC3, 0xE15F5FBE, 0xA2979735, 0xCC444488, 0x3917172E,
109  0x57C4C493, 0xF2A7A755, 0x827E7EFC, 0x473D3D7A, 0xAC6464C8, 0xE75D5DBA, 0x2B191932, 0x957373E6,
110  0xA06060C0, 0x98818119, 0xD14F4F9E, 0x7FDCDCA3, 0x66222244, 0x7E2A2A54, 0xAB90903B, 0x8388880B,
111  0xCA46468C, 0x29EEEEC7, 0xD3B8B86B, 0x3C141428, 0x79DEDEA7, 0xE25E5EBC, 0x1D0B0B16, 0x76DBDBAD,
112  0x3BE0E0DB, 0x56323264, 0x4E3A3A74, 0x1E0A0A14, 0xDB494992, 0x0A06060C, 0x6C242448, 0xE45C5CB8,
113  0x5DC2C29F, 0x6ED3D3BD, 0xEFACAC43, 0xA66262C4, 0xA8919139, 0xA4959531, 0x37E4E4D3, 0x8B7979F2,
114  0x32E7E7D5, 0x43C8C88B, 0x5937376E, 0xB76D6DDA, 0x8C8D8D01, 0x64D5D5B1, 0xD24E4E9C, 0xE0A9A949,
115  0xB46C6CD8, 0xFA5656AC, 0x07F4F4F3, 0x25EAEACF, 0xAF6565CA, 0x8E7A7AF4, 0xE9AEAE47, 0x18080810,
116  0xD5BABA6F, 0x887878F0, 0x6F25254A, 0x722E2E5C, 0x241C1C38, 0xF1A6A657, 0xC7B4B473, 0x51C6C697,
117  0x23E8E8CB, 0x7CDDDDA1, 0x9C7474E8, 0x211F1F3E, 0xDD4B4B96, 0xDCBDBD61, 0x868B8B0D, 0x858A8A0F,
118  0x907070E0, 0x423E3E7C, 0xC4B5B571, 0xAA6666CC, 0xD8484890, 0x05030306, 0x01F6F6F7, 0x120E0E1C,
119  0xA36161C2, 0x5F35356A, 0xF95757AE, 0xD0B9B969, 0x91868617, 0x58C1C199, 0x271D1D3A, 0xB99E9E27,
120  0x38E1E1D9, 0x13F8F8EB, 0xB398982B, 0x33111122, 0xBB6969D2, 0x70D9D9A9, 0x898E8E07, 0xA7949433,
121  0xB69B9B2D, 0x221E1E3C, 0x92878715, 0x20E9E9C9, 0x49CECE87, 0xFF5555AA, 0x78282850, 0x7ADFDFA5,
122  0x8F8C8C03, 0xF8A1A159, 0x80898909, 0x170D0D1A, 0xDABFBF65, 0x31E6E6D7, 0xC6424284, 0xB86868D0,
123  0xC3414182, 0xB0999929, 0x772D2D5A, 0x110F0F1E, 0xCBB0B07B, 0xFC5454A8, 0xD6BBBB6D, 0x3A16162C
124 };
125 
126 //Precalculated table (decryption)
127 static const uint32_t td[256] =
128 {
129  0x50A7F451, 0x5365417E, 0xC3A4171A, 0x965E273A, 0xCB6BAB3B, 0xF1459D1F, 0xAB58FAAC, 0x9303E34B,
130  0x55FA3020, 0xF66D76AD, 0x9176CC88, 0x254C02F5, 0xFCD7E54F, 0xD7CB2AC5, 0x80443526, 0x8FA362B5,
131  0x495AB1DE, 0x671BBA25, 0x980EEA45, 0xE1C0FE5D, 0x02752FC3, 0x12F04C81, 0xA397468D, 0xC6F9D36B,
132  0xE75F8F03, 0x959C9215, 0xEB7A6DBF, 0xDA595295, 0x2D83BED4, 0xD3217458, 0x2969E049, 0x44C8C98E,
133  0x6A89C275, 0x78798EF4, 0x6B3E5899, 0xDD71B927, 0xB64FE1BE, 0x17AD88F0, 0x66AC20C9, 0xB43ACE7D,
134  0x184ADF63, 0x82311AE5, 0x60335197, 0x457F5362, 0xE07764B1, 0x84AE6BBB, 0x1CA081FE, 0x942B08F9,
135  0x58684870, 0x19FD458F, 0x876CDE94, 0xB7F87B52, 0x23D373AB, 0xE2024B72, 0x578F1FE3, 0x2AAB5566,
136  0x0728EBB2, 0x03C2B52F, 0x9A7BC586, 0xA50837D3, 0xF2872830, 0xB2A5BF23, 0xBA6A0302, 0x5C8216ED,
137  0x2B1CCF8A, 0x92B479A7, 0xF0F207F3, 0xA1E2694E, 0xCDF4DA65, 0xD5BE0506, 0x1F6234D1, 0x8AFEA6C4,
138  0x9D532E34, 0xA055F3A2, 0x32E18A05, 0x75EBF6A4, 0x39EC830B, 0xAAEF6040, 0x069F715E, 0x51106EBD,
139  0xF98A213E, 0x3D06DD96, 0xAE053EDD, 0x46BDE64D, 0xB58D5491, 0x055DC471, 0x6FD40604, 0xFF155060,
140  0x24FB9819, 0x97E9BDD6, 0xCC434089, 0x779ED967, 0xBD42E8B0, 0x888B8907, 0x385B19E7, 0xDBEEC879,
141  0x470A7CA1, 0xE90F427C, 0xC91E84F8, 0x00000000, 0x83868009, 0x48ED2B32, 0xAC70111E, 0x4E725A6C,
142  0xFBFF0EFD, 0x5638850F, 0x1ED5AE3D, 0x27392D36, 0x64D90F0A, 0x21A65C68, 0xD1545B9B, 0x3A2E3624,
143  0xB1670A0C, 0x0FE75793, 0xD296EEB4, 0x9E919B1B, 0x4FC5C080, 0xA220DC61, 0x694B775A, 0x161A121C,
144  0x0ABA93E2, 0xE52AA0C0, 0x43E0223C, 0x1D171B12, 0x0B0D090E, 0xADC78BF2, 0xB9A8B62D, 0xC8A91E14,
145  0x8519F157, 0x4C0775AF, 0xBBDD99EE, 0xFD607FA3, 0x9F2601F7, 0xBCF5725C, 0xC53B6644, 0x347EFB5B,
146  0x7629438B, 0xDCC623CB, 0x68FCEDB6, 0x63F1E4B8, 0xCADC31D7, 0x10856342, 0x40229713, 0x2011C684,
147  0x7D244A85, 0xF83DBBD2, 0x1132F9AE, 0x6DA129C7, 0x4B2F9E1D, 0xF330B2DC, 0xEC52860D, 0xD0E3C177,
148  0x6C16B32B, 0x99B970A9, 0xFA489411, 0x2264E947, 0xC48CFCA8, 0x1A3FF0A0, 0xD82C7D56, 0xEF903322,
149  0xC74E4987, 0xC1D138D9, 0xFEA2CA8C, 0x360BD498, 0xCF81F5A6, 0x28DE7AA5, 0x268EB7DA, 0xA4BFAD3F,
150  0xE49D3A2C, 0x0D927850, 0x9BCC5F6A, 0x62467E54, 0xC2138DF6, 0xE8B8D890, 0x5EF7392E, 0xF5AFC382,
151  0xBE805D9F, 0x7C93D069, 0xA92DD56F, 0xB31225CF, 0x3B99ACC8, 0xA77D1810, 0x6E639CE8, 0x7BBB3BDB,
152  0x097826CD, 0xF418596E, 0x01B79AEC, 0xA89A4F83, 0x656E95E6, 0x7EE6FFAA, 0x08CFBC21, 0xE6E815EF,
153  0xD99BE7BA, 0xCE366F4A, 0xD4099FEA, 0xD67CB029, 0xAFB2A431, 0x31233F2A, 0x3094A5C6, 0xC066A235,
154  0x37BC4E74, 0xA6CA82FC, 0xB0D090E0, 0x15D8A733, 0x4A9804F1, 0xF7DAEC41, 0x0E50CD7F, 0x2FF69117,
155  0x8DD64D76, 0x4DB0EF43, 0x544DAACC, 0xDF0496E4, 0xE3B5D19E, 0x1B886A4C, 0xB81F2CC1, 0x7F516546,
156  0x04EA5E9D, 0x5D358C01, 0x737487FA, 0x2E410BFB, 0x5A1D67B3, 0x52D2DB92, 0x335610E9, 0x1347D66D,
157  0x8C61D79A, 0x7A0CA137, 0x8E14F859, 0x893C13EB, 0xEE27A9CE, 0x35C961B7, 0xEDE51CE1, 0x3CB1477A,
158  0x59DFD29C, 0x3F73F255, 0x79CE1418, 0xBF37C773, 0xEACDF753, 0x5BAAFD5F, 0x146F3DDF, 0x86DB4478,
159  0x81F3AFCA, 0x3EC468B9, 0x2C342438, 0x5F40A3C2, 0x72C31D16, 0x0C25E2BC, 0x8B493C28, 0x41950DFF,
160  0x7101A839, 0xDEB30C08, 0x9CE4B4D8, 0x90C15664, 0x6184CB7B, 0x70B632D5, 0x745C6C48, 0x4257B8D0
161 };
162 
163 //Round constant word array
164 static const uint32_t rcon[11] =
165 {
166  0x00000000,
167  0x00000001,
168  0x00000002,
169  0x00000004,
170  0x00000008,
171  0x00000010,
172  0x00000020,
173  0x00000040,
174  0x00000080,
175  0x0000001B,
176  0x00000036
177 };
178 
179 //Common interface for encryption algorithms
181 {
182  "AES",
183  sizeof(AesContext),
187  NULL,
188  NULL,
191 };
192 
193 
194 /**
195  * @brief Key expansion
196  * @param[in] context Pointer to the AES context to initialize
197  * @param[in] key Pointer to the key
198  * @param[in] keyLen Length of the key
199  * @return Error code
200  **/
201 
202 error_t aesInit(AesContext *context, const uint8_t *key, size_t keyLen)
203 {
204  uint_t i;
205  uint32_t temp;
206  size_t keyScheduleSize;
207 
208  //Check parameters
209  if(context == NULL || key == NULL)
211 
212  //Check the length of the key
213  if(keyLen == 16)
214  {
215  //10 rounds are required for 128-bit key
216  context->nr = 10;
217  }
218  else if(keyLen == 24)
219  {
220  //12 rounds are required for 192-bit key
221  context->nr = 12;
222  }
223  else if(keyLen == 32)
224  {
225  //14 rounds are required for 256-bit key
226  context->nr = 14;
227  }
228  else
229  {
230  //Report an error
232  }
233 
234  //Determine the number of 32-bit words in the key
235  keyLen /= 4;
236 
237  //Copy the original key
238  for(i = 0; i < keyLen; i++)
239  {
240  context->ek[i] = LOAD32LE(key + (i * 4));
241  }
242 
243  //The size of the key schedule depends on the number of rounds
244  keyScheduleSize = 4 * (context->nr + 1);
245 
246  //Generate the key schedule (encryption)
247  for(i = keyLen; i < keyScheduleSize; i++)
248  {
249  //Save previous word
250  temp = context->ek[i - 1];
251 
252  //Apply transformation
253  if((i % keyLen) == 0)
254  {
255  context->ek[i] = sbox[(temp >> 8) & 0xFF];
256  context->ek[i] |= (sbox[(temp >> 16) & 0xFF] << 8);
257  context->ek[i] |= (sbox[(temp >> 24) & 0xFF] << 16);
258  context->ek[i] |= (sbox[temp & 0xFF] << 24);
259  context->ek[i] ^= rcon[i / keyLen];
260  }
261  else if(keyLen > 6 && (i % keyLen) == 4)
262  {
263  context->ek[i] = sbox[temp & 0xFF];
264  context->ek[i] |= (sbox[(temp >> 8) & 0xFF] << 8);
265  context->ek[i] |= (sbox[(temp >> 16) & 0xFF] << 16);
266  context->ek[i] |= (sbox[(temp >> 24) & 0xFF] << 24);
267  }
268  else
269  {
270  context->ek[i] = temp;
271  }
272 
273  //Update the key schedule
274  context->ek[i] ^= context->ek[i - keyLen];
275  }
276 
277  //Generate the key schedule (decryption)
278  for(i = 0; i < keyScheduleSize; i++)
279  {
280  //Apply the InvMixColumns transformation to all round keys
281  //but the first and the last
282  if(i < 4 || i >= (keyScheduleSize - 4))
283  {
284  context->dk[i] = context->ek[i];
285  }
286  else
287  {
288  context->dk[i] = td[sbox[context->ek[i] & 0xFF]];
289  temp = td[sbox[(context->ek[i] >> 8) & 0xFF]];
290  context->dk[i] ^= ROL32(temp, 8);
291  temp = td[sbox[(context->ek[i] >> 16) & 0xFF]];
292  context->dk[i] ^= ROL32(temp, 16);
293  temp = td[sbox[(context->ek[i] >> 24) & 0xFF]];
294  context->dk[i] ^= ROL32(temp, 24);
295  }
296  }
297 
298  //No error to report
299  return NO_ERROR;
300 }
301 
302 
303 /**
304  * @brief Encrypt a 16-byte block using AES algorithm
305  * @param[in] context Pointer to the AES context
306  * @param[in] input Plaintext block to encrypt
307  * @param[out] output Ciphertext block resulting from encryption
308  **/
309 
310 void aesEncryptBlock(AesContext *context, const uint8_t *input, uint8_t *output)
311 {
312  uint_t i;
313  uint32_t s0;
314  uint32_t s1;
315  uint32_t s2;
316  uint32_t s3;
317  uint32_t t0;
318  uint32_t t1;
319  uint32_t t2;
320  uint32_t t3;
321  uint32_t temp;
322 
323  //Copy the plaintext to the state array
324  s0 = LOAD32LE(input + 0);
325  s1 = LOAD32LE(input + 4);
326  s2 = LOAD32LE(input + 8);
327  s3 = LOAD32LE(input + 12);
328 
329  //Initial round key addition
330  s0 ^= context->ek[0];
331  s1 ^= context->ek[1];
332  s2 ^= context->ek[2];
333  s3 ^= context->ek[3];
334 
335  //The number of rounds depends on the key length
336  for(i = 1; i < context->nr; i++)
337  {
338  //Apply round function
339  t0 = te[s0 & 0xFF];
340  temp = te[(s1 >> 8) & 0xFF];
341  t0 ^= ROL32(temp, 8);
342  temp = te[(s2 >> 16) & 0xFF];
343  t0 ^= ROL32(temp, 16);
344  temp = te[(s3 >> 24) & 0xFF];
345  t0 ^= ROL32(temp, 24);
346 
347  t1 = te[s1 & 0xFF];
348  temp = te[(s2 >> 8) & 0xFF];
349  t1 ^= ROL32(temp, 8);
350  temp = te[(s3 >> 16) & 0xFF];
351  t1 ^= ROL32(temp, 16);
352  temp = te[(s0 >> 24) & 0xFF];
353  t1 ^= ROL32(temp, 24);
354 
355  t2 = te[s2 & 0xFF];
356  temp = te[(s3 >> 8) & 0xFF];
357  t2 ^= ROL32(temp, 8);
358  temp = te[(s0 >> 16) & 0xFF];
359  t2 ^= ROL32(temp, 16);
360  temp = te[(s1 >> 24) & 0xFF];
361  t2 ^= ROL32(temp, 24);
362 
363  t3 = te[s3 & 0xFF];
364  temp = te[(s0 >> 8) & 0xFF];
365  t3 ^= ROL32(temp, 8);
366  temp = te[(s1 >> 16) & 0xFF];
367  t3 ^= ROL32(temp, 16);
368  temp = te[(s2 >> 24) & 0xFF];
369  t3 ^= ROL32(temp, 24);
370 
371  //Round key addition
372  s0 = t0 ^ context->ek[i * 4];
373  s1 = t1 ^ context->ek[i * 4 + 1];
374  s2 = t2 ^ context->ek[i * 4 + 2];
375  s3 = t3 ^ context->ek[i * 4 + 3];
376  }
377 
378  //The last round differs slightly from the first rounds
379  t0 = sbox[s0 & 0xFF];
380  t0 |= sbox[(s1 >> 8) & 0xFF] << 8;
381  t0 |= sbox[(s2 >> 16) & 0xFF] << 16;
382  t0 |= sbox[(s3 >> 24) & 0xFF] << 24;
383 
384  t1 = sbox[s1 & 0xFF];
385  t1 |= sbox[(s2 >> 8) & 0xFF] << 8;
386  t1 |= sbox[(s3 >> 16) & 0xFF] << 16;
387  t1 |= sbox[(s0 >> 24) & 0xFF] << 24;
388 
389  t2 = sbox[s2 & 0xFF];
390  t2 |= sbox[(s3 >> 8) & 0xFF] << 8;
391  t2 |= sbox[(s0 >> 16) & 0xFF] << 16;
392  t2 |= sbox[(s1 >> 24) & 0xFF] << 24;
393 
394  t3 = sbox[s3 & 0xFF];
395  t3 |= sbox[(s0 >> 8) & 0xFF] << 8;
396  t3 |= sbox[(s1 >> 16) & 0xFF] << 16;
397  t3 |= sbox[(s2 >> 24) & 0xFF] << 24;
398 
399  //Last round key addition
400  s0 = t0 ^ context->ek[context->nr * 4];
401  s1 = t1 ^ context->ek[context->nr * 4 + 1];
402  s2 = t2 ^ context->ek[context->nr * 4 + 2];
403  s3 = t3 ^ context->ek[context->nr * 4 + 3];
404 
405  //The final state is then copied to the output
406  STORE32LE(s0, output + 0);
407  STORE32LE(s1, output + 4);
408  STORE32LE(s2, output + 8);
409  STORE32LE(s3, output + 12);
410 }
411 
412 
413 /**
414  * @brief Decrypt a 16-byte block using AES algorithm
415  * @param[in] context Pointer to the AES context
416  * @param[in] input Ciphertext block to decrypt
417  * @param[out] output Plaintext block resulting from decryption
418  **/
419 
420 void aesDecryptBlock(AesContext *context, const uint8_t *input, uint8_t *output)
421 {
422  uint_t i;
423  uint32_t s0;
424  uint32_t s1;
425  uint32_t s2;
426  uint32_t s3;
427  uint32_t t0;
428  uint32_t t1;
429  uint32_t t2;
430  uint32_t t3;
431  uint32_t temp;
432 
433  //Copy the ciphertext to the state array
434  s0 = LOAD32LE(input + 0);
435  s1 = LOAD32LE(input + 4);
436  s2 = LOAD32LE(input + 8);
437  s3 = LOAD32LE(input + 12);
438 
439  //Initial round key addition
440  s0 ^= context->dk[context->nr * 4];
441  s1 ^= context->dk[context->nr * 4 + 1];
442  s2 ^= context->dk[context->nr * 4 + 2];
443  s3 ^= context->dk[context->nr * 4 + 3];
444 
445  //The number of rounds depends on the key length
446  for(i = context->nr - 1; i >= 1; i--)
447  {
448  //Apply round function
449  t0 = td[s0 & 0xFF];
450  temp = td[(s3 >> 8) & 0xFF];
451  t0 ^= ROL32(temp, 8);
452  temp = td[(s2 >> 16) & 0xFF];
453  t0 ^= ROL32(temp, 16);
454  temp = td[(s1 >> 24) & 0xFF];
455  t0 ^= ROL32(temp, 24);
456 
457  t1 = td[s1 & 0xFF];
458  temp = td[(s0 >> 8) & 0xFF];
459  t1 ^= ROL32(temp, 8);
460  temp = td[(s3 >> 16) & 0xFF];
461  t1 ^= ROL32(temp, 16);
462  temp = td[(s2 >> 24) & 0xFF];
463  t1 ^= ROL32(temp, 24);
464 
465  t2 = td[s2 & 0xFF];
466  temp = td[(s1 >> 8) & 0xFF];
467  t2 ^= ROL32(temp, 8);
468  temp = td[(s0 >> 16) & 0xFF];
469  t2 ^= ROL32(temp, 16);
470  temp = td[(s3 >> 24) & 0xFF];
471  t2 ^= ROL32(temp, 24);
472 
473  t3 = td[s3 & 0xFF];
474  temp = td[(s2 >> 8) & 0xFF];
475  t3 ^= ROL32(temp, 8);
476  temp = td[(s1 >> 16) & 0xFF];
477  t3 ^= ROL32(temp, 16);
478  temp = td[(s0 >> 24) & 0xFF];
479  t3 ^= ROL32(temp, 24);
480 
481  //Round key addition
482  s0 = t0 ^ context->dk[i * 4];
483  s1 = t1 ^ context->dk[i * 4 + 1];
484  s2 = t2 ^ context->dk[i * 4 + 2];
485  s3 = t3 ^ context->dk[i * 4 + 3];
486  }
487 
488  //The last round differs slightly from the first rounds
489  t0 = isbox[s0 & 0xFF];
490  t0 |= isbox[(s3 >> 8) & 0xFF] << 8;
491  t0 |= isbox[(s2 >> 16) & 0xFF] << 16;
492  t0 |= isbox[(s1 >> 24) & 0xFF] << 24;
493 
494  t1 = isbox[s1 & 0xFF];
495  t1 |= isbox[(s0 >> 8) & 0xFF] << 8;
496  t1 |= isbox[(s3 >> 16) & 0xFF] << 16;
497  t1 |= isbox[(s2 >> 24) & 0xFF] << 24;
498 
499  t2 = isbox[s2 & 0xFF];
500  t2 |= isbox[(s1 >> 8) & 0xFF] << 8;
501  t2 |= isbox[(s0 >> 16) & 0xFF] << 16;
502  t2 |= isbox[(s3 >> 24) & 0xFF] << 24;
503 
504  t3 = isbox[s3 & 0xFF];
505  t3 |= isbox[(s2 >> 8) & 0xFF] << 8;
506  t3 |= isbox[(s1 >> 16) & 0xFF] << 16;
507  t3 |= isbox[(s0 >> 24) & 0xFF] << 24;
508 
509  //Last round key addition
510  s0 = t0 ^ context->dk[0];
511  s1 = t1 ^ context->dk[1];
512  s2 = t2 ^ context->dk[2];
513  s3 = t3 ^ context->dk[3];
514 
515  //The final state is then copied to the output
516  STORE32LE(s0, output + 0);
517  STORE32LE(s1, output + 4);
518  STORE32LE(s2, output + 8);
519  STORE32LE(s3, output + 12);
520 }
521 
522 #endif
void aesDecryptBlock(AesContext *context, const uint8_t *input, uint8_t *output)
Decrypt a 16-byte block using AES algorithm.
Definition: aes.c:420
void(* CipherAlgoEncryptBlock)(void *context, const uint8_t *input, uint8_t *output)
Definition: crypto.h:1103
@ CIPHER_ALGO_TYPE_BLOCK
Definition: crypto.h:1069
#define STORE32LE(a, p)
Definition: cpu_endian.h:263
error_t aesInit(AesContext *context, const uint8_t *key, size_t keyLen)
Key expansion.
Definition: aes.c:202
AES algorithm context.
Definition: aes.h:52
#define AES_BLOCK_SIZE
Definition: aes.h:38
@ ERROR_INVALID_PARAMETER
Invalid parameter.
Definition: error.h:47
error_t
Error codes.
Definition: error.h:42
void aesEncryptBlock(AesContext *context, const uint8_t *input, uint8_t *output)
Encrypt a 16-byte block using AES algorithm.
Definition: aes.c:310
const CipherAlgo aesCipherAlgo
Definition: aes.c:180
void(* CipherAlgoDecryptBlock)(void *context, const uint8_t *input, uint8_t *output)
Definition: crypto.h:1104
AES (Advanced Encryption Standard)
@ ERROR_INVALID_KEY_LENGTH
Definition: error.h:105
General definitions for cryptographic algorithms.
uint32_t t2
error_t(* CipherAlgoInit)(void *context, const uint8_t *key, size_t keyLen)
Definition: crypto.h:1100
uint_t nr
Definition: aes.h:54
#define ROL32(a, n)
Definition: crypto.h:917
uint32_t t1
Common interface for encryption algorithms.
Definition: crypto.h:1150
#define LOAD32LE(p)
Definition: cpu_endian.h:187
uint32_t ek[60]
Definition: aes.h:55
unsigned int uint_t
Definition: compiler_port.h:45
uint32_t dk[60]
Definition: aes.h:56
@ NO_ERROR
Success.
Definition: error.h:44