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-2023 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 2.2.4
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,
192 };
193 
194 
195 /**
196  * @brief Key expansion
197  * @param[in] context Pointer to the AES context to initialize
198  * @param[in] key Pointer to the key
199  * @param[in] keyLen Length of the key
200  * @return Error code
201  **/
202 
203 __weak_func error_t aesInit(AesContext *context, const uint8_t *key,
204  size_t keyLen)
205 {
206  uint_t i;
207  uint32_t temp;
208  size_t keyScheduleSize;
209 
210  //Check parameters
211  if(context == NULL || key == NULL)
213 
214  //Check the length of the key
215  if(keyLen == 16)
216  {
217  //10 rounds are required for 128-bit key
218  context->nr = 10;
219  }
220  else if(keyLen == 24)
221  {
222  //12 rounds are required for 192-bit key
223  context->nr = 12;
224  }
225  else if(keyLen == 32)
226  {
227  //14 rounds are required for 256-bit key
228  context->nr = 14;
229  }
230  else
231  {
232  //Report an error
234  }
235 
236  //Determine the number of 32-bit words in the key
237  keyLen /= 4;
238 
239  //Copy the original key
240  for(i = 0; i < keyLen; i++)
241  {
242  context->ek[i] = LOAD32LE(key + (i * 4));
243  }
244 
245  //The size of the key schedule depends on the number of rounds
246  keyScheduleSize = 4 * (context->nr + 1);
247 
248  //Generate the key schedule (encryption)
249  for(i = keyLen; i < keyScheduleSize; i++)
250  {
251  //Save previous word
252  temp = context->ek[i - 1];
253 
254  //Apply transformation
255  if((i % keyLen) == 0)
256  {
257  context->ek[i] = sbox[(temp >> 8) & 0xFF];
258  context->ek[i] |= (sbox[(temp >> 16) & 0xFF] << 8);
259  context->ek[i] |= (sbox[(temp >> 24) & 0xFF] << 16);
260  context->ek[i] |= (sbox[temp & 0xFF] << 24);
261  context->ek[i] ^= rcon[i / keyLen];
262  }
263  else if(keyLen > 6 && (i % keyLen) == 4)
264  {
265  context->ek[i] = sbox[temp & 0xFF];
266  context->ek[i] |= (sbox[(temp >> 8) & 0xFF] << 8);
267  context->ek[i] |= (sbox[(temp >> 16) & 0xFF] << 16);
268  context->ek[i] |= (sbox[(temp >> 24) & 0xFF] << 24);
269  }
270  else
271  {
272  context->ek[i] = temp;
273  }
274 
275  //Update the key schedule
276  context->ek[i] ^= context->ek[i - keyLen];
277  }
278 
279  //Generate the key schedule (decryption)
280  for(i = 0; i < keyScheduleSize; i++)
281  {
282  //Apply the InvMixColumns transformation to all round keys but the first
283  //and the last
284  if(i < 4 || i >= (keyScheduleSize - 4))
285  {
286  context->dk[i] = context->ek[i];
287  }
288  else
289  {
290  context->dk[i] = td[sbox[context->ek[i] & 0xFF]];
291  temp = td[sbox[(context->ek[i] >> 8) & 0xFF]];
292  context->dk[i] ^= ROL32(temp, 8);
293  temp = td[sbox[(context->ek[i] >> 16) & 0xFF]];
294  context->dk[i] ^= ROL32(temp, 16);
295  temp = td[sbox[(context->ek[i] >> 24) & 0xFF]];
296  context->dk[i] ^= ROL32(temp, 24);
297  }
298  }
299 
300  //No error to report
301  return NO_ERROR;
302 }
303 
304 
305 /**
306  * @brief Encrypt a 16-byte block using AES algorithm
307  * @param[in] context Pointer to the AES context
308  * @param[in] input Plaintext block to encrypt
309  * @param[out] output Ciphertext block resulting from encryption
310  **/
311 
312 __weak_func void aesEncryptBlock(AesContext *context, const uint8_t *input,
313  uint8_t *output)
314 {
315  uint_t i;
316  uint32_t s0;
317  uint32_t s1;
318  uint32_t s2;
319  uint32_t s3;
320  uint32_t t0;
321  uint32_t t1;
322  uint32_t t2;
323  uint32_t t3;
324  uint32_t temp;
325 
326  //Copy the plaintext to the state array
327  s0 = LOAD32LE(input + 0);
328  s1 = LOAD32LE(input + 4);
329  s2 = LOAD32LE(input + 8);
330  s3 = LOAD32LE(input + 12);
331 
332  //Initial round key addition
333  s0 ^= context->ek[0];
334  s1 ^= context->ek[1];
335  s2 ^= context->ek[2];
336  s3 ^= context->ek[3];
337 
338  //The number of rounds depends on the key length
339  for(i = 1; i < context->nr; i++)
340  {
341  //Apply round function
342  t0 = te[s0 & 0xFF];
343  temp = te[(s1 >> 8) & 0xFF];
344  t0 ^= ROL32(temp, 8);
345  temp = te[(s2 >> 16) & 0xFF];
346  t0 ^= ROL32(temp, 16);
347  temp = te[(s3 >> 24) & 0xFF];
348  t0 ^= ROL32(temp, 24);
349 
350  t1 = te[s1 & 0xFF];
351  temp = te[(s2 >> 8) & 0xFF];
352  t1 ^= ROL32(temp, 8);
353  temp = te[(s3 >> 16) & 0xFF];
354  t1 ^= ROL32(temp, 16);
355  temp = te[(s0 >> 24) & 0xFF];
356  t1 ^= ROL32(temp, 24);
357 
358  t2 = te[s2 & 0xFF];
359  temp = te[(s3 >> 8) & 0xFF];
360  t2 ^= ROL32(temp, 8);
361  temp = te[(s0 >> 16) & 0xFF];
362  t2 ^= ROL32(temp, 16);
363  temp = te[(s1 >> 24) & 0xFF];
364  t2 ^= ROL32(temp, 24);
365 
366  t3 = te[s3 & 0xFF];
367  temp = te[(s0 >> 8) & 0xFF];
368  t3 ^= ROL32(temp, 8);
369  temp = te[(s1 >> 16) & 0xFF];
370  t3 ^= ROL32(temp, 16);
371  temp = te[(s2 >> 24) & 0xFF];
372  t3 ^= ROL32(temp, 24);
373 
374  //Round key addition
375  s0 = t0 ^ context->ek[i * 4];
376  s1 = t1 ^ context->ek[i * 4 + 1];
377  s2 = t2 ^ context->ek[i * 4 + 2];
378  s3 = t3 ^ context->ek[i * 4 + 3];
379  }
380 
381  //The last round differs slightly from the first rounds
382  t0 = sbox[s0 & 0xFF];
383  t0 |= sbox[(s1 >> 8) & 0xFF] << 8;
384  t0 |= sbox[(s2 >> 16) & 0xFF] << 16;
385  t0 |= sbox[(s3 >> 24) & 0xFF] << 24;
386 
387  t1 = sbox[s1 & 0xFF];
388  t1 |= sbox[(s2 >> 8) & 0xFF] << 8;
389  t1 |= sbox[(s3 >> 16) & 0xFF] << 16;
390  t1 |= sbox[(s0 >> 24) & 0xFF] << 24;
391 
392  t2 = sbox[s2 & 0xFF];
393  t2 |= sbox[(s3 >> 8) & 0xFF] << 8;
394  t2 |= sbox[(s0 >> 16) & 0xFF] << 16;
395  t2 |= sbox[(s1 >> 24) & 0xFF] << 24;
396 
397  t3 = sbox[s3 & 0xFF];
398  t3 |= sbox[(s0 >> 8) & 0xFF] << 8;
399  t3 |= sbox[(s1 >> 16) & 0xFF] << 16;
400  t3 |= sbox[(s2 >> 24) & 0xFF] << 24;
401 
402  //Last round key addition
403  s0 = t0 ^ context->ek[context->nr * 4];
404  s1 = t1 ^ context->ek[context->nr * 4 + 1];
405  s2 = t2 ^ context->ek[context->nr * 4 + 2];
406  s3 = t3 ^ context->ek[context->nr * 4 + 3];
407 
408  //The final state is then copied to the output
409  STORE32LE(s0, output + 0);
410  STORE32LE(s1, output + 4);
411  STORE32LE(s2, output + 8);
412  STORE32LE(s3, output + 12);
413 }
414 
415 
416 /**
417  * @brief Decrypt a 16-byte block using AES algorithm
418  * @param[in] context Pointer to the AES context
419  * @param[in] input Ciphertext block to decrypt
420  * @param[out] output Plaintext block resulting from decryption
421  **/
422 
423 __weak_func void aesDecryptBlock(AesContext *context, const uint8_t *input,
424  uint8_t *output)
425 {
426  uint_t i;
427  uint32_t s0;
428  uint32_t s1;
429  uint32_t s2;
430  uint32_t s3;
431  uint32_t t0;
432  uint32_t t1;
433  uint32_t t2;
434  uint32_t t3;
435  uint32_t temp;
436 
437  //Copy the ciphertext to the state array
438  s0 = LOAD32LE(input + 0);
439  s1 = LOAD32LE(input + 4);
440  s2 = LOAD32LE(input + 8);
441  s3 = LOAD32LE(input + 12);
442 
443  //Initial round key addition
444  s0 ^= context->dk[context->nr * 4];
445  s1 ^= context->dk[context->nr * 4 + 1];
446  s2 ^= context->dk[context->nr * 4 + 2];
447  s3 ^= context->dk[context->nr * 4 + 3];
448 
449  //The number of rounds depends on the key length
450  for(i = context->nr - 1; i >= 1; i--)
451  {
452  //Apply round function
453  t0 = td[s0 & 0xFF];
454  temp = td[(s3 >> 8) & 0xFF];
455  t0 ^= ROL32(temp, 8);
456  temp = td[(s2 >> 16) & 0xFF];
457  t0 ^= ROL32(temp, 16);
458  temp = td[(s1 >> 24) & 0xFF];
459  t0 ^= ROL32(temp, 24);
460 
461  t1 = td[s1 & 0xFF];
462  temp = td[(s0 >> 8) & 0xFF];
463  t1 ^= ROL32(temp, 8);
464  temp = td[(s3 >> 16) & 0xFF];
465  t1 ^= ROL32(temp, 16);
466  temp = td[(s2 >> 24) & 0xFF];
467  t1 ^= ROL32(temp, 24);
468 
469  t2 = td[s2 & 0xFF];
470  temp = td[(s1 >> 8) & 0xFF];
471  t2 ^= ROL32(temp, 8);
472  temp = td[(s0 >> 16) & 0xFF];
473  t2 ^= ROL32(temp, 16);
474  temp = td[(s3 >> 24) & 0xFF];
475  t2 ^= ROL32(temp, 24);
476 
477  t3 = td[s3 & 0xFF];
478  temp = td[(s2 >> 8) & 0xFF];
479  t3 ^= ROL32(temp, 8);
480  temp = td[(s1 >> 16) & 0xFF];
481  t3 ^= ROL32(temp, 16);
482  temp = td[(s0 >> 24) & 0xFF];
483  t3 ^= ROL32(temp, 24);
484 
485  //Round key addition
486  s0 = t0 ^ context->dk[i * 4];
487  s1 = t1 ^ context->dk[i * 4 + 1];
488  s2 = t2 ^ context->dk[i * 4 + 2];
489  s3 = t3 ^ context->dk[i * 4 + 3];
490  }
491 
492  //The last round differs slightly from the first rounds
493  t0 = isbox[s0 & 0xFF];
494  t0 |= isbox[(s3 >> 8) & 0xFF] << 8;
495  t0 |= isbox[(s2 >> 16) & 0xFF] << 16;
496  t0 |= isbox[(s1 >> 24) & 0xFF] << 24;
497 
498  t1 = isbox[s1 & 0xFF];
499  t1 |= isbox[(s0 >> 8) & 0xFF] << 8;
500  t1 |= isbox[(s3 >> 16) & 0xFF] << 16;
501  t1 |= isbox[(s2 >> 24) & 0xFF] << 24;
502 
503  t2 = isbox[s2 & 0xFF];
504  t2 |= isbox[(s1 >> 8) & 0xFF] << 8;
505  t2 |= isbox[(s0 >> 16) & 0xFF] << 16;
506  t2 |= isbox[(s3 >> 24) & 0xFF] << 24;
507 
508  t3 = isbox[s3 & 0xFF];
509  t3 |= isbox[(s2 >> 8) & 0xFF] << 8;
510  t3 |= isbox[(s1 >> 16) & 0xFF] << 16;
511  t3 |= isbox[(s0 >> 24) & 0xFF] << 24;
512 
513  //Last round key addition
514  s0 = t0 ^ context->dk[0];
515  s1 = t1 ^ context->dk[1];
516  s2 = t2 ^ context->dk[2];
517  s3 = t3 ^ context->dk[3];
518 
519  //The final state is then copied to the output
520  STORE32LE(s0, output + 0);
521  STORE32LE(s1, output + 4);
522  STORE32LE(s2, output + 8);
523  STORE32LE(s3, output + 12);
524 }
525 
526 
527 /**
528  * @brief Release AES context
529  * @param[in] context Pointer to the AES context
530  **/
531 
532 __weak_func void aesDeinit(AesContext *context)
533 {
534  //Clear AES context
535  osMemset(context, 0, sizeof(AesContext));
536 }
537 
538 #endif
void(* CipherAlgoEncryptBlock)(void *context, const uint8_t *input, uint8_t *output)
Definition: crypto.h:921
@ CIPHER_ALGO_TYPE_BLOCK
Definition: crypto.h:876
#define STORE32LE(a, p)
Definition: cpu_endian.h:279
__weak_func void aesEncryptBlock(AesContext *context, const uint8_t *input, uint8_t *output)
Encrypt a 16-byte block using AES algorithm.
Definition: aes.c:312
AES algorithm context.
Definition: aes.h:58
#define AES_BLOCK_SIZE
Definition: aes.h:43
@ ERROR_INVALID_PARAMETER
Invalid parameter.
Definition: error.h:47
error_t
Error codes.
Definition: error.h:43
const CipherAlgo aesCipherAlgo
Definition: aes.c:180
void(* CipherAlgoDecryptBlock)(void *context, const uint8_t *input, uint8_t *output)
Definition: crypto.h:924
AES (Advanced Encryption Standard)
__weak_func error_t aesInit(AesContext *context, const uint8_t *key, size_t keyLen)
Key expansion.
Definition: aes.c:203
@ ERROR_INVALID_KEY_LENGTH
Definition: error.h:107
General definitions for cryptographic algorithms.
uint32_t t2
error_t(* CipherAlgoInit)(void *context, const uint8_t *key, size_t keyLen)
Definition: crypto.h:912
__weak_func void aesDecryptBlock(AesContext *context, const uint8_t *input, uint8_t *output)
Decrypt a 16-byte block using AES algorithm.
Definition: aes.c:423
uint_t nr
Definition: aes.h:59
__weak_func void aesDeinit(AesContext *context)
Release AES context.
Definition: aes.c:532
#define ROL32(a, n)
Definition: crypto.h:720
uint32_t t1
Common interface for encryption algorithms.
Definition: crypto.h:980
#define LOAD32LE(p)
Definition: cpu_endian.h:203
uint32_t ek[60]
Definition: aes.h:60
unsigned int uint_t
Definition: compiler_port.h:50
#define osMemset(p, value, length)
Definition: os_port.h:134
void(* CipherAlgoDeinit)(void *context)
Definition: crypto.h:927
uint32_t dk[60]
Definition: aes.h:61
@ NO_ERROR
Success.
Definition: error.h:44