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-2024 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.4.0
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 //AES128-ECB OID (2.16.840.1.101.3.4.1.1)
180 const uint8_t AES128_ECB_OID[9] = {0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x01, 0x01};
181 //AES128-CBC OID (2.16.840.1.101.3.4.1.2)
182 const uint8_t AES128_CBC_OID[9] = {0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x01, 0x02};
183 //AES128-OFB OID (2.16.840.1.101.3.4.1.3)
184 const uint8_t AES128_OFB_OID[9] = {0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x01, 0x03};
185 //AES128-CFB OID (2.16.840.1.101.3.4.1.4)
186 const uint8_t AES128_CFB_OID[9] = {0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x01, 0x04};
187 //AES128-GCM OID (2.16.840.1.101.3.4.1.6)
188 const uint8_t AES128_GCM_OID[9] = {0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x01, 0x06};
189 //AES128-CCM OID (2.16.840.1.101.3.4.1.7)
190 const uint8_t AES128_CCM_OID[9] = {0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x01, 0x07};
191 
192 //AES192-ECB OID (2.16.840.1.101.3.4.1.21)
193 const uint8_t AES192_ECB_OID[9] = {0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x01, 0x15};
194 //AES192-CBC OID (2.16.840.1.101.3.4.1.22)
195 const uint8_t AES192_CBC_OID[9] = {0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x01, 0x16};
196 //AES192-OFB OID (2.16.840.1.101.3.4.1.23)
197 const uint8_t AES192_OFB_OID[9] = {0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x01, 0x17};
198 //AES192-CFB OID (2.16.840.1.101.3.4.1.24)
199 const uint8_t AES192_CFB_OID[9] = {0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x01, 0x18};
200 //AES192-GCM OID (2.16.840.1.101.3.4.1.26)
201 const uint8_t AES192_GCM_OID[9] = {0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x01, 0x1A};
202 //AES192-CCM OID (2.16.840.1.101.3.4.1.27)
203 const uint8_t AES192_CCM_OID[9] = {0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x01, 0x1B};
204 
205 //AES256-ECB OID (2.16.840.1.101.3.4.1.41)
206 const uint8_t AES256_ECB_OID[9] = {0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x01, 0x29};
207 //AES256-CBC OID (2.16.840.1.101.3.4.1.42)
208 const uint8_t AES256_CBC_OID[9] = {0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x01, 0x2A};
209 //AES256-OFB OID (2.16.840.1.101.3.4.1.43)
210 const uint8_t AES256_OFB_OID[9] = {0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x01, 0x2B};
211 //AES256-CFB OID (2.16.840.1.101.3.4.1.44)
212 const uint8_t AES256_CFB_OID[9] = {0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x01, 0x2C};
213 //AES256-GCM OID (2.16.840.1.101.3.4.1.46)
214 const uint8_t AES256_GCM_OID[9] = {0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x01, 0x2E};
215 //AES256-CCM OID (2.16.840.1.101.3.4.1.47)
216 const uint8_t AES256_CCM_OID[9] = {0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x01, 0x2F};
217 
218 //Common interface for encryption algorithms
220 {
221  "AES",
222  sizeof(AesContext),
226  NULL,
227  NULL,
231 };
232 
233 
234 /**
235  * @brief Key expansion
236  * @param[in] context Pointer to the AES context to initialize
237  * @param[in] key Pointer to the key
238  * @param[in] keyLen Length of the key
239  * @return Error code
240  **/
241 
242 __weak_func error_t aesInit(AesContext *context, const uint8_t *key,
243  size_t keyLen)
244 {
245  uint_t i;
246  uint32_t temp;
247  size_t keyScheduleSize;
248 
249  //Check parameters
250  if(context == NULL || key == NULL)
252 
253  //Check the length of the key
254  if(keyLen == 16)
255  {
256  //10 rounds are required for 128-bit key
257  context->nr = 10;
258  }
259  else if(keyLen == 24)
260  {
261  //12 rounds are required for 192-bit key
262  context->nr = 12;
263  }
264  else if(keyLen == 32)
265  {
266  //14 rounds are required for 256-bit key
267  context->nr = 14;
268  }
269  else
270  {
271  //Report an error
273  }
274 
275  //Determine the number of 32-bit words in the key
276  keyLen /= 4;
277 
278  //Copy the original key
279  for(i = 0; i < keyLen; i++)
280  {
281  context->ek[i] = LOAD32LE(key + (i * 4));
282  }
283 
284  //The size of the key schedule depends on the number of rounds
285  keyScheduleSize = 4 * (context->nr + 1);
286 
287  //Generate the key schedule (encryption)
288  for(i = keyLen; i < keyScheduleSize; i++)
289  {
290  //Save previous word
291  temp = context->ek[i - 1];
292 
293  //Apply transformation
294  if((i % keyLen) == 0)
295  {
296  context->ek[i] = sbox[(temp >> 8) & 0xFF];
297  context->ek[i] |= (sbox[(temp >> 16) & 0xFF] << 8);
298  context->ek[i] |= (sbox[(temp >> 24) & 0xFF] << 16);
299  context->ek[i] |= (sbox[temp & 0xFF] << 24);
300  context->ek[i] ^= rcon[i / keyLen];
301  }
302  else if(keyLen > 6 && (i % keyLen) == 4)
303  {
304  context->ek[i] = sbox[temp & 0xFF];
305  context->ek[i] |= (sbox[(temp >> 8) & 0xFF] << 8);
306  context->ek[i] |= (sbox[(temp >> 16) & 0xFF] << 16);
307  context->ek[i] |= (sbox[(temp >> 24) & 0xFF] << 24);
308  }
309  else
310  {
311  context->ek[i] = temp;
312  }
313 
314  //Update the key schedule
315  context->ek[i] ^= context->ek[i - keyLen];
316  }
317 
318  //Generate the key schedule (decryption)
319  for(i = 0; i < keyScheduleSize; i++)
320  {
321  //Apply the InvMixColumns transformation to all round keys but the first
322  //and the last
323  if(i < 4 || i >= (keyScheduleSize - 4))
324  {
325  context->dk[i] = context->ek[i];
326  }
327  else
328  {
329  context->dk[i] = td[sbox[context->ek[i] & 0xFF]];
330  temp = td[sbox[(context->ek[i] >> 8) & 0xFF]];
331  context->dk[i] ^= ROL32(temp, 8);
332  temp = td[sbox[(context->ek[i] >> 16) & 0xFF]];
333  context->dk[i] ^= ROL32(temp, 16);
334  temp = td[sbox[(context->ek[i] >> 24) & 0xFF]];
335  context->dk[i] ^= ROL32(temp, 24);
336  }
337  }
338 
339  //No error to report
340  return NO_ERROR;
341 }
342 
343 
344 /**
345  * @brief Encrypt a 16-byte block using AES algorithm
346  * @param[in] context Pointer to the AES context
347  * @param[in] input Plaintext block to encrypt
348  * @param[out] output Ciphertext block resulting from encryption
349  **/
350 
351 __weak_func void aesEncryptBlock(AesContext *context, const uint8_t *input,
352  uint8_t *output)
353 {
354  uint_t i;
355  uint32_t s0;
356  uint32_t s1;
357  uint32_t s2;
358  uint32_t s3;
359  uint32_t t0;
360  uint32_t t1;
361  uint32_t t2;
362  uint32_t t3;
363  uint32_t temp;
364 
365  //Copy the plaintext to the state array
366  s0 = LOAD32LE(input + 0);
367  s1 = LOAD32LE(input + 4);
368  s2 = LOAD32LE(input + 8);
369  s3 = LOAD32LE(input + 12);
370 
371  //Initial round key addition
372  s0 ^= context->ek[0];
373  s1 ^= context->ek[1];
374  s2 ^= context->ek[2];
375  s3 ^= context->ek[3];
376 
377  //The number of rounds depends on the key length
378  for(i = 1; i < context->nr; i++)
379  {
380  //Apply round function
381  t0 = te[s0 & 0xFF];
382  temp = te[(s1 >> 8) & 0xFF];
383  t0 ^= ROL32(temp, 8);
384  temp = te[(s2 >> 16) & 0xFF];
385  t0 ^= ROL32(temp, 16);
386  temp = te[(s3 >> 24) & 0xFF];
387  t0 ^= ROL32(temp, 24);
388 
389  t1 = te[s1 & 0xFF];
390  temp = te[(s2 >> 8) & 0xFF];
391  t1 ^= ROL32(temp, 8);
392  temp = te[(s3 >> 16) & 0xFF];
393  t1 ^= ROL32(temp, 16);
394  temp = te[(s0 >> 24) & 0xFF];
395  t1 ^= ROL32(temp, 24);
396 
397  t2 = te[s2 & 0xFF];
398  temp = te[(s3 >> 8) & 0xFF];
399  t2 ^= ROL32(temp, 8);
400  temp = te[(s0 >> 16) & 0xFF];
401  t2 ^= ROL32(temp, 16);
402  temp = te[(s1 >> 24) & 0xFF];
403  t2 ^= ROL32(temp, 24);
404 
405  t3 = te[s3 & 0xFF];
406  temp = te[(s0 >> 8) & 0xFF];
407  t3 ^= ROL32(temp, 8);
408  temp = te[(s1 >> 16) & 0xFF];
409  t3 ^= ROL32(temp, 16);
410  temp = te[(s2 >> 24) & 0xFF];
411  t3 ^= ROL32(temp, 24);
412 
413  //Round key addition
414  s0 = t0 ^ context->ek[i * 4];
415  s1 = t1 ^ context->ek[i * 4 + 1];
416  s2 = t2 ^ context->ek[i * 4 + 2];
417  s3 = t3 ^ context->ek[i * 4 + 3];
418  }
419 
420  //The last round differs slightly from the first rounds
421  t0 = sbox[s0 & 0xFF];
422  t0 |= sbox[(s1 >> 8) & 0xFF] << 8;
423  t0 |= sbox[(s2 >> 16) & 0xFF] << 16;
424  t0 |= sbox[(s3 >> 24) & 0xFF] << 24;
425 
426  t1 = sbox[s1 & 0xFF];
427  t1 |= sbox[(s2 >> 8) & 0xFF] << 8;
428  t1 |= sbox[(s3 >> 16) & 0xFF] << 16;
429  t1 |= sbox[(s0 >> 24) & 0xFF] << 24;
430 
431  t2 = sbox[s2 & 0xFF];
432  t2 |= sbox[(s3 >> 8) & 0xFF] << 8;
433  t2 |= sbox[(s0 >> 16) & 0xFF] << 16;
434  t2 |= sbox[(s1 >> 24) & 0xFF] << 24;
435 
436  t3 = sbox[s3 & 0xFF];
437  t3 |= sbox[(s0 >> 8) & 0xFF] << 8;
438  t3 |= sbox[(s1 >> 16) & 0xFF] << 16;
439  t3 |= sbox[(s2 >> 24) & 0xFF] << 24;
440 
441  //Last round key addition
442  s0 = t0 ^ context->ek[context->nr * 4];
443  s1 = t1 ^ context->ek[context->nr * 4 + 1];
444  s2 = t2 ^ context->ek[context->nr * 4 + 2];
445  s3 = t3 ^ context->ek[context->nr * 4 + 3];
446 
447  //The final state is then copied to the output
448  STORE32LE(s0, output + 0);
449  STORE32LE(s1, output + 4);
450  STORE32LE(s2, output + 8);
451  STORE32LE(s3, output + 12);
452 }
453 
454 
455 /**
456  * @brief Decrypt a 16-byte block using AES algorithm
457  * @param[in] context Pointer to the AES context
458  * @param[in] input Ciphertext block to decrypt
459  * @param[out] output Plaintext block resulting from decryption
460  **/
461 
462 __weak_func void aesDecryptBlock(AesContext *context, const uint8_t *input,
463  uint8_t *output)
464 {
465  uint_t i;
466  uint32_t s0;
467  uint32_t s1;
468  uint32_t s2;
469  uint32_t s3;
470  uint32_t t0;
471  uint32_t t1;
472  uint32_t t2;
473  uint32_t t3;
474  uint32_t temp;
475 
476  //Copy the ciphertext to the state array
477  s0 = LOAD32LE(input + 0);
478  s1 = LOAD32LE(input + 4);
479  s2 = LOAD32LE(input + 8);
480  s3 = LOAD32LE(input + 12);
481 
482  //Initial round key addition
483  s0 ^= context->dk[context->nr * 4];
484  s1 ^= context->dk[context->nr * 4 + 1];
485  s2 ^= context->dk[context->nr * 4 + 2];
486  s3 ^= context->dk[context->nr * 4 + 3];
487 
488  //The number of rounds depends on the key length
489  for(i = context->nr - 1; i >= 1; i--)
490  {
491  //Apply round function
492  t0 = td[s0 & 0xFF];
493  temp = td[(s3 >> 8) & 0xFF];
494  t0 ^= ROL32(temp, 8);
495  temp = td[(s2 >> 16) & 0xFF];
496  t0 ^= ROL32(temp, 16);
497  temp = td[(s1 >> 24) & 0xFF];
498  t0 ^= ROL32(temp, 24);
499 
500  t1 = td[s1 & 0xFF];
501  temp = td[(s0 >> 8) & 0xFF];
502  t1 ^= ROL32(temp, 8);
503  temp = td[(s3 >> 16) & 0xFF];
504  t1 ^= ROL32(temp, 16);
505  temp = td[(s2 >> 24) & 0xFF];
506  t1 ^= ROL32(temp, 24);
507 
508  t2 = td[s2 & 0xFF];
509  temp = td[(s1 >> 8) & 0xFF];
510  t2 ^= ROL32(temp, 8);
511  temp = td[(s0 >> 16) & 0xFF];
512  t2 ^= ROL32(temp, 16);
513  temp = td[(s3 >> 24) & 0xFF];
514  t2 ^= ROL32(temp, 24);
515 
516  t3 = td[s3 & 0xFF];
517  temp = td[(s2 >> 8) & 0xFF];
518  t3 ^= ROL32(temp, 8);
519  temp = td[(s1 >> 16) & 0xFF];
520  t3 ^= ROL32(temp, 16);
521  temp = td[(s0 >> 24) & 0xFF];
522  t3 ^= ROL32(temp, 24);
523 
524  //Round key addition
525  s0 = t0 ^ context->dk[i * 4];
526  s1 = t1 ^ context->dk[i * 4 + 1];
527  s2 = t2 ^ context->dk[i * 4 + 2];
528  s3 = t3 ^ context->dk[i * 4 + 3];
529  }
530 
531  //The last round differs slightly from the first rounds
532  t0 = isbox[s0 & 0xFF];
533  t0 |= isbox[(s3 >> 8) & 0xFF] << 8;
534  t0 |= isbox[(s2 >> 16) & 0xFF] << 16;
535  t0 |= isbox[(s1 >> 24) & 0xFF] << 24;
536 
537  t1 = isbox[s1 & 0xFF];
538  t1 |= isbox[(s0 >> 8) & 0xFF] << 8;
539  t1 |= isbox[(s3 >> 16) & 0xFF] << 16;
540  t1 |= isbox[(s2 >> 24) & 0xFF] << 24;
541 
542  t2 = isbox[s2 & 0xFF];
543  t2 |= isbox[(s1 >> 8) & 0xFF] << 8;
544  t2 |= isbox[(s0 >> 16) & 0xFF] << 16;
545  t2 |= isbox[(s3 >> 24) & 0xFF] << 24;
546 
547  t3 = isbox[s3 & 0xFF];
548  t3 |= isbox[(s2 >> 8) & 0xFF] << 8;
549  t3 |= isbox[(s1 >> 16) & 0xFF] << 16;
550  t3 |= isbox[(s0 >> 24) & 0xFF] << 24;
551 
552  //Last round key addition
553  s0 = t0 ^ context->dk[0];
554  s1 = t1 ^ context->dk[1];
555  s2 = t2 ^ context->dk[2];
556  s3 = t3 ^ context->dk[3];
557 
558  //The final state is then copied to the output
559  STORE32LE(s0, output + 0);
560  STORE32LE(s1, output + 4);
561  STORE32LE(s2, output + 8);
562  STORE32LE(s3, output + 12);
563 }
564 
565 
566 /**
567  * @brief Release AES context
568  * @param[in] context Pointer to the AES context
569  **/
570 
571 __weak_func void aesDeinit(AesContext *context)
572 {
573  //Clear AES context
574  osMemset(context, 0, sizeof(AesContext));
575 }
576 
577 #endif
const uint8_t AES192_CBC_OID[9]
Definition: aes.c:195
const uint8_t AES256_CBC_OID[9]
Definition: aes.c:208
const uint8_t AES128_CCM_OID[9]
Definition: aes.c:190
__weak_func void aesDecryptBlock(AesContext *context, const uint8_t *input, uint8_t *output)
Decrypt a 16-byte block using AES algorithm.
Definition: aes.c:462
const uint8_t AES192_CFB_OID[9]
Definition: aes.c:199
const uint8_t AES256_OFB_OID[9]
Definition: aes.c:210
const uint8_t AES256_ECB_OID[9]
Definition: aes.c:206
const uint8_t AES192_OFB_OID[9]
Definition: aes.c:197
const uint8_t AES192_ECB_OID[9]
Definition: aes.c:193
const uint8_t AES128_ECB_OID[9]
Definition: aes.c:180
const uint8_t AES128_CFB_OID[9]
Definition: aes.c:186
const CipherAlgo aesCipherAlgo
Definition: aes.c:219
const uint8_t AES128_OFB_OID[9]
Definition: aes.c:184
const uint8_t AES128_GCM_OID[9]
Definition: aes.c:188
const uint8_t AES128_CBC_OID[9]
Definition: aes.c:182
const uint8_t AES256_CCM_OID[9]
Definition: aes.c:216
const uint8_t AES256_GCM_OID[9]
Definition: aes.c:214
const uint8_t AES192_CCM_OID[9]
Definition: aes.c:203
const uint8_t AES192_GCM_OID[9]
Definition: aes.c:201
__weak_func void aesDeinit(AesContext *context)
Release AES context.
Definition: aes.c:571
__weak_func void aesEncryptBlock(AesContext *context, const uint8_t *input, uint8_t *output)
Encrypt a 16-byte block using AES algorithm.
Definition: aes.c:351
__weak_func error_t aesInit(AesContext *context, const uint8_t *key, size_t keyLen)
Key expansion.
Definition: aes.c:242
const uint8_t AES256_CFB_OID[9]
Definition: aes.c:212
AES (Advanced Encryption Standard)
#define AES_BLOCK_SIZE
Definition: aes.h:43
unsigned int uint_t
Definition: compiler_port.h:50
#define LOAD32LE(p)
Definition: cpu_endian.h:203
#define STORE32LE(a, p)
Definition: cpu_endian.h:279
General definitions for cryptographic algorithms.
void(* CipherAlgoDeinit)(void *context)
Definition: crypto.h:983
void(* CipherAlgoDecryptBlock)(void *context, const uint8_t *input, uint8_t *output)
Definition: crypto.h:980
error_t(* CipherAlgoInit)(void *context, const uint8_t *key, size_t keyLen)
Definition: crypto.h:968
void(* CipherAlgoEncryptBlock)(void *context, const uint8_t *input, uint8_t *output)
Definition: crypto.h:977
#define ROL32(a, n)
Definition: crypto.h:776
@ CIPHER_ALGO_TYPE_BLOCK
Definition: crypto.h:932
uint32_t t1
uint32_t t2
error_t
Error codes.
Definition: error.h:43
@ ERROR_INVALID_KEY_LENGTH
Definition: error.h:107
@ NO_ERROR
Success.
Definition: error.h:44
@ ERROR_INVALID_PARAMETER
Invalid parameter.
Definition: error.h:47
#define osMemset(p, value, length)
Definition: os_port.h:135
AES algorithm context.
Definition: aes.h:58
uint_t nr
Definition: aes.h:59
uint32_t dk[60]
Definition: aes.h:61
uint32_t ek[60]
Definition: aes.h:60
Common interface for encryption algorithms.
Definition: crypto.h:1036