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