Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
aes.c
00001 /** 00002 * @file aes.c 00003 * @brief AES (Advanced Encryption Standard) 00004 * 00005 * @section License 00006 * 00007 * Copyright (C) 2010-2017 Oryx Embedded SARL. All rights reserved. 00008 * 00009 * This file is part of CycloneCrypto Open. 00010 * 00011 * This program is free software; you can redistribute it and/or 00012 * modify it under the terms of the GNU General Public License 00013 * as published by the Free Software Foundation; either version 2 00014 * of the License, or (at your option) any later version. 00015 * 00016 * This program is distributed in the hope that it will be useful, 00017 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00018 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00019 * GNU General Public License for more details. 00020 * 00021 * You should have received a copy of the GNU General Public License 00022 * along with this program; if not, write to the Free Software Foundation, 00023 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00024 * 00025 * @section Description 00026 * 00027 * AES is an encryption standard based on Rijndael algorithm, a symmetric block 00028 * cipher that can process data blocks of 128 bits, using cipher keys with 00029 * lengths of 128, 192, and 256 bits. Refer to FIPS 197 for more details 00030 * 00031 * @author Oryx Embedded SARL (www.oryx-embedded.com) 00032 * @version 1.7.6 00033 **/ 00034 00035 //Switch to the appropriate trace level 00036 #define TRACE_LEVEL CRYPTO_TRACE_LEVEL 00037 00038 //Dependencies 00039 #include <string.h> 00040 #include "crypto.h" 00041 #include "aes.h" 00042 00043 //Check crypto library configuration 00044 #if (AES_SUPPORT == ENABLED) 00045 00046 //Substitution table used by encryption algorithm (S-box) 00047 static const uint8_t sbox[256] = 00048 { 00049 0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5, 0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76, 00050 0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0, 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0, 00051 0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC, 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15, 00052 0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A, 0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75, 00053 0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0, 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84, 00054 0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B, 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF, 00055 0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85, 0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8, 00056 0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5, 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2, 00057 0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17, 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73, 00058 0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88, 0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB, 00059 0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C, 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79, 00060 0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9, 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08, 00061 0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6, 0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A, 00062 0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E, 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E, 00063 0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94, 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF, 00064 0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68, 0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16 00065 }; 00066 00067 //Substitution table used by decryption algorithm (inverse S-box) 00068 static const uint8_t isbox[256] = 00069 { 00070 0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38, 0xBF, 0x40, 0xA3, 0x9E, 0x81, 0xF3, 0xD7, 0xFB, 00071 0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87, 0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB, 00072 0x54, 0x7B, 0x94, 0x32, 0xA6, 0xC2, 0x23, 0x3D, 0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E, 00073 0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2, 0x76, 0x5B, 0xA2, 0x49, 0x6D, 0x8B, 0xD1, 0x25, 00074 0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92, 00075 0x6C, 0x70, 0x48, 0x50, 0xFD, 0xED, 0xB9, 0xDA, 0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84, 00076 0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A, 0xF7, 0xE4, 0x58, 0x05, 0xB8, 0xB3, 0x45, 0x06, 00077 0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02, 0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B, 00078 0x3A, 0x91, 0x11, 0x41, 0x4F, 0x67, 0xDC, 0xEA, 0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73, 00079 0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85, 0xE2, 0xF9, 0x37, 0xE8, 0x1C, 0x75, 0xDF, 0x6E, 00080 0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89, 0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B, 00081 0xFC, 0x56, 0x3E, 0x4B, 0xC6, 0xD2, 0x79, 0x20, 0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4, 00082 0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31, 0xB1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xEC, 0x5F, 00083 0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D, 0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF, 00084 0xA0, 0xE0, 0x3B, 0x4D, 0xAE, 0x2A, 0xF5, 0xB0, 0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61, 00085 0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26, 0xE1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0C, 0x7D 00086 }; 00087 00088 //Precalculated table (encryption) 00089 static const uint32_t te[256] = 00090 { 00091 0xA56363C6, 0x847C7CF8, 0x997777EE, 0x8D7B7BF6, 0x0DF2F2FF, 0xBD6B6BD6, 0xB16F6FDE, 0x54C5C591, 00092 0x50303060, 0x03010102, 0xA96767CE, 0x7D2B2B56, 0x19FEFEE7, 0x62D7D7B5, 0xE6ABAB4D, 0x9A7676EC, 00093 0x45CACA8F, 0x9D82821F, 0x40C9C989, 0x877D7DFA, 0x15FAFAEF, 0xEB5959B2, 0xC947478E, 0x0BF0F0FB, 00094 0xECADAD41, 0x67D4D4B3, 0xFDA2A25F, 0xEAAFAF45, 0xBF9C9C23, 0xF7A4A453, 0x967272E4, 0x5BC0C09B, 00095 0xC2B7B775, 0x1CFDFDE1, 0xAE93933D, 0x6A26264C, 0x5A36366C, 0x413F3F7E, 0x02F7F7F5, 0x4FCCCC83, 00096 0x5C343468, 0xF4A5A551, 0x34E5E5D1, 0x08F1F1F9, 0x937171E2, 0x73D8D8AB, 0x53313162, 0x3F15152A, 00097 0x0C040408, 0x52C7C795, 0x65232346, 0x5EC3C39D, 0x28181830, 0xA1969637, 0x0F05050A, 0xB59A9A2F, 00098 0x0907070E, 0x36121224, 0x9B80801B, 0x3DE2E2DF, 0x26EBEBCD, 0x6927274E, 0xCDB2B27F, 0x9F7575EA, 00099 0x1B090912, 0x9E83831D, 0x742C2C58, 0x2E1A1A34, 0x2D1B1B36, 0xB26E6EDC, 0xEE5A5AB4, 0xFBA0A05B, 00100 0xF65252A4, 0x4D3B3B76, 0x61D6D6B7, 0xCEB3B37D, 0x7B292952, 0x3EE3E3DD, 0x712F2F5E, 0x97848413, 00101 0xF55353A6, 0x68D1D1B9, 0x00000000, 0x2CEDEDC1, 0x60202040, 0x1FFCFCE3, 0xC8B1B179, 0xED5B5BB6, 00102 0xBE6A6AD4, 0x46CBCB8D, 0xD9BEBE67, 0x4B393972, 0xDE4A4A94, 0xD44C4C98, 0xE85858B0, 0x4ACFCF85, 00103 0x6BD0D0BB, 0x2AEFEFC5, 0xE5AAAA4F, 0x16FBFBED, 0xC5434386, 0xD74D4D9A, 0x55333366, 0x94858511, 00104 0xCF45458A, 0x10F9F9E9, 0x06020204, 0x817F7FFE, 0xF05050A0, 0x443C3C78, 0xBA9F9F25, 0xE3A8A84B, 00105 0xF35151A2, 0xFEA3A35D, 0xC0404080, 0x8A8F8F05, 0xAD92923F, 0xBC9D9D21, 0x48383870, 0x04F5F5F1, 00106 0xDFBCBC63, 0xC1B6B677, 0x75DADAAF, 0x63212142, 0x30101020, 0x1AFFFFE5, 0x0EF3F3FD, 0x6DD2D2BF, 00107 0x4CCDCD81, 0x140C0C18, 0x35131326, 0x2FECECC3, 0xE15F5FBE, 0xA2979735, 0xCC444488, 0x3917172E, 00108 0x57C4C493, 0xF2A7A755, 0x827E7EFC, 0x473D3D7A, 0xAC6464C8, 0xE75D5DBA, 0x2B191932, 0x957373E6, 00109 0xA06060C0, 0x98818119, 0xD14F4F9E, 0x7FDCDCA3, 0x66222244, 0x7E2A2A54, 0xAB90903B, 0x8388880B, 00110 0xCA46468C, 0x29EEEEC7, 0xD3B8B86B, 0x3C141428, 0x79DEDEA7, 0xE25E5EBC, 0x1D0B0B16, 0x76DBDBAD, 00111 0x3BE0E0DB, 0x56323264, 0x4E3A3A74, 0x1E0A0A14, 0xDB494992, 0x0A06060C, 0x6C242448, 0xE45C5CB8, 00112 0x5DC2C29F, 0x6ED3D3BD, 0xEFACAC43, 0xA66262C4, 0xA8919139, 0xA4959531, 0x37E4E4D3, 0x8B7979F2, 00113 0x32E7E7D5, 0x43C8C88B, 0x5937376E, 0xB76D6DDA, 0x8C8D8D01, 0x64D5D5B1, 0xD24E4E9C, 0xE0A9A949, 00114 0xB46C6CD8, 0xFA5656AC, 0x07F4F4F3, 0x25EAEACF, 0xAF6565CA, 0x8E7A7AF4, 0xE9AEAE47, 0x18080810, 00115 0xD5BABA6F, 0x887878F0, 0x6F25254A, 0x722E2E5C, 0x241C1C38, 0xF1A6A657, 0xC7B4B473, 0x51C6C697, 00116 0x23E8E8CB, 0x7CDDDDA1, 0x9C7474E8, 0x211F1F3E, 0xDD4B4B96, 0xDCBDBD61, 0x868B8B0D, 0x858A8A0F, 00117 0x907070E0, 0x423E3E7C, 0xC4B5B571, 0xAA6666CC, 0xD8484890, 0x05030306, 0x01F6F6F7, 0x120E0E1C, 00118 0xA36161C2, 0x5F35356A, 0xF95757AE, 0xD0B9B969, 0x91868617, 0x58C1C199, 0x271D1D3A, 0xB99E9E27, 00119 0x38E1E1D9, 0x13F8F8EB, 0xB398982B, 0x33111122, 0xBB6969D2, 0x70D9D9A9, 0x898E8E07, 0xA7949433, 00120 0xB69B9B2D, 0x221E1E3C, 0x92878715, 0x20E9E9C9, 0x49CECE87, 0xFF5555AA, 0x78282850, 0x7ADFDFA5, 00121 0x8F8C8C03, 0xF8A1A159, 0x80898909, 0x170D0D1A, 0xDABFBF65, 0x31E6E6D7, 0xC6424284, 0xB86868D0, 00122 0xC3414182, 0xB0999929, 0x772D2D5A, 0x110F0F1E, 0xCBB0B07B, 0xFC5454A8, 0xD6BBBB6D, 0x3A16162C 00123 }; 00124 00125 //Precalculated table (decryption) 00126 static const uint32_t td[256] = 00127 { 00128 0x50A7F451, 0x5365417E, 0xC3A4171A, 0x965E273A, 0xCB6BAB3B, 0xF1459D1F, 0xAB58FAAC, 0x9303E34B, 00129 0x55FA3020, 0xF66D76AD, 0x9176CC88, 0x254C02F5, 0xFCD7E54F, 0xD7CB2AC5, 0x80443526, 0x8FA362B5, 00130 0x495AB1DE, 0x671BBA25, 0x980EEA45, 0xE1C0FE5D, 0x02752FC3, 0x12F04C81, 0xA397468D, 0xC6F9D36B, 00131 0xE75F8F03, 0x959C9215, 0xEB7A6DBF, 0xDA595295, 0x2D83BED4, 0xD3217458, 0x2969E049, 0x44C8C98E, 00132 0x6A89C275, 0x78798EF4, 0x6B3E5899, 0xDD71B927, 0xB64FE1BE, 0x17AD88F0, 0x66AC20C9, 0xB43ACE7D, 00133 0x184ADF63, 0x82311AE5, 0x60335197, 0x457F5362, 0xE07764B1, 0x84AE6BBB, 0x1CA081FE, 0x942B08F9, 00134 0x58684870, 0x19FD458F, 0x876CDE94, 0xB7F87B52, 0x23D373AB, 0xE2024B72, 0x578F1FE3, 0x2AAB5566, 00135 0x0728EBB2, 0x03C2B52F, 0x9A7BC586, 0xA50837D3, 0xF2872830, 0xB2A5BF23, 0xBA6A0302, 0x5C8216ED, 00136 0x2B1CCF8A, 0x92B479A7, 0xF0F207F3, 0xA1E2694E, 0xCDF4DA65, 0xD5BE0506, 0x1F6234D1, 0x8AFEA6C4, 00137 0x9D532E34, 0xA055F3A2, 0x32E18A05, 0x75EBF6A4, 0x39EC830B, 0xAAEF6040, 0x069F715E, 0x51106EBD, 00138 0xF98A213E, 0x3D06DD96, 0xAE053EDD, 0x46BDE64D, 0xB58D5491, 0x055DC471, 0x6FD40604, 0xFF155060, 00139 0x24FB9819, 0x97E9BDD6, 0xCC434089, 0x779ED967, 0xBD42E8B0, 0x888B8907, 0x385B19E7, 0xDBEEC879, 00140 0x470A7CA1, 0xE90F427C, 0xC91E84F8, 0x00000000, 0x83868009, 0x48ED2B32, 0xAC70111E, 0x4E725A6C, 00141 0xFBFF0EFD, 0x5638850F, 0x1ED5AE3D, 0x27392D36, 0x64D90F0A, 0x21A65C68, 0xD1545B9B, 0x3A2E3624, 00142 0xB1670A0C, 0x0FE75793, 0xD296EEB4, 0x9E919B1B, 0x4FC5C080, 0xA220DC61, 0x694B775A, 0x161A121C, 00143 0x0ABA93E2, 0xE52AA0C0, 0x43E0223C, 0x1D171B12, 0x0B0D090E, 0xADC78BF2, 0xB9A8B62D, 0xC8A91E14, 00144 0x8519F157, 0x4C0775AF, 0xBBDD99EE, 0xFD607FA3, 0x9F2601F7, 0xBCF5725C, 0xC53B6644, 0x347EFB5B, 00145 0x7629438B, 0xDCC623CB, 0x68FCEDB6, 0x63F1E4B8, 0xCADC31D7, 0x10856342, 0x40229713, 0x2011C684, 00146 0x7D244A85, 0xF83DBBD2, 0x1132F9AE, 0x6DA129C7, 0x4B2F9E1D, 0xF330B2DC, 0xEC52860D, 0xD0E3C177, 00147 0x6C16B32B, 0x99B970A9, 0xFA489411, 0x2264E947, 0xC48CFCA8, 0x1A3FF0A0, 0xD82C7D56, 0xEF903322, 00148 0xC74E4987, 0xC1D138D9, 0xFEA2CA8C, 0x360BD498, 0xCF81F5A6, 0x28DE7AA5, 0x268EB7DA, 0xA4BFAD3F, 00149 0xE49D3A2C, 0x0D927850, 0x9BCC5F6A, 0x62467E54, 0xC2138DF6, 0xE8B8D890, 0x5EF7392E, 0xF5AFC382, 00150 0xBE805D9F, 0x7C93D069, 0xA92DD56F, 0xB31225CF, 0x3B99ACC8, 0xA77D1810, 0x6E639CE8, 0x7BBB3BDB, 00151 0x097826CD, 0xF418596E, 0x01B79AEC, 0xA89A4F83, 0x656E95E6, 0x7EE6FFAA, 0x08CFBC21, 0xE6E815EF, 00152 0xD99BE7BA, 0xCE366F4A, 0xD4099FEA, 0xD67CB029, 0xAFB2A431, 0x31233F2A, 0x3094A5C6, 0xC066A235, 00153 0x37BC4E74, 0xA6CA82FC, 0xB0D090E0, 0x15D8A733, 0x4A9804F1, 0xF7DAEC41, 0x0E50CD7F, 0x2FF69117, 00154 0x8DD64D76, 0x4DB0EF43, 0x544DAACC, 0xDF0496E4, 0xE3B5D19E, 0x1B886A4C, 0xB81F2CC1, 0x7F516546, 00155 0x04EA5E9D, 0x5D358C01, 0x737487FA, 0x2E410BFB, 0x5A1D67B3, 0x52D2DB92, 0x335610E9, 0x1347D66D, 00156 0x8C61D79A, 0x7A0CA137, 0x8E14F859, 0x893C13EB, 0xEE27A9CE, 0x35C961B7, 0xEDE51CE1, 0x3CB1477A, 00157 0x59DFD29C, 0x3F73F255, 0x79CE1418, 0xBF37C773, 0xEACDF753, 0x5BAAFD5F, 0x146F3DDF, 0x86DB4478, 00158 0x81F3AFCA, 0x3EC468B9, 0x2C342438, 0x5F40A3C2, 0x72C31D16, 0x0C25E2BC, 0x8B493C28, 0x41950DFF, 00159 0x7101A839, 0xDEB30C08, 0x9CE4B4D8, 0x90C15664, 0x6184CB7B, 0x70B632D5, 0x745C6C48, 0x4257B8D0 00160 }; 00161 00162 //Round constant word array 00163 static const uint32_t rcon[11] = 00164 { 00165 0x00000000, 00166 0x00000001, 00167 0x00000002, 00168 0x00000004, 00169 0x00000008, 00170 0x00000010, 00171 0x00000020, 00172 0x00000040, 00173 0x00000080, 00174 0x0000001B, 00175 0x00000036 00176 }; 00177 00178 //Common interface for encryption algorithms 00179 const CipherAlgo aesCipherAlgo = 00180 { 00181 "AES", 00182 sizeof(AesContext), 00183 CIPHER_ALGO_TYPE_BLOCK, 00184 AES_BLOCK_SIZE, 00185 (CipherAlgoInit) aesInit, 00186 NULL, 00187 NULL, 00188 (CipherAlgoEncryptBlock) aesEncryptBlock, 00189 (CipherAlgoDecryptBlock) aesDecryptBlock 00190 }; 00191 00192 00193 /** 00194 * @brief Key expansion 00195 * @param[in] context Pointer to the AES context to initialize 00196 * @param[in] key Pointer to the key 00197 * @param[in] keyLength Length of the key 00198 * @return Error code 00199 **/ 00200 00201 error_t aesInit(AesContext *context, const uint8_t *key, size_t keyLength) 00202 { 00203 uint_t i; 00204 uint32_t temp; 00205 size_t keyScheduleSize; 00206 00207 //10 rounds are required for 128-bit key 00208 if(keyLength == 16) 00209 context->nr = 10; 00210 //12 rounds are required for 192-bit key 00211 else if(keyLength == 24) 00212 context->nr = 12; 00213 //14 rounds are required for 256-bit key 00214 else if(keyLength == 32) 00215 context->nr = 14; 00216 //Key length is not supported... 00217 else 00218 return ERROR_INVALID_KEY_LENGTH; 00219 00220 //Determine the number of 32-bit words in the key 00221 keyLength /= 4; 00222 00223 //Copy the original key 00224 for(i = 0; i < keyLength; i++) 00225 context->ek[i] = LOAD32LE(key + (i * 4)); 00226 00227 //The size of the key schedule depends on the number of rounds 00228 keyScheduleSize = 4 * (context->nr + 1); 00229 00230 //Generate the key schedule (encryption) 00231 for(i = keyLength; i < keyScheduleSize; i++) 00232 { 00233 //Save previous word 00234 temp = context->ek[i - 1]; 00235 00236 //Apply transformation 00237 if((i % keyLength) == 0) 00238 { 00239 context->ek[i] = sbox[(temp >> 8) & 0xFF]; 00240 context->ek[i] |= (sbox[(temp >> 16) & 0xFF] << 8); 00241 context->ek[i] |= (sbox[(temp >> 24) & 0xFF] << 16); 00242 context->ek[i] |= (sbox[temp & 0xFF] << 24); 00243 context->ek[i] ^= rcon[i / keyLength]; 00244 } 00245 else if(keyLength > 6 && (i % keyLength) == 4) 00246 { 00247 context->ek[i] = sbox[temp & 0xFF]; 00248 context->ek[i] |= (sbox[(temp >> 8) & 0xFF] << 8); 00249 context->ek[i] |= (sbox[(temp >> 16) & 0xFF] << 16); 00250 context->ek[i] |= (sbox[(temp >> 24) & 0xFF] << 24); 00251 } 00252 else 00253 { 00254 context->ek[i] = temp; 00255 } 00256 00257 //Update the key schedule 00258 context->ek[i] ^= context->ek[i - keyLength]; 00259 } 00260 00261 //Generate the key schedule (decryption) 00262 for(i = 0; i < keyScheduleSize; i++) 00263 { 00264 //Apply the InvMixColumns transformation to all round keys 00265 //but the first and the last 00266 if(i < 4 || i >= (keyScheduleSize - 4)) 00267 { 00268 context->dk[i] = context->ek[i]; 00269 } 00270 else 00271 { 00272 context->dk[i] = td[sbox[context->ek[i] & 0xFF]]; 00273 temp = td[sbox[(context->ek[i] >> 8) & 0xFF]]; 00274 context->dk[i] ^= ROL32(temp, 8); 00275 temp = td[sbox[(context->ek[i] >> 16) & 0xFF]]; 00276 context->dk[i] ^= ROL32(temp, 16); 00277 temp = td[sbox[(context->ek[i] >> 24) & 0xFF]]; 00278 context->dk[i] ^= ROL32(temp, 24); 00279 } 00280 } 00281 00282 //No error to report 00283 return NO_ERROR; 00284 } 00285 00286 00287 /** 00288 * @brief Encrypt a 16-byte block using AES algorithm 00289 * @param[in] context Pointer to the AES context 00290 * @param[in] input Plaintext block to encrypt 00291 * @param[out] output Ciphertext block resulting from encryption 00292 **/ 00293 00294 void aesEncryptBlock(AesContext *context, const uint8_t *input, uint8_t *output) 00295 { 00296 uint_t i; 00297 uint32_t s0; 00298 uint32_t s1; 00299 uint32_t s2; 00300 uint32_t s3; 00301 uint32_t t0; 00302 uint32_t t1; 00303 uint32_t t2; 00304 uint32_t t3; 00305 uint32_t temp; 00306 00307 //Copy the plaintext to the state array 00308 s0 = LOAD32LE(input + 0); 00309 s1 = LOAD32LE(input + 4); 00310 s2 = LOAD32LE(input + 8); 00311 s3 = LOAD32LE(input + 12); 00312 00313 //Initial round key addition 00314 s0 ^= context->ek[0]; 00315 s1 ^= context->ek[1]; 00316 s2 ^= context->ek[2]; 00317 s3 ^= context->ek[3]; 00318 00319 //The number of rounds depends on the key length 00320 for(i = 1; i < context->nr; i++) 00321 { 00322 //Apply round function 00323 t0 = te[s0 & 0xFF]; 00324 temp = te[(s1 >> 8) & 0xFF]; 00325 t0 ^= ROL32(temp, 8); 00326 temp = te[(s2 >> 16) & 0xFF]; 00327 t0 ^= ROL32(temp, 16); 00328 temp = te[(s3 >> 24) & 0xFF]; 00329 t0 ^= ROL32(temp, 24); 00330 00331 t1 = te[s1 & 0xFF]; 00332 temp = te[(s2 >> 8) & 0xFF]; 00333 t1 ^= ROL32(temp, 8); 00334 temp = te[(s3 >> 16) & 0xFF]; 00335 t1 ^= ROL32(temp, 16); 00336 temp = te[(s0 >> 24) & 0xFF]; 00337 t1 ^= ROL32(temp, 24); 00338 00339 t2 = te[s2 & 0xFF]; 00340 temp = te[(s3 >> 8) & 0xFF]; 00341 t2 ^= ROL32(temp, 8); 00342 temp = te[(s0 >> 16) & 0xFF]; 00343 t2 ^= ROL32(temp, 16); 00344 temp = te[(s1 >> 24) & 0xFF]; 00345 t2 ^= ROL32(temp, 24); 00346 00347 t3 = te[s3 & 0xFF]; 00348 temp = te[(s0 >> 8) & 0xFF]; 00349 t3 ^= ROL32(temp, 8); 00350 temp = te[(s1 >> 16) & 0xFF]; 00351 t3 ^= ROL32(temp, 16); 00352 temp = te[(s2 >> 24) & 0xFF]; 00353 t3 ^= ROL32(temp, 24); 00354 00355 //Round key addition 00356 s0 = t0 ^ context->ek[i * 4]; 00357 s1 = t1 ^ context->ek[i * 4 + 1]; 00358 s2 = t2 ^ context->ek[i * 4 + 2]; 00359 s3 = t3 ^ context->ek[i * 4 + 3]; 00360 } 00361 00362 //The last round differs slightly from the first rounds 00363 t0 = sbox[s0 & 0xFF]; 00364 t0 |= sbox[(s1 >> 8) & 0xFF] << 8; 00365 t0 |= sbox[(s2 >> 16) & 0xFF] << 16; 00366 t0 |= sbox[(s3 >> 24) & 0xFF] << 24; 00367 00368 t1 = sbox[s1 & 0xFF]; 00369 t1 |= sbox[(s2 >> 8) & 0xFF] << 8; 00370 t1 |= sbox[(s3 >> 16) & 0xFF] << 16; 00371 t1 |= sbox[(s0 >> 24) & 0xFF] << 24; 00372 00373 t2 = sbox[s2 & 0xFF]; 00374 t2 |= sbox[(s3 >> 8) & 0xFF] << 8; 00375 t2 |= sbox[(s0 >> 16) & 0xFF] << 16; 00376 t2 |= sbox[(s1 >> 24) & 0xFF] << 24; 00377 00378 t3 = sbox[s3 & 0xFF]; 00379 t3 |= sbox[(s0 >> 8) & 0xFF] << 8; 00380 t3 |= sbox[(s1 >> 16) & 0xFF] << 16; 00381 t3 |= sbox[(s2 >> 24) & 0xFF] << 24; 00382 00383 //Last round key addition 00384 s0 = t0 ^ context->ek[context->nr * 4]; 00385 s1 = t1 ^ context->ek[context->nr * 4 + 1]; 00386 s2 = t2 ^ context->ek[context->nr * 4 + 2]; 00387 s3 = t3 ^ context->ek[context->nr * 4 + 3]; 00388 00389 //The final state is then copied to the output 00390 STORE32LE(s0, output + 0); 00391 STORE32LE(s1, output + 4); 00392 STORE32LE(s2, output + 8); 00393 STORE32LE(s3, output + 12); 00394 } 00395 00396 00397 /** 00398 * @brief Decrypt a 16-byte block using AES algorithm 00399 * @param[in] context Pointer to the AES context 00400 * @param[in] input Ciphertext block to decrypt 00401 * @param[out] output Plaintext block resulting from decryption 00402 **/ 00403 00404 void aesDecryptBlock(AesContext *context, const uint8_t *input, uint8_t *output) 00405 { 00406 uint_t i; 00407 uint32_t s0; 00408 uint32_t s1; 00409 uint32_t s2; 00410 uint32_t s3; 00411 uint32_t t0; 00412 uint32_t t1; 00413 uint32_t t2; 00414 uint32_t t3; 00415 uint32_t temp; 00416 00417 //Copy the ciphertext to the state array 00418 s0 = LOAD32LE(input + 0); 00419 s1 = LOAD32LE(input + 4); 00420 s2 = LOAD32LE(input + 8); 00421 s3 = LOAD32LE(input + 12); 00422 00423 //Initial round key addition 00424 s0 ^= context->dk[context->nr * 4]; 00425 s1 ^= context->dk[context->nr * 4 + 1]; 00426 s2 ^= context->dk[context->nr * 4 + 2]; 00427 s3 ^= context->dk[context->nr * 4 + 3]; 00428 00429 //The number of rounds depends on the key length 00430 for(i = context->nr - 1; i >= 1; i--) 00431 { 00432 //Apply round function 00433 t0 = td[s0 & 0xFF]; 00434 temp = td[(s3 >> 8) & 0xFF]; 00435 t0 ^= ROL32(temp, 8); 00436 temp = td[(s2 >> 16) & 0xFF]; 00437 t0 ^= ROL32(temp, 16); 00438 temp = td[(s1 >> 24) & 0xFF]; 00439 t0 ^= ROL32(temp, 24); 00440 00441 t1 = td[s1 & 0xFF]; 00442 temp = td[(s0 >> 8) & 0xFF]; 00443 t1 ^= ROL32(temp, 8); 00444 temp = td[(s3 >> 16) & 0xFF]; 00445 t1 ^= ROL32(temp, 16); 00446 temp = td[(s2 >> 24) & 0xFF]; 00447 t1 ^= ROL32(temp, 24); 00448 00449 t2 = td[s2 & 0xFF]; 00450 temp = td[(s1 >> 8) & 0xFF]; 00451 t2 ^= ROL32(temp, 8); 00452 temp = td[(s0 >> 16) & 0xFF]; 00453 t2 ^= ROL32(temp, 16); 00454 temp = td[(s3 >> 24) & 0xFF]; 00455 t2 ^= ROL32(temp, 24); 00456 00457 t3 = td[s3 & 0xFF]; 00458 temp = td[(s2 >> 8) & 0xFF]; 00459 t3 ^= ROL32(temp, 8); 00460 temp = td[(s1 >> 16) & 0xFF]; 00461 t3 ^= ROL32(temp, 16); 00462 temp = td[(s0 >> 24) & 0xFF]; 00463 t3 ^= ROL32(temp, 24); 00464 00465 //Round key addition 00466 s0 = t0 ^ context->dk[i * 4]; 00467 s1 = t1 ^ context->dk[i * 4 + 1]; 00468 s2 = t2 ^ context->dk[i * 4 + 2]; 00469 s3 = t3 ^ context->dk[i * 4 + 3]; 00470 } 00471 00472 //The last round differs slightly from the first rounds 00473 t0 = isbox[s0 & 0xFF]; 00474 t0 |= isbox[(s3 >> 8) & 0xFF] << 8; 00475 t0 |= isbox[(s2 >> 16) & 0xFF] << 16; 00476 t0 |= isbox[(s1 >> 24) & 0xFF] << 24; 00477 00478 t1 = isbox[s1 & 0xFF]; 00479 t1 |= isbox[(s0 >> 8) & 0xFF] << 8; 00480 t1 |= isbox[(s3 >> 16) & 0xFF] << 16; 00481 t1 |= isbox[(s2 >> 24) & 0xFF] << 24; 00482 00483 t2 = isbox[s2 & 0xFF]; 00484 t2 |= isbox[(s1 >> 8) & 0xFF] << 8; 00485 t2 |= isbox[(s0 >> 16) & 0xFF] << 16; 00486 t2 |= isbox[(s3 >> 24) & 0xFF] << 24; 00487 00488 t3 = isbox[s3 & 0xFF]; 00489 t3 |= isbox[(s2 >> 8) & 0xFF] << 8; 00490 t3 |= isbox[(s1 >> 16) & 0xFF] << 16; 00491 t3 |= isbox[(s0 >> 24) & 0xFF] << 24; 00492 00493 //Last round key addition 00494 s0 = t0 ^ context->dk[0]; 00495 s1 = t1 ^ context->dk[1]; 00496 s2 = t2 ^ context->dk[2]; 00497 s3 = t3 ^ context->dk[3]; 00498 00499 //The final state is then copied to the output 00500 STORE32LE(s0, output + 0); 00501 STORE32LE(s1, output + 4); 00502 STORE32LE(s2, output + 8); 00503 STORE32LE(s3, output + 12); 00504 } 00505 00506 #endif 00507
Generated on Tue Jul 12 2022 17:10:12 by
1.7.2