Sergey Pastor / 1

Dependents:   Nucleo

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers aes.c Source File

aes.c

Go to the documentation of this file.
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