A lightweight AES implementation with Cipher Block Chaining and Ciphertext Stealing.

Dependents:   AES_HelloWorld AES_ExtendedTests AESslave_modified_test AESslave_modified_test_27-9-2017 ... more

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers AES.h Source File

AES.h

00001 /* AES Cipher Library
00002  * Copyright (c) 2016 Neil Thiessen
00003  *
00004  * Licensed under the Apache License, Version 2.0 (the "License");
00005  * you may not use this file except in compliance with the License.
00006  * You may obtain a copy of the License at
00007  *
00008  *     http://www.apache.org/licenses/LICENSE-2.0
00009  *
00010  * Unless required by applicable law or agreed to in writing, software
00011  * distributed under the License is distributed on an "AS IS" BASIS,
00012  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00013  * See the License for the specific language governing permissions and
00014  * limitations under the License.
00015  */
00016 
00017 #ifndef AES_H
00018 #define AES_H
00019 
00020 #include "mbed.h"
00021 
00022 /** AES class.
00023  *  Used for encrypting/decrypting data using the AES block cipher.
00024  *
00025  * Example:
00026  * @code
00027  * #include "mbed.h"
00028  * #include "AES.h"
00029  *
00030  * char message[] = {
00031  *     "Hello World!"
00032  * };
00033  *
00034  * const char key[32] = {
00035  *     0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE,
00036  *     0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81,
00037  *     0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7,
00038  *     0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4
00039  * };
00040  *
00041  * const char iv[16] = {
00042  *     0x74, 0x11, 0xF0, 0x45, 0xD6, 0xA4, 0x3F, 0x69,
00043  *     0x18, 0xC6, 0x75, 0x42, 0xDF, 0x4C, 0xA7, 0x84
00044  * };
00045  *
00046  * void printData(const void* data, size_t length)
00047  * {
00048  *     const char* dataBytes = (const char*)data;
00049  *     for (size_t i = 0; i < length; i++) {
00050  *         if ((i % 8) == 0)
00051  *             printf("\n\t");
00052  *         printf("0x%02X, ", dataBytes[i]);
00053  *     }
00054  *     printf("\n");
00055  * }
00056  *
00057  * int main()
00058  * {
00059  *     AES aes;
00060  *
00061  *     //Print the original message
00062  *     printf("Original message: \"%s\"", message);
00063  *     printData(message, sizeof(message));
00064  *
00065  *     //Encrypt the message in-place
00066  *     aes.setup(key, AES::KEY_256, AES::MODE_CBC, iv);
00067  *     aes.encrypt(message, sizeof(message));
00068  *     aes.clear();
00069  *
00070  *     //Print the encrypted message
00071  *     printf("Encrypted message:");
00072  *     printData(message, sizeof(message));
00073  *
00074  *     //Decrypt the message in-place
00075  *     aes.setup(key, AES::KEY_256, AES::MODE_CBC, iv);
00076  *     aes.decrypt(message, sizeof(message));
00077  *     aes.clear();
00078  *
00079  *     //Print the decrypted message
00080  *     printf("Decrypted message: \"%s\"", message);
00081  *     printData(message, sizeof(message));
00082  * }
00083  * @endcode
00084  */
00085 class AES
00086 {
00087 public:
00088     /** Represents the different AES key sizes
00089      */
00090     enum KeySize {
00091         KEY_128 = 4,    /**< 128-bit AES key */
00092         KEY_192 = 6,    /**< 192-bit AES key */
00093         KEY_256 = 8     /**< 256-bit AES key */
00094     };
00095 
00096     /** Represents the different cipher modes
00097      */
00098     enum CipherMode {
00099         MODE_ECB,   /**< Electronic codebook */
00100         MODE_CBC    /**< Cipher block chaining */
00101     };
00102 
00103     /** Create a blank AES object
00104      */
00105     AES();
00106 
00107     /** Create an AES object with the specified parameters
00108      *
00109      * @param key Pointer to the AES key.
00110      * @param keySize The AES key size as a KeySize enum.
00111      * @param mode The cipher mode as a CipherMode enum (MODE_ECB by default).
00112      * @param iv Pointer to the 16B initialization vector (NULL by default).
00113      */
00114     AES(const char* key, KeySize keySize, CipherMode mode = MODE_ECB, const char* iv = NULL);
00115 
00116     /** Destructor
00117      */
00118     ~AES();
00119 
00120     /** Set up this AES object for encryption/decryption with the specified parameters
00121      *
00122      * @param key Pointer to the AES key.
00123      * @param keySize The AES key size as a KeySize enum.
00124      * @param mode The cipher mode as a CipherMode enum (MODE_ECB by default).
00125      * @param iv Pointer to the 16B initialization vector (NULL by default).
00126      */
00127     void setup(const char* key, KeySize keySize, CipherMode mode = MODE_ECB, const char* iv = NULL);
00128 
00129     /** Encrypt the specified data in-place, using CTS or zero-padding if necessary
00130      *
00131      * @param data Pointer to the data to encrypt (minimum 16B for output).
00132      * @param length The length of the data to encrypt in bytes.
00133      */
00134     void encrypt(void* data, size_t length);
00135 
00136     /** Encrypt the specified data, using CTS or zero-padding if necessary
00137      *
00138      * @param src Pointer to the data to encrypt.
00139      * @param dest Pointer to an array in which to store the encrypted data (minimum 16B).
00140      * @param length The length of the data to encrypt in bytes.
00141      */
00142     void encrypt(const void* src, char* dest, size_t length);
00143 
00144     /** Decrypt the specified data in-place, and remove the padding if necessary
00145      *
00146      * @param data Pointer to the data to decrypt (minimum 16B).
00147      * @param length The length of the decrypted data without padding in bytes.
00148      */
00149     void decrypt(void* data, size_t length);
00150 
00151     /** Decrypt the specified data, and remove the padding if necessary
00152      *
00153      * @param src Pointer to the data to decrypt (minimum 16B).
00154      * @param dest Pointer to an array in which to store the decrypted data.
00155      * @param length The length of the decrypted data without padding in bytes.
00156      */
00157     void decrypt(const char* src, void* dest, size_t length);
00158 
00159     /** Erase any sensitive information in this AES object
00160      */
00161     void clear();
00162 
00163 private:
00164     //Member variables
00165     static const char m_Sbox[256];
00166     static const char m_InvSbox[256];
00167     static const unsigned int m_Rcon[10];
00168     AES::CipherMode m_CipherMode;
00169     int m_Rounds;
00170     unsigned int m_Key[60];
00171     char m_State[16];
00172     char m_CarryVector[16];
00173 
00174     //Internal methods
00175     void aesEncrypt();
00176     void aesDecrypt();
00177     void expandKey(const char* key, int nk);
00178     unsigned int rotWord(unsigned int w);
00179     unsigned int invRotWord(unsigned int w);
00180     unsigned int subWord(unsigned int w);
00181     void subBytes();
00182     void invSubBytes();
00183     void shiftRows();
00184     void invShiftRows();
00185     char gmul(char a, char b);
00186     void mul(char* r);
00187     void invMul(char* r);
00188     void mixColumns();
00189     void invMixColumns();
00190     void addRoundKey(int round);
00191 };
00192 
00193 #endif