├── .gitignore ├── LICENSE ├── QAes ├── QAes.pri ├── aes.c ├── aes.h ├── qaeswrap.cpp └── qaeswrap.h ├── README.md └── Test ├── QAestTest.pro └── main.cpp /.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled Object files 2 | *.slo 3 | *.lo 4 | *.o 5 | *.obj 6 | 7 | # Precompiled Headers 8 | *.gch 9 | *.pch 10 | 11 | # Compiled Dynamic libraries 12 | *.so 13 | *.dylib 14 | *.dll 15 | 16 | # Fortran module files 17 | *.mod 18 | 19 | # Compiled Static libraries 20 | *.lai 21 | *.la 22 | *.a 23 | *.lib 24 | 25 | # Executables 26 | *.exe 27 | *.out 28 | *.app 29 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 渡世白玉 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /QAes/QAes.pri: -------------------------------------------------------------------------------- 1 | INCLUDEPATH += $$PWD/ 2 | SOURCES += \ 3 | $$PWD/qaeswrap.cpp \ 4 | $$PWD/aes.c 5 | 6 | HEADERS += \ 7 | $$PWD/qaeswrap.h \ 8 | $$PWD/aes.h 9 | -------------------------------------------------------------------------------- /QAes/aes.c: -------------------------------------------------------------------------------- 1 | /********************************************************************* 2 | * Filename: aes.c 3 | * Author: Brad Conte (brad AT bradconte.com) 4 | * Copyright: 5 | * Disclaimer: This code is presented "as is" without any guarantees. 6 | * Details: This code is the implementation of the AES algorithm and 7 | the CTR, CBC, and CCM modes of operation it can be used in. 8 | AES is, specified by the NIST in in publication FIPS PUB 197, 9 | availible at: 10 | * http://csrc.nist.gov/publications/fips/fips197/fips-197.pdf . 11 | The CBC and CTR modes of operation are specified by 12 | NIST SP 800-38 A, available at: 13 | * http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf . 14 | The CCM mode of operation is specified by NIST SP80-38 C, available at: 15 | * http://csrc.nist.gov/publications/nistpubs/800-38C/SP800-38C_updated-July20_2007.pdf 16 | *********************************************************************/ 17 | 18 | /*************************** HEADER FILES ***************************/ 19 | #include 20 | #include 21 | #include "aes.h" 22 | 23 | #include 24 | 25 | /****************************** MACROS ******************************/ 26 | // The least significant byte of the word is rotated to the end. 27 | #define KE_ROTWORD(x) (((x) << 8) | ((x) >> 24)) 28 | 29 | #define TRUE 1 30 | #define FALSE 0 31 | 32 | /**************************** DATA TYPES ****************************/ 33 | #define AES_128_ROUNDS 10 34 | #define AES_192_ROUNDS 12 35 | #define AES_256_ROUNDS 14 36 | 37 | /*********************** FUNCTION DECLARATIONS **********************/ 38 | void ccm_prepare_first_ctr_blk(BYTE counter[], const BYTE nonce[], int nonce_len, int payload_len_store_size); 39 | void ccm_prepare_first_format_blk(BYTE buf[], int assoc_len, int payload_len, int payload_len_store_size, int mac_len, const BYTE nonce[], int nonce_len); 40 | void ccm_format_assoc_data(BYTE buf[], int *end_of_buf, const BYTE assoc[], int assoc_len); 41 | void ccm_format_payload_data(BYTE buf[], int *end_of_buf, const BYTE payload[], int payload_len); 42 | 43 | /**************************** VARIABLES *****************************/ 44 | // This is the specified AES SBox. To look up a substitution value, put the first 45 | // nibble in the first index (row) and the second nibble in the second index (column). 46 | static const BYTE aes_sbox[16][16] = { 47 | {0x63,0x7C,0x77,0x7B,0xF2,0x6B,0x6F,0xC5,0x30,0x01,0x67,0x2B,0xFE,0xD7,0xAB,0x76}, 48 | {0xCA,0x82,0xC9,0x7D,0xFA,0x59,0x47,0xF0,0xAD,0xD4,0xA2,0xAF,0x9C,0xA4,0x72,0xC0}, 49 | {0xB7,0xFD,0x93,0x26,0x36,0x3F,0xF7,0xCC,0x34,0xA5,0xE5,0xF1,0x71,0xD8,0x31,0x15}, 50 | {0x04,0xC7,0x23,0xC3,0x18,0x96,0x05,0x9A,0x07,0x12,0x80,0xE2,0xEB,0x27,0xB2,0x75}, 51 | {0x09,0x83,0x2C,0x1A,0x1B,0x6E,0x5A,0xA0,0x52,0x3B,0xD6,0xB3,0x29,0xE3,0x2F,0x84}, 52 | {0x53,0xD1,0x00,0xED,0x20,0xFC,0xB1,0x5B,0x6A,0xCB,0xBE,0x39,0x4A,0x4C,0x58,0xCF}, 53 | {0xD0,0xEF,0xAA,0xFB,0x43,0x4D,0x33,0x85,0x45,0xF9,0x02,0x7F,0x50,0x3C,0x9F,0xA8}, 54 | {0x51,0xA3,0x40,0x8F,0x92,0x9D,0x38,0xF5,0xBC,0xB6,0xDA,0x21,0x10,0xFF,0xF3,0xD2}, 55 | {0xCD,0x0C,0x13,0xEC,0x5F,0x97,0x44,0x17,0xC4,0xA7,0x7E,0x3D,0x64,0x5D,0x19,0x73}, 56 | {0x60,0x81,0x4F,0xDC,0x22,0x2A,0x90,0x88,0x46,0xEE,0xB8,0x14,0xDE,0x5E,0x0B,0xDB}, 57 | {0xE0,0x32,0x3A,0x0A,0x49,0x06,0x24,0x5C,0xC2,0xD3,0xAC,0x62,0x91,0x95,0xE4,0x79}, 58 | {0xE7,0xC8,0x37,0x6D,0x8D,0xD5,0x4E,0xA9,0x6C,0x56,0xF4,0xEA,0x65,0x7A,0xAE,0x08}, 59 | {0xBA,0x78,0x25,0x2E,0x1C,0xA6,0xB4,0xC6,0xE8,0xDD,0x74,0x1F,0x4B,0xBD,0x8B,0x8A}, 60 | {0x70,0x3E,0xB5,0x66,0x48,0x03,0xF6,0x0E,0x61,0x35,0x57,0xB9,0x86,0xC1,0x1D,0x9E}, 61 | {0xE1,0xF8,0x98,0x11,0x69,0xD9,0x8E,0x94,0x9B,0x1E,0x87,0xE9,0xCE,0x55,0x28,0xDF}, 62 | {0x8C,0xA1,0x89,0x0D,0xBF,0xE6,0x42,0x68,0x41,0x99,0x2D,0x0F,0xB0,0x54,0xBB,0x16} 63 | }; 64 | 65 | static const BYTE aes_invsbox[16][16] = { 66 | {0x52,0x09,0x6A,0xD5,0x30,0x36,0xA5,0x38,0xBF,0x40,0xA3,0x9E,0x81,0xF3,0xD7,0xFB}, 67 | {0x7C,0xE3,0x39,0x82,0x9B,0x2F,0xFF,0x87,0x34,0x8E,0x43,0x44,0xC4,0xDE,0xE9,0xCB}, 68 | {0x54,0x7B,0x94,0x32,0xA6,0xC2,0x23,0x3D,0xEE,0x4C,0x95,0x0B,0x42,0xFA,0xC3,0x4E}, 69 | {0x08,0x2E,0xA1,0x66,0x28,0xD9,0x24,0xB2,0x76,0x5B,0xA2,0x49,0x6D,0x8B,0xD1,0x25}, 70 | {0x72,0xF8,0xF6,0x64,0x86,0x68,0x98,0x16,0xD4,0xA4,0x5C,0xCC,0x5D,0x65,0xB6,0x92}, 71 | {0x6C,0x70,0x48,0x50,0xFD,0xED,0xB9,0xDA,0x5E,0x15,0x46,0x57,0xA7,0x8D,0x9D,0x84}, 72 | {0x90,0xD8,0xAB,0x00,0x8C,0xBC,0xD3,0x0A,0xF7,0xE4,0x58,0x05,0xB8,0xB3,0x45,0x06}, 73 | {0xD0,0x2C,0x1E,0x8F,0xCA,0x3F,0x0F,0x02,0xC1,0xAF,0xBD,0x03,0x01,0x13,0x8A,0x6B}, 74 | {0x3A,0x91,0x11,0x41,0x4F,0x67,0xDC,0xEA,0x97,0xF2,0xCF,0xCE,0xF0,0xB4,0xE6,0x73}, 75 | {0x96,0xAC,0x74,0x22,0xE7,0xAD,0x35,0x85,0xE2,0xF9,0x37,0xE8,0x1C,0x75,0xDF,0x6E}, 76 | {0x47,0xF1,0x1A,0x71,0x1D,0x29,0xC5,0x89,0x6F,0xB7,0x62,0x0E,0xAA,0x18,0xBE,0x1B}, 77 | {0xFC,0x56,0x3E,0x4B,0xC6,0xD2,0x79,0x20,0x9A,0xDB,0xC0,0xFE,0x78,0xCD,0x5A,0xF4}, 78 | {0x1F,0xDD,0xA8,0x33,0x88,0x07,0xC7,0x31,0xB1,0x12,0x10,0x59,0x27,0x80,0xEC,0x5F}, 79 | {0x60,0x51,0x7F,0xA9,0x19,0xB5,0x4A,0x0D,0x2D,0xE5,0x7A,0x9F,0x93,0xC9,0x9C,0xEF}, 80 | {0xA0,0xE0,0x3B,0x4D,0xAE,0x2A,0xF5,0xB0,0xC8,0xEB,0xBB,0x3C,0x83,0x53,0x99,0x61}, 81 | {0x17,0x2B,0x04,0x7E,0xBA,0x77,0xD6,0x26,0xE1,0x69,0x14,0x63,0x55,0x21,0x0C,0x7D} 82 | }; 83 | 84 | // This table stores pre-calculated values for all possible GF(2^8) calculations.This 85 | // table is only used by the (Inv)MixColumns steps. 86 | // USAGE: The second index (column) is the coefficient of multiplication. Only 7 different 87 | // coefficients are used: 0x01, 0x02, 0x03, 0x09, 0x0b, 0x0d, 0x0e, but multiplication by 88 | // 1 is negligible leaving only 6 coefficients. Each column of the table is devoted to one 89 | // of these coefficients, in the ascending order of value, from values 0x00 to 0xFF. 90 | static const BYTE gf_mul[256][6] = { 91 | {0x00,0x00,0x00,0x00,0x00,0x00},{0x02,0x03,0x09,0x0b,0x0d,0x0e}, 92 | {0x04,0x06,0x12,0x16,0x1a,0x1c},{0x06,0x05,0x1b,0x1d,0x17,0x12}, 93 | {0x08,0x0c,0x24,0x2c,0x34,0x38},{0x0a,0x0f,0x2d,0x27,0x39,0x36}, 94 | {0x0c,0x0a,0x36,0x3a,0x2e,0x24},{0x0e,0x09,0x3f,0x31,0x23,0x2a}, 95 | {0x10,0x18,0x48,0x58,0x68,0x70},{0x12,0x1b,0x41,0x53,0x65,0x7e}, 96 | {0x14,0x1e,0x5a,0x4e,0x72,0x6c},{0x16,0x1d,0x53,0x45,0x7f,0x62}, 97 | {0x18,0x14,0x6c,0x74,0x5c,0x48},{0x1a,0x17,0x65,0x7f,0x51,0x46}, 98 | {0x1c,0x12,0x7e,0x62,0x46,0x54},{0x1e,0x11,0x77,0x69,0x4b,0x5a}, 99 | {0x20,0x30,0x90,0xb0,0xd0,0xe0},{0x22,0x33,0x99,0xbb,0xdd,0xee}, 100 | {0x24,0x36,0x82,0xa6,0xca,0xfc},{0x26,0x35,0x8b,0xad,0xc7,0xf2}, 101 | {0x28,0x3c,0xb4,0x9c,0xe4,0xd8},{0x2a,0x3f,0xbd,0x97,0xe9,0xd6}, 102 | {0x2c,0x3a,0xa6,0x8a,0xfe,0xc4},{0x2e,0x39,0xaf,0x81,0xf3,0xca}, 103 | {0x30,0x28,0xd8,0xe8,0xb8,0x90},{0x32,0x2b,0xd1,0xe3,0xb5,0x9e}, 104 | {0x34,0x2e,0xca,0xfe,0xa2,0x8c},{0x36,0x2d,0xc3,0xf5,0xaf,0x82}, 105 | {0x38,0x24,0xfc,0xc4,0x8c,0xa8},{0x3a,0x27,0xf5,0xcf,0x81,0xa6}, 106 | {0x3c,0x22,0xee,0xd2,0x96,0xb4},{0x3e,0x21,0xe7,0xd9,0x9b,0xba}, 107 | {0x40,0x60,0x3b,0x7b,0xbb,0xdb},{0x42,0x63,0x32,0x70,0xb6,0xd5}, 108 | {0x44,0x66,0x29,0x6d,0xa1,0xc7},{0x46,0x65,0x20,0x66,0xac,0xc9}, 109 | {0x48,0x6c,0x1f,0x57,0x8f,0xe3},{0x4a,0x6f,0x16,0x5c,0x82,0xed}, 110 | {0x4c,0x6a,0x0d,0x41,0x95,0xff},{0x4e,0x69,0x04,0x4a,0x98,0xf1}, 111 | {0x50,0x78,0x73,0x23,0xd3,0xab},{0x52,0x7b,0x7a,0x28,0xde,0xa5}, 112 | {0x54,0x7e,0x61,0x35,0xc9,0xb7},{0x56,0x7d,0x68,0x3e,0xc4,0xb9}, 113 | {0x58,0x74,0x57,0x0f,0xe7,0x93},{0x5a,0x77,0x5e,0x04,0xea,0x9d}, 114 | {0x5c,0x72,0x45,0x19,0xfd,0x8f},{0x5e,0x71,0x4c,0x12,0xf0,0x81}, 115 | {0x60,0x50,0xab,0xcb,0x6b,0x3b},{0x62,0x53,0xa2,0xc0,0x66,0x35}, 116 | {0x64,0x56,0xb9,0xdd,0x71,0x27},{0x66,0x55,0xb0,0xd6,0x7c,0x29}, 117 | {0x68,0x5c,0x8f,0xe7,0x5f,0x03},{0x6a,0x5f,0x86,0xec,0x52,0x0d}, 118 | {0x6c,0x5a,0x9d,0xf1,0x45,0x1f},{0x6e,0x59,0x94,0xfa,0x48,0x11}, 119 | {0x70,0x48,0xe3,0x93,0x03,0x4b},{0x72,0x4b,0xea,0x98,0x0e,0x45}, 120 | {0x74,0x4e,0xf1,0x85,0x19,0x57},{0x76,0x4d,0xf8,0x8e,0x14,0x59}, 121 | {0x78,0x44,0xc7,0xbf,0x37,0x73},{0x7a,0x47,0xce,0xb4,0x3a,0x7d}, 122 | {0x7c,0x42,0xd5,0xa9,0x2d,0x6f},{0x7e,0x41,0xdc,0xa2,0x20,0x61}, 123 | {0x80,0xc0,0x76,0xf6,0x6d,0xad},{0x82,0xc3,0x7f,0xfd,0x60,0xa3}, 124 | {0x84,0xc6,0x64,0xe0,0x77,0xb1},{0x86,0xc5,0x6d,0xeb,0x7a,0xbf}, 125 | {0x88,0xcc,0x52,0xda,0x59,0x95},{0x8a,0xcf,0x5b,0xd1,0x54,0x9b}, 126 | {0x8c,0xca,0x40,0xcc,0x43,0x89},{0x8e,0xc9,0x49,0xc7,0x4e,0x87}, 127 | {0x90,0xd8,0x3e,0xae,0x05,0xdd},{0x92,0xdb,0x37,0xa5,0x08,0xd3}, 128 | {0x94,0xde,0x2c,0xb8,0x1f,0xc1},{0x96,0xdd,0x25,0xb3,0x12,0xcf}, 129 | {0x98,0xd4,0x1a,0x82,0x31,0xe5},{0x9a,0xd7,0x13,0x89,0x3c,0xeb}, 130 | {0x9c,0xd2,0x08,0x94,0x2b,0xf9},{0x9e,0xd1,0x01,0x9f,0x26,0xf7}, 131 | {0xa0,0xf0,0xe6,0x46,0xbd,0x4d},{0xa2,0xf3,0xef,0x4d,0xb0,0x43}, 132 | {0xa4,0xf6,0xf4,0x50,0xa7,0x51},{0xa6,0xf5,0xfd,0x5b,0xaa,0x5f}, 133 | {0xa8,0xfc,0xc2,0x6a,0x89,0x75},{0xaa,0xff,0xcb,0x61,0x84,0x7b}, 134 | {0xac,0xfa,0xd0,0x7c,0x93,0x69},{0xae,0xf9,0xd9,0x77,0x9e,0x67}, 135 | {0xb0,0xe8,0xae,0x1e,0xd5,0x3d},{0xb2,0xeb,0xa7,0x15,0xd8,0x33}, 136 | {0xb4,0xee,0xbc,0x08,0xcf,0x21},{0xb6,0xed,0xb5,0x03,0xc2,0x2f}, 137 | {0xb8,0xe4,0x8a,0x32,0xe1,0x05},{0xba,0xe7,0x83,0x39,0xec,0x0b}, 138 | {0xbc,0xe2,0x98,0x24,0xfb,0x19},{0xbe,0xe1,0x91,0x2f,0xf6,0x17}, 139 | {0xc0,0xa0,0x4d,0x8d,0xd6,0x76},{0xc2,0xa3,0x44,0x86,0xdb,0x78}, 140 | {0xc4,0xa6,0x5f,0x9b,0xcc,0x6a},{0xc6,0xa5,0x56,0x90,0xc1,0x64}, 141 | {0xc8,0xac,0x69,0xa1,0xe2,0x4e},{0xca,0xaf,0x60,0xaa,0xef,0x40}, 142 | {0xcc,0xaa,0x7b,0xb7,0xf8,0x52},{0xce,0xa9,0x72,0xbc,0xf5,0x5c}, 143 | {0xd0,0xb8,0x05,0xd5,0xbe,0x06},{0xd2,0xbb,0x0c,0xde,0xb3,0x08}, 144 | {0xd4,0xbe,0x17,0xc3,0xa4,0x1a},{0xd6,0xbd,0x1e,0xc8,0xa9,0x14}, 145 | {0xd8,0xb4,0x21,0xf9,0x8a,0x3e},{0xda,0xb7,0x28,0xf2,0x87,0x30}, 146 | {0xdc,0xb2,0x33,0xef,0x90,0x22},{0xde,0xb1,0x3a,0xe4,0x9d,0x2c}, 147 | {0xe0,0x90,0xdd,0x3d,0x06,0x96},{0xe2,0x93,0xd4,0x36,0x0b,0x98}, 148 | {0xe4,0x96,0xcf,0x2b,0x1c,0x8a},{0xe6,0x95,0xc6,0x20,0x11,0x84}, 149 | {0xe8,0x9c,0xf9,0x11,0x32,0xae},{0xea,0x9f,0xf0,0x1a,0x3f,0xa0}, 150 | {0xec,0x9a,0xeb,0x07,0x28,0xb2},{0xee,0x99,0xe2,0x0c,0x25,0xbc}, 151 | {0xf0,0x88,0x95,0x65,0x6e,0xe6},{0xf2,0x8b,0x9c,0x6e,0x63,0xe8}, 152 | {0xf4,0x8e,0x87,0x73,0x74,0xfa},{0xf6,0x8d,0x8e,0x78,0x79,0xf4}, 153 | {0xf8,0x84,0xb1,0x49,0x5a,0xde},{0xfa,0x87,0xb8,0x42,0x57,0xd0}, 154 | {0xfc,0x82,0xa3,0x5f,0x40,0xc2},{0xfe,0x81,0xaa,0x54,0x4d,0xcc}, 155 | {0x1b,0x9b,0xec,0xf7,0xda,0x41},{0x19,0x98,0xe5,0xfc,0xd7,0x4f}, 156 | {0x1f,0x9d,0xfe,0xe1,0xc0,0x5d},{0x1d,0x9e,0xf7,0xea,0xcd,0x53}, 157 | {0x13,0x97,0xc8,0xdb,0xee,0x79},{0x11,0x94,0xc1,0xd0,0xe3,0x77}, 158 | {0x17,0x91,0xda,0xcd,0xf4,0x65},{0x15,0x92,0xd3,0xc6,0xf9,0x6b}, 159 | {0x0b,0x83,0xa4,0xaf,0xb2,0x31},{0x09,0x80,0xad,0xa4,0xbf,0x3f}, 160 | {0x0f,0x85,0xb6,0xb9,0xa8,0x2d},{0x0d,0x86,0xbf,0xb2,0xa5,0x23}, 161 | {0x03,0x8f,0x80,0x83,0x86,0x09},{0x01,0x8c,0x89,0x88,0x8b,0x07}, 162 | {0x07,0x89,0x92,0x95,0x9c,0x15},{0x05,0x8a,0x9b,0x9e,0x91,0x1b}, 163 | {0x3b,0xab,0x7c,0x47,0x0a,0xa1},{0x39,0xa8,0x75,0x4c,0x07,0xaf}, 164 | {0x3f,0xad,0x6e,0x51,0x10,0xbd},{0x3d,0xae,0x67,0x5a,0x1d,0xb3}, 165 | {0x33,0xa7,0x58,0x6b,0x3e,0x99},{0x31,0xa4,0x51,0x60,0x33,0x97}, 166 | {0x37,0xa1,0x4a,0x7d,0x24,0x85},{0x35,0xa2,0x43,0x76,0x29,0x8b}, 167 | {0x2b,0xb3,0x34,0x1f,0x62,0xd1},{0x29,0xb0,0x3d,0x14,0x6f,0xdf}, 168 | {0x2f,0xb5,0x26,0x09,0x78,0xcd},{0x2d,0xb6,0x2f,0x02,0x75,0xc3}, 169 | {0x23,0xbf,0x10,0x33,0x56,0xe9},{0x21,0xbc,0x19,0x38,0x5b,0xe7}, 170 | {0x27,0xb9,0x02,0x25,0x4c,0xf5},{0x25,0xba,0x0b,0x2e,0x41,0xfb}, 171 | {0x5b,0xfb,0xd7,0x8c,0x61,0x9a},{0x59,0xf8,0xde,0x87,0x6c,0x94}, 172 | {0x5f,0xfd,0xc5,0x9a,0x7b,0x86},{0x5d,0xfe,0xcc,0x91,0x76,0x88}, 173 | {0x53,0xf7,0xf3,0xa0,0x55,0xa2},{0x51,0xf4,0xfa,0xab,0x58,0xac}, 174 | {0x57,0xf1,0xe1,0xb6,0x4f,0xbe},{0x55,0xf2,0xe8,0xbd,0x42,0xb0}, 175 | {0x4b,0xe3,0x9f,0xd4,0x09,0xea},{0x49,0xe0,0x96,0xdf,0x04,0xe4}, 176 | {0x4f,0xe5,0x8d,0xc2,0x13,0xf6},{0x4d,0xe6,0x84,0xc9,0x1e,0xf8}, 177 | {0x43,0xef,0xbb,0xf8,0x3d,0xd2},{0x41,0xec,0xb2,0xf3,0x30,0xdc}, 178 | {0x47,0xe9,0xa9,0xee,0x27,0xce},{0x45,0xea,0xa0,0xe5,0x2a,0xc0}, 179 | {0x7b,0xcb,0x47,0x3c,0xb1,0x7a},{0x79,0xc8,0x4e,0x37,0xbc,0x74}, 180 | {0x7f,0xcd,0x55,0x2a,0xab,0x66},{0x7d,0xce,0x5c,0x21,0xa6,0x68}, 181 | {0x73,0xc7,0x63,0x10,0x85,0x42},{0x71,0xc4,0x6a,0x1b,0x88,0x4c}, 182 | {0x77,0xc1,0x71,0x06,0x9f,0x5e},{0x75,0xc2,0x78,0x0d,0x92,0x50}, 183 | {0x6b,0xd3,0x0f,0x64,0xd9,0x0a},{0x69,0xd0,0x06,0x6f,0xd4,0x04}, 184 | {0x6f,0xd5,0x1d,0x72,0xc3,0x16},{0x6d,0xd6,0x14,0x79,0xce,0x18}, 185 | {0x63,0xdf,0x2b,0x48,0xed,0x32},{0x61,0xdc,0x22,0x43,0xe0,0x3c}, 186 | {0x67,0xd9,0x39,0x5e,0xf7,0x2e},{0x65,0xda,0x30,0x55,0xfa,0x20}, 187 | {0x9b,0x5b,0x9a,0x01,0xb7,0xec},{0x99,0x58,0x93,0x0a,0xba,0xe2}, 188 | {0x9f,0x5d,0x88,0x17,0xad,0xf0},{0x9d,0x5e,0x81,0x1c,0xa0,0xfe}, 189 | {0x93,0x57,0xbe,0x2d,0x83,0xd4},{0x91,0x54,0xb7,0x26,0x8e,0xda}, 190 | {0x97,0x51,0xac,0x3b,0x99,0xc8},{0x95,0x52,0xa5,0x30,0x94,0xc6}, 191 | {0x8b,0x43,0xd2,0x59,0xdf,0x9c},{0x89,0x40,0xdb,0x52,0xd2,0x92}, 192 | {0x8f,0x45,0xc0,0x4f,0xc5,0x80},{0x8d,0x46,0xc9,0x44,0xc8,0x8e}, 193 | {0x83,0x4f,0xf6,0x75,0xeb,0xa4},{0x81,0x4c,0xff,0x7e,0xe6,0xaa}, 194 | {0x87,0x49,0xe4,0x63,0xf1,0xb8},{0x85,0x4a,0xed,0x68,0xfc,0xb6}, 195 | {0xbb,0x6b,0x0a,0xb1,0x67,0x0c},{0xb9,0x68,0x03,0xba,0x6a,0x02}, 196 | {0xbf,0x6d,0x18,0xa7,0x7d,0x10},{0xbd,0x6e,0x11,0xac,0x70,0x1e}, 197 | {0xb3,0x67,0x2e,0x9d,0x53,0x34},{0xb1,0x64,0x27,0x96,0x5e,0x3a}, 198 | {0xb7,0x61,0x3c,0x8b,0x49,0x28},{0xb5,0x62,0x35,0x80,0x44,0x26}, 199 | {0xab,0x73,0x42,0xe9,0x0f,0x7c},{0xa9,0x70,0x4b,0xe2,0x02,0x72}, 200 | {0xaf,0x75,0x50,0xff,0x15,0x60},{0xad,0x76,0x59,0xf4,0x18,0x6e}, 201 | {0xa3,0x7f,0x66,0xc5,0x3b,0x44},{0xa1,0x7c,0x6f,0xce,0x36,0x4a}, 202 | {0xa7,0x79,0x74,0xd3,0x21,0x58},{0xa5,0x7a,0x7d,0xd8,0x2c,0x56}, 203 | {0xdb,0x3b,0xa1,0x7a,0x0c,0x37},{0xd9,0x38,0xa8,0x71,0x01,0x39}, 204 | {0xdf,0x3d,0xb3,0x6c,0x16,0x2b},{0xdd,0x3e,0xba,0x67,0x1b,0x25}, 205 | {0xd3,0x37,0x85,0x56,0x38,0x0f},{0xd1,0x34,0x8c,0x5d,0x35,0x01}, 206 | {0xd7,0x31,0x97,0x40,0x22,0x13},{0xd5,0x32,0x9e,0x4b,0x2f,0x1d}, 207 | {0xcb,0x23,0xe9,0x22,0x64,0x47},{0xc9,0x20,0xe0,0x29,0x69,0x49}, 208 | {0xcf,0x25,0xfb,0x34,0x7e,0x5b},{0xcd,0x26,0xf2,0x3f,0x73,0x55}, 209 | {0xc3,0x2f,0xcd,0x0e,0x50,0x7f},{0xc1,0x2c,0xc4,0x05,0x5d,0x71}, 210 | {0xc7,0x29,0xdf,0x18,0x4a,0x63},{0xc5,0x2a,0xd6,0x13,0x47,0x6d}, 211 | {0xfb,0x0b,0x31,0xca,0xdc,0xd7},{0xf9,0x08,0x38,0xc1,0xd1,0xd9}, 212 | {0xff,0x0d,0x23,0xdc,0xc6,0xcb},{0xfd,0x0e,0x2a,0xd7,0xcb,0xc5}, 213 | {0xf3,0x07,0x15,0xe6,0xe8,0xef},{0xf1,0x04,0x1c,0xed,0xe5,0xe1}, 214 | {0xf7,0x01,0x07,0xf0,0xf2,0xf3},{0xf5,0x02,0x0e,0xfb,0xff,0xfd}, 215 | {0xeb,0x13,0x79,0x92,0xb4,0xa7},{0xe9,0x10,0x70,0x99,0xb9,0xa9}, 216 | {0xef,0x15,0x6b,0x84,0xae,0xbb},{0xed,0x16,0x62,0x8f,0xa3,0xb5}, 217 | {0xe3,0x1f,0x5d,0xbe,0x80,0x9f},{0xe1,0x1c,0x54,0xb5,0x8d,0x91}, 218 | {0xe7,0x19,0x4f,0xa8,0x9a,0x83},{0xe5,0x1a,0x46,0xa3,0x97,0x8d} 219 | }; 220 | 221 | /*********************** FUNCTION DEFINITIONS ***********************/ 222 | // XORs the in and out buffers, storing the result in out. Length is in bytes. 223 | void xor_buf(const BYTE in[], BYTE out[], size_t len) 224 | { 225 | size_t idx; 226 | 227 | for (idx = 0; idx < len; idx++) 228 | out[idx] ^= in[idx]; 229 | } 230 | 231 | /******************* 232 | * AES - CBC 233 | *******************/ 234 | void aes_encrypt_cbc(const BYTE in[], size_t in_len,const BYTE * lastBlock, BYTE out[], const WORD key[], int keysize, const BYTE iv[]) 235 | { 236 | BYTE buf_in[AES_BLOCK_SIZE], buf_out[AES_BLOCK_SIZE], iv_buf[AES_BLOCK_SIZE]; 237 | int blocks, idx; 238 | 239 | blocks = in_len / AES_BLOCK_SIZE; 240 | 241 | memcpy(iv_buf, iv, AES_BLOCK_SIZE); 242 | 243 | for (idx = 0; idx < blocks; idx++) { 244 | memcpy(buf_in, &in[idx * AES_BLOCK_SIZE], AES_BLOCK_SIZE); 245 | xor_buf(iv_buf, buf_in, AES_BLOCK_SIZE); 246 | aes_encrypt(buf_in, buf_out, key, keysize); 247 | memcpy(&out[idx * AES_BLOCK_SIZE], buf_out, AES_BLOCK_SIZE); 248 | memcpy(iv_buf, buf_out, AES_BLOCK_SIZE); 249 | } 250 | if (lastBlock) { 251 | memcpy(buf_in, lastBlock, AES_BLOCK_SIZE); 252 | xor_buf(iv_buf, buf_in, AES_BLOCK_SIZE); 253 | aes_encrypt(buf_in, buf_out, key, keysize); 254 | memcpy(&out[idx * AES_BLOCK_SIZE], buf_out, AES_BLOCK_SIZE); 255 | memcpy(iv_buf, buf_out, AES_BLOCK_SIZE); 256 | } 257 | 258 | return; 259 | } 260 | 261 | void aes_decrypt_cbc(const BYTE in[], size_t in_len, BYTE out[], const WORD key[], int keysize, const BYTE iv[]) 262 | { 263 | BYTE buf_in[AES_BLOCK_SIZE], buf_out[AES_BLOCK_SIZE], iv_buf[AES_BLOCK_SIZE]; 264 | int blocks, idx; 265 | 266 | blocks = in_len / AES_BLOCK_SIZE; 267 | 268 | memcpy(iv_buf, iv, AES_BLOCK_SIZE); 269 | 270 | for (idx = 0; idx < blocks; idx++) { 271 | memcpy(buf_in, &in[idx * AES_BLOCK_SIZE], AES_BLOCK_SIZE); 272 | aes_decrypt(buf_in, buf_out, key, keysize); 273 | xor_buf(iv_buf, buf_out, AES_BLOCK_SIZE); 274 | memcpy(&out[idx * AES_BLOCK_SIZE], buf_out, AES_BLOCK_SIZE); 275 | memcpy(iv_buf, buf_in, AES_BLOCK_SIZE); 276 | } 277 | 278 | 279 | return; 280 | } 281 | 282 | int aes_encrypt_cbc_mac(const BYTE in[], size_t in_len, BYTE out[], const WORD key[], int keysize, const BYTE iv[]) 283 | { 284 | BYTE buf_in[AES_BLOCK_SIZE], buf_out[AES_BLOCK_SIZE], iv_buf[AES_BLOCK_SIZE]; 285 | int blocks, idx; 286 | 287 | if (in_len % AES_BLOCK_SIZE != 0) 288 | return(FALSE); 289 | 290 | blocks = in_len / AES_BLOCK_SIZE; 291 | 292 | memcpy(iv_buf, iv, AES_BLOCK_SIZE); 293 | 294 | for (idx = 0; idx < blocks; idx++) { 295 | memcpy(buf_in, &in[idx * AES_BLOCK_SIZE], AES_BLOCK_SIZE); 296 | xor_buf(iv_buf, buf_in, AES_BLOCK_SIZE); 297 | aes_encrypt(buf_in, buf_out, key, keysize); 298 | memcpy(iv_buf, buf_out, AES_BLOCK_SIZE); 299 | // Do not output all encrypted blocks. 300 | } 301 | 302 | memcpy(out, buf_out, AES_BLOCK_SIZE); // Only output the last block. 303 | 304 | return(TRUE); 305 | } 306 | 307 | 308 | /******************* 309 | * AES - CTR 310 | *******************/ 311 | void increment_iv(BYTE iv[], int counter_size) 312 | { 313 | int idx; 314 | 315 | // Use counter_size bytes at the end of the IV as the big-endian integer to increment. 316 | for (idx = AES_BLOCK_SIZE - 1; idx >= AES_BLOCK_SIZE - counter_size; idx--) { 317 | iv[idx]++; 318 | if (iv[idx] != 0 || idx == AES_BLOCK_SIZE - counter_size) 319 | break; 320 | } 321 | } 322 | 323 | // Performs the encryption in-place, the input and output buffers may be the same. 324 | // Input may be an arbitrary length (in bytes). 325 | void aes_encrypt_ctr(const BYTE in[], size_t in_len, BYTE out[], const WORD key[], int keysize, const BYTE iv[]) 326 | { 327 | size_t idx = 0, last_block_length; 328 | BYTE iv_buf[AES_BLOCK_SIZE], out_buf[AES_BLOCK_SIZE]; 329 | 330 | if (in != out) 331 | memcpy(out, in, in_len); 332 | 333 | memcpy(iv_buf, iv, AES_BLOCK_SIZE); 334 | last_block_length = in_len - AES_BLOCK_SIZE; 335 | 336 | if (in_len > AES_BLOCK_SIZE) { 337 | for (idx = 0; idx < last_block_length; idx += AES_BLOCK_SIZE) { 338 | aes_encrypt(iv_buf, out_buf, key, keysize); 339 | xor_buf(out_buf, &out[idx], AES_BLOCK_SIZE); 340 | increment_iv(iv_buf, AES_BLOCK_SIZE); 341 | } 342 | } 343 | 344 | aes_encrypt(iv_buf, out_buf, key, keysize); 345 | xor_buf(out_buf, &out[idx], in_len - idx); // Use the Most Significant bytes. 346 | } 347 | 348 | void aes_decrypt_ctr(const BYTE in[], size_t in_len, BYTE out[], const WORD key[], int keysize, const BYTE iv[]) 349 | { 350 | // CTR encryption is its own inverse function. 351 | aes_encrypt_ctr(in, in_len, out, key, keysize, iv); 352 | } 353 | 354 | /******************* 355 | * AES - CCM 356 | *******************/ 357 | // out_len = payload_len + assoc_len 358 | int aes_encrypt_ccm(const BYTE payload[], WORD payload_len, const BYTE assoc[], unsigned short assoc_len, 359 | const BYTE nonce[], unsigned short nonce_len, BYTE out[], WORD *out_len, 360 | WORD mac_len, const BYTE key_str[], int keysize) 361 | { 362 | BYTE temp_iv[AES_BLOCK_SIZE], counter[AES_BLOCK_SIZE], mac[16], *buf; 363 | int end_of_buf, payload_len_store_size; 364 | WORD key[60]; 365 | 366 | if (mac_len != 4 && mac_len != 6 && mac_len != 8 && mac_len != 10 && 367 | mac_len != 12 && mac_len != 14 && mac_len != 16) 368 | return(FALSE); 369 | 370 | if (nonce_len < 7 || nonce_len > 13) 371 | return(FALSE); 372 | 373 | if (assoc_len > 32768 /* = 2^15 */) 374 | return(FALSE); 375 | 376 | buf = (BYTE*)malloc(payload_len + assoc_len + 48 /*Round both payload and associated data up a block size and add an extra block.*/); 377 | if (! buf) 378 | return(FALSE); 379 | 380 | // Prepare the key for usage. 381 | aes_key_setup(key_str, key, keysize); 382 | 383 | // Format the first block of the formatted data. 384 | payload_len_store_size = AES_BLOCK_SIZE - 1 - nonce_len; 385 | ccm_prepare_first_format_blk(buf, assoc_len, payload_len, payload_len_store_size, mac_len, nonce, nonce_len); 386 | end_of_buf = AES_BLOCK_SIZE; 387 | 388 | // Format the Associated Data, aka, assoc[]. 389 | ccm_format_assoc_data(buf, &end_of_buf, assoc, assoc_len); 390 | 391 | // Format the Payload, aka payload[]. 392 | ccm_format_payload_data(buf, &end_of_buf, payload, payload_len); 393 | 394 | // Create the first counter block. 395 | ccm_prepare_first_ctr_blk(counter, nonce, nonce_len, payload_len_store_size); 396 | 397 | // Perform the CBC operation with an IV of zeros on the formatted buffer to calculate the MAC. 398 | memset(temp_iv, 0, AES_BLOCK_SIZE); 399 | aes_encrypt_cbc_mac(buf, end_of_buf, mac, key, keysize, temp_iv); 400 | 401 | // Copy the Payload and MAC to the output buffer. 402 | memcpy(out, payload, payload_len); 403 | memcpy(&out[payload_len], mac, mac_len); 404 | 405 | // Encrypt the Payload with CTR mode with a counter starting at 1. 406 | memcpy(temp_iv, counter, AES_BLOCK_SIZE); 407 | increment_iv(temp_iv, AES_BLOCK_SIZE - 1 - mac_len); // Last argument is the byte size of the counting portion of the counter block. /*BUG?*/ 408 | aes_encrypt_ctr(out, payload_len, out, key, keysize, temp_iv); 409 | 410 | // Encrypt the MAC with CTR mode with a counter starting at 0. 411 | aes_encrypt_ctr(&out[payload_len], mac_len, &out[payload_len], key, keysize, counter); 412 | 413 | free(buf); 414 | *out_len = payload_len + mac_len; 415 | 416 | return(TRUE); 417 | } 418 | 419 | // plaintext_len = ciphertext_len - mac_len 420 | // Needs a flag for whether the MAC matches. 421 | int aes_decrypt_ccm(const BYTE ciphertext[], WORD ciphertext_len, const BYTE assoc[], unsigned short assoc_len, 422 | const BYTE nonce[], unsigned short nonce_len, BYTE plaintext[], WORD *plaintext_len, 423 | WORD mac_len, int *mac_auth, const BYTE key_str[], int keysize) 424 | { 425 | BYTE temp_iv[AES_BLOCK_SIZE], counter[AES_BLOCK_SIZE], mac[16], mac_buf[16], *buf; 426 | int end_of_buf, plaintext_len_store_size; 427 | WORD key[60]; 428 | 429 | if (ciphertext_len <= mac_len) 430 | return(FALSE); 431 | 432 | buf = (BYTE*)malloc(assoc_len + ciphertext_len /*ciphertext_len = plaintext_len + mac_len*/ + 48); 433 | if (! buf) 434 | return(FALSE); 435 | 436 | // Prepare the key for usage. 437 | aes_key_setup(key_str, key, keysize); 438 | 439 | // Copy the plaintext and MAC to the output buffers. 440 | *plaintext_len = ciphertext_len - mac_len; 441 | plaintext_len_store_size = AES_BLOCK_SIZE - 1 - nonce_len; 442 | memcpy(plaintext, ciphertext, *plaintext_len); 443 | memcpy(mac, &ciphertext[*plaintext_len], mac_len); 444 | 445 | // Prepare the first counter block for use in decryption. 446 | ccm_prepare_first_ctr_blk(counter, nonce, nonce_len, plaintext_len_store_size); 447 | 448 | // Decrypt the Payload with CTR mode with a counter starting at 1. 449 | memcpy(temp_iv, counter, AES_BLOCK_SIZE); 450 | increment_iv(temp_iv, AES_BLOCK_SIZE - 1 - mac_len); // (AES_BLOCK_SIZE - 1 - mac_len) is the byte size of the counting portion of the counter block. 451 | aes_decrypt_ctr(plaintext, *plaintext_len, plaintext, key, keysize, temp_iv); 452 | 453 | // Setting mac_auth to NULL disables the authentication check. 454 | if (mac_auth != NULL) { 455 | // Decrypt the MAC with CTR mode with a counter starting at 0. 456 | aes_decrypt_ctr(mac, mac_len, mac, key, keysize, counter); 457 | 458 | // Format the first block of the formatted data. 459 | plaintext_len_store_size = AES_BLOCK_SIZE - 1 - nonce_len; 460 | ccm_prepare_first_format_blk(buf, assoc_len, *plaintext_len, plaintext_len_store_size, mac_len, nonce, nonce_len); 461 | end_of_buf = AES_BLOCK_SIZE; 462 | 463 | // Format the Associated Data into the authentication buffer. 464 | ccm_format_assoc_data(buf, &end_of_buf, assoc, assoc_len); 465 | 466 | // Format the Payload into the authentication buffer. 467 | ccm_format_payload_data(buf, &end_of_buf, plaintext, *plaintext_len); 468 | 469 | // Perform the CBC operation with an IV of zeros on the formatted buffer to calculate the MAC. 470 | memset(temp_iv, 0, AES_BLOCK_SIZE); 471 | aes_encrypt_cbc_mac(buf, end_of_buf, mac_buf, key, keysize, temp_iv); 472 | 473 | // Compare the calculated MAC against the MAC embedded in the ciphertext to see if they are the same. 474 | if (! memcmp(mac, mac_buf, mac_len)) { 475 | *mac_auth = TRUE; 476 | } 477 | else { 478 | *mac_auth = FALSE; 479 | memset(plaintext, 0, *plaintext_len); 480 | } 481 | } 482 | 483 | free(buf); 484 | 485 | return(TRUE); 486 | } 487 | 488 | // Creates the first counter block. First byte is flags, then the nonce, then the incremented part. 489 | void ccm_prepare_first_ctr_blk(BYTE counter[], const BYTE nonce[], int nonce_len, int payload_len_store_size) 490 | { 491 | memset(counter, 0, AES_BLOCK_SIZE); 492 | counter[0] = (payload_len_store_size - 1) & 0x07; 493 | memcpy(&counter[1], nonce, nonce_len); 494 | } 495 | 496 | void ccm_prepare_first_format_blk(BYTE buf[], int assoc_len, int payload_len, int payload_len_store_size, int mac_len, const BYTE nonce[], int nonce_len) 497 | { 498 | // Set the flags for the first byte of the first block. 499 | buf[0] = ((((mac_len - 2) / 2) & 0x07) << 3) | ((payload_len_store_size - 1) & 0x07); 500 | if (assoc_len > 0) 501 | buf[0] += 0x40; 502 | // Format the rest of the first block, storing the nonce and the size of the payload. 503 | memcpy(&buf[1], nonce, nonce_len); 504 | memset(&buf[1 + nonce_len], 0, AES_BLOCK_SIZE - 1 - nonce_len); 505 | buf[15] = payload_len & 0x000000FF; 506 | buf[14] = (payload_len >> 8) & 0x000000FF; 507 | } 508 | 509 | void ccm_format_assoc_data(BYTE buf[], int *end_of_buf, const BYTE assoc[], int assoc_len) 510 | { 511 | int pad; 512 | 513 | buf[*end_of_buf + 1] = assoc_len & 0x00FF; 514 | buf[*end_of_buf] = (assoc_len >> 8) & 0x00FF; 515 | *end_of_buf += 2; 516 | memcpy(&buf[*end_of_buf], assoc, assoc_len); 517 | *end_of_buf += assoc_len; 518 | pad = AES_BLOCK_SIZE - (*end_of_buf % AES_BLOCK_SIZE); /*BUG?*/ 519 | memset(&buf[*end_of_buf], 0, pad); 520 | *end_of_buf += pad; 521 | } 522 | 523 | void ccm_format_payload_data(BYTE buf[], int *end_of_buf, const BYTE payload[], int payload_len) 524 | { 525 | int pad; 526 | 527 | memcpy(&buf[*end_of_buf], payload, payload_len); 528 | *end_of_buf += payload_len; 529 | pad = *end_of_buf % AES_BLOCK_SIZE; 530 | if (pad != 0) 531 | pad = AES_BLOCK_SIZE - pad; 532 | memset(&buf[*end_of_buf], 0, pad); 533 | *end_of_buf += pad; 534 | } 535 | 536 | /******************* 537 | * AES 538 | *******************/ 539 | ///////////////// 540 | // KEY EXPANSION 541 | ///////////////// 542 | 543 | // Substitutes a word using the AES S-Box. 544 | WORD SubWord(WORD word) 545 | { 546 | unsigned int result; 547 | 548 | result = (int)aes_sbox[(word >> 4) & 0x0000000F][word & 0x0000000F]; 549 | result += (int)aes_sbox[(word >> 12) & 0x0000000F][(word >> 8) & 0x0000000F] << 8; 550 | result += (int)aes_sbox[(word >> 20) & 0x0000000F][(word >> 16) & 0x0000000F] << 16; 551 | result += (int)aes_sbox[(word >> 28) & 0x0000000F][(word >> 24) & 0x0000000F] << 24; 552 | return(result); 553 | } 554 | 555 | // Performs the action of generating the keys that will be used in every round of 556 | // encryption. "key" is the user-supplied input key, "w" is the output key schedule, 557 | // "keysize" is the length in bits of "key", must be 128, 192, or 256. 558 | void aes_key_setup(const BYTE key[], WORD w[], int keysize) 559 | { 560 | int Nb=4,Nr,Nk,idx; 561 | WORD temp,Rcon[]={0x01000000,0x02000000,0x04000000,0x08000000,0x10000000,0x20000000, 562 | 0x40000000,0x80000000,0x1b000000,0x36000000,0x6c000000,0xd8000000, 563 | 0xab000000,0x4d000000,0x9a000000}; 564 | 565 | switch (keysize) { 566 | case 128: Nr = 10; Nk = 4; break; 567 | case 192: Nr = 12; Nk = 6; break; 568 | case 256: Nr = 14; Nk = 8; break; 569 | default: return; 570 | } 571 | 572 | for (idx=0; idx < Nk; ++idx) { 573 | w[idx] = ((key[4 * idx]) << 24) | ((key[4 * idx + 1]) << 16) | 574 | ((key[4 * idx + 2]) << 8) | ((key[4 * idx + 3])); 575 | } 576 | 577 | for (idx = Nk; idx < Nb * (Nr+1); ++idx) { 578 | temp = w[idx - 1]; 579 | if ((idx % Nk) == 0) 580 | temp = SubWord(KE_ROTWORD(temp)) ^ Rcon[(idx-1)/Nk]; 581 | else if (Nk > 6 && (idx % Nk) == 4) 582 | temp = SubWord(temp); 583 | w[idx] = w[idx-Nk] ^ temp; 584 | } 585 | } 586 | 587 | ///////////////// 588 | // ADD ROUND KEY 589 | ///////////////// 590 | 591 | // Performs the AddRoundKey step. Each round has its own pre-generated 16-byte key in the 592 | // form of 4 integers (the "w" array). Each integer is XOR'd by one column of the state. 593 | // Also performs the job of InvAddRoundKey(); since the function is a simple XOR process, 594 | // it is its own inverse. 595 | void AddRoundKey(BYTE state[][4], const WORD w[]) 596 | { 597 | BYTE subkey[4]; 598 | 599 | // memcpy(subkey,&w[idx],4); // Not accurate for big endian machines 600 | // Subkey 1 601 | subkey[0] = w[0] >> 24; 602 | subkey[1] = w[0] >> 16; 603 | subkey[2] = w[0] >> 8; 604 | subkey[3] = w[0]; 605 | state[0][0] ^= subkey[0]; 606 | state[1][0] ^= subkey[1]; 607 | state[2][0] ^= subkey[2]; 608 | state[3][0] ^= subkey[3]; 609 | // Subkey 2 610 | subkey[0] = w[1] >> 24; 611 | subkey[1] = w[1] >> 16; 612 | subkey[2] = w[1] >> 8; 613 | subkey[3] = w[1]; 614 | state[0][1] ^= subkey[0]; 615 | state[1][1] ^= subkey[1]; 616 | state[2][1] ^= subkey[2]; 617 | state[3][1] ^= subkey[3]; 618 | // Subkey 3 619 | subkey[0] = w[2] >> 24; 620 | subkey[1] = w[2] >> 16; 621 | subkey[2] = w[2] >> 8; 622 | subkey[3] = w[2]; 623 | state[0][2] ^= subkey[0]; 624 | state[1][2] ^= subkey[1]; 625 | state[2][2] ^= subkey[2]; 626 | state[3][2] ^= subkey[3]; 627 | // Subkey 4 628 | subkey[0] = w[3] >> 24; 629 | subkey[1] = w[3] >> 16; 630 | subkey[2] = w[3] >> 8; 631 | subkey[3] = w[3]; 632 | state[0][3] ^= subkey[0]; 633 | state[1][3] ^= subkey[1]; 634 | state[2][3] ^= subkey[2]; 635 | state[3][3] ^= subkey[3]; 636 | } 637 | 638 | ///////////////// 639 | // (Inv)SubBytes 640 | ///////////////// 641 | 642 | // Performs the SubBytes step. All bytes in the state are substituted with a 643 | // pre-calculated value from a lookup table. 644 | void SubBytes(BYTE state[][4]) 645 | { 646 | state[0][0] = aes_sbox[state[0][0] >> 4][state[0][0] & 0x0F]; 647 | state[0][1] = aes_sbox[state[0][1] >> 4][state[0][1] & 0x0F]; 648 | state[0][2] = aes_sbox[state[0][2] >> 4][state[0][2] & 0x0F]; 649 | state[0][3] = aes_sbox[state[0][3] >> 4][state[0][3] & 0x0F]; 650 | state[1][0] = aes_sbox[state[1][0] >> 4][state[1][0] & 0x0F]; 651 | state[1][1] = aes_sbox[state[1][1] >> 4][state[1][1] & 0x0F]; 652 | state[1][2] = aes_sbox[state[1][2] >> 4][state[1][2] & 0x0F]; 653 | state[1][3] = aes_sbox[state[1][3] >> 4][state[1][3] & 0x0F]; 654 | state[2][0] = aes_sbox[state[2][0] >> 4][state[2][0] & 0x0F]; 655 | state[2][1] = aes_sbox[state[2][1] >> 4][state[2][1] & 0x0F]; 656 | state[2][2] = aes_sbox[state[2][2] >> 4][state[2][2] & 0x0F]; 657 | state[2][3] = aes_sbox[state[2][3] >> 4][state[2][3] & 0x0F]; 658 | state[3][0] = aes_sbox[state[3][0] >> 4][state[3][0] & 0x0F]; 659 | state[3][1] = aes_sbox[state[3][1] >> 4][state[3][1] & 0x0F]; 660 | state[3][2] = aes_sbox[state[3][2] >> 4][state[3][2] & 0x0F]; 661 | state[3][3] = aes_sbox[state[3][3] >> 4][state[3][3] & 0x0F]; 662 | } 663 | 664 | void InvSubBytes(BYTE state[][4]) 665 | { 666 | state[0][0] = aes_invsbox[state[0][0] >> 4][state[0][0] & 0x0F]; 667 | state[0][1] = aes_invsbox[state[0][1] >> 4][state[0][1] & 0x0F]; 668 | state[0][2] = aes_invsbox[state[0][2] >> 4][state[0][2] & 0x0F]; 669 | state[0][3] = aes_invsbox[state[0][3] >> 4][state[0][3] & 0x0F]; 670 | state[1][0] = aes_invsbox[state[1][0] >> 4][state[1][0] & 0x0F]; 671 | state[1][1] = aes_invsbox[state[1][1] >> 4][state[1][1] & 0x0F]; 672 | state[1][2] = aes_invsbox[state[1][2] >> 4][state[1][2] & 0x0F]; 673 | state[1][3] = aes_invsbox[state[1][3] >> 4][state[1][3] & 0x0F]; 674 | state[2][0] = aes_invsbox[state[2][0] >> 4][state[2][0] & 0x0F]; 675 | state[2][1] = aes_invsbox[state[2][1] >> 4][state[2][1] & 0x0F]; 676 | state[2][2] = aes_invsbox[state[2][2] >> 4][state[2][2] & 0x0F]; 677 | state[2][3] = aes_invsbox[state[2][3] >> 4][state[2][3] & 0x0F]; 678 | state[3][0] = aes_invsbox[state[3][0] >> 4][state[3][0] & 0x0F]; 679 | state[3][1] = aes_invsbox[state[3][1] >> 4][state[3][1] & 0x0F]; 680 | state[3][2] = aes_invsbox[state[3][2] >> 4][state[3][2] & 0x0F]; 681 | state[3][3] = aes_invsbox[state[3][3] >> 4][state[3][3] & 0x0F]; 682 | } 683 | 684 | ///////////////// 685 | // (Inv)ShiftRows 686 | ///////////////// 687 | 688 | // Performs the ShiftRows step. All rows are shifted cylindrically to the left. 689 | void ShiftRows(BYTE state[][4]) 690 | { 691 | int t; 692 | 693 | // Shift left by 1 694 | t = state[1][0]; 695 | state[1][0] = state[1][1]; 696 | state[1][1] = state[1][2]; 697 | state[1][2] = state[1][3]; 698 | state[1][3] = t; 699 | // Shift left by 2 700 | t = state[2][0]; 701 | state[2][0] = state[2][2]; 702 | state[2][2] = t; 703 | t = state[2][1]; 704 | state[2][1] = state[2][3]; 705 | state[2][3] = t; 706 | // Shift left by 3 707 | t = state[3][0]; 708 | state[3][0] = state[3][3]; 709 | state[3][3] = state[3][2]; 710 | state[3][2] = state[3][1]; 711 | state[3][1] = t; 712 | } 713 | 714 | // All rows are shifted cylindrically to the right. 715 | void InvShiftRows(BYTE state[][4]) 716 | { 717 | int t; 718 | 719 | // Shift right by 1 720 | t = state[1][3]; 721 | state[1][3] = state[1][2]; 722 | state[1][2] = state[1][1]; 723 | state[1][1] = state[1][0]; 724 | state[1][0] = t; 725 | // Shift right by 2 726 | t = state[2][3]; 727 | state[2][3] = state[2][1]; 728 | state[2][1] = t; 729 | t = state[2][2]; 730 | state[2][2] = state[2][0]; 731 | state[2][0] = t; 732 | // Shift right by 3 733 | t = state[3][3]; 734 | state[3][3] = state[3][0]; 735 | state[3][0] = state[3][1]; 736 | state[3][1] = state[3][2]; 737 | state[3][2] = t; 738 | } 739 | 740 | ///////////////// 741 | // (Inv)MixColumns 742 | ///////////////// 743 | 744 | // Performs the MixColums step. The state is multiplied by itself using matrix 745 | // multiplication in a Galios Field 2^8. All multiplication is pre-computed in a table. 746 | // Addition is equivilent to XOR. (Must always make a copy of the column as the original 747 | // values will be destoyed.) 748 | void MixColumns(BYTE state[][4]) 749 | { 750 | BYTE col[4]; 751 | 752 | // Column 1 753 | col[0] = state[0][0]; 754 | col[1] = state[1][0]; 755 | col[2] = state[2][0]; 756 | col[3] = state[3][0]; 757 | state[0][0] = gf_mul[col[0]][0]; 758 | state[0][0] ^= gf_mul[col[1]][1]; 759 | state[0][0] ^= col[2]; 760 | state[0][0] ^= col[3]; 761 | state[1][0] = col[0]; 762 | state[1][0] ^= gf_mul[col[1]][0]; 763 | state[1][0] ^= gf_mul[col[2]][1]; 764 | state[1][0] ^= col[3]; 765 | state[2][0] = col[0]; 766 | state[2][0] ^= col[1]; 767 | state[2][0] ^= gf_mul[col[2]][0]; 768 | state[2][0] ^= gf_mul[col[3]][1]; 769 | state[3][0] = gf_mul[col[0]][1]; 770 | state[3][0] ^= col[1]; 771 | state[3][0] ^= col[2]; 772 | state[3][0] ^= gf_mul[col[3]][0]; 773 | // Column 2 774 | col[0] = state[0][1]; 775 | col[1] = state[1][1]; 776 | col[2] = state[2][1]; 777 | col[3] = state[3][1]; 778 | state[0][1] = gf_mul[col[0]][0]; 779 | state[0][1] ^= gf_mul[col[1]][1]; 780 | state[0][1] ^= col[2]; 781 | state[0][1] ^= col[3]; 782 | state[1][1] = col[0]; 783 | state[1][1] ^= gf_mul[col[1]][0]; 784 | state[1][1] ^= gf_mul[col[2]][1]; 785 | state[1][1] ^= col[3]; 786 | state[2][1] = col[0]; 787 | state[2][1] ^= col[1]; 788 | state[2][1] ^= gf_mul[col[2]][0]; 789 | state[2][1] ^= gf_mul[col[3]][1]; 790 | state[3][1] = gf_mul[col[0]][1]; 791 | state[3][1] ^= col[1]; 792 | state[3][1] ^= col[2]; 793 | state[3][1] ^= gf_mul[col[3]][0]; 794 | // Column 3 795 | col[0] = state[0][2]; 796 | col[1] = state[1][2]; 797 | col[2] = state[2][2]; 798 | col[3] = state[3][2]; 799 | state[0][2] = gf_mul[col[0]][0]; 800 | state[0][2] ^= gf_mul[col[1]][1]; 801 | state[0][2] ^= col[2]; 802 | state[0][2] ^= col[3]; 803 | state[1][2] = col[0]; 804 | state[1][2] ^= gf_mul[col[1]][0]; 805 | state[1][2] ^= gf_mul[col[2]][1]; 806 | state[1][2] ^= col[3]; 807 | state[2][2] = col[0]; 808 | state[2][2] ^= col[1]; 809 | state[2][2] ^= gf_mul[col[2]][0]; 810 | state[2][2] ^= gf_mul[col[3]][1]; 811 | state[3][2] = gf_mul[col[0]][1]; 812 | state[3][2] ^= col[1]; 813 | state[3][2] ^= col[2]; 814 | state[3][2] ^= gf_mul[col[3]][0]; 815 | // Column 4 816 | col[0] = state[0][3]; 817 | col[1] = state[1][3]; 818 | col[2] = state[2][3]; 819 | col[3] = state[3][3]; 820 | state[0][3] = gf_mul[col[0]][0]; 821 | state[0][3] ^= gf_mul[col[1]][1]; 822 | state[0][3] ^= col[2]; 823 | state[0][3] ^= col[3]; 824 | state[1][3] = col[0]; 825 | state[1][3] ^= gf_mul[col[1]][0]; 826 | state[1][3] ^= gf_mul[col[2]][1]; 827 | state[1][3] ^= col[3]; 828 | state[2][3] = col[0]; 829 | state[2][3] ^= col[1]; 830 | state[2][3] ^= gf_mul[col[2]][0]; 831 | state[2][3] ^= gf_mul[col[3]][1]; 832 | state[3][3] = gf_mul[col[0]][1]; 833 | state[3][3] ^= col[1]; 834 | state[3][3] ^= col[2]; 835 | state[3][3] ^= gf_mul[col[3]][0]; 836 | } 837 | 838 | void InvMixColumns(BYTE state[][4]) 839 | { 840 | BYTE col[4]; 841 | 842 | // Column 1 843 | col[0] = state[0][0]; 844 | col[1] = state[1][0]; 845 | col[2] = state[2][0]; 846 | col[3] = state[3][0]; 847 | state[0][0] = gf_mul[col[0]][5]; 848 | state[0][0] ^= gf_mul[col[1]][3]; 849 | state[0][0] ^= gf_mul[col[2]][4]; 850 | state[0][0] ^= gf_mul[col[3]][2]; 851 | state[1][0] = gf_mul[col[0]][2]; 852 | state[1][0] ^= gf_mul[col[1]][5]; 853 | state[1][0] ^= gf_mul[col[2]][3]; 854 | state[1][0] ^= gf_mul[col[3]][4]; 855 | state[2][0] = gf_mul[col[0]][4]; 856 | state[2][0] ^= gf_mul[col[1]][2]; 857 | state[2][0] ^= gf_mul[col[2]][5]; 858 | state[2][0] ^= gf_mul[col[3]][3]; 859 | state[3][0] = gf_mul[col[0]][3]; 860 | state[3][0] ^= gf_mul[col[1]][4]; 861 | state[3][0] ^= gf_mul[col[2]][2]; 862 | state[3][0] ^= gf_mul[col[3]][5]; 863 | // Column 2 864 | col[0] = state[0][1]; 865 | col[1] = state[1][1]; 866 | col[2] = state[2][1]; 867 | col[3] = state[3][1]; 868 | state[0][1] = gf_mul[col[0]][5]; 869 | state[0][1] ^= gf_mul[col[1]][3]; 870 | state[0][1] ^= gf_mul[col[2]][4]; 871 | state[0][1] ^= gf_mul[col[3]][2]; 872 | state[1][1] = gf_mul[col[0]][2]; 873 | state[1][1] ^= gf_mul[col[1]][5]; 874 | state[1][1] ^= gf_mul[col[2]][3]; 875 | state[1][1] ^= gf_mul[col[3]][4]; 876 | state[2][1] = gf_mul[col[0]][4]; 877 | state[2][1] ^= gf_mul[col[1]][2]; 878 | state[2][1] ^= gf_mul[col[2]][5]; 879 | state[2][1] ^= gf_mul[col[3]][3]; 880 | state[3][1] = gf_mul[col[0]][3]; 881 | state[3][1] ^= gf_mul[col[1]][4]; 882 | state[3][1] ^= gf_mul[col[2]][2]; 883 | state[3][1] ^= gf_mul[col[3]][5]; 884 | // Column 3 885 | col[0] = state[0][2]; 886 | col[1] = state[1][2]; 887 | col[2] = state[2][2]; 888 | col[3] = state[3][2]; 889 | state[0][2] = gf_mul[col[0]][5]; 890 | state[0][2] ^= gf_mul[col[1]][3]; 891 | state[0][2] ^= gf_mul[col[2]][4]; 892 | state[0][2] ^= gf_mul[col[3]][2]; 893 | state[1][2] = gf_mul[col[0]][2]; 894 | state[1][2] ^= gf_mul[col[1]][5]; 895 | state[1][2] ^= gf_mul[col[2]][3]; 896 | state[1][2] ^= gf_mul[col[3]][4]; 897 | state[2][2] = gf_mul[col[0]][4]; 898 | state[2][2] ^= gf_mul[col[1]][2]; 899 | state[2][2] ^= gf_mul[col[2]][5]; 900 | state[2][2] ^= gf_mul[col[3]][3]; 901 | state[3][2] = gf_mul[col[0]][3]; 902 | state[3][2] ^= gf_mul[col[1]][4]; 903 | state[3][2] ^= gf_mul[col[2]][2]; 904 | state[3][2] ^= gf_mul[col[3]][5]; 905 | // Column 4 906 | col[0] = state[0][3]; 907 | col[1] = state[1][3]; 908 | col[2] = state[2][3]; 909 | col[3] = state[3][3]; 910 | state[0][3] = gf_mul[col[0]][5]; 911 | state[0][3] ^= gf_mul[col[1]][3]; 912 | state[0][3] ^= gf_mul[col[2]][4]; 913 | state[0][3] ^= gf_mul[col[3]][2]; 914 | state[1][3] = gf_mul[col[0]][2]; 915 | state[1][3] ^= gf_mul[col[1]][5]; 916 | state[1][3] ^= gf_mul[col[2]][3]; 917 | state[1][3] ^= gf_mul[col[3]][4]; 918 | state[2][3] = gf_mul[col[0]][4]; 919 | state[2][3] ^= gf_mul[col[1]][2]; 920 | state[2][3] ^= gf_mul[col[2]][5]; 921 | state[2][3] ^= gf_mul[col[3]][3]; 922 | state[3][3] = gf_mul[col[0]][3]; 923 | state[3][3] ^= gf_mul[col[1]][4]; 924 | state[3][3] ^= gf_mul[col[2]][2]; 925 | state[3][3] ^= gf_mul[col[3]][5]; 926 | } 927 | 928 | ///////////////// 929 | // (En/De)Crypt 930 | ///////////////// 931 | 932 | void aes_encrypt(const BYTE in[], BYTE out[], const WORD key[], int keysize) 933 | { 934 | BYTE state[4][4]; 935 | 936 | // Copy input array (should be 16 bytes long) to a matrix (sequential bytes are ordered 937 | // by row, not col) called "state" for processing. 938 | // *** Implementation note: The official AES documentation references the state by 939 | // column, then row. Accessing an element in C requires row then column. Thus, all state 940 | // references in AES must have the column and row indexes reversed for C implementation. 941 | state[0][0] = in[0]; 942 | state[1][0] = in[1]; 943 | state[2][0] = in[2]; 944 | state[3][0] = in[3]; 945 | state[0][1] = in[4]; 946 | state[1][1] = in[5]; 947 | state[2][1] = in[6]; 948 | state[3][1] = in[7]; 949 | state[0][2] = in[8]; 950 | state[1][2] = in[9]; 951 | state[2][2] = in[10]; 952 | state[3][2] = in[11]; 953 | state[0][3] = in[12]; 954 | state[1][3] = in[13]; 955 | state[2][3] = in[14]; 956 | state[3][3] = in[15]; 957 | 958 | // Perform the necessary number of rounds. The round key is added first. 959 | // The last round does not perform the MixColumns step. 960 | AddRoundKey(state,&key[0]); 961 | SubBytes(state); ShiftRows(state); MixColumns(state); AddRoundKey(state,&key[4]); 962 | SubBytes(state); ShiftRows(state); MixColumns(state); AddRoundKey(state,&key[8]); 963 | SubBytes(state); ShiftRows(state); MixColumns(state); AddRoundKey(state,&key[12]); 964 | SubBytes(state); ShiftRows(state); MixColumns(state); AddRoundKey(state,&key[16]); 965 | SubBytes(state); ShiftRows(state); MixColumns(state); AddRoundKey(state,&key[20]); 966 | SubBytes(state); ShiftRows(state); MixColumns(state); AddRoundKey(state,&key[24]); 967 | SubBytes(state); ShiftRows(state); MixColumns(state); AddRoundKey(state,&key[28]); 968 | SubBytes(state); ShiftRows(state); MixColumns(state); AddRoundKey(state,&key[32]); 969 | SubBytes(state); ShiftRows(state); MixColumns(state); AddRoundKey(state,&key[36]); 970 | if (keysize != 128) { 971 | SubBytes(state); ShiftRows(state); MixColumns(state); AddRoundKey(state,&key[40]); 972 | SubBytes(state); ShiftRows(state); MixColumns(state); AddRoundKey(state,&key[44]); 973 | if (keysize != 192) { 974 | SubBytes(state); ShiftRows(state); MixColumns(state); AddRoundKey(state,&key[48]); 975 | SubBytes(state); ShiftRows(state); MixColumns(state); AddRoundKey(state,&key[52]); 976 | SubBytes(state); ShiftRows(state); AddRoundKey(state,&key[56]); 977 | } 978 | else { 979 | SubBytes(state); ShiftRows(state); AddRoundKey(state,&key[48]); 980 | } 981 | } 982 | else { 983 | SubBytes(state); ShiftRows(state); AddRoundKey(state,&key[40]); 984 | } 985 | 986 | // Copy the state to the output array. 987 | out[0] = state[0][0]; 988 | out[1] = state[1][0]; 989 | out[2] = state[2][0]; 990 | out[3] = state[3][0]; 991 | out[4] = state[0][1]; 992 | out[5] = state[1][1]; 993 | out[6] = state[2][1]; 994 | out[7] = state[3][1]; 995 | out[8] = state[0][2]; 996 | out[9] = state[1][2]; 997 | out[10] = state[2][2]; 998 | out[11] = state[3][2]; 999 | out[12] = state[0][3]; 1000 | out[13] = state[1][3]; 1001 | out[14] = state[2][3]; 1002 | out[15] = state[3][3]; 1003 | } 1004 | 1005 | void aes_decrypt(const BYTE in[], BYTE out[], const WORD key[], int keysize) 1006 | { 1007 | BYTE state[4][4]; 1008 | 1009 | // Copy the input to the state. 1010 | state[0][0] = in[0]; 1011 | state[1][0] = in[1]; 1012 | state[2][0] = in[2]; 1013 | state[3][0] = in[3]; 1014 | state[0][1] = in[4]; 1015 | state[1][1] = in[5]; 1016 | state[2][1] = in[6]; 1017 | state[3][1] = in[7]; 1018 | state[0][2] = in[8]; 1019 | state[1][2] = in[9]; 1020 | state[2][2] = in[10]; 1021 | state[3][2] = in[11]; 1022 | state[0][3] = in[12]; 1023 | state[1][3] = in[13]; 1024 | state[2][3] = in[14]; 1025 | state[3][3] = in[15]; 1026 | 1027 | // Perform the necessary number of rounds. The round key is added first. 1028 | // The last round does not perform the MixColumns step. 1029 | if (keysize > 128) { 1030 | if (keysize > 192) { 1031 | AddRoundKey(state,&key[56]); 1032 | InvShiftRows(state);InvSubBytes(state);AddRoundKey(state,&key[52]);InvMixColumns(state); 1033 | InvShiftRows(state);InvSubBytes(state);AddRoundKey(state,&key[48]);InvMixColumns(state); 1034 | } 1035 | else { 1036 | AddRoundKey(state,&key[48]); 1037 | } 1038 | InvShiftRows(state);InvSubBytes(state);AddRoundKey(state,&key[44]);InvMixColumns(state); 1039 | InvShiftRows(state);InvSubBytes(state);AddRoundKey(state,&key[40]);InvMixColumns(state); 1040 | } 1041 | else { 1042 | AddRoundKey(state,&key[40]); 1043 | } 1044 | InvShiftRows(state);InvSubBytes(state);AddRoundKey(state,&key[36]);InvMixColumns(state); 1045 | InvShiftRows(state);InvSubBytes(state);AddRoundKey(state,&key[32]);InvMixColumns(state); 1046 | InvShiftRows(state);InvSubBytes(state);AddRoundKey(state,&key[28]);InvMixColumns(state); 1047 | InvShiftRows(state);InvSubBytes(state);AddRoundKey(state,&key[24]);InvMixColumns(state); 1048 | InvShiftRows(state);InvSubBytes(state);AddRoundKey(state,&key[20]);InvMixColumns(state); 1049 | InvShiftRows(state);InvSubBytes(state);AddRoundKey(state,&key[16]);InvMixColumns(state); 1050 | InvShiftRows(state);InvSubBytes(state);AddRoundKey(state,&key[12]);InvMixColumns(state); 1051 | InvShiftRows(state);InvSubBytes(state);AddRoundKey(state,&key[8]);InvMixColumns(state); 1052 | InvShiftRows(state);InvSubBytes(state);AddRoundKey(state,&key[4]);InvMixColumns(state); 1053 | InvShiftRows(state);InvSubBytes(state);AddRoundKey(state,&key[0]); 1054 | 1055 | // Copy the state to the output array. 1056 | out[0] = state[0][0]; 1057 | out[1] = state[1][0]; 1058 | out[2] = state[2][0]; 1059 | out[3] = state[3][0]; 1060 | out[4] = state[0][1]; 1061 | out[5] = state[1][1]; 1062 | out[6] = state[2][1]; 1063 | out[7] = state[3][1]; 1064 | out[8] = state[0][2]; 1065 | out[9] = state[1][2]; 1066 | out[10] = state[2][2]; 1067 | out[11] = state[3][2]; 1068 | out[12] = state[0][3]; 1069 | out[13] = state[1][3]; 1070 | out[14] = state[2][3]; 1071 | out[15] = state[3][3]; 1072 | } 1073 | 1074 | /******************* 1075 | ** AES DEBUGGING FUNCTIONS 1076 | *******************/ 1077 | /* 1078 | // This prints the "state" grid as a linear hex string. 1079 | void print_state(BYTE state[][4]) 1080 | { 1081 | int idx,idx2; 1082 | 1083 | for (idx=0; idx < 4; idx++) 1084 | for (idx2=0; idx2 < 4; idx2++) 1085 | printf("%02x",state[idx2][idx]); 1086 | printf("\n"); 1087 | } 1088 | 1089 | // This prints the key (4 consecutive ints) used for a given round as a linear hex string. 1090 | void print_rnd_key(WORD key[]) 1091 | { 1092 | int idx; 1093 | 1094 | for (idx=0; idx < 4; idx++) 1095 | printf("%08x",key[idx]); 1096 | printf("\n"); 1097 | } 1098 | */ 1099 | -------------------------------------------------------------------------------- /QAes/aes.h: -------------------------------------------------------------------------------- 1 | /********************************************************************* 2 | * Filename: aes.h 3 | * Author: Brad Conte (brad AT bradconte.com) 4 | * Copyright: 5 | * Disclaimer: This code is presented "as is" without any guarantees. 6 | * Details: Defines the API for the corresponding AES implementation. 7 | *********************************************************************/ 8 | 9 | #ifndef AES_H 10 | #define AES_H 11 | 12 | /*************************** HEADER FILES ***************************/ 13 | #include 14 | 15 | /****************************** MACROS ******************************/ 16 | #define AES_BLOCK_SIZE 16 // AES operates on 16 bytes at a time 17 | 18 | /**************************** DATA TYPES ****************************/ 19 | typedef unsigned char BYTE; // 8-bit byte 20 | typedef unsigned int WORD; // 32-bit word, change to "long" for 16-bit machines 21 | 22 | /*********************** FUNCTION DECLARATIONS **********************/ 23 | /////////////////// 24 | // AES 25 | /////////////////// 26 | // Key setup must be done before any AES en/de-cryption functions can be used. 27 | // 128 bits = 16 字节 28 | // 192 bits = 24 字节 29 | // 256 bits = 32 字节 30 | void aes_key_setup(const BYTE key[], // The key, must be 128, 192, or 256 bits 31 | WORD w[], // Output key schedule to be used later 32 | int keysize); // Bit length of the key, 128, 192, or 256 33 | 34 | void aes_encrypt(const BYTE in[], // 16 bytes of plaintext 35 | BYTE out[], // 16 bytes of ciphertext 36 | const WORD key[], // From the key setup 37 | int keysize); // Bit length of the key, 128, 192, or 256 38 | 39 | void aes_decrypt(const BYTE in[], // 16 bytes of ciphertext 40 | BYTE out[], // 16 bytes of plaintext 41 | const WORD key[], // From the key setup 42 | int keysize); // Bit length of the key, 128, 192, or 256 43 | 44 | /////////////////// 45 | // AES - CBC 46 | /////////////////// 47 | void aes_encrypt_cbc(const BYTE in[], // Plaintext 48 | size_t in_len, const BYTE * lastBlock, // Must be a multiple of AES_BLOCK_SIZE 49 | BYTE out[], // Ciphertext, same length as plaintext 50 | const WORD key[], // From the key setup 51 | int keysize, // Bit length of the key, 128, 192, or 256 52 | const BYTE iv[]); // IV, must be AES_BLOCK_SIZE bytes long 53 | 54 | void aes_decrypt_cbc(const BYTE in[], 55 | size_t in_len, 56 | BYTE out[], 57 | const WORD key[], 58 | int keysize, 59 | const BYTE iv[]); 60 | 61 | //// Only output the CBC-MAC of the input. 62 | //int aes_encrypt_cbc_mac(const BYTE in[], // plaintext 63 | // size_t in_len, // Must be a multiple of AES_BLOCK_SIZE 64 | // BYTE out[], // Output MAC 65 | // const WORD key[], // From the key setup 66 | // int keysize, // Bit length of the key, 128, 192, or 256 67 | // const BYTE iv[]); // IV, must be AES_BLOCK_SIZE bytes long 68 | 69 | /////////////////// 70 | // AES - CTR 71 | /////////////////// 72 | //void increment_iv(BYTE iv[], // Must be a multiple of AES_BLOCK_SIZE 73 | // int counter_size); // Bytes of the IV used for counting (low end) 74 | 75 | void aes_encrypt_ctr(const BYTE in[], // Plaintext 76 | size_t in_len, // Any byte length 77 | BYTE out[], // Ciphertext, same length as plaintext 78 | const WORD key[], // From the key setup 79 | int keysize, // Bit length of the key, 128, 192, or 256 80 | const BYTE iv[]); // IV, must be AES_BLOCK_SIZE bytes long 81 | 82 | void aes_decrypt_ctr(const BYTE in[], // Ciphertext 83 | size_t in_len, // Any byte length 84 | BYTE out[], // Plaintext, same length as ciphertext 85 | const WORD key[], // From the key setup 86 | int keysize, // Bit length of the key, 128, 192, or 256 87 | const BYTE iv[]); // IV, must be AES_BLOCK_SIZE bytes long 88 | 89 | /////////////////// 90 | // AES - CCM 91 | /////////////////// 92 | // Returns True if the input parameters do not violate any constraint. 93 | int aes_encrypt_ccm(const BYTE plaintext[], // IN - Plaintext. 94 | WORD plaintext_len, // IN - Plaintext length. 95 | const BYTE associated_data[], // IN - Associated Data included in authentication, but not encryption. 96 | unsigned short associated_data_len, // IN - Associated Data length in bytes. 97 | const BYTE nonce[], // IN - The Nonce to be used for encryption. 98 | unsigned short nonce_len, // IN - Nonce length in bytes. 99 | BYTE ciphertext[], // OUT - Ciphertext, a concatination of the plaintext and the MAC. 100 | WORD *ciphertext_len, // OUT - The length of the ciphertext, always plaintext_len + mac_len. 101 | WORD mac_len, // IN - The desired length of the MAC, must be 4, 6, 8, 10, 12, 14, or 16. 102 | const BYTE key[], // IN - The AES key for encryption. 103 | int keysize); // IN - The length of the key in bits. Valid values are 128, 192, 256. 104 | 105 | // Returns True if the input parameters do not violate any constraint. 106 | // Use mac_auth to ensure decryption/validation was preformed correctly. 107 | // If authentication does not succeed, the plaintext is zeroed out. To overwride 108 | // this, call with mac_auth = NULL. The proper proceedure is to decrypt with 109 | // authentication enabled (mac_auth != NULL) and make a second call to that 110 | // ignores authentication explicitly if the first call failes. 111 | int aes_decrypt_ccm(const BYTE ciphertext[], // IN - Ciphertext, the concatination of encrypted plaintext and MAC. 112 | WORD ciphertext_len, // IN - Ciphertext length in bytes. 113 | const BYTE assoc[], // IN - The Associated Data, required for authentication. 114 | unsigned short assoc_len, // IN - Associated Data length in bytes. 115 | const BYTE nonce[], // IN - The Nonce to use for decryption, same one as for encryption. 116 | unsigned short nonce_len, // IN - Nonce length in bytes. 117 | BYTE plaintext[], // OUT - The plaintext that was decrypted. Will need to be large enough to hold ciphertext_len - mac_len. 118 | WORD *plaintext_len, // OUT - Length in bytes of the output plaintext, always ciphertext_len - mac_len . 119 | WORD mac_len, // IN - The length of the MAC that was calculated. 120 | int *mac_auth, // OUT - TRUE if authentication succeeded, FALSE if it did not. NULL pointer will ignore the authentication. 121 | const BYTE key[], // IN - The AES key for decryption. 122 | int keysize); // IN - The length of the key in BITS. Valid values are 128, 192, 256. 123 | 124 | #endif // AES_H 125 | -------------------------------------------------------------------------------- /QAes/qaeswrap.cpp: -------------------------------------------------------------------------------- 1 | #include "qaeswrap.h" 2 | #include 3 | 4 | QAesWrap::QAesWrap(const QByteArray & passwprd,const QByteArray & salt,AesBit bit):mbit(bit) 5 | { 6 | QByteArray data = QCryptographicHash::hash(passwprd,QCryptographicHash::Sha3_256); 7 | aes_key_setup((unsigned char *)data.data(),mpass,mbit); 8 | data = QCryptographicHash::hash(salt,QCryptographicHash::Sha3_256); 9 | memcpy(msalt,data.data(),AES_BLOCK_SIZE); 10 | } 11 | 12 | bool QAesWrap::encrypt(const QByteArray & in, QByteArray & out, AesMode mode,PaddingMode pad) const 13 | { 14 | if (in.isEmpty()) return false; 15 | out.clear(); 16 | switch (mode) { 17 | case AES_CTR: 18 | out.resize(in.size()); 19 | aes_encrypt_ctr((unsigned char *)in.data(),in.size(),(unsigned char *)out.data(),mpass,mbit,msalt); 20 | break; 21 | case AES_ECB: 22 | case AES_CBC: 23 | initPadding(in,out,mode,pad); 24 | break; 25 | default: 26 | return false; 27 | } 28 | return true; 29 | } 30 | 31 | void QAesWrap::initPadding(const QByteArray & in,QByteArray & out,AesMode mode,PaddingMode pad) const 32 | { 33 | int size = in.size(); 34 | int last = size % AES_BLOCK_SIZE; 35 | const BYTE * data = (unsigned char *)in.data(); 36 | if (last == 0) { 37 | out.resize(size); 38 | if (mode == AES_ECB) { 39 | ecbencrypt(data,size,0,out); 40 | } else { 41 | aes_encrypt_cbc(data,size,0,(unsigned char *)out.data(),mpass,mbit,msalt); 42 | } 43 | return; 44 | } 45 | int blocks = size / AES_BLOCK_SIZE; 46 | 47 | BYTE datablocks[AES_BLOCK_SIZE] = {0}; 48 | memcpy(datablocks,(data + blocks * AES_BLOCK_SIZE),last); 49 | 50 | uchar ch = uchar(AES_BLOCK_SIZE - last); 51 | 52 | switch (pad) { 53 | case ANSIX923: 54 | case PKCS7: 55 | { 56 | size = blocks * AES_BLOCK_SIZE; 57 | out.resize((blocks +1) * AES_BLOCK_SIZE); 58 | if (pad == ANSIX923) { 59 | memset(&datablocks[last],0,(ch -1)); 60 | datablocks[AES_BLOCK_SIZE -1] = ch; 61 | } else { 62 | memset(&datablocks[last],ch,ch); 63 | } 64 | 65 | if (mode == AES_ECB) { 66 | ecbencrypt(data,size,datablocks,out); 67 | } else { 68 | aes_encrypt_cbc(data,size,datablocks,(unsigned char *)out.data(),mpass,mbit,msalt); 69 | } 70 | } 71 | break; 72 | default: 73 | { 74 | if (blocks <= 0) {out = in; return;} 75 | out.resize(size); 76 | size = blocks * AES_BLOCK_SIZE; 77 | if (mode == AES_ECB) { 78 | ecbencrypt(data,size,0,out); 79 | } else { 80 | aes_encrypt_cbc(data,size,0,(unsigned char *)out.data(),mpass,mbit,msalt); 81 | } 82 | for (int i = 0,j = size; i < last; ++i, ++j) { 83 | out[j] = datablocks[i]; 84 | } 85 | } 86 | break; 87 | } 88 | } 89 | 90 | void QAesWrap::ecbencrypt(const BYTE * in, size_t size, BYTE *blcok, QByteArray & out) const 91 | { 92 | BYTE buf_in[AES_BLOCK_SIZE] = {0}, buf_out[AES_BLOCK_SIZE] = {0}; 93 | int blocks, idx; 94 | char * data = out.data(); 95 | blocks = size / AES_BLOCK_SIZE; 96 | memset(buf_out,0,AES_BLOCK_SIZE); 97 | for (idx = 0; idx < blocks; idx++) { 98 | memcpy(buf_in, &in[idx * AES_BLOCK_SIZE], AES_BLOCK_SIZE); 99 | aes_encrypt(buf_in, buf_out, mpass, mbit); 100 | memcpy(&data[idx * AES_BLOCK_SIZE], buf_out, AES_BLOCK_SIZE); 101 | memset(buf_out,0,AES_BLOCK_SIZE); 102 | } 103 | if (blcok) { 104 | memcpy(buf_in, blcok, AES_BLOCK_SIZE); 105 | aes_encrypt(blcok, buf_out, mpass, mbit); 106 | memcpy(&data[idx * AES_BLOCK_SIZE], buf_out, AES_BLOCK_SIZE); 107 | } 108 | } 109 | 110 | void QAesWrap::ecbdecrypt(const BYTE *in, size_t size, QByteArray & out) const 111 | { 112 | BYTE buf_in[AES_BLOCK_SIZE] = {0}, buf_out[AES_BLOCK_SIZE] = {0}; 113 | int blocks, idx; 114 | char * data = out.data(); 115 | blocks = size / AES_BLOCK_SIZE; 116 | memset(buf_out,0,AES_BLOCK_SIZE); 117 | for (idx = 0; idx < blocks; idx++) { 118 | memcpy(buf_in, &in[idx * AES_BLOCK_SIZE], AES_BLOCK_SIZE); 119 | aes_decrypt(buf_in, buf_out, mpass, mbit); 120 | memcpy(&data[idx * AES_BLOCK_SIZE], buf_out, AES_BLOCK_SIZE); 121 | memset(buf_out,0,AES_BLOCK_SIZE); 122 | } 123 | } 124 | 125 | bool QAesWrap::decrypt(const QByteArray & in, QByteArray & out, AesMode mode,PaddingMode pad) const 126 | { 127 | if (in.isEmpty()) return false; 128 | out.clear(); 129 | int size = in.size(); 130 | out.resize(size); 131 | if (mode == AES_CTR) { 132 | aes_encrypt_ctr((unsigned char *)in.data(),size,(unsigned char *)out.data(),mpass,mbit,msalt); 133 | return true; 134 | } 135 | int last = size % AES_BLOCK_SIZE; 136 | int blocks = size / AES_BLOCK_SIZE; 137 | int useSize = blocks * AES_BLOCK_SIZE; 138 | if (blocks == 0 ) { 139 | out = in; 140 | return false; 141 | } 142 | QByteArray tdata; 143 | if (last > 0) { 144 | if(pad == ANSIX923 || pad == PKCS7) { 145 | out.clear(); 146 | return false; 147 | } 148 | tdata = in.right(last); 149 | } 150 | 151 | 152 | switch (mode) { 153 | case AES_ECB: 154 | ecbdecrypt((unsigned char *)in.data(),useSize,out); 155 | break; 156 | case AES_CBC: 157 | aes_decrypt_cbc((unsigned char *)in.data(),useSize,(unsigned char *)out.data(),mpass,mbit,msalt); 158 | break; 159 | default: 160 | return false; 161 | } 162 | if (last > 0) { 163 | for (int i = useSize, j = 0;i < size; ++i,++j) { 164 | out[i] = tdata.at(j); 165 | } 166 | } else { 167 | char ch = out.at(size-1); 168 | if (ch < 16) { //验证是否需要移除。 169 | int removed = 0; 170 | int tsize = size - ch; 171 | bool isPad = true; 172 | if (pad == ANSIX923) { 173 | int mysize = size - 1; 174 | char tch; 175 | for (int i = tsize; i < mysize; ++i) { 176 | tch = out.at(i); 177 | if (tch != char(0x00)) { 178 | isPad = false; 179 | } 180 | } 181 | if (isPad) removed = ch; 182 | }else { 183 | char tch; 184 | for (int i = tsize; i < size; ++i) { 185 | tch = out.at(i); 186 | if (tch != ch) { 187 | isPad = false; 188 | } 189 | } 190 | if (isPad) removed = ch; 191 | } 192 | if (removed > 0) { 193 | out.remove(size - removed,removed); 194 | } 195 | } 196 | } 197 | 198 | return true; 199 | } 200 | -------------------------------------------------------------------------------- /QAes/qaeswrap.h: -------------------------------------------------------------------------------- 1 | #ifndef QAESWRAP_H 2 | #define QAESWRAP_H 3 | 4 | extern "C" { 5 | #include "aes.h" 6 | } 7 | #include 8 | 9 | 10 | class QAesWrap 11 | { 12 | public: 13 | enum AesBit { 14 | AES_128 = 128, 15 | AES_192 = 192, 16 | AES_256 = 256 17 | }; 18 | enum AesMode { 19 | AES_ECB, 20 | AES_CBC, 21 | AES_CTR 22 | }; 23 | enum PaddingMode { 24 | None, 25 | ANSIX923, 26 | PKCS7 27 | }; 28 | public: 29 | QAesWrap(const QByteArray & passwprd,const QByteArray & salt,AesBit bit); 30 | 31 | bool encrypt(const QByteArray & in, QByteArray & out, AesMode mode,PaddingMode pad = PKCS7) const; 32 | bool decrypt(const QByteArray & in, QByteArray & out, AesMode mode,PaddingMode pad = PKCS7) const; 33 | 34 | inline QByteArray encrypt(const QByteArray & data,AesMode mode,PaddingMode pad = PKCS7) const { 35 | QByteArray out; 36 | encrypt(data,out,mode,pad); 37 | return out; 38 | } 39 | 40 | inline QByteArray decrypt(const QByteArray & data,AesMode mode,PaddingMode pad = PKCS7) const { 41 | QByteArray out; 42 | decrypt(data,out,mode,pad); 43 | return out; 44 | } 45 | private: 46 | void ecbencrypt(const BYTE *in, size_t size, BYTE *blcok, QByteArray & out) const; 47 | void ecbdecrypt(const BYTE *in, size_t size, QByteArray & out) const; 48 | void initPadding(const QByteArray & in,QByteArray & out,AesMode mode,PaddingMode pad) const; 49 | private: 50 | AesBit mbit; 51 | WORD mpass[60]; 52 | BYTE msalt[AES_BLOCK_SIZE]; 53 | }; 54 | 55 | #endif // QAESWRAP_H 56 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # QAes 2 | Qt AES encrypt decrypt
3 | QByteArry直接使用的AES加密解密。 4 | ########################## 5 | ###支持的模式: 6 | ECB,CBC,CTR 7 | ###填充模式: 8 | ANSIX923,PKCS7,None(不填充) 9 | None:模式下,不是16字节的整数倍的多余的部分不加密。不足16个字节的,都不加密。 10 | (CTR模式是流式模式,不需要填充。) 11 | ###密码模式: 12 | 传进去参数支持任意长度: 13 | 密码:传进去密码后进行Sha3_256计算出hash值作为密码。对于AES256则是全部hash值,128和192则是去前面相应的16个和24个字节值。 14 | salt: 传进去的salt进行Sha3_256计算出hash值的前16个字节作为salt。(ecb模式下不用salt值的)。 15 | 16 | -------------------------------------------------------------------------------- /Test/QAestTest.pro: -------------------------------------------------------------------------------- 1 | #------------------------------------------------- 2 | # 3 | # Project created by QtCreator 2015-08-03T09:20:31 4 | # 5 | #------------------------------------------------- 6 | 7 | QT += core 8 | 9 | QT -= gui 10 | 11 | TARGET = QAesTest 12 | CONFIG += console 13 | CONFIG -= app_bundle 14 | 15 | TEMPLATE = app 16 | 17 | include (../QAes/QAes.pri) 18 | 19 | SOURCES += main.cpp 20 | -------------------------------------------------------------------------------- /Test/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "qaeswrap.h" 5 | 6 | int main(int argc, char *argv[]) 7 | { 8 | QCoreApplication a(argc, argv); 9 | 10 | 11 | QByteArray data = "12345678901234567890"; 12 | qDebug() << "Sha3_256 size:" << data.size() << " data:" << data; 13 | 14 | qDebug() << "\naes_ctr" ; 15 | QAesWrap aes("dushibaiyu","dushibaiyu.com",QAesWrap::AES_256); 16 | QByteArray mdata = aes.encrypt(data,QAesWrap::AES_CTR); 17 | qDebug() << "mdata size : " << mdata.size() << " mdata:" << mdata.toHex(); 18 | 19 | aes.decrypt(mdata,data,QAesWrap::AES_CTR); 20 | qDebug() << "data size:" << data.size() << " data:" << data; 21 | 22 | qDebug() << "\n\naes_ecb None:" ; 23 | 24 | aes.encrypt(data,mdata,QAesWrap::AES_ECB,QAesWrap::None); 25 | qDebug() << "mdata size : " << mdata.size() << " mdata:" << mdata.toHex(); 26 | 27 | aes.decrypt(mdata,data,QAesWrap::AES_ECB,QAesWrap::None); 28 | qDebug() << "data size:" << data.size() << " data:" << data; 29 | 30 | 31 | qDebug() << "\n\naes_cbc None:" ; 32 | 33 | aes.encrypt(data,mdata,QAesWrap::AES_CBC,QAesWrap::None); 34 | qDebug() << "mdata size : " << mdata.size() << " mdata:" << mdata.toHex(); 35 | 36 | aes.decrypt(mdata,data,QAesWrap::AES_CBC,QAesWrap::None); 37 | qDebug() << "data size:" << data.size() << " data:" << data; 38 | 39 | 40 | qDebug() << "\n\naes_ecb PKCS7:" ; 41 | 42 | aes.encrypt(data,mdata,QAesWrap::AES_ECB,QAesWrap::PKCS7); 43 | qDebug() << "mdata size : " << mdata.size() << " mdata:" << mdata.toHex(); 44 | 45 | aes.decrypt(mdata,data,QAesWrap::AES_ECB,QAesWrap::PKCS7); 46 | qDebug() << "data size:" << data.size() << " data:" << data; 47 | 48 | 49 | qDebug() << "\n\naes_cbc PKCS7:" ; 50 | 51 | aes.encrypt(data,mdata,QAesWrap::AES_CBC,QAesWrap::PKCS7); 52 | qDebug() << "mdata size : " << mdata.size() << " mdata:" << mdata.toHex(); 53 | 54 | aes.decrypt(mdata,data,QAesWrap::AES_CBC,QAesWrap::PKCS7); 55 | qDebug() << "data size:" << data.size() << " data:" << data; 56 | 57 | qDebug() << "\n\naes_ecb ANSIX923:" ; 58 | 59 | aes.encrypt(data,mdata,QAesWrap::AES_ECB,QAesWrap::ANSIX923); 60 | qDebug() << "mdata size : " << mdata.size() << " mdata:" << mdata.toHex(); 61 | 62 | aes.decrypt(mdata,data,QAesWrap::AES_ECB,QAesWrap::ANSIX923); 63 | qDebug() << "data size:" << data.size() << " data:" << data; 64 | 65 | 66 | qDebug() << "\n\naes_cbc ANSIX923:" ; 67 | 68 | aes.encrypt(data,mdata,QAesWrap::AES_CBC,QAesWrap::ANSIX923); 69 | qDebug() << "mdata size : " << mdata.size() << " mdata:" << mdata.toHex(); 70 | 71 | aes.decrypt(mdata,data,QAesWrap::AES_CBC,QAesWrap::ANSIX923); 72 | qDebug() << "data size:" << data.size() << " data:" << data; 73 | 74 | return a.exec(); 75 | } 76 | --------------------------------------------------------------------------------