| 1 | /*********************************************************************\r |
| 2 | * Filename: aes_test.c\r |
| 3 | * Author: Brad Conte (brad AT bradconte.com)\r |
| 4 | * Copyright:\r |
| 5 | * Disclaimer: This code is presented "as is" without any guarantees.\r |
| 6 | * Details: Performs known-answer tests on the corresponding AES\r |
| 7 | implementation. These tests do not encompass the full\r |
| 8 | range of available test vectors and are not sufficient\r |
| 9 | for FIPS-140 certification. However, if the tests pass\r |
| 10 | it is very, very likely that the code is correct and was\r |
| 11 | compiled properly. This code also serves as\r |
| 12 | example usage of the functions.\r |
| 13 | *********************************************************************/\r |
| 14 | \r |
| 15 | /*************************** HEADER FILES ***************************/\r |
| 16 | #include <stdio.h>\r |
| 17 | #include <memory.h>\r |
| 18 | #include "aes.h"\r |
| 19 | \r |
| 20 | /*********************** FUNCTION DEFINITIONS ***********************/\r |
| 21 | void print_hex(BYTE str[], int len)\r |
| 22 | {\r |
| 23 | int idx;\r |
| 24 | \r |
| 25 | for(idx = 0; idx < len; idx++)\r |
| 26 | printf("%02x", str[idx]);\r |
| 27 | }\r |
| 28 | \r |
| 29 | int aes_ecb_test()\r |
| 30 | {\r |
| 31 | WORD key_schedule[60], idx;\r |
| 32 | BYTE enc_buf[128];\r |
| 33 | BYTE plaintext[2][16] = {\r |
| 34 | {0x6b,0xc1,0xbe,0xe2,0x2e,0x40,0x9f,0x96,0xe9,0x3d,0x7e,0x11,0x73,0x93,0x17,0x2a},\r |
| 35 | {0xae,0x2d,0x8a,0x57,0x1e,0x03,0xac,0x9c,0x9e,0xb7,0x6f,0xac,0x45,0xaf,0x8e,0x51}\r |
| 36 | };\r |
| 37 | BYTE ciphertext[2][16] = {\r |
| 38 | {0xf3,0xee,0xd1,0xbd,0xb5,0xd2,0xa0,0x3c,0x06,0x4b,0x5a,0x7e,0x3d,0xb1,0x81,0xf8},\r |
| 39 | {0x59,0x1c,0xcb,0x10,0xd4,0x10,0xed,0x26,0xdc,0x5b,0xa7,0x4a,0x31,0x36,0x28,0x70}\r |
| 40 | };\r |
| 41 | BYTE key[1][32] = {\r |
| 42 | {0x60,0x3d,0xeb,0x10,0x15,0xca,0x71,0xbe,0x2b,0x73,0xae,0xf0,0x85,0x7d,0x77,0x81,0x1f,0x35,0x2c,0x07,0x3b,0x61,0x08,0xd7,0x2d,0x98,0x10,0xa3,0x09,0x14,0xdf,0xf4}\r |
| 43 | };\r |
| 44 | int pass = 1;\r |
| 45 | \r |
| 46 | // Raw ECB mode.\r |
| 47 | //printf("* ECB mode:\n");\r |
| 48 | aes_key_setup(key[0], key_schedule, 256);\r |
| 49 | //printf( "Key : ");\r |
| 50 | //print_hex(key[0], 32);\r |
| 51 | \r |
| 52 | for(idx = 0; idx < 2; idx++) {\r |
| 53 | aes_encrypt(plaintext[idx], enc_buf, key_schedule, 256);\r |
| 54 | //printf("\nPlaintext : ");\r |
| 55 | //print_hex(plaintext[idx], 16);\r |
| 56 | //printf("\n-encrypted to: ");\r |
| 57 | //print_hex(enc_buf, 16);\r |
| 58 | pass = pass && !memcmp(enc_buf, ciphertext[idx], 16);\r |
| 59 | \r |
| 60 | aes_decrypt(ciphertext[idx], enc_buf, key_schedule, 256);\r |
| 61 | //printf("\nCiphertext : ");\r |
| 62 | //print_hex(ciphertext[idx], 16);\r |
| 63 | //printf("\n-decrypted to: ");\r |
| 64 | //print_hex(enc_buf, 16);\r |
| 65 | pass = pass && !memcmp(enc_buf, plaintext[idx], 16);\r |
| 66 | \r |
| 67 | //printf("\n\n");\r |
| 68 | }\r |
| 69 | \r |
| 70 | return(pass);\r |
| 71 | }\r |
| 72 | \r |
| 73 | int aes_cbc_test()\r |
| 74 | {\r |
| 75 | WORD key_schedule[60];\r |
| 76 | BYTE enc_buf[128];\r |
| 77 | BYTE plaintext[1][32] = {\r |
| 78 | {0x6b,0xc1,0xbe,0xe2,0x2e,0x40,0x9f,0x96,0xe9,0x3d,0x7e,0x11,0x73,0x93,0x17,0x2a,0xae,0x2d,0x8a,0x57,0x1e,0x03,0xac,0x9c,0x9e,0xb7,0x6f,0xac,0x45,0xaf,0x8e,0x51}\r |
| 79 | };\r |
| 80 | BYTE ciphertext[1][32] = {\r |
| 81 | {0xf5,0x8c,0x4c,0x04,0xd6,0xe5,0xf1,0xba,0x77,0x9e,0xab,0xfb,0x5f,0x7b,0xfb,0xd6,0x9c,0xfc,0x4e,0x96,0x7e,0xdb,0x80,0x8d,0x67,0x9f,0x77,0x7b,0xc6,0x70,0x2c,0x7d}\r |
| 82 | };\r |
| 83 | BYTE iv[1][16] = {\r |
| 84 | {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f}\r |
| 85 | };\r |
| 86 | BYTE key[1][32] = {\r |
| 87 | {0x60,0x3d,0xeb,0x10,0x15,0xca,0x71,0xbe,0x2b,0x73,0xae,0xf0,0x85,0x7d,0x77,0x81,0x1f,0x35,0x2c,0x07,0x3b,0x61,0x08,0xd7,0x2d,0x98,0x10,0xa3,0x09,0x14,0xdf,0xf4}\r |
| 88 | };\r |
| 89 | int pass = 1;\r |
| 90 | \r |
| 91 | //printf("* CBC mode:\n");\r |
| 92 | aes_key_setup(key[0], key_schedule, 256);\r |
| 93 | \r |
| 94 | //printf( "Key : ");\r |
| 95 | //print_hex(key[0], 32);\r |
| 96 | //printf("\nIV : ");\r |
| 97 | //print_hex(iv[0], 16);\r |
| 98 | \r |
| 99 | aes_encrypt_cbc(plaintext[0], 32, enc_buf, key_schedule, 256, iv[0]);\r |
| 100 | //printf("\nPlaintext : ");\r |
| 101 | //print_hex(plaintext[0], 32);\r |
| 102 | //printf("\n-encrypted to: ");\r |
| 103 | //print_hex(enc_buf, 32);\r |
| 104 | //printf("\nCiphertext : ");\r |
| 105 | //print_hex(ciphertext[0], 32);\r |
| 106 | pass = pass && !memcmp(enc_buf, ciphertext[0], 32);\r |
| 107 | \r |
| 108 | aes_decrypt_cbc(ciphertext[0], 32, enc_buf, key_schedule, 256, iv[0]);\r |
| 109 | //printf("\nCiphertext : ");\r |
| 110 | //print_hex(ciphertext[0], 32);\r |
| 111 | //printf("\n-decrypted to: ");\r |
| 112 | //print_hex(enc_buf, 32);\r |
| 113 | //printf("\nPlaintext : ");\r |
| 114 | //print_hex(plaintext[0], 32);\r |
| 115 | pass = pass && !memcmp(enc_buf, plaintext[0], 32);\r |
| 116 | \r |
| 117 | //printf("\n\n");\r |
| 118 | return(pass);\r |
| 119 | }\r |
| 120 | \r |
| 121 | int aes_ctr_test()\r |
| 122 | {\r |
| 123 | WORD key_schedule[60];\r |
| 124 | BYTE enc_buf[128];\r |
| 125 | BYTE plaintext[1][32] = {\r |
| 126 | {0x6b,0xc1,0xbe,0xe2,0x2e,0x40,0x9f,0x96,0xe9,0x3d,0x7e,0x11,0x73,0x93,0x17,0x2a,0xae,0x2d,0x8a,0x57,0x1e,0x03,0xac,0x9c,0x9e,0xb7,0x6f,0xac,0x45,0xaf,0x8e,0x51}\r |
| 127 | };\r |
| 128 | BYTE ciphertext[1][32] = {\r |
| 129 | {0x60,0x1e,0xc3,0x13,0x77,0x57,0x89,0xa5,0xb7,0xa7,0xf5,0x04,0xbb,0xf3,0xd2,0x28,0xf4,0x43,0xe3,0xca,0x4d,0x62,0xb5,0x9a,0xca,0x84,0xe9,0x90,0xca,0xca,0xf5,0xc5}\r |
| 130 | };\r |
| 131 | BYTE iv[1][16] = {\r |
| 132 | {0xf0,0xf1,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7,0xf8,0xf9,0xfa,0xfb,0xfc,0xfd,0xfe,0xff},\r |
| 133 | };\r |
| 134 | BYTE key[1][32] = {\r |
| 135 | {0x60,0x3d,0xeb,0x10,0x15,0xca,0x71,0xbe,0x2b,0x73,0xae,0xf0,0x85,0x7d,0x77,0x81,0x1f,0x35,0x2c,0x07,0x3b,0x61,0x08,0xd7,0x2d,0x98,0x10,0xa3,0x09,0x14,0xdf,0xf4}\r |
| 136 | };\r |
| 137 | int pass = 1;\r |
| 138 | \r |
| 139 | //printf("* CTR mode:\n");\r |
| 140 | aes_key_setup(key[0], key_schedule, 256);\r |
| 141 | \r |
| 142 | //printf( "Key : ");\r |
| 143 | //print_hex(key[0], 32);\r |
| 144 | //printf("\nIV : ");\r |
| 145 | //print_hex(iv[0], 16);\r |
| 146 | \r |
| 147 | aes_encrypt_ctr(plaintext[0], 32, enc_buf, key_schedule, 256, iv[0]);\r |
| 148 | //printf("\nPlaintext : ");\r |
| 149 | //print_hex(plaintext[0], 32);\r |
| 150 | //printf("\n-encrypted to: ");\r |
| 151 | //print_hex(enc_buf, 32);\r |
| 152 | pass = pass && !memcmp(enc_buf, ciphertext[0], 32);\r |
| 153 | \r |
| 154 | aes_decrypt_ctr(ciphertext[0], 32, enc_buf, key_schedule, 256, iv[0]);\r |
| 155 | //printf("\nCiphertext : ");\r |
| 156 | //print_hex(ciphertext[0], 32);\r |
| 157 | //printf("\n-decrypted to: ");\r |
| 158 | //print_hex(enc_buf, 32);\r |
| 159 | pass = pass && !memcmp(enc_buf, plaintext[0], 32);\r |
| 160 | \r |
| 161 | //printf("\n\n");\r |
| 162 | return(pass);\r |
| 163 | }\r |
| 164 | \r |
| 165 | int aes_ccm_test()\r |
| 166 | {\r |
| 167 | int mac_auth;\r |
| 168 | WORD enc_buf_len;\r |
| 169 | BYTE enc_buf[128];\r |
| 170 | BYTE plaintext[3][32] = {\r |
| 171 | {0x20,0x21,0x22,0x23},\r |
| 172 | {0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f},\r |
| 173 | {0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37}\r |
| 174 | };\r |
| 175 | BYTE assoc[3][32] = {\r |
| 176 | {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07},\r |
| 177 | {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f},\r |
| 178 | {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13}\r |
| 179 | };\r |
| 180 | BYTE ciphertext[3][32 + 16] = {\r |
| 181 | {0x71,0x62,0x01,0x5b,0x4d,0xac,0x25,0x5d},\r |
| 182 | {0xd2,0xa1,0xf0,0xe0,0x51,0xea,0x5f,0x62,0x08,0x1a,0x77,0x92,0x07,0x3d,0x59,0x3d,0x1f,0xc6,0x4f,0xbf,0xac,0xcd},\r |
| 183 | {0xe3,0xb2,0x01,0xa9,0xf5,0xb7,0x1a,0x7a,0x9b,0x1c,0xea,0xec,0xcd,0x97,0xe7,0x0b,0x61,0x76,0xaa,0xd9,0xa4,0x42,0x8a,0xa5,0x48,0x43,0x92,0xfb,0xc1,0xb0,0x99,0x51}\r |
| 184 | };\r |
| 185 | BYTE iv[3][16] = {\r |
| 186 | {0x10,0x11,0x12,0x13,0x14,0x15,0x16},\r |
| 187 | {0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17},\r |
| 188 | {0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b}\r |
| 189 | };\r |
| 190 | BYTE key[1][32] = {\r |
| 191 | {0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f}\r |
| 192 | };\r |
| 193 | int pass = 1;\r |
| 194 | \r |
| 195 | //printf("* CCM mode:\n");\r |
| 196 | //printf("Key : ");\r |
| 197 | //print_hex(key[0], 16);\r |
| 198 | \r |
| 199 | //print_hex(plaintext[0], 4);\r |
| 200 | //print_hex(assoc[0], 8);\r |
| 201 | //print_hex(ciphertext[0], 8);\r |
| 202 | //print_hex(iv[0], 7);\r |
| 203 | //print_hex(key[0], 16);\r |
| 204 | \r |
| 205 | aes_encrypt_ccm(plaintext[0], 4, assoc[0], 8, iv[0], 7, enc_buf, &enc_buf_len, 4, key[0], 128);\r |
| 206 | //printf("\nNONCE : ");\r |
| 207 | //print_hex(iv[0], 7);\r |
| 208 | //printf("\nAssoc. Data : ");\r |
| 209 | //print_hex(assoc[0], 8);\r |
| 210 | //printf("\nPayload : ");\r |
| 211 | //print_hex(plaintext[0], 4);\r |
| 212 | //printf("\n-encrypted to: ");\r |
| 213 | //print_hex(enc_buf, enc_buf_len);\r |
| 214 | pass = pass && !memcmp(enc_buf, ciphertext[0], enc_buf_len);\r |
| 215 | \r |
| 216 | aes_decrypt_ccm(ciphertext[0], 8, assoc[0], 8, iv[0], 7, enc_buf, &enc_buf_len, 4, &mac_auth, key[0], 128);\r |
| 217 | //printf("\n-Ciphertext : ");\r |
| 218 | //print_hex(ciphertext[0], 8);\r |
| 219 | //printf("\n-decrypted to: ");\r |
| 220 | //print_hex(enc_buf, enc_buf_len);\r |
| 221 | //printf("\nAuthenticated: %d ", mac_auth);\r |
| 222 | pass = pass && !memcmp(enc_buf, plaintext[0], enc_buf_len) && mac_auth;\r |
| 223 | \r |
| 224 | \r |
| 225 | aes_encrypt_ccm(plaintext[1], 16, assoc[1], 16, iv[1], 8, enc_buf, &enc_buf_len, 6, key[0], 128);\r |
| 226 | //printf("\n\nNONCE : ");\r |
| 227 | //print_hex(iv[1], 8);\r |
| 228 | //printf("\nAssoc. Data : ");\r |
| 229 | //print_hex(assoc[1], 16);\r |
| 230 | //printf("\nPayload : ");\r |
| 231 | //print_hex(plaintext[1], 16);\r |
| 232 | //printf("\n-encrypted to: ");\r |
| 233 | //print_hex(enc_buf, enc_buf_len);\r |
| 234 | pass = pass && !memcmp(enc_buf, ciphertext[1], enc_buf_len);\r |
| 235 | \r |
| 236 | aes_decrypt_ccm(ciphertext[1], 22, assoc[1], 16, iv[1], 8, enc_buf, &enc_buf_len, 6, &mac_auth, key[0], 128);\r |
| 237 | //printf("\n-Ciphertext : ");\r |
| 238 | //print_hex(ciphertext[1], 22);\r |
| 239 | //printf("\n-decrypted to: ");\r |
| 240 | //print_hex(enc_buf, enc_buf_len);\r |
| 241 | //printf("\nAuthenticated: %d ", mac_auth);\r |
| 242 | pass = pass && !memcmp(enc_buf, plaintext[1], enc_buf_len) && mac_auth;\r |
| 243 | \r |
| 244 | \r |
| 245 | aes_encrypt_ccm(plaintext[2], 24, assoc[2], 20, iv[2], 12, enc_buf, &enc_buf_len, 8, key[0], 128);\r |
| 246 | //printf("\n\nNONCE : ");\r |
| 247 | //print_hex(iv[2], 12);\r |
| 248 | //printf("\nAssoc. Data : ");\r |
| 249 | //print_hex(assoc[2], 20);\r |
| 250 | //printf("\nPayload : ");\r |
| 251 | //print_hex(plaintext[2], 24);\r |
| 252 | //printf("\n-encrypted to: ");\r |
| 253 | //print_hex(enc_buf, enc_buf_len);\r |
| 254 | pass = pass && !memcmp(enc_buf, ciphertext[2], enc_buf_len);\r |
| 255 | \r |
| 256 | aes_decrypt_ccm(ciphertext[2], 32, assoc[2], 20, iv[2], 12, enc_buf, &enc_buf_len, 8, &mac_auth, key[0], 128);\r |
| 257 | //printf("\n-Ciphertext : ");\r |
| 258 | //print_hex(ciphertext[2], 32);\r |
| 259 | //printf("\n-decrypted to: ");\r |
| 260 | //print_hex(enc_buf, enc_buf_len);\r |
| 261 | //printf("\nAuthenticated: %d ", mac_auth);\r |
| 262 | pass = pass && !memcmp(enc_buf, plaintext[2], enc_buf_len) && mac_auth;\r |
| 263 | \r |
| 264 | //printf("\n\n");\r |
| 265 | return(pass);\r |
| 266 | }\r |
| 267 | \r |
| 268 | int aes_test()\r |
| 269 | {\r |
| 270 | int pass = 1;\r |
| 271 | \r |
| 272 | pass = pass && aes_ecb_test();\r |
| 273 | pass = pass && aes_cbc_test();\r |
| 274 | pass = pass && aes_ctr_test();\r |
| 275 | pass = pass && aes_ccm_test();\r |
| 276 | \r |
| 277 | return(pass);\r |
| 278 | }\r |
| 279 | \r |
| 280 | int main(int argc, char *argv[])\r |
| 281 | {\r |
| 282 | printf("AES Tests: %s\n", aes_test() ? "SUCCEEDED" : "FAILED");\r |
| 283 | \r |
| 284 | return(0);\r |
| 285 | }\r |