1/* ==================================================================== 2 * Copyright (c) 2008 The OpenSSL Project. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in 13 * the documentation and/or other materials provided with the 14 * distribution. 15 * 16 * 3. All advertising materials mentioning features or use of this 17 * software must display the following acknowledgment: 18 * "This product includes software developed by the OpenSSL Project 19 * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" 20 * 21 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 22 * endorse or promote products derived from this software without 23 * prior written permission. For written permission, please contact 24 * openssl-core@openssl.org. 25 * 26 * 5. Products derived from this software may not be called "OpenSSL" 27 * nor may "OpenSSL" appear in their names without prior written 28 * permission of the OpenSSL Project. 29 * 30 * 6. Redistributions of any form whatsoever must retain the following 31 * acknowledgment: 32 * "This product includes software developed by the OpenSSL Project 33 * for use in the OpenSSL Toolkit (http://www.openssl.org/)" 34 * 35 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 36 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 37 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 38 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 39 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 40 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 41 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 42 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 43 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 44 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 45 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 46 * OF THE POSSIBILITY OF SUCH DAMAGE. 47 * ==================================================================== */ 48 49#include <stdio.h> 50#include <string.h> 51 52#include <openssl/aes.h> 53#include <openssl/crypto.h> 54#include <openssl/mem.h> 55 56#include "internal.h" 57#include "../test/test_util.h" 58 59 60struct test_case { 61 const char *key; 62 const char *plaintext; 63 const char *additional_data; 64 const char *nonce; 65 const char *ciphertext; 66 const char *tag; 67}; 68 69static const struct test_case test_cases[] = { 70 { 71 "00000000000000000000000000000000", 72 NULL, 73 NULL, 74 "000000000000000000000000", 75 NULL, 76 "58e2fccefa7e3061367f1d57a4e7455a", 77 }, 78 { 79 "00000000000000000000000000000000", 80 "00000000000000000000000000000000", 81 NULL, 82 "000000000000000000000000", 83 "0388dace60b6a392f328c2b971b2fe78", 84 "ab6e47d42cec13bdf53a67b21257bddf", 85 }, 86 { 87 "feffe9928665731c6d6a8f9467308308", 88 "d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b391aafd255", 89 NULL, 90 "cafebabefacedbaddecaf888", 91 "42831ec2217774244b7221b784d0d49ce3aa212f2c02a4e035c17e2329aca12e21d514b25466931c7d8f6a5aac84aa051ba30b396a0aac973d58e091473f5985", 92 "4d5c2af327cd64a62cf35abd2ba6fab4", 93 }, 94 { 95 "feffe9928665731c6d6a8f9467308308", 96 "d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39", 97 "feedfacedeadbeeffeedfacedeadbeefabaddad2", 98 "cafebabefacedbaddecaf888", 99 "42831ec2217774244b7221b784d0d49ce3aa212f2c02a4e035c17e2329aca12e21d514b25466931c7d8f6a5aac84aa051ba30b396a0aac973d58e091", 100 "5bc94fbc3221a5db94fae95ae7121a47", 101 }, 102 { 103 "feffe9928665731c6d6a8f9467308308", 104 "d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39", 105 "feedfacedeadbeeffeedfacedeadbeefabaddad2", 106 "cafebabefacedbad", 107 "61353b4c2806934a777ff51fa22a4755699b2a714fcdc6f83766e5f97b6c742373806900e49f24b22b097544d4896b424989b5e1ebac0f07c23f4598", 108 "3612d2e79e3b0785561be14aaca2fccb", 109 }, 110 { 111 "feffe9928665731c6d6a8f9467308308", 112 "d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39", 113 "feedfacedeadbeeffeedfacedeadbeefabaddad2", 114 "9313225df88406e555909c5aff5269aa6a7a9538534f7da1e4c303d2a318a728c3c0c95156809539fcf0e2429a6b525416aedbf5a0de6a57a637b39b", 115 "8ce24998625615b603a033aca13fb894be9112a5c3a211a8ba262a3cca7e2ca701e4a9a4fba43c90ccdcb281d48c7c6fd62875d2aca417034c34aee5", 116 "619cc5aefffe0bfa462af43c1699d050", 117 }, 118 { 119 "000000000000000000000000000000000000000000000000", 120 NULL, 121 NULL, 122 "000000000000000000000000", 123 NULL, 124 "cd33b28ac773f74ba00ed1f312572435", 125 }, 126 { 127 "000000000000000000000000000000000000000000000000", 128 "00000000000000000000000000000000", 129 NULL, 130 "000000000000000000000000", 131 "98e7247c07f0fe411c267e4384b0f600", 132 "2ff58d80033927ab8ef4d4587514f0fb", 133 }, 134 { 135 "feffe9928665731c6d6a8f9467308308feffe9928665731c", 136 "d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b391aafd255", 137 NULL, 138 "cafebabefacedbaddecaf888", 139 "3980ca0b3c00e841eb06fac4872a2757859e1ceaa6efd984628593b40ca1e19c7d773d00c144c525ac619d18c84a3f4718e2448b2fe324d9ccda2710acade256", 140 "9924a7c8587336bfb118024db8674a14", 141 }, 142 { 143 "feffe9928665731c6d6a8f9467308308feffe9928665731c", 144 "d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39", 145 "feedfacedeadbeeffeedfacedeadbeefabaddad2", 146 "cafebabefacedbaddecaf888", 147 "3980ca0b3c00e841eb06fac4872a2757859e1ceaa6efd984628593b40ca1e19c7d773d00c144c525ac619d18c84a3f4718e2448b2fe324d9ccda2710", 148 "2519498e80f1478f37ba55bd6d27618c", 149 }, 150 { 151 "feffe9928665731c6d6a8f9467308308feffe9928665731c", 152 "d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39", 153 "feedfacedeadbeeffeedfacedeadbeefabaddad2", 154 "cafebabefacedbad", 155 "0f10f599ae14a154ed24b36e25324db8c566632ef2bbb34f8347280fc4507057fddc29df9a471f75c66541d4d4dad1c9e93a19a58e8b473fa0f062f7", 156 "65dcc57fcf623a24094fcca40d3533f8", 157 }, 158 { 159 "feffe9928665731c6d6a8f9467308308feffe9928665731c", 160 "d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39", 161 "feedfacedeadbeeffeedfacedeadbeefabaddad2", 162 "cafebabefacedbad", 163 "0f10f599ae14a154ed24b36e25324db8c566632ef2bbb34f8347280fc4507057fddc29df9a471f75c66541d4d4dad1c9e93a19a58e8b473fa0f062f7", 164 "65dcc57fcf623a24094fcca40d3533f8", 165 }, 166 { 167 "feffe9928665731c6d6a8f9467308308feffe9928665731c", 168 "d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39", 169 "feedfacedeadbeeffeedfacedeadbeefabaddad2", 170 "9313225df88406e555909c5aff5269aa6a7a9538534f7da1e4c303d2a318a728c3c0c95156809539fcf0e2429a6b525416aedbf5a0de6a57a637b39b", 171 "d27e88681ce3243c4830165a8fdcf9ff1de9a1d8e6b447ef6ef7b79828666e4581e79012af34ddd9e2f037589b292db3e67c036745fa22e7e9b7373b", 172 "dcf566ff291c25bbb8568fc3d376a6d9", 173 }, 174 { 175 "0000000000000000000000000000000000000000000000000000000000000000", 176 NULL, 177 NULL, 178 "000000000000000000000000", 179 NULL, 180 "530f8afbc74536b9a963b4f1c4cb738b", 181 }, 182 { 183 "0000000000000000000000000000000000000000000000000000000000000000", 184 "00000000000000000000000000000000", 185 NULL, 186 "000000000000000000000000", 187 "cea7403d4d606b6e074ec5d3baf39d18", 188 "d0d1c8a799996bf0265b98b5d48ab919", 189 }, 190 { 191 "feffe9928665731c6d6a8f9467308308feffe9928665731c6d6a8f9467308308", 192 "d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b391aafd255", 193 NULL, 194 "cafebabefacedbaddecaf888", 195 "522dc1f099567d07f47f37a32a84427d643a8cdcbfe5c0c97598a2bd2555d1aa8cb08e48590dbb3da7b08b1056828838c5f61e6393ba7a0abcc9f662898015ad", 196 "b094dac5d93471bdec1a502270e3cc6c", 197 }, 198 { 199 "feffe9928665731c6d6a8f9467308308feffe9928665731c6d6a8f9467308308", 200 "d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39", 201 "feedfacedeadbeeffeedfacedeadbeefabaddad2", 202 "cafebabefacedbaddecaf888", 203 "522dc1f099567d07f47f37a32a84427d643a8cdcbfe5c0c97598a2bd2555d1aa8cb08e48590dbb3da7b08b1056828838c5f61e6393ba7a0abcc9f662", 204 "76fc6ece0f4e1768cddf8853bb2d551b", 205 }, 206 { 207 "feffe9928665731c6d6a8f9467308308feffe9928665731c6d6a8f9467308308", 208 "d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39", 209 "feedfacedeadbeeffeedfacedeadbeefabaddad2", 210 "cafebabefacedbad", 211 "c3762df1ca787d32ae47c13bf19844cbaf1ae14d0b976afac52ff7d79bba9de0feb582d33934a4f0954cc2363bc73f7862ac430e64abe499f47c9b1f", 212 "3a337dbf46a792c45e454913fe2ea8f2", 213 }, 214 { 215 "feffe9928665731c6d6a8f9467308308feffe9928665731c6d6a8f9467308308", 216 "d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39", 217 "feedfacedeadbeeffeedfacedeadbeefabaddad2", 218 "9313225df88406e555909c5aff5269aa6a7a9538534f7da1e4c303d2a318a728c3c0c95156809539fcf0e2429a6b525416aedbf5a0de6a57a637b39b", 219 "5a8def2f0c9e53f1f75d7853659e2a20eeb2b22aafde6419a058ab4f6f746bf40fc0c3b780f244452da3ebf1c5d82cdea2418997200ef82e44ae7e3f", 220 "a44a8266ee1c8eb0c8b5d4cf5ae9f19a", 221 }, 222 { 223 "00000000000000000000000000000000", 224 NULL, 225 "d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b391aafd255522dc1f099567d07f47f37a32a84427d643a8cdcbfe5c0c97598a2bd2555d1aa8cb08e48590dbb3da7b08b1056828838c5f61e6393ba7a0abcc9f662898015ad", 226 "000000000000000000000000", 227 NULL, 228 "5fea793a2d6f974d37e68e0cb8ff9492", 229 }, 230 { 231 "00000000000000000000000000000000", 232 "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", 233 NULL, 234 /* This nonce results in 0xfff in counter LSB. */ 235 "ffffffff000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", 236 "56b3373ca9ef6e4a2b64fe1e9a17b61425f10d47a75a5fce13efc6bc784af24f4141bdd48cf7c770887afd573cca5418a9aeffcd7c5ceddfc6a78397b9a85b499da558257267caab2ad0b23ca476a53cb17fb41c4b8b475cb4f3f7165094c229c9e8c4dc0a2a5ff1903e501511221376a1cdb8364c5061a20cae74bc4acd76ceb0abc9fd3217ef9f8c90be402ddf6d8697f4f880dff15bfb7a6b28241ec8fe183c2d59e3f9dfff653c7126f0acb9e64211f42bae12af462b1070bef1ab5e3606872ca10dee15b3249b1a1b958f23134c4bccb7d03200bce420a2f8eb66dcf3644d1423c1b5699003c13ecef4bf38a3b60eedc34033bac1902783dc6d89e2e774188a439c7ebcc0672dbda4ddcfb2794613b0be41315ef778708a70ee7d75165c", 237 "8b307f6b33286d0ab026a9ed3fe1e85f", 238 }, 239}; 240 241static int from_hex(uint8_t *out, char in) { 242 if (in >= '0' && in <= '9') { 243 *out = in - '0'; 244 return 1; 245 } 246 if (in >= 'a' && in <= 'f') { 247 *out = in - 'a' + 10; 248 return 1; 249 } 250 if (in >= 'A' && in <= 'F') { 251 *out = in - 'A' + 10; 252 return 1; 253 } 254 255 return 0; 256} 257 258static int decode_hex(uint8_t **out, size_t *out_len, const char *in, 259 unsigned test_num, const char *description) { 260 uint8_t *buf = NULL; 261 size_t i; 262 263 if (in == NULL) { 264 *out = NULL; 265 *out_len = 0; 266 return 1; 267 } 268 269 size_t len = strlen(in); 270 if (len & 1) { 271 fprintf(stderr, "%u: Odd-length %s input.\n", test_num, description); 272 goto err; 273 } 274 275 buf = OPENSSL_malloc(len / 2); 276 if (buf == NULL) { 277 fprintf(stderr, "%u: malloc failure.\n", test_num); 278 goto err; 279 } 280 281 for (i = 0; i < len; i += 2) { 282 uint8_t v, v2; 283 if (!from_hex(&v, in[i]) || 284 !from_hex(&v2, in[i+1])) { 285 fprintf(stderr, "%u: invalid hex digit in %s around offset %u.\n", 286 test_num, description, (unsigned)i); 287 goto err; 288 } 289 buf[i/2] = (v << 4) | v2; 290 } 291 292 *out = buf; 293 *out_len = len/2; 294 return 1; 295 296err: 297 OPENSSL_free(buf); 298 return 0; 299} 300 301static int run_test_case(unsigned test_num, const struct test_case *test) { 302 size_t key_len, plaintext_len, additional_data_len, nonce_len, ciphertext_len, 303 tag_len; 304 uint8_t *key = NULL, *plaintext = NULL, *additional_data = NULL, 305 *nonce = NULL, *ciphertext = NULL, *tag = NULL, *out = NULL; 306 int ret = 0; 307 AES_KEY aes_key; 308 GCM128_CONTEXT ctx; 309 310 if (!decode_hex(&key, &key_len, test->key, test_num, "key") || 311 !decode_hex(&plaintext, &plaintext_len, test->plaintext, test_num, 312 "plaintext") || 313 !decode_hex(&additional_data, &additional_data_len, test->additional_data, 314 test_num, "additional_data") || 315 !decode_hex(&nonce, &nonce_len, test->nonce, test_num, "nonce") || 316 !decode_hex(&ciphertext, &ciphertext_len, test->ciphertext, test_num, 317 "ciphertext") || 318 !decode_hex(&tag, &tag_len, test->tag, test_num, "tag")) { 319 goto out; 320 } 321 322 if (plaintext_len != ciphertext_len) { 323 fprintf(stderr, "%u: plaintext and ciphertext have differing lengths.\n", 324 test_num); 325 goto out; 326 } 327 328 if (key_len != 16 && key_len != 24 && key_len != 32) { 329 fprintf(stderr, "%u: bad key length.\n", test_num); 330 goto out; 331 } 332 333 if (tag_len != 16) { 334 fprintf(stderr, "%u: bad tag length.\n", test_num); 335 goto out; 336 } 337 338 out = OPENSSL_malloc(plaintext_len); 339 if (out == NULL) { 340 goto out; 341 } 342 if (AES_set_encrypt_key(key, key_len*8, &aes_key)) { 343 fprintf(stderr, "%u: AES_set_encrypt_key failed.\n", test_num); 344 goto out; 345 } 346 347 CRYPTO_gcm128_init(&ctx, &aes_key, (block128_f) AES_encrypt); 348 CRYPTO_gcm128_setiv(&ctx, &aes_key, nonce, nonce_len); 349 memset(out, 0, plaintext_len); 350 if (additional_data) { 351 CRYPTO_gcm128_aad(&ctx, additional_data, additional_data_len); 352 } 353 if (plaintext) { 354 CRYPTO_gcm128_encrypt(&ctx, &aes_key, plaintext, out, plaintext_len); 355 } 356 if (!CRYPTO_gcm128_finish(&ctx, tag, tag_len) || 357 (ciphertext && memcmp(out, ciphertext, plaintext_len) != 0)) { 358 fprintf(stderr, "%u: encrypt failed.\n", test_num); 359 hexdump(stderr, "got :", out, plaintext_len); 360 hexdump(stderr, "want:", ciphertext, plaintext_len); 361 goto out; 362 } 363 364 CRYPTO_gcm128_setiv(&ctx, &aes_key, nonce, nonce_len); 365 memset(out, 0, plaintext_len); 366 if (additional_data) { 367 CRYPTO_gcm128_aad(&ctx, additional_data, additional_data_len); 368 } 369 if (ciphertext) { 370 CRYPTO_gcm128_decrypt(&ctx, &aes_key, ciphertext, out, plaintext_len); 371 } 372 if (!CRYPTO_gcm128_finish(&ctx, tag, tag_len)) { 373 fprintf(stderr, "%u: decrypt failed.\n", test_num); 374 goto out; 375 } 376 if (plaintext && memcmp(out, plaintext, plaintext_len)) { 377 fprintf(stderr, "%u: plaintext doesn't match.\n", test_num); 378 goto out; 379 } 380 381 ret = 1; 382 383out: 384 OPENSSL_free(key); 385 OPENSSL_free(plaintext); 386 OPENSSL_free(additional_data); 387 OPENSSL_free(nonce); 388 OPENSSL_free(ciphertext); 389 OPENSSL_free(tag); 390 OPENSSL_free(out); 391 return ret; 392} 393 394int main(void) { 395 int ret = 0; 396 unsigned i; 397 398 CRYPTO_library_init(); 399 400 for (i = 0; i < sizeof(test_cases) / sizeof(struct test_case); i++) { 401 if (!run_test_case(i, &test_cases[i])) { 402 ret = 1; 403 } 404 } 405 406 if (ret == 0) { 407 printf("PASS\n"); 408 } 409 410 return ret; 411} 412