1/* BEGIN_HEADER */ 2#include "mbedtls/gcm.h" 3 4/* Use the multipart interface to process the encrypted data in two parts 5 * and check that the output matches the expected output. 6 * The context must have been set up with the key. */ 7static int check_multipart(mbedtls_gcm_context *ctx, 8 int mode, 9 const data_t *iv, 10 const data_t *add, 11 const data_t *input, 12 const data_t *expected_output, 13 const data_t *tag, 14 size_t n1, 15 size_t n1_add) 16{ 17 int ok = 0; 18 uint8_t *output = NULL; 19 size_t n2 = input->len - n1; 20 size_t n2_add = add->len - n1_add; 21 size_t olen; 22 23 /* Sanity checks on the test data */ 24 TEST_ASSERT(n1 <= input->len); 25 TEST_ASSERT(n1_add <= add->len); 26 TEST_EQUAL(input->len, expected_output->len); 27 28 TEST_EQUAL(0, mbedtls_gcm_starts(ctx, mode, 29 iv->x, iv->len)); 30 TEST_EQUAL(0, mbedtls_gcm_update_ad(ctx, add->x, n1_add)); 31 TEST_EQUAL(0, mbedtls_gcm_update_ad(ctx, add->x + n1_add, n2_add)); 32 33 /* Allocate a tight buffer for each update call. This way, if the function 34 * tries to write beyond the advertised required buffer size, this will 35 * count as an overflow for memory sanitizers and static checkers. */ 36 ASSERT_ALLOC(output, n1); 37 olen = 0xdeadbeef; 38 TEST_EQUAL(0, mbedtls_gcm_update(ctx, input->x, n1, output, n1, &olen)); 39 TEST_EQUAL(n1, olen); 40 ASSERT_COMPARE(output, olen, expected_output->x, n1); 41 mbedtls_free(output); 42 output = NULL; 43 44 ASSERT_ALLOC(output, n2); 45 olen = 0xdeadbeef; 46 TEST_EQUAL(0, mbedtls_gcm_update(ctx, input->x + n1, n2, output, n2, &olen)); 47 TEST_EQUAL(n2, olen); 48 ASSERT_COMPARE(output, olen, expected_output->x + n1, n2); 49 mbedtls_free(output); 50 output = NULL; 51 52 ASSERT_ALLOC(output, tag->len); 53 TEST_EQUAL(0, mbedtls_gcm_finish(ctx, NULL, 0, &olen, output, tag->len)); 54 TEST_EQUAL(0, olen); 55 ASSERT_COMPARE(output, tag->len, tag->x, tag->len); 56 mbedtls_free(output); 57 output = NULL; 58 59 ok = 1; 60exit: 61 mbedtls_free(output); 62 return ok; 63} 64 65static void check_cipher_with_empty_ad(mbedtls_gcm_context *ctx, 66 int mode, 67 const data_t *iv, 68 const data_t *input, 69 const data_t *expected_output, 70 const data_t *tag, 71 size_t ad_update_count) 72{ 73 size_t n; 74 uint8_t *output = NULL; 75 size_t olen; 76 77 /* Sanity checks on the test data */ 78 TEST_EQUAL(input->len, expected_output->len); 79 80 TEST_EQUAL(0, mbedtls_gcm_starts(ctx, mode, 81 iv->x, iv->len)); 82 83 for (n = 0; n < ad_update_count; n++) { 84 TEST_EQUAL(0, mbedtls_gcm_update_ad(ctx, NULL, 0)); 85 } 86 87 /* Allocate a tight buffer for each update call. This way, if the function 88 * tries to write beyond the advertised required buffer size, this will 89 * count as an overflow for memory sanitizers and static checkers. */ 90 ASSERT_ALLOC(output, input->len); 91 olen = 0xdeadbeef; 92 TEST_EQUAL(0, mbedtls_gcm_update(ctx, input->x, input->len, output, input->len, &olen)); 93 TEST_EQUAL(input->len, olen); 94 ASSERT_COMPARE(output, olen, expected_output->x, input->len); 95 mbedtls_free(output); 96 output = NULL; 97 98 ASSERT_ALLOC(output, tag->len); 99 TEST_EQUAL(0, mbedtls_gcm_finish(ctx, NULL, 0, &olen, output, tag->len)); 100 TEST_EQUAL(0, olen); 101 ASSERT_COMPARE(output, tag->len, tag->x, tag->len); 102 103exit: 104 mbedtls_free(output); 105} 106 107static void check_empty_cipher_with_ad(mbedtls_gcm_context *ctx, 108 int mode, 109 const data_t *iv, 110 const data_t *add, 111 const data_t *tag, 112 size_t cipher_update_count) 113{ 114 size_t olen; 115 size_t n; 116 uint8_t *output_tag = NULL; 117 118 TEST_EQUAL(0, mbedtls_gcm_starts(ctx, mode, iv->x, iv->len)); 119 TEST_EQUAL(0, mbedtls_gcm_update_ad(ctx, add->x, add->len)); 120 121 for (n = 0; n < cipher_update_count; n++) { 122 olen = 0xdeadbeef; 123 TEST_EQUAL(0, mbedtls_gcm_update(ctx, NULL, 0, NULL, 0, &olen)); 124 TEST_EQUAL(0, olen); 125 } 126 127 ASSERT_ALLOC(output_tag, tag->len); 128 TEST_EQUAL(0, mbedtls_gcm_finish(ctx, NULL, 0, &olen, 129 output_tag, tag->len)); 130 TEST_EQUAL(0, olen); 131 ASSERT_COMPARE(output_tag, tag->len, tag->x, tag->len); 132 133exit: 134 mbedtls_free(output_tag); 135} 136 137static void check_no_cipher_no_ad(mbedtls_gcm_context *ctx, 138 int mode, 139 const data_t *iv, 140 const data_t *tag) 141{ 142 uint8_t *output = NULL; 143 size_t olen = 0; 144 145 TEST_EQUAL(0, mbedtls_gcm_starts(ctx, mode, 146 iv->x, iv->len)); 147 ASSERT_ALLOC(output, tag->len); 148 TEST_EQUAL(0, mbedtls_gcm_finish(ctx, NULL, 0, &olen, output, tag->len)); 149 TEST_EQUAL(0, olen); 150 ASSERT_COMPARE(output, tag->len, tag->x, tag->len); 151 152exit: 153 mbedtls_free(output); 154} 155 156/* END_HEADER */ 157 158/* BEGIN_DEPENDENCIES 159 * depends_on:MBEDTLS_GCM_C 160 * END_DEPENDENCIES 161 */ 162 163/* BEGIN_CASE */ 164void gcm_bad_parameters(int cipher_id, int direction, 165 data_t *key_str, data_t *src_str, 166 data_t *iv_str, data_t *add_str, 167 int tag_len_bits, int gcm_result) 168{ 169 unsigned char output[128]; 170 unsigned char tag_output[16]; 171 mbedtls_gcm_context ctx; 172 size_t tag_len = tag_len_bits / 8; 173 174 mbedtls_gcm_init(&ctx); 175 176 memset(output, 0x00, sizeof(output)); 177 memset(tag_output, 0x00, sizeof(tag_output)); 178 179 TEST_ASSERT(mbedtls_gcm_setkey(&ctx, cipher_id, key_str->x, key_str->len * 8) == 0); 180 TEST_ASSERT(mbedtls_gcm_crypt_and_tag(&ctx, direction, src_str->len, iv_str->x, iv_str->len, 181 add_str->x, add_str->len, src_str->x, output, tag_len, 182 tag_output) == gcm_result); 183 184exit: 185 mbedtls_gcm_free(&ctx); 186} 187/* END_CASE */ 188 189/* BEGIN_CASE */ 190void gcm_encrypt_and_tag(int cipher_id, data_t *key_str, 191 data_t *src_str, data_t *iv_str, 192 data_t *add_str, data_t *dst, 193 int tag_len_bits, data_t *tag, 194 int init_result) 195{ 196 unsigned char output[128]; 197 unsigned char tag_output[16]; 198 mbedtls_gcm_context ctx; 199 size_t tag_len = tag_len_bits / 8; 200 size_t n1; 201 size_t n1_add; 202 203 mbedtls_gcm_init(&ctx); 204 205 memset(output, 0x00, 128); 206 memset(tag_output, 0x00, 16); 207 208 209 TEST_ASSERT(mbedtls_gcm_setkey(&ctx, cipher_id, key_str->x, key_str->len * 8) == init_result); 210 if (init_result == 0) { 211 TEST_ASSERT(mbedtls_gcm_crypt_and_tag(&ctx, MBEDTLS_GCM_ENCRYPT, src_str->len, iv_str->x, 212 iv_str->len, add_str->x, add_str->len, src_str->x, 213 output, tag_len, tag_output) == 0); 214 215 ASSERT_COMPARE(output, src_str->len, dst->x, dst->len); 216 ASSERT_COMPARE(tag_output, tag_len, tag->x, tag->len); 217 218 for (n1 = 0; n1 <= src_str->len; n1 += 1) { 219 for (n1_add = 0; n1_add <= add_str->len; n1_add += 1) { 220 mbedtls_test_set_step(n1 * 10000 + n1_add); 221 if (!check_multipart(&ctx, MBEDTLS_GCM_ENCRYPT, 222 iv_str, add_str, src_str, 223 dst, tag, 224 n1, n1_add)) { 225 goto exit; 226 } 227 } 228 } 229 } 230 231exit: 232 mbedtls_gcm_free(&ctx); 233} 234/* END_CASE */ 235 236/* BEGIN_CASE */ 237void gcm_decrypt_and_verify(int cipher_id, data_t *key_str, 238 data_t *src_str, data_t *iv_str, 239 data_t *add_str, int tag_len_bits, 240 data_t *tag_str, char *result, 241 data_t *pt_result, int init_result) 242{ 243 unsigned char output[128]; 244 mbedtls_gcm_context ctx; 245 int ret; 246 size_t tag_len = tag_len_bits / 8; 247 size_t n1; 248 size_t n1_add; 249 250 mbedtls_gcm_init(&ctx); 251 252 memset(output, 0x00, 128); 253 254 255 TEST_ASSERT(mbedtls_gcm_setkey(&ctx, cipher_id, key_str->x, key_str->len * 8) == init_result); 256 if (init_result == 0) { 257 ret = mbedtls_gcm_auth_decrypt(&ctx, 258 src_str->len, 259 iv_str->x, 260 iv_str->len, 261 add_str->x, 262 add_str->len, 263 tag_str->x, 264 tag_len, 265 src_str->x, 266 output); 267 268 if (strcmp("FAIL", result) == 0) { 269 TEST_ASSERT(ret == MBEDTLS_ERR_GCM_AUTH_FAILED); 270 } else { 271 TEST_ASSERT(ret == 0); 272 ASSERT_COMPARE(output, src_str->len, pt_result->x, pt_result->len); 273 274 for (n1 = 0; n1 <= src_str->len; n1 += 1) { 275 for (n1_add = 0; n1_add <= add_str->len; n1_add += 1) { 276 mbedtls_test_set_step(n1 * 10000 + n1_add); 277 if (!check_multipart(&ctx, MBEDTLS_GCM_DECRYPT, 278 iv_str, add_str, src_str, 279 pt_result, tag_str, 280 n1, n1_add)) { 281 goto exit; 282 } 283 } 284 } 285 } 286 } 287 288exit: 289 mbedtls_gcm_free(&ctx); 290} 291/* END_CASE */ 292 293/* BEGIN_CASE */ 294void gcm_decrypt_and_verify_empty_cipher(int cipher_id, 295 data_t *key_str, 296 data_t *iv_str, 297 data_t *add_str, 298 data_t *tag_str, 299 int cipher_update_calls) 300{ 301 mbedtls_gcm_context ctx; 302 303 mbedtls_gcm_init(&ctx); 304 305 TEST_ASSERT(mbedtls_gcm_setkey(&ctx, cipher_id, key_str->x, key_str->len * 8) == 0); 306 check_empty_cipher_with_ad(&ctx, MBEDTLS_GCM_DECRYPT, 307 iv_str, add_str, tag_str, 308 cipher_update_calls); 309 310 mbedtls_gcm_free(&ctx); 311} 312/* END_CASE */ 313 314/* BEGIN_CASE */ 315void gcm_decrypt_and_verify_empty_ad(int cipher_id, 316 data_t *key_str, 317 data_t *iv_str, 318 data_t *src_str, 319 data_t *tag_str, 320 data_t *pt_result, 321 int ad_update_calls) 322{ 323 mbedtls_gcm_context ctx; 324 325 mbedtls_gcm_init(&ctx); 326 327 TEST_ASSERT(mbedtls_gcm_setkey(&ctx, cipher_id, key_str->x, key_str->len * 8) == 0); 328 check_cipher_with_empty_ad(&ctx, MBEDTLS_GCM_DECRYPT, 329 iv_str, src_str, pt_result, tag_str, 330 ad_update_calls); 331 332 mbedtls_gcm_free(&ctx); 333} 334/* END_CASE */ 335 336/* BEGIN_CASE */ 337void gcm_decrypt_and_verify_no_ad_no_cipher(int cipher_id, 338 data_t *key_str, 339 data_t *iv_str, 340 data_t *tag_str) 341{ 342 mbedtls_gcm_context ctx; 343 344 mbedtls_gcm_init(&ctx); 345 346 TEST_ASSERT(mbedtls_gcm_setkey(&ctx, cipher_id, key_str->x, key_str->len * 8) == 0); 347 check_no_cipher_no_ad(&ctx, MBEDTLS_GCM_DECRYPT, 348 iv_str, tag_str); 349 350 mbedtls_gcm_free(&ctx); 351} 352/* END_CASE */ 353 354/* BEGIN_CASE */ 355void gcm_encrypt_and_tag_empty_cipher(int cipher_id, 356 data_t *key_str, 357 data_t *iv_str, 358 data_t *add_str, 359 data_t *tag_str, 360 int cipher_update_calls) 361{ 362 mbedtls_gcm_context ctx; 363 364 mbedtls_gcm_init(&ctx); 365 366 TEST_ASSERT(mbedtls_gcm_setkey(&ctx, cipher_id, key_str->x, key_str->len * 8) == 0); 367 check_empty_cipher_with_ad(&ctx, MBEDTLS_GCM_ENCRYPT, 368 iv_str, add_str, tag_str, 369 cipher_update_calls); 370 371exit: 372 mbedtls_gcm_free(&ctx); 373} 374/* END_CASE */ 375 376/* BEGIN_CASE */ 377void gcm_encrypt_and_tag_empty_ad(int cipher_id, 378 data_t *key_str, 379 data_t *iv_str, 380 data_t *src_str, 381 data_t *dst, 382 data_t *tag_str, 383 int ad_update_calls) 384{ 385 mbedtls_gcm_context ctx; 386 387 mbedtls_gcm_init(&ctx); 388 389 TEST_ASSERT(mbedtls_gcm_setkey(&ctx, cipher_id, key_str->x, key_str->len * 8) == 0); 390 check_cipher_with_empty_ad(&ctx, MBEDTLS_GCM_ENCRYPT, 391 iv_str, src_str, dst, tag_str, 392 ad_update_calls); 393 394exit: 395 mbedtls_gcm_free(&ctx); 396} 397/* END_CASE */ 398 399/* BEGIN_CASE */ 400void gcm_encrypt_and_verify_no_ad_no_cipher(int cipher_id, 401 data_t *key_str, 402 data_t *iv_str, 403 data_t *tag_str) 404{ 405 mbedtls_gcm_context ctx; 406 407 mbedtls_gcm_init(&ctx); 408 409 TEST_ASSERT(mbedtls_gcm_setkey(&ctx, cipher_id, key_str->x, key_str->len * 8) == 0); 410 check_no_cipher_no_ad(&ctx, MBEDTLS_GCM_ENCRYPT, 411 iv_str, tag_str); 412 413 mbedtls_gcm_free(&ctx); 414} 415/* END_CASE */ 416 417/* BEGIN_CASE */ 418void gcm_invalid_param() 419{ 420 mbedtls_gcm_context ctx; 421 unsigned char valid_buffer[] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 }; 422 mbedtls_cipher_id_t valid_cipher = MBEDTLS_CIPHER_ID_AES; 423 int invalid_bitlen = 1; 424 425 mbedtls_gcm_init(&ctx); 426 427 /* mbedtls_gcm_setkey */ 428 TEST_EQUAL( 429 MBEDTLS_ERR_GCM_BAD_INPUT, 430 mbedtls_gcm_setkey(&ctx, valid_cipher, valid_buffer, invalid_bitlen)); 431 432exit: 433 mbedtls_gcm_free(&ctx); 434} 435/* END_CASE */ 436 437/* BEGIN_CASE */ 438void gcm_update_output_buffer_too_small(int cipher_id, int mode, 439 data_t *key_str, const data_t *input, 440 const data_t *iv) 441{ 442 mbedtls_gcm_context ctx; 443 uint8_t *output = NULL; 444 size_t olen = 0; 445 size_t output_len = input->len - 1; 446 447 mbedtls_gcm_init(&ctx); 448 TEST_EQUAL(mbedtls_gcm_setkey(&ctx, cipher_id, key_str->x, key_str->len * 8), 0); 449 TEST_EQUAL(0, mbedtls_gcm_starts(&ctx, mode, iv->x, iv->len)); 450 451 ASSERT_ALLOC(output, output_len); 452 TEST_EQUAL(MBEDTLS_ERR_GCM_BUFFER_TOO_SMALL, 453 mbedtls_gcm_update(&ctx, input->x, input->len, output, output_len, &olen)); 454 455exit: 456 mbedtls_free(output); 457 mbedtls_gcm_free(&ctx); 458} 459/* END_CASE */ 460 461/* BEGIN_CASE depends_on:MBEDTLS_SELF_TEST:MBEDTLS_AES_C */ 462void gcm_selftest() 463{ 464 TEST_ASSERT(mbedtls_gcm_self_test(1) == 0); 465} 466/* END_CASE */ 467