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