1a8e1175bSopenharmony_ci/* BEGIN_HEADER */ 2a8e1175bSopenharmony_ci#include "mbedtls/gcm.h" 3a8e1175bSopenharmony_ci 4a8e1175bSopenharmony_ci/* Use the multipart interface to process the encrypted data in two parts 5a8e1175bSopenharmony_ci * and check that the output matches the expected output. 6a8e1175bSopenharmony_ci * The context must have been set up with the key. */ 7a8e1175bSopenharmony_cistatic int check_multipart(mbedtls_gcm_context *ctx, 8a8e1175bSopenharmony_ci int mode, 9a8e1175bSopenharmony_ci const data_t *iv, 10a8e1175bSopenharmony_ci const data_t *add, 11a8e1175bSopenharmony_ci const data_t *input, 12a8e1175bSopenharmony_ci const data_t *expected_output, 13a8e1175bSopenharmony_ci const data_t *tag, 14a8e1175bSopenharmony_ci size_t n1, 15a8e1175bSopenharmony_ci size_t n1_add) 16a8e1175bSopenharmony_ci{ 17a8e1175bSopenharmony_ci int ok = 0; 18a8e1175bSopenharmony_ci uint8_t *output = NULL; 19a8e1175bSopenharmony_ci size_t n2 = input->len - n1; 20a8e1175bSopenharmony_ci size_t n2_add = add->len - n1_add; 21a8e1175bSopenharmony_ci size_t olen; 22a8e1175bSopenharmony_ci 23a8e1175bSopenharmony_ci /* Sanity checks on the test data */ 24a8e1175bSopenharmony_ci TEST_ASSERT(n1 <= input->len); 25a8e1175bSopenharmony_ci TEST_ASSERT(n1_add <= add->len); 26a8e1175bSopenharmony_ci TEST_EQUAL(input->len, expected_output->len); 27a8e1175bSopenharmony_ci 28a8e1175bSopenharmony_ci TEST_EQUAL(0, mbedtls_gcm_starts(ctx, mode, 29a8e1175bSopenharmony_ci iv->x, iv->len)); 30a8e1175bSopenharmony_ci TEST_EQUAL(0, mbedtls_gcm_update_ad(ctx, add->x, n1_add)); 31a8e1175bSopenharmony_ci TEST_EQUAL(0, mbedtls_gcm_update_ad(ctx, add->x + n1_add, n2_add)); 32a8e1175bSopenharmony_ci 33a8e1175bSopenharmony_ci /* Allocate a tight buffer for each update call. This way, if the function 34a8e1175bSopenharmony_ci * tries to write beyond the advertised required buffer size, this will 35a8e1175bSopenharmony_ci * count as an overflow for memory sanitizers and static checkers. */ 36a8e1175bSopenharmony_ci TEST_CALLOC(output, n1); 37a8e1175bSopenharmony_ci olen = 0xdeadbeef; 38a8e1175bSopenharmony_ci TEST_EQUAL(0, mbedtls_gcm_update(ctx, input->x, n1, output, n1, &olen)); 39a8e1175bSopenharmony_ci TEST_EQUAL(n1, olen); 40a8e1175bSopenharmony_ci TEST_MEMORY_COMPARE(output, olen, expected_output->x, n1); 41a8e1175bSopenharmony_ci mbedtls_free(output); 42a8e1175bSopenharmony_ci output = NULL; 43a8e1175bSopenharmony_ci 44a8e1175bSopenharmony_ci TEST_CALLOC(output, n2); 45a8e1175bSopenharmony_ci olen = 0xdeadbeef; 46a8e1175bSopenharmony_ci TEST_EQUAL(0, mbedtls_gcm_update(ctx, input->x + n1, n2, output, n2, &olen)); 47a8e1175bSopenharmony_ci TEST_EQUAL(n2, olen); 48a8e1175bSopenharmony_ci TEST_MEMORY_COMPARE(output, olen, expected_output->x + n1, n2); 49a8e1175bSopenharmony_ci mbedtls_free(output); 50a8e1175bSopenharmony_ci output = NULL; 51a8e1175bSopenharmony_ci 52a8e1175bSopenharmony_ci TEST_CALLOC(output, tag->len); 53a8e1175bSopenharmony_ci TEST_EQUAL(0, mbedtls_gcm_finish(ctx, NULL, 0, &olen, output, tag->len)); 54a8e1175bSopenharmony_ci TEST_EQUAL(0, olen); 55a8e1175bSopenharmony_ci TEST_MEMORY_COMPARE(output, tag->len, tag->x, tag->len); 56a8e1175bSopenharmony_ci mbedtls_free(output); 57a8e1175bSopenharmony_ci output = NULL; 58a8e1175bSopenharmony_ci 59a8e1175bSopenharmony_ci ok = 1; 60a8e1175bSopenharmony_ciexit: 61a8e1175bSopenharmony_ci mbedtls_free(output); 62a8e1175bSopenharmony_ci return ok; 63a8e1175bSopenharmony_ci} 64a8e1175bSopenharmony_ci 65a8e1175bSopenharmony_cistatic void check_cipher_with_empty_ad(mbedtls_gcm_context *ctx, 66a8e1175bSopenharmony_ci int mode, 67a8e1175bSopenharmony_ci const data_t *iv, 68a8e1175bSopenharmony_ci const data_t *input, 69a8e1175bSopenharmony_ci const data_t *expected_output, 70a8e1175bSopenharmony_ci const data_t *tag, 71a8e1175bSopenharmony_ci size_t ad_update_count) 72a8e1175bSopenharmony_ci{ 73a8e1175bSopenharmony_ci size_t n; 74a8e1175bSopenharmony_ci uint8_t *output = NULL; 75a8e1175bSopenharmony_ci size_t olen; 76a8e1175bSopenharmony_ci 77a8e1175bSopenharmony_ci /* Sanity checks on the test data */ 78a8e1175bSopenharmony_ci TEST_EQUAL(input->len, expected_output->len); 79a8e1175bSopenharmony_ci 80a8e1175bSopenharmony_ci TEST_EQUAL(0, mbedtls_gcm_starts(ctx, mode, 81a8e1175bSopenharmony_ci iv->x, iv->len)); 82a8e1175bSopenharmony_ci 83a8e1175bSopenharmony_ci for (n = 0; n < ad_update_count; n++) { 84a8e1175bSopenharmony_ci TEST_EQUAL(0, mbedtls_gcm_update_ad(ctx, NULL, 0)); 85a8e1175bSopenharmony_ci } 86a8e1175bSopenharmony_ci 87a8e1175bSopenharmony_ci /* Allocate a tight buffer for each update call. This way, if the function 88a8e1175bSopenharmony_ci * tries to write beyond the advertised required buffer size, this will 89a8e1175bSopenharmony_ci * count as an overflow for memory sanitizers and static checkers. */ 90a8e1175bSopenharmony_ci TEST_CALLOC(output, input->len); 91a8e1175bSopenharmony_ci olen = 0xdeadbeef; 92a8e1175bSopenharmony_ci TEST_EQUAL(0, mbedtls_gcm_update(ctx, input->x, input->len, output, input->len, &olen)); 93a8e1175bSopenharmony_ci TEST_EQUAL(input->len, olen); 94a8e1175bSopenharmony_ci TEST_MEMORY_COMPARE(output, olen, expected_output->x, input->len); 95a8e1175bSopenharmony_ci mbedtls_free(output); 96a8e1175bSopenharmony_ci output = NULL; 97a8e1175bSopenharmony_ci 98a8e1175bSopenharmony_ci TEST_CALLOC(output, tag->len); 99a8e1175bSopenharmony_ci TEST_EQUAL(0, mbedtls_gcm_finish(ctx, NULL, 0, &olen, output, tag->len)); 100a8e1175bSopenharmony_ci TEST_EQUAL(0, olen); 101a8e1175bSopenharmony_ci TEST_MEMORY_COMPARE(output, tag->len, tag->x, tag->len); 102a8e1175bSopenharmony_ci 103a8e1175bSopenharmony_ciexit: 104a8e1175bSopenharmony_ci mbedtls_free(output); 105a8e1175bSopenharmony_ci} 106a8e1175bSopenharmony_ci 107a8e1175bSopenharmony_cistatic void check_empty_cipher_with_ad(mbedtls_gcm_context *ctx, 108a8e1175bSopenharmony_ci int mode, 109a8e1175bSopenharmony_ci const data_t *iv, 110a8e1175bSopenharmony_ci const data_t *add, 111a8e1175bSopenharmony_ci const data_t *tag, 112a8e1175bSopenharmony_ci size_t cipher_update_count) 113a8e1175bSopenharmony_ci{ 114a8e1175bSopenharmony_ci size_t olen; 115a8e1175bSopenharmony_ci size_t n; 116a8e1175bSopenharmony_ci uint8_t *output_tag = NULL; 117a8e1175bSopenharmony_ci 118a8e1175bSopenharmony_ci TEST_EQUAL(0, mbedtls_gcm_starts(ctx, mode, iv->x, iv->len)); 119a8e1175bSopenharmony_ci TEST_EQUAL(0, mbedtls_gcm_update_ad(ctx, add->x, add->len)); 120a8e1175bSopenharmony_ci 121a8e1175bSopenharmony_ci for (n = 0; n < cipher_update_count; n++) { 122a8e1175bSopenharmony_ci olen = 0xdeadbeef; 123a8e1175bSopenharmony_ci TEST_EQUAL(0, mbedtls_gcm_update(ctx, NULL, 0, NULL, 0, &olen)); 124a8e1175bSopenharmony_ci TEST_EQUAL(0, olen); 125a8e1175bSopenharmony_ci } 126a8e1175bSopenharmony_ci 127a8e1175bSopenharmony_ci TEST_CALLOC(output_tag, tag->len); 128a8e1175bSopenharmony_ci TEST_EQUAL(0, mbedtls_gcm_finish(ctx, NULL, 0, &olen, 129a8e1175bSopenharmony_ci output_tag, tag->len)); 130a8e1175bSopenharmony_ci TEST_EQUAL(0, olen); 131a8e1175bSopenharmony_ci TEST_MEMORY_COMPARE(output_tag, tag->len, tag->x, tag->len); 132a8e1175bSopenharmony_ci 133a8e1175bSopenharmony_ciexit: 134a8e1175bSopenharmony_ci mbedtls_free(output_tag); 135a8e1175bSopenharmony_ci} 136a8e1175bSopenharmony_ci 137a8e1175bSopenharmony_cistatic void check_no_cipher_no_ad(mbedtls_gcm_context *ctx, 138a8e1175bSopenharmony_ci int mode, 139a8e1175bSopenharmony_ci const data_t *iv, 140a8e1175bSopenharmony_ci const data_t *tag) 141a8e1175bSopenharmony_ci{ 142a8e1175bSopenharmony_ci uint8_t *output = NULL; 143a8e1175bSopenharmony_ci size_t olen = 0; 144a8e1175bSopenharmony_ci 145a8e1175bSopenharmony_ci TEST_EQUAL(0, mbedtls_gcm_starts(ctx, mode, 146a8e1175bSopenharmony_ci iv->x, iv->len)); 147a8e1175bSopenharmony_ci TEST_CALLOC(output, tag->len); 148a8e1175bSopenharmony_ci TEST_EQUAL(0, mbedtls_gcm_finish(ctx, NULL, 0, &olen, output, tag->len)); 149a8e1175bSopenharmony_ci TEST_EQUAL(0, olen); 150a8e1175bSopenharmony_ci TEST_MEMORY_COMPARE(output, tag->len, tag->x, tag->len); 151a8e1175bSopenharmony_ci 152a8e1175bSopenharmony_ciexit: 153a8e1175bSopenharmony_ci mbedtls_free(output); 154a8e1175bSopenharmony_ci} 155a8e1175bSopenharmony_ci 156a8e1175bSopenharmony_cistatic void gcm_reset_ctx(mbedtls_gcm_context *ctx, const uint8_t *key, 157a8e1175bSopenharmony_ci size_t key_bits, const uint8_t *iv, size_t iv_len, 158a8e1175bSopenharmony_ci int starts_ret) 159a8e1175bSopenharmony_ci{ 160a8e1175bSopenharmony_ci int mode = MBEDTLS_GCM_ENCRYPT; 161a8e1175bSopenharmony_ci mbedtls_cipher_id_t valid_cipher = MBEDTLS_CIPHER_ID_AES; 162a8e1175bSopenharmony_ci 163a8e1175bSopenharmony_ci mbedtls_gcm_init(ctx); 164a8e1175bSopenharmony_ci TEST_EQUAL(mbedtls_gcm_setkey(ctx, valid_cipher, key, key_bits), 0); 165a8e1175bSopenharmony_ci TEST_EQUAL(starts_ret, mbedtls_gcm_starts(ctx, mode, iv, iv_len)); 166a8e1175bSopenharmony_ciexit: 167a8e1175bSopenharmony_ci /* empty */ 168a8e1175bSopenharmony_ci return; 169a8e1175bSopenharmony_ci} 170a8e1175bSopenharmony_ci 171a8e1175bSopenharmony_ci/* END_HEADER */ 172a8e1175bSopenharmony_ci 173a8e1175bSopenharmony_ci/* BEGIN_DEPENDENCIES 174a8e1175bSopenharmony_ci * depends_on:MBEDTLS_GCM_C 175a8e1175bSopenharmony_ci * END_DEPENDENCIES 176a8e1175bSopenharmony_ci */ 177a8e1175bSopenharmony_ci 178a8e1175bSopenharmony_ci/* BEGIN_CASE */ 179a8e1175bSopenharmony_civoid gcm_bad_parameters(int cipher_id, int direction, 180a8e1175bSopenharmony_ci data_t *key_str, data_t *src_str, 181a8e1175bSopenharmony_ci data_t *iv_str, data_t *add_str, 182a8e1175bSopenharmony_ci int tag_len_bits, int gcm_result) 183a8e1175bSopenharmony_ci{ 184a8e1175bSopenharmony_ci unsigned char output[128]; 185a8e1175bSopenharmony_ci unsigned char tag_output[16]; 186a8e1175bSopenharmony_ci mbedtls_gcm_context ctx; 187a8e1175bSopenharmony_ci size_t tag_len = tag_len_bits / 8; 188a8e1175bSopenharmony_ci 189a8e1175bSopenharmony_ci BLOCK_CIPHER_PSA_INIT(); 190a8e1175bSopenharmony_ci mbedtls_gcm_init(&ctx); 191a8e1175bSopenharmony_ci 192a8e1175bSopenharmony_ci memset(output, 0x00, sizeof(output)); 193a8e1175bSopenharmony_ci memset(tag_output, 0x00, sizeof(tag_output)); 194a8e1175bSopenharmony_ci 195a8e1175bSopenharmony_ci TEST_ASSERT(mbedtls_gcm_setkey(&ctx, cipher_id, key_str->x, key_str->len * 8) == 0); 196a8e1175bSopenharmony_ci TEST_ASSERT(mbedtls_gcm_crypt_and_tag(&ctx, direction, src_str->len, iv_str->x, iv_str->len, 197a8e1175bSopenharmony_ci add_str->x, add_str->len, src_str->x, output, tag_len, 198a8e1175bSopenharmony_ci tag_output) == gcm_result); 199a8e1175bSopenharmony_ci 200a8e1175bSopenharmony_ciexit: 201a8e1175bSopenharmony_ci mbedtls_gcm_free(&ctx); 202a8e1175bSopenharmony_ci BLOCK_CIPHER_PSA_DONE(); 203a8e1175bSopenharmony_ci} 204a8e1175bSopenharmony_ci/* END_CASE */ 205a8e1175bSopenharmony_ci 206a8e1175bSopenharmony_ci/* BEGIN_CASE */ 207a8e1175bSopenharmony_civoid gcm_encrypt_and_tag(int cipher_id, data_t *key_str, 208a8e1175bSopenharmony_ci data_t *src_str, data_t *iv_str, 209a8e1175bSopenharmony_ci data_t *add_str, data_t *dst, 210a8e1175bSopenharmony_ci int tag_len_bits, data_t *tag, 211a8e1175bSopenharmony_ci int init_result) 212a8e1175bSopenharmony_ci{ 213a8e1175bSopenharmony_ci unsigned char output[128]; 214a8e1175bSopenharmony_ci unsigned char tag_output[16]; 215a8e1175bSopenharmony_ci mbedtls_gcm_context ctx; 216a8e1175bSopenharmony_ci size_t tag_len = tag_len_bits / 8; 217a8e1175bSopenharmony_ci size_t n1; 218a8e1175bSopenharmony_ci size_t n1_add; 219a8e1175bSopenharmony_ci 220a8e1175bSopenharmony_ci BLOCK_CIPHER_PSA_INIT(); 221a8e1175bSopenharmony_ci mbedtls_gcm_init(&ctx); 222a8e1175bSopenharmony_ci 223a8e1175bSopenharmony_ci memset(output, 0x00, 128); 224a8e1175bSopenharmony_ci memset(tag_output, 0x00, 16); 225a8e1175bSopenharmony_ci 226a8e1175bSopenharmony_ci 227a8e1175bSopenharmony_ci TEST_ASSERT(mbedtls_gcm_setkey(&ctx, cipher_id, key_str->x, key_str->len * 8) == init_result); 228a8e1175bSopenharmony_ci if (init_result == 0) { 229a8e1175bSopenharmony_ci TEST_ASSERT(mbedtls_gcm_crypt_and_tag(&ctx, MBEDTLS_GCM_ENCRYPT, src_str->len, iv_str->x, 230a8e1175bSopenharmony_ci iv_str->len, add_str->x, add_str->len, src_str->x, 231a8e1175bSopenharmony_ci output, tag_len, tag_output) == 0); 232a8e1175bSopenharmony_ci 233a8e1175bSopenharmony_ci TEST_MEMORY_COMPARE(output, src_str->len, dst->x, dst->len); 234a8e1175bSopenharmony_ci TEST_MEMORY_COMPARE(tag_output, tag_len, tag->x, tag->len); 235a8e1175bSopenharmony_ci 236a8e1175bSopenharmony_ci for (n1 = 0; n1 <= src_str->len; n1 += 1) { 237a8e1175bSopenharmony_ci for (n1_add = 0; n1_add <= add_str->len; n1_add += 1) { 238a8e1175bSopenharmony_ci mbedtls_test_set_step(n1 * 10000 + n1_add); 239a8e1175bSopenharmony_ci if (!check_multipart(&ctx, MBEDTLS_GCM_ENCRYPT, 240a8e1175bSopenharmony_ci iv_str, add_str, src_str, 241a8e1175bSopenharmony_ci dst, tag, 242a8e1175bSopenharmony_ci n1, n1_add)) { 243a8e1175bSopenharmony_ci goto exit; 244a8e1175bSopenharmony_ci } 245a8e1175bSopenharmony_ci } 246a8e1175bSopenharmony_ci } 247a8e1175bSopenharmony_ci } 248a8e1175bSopenharmony_ci 249a8e1175bSopenharmony_ciexit: 250a8e1175bSopenharmony_ci mbedtls_gcm_free(&ctx); 251a8e1175bSopenharmony_ci BLOCK_CIPHER_PSA_DONE(); 252a8e1175bSopenharmony_ci} 253a8e1175bSopenharmony_ci/* END_CASE */ 254a8e1175bSopenharmony_ci 255a8e1175bSopenharmony_ci/* BEGIN_CASE */ 256a8e1175bSopenharmony_civoid gcm_decrypt_and_verify(int cipher_id, data_t *key_str, 257a8e1175bSopenharmony_ci data_t *src_str, data_t *iv_str, 258a8e1175bSopenharmony_ci data_t *add_str, int tag_len_bits, 259a8e1175bSopenharmony_ci data_t *tag_str, char *result, 260a8e1175bSopenharmony_ci data_t *pt_result, int init_result) 261a8e1175bSopenharmony_ci{ 262a8e1175bSopenharmony_ci unsigned char output[128]; 263a8e1175bSopenharmony_ci mbedtls_gcm_context ctx; 264a8e1175bSopenharmony_ci int ret; 265a8e1175bSopenharmony_ci size_t tag_len = tag_len_bits / 8; 266a8e1175bSopenharmony_ci size_t n1; 267a8e1175bSopenharmony_ci size_t n1_add; 268a8e1175bSopenharmony_ci 269a8e1175bSopenharmony_ci BLOCK_CIPHER_PSA_INIT(); 270a8e1175bSopenharmony_ci mbedtls_gcm_init(&ctx); 271a8e1175bSopenharmony_ci 272a8e1175bSopenharmony_ci memset(output, 0x00, 128); 273a8e1175bSopenharmony_ci 274a8e1175bSopenharmony_ci 275a8e1175bSopenharmony_ci TEST_ASSERT(mbedtls_gcm_setkey(&ctx, cipher_id, key_str->x, key_str->len * 8) == init_result); 276a8e1175bSopenharmony_ci if (init_result == 0) { 277a8e1175bSopenharmony_ci ret = mbedtls_gcm_auth_decrypt(&ctx, 278a8e1175bSopenharmony_ci src_str->len, 279a8e1175bSopenharmony_ci iv_str->x, 280a8e1175bSopenharmony_ci iv_str->len, 281a8e1175bSopenharmony_ci add_str->x, 282a8e1175bSopenharmony_ci add_str->len, 283a8e1175bSopenharmony_ci tag_str->x, 284a8e1175bSopenharmony_ci tag_len, 285a8e1175bSopenharmony_ci src_str->x, 286a8e1175bSopenharmony_ci output); 287a8e1175bSopenharmony_ci 288a8e1175bSopenharmony_ci if (strcmp("FAIL", result) == 0) { 289a8e1175bSopenharmony_ci TEST_ASSERT(ret == MBEDTLS_ERR_GCM_AUTH_FAILED); 290a8e1175bSopenharmony_ci } else { 291a8e1175bSopenharmony_ci TEST_ASSERT(ret == 0); 292a8e1175bSopenharmony_ci TEST_MEMORY_COMPARE(output, src_str->len, pt_result->x, pt_result->len); 293a8e1175bSopenharmony_ci 294a8e1175bSopenharmony_ci for (n1 = 0; n1 <= src_str->len; n1 += 1) { 295a8e1175bSopenharmony_ci for (n1_add = 0; n1_add <= add_str->len; n1_add += 1) { 296a8e1175bSopenharmony_ci mbedtls_test_set_step(n1 * 10000 + n1_add); 297a8e1175bSopenharmony_ci if (!check_multipart(&ctx, MBEDTLS_GCM_DECRYPT, 298a8e1175bSopenharmony_ci iv_str, add_str, src_str, 299a8e1175bSopenharmony_ci pt_result, tag_str, 300a8e1175bSopenharmony_ci n1, n1_add)) { 301a8e1175bSopenharmony_ci goto exit; 302a8e1175bSopenharmony_ci } 303a8e1175bSopenharmony_ci } 304a8e1175bSopenharmony_ci } 305a8e1175bSopenharmony_ci } 306a8e1175bSopenharmony_ci } 307a8e1175bSopenharmony_ci 308a8e1175bSopenharmony_ciexit: 309a8e1175bSopenharmony_ci mbedtls_gcm_free(&ctx); 310a8e1175bSopenharmony_ci BLOCK_CIPHER_PSA_DONE(); 311a8e1175bSopenharmony_ci} 312a8e1175bSopenharmony_ci/* END_CASE */ 313a8e1175bSopenharmony_ci 314a8e1175bSopenharmony_ci/* BEGIN_CASE */ 315a8e1175bSopenharmony_civoid gcm_decrypt_and_verify_empty_cipher(int cipher_id, 316a8e1175bSopenharmony_ci data_t *key_str, 317a8e1175bSopenharmony_ci data_t *iv_str, 318a8e1175bSopenharmony_ci data_t *add_str, 319a8e1175bSopenharmony_ci data_t *tag_str, 320a8e1175bSopenharmony_ci int cipher_update_calls) 321a8e1175bSopenharmony_ci{ 322a8e1175bSopenharmony_ci mbedtls_gcm_context ctx; 323a8e1175bSopenharmony_ci 324a8e1175bSopenharmony_ci BLOCK_CIPHER_PSA_INIT(); 325a8e1175bSopenharmony_ci mbedtls_gcm_init(&ctx); 326a8e1175bSopenharmony_ci 327a8e1175bSopenharmony_ci TEST_ASSERT(mbedtls_gcm_setkey(&ctx, cipher_id, key_str->x, key_str->len * 8) == 0); 328a8e1175bSopenharmony_ci check_empty_cipher_with_ad(&ctx, MBEDTLS_GCM_DECRYPT, 329a8e1175bSopenharmony_ci iv_str, add_str, tag_str, 330a8e1175bSopenharmony_ci cipher_update_calls); 331a8e1175bSopenharmony_ci 332a8e1175bSopenharmony_ci mbedtls_gcm_free(&ctx); 333a8e1175bSopenharmony_ci BLOCK_CIPHER_PSA_DONE(); 334a8e1175bSopenharmony_ci} 335a8e1175bSopenharmony_ci/* END_CASE */ 336a8e1175bSopenharmony_ci 337a8e1175bSopenharmony_ci/* BEGIN_CASE */ 338a8e1175bSopenharmony_civoid gcm_decrypt_and_verify_empty_ad(int cipher_id, 339a8e1175bSopenharmony_ci data_t *key_str, 340a8e1175bSopenharmony_ci data_t *iv_str, 341a8e1175bSopenharmony_ci data_t *src_str, 342a8e1175bSopenharmony_ci data_t *tag_str, 343a8e1175bSopenharmony_ci data_t *pt_result, 344a8e1175bSopenharmony_ci int ad_update_calls) 345a8e1175bSopenharmony_ci{ 346a8e1175bSopenharmony_ci mbedtls_gcm_context ctx; 347a8e1175bSopenharmony_ci 348a8e1175bSopenharmony_ci BLOCK_CIPHER_PSA_INIT(); 349a8e1175bSopenharmony_ci mbedtls_gcm_init(&ctx); 350a8e1175bSopenharmony_ci 351a8e1175bSopenharmony_ci TEST_ASSERT(mbedtls_gcm_setkey(&ctx, cipher_id, key_str->x, key_str->len * 8) == 0); 352a8e1175bSopenharmony_ci check_cipher_with_empty_ad(&ctx, MBEDTLS_GCM_DECRYPT, 353a8e1175bSopenharmony_ci iv_str, src_str, pt_result, tag_str, 354a8e1175bSopenharmony_ci ad_update_calls); 355a8e1175bSopenharmony_ci 356a8e1175bSopenharmony_ci mbedtls_gcm_free(&ctx); 357a8e1175bSopenharmony_ci BLOCK_CIPHER_PSA_DONE(); 358a8e1175bSopenharmony_ci} 359a8e1175bSopenharmony_ci/* END_CASE */ 360a8e1175bSopenharmony_ci 361a8e1175bSopenharmony_ci/* BEGIN_CASE */ 362a8e1175bSopenharmony_civoid gcm_decrypt_and_verify_no_ad_no_cipher(int cipher_id, 363a8e1175bSopenharmony_ci data_t *key_str, 364a8e1175bSopenharmony_ci data_t *iv_str, 365a8e1175bSopenharmony_ci data_t *tag_str) 366a8e1175bSopenharmony_ci{ 367a8e1175bSopenharmony_ci mbedtls_gcm_context ctx; 368a8e1175bSopenharmony_ci 369a8e1175bSopenharmony_ci BLOCK_CIPHER_PSA_INIT(); 370a8e1175bSopenharmony_ci mbedtls_gcm_init(&ctx); 371a8e1175bSopenharmony_ci 372a8e1175bSopenharmony_ci TEST_ASSERT(mbedtls_gcm_setkey(&ctx, cipher_id, key_str->x, key_str->len * 8) == 0); 373a8e1175bSopenharmony_ci check_no_cipher_no_ad(&ctx, MBEDTLS_GCM_DECRYPT, 374a8e1175bSopenharmony_ci iv_str, tag_str); 375a8e1175bSopenharmony_ci 376a8e1175bSopenharmony_ci mbedtls_gcm_free(&ctx); 377a8e1175bSopenharmony_ci BLOCK_CIPHER_PSA_DONE(); 378a8e1175bSopenharmony_ci} 379a8e1175bSopenharmony_ci/* END_CASE */ 380a8e1175bSopenharmony_ci 381a8e1175bSopenharmony_ci/* BEGIN_CASE */ 382a8e1175bSopenharmony_civoid gcm_encrypt_and_tag_empty_cipher(int cipher_id, 383a8e1175bSopenharmony_ci data_t *key_str, 384a8e1175bSopenharmony_ci data_t *iv_str, 385a8e1175bSopenharmony_ci data_t *add_str, 386a8e1175bSopenharmony_ci data_t *tag_str, 387a8e1175bSopenharmony_ci int cipher_update_calls) 388a8e1175bSopenharmony_ci{ 389a8e1175bSopenharmony_ci mbedtls_gcm_context ctx; 390a8e1175bSopenharmony_ci 391a8e1175bSopenharmony_ci BLOCK_CIPHER_PSA_INIT(); 392a8e1175bSopenharmony_ci mbedtls_gcm_init(&ctx); 393a8e1175bSopenharmony_ci 394a8e1175bSopenharmony_ci TEST_ASSERT(mbedtls_gcm_setkey(&ctx, cipher_id, key_str->x, key_str->len * 8) == 0); 395a8e1175bSopenharmony_ci check_empty_cipher_with_ad(&ctx, MBEDTLS_GCM_ENCRYPT, 396a8e1175bSopenharmony_ci iv_str, add_str, tag_str, 397a8e1175bSopenharmony_ci cipher_update_calls); 398a8e1175bSopenharmony_ci 399a8e1175bSopenharmony_ciexit: 400a8e1175bSopenharmony_ci mbedtls_gcm_free(&ctx); 401a8e1175bSopenharmony_ci BLOCK_CIPHER_PSA_DONE(); 402a8e1175bSopenharmony_ci} 403a8e1175bSopenharmony_ci/* END_CASE */ 404a8e1175bSopenharmony_ci 405a8e1175bSopenharmony_ci/* BEGIN_CASE */ 406a8e1175bSopenharmony_civoid gcm_encrypt_and_tag_empty_ad(int cipher_id, 407a8e1175bSopenharmony_ci data_t *key_str, 408a8e1175bSopenharmony_ci data_t *iv_str, 409a8e1175bSopenharmony_ci data_t *src_str, 410a8e1175bSopenharmony_ci data_t *dst, 411a8e1175bSopenharmony_ci data_t *tag_str, 412a8e1175bSopenharmony_ci int ad_update_calls) 413a8e1175bSopenharmony_ci{ 414a8e1175bSopenharmony_ci mbedtls_gcm_context ctx; 415a8e1175bSopenharmony_ci 416a8e1175bSopenharmony_ci BLOCK_CIPHER_PSA_INIT(); 417a8e1175bSopenharmony_ci mbedtls_gcm_init(&ctx); 418a8e1175bSopenharmony_ci 419a8e1175bSopenharmony_ci TEST_ASSERT(mbedtls_gcm_setkey(&ctx, cipher_id, key_str->x, key_str->len * 8) == 0); 420a8e1175bSopenharmony_ci check_cipher_with_empty_ad(&ctx, MBEDTLS_GCM_ENCRYPT, 421a8e1175bSopenharmony_ci iv_str, src_str, dst, tag_str, 422a8e1175bSopenharmony_ci ad_update_calls); 423a8e1175bSopenharmony_ci 424a8e1175bSopenharmony_ciexit: 425a8e1175bSopenharmony_ci mbedtls_gcm_free(&ctx); 426a8e1175bSopenharmony_ci BLOCK_CIPHER_PSA_DONE(); 427a8e1175bSopenharmony_ci} 428a8e1175bSopenharmony_ci/* END_CASE */ 429a8e1175bSopenharmony_ci 430a8e1175bSopenharmony_ci/* BEGIN_CASE */ 431a8e1175bSopenharmony_civoid gcm_encrypt_and_verify_no_ad_no_cipher(int cipher_id, 432a8e1175bSopenharmony_ci data_t *key_str, 433a8e1175bSopenharmony_ci data_t *iv_str, 434a8e1175bSopenharmony_ci data_t *tag_str) 435a8e1175bSopenharmony_ci{ 436a8e1175bSopenharmony_ci mbedtls_gcm_context ctx; 437a8e1175bSopenharmony_ci 438a8e1175bSopenharmony_ci BLOCK_CIPHER_PSA_INIT(); 439a8e1175bSopenharmony_ci mbedtls_gcm_init(&ctx); 440a8e1175bSopenharmony_ci 441a8e1175bSopenharmony_ci TEST_ASSERT(mbedtls_gcm_setkey(&ctx, cipher_id, key_str->x, key_str->len * 8) == 0); 442a8e1175bSopenharmony_ci check_no_cipher_no_ad(&ctx, MBEDTLS_GCM_ENCRYPT, 443a8e1175bSopenharmony_ci iv_str, tag_str); 444a8e1175bSopenharmony_ci 445a8e1175bSopenharmony_ci mbedtls_gcm_free(&ctx); 446a8e1175bSopenharmony_ci BLOCK_CIPHER_PSA_DONE(); 447a8e1175bSopenharmony_ci} 448a8e1175bSopenharmony_ci/* END_CASE */ 449a8e1175bSopenharmony_ci 450a8e1175bSopenharmony_ci/* BEGIN_CASE */ 451a8e1175bSopenharmony_civoid gcm_invalid_param() 452a8e1175bSopenharmony_ci{ 453a8e1175bSopenharmony_ci mbedtls_gcm_context ctx; 454a8e1175bSopenharmony_ci unsigned char valid_buffer[] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 }; 455a8e1175bSopenharmony_ci mbedtls_cipher_id_t valid_cipher = MBEDTLS_CIPHER_ID_AES; 456a8e1175bSopenharmony_ci int invalid_bitlen = 1; 457a8e1175bSopenharmony_ci 458a8e1175bSopenharmony_ci mbedtls_gcm_init(&ctx); 459a8e1175bSopenharmony_ci 460a8e1175bSopenharmony_ci /* mbedtls_gcm_setkey */ 461a8e1175bSopenharmony_ci TEST_EQUAL( 462a8e1175bSopenharmony_ci MBEDTLS_ERR_GCM_BAD_INPUT, 463a8e1175bSopenharmony_ci mbedtls_gcm_setkey(&ctx, valid_cipher, valid_buffer, invalid_bitlen)); 464a8e1175bSopenharmony_ci 465a8e1175bSopenharmony_ciexit: 466a8e1175bSopenharmony_ci mbedtls_gcm_free(&ctx); 467a8e1175bSopenharmony_ci} 468a8e1175bSopenharmony_ci/* END_CASE */ 469a8e1175bSopenharmony_ci 470a8e1175bSopenharmony_ci/* BEGIN_CASE */ 471a8e1175bSopenharmony_civoid gcm_update_output_buffer_too_small(int cipher_id, int mode, 472a8e1175bSopenharmony_ci data_t *key_str, const data_t *input, 473a8e1175bSopenharmony_ci const data_t *iv) 474a8e1175bSopenharmony_ci{ 475a8e1175bSopenharmony_ci mbedtls_gcm_context ctx; 476a8e1175bSopenharmony_ci uint8_t *output = NULL; 477a8e1175bSopenharmony_ci size_t olen = 0; 478a8e1175bSopenharmony_ci size_t output_len = input->len - 1; 479a8e1175bSopenharmony_ci 480a8e1175bSopenharmony_ci BLOCK_CIPHER_PSA_INIT(); 481a8e1175bSopenharmony_ci mbedtls_gcm_init(&ctx); 482a8e1175bSopenharmony_ci TEST_EQUAL(mbedtls_gcm_setkey(&ctx, cipher_id, key_str->x, key_str->len * 8), 0); 483a8e1175bSopenharmony_ci TEST_EQUAL(0, mbedtls_gcm_starts(&ctx, mode, iv->x, iv->len)); 484a8e1175bSopenharmony_ci 485a8e1175bSopenharmony_ci TEST_CALLOC(output, output_len); 486a8e1175bSopenharmony_ci TEST_EQUAL(MBEDTLS_ERR_GCM_BUFFER_TOO_SMALL, 487a8e1175bSopenharmony_ci mbedtls_gcm_update(&ctx, input->x, input->len, output, output_len, &olen)); 488a8e1175bSopenharmony_ci 489a8e1175bSopenharmony_ciexit: 490a8e1175bSopenharmony_ci mbedtls_free(output); 491a8e1175bSopenharmony_ci mbedtls_gcm_free(&ctx); 492a8e1175bSopenharmony_ci BLOCK_CIPHER_PSA_DONE(); 493a8e1175bSopenharmony_ci} 494a8e1175bSopenharmony_ci/* END_CASE */ 495a8e1175bSopenharmony_ci 496a8e1175bSopenharmony_ci/* BEGIN_CASE */ 497a8e1175bSopenharmony_ci/* NISP SP 800-38D, Section 5.2.1.1 requires that bit length of IV should 498a8e1175bSopenharmony_ci * satisfy 1 <= bit_len(IV) <= 2^64 - 1. */ 499a8e1175bSopenharmony_civoid gcm_invalid_iv_len(void) 500a8e1175bSopenharmony_ci{ 501a8e1175bSopenharmony_ci mbedtls_gcm_context ctx; 502a8e1175bSopenharmony_ci mbedtls_gcm_init(&ctx); 503a8e1175bSopenharmony_ci uint8_t b16[16] = { 0 }; 504a8e1175bSopenharmony_ci 505a8e1175bSopenharmony_ci BLOCK_CIPHER_PSA_INIT(); 506a8e1175bSopenharmony_ci 507a8e1175bSopenharmony_ci // Invalid IV length 0 508a8e1175bSopenharmony_ci gcm_reset_ctx(&ctx, b16, sizeof(b16) * 8, b16, 0, MBEDTLS_ERR_GCM_BAD_INPUT); 509a8e1175bSopenharmony_ci mbedtls_gcm_free(&ctx); 510a8e1175bSopenharmony_ci 511a8e1175bSopenharmony_ci // Only testable on platforms where sizeof(size_t) >= 8. 512a8e1175bSopenharmony_ci#if SIZE_MAX >= UINT64_MAX 513a8e1175bSopenharmony_ci // Invalid IV length 2^61 514a8e1175bSopenharmony_ci gcm_reset_ctx(&ctx, b16, sizeof(b16) * 8, b16, 1ULL << 61, MBEDTLS_ERR_GCM_BAD_INPUT); 515a8e1175bSopenharmony_ci mbedtls_gcm_free(&ctx); 516a8e1175bSopenharmony_ci#endif 517a8e1175bSopenharmony_ci 518a8e1175bSopenharmony_ci goto exit; /* To suppress error that exit is defined but not used */ 519a8e1175bSopenharmony_ciexit: 520a8e1175bSopenharmony_ci mbedtls_gcm_free(&ctx); 521a8e1175bSopenharmony_ci BLOCK_CIPHER_PSA_DONE(); 522a8e1175bSopenharmony_ci} 523a8e1175bSopenharmony_ci/* END_CASE */ 524a8e1175bSopenharmony_ci 525a8e1175bSopenharmony_ci/* BEGIN_CASE */ 526a8e1175bSopenharmony_civoid gcm_add_len_too_long(void) 527a8e1175bSopenharmony_ci{ 528a8e1175bSopenharmony_ci // Only testable on platforms where sizeof(size_t) >= 8. 529a8e1175bSopenharmony_ci#if SIZE_MAX >= UINT64_MAX 530a8e1175bSopenharmony_ci mbedtls_gcm_context ctx; 531a8e1175bSopenharmony_ci mbedtls_gcm_init(&ctx); 532a8e1175bSopenharmony_ci uint8_t b16[16] = { 0 }; 533a8e1175bSopenharmony_ci BLOCK_CIPHER_PSA_INIT(); 534a8e1175bSopenharmony_ci 535a8e1175bSopenharmony_ci /* NISP SP 800-38D, Section 5.2.1.1 requires that bit length of AD should 536a8e1175bSopenharmony_ci * be <= 2^64 - 1, ie < 2^64. This is the minimum invalid length in bytes. */ 537a8e1175bSopenharmony_ci uint64_t len_max = 1ULL << 61; 538a8e1175bSopenharmony_ci 539a8e1175bSopenharmony_ci gcm_reset_ctx(&ctx, b16, sizeof(b16) * 8, b16, sizeof(b16), 0); 540a8e1175bSopenharmony_ci // Feed AD that just exceeds the length limit 541a8e1175bSopenharmony_ci TEST_EQUAL(mbedtls_gcm_update_ad(&ctx, b16, len_max), 542a8e1175bSopenharmony_ci MBEDTLS_ERR_GCM_BAD_INPUT); 543a8e1175bSopenharmony_ci mbedtls_gcm_free(&ctx); 544a8e1175bSopenharmony_ci 545a8e1175bSopenharmony_ci gcm_reset_ctx(&ctx, b16, sizeof(b16) * 8, b16, sizeof(b16), 0); 546a8e1175bSopenharmony_ci // Feed AD that just exceeds the length limit in two calls 547a8e1175bSopenharmony_ci TEST_EQUAL(mbedtls_gcm_update_ad(&ctx, b16, 1), 0); 548a8e1175bSopenharmony_ci TEST_EQUAL(mbedtls_gcm_update_ad(&ctx, b16, len_max - 1), 549a8e1175bSopenharmony_ci MBEDTLS_ERR_GCM_BAD_INPUT); 550a8e1175bSopenharmony_ci mbedtls_gcm_free(&ctx); 551a8e1175bSopenharmony_ci 552a8e1175bSopenharmony_ci gcm_reset_ctx(&ctx, b16, sizeof(b16) * 8, b16, sizeof(b16), 0); 553a8e1175bSopenharmony_ci // Test if potential total AD length overflow is handled properly 554a8e1175bSopenharmony_ci TEST_EQUAL(mbedtls_gcm_update_ad(&ctx, b16, 1), 0); 555a8e1175bSopenharmony_ci TEST_EQUAL(mbedtls_gcm_update_ad(&ctx, b16, UINT64_MAX), MBEDTLS_ERR_GCM_BAD_INPUT); 556a8e1175bSopenharmony_ci 557a8e1175bSopenharmony_ciexit: 558a8e1175bSopenharmony_ci mbedtls_gcm_free(&ctx); 559a8e1175bSopenharmony_ci BLOCK_CIPHER_PSA_DONE(); 560a8e1175bSopenharmony_ci#endif 561a8e1175bSopenharmony_ci} 562a8e1175bSopenharmony_ci/* END_CASE */ 563a8e1175bSopenharmony_ci 564a8e1175bSopenharmony_ci/* BEGIN_CASE */ 565a8e1175bSopenharmony_civoid gcm_input_len_too_long(void) 566a8e1175bSopenharmony_ci{ 567a8e1175bSopenharmony_ci // Only testable on platforms where sizeof(size_t) >= 8 568a8e1175bSopenharmony_ci#if SIZE_MAX >= UINT64_MAX 569a8e1175bSopenharmony_ci mbedtls_gcm_context ctx; 570a8e1175bSopenharmony_ci uint8_t b16[16] = { 0 }; 571a8e1175bSopenharmony_ci uint8_t out[1]; 572a8e1175bSopenharmony_ci size_t out_len; 573a8e1175bSopenharmony_ci mbedtls_gcm_init(&ctx); 574a8e1175bSopenharmony_ci BLOCK_CIPHER_PSA_INIT(); 575a8e1175bSopenharmony_ci 576a8e1175bSopenharmony_ci /* NISP SP 800-38D, Section 5.2.1.1 requires that bit length of input should 577a8e1175bSopenharmony_ci * be <= 2^39 - 256. This is the maximum valid length in bytes. */ 578a8e1175bSopenharmony_ci uint64_t len_max = (1ULL << 36) - 32; 579a8e1175bSopenharmony_ci 580a8e1175bSopenharmony_ci gcm_reset_ctx(&ctx, b16, sizeof(b16) * 8, b16, sizeof(b16), 0); 581a8e1175bSopenharmony_ci // Feed input that just exceeds the length limit 582a8e1175bSopenharmony_ci TEST_EQUAL(mbedtls_gcm_update(&ctx, b16, len_max + 1, out, len_max + 1, 583a8e1175bSopenharmony_ci &out_len), 584a8e1175bSopenharmony_ci MBEDTLS_ERR_GCM_BAD_INPUT); 585a8e1175bSopenharmony_ci mbedtls_gcm_free(&ctx); 586a8e1175bSopenharmony_ci 587a8e1175bSopenharmony_ci gcm_reset_ctx(&ctx, b16, sizeof(b16) * 8, b16, sizeof(b16), 0); 588a8e1175bSopenharmony_ci // Feed input that just exceeds the length limit in two calls 589a8e1175bSopenharmony_ci TEST_EQUAL(mbedtls_gcm_update(&ctx, b16, 1, out, 1, &out_len), 0); 590a8e1175bSopenharmony_ci TEST_EQUAL(mbedtls_gcm_update(&ctx, b16, len_max, out, len_max, &out_len), 591a8e1175bSopenharmony_ci MBEDTLS_ERR_GCM_BAD_INPUT); 592a8e1175bSopenharmony_ci mbedtls_gcm_free(&ctx); 593a8e1175bSopenharmony_ci 594a8e1175bSopenharmony_ci gcm_reset_ctx(&ctx, b16, sizeof(b16) * 8, b16, sizeof(b16), 0); 595a8e1175bSopenharmony_ci // Test if potential total input length overflow is handled properly 596a8e1175bSopenharmony_ci TEST_EQUAL(mbedtls_gcm_update(&ctx, b16, 1, out, 1, &out_len), 0); 597a8e1175bSopenharmony_ci TEST_EQUAL(mbedtls_gcm_update(&ctx, b16, UINT64_MAX, out, UINT64_MAX, 598a8e1175bSopenharmony_ci &out_len), 599a8e1175bSopenharmony_ci MBEDTLS_ERR_GCM_BAD_INPUT); 600a8e1175bSopenharmony_ci 601a8e1175bSopenharmony_ciexit: 602a8e1175bSopenharmony_ci mbedtls_gcm_free(&ctx); 603a8e1175bSopenharmony_ci BLOCK_CIPHER_PSA_DONE(); 604a8e1175bSopenharmony_ci#endif 605a8e1175bSopenharmony_ci} 606a8e1175bSopenharmony_ci/* END_CASE */ 607a8e1175bSopenharmony_ci 608a8e1175bSopenharmony_ci/* BEGIN_CASE depends_on:MBEDTLS_SELF_TEST:MBEDTLS_CCM_GCM_CAN_AES */ 609a8e1175bSopenharmony_civoid gcm_selftest() 610a8e1175bSopenharmony_ci{ 611a8e1175bSopenharmony_ci BLOCK_CIPHER_PSA_INIT(); 612a8e1175bSopenharmony_ci TEST_ASSERT(mbedtls_gcm_self_test(1) == 0); 613a8e1175bSopenharmony_ci BLOCK_CIPHER_PSA_DONE(); 614a8e1175bSopenharmony_ci} 615a8e1175bSopenharmony_ci/* END_CASE */ 616