Skip to content

Commit

Permalink
Merge pull request #9774 from Harry-Ramsey/update-gcm-doc-2.28
Browse files Browse the repository at this point in the history
[Backport 2.28] Fix doc on GCM API
  • Loading branch information
davidhorstmann-arm authored Nov 21, 2024
2 parents 89c68e2 + c22ead7 commit 763c116
Show file tree
Hide file tree
Showing 9 changed files with 4,364 additions and 10 deletions.
23 changes: 13 additions & 10 deletions include/mbedtls/gcm.h
Original file line number Diff line number Diff line change
Expand Up @@ -107,10 +107,9 @@ int mbedtls_gcm_setkey(mbedtls_gcm_context *ctx,
/**
* \brief This function performs GCM encryption or decryption of a buffer.
*
* \note For encryption, the output buffer can be the same as the
* input buffer. For decryption, the output buffer cannot be
* the same as input buffer. If the buffers overlap, the output
* buffer must trail at least 8 Bytes behind the input buffer.
* \note The output buffer \p output can be the same as the input
* buffer \p input. If \p output is greater than \p input, they
* cannot overlap.
*
* \warning When this function performs a decryption, it outputs the
* authentication tag and does not verify that the data is
Expand Down Expand Up @@ -171,9 +170,11 @@ int mbedtls_gcm_crypt_and_tag(mbedtls_gcm_context *ctx,
* \brief This function performs a GCM authenticated decryption of a
* buffer.
*
* \note For decryption, the output buffer cannot be the same as
* input buffer. If the buffers overlap, the output buffer
* must trail at least 8 Bytes behind the input buffer.
* \note The output buffer \p output can be the same as the input
* buffer \p input. If \p output is greater than \p input, they
* cannot overlap. Implementations which require
* MBEDTLS_GCM_ALT to be enabled may not provide support for
* overlapping buffers.
*
* \param ctx The GCM context. This must be initialized.
* \param length The length of the ciphertext to decrypt, which is also
Expand Down Expand Up @@ -243,9 +244,11 @@ int mbedtls_gcm_starts(mbedtls_gcm_context *ctx,
* Bytes. Only the last call before calling
* mbedtls_gcm_finish() can be less than 16 Bytes.
*
* \note For decryption, the output buffer cannot be the same as
* input buffer. If the buffers overlap, the output buffer
* must trail at least 8 Bytes behind the input buffer.
* \note The output buffer \p output can be the same as the input
* buffer \p input. If \p output is greater than \p input, they
* cannot overlap. Implementations which require
* MBEDTLS_GCM_ALT to be enabled may not provide support for
* overlapping buffers.
*
* \param ctx The GCM context. This must be initialized.
* \param length The length of the input data. This must be a multiple of
Expand Down
673 changes: 673 additions & 0 deletions tests/suites/test_suite_gcm.aes128_de.data

Large diffs are not rendered by default.

673 changes: 673 additions & 0 deletions tests/suites/test_suite_gcm.aes128_en.data

Large diffs are not rendered by default.

673 changes: 673 additions & 0 deletions tests/suites/test_suite_gcm.aes192_de.data

Large diffs are not rendered by default.

672 changes: 672 additions & 0 deletions tests/suites/test_suite_gcm.aes192_en.data

Large diffs are not rendered by default.

672 changes: 672 additions & 0 deletions tests/suites/test_suite_gcm.aes256_de.data

Large diffs are not rendered by default.

672 changes: 672 additions & 0 deletions tests/suites/test_suite_gcm.aes256_en.data

Large diffs are not rendered by default.

216 changes: 216 additions & 0 deletions tests/suites/test_suite_gcm.camellia.data

Large diffs are not rendered by default.

100 changes: 100 additions & 0 deletions tests/suites/test_suite_gcm.function
Original file line number Diff line number Diff line change
Expand Up @@ -289,3 +289,103 @@ void gcm_selftest()
TEST_ASSERT(mbedtls_gcm_self_test(1) == 0);
}
/* END_CASE */

/* BEGIN_CASE */
void gcm_encrypt_input_output_buffer_overlap(int cipher_id, data_t *key_str,
data_t *src_str, data_t *iv_str,
data_t *add_str, data_t *dst,
int tag_len_bits, data_t *tag,
int init_result)
{
unsigned char *buffer = NULL;
size_t buffer_len;
unsigned char tag_output[16];
mbedtls_gcm_context ctx;
size_t tag_len = tag_len_bits / 8;

mbedtls_gcm_init(&ctx);

/* GCM includes padding and therefore input length can be shorter than the output length
* Therefore we must ensure we round up to the nearest 128-bits/16-bytes.
*/
buffer_len = src_str->len;
if (buffer_len % 16 != 0 || buffer_len == 0) {
buffer_len += (16 - (buffer_len % 16));
}
TEST_CALLOC(buffer, buffer_len);
memcpy(buffer, src_str->x, src_str->len);

memset(tag_output, 0x00, 16);

TEST_ASSERT(mbedtls_gcm_setkey(&ctx, cipher_id, key_str->x, key_str->len * 8) == init_result);
if (init_result == 0) {
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, buffer,
buffer, tag_len, tag_output) == 0);

TEST_ASSERT(mbedtls_test_hexcmp(buffer, dst->x,
src_str->len, dst->len) == 0);
TEST_ASSERT(mbedtls_test_hexcmp(tag_output, tag->x,
tag_len, tag->len) == 0);
}

exit:
mbedtls_free(buffer);
mbedtls_gcm_free(&ctx);
}
/* END_CASE */

/* BEGIN_CASE */
void gcm_decrypt_input_output_buffer_overlap(int cipher_id, data_t *key_str,
data_t *src_str, data_t *iv_str,
data_t *add_str, int tag_len_bits,
data_t *tag_str, char *result,
data_t *pt_result, int init_result)
{
unsigned char *buffer = NULL;
size_t buffer_len;
mbedtls_gcm_context ctx;
int ret;
size_t tag_len = tag_len_bits / 8;

mbedtls_gcm_init(&ctx);

/* GCM includes padding and therefore input length can be shorter than the output length
* Therefore we must ensure we round up to the nearest 128-bits/16-bytes.
*/
buffer_len = src_str->len;
if (buffer_len % 16 != 0 || buffer_len == 0) {
buffer_len += (16 - (buffer_len % 16));
}
TEST_CALLOC(buffer, buffer_len);
memcpy(buffer, src_str->x, src_str->len);

TEST_ASSERT(mbedtls_gcm_setkey(&ctx, cipher_id, key_str->x, key_str->len * 8) == init_result);
if (init_result == 0) {
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,
buffer,
buffer);

if (strcmp("FAIL", result) == 0) {
TEST_ASSERT(ret == MBEDTLS_ERR_GCM_AUTH_FAILED);
} else {
TEST_ASSERT(ret == 0);

TEST_ASSERT(mbedtls_test_hexcmp(buffer, pt_result->x,
src_str->len,
pt_result->len) == 0);
}
}

exit:
mbedtls_free(buffer);
mbedtls_gcm_free(&ctx);
}
/* END_CASE */

0 comments on commit 763c116

Please sign in to comment.