Skip to content

Commit

Permalink
change srtp_cipher_encrypt to append the tag generated
Browse files Browse the repository at this point in the history
This makes it symmetric with the srtp_cipher_decrypt function that will
remove the tag.
Currently most of the backends would have cached the tag internally
and returned it in the srtp_cipher_get_tag function, this removes that
extra complexity.
  • Loading branch information
pabuhler committed Jun 30, 2024
1 parent 5dea791 commit 2eaf98b
Show file tree
Hide file tree
Showing 16 changed files with 92 additions and 300 deletions.
39 changes: 9 additions & 30 deletions crypto/cipher/aes_gcm_mbedtls.c
Original file line number Diff line number Diff line change
Expand Up @@ -291,49 +291,26 @@ static srtp_err_status_t srtp_aes_gcm_mbedtls_encrypt(void *cv,
int errCode = 0;

if (c->dir != srtp_direction_encrypt && c->dir != srtp_direction_decrypt) {
return (srtp_err_status_bad_param);
return srtp_err_status_bad_param;
}

if (*dst_len < src_len) {
if (*dst_len < src_len + c->tag_len) {
return srtp_err_status_buffer_small;
}

errCode = mbedtls_gcm_crypt_and_tag(c->ctx, MBEDTLS_GCM_ENCRYPT, src_len,
c->iv, c->iv_len, c->aad, c->aad_size,
src, dst, c->tag_len, c->tag);
src, dst, c->tag_len, dst + src_len);

c->aad_size = 0;
if (errCode != 0) {
debug_print(srtp_mod_aes_gcm, "mbedtls error code: %d", errCode);
return srtp_err_status_bad_param;
}

*dst_len = src_len;

return (srtp_err_status_ok);
}
*dst_len = src_len + c->tag_len;

/*
* This function calculates and returns the GCM tag for a given context.
* This should be called after encrypting the data. The *len value
* is increased by the tag size. The caller must ensure that *buf has
* enough room to accept the appended tag.
*
* Parameters:
* c Crypto context
* buf data to encrypt
* len length of encrypt buffer
*/
static srtp_err_status_t srtp_aes_gcm_mbedtls_get_tag(void *cv,
uint8_t *buf,
size_t *len)
{
FUNC_ENTRY();
srtp_aes_gcm_ctx_t *c = (srtp_aes_gcm_ctx_t *)cv;
debug_print(srtp_mod_aes_gcm, "appended tag size: %zu", c->tag_len);
*len = c->tag_len;
memcpy(buf, c->tag, c->tag_len);
return (srtp_err_status_ok);
return srtp_err_status_ok;
}

/*
Expand Down Expand Up @@ -393,6 +370,7 @@ static const char srtp_aes_gcm_256_mbedtls_description[] =
/*
* This is the vector function table for this crypto engine.
*/
/* clang-format off */
const srtp_cipher_type_t srtp_aes_gcm_128 = {
srtp_aes_gcm_mbedtls_alloc,
srtp_aes_gcm_mbedtls_dealloc,
Expand All @@ -401,15 +379,16 @@ const srtp_cipher_type_t srtp_aes_gcm_128 = {
srtp_aes_gcm_mbedtls_encrypt,
srtp_aes_gcm_mbedtls_decrypt,
srtp_aes_gcm_mbedtls_set_iv,
srtp_aes_gcm_mbedtls_get_tag,
srtp_aes_gcm_128_mbedtls_description,
&srtp_aes_gcm_128_test_case_0,
SRTP_AES_GCM_128
};
/* clang-format on */

/*
* This is the vector function table for this crypto engine.
*/
/* clang-format off */
const srtp_cipher_type_t srtp_aes_gcm_256 = {
srtp_aes_gcm_mbedtls_alloc,
srtp_aes_gcm_mbedtls_dealloc,
Expand All @@ -418,8 +397,8 @@ const srtp_cipher_type_t srtp_aes_gcm_256 = {
srtp_aes_gcm_mbedtls_encrypt,
srtp_aes_gcm_mbedtls_decrypt,
srtp_aes_gcm_mbedtls_set_iv,
srtp_aes_gcm_mbedtls_get_tag,
srtp_aes_gcm_256_mbedtls_description,
&srtp_aes_gcm_256_test_case_0,
SRTP_AES_GCM_256
};
/* clang-format on */
60 changes: 1 addition & 59 deletions crypto/cipher/aes_gcm_nss.c
Original file line number Diff line number Diff line change
Expand Up @@ -319,11 +319,6 @@ static srtp_err_status_t srtp_aes_gcm_nss_do_crypto(void *cv,
/*
* This function encrypts a buffer using AES GCM mode
*
* XXX([email protected]): We're required to break off and cache the tag
* here, because the get_tag() method is separate and the tests expect
* encrypt() not to change the size of the plaintext. It might be
* good to update the calling API so that this is cleaner.
*
* Parameters:
* c Crypto context
* buf data to encrypt
Expand All @@ -335,58 +330,7 @@ static srtp_err_status_t srtp_aes_gcm_nss_encrypt(void *cv,
uint8_t *dst,
size_t *dst_len)
{
srtp_aes_gcm_ctx_t *c = (srtp_aes_gcm_ctx_t *)cv;

// When we get a non-NULL src buffer, we know that the caller is
// prepared to also take the tag. When we get a NULL src buffer,
// even though there's no data, we need to give NSS a buffer
// where it can write the tag. We can't just use c->tag because
// memcpy has undefined behavior on overlapping ranges.
uint8_t tagbuf[16];
const uint8_t *non_null_buf = src;
uint8_t *non_null_dst_buf = dst;
if (!non_null_buf && (src_len == 0)) {
non_null_buf = tagbuf;
non_null_dst_buf = tagbuf;
*dst_len = sizeof(tagbuf);
} else if (!non_null_buf) {
return srtp_err_status_bad_param;
}

srtp_err_status_t status = srtp_aes_gcm_nss_do_crypto(
cv, true, non_null_buf, src_len, non_null_dst_buf, dst_len);
if (status != srtp_err_status_ok) {
return status;
}

if (*dst_len < c->tag_size) {
return srtp_err_status_bad_param;
}

memcpy(c->tag, non_null_dst_buf + (*dst_len - c->tag_size), c->tag_size);
*dst_len -= c->tag_size;
return srtp_err_status_ok;
}

/*
* This function calculates and returns the GCM tag for a given context.
* This should be called after encrypting the data. The *len value
* is increased by the tag size. The caller must ensure that *buf has
* enough room to accept the appended tag.
*
* Parameters:
* c Crypto context
* buf data to encrypt
* len length of encrypt buffer
*/
static srtp_err_status_t srtp_aes_gcm_nss_get_tag(void *cv,
uint8_t *buf,
size_t *len)
{
srtp_aes_gcm_ctx_t *c = (srtp_aes_gcm_ctx_t *)cv;
*len = c->tag_size;
memcpy(buf, c->tag, c->tag_size);
return (srtp_err_status_ok);
return srtp_aes_gcm_nss_do_crypto(cv, true, src, src_len, dst, dst_len);
}

/*
Expand Down Expand Up @@ -442,7 +386,6 @@ const srtp_cipher_type_t srtp_aes_gcm_128 = {
srtp_aes_gcm_nss_encrypt,
srtp_aes_gcm_nss_decrypt,
srtp_aes_gcm_nss_set_iv,
srtp_aes_gcm_nss_get_tag,
srtp_aes_gcm_128_nss_description,
&srtp_aes_gcm_128_test_case_0,
SRTP_AES_GCM_128
Expand All @@ -461,7 +404,6 @@ const srtp_cipher_type_t srtp_aes_gcm_256 = {
srtp_aes_gcm_nss_encrypt,
srtp_aes_gcm_nss_decrypt,
srtp_aes_gcm_nss_set_iv,
srtp_aes_gcm_nss_get_tag,
srtp_aes_gcm_256_nss_description,
&srtp_aes_gcm_256_test_case_0,
SRTP_AES_GCM_256
Expand Down
56 changes: 23 additions & 33 deletions crypto/cipher/aes_gcm_ossl.c
Original file line number Diff line number Diff line change
Expand Up @@ -299,51 +299,34 @@ static srtp_err_status_t srtp_aes_gcm_openssl_encrypt(void *cv,
size_t *dst_len)
{
srtp_aes_gcm_ctx_t *c = (srtp_aes_gcm_ctx_t *)cv;

if (c->dir != srtp_direction_encrypt && c->dir != srtp_direction_decrypt) {
return (srtp_err_status_bad_param);
return srtp_err_status_bad_param;
}

if (*dst_len < src_len + c->tag_len) {
return srtp_err_status_buffer_small;
}

/*
* Encrypt the data
*/
EVP_Cipher(c->ctx, dst, src, src_len);
*dst_len = src_len;

return (srtp_err_status_ok);
}

/*
* This function calculates and returns the GCM tag for a given context.
* This should be called after encrypting the data. The *len value
* is increased by the tag size. The caller must ensure that *buf has
* enough room to accept the appended tag.
*
* Parameters:
* c Crypto context
* buf data to encrypt
* len length of encrypt buffer
*/
static srtp_err_status_t srtp_aes_gcm_openssl_get_tag(void *cv,
uint8_t *buf,
size_t *len)
{
srtp_aes_gcm_ctx_t *c = (srtp_aes_gcm_ctx_t *)cv;
/*
* Calculate the tag
*/
EVP_Cipher(c->ctx, NULL, NULL, 0);

/*
* Retreive the tag
* Retrieve the tag
*/
if (!EVP_CIPHER_CTX_ctrl(c->ctx, EVP_CTRL_GCM_GET_TAG, c->tag_len, buf)) {
return (srtp_err_status_algo_fail);
if (!EVP_CIPHER_CTX_ctrl(c->ctx, EVP_CTRL_GCM_GET_TAG, c->tag_len,
dst + src_len)) {
return srtp_err_status_algo_fail;
}

/*
* Increase encryption length by desired tag size
*/
*len = c->tag_len;
*dst_len = src_len + c->tag_len;

return (srtp_err_status_ok);
}
Expand All @@ -363,8 +346,13 @@ static srtp_err_status_t srtp_aes_gcm_openssl_decrypt(void *cv,
size_t *dst_len)
{
srtp_aes_gcm_ctx_t *c = (srtp_aes_gcm_ctx_t *)cv;

if (c->dir != srtp_direction_encrypt && c->dir != srtp_direction_decrypt) {
return (srtp_err_status_bad_param);
return srtp_err_status_bad_param;
}

if (*dst_len < src_len - c->tag_len) {
return srtp_err_status_buffer_small;
}

/*
Expand All @@ -375,15 +363,15 @@ static srtp_err_status_t srtp_aes_gcm_openssl_decrypt(void *cv,
if (!EVP_CIPHER_CTX_ctrl(
c->ctx, EVP_CTRL_GCM_SET_TAG, c->tag_len,
(void *)(uintptr_t)(src + (src_len - c->tag_len)))) {
return (srtp_err_status_auth_fail);
return srtp_err_status_auth_fail;
}
EVP_Cipher(c->ctx, dst, src, src_len - c->tag_len);

/*
* Check the tag
*/
if (EVP_Cipher(c->ctx, NULL, NULL, 0)) {
return (srtp_err_status_auth_fail);
return srtp_err_status_auth_fail;
}

/*
Expand All @@ -406,6 +394,7 @@ static const char srtp_aes_gcm_256_openssl_description[] =
/*
* This is the vector function table for this crypto engine.
*/
/* clang-format off */
const srtp_cipher_type_t srtp_aes_gcm_128 = {
srtp_aes_gcm_openssl_alloc,
srtp_aes_gcm_openssl_dealloc,
Expand All @@ -414,15 +403,16 @@ const srtp_cipher_type_t srtp_aes_gcm_128 = {
srtp_aes_gcm_openssl_encrypt,
srtp_aes_gcm_openssl_decrypt,
srtp_aes_gcm_openssl_set_iv,
srtp_aes_gcm_openssl_get_tag,
srtp_aes_gcm_128_openssl_description,
&srtp_aes_gcm_128_test_case_0,
SRTP_AES_GCM_128
};
/* clang-format on */

/*
* This is the vector function table for this crypto engine.
*/
/* clang-format off */
const srtp_cipher_type_t srtp_aes_gcm_256 = {
srtp_aes_gcm_openssl_alloc,
srtp_aes_gcm_openssl_dealloc,
Expand All @@ -431,8 +421,8 @@ const srtp_cipher_type_t srtp_aes_gcm_256 = {
srtp_aes_gcm_openssl_encrypt,
srtp_aes_gcm_openssl_decrypt,
srtp_aes_gcm_openssl_set_iv,
srtp_aes_gcm_openssl_get_tag,
srtp_aes_gcm_256_openssl_description,
&srtp_aes_gcm_256_test_case_0,
SRTP_AES_GCM_256
};
/* clang-format on */
Loading

0 comments on commit 2eaf98b

Please sign in to comment.